Added my gui version
[matches/MCTX3420.git] / testing / ver0.01 / jquery-ui-1.10.3.custom / development-bundle / ui / jquery-ui.custom.js
1 /*! jQuery UI - v1.10.3 - 2013-08-18
2 * http://jqueryui.com
3 * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
4 * Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
5
6 (function( $, undefined ) {
7
8 var uuid = 0,
9         runiqueId = /^ui-id-\d+$/;
10
11 // $.ui might exist from components with no dependencies, e.g., $.ui.position
12 $.ui = $.ui || {};
13
14 $.extend( $.ui, {
15         version: "1.10.3",
16
17         keyCode: {
18                 BACKSPACE: 8,
19                 COMMA: 188,
20                 DELETE: 46,
21                 DOWN: 40,
22                 END: 35,
23                 ENTER: 13,
24                 ESCAPE: 27,
25                 HOME: 36,
26                 LEFT: 37,
27                 NUMPAD_ADD: 107,
28                 NUMPAD_DECIMAL: 110,
29                 NUMPAD_DIVIDE: 111,
30                 NUMPAD_ENTER: 108,
31                 NUMPAD_MULTIPLY: 106,
32                 NUMPAD_SUBTRACT: 109,
33                 PAGE_DOWN: 34,
34                 PAGE_UP: 33,
35                 PERIOD: 190,
36                 RIGHT: 39,
37                 SPACE: 32,
38                 TAB: 9,
39                 UP: 38
40         }
41 });
42
43 // plugins
44 $.fn.extend({
45         focus: (function( orig ) {
46                 return function( delay, fn ) {
47                         return typeof delay === "number" ?
48                                 this.each(function() {
49                                         var elem = this;
50                                         setTimeout(function() {
51                                                 $( elem ).focus();
52                                                 if ( fn ) {
53                                                         fn.call( elem );
54                                                 }
55                                         }, delay );
56                                 }) :
57                                 orig.apply( this, arguments );
58                 };
59         })( $.fn.focus ),
60
61         scrollParent: function() {
62                 var scrollParent;
63                 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
64                         scrollParent = this.parents().filter(function() {
65                                 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
66                         }).eq(0);
67                 } else {
68                         scrollParent = this.parents().filter(function() {
69                                 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70                         }).eq(0);
71                 }
72
73                 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
74         },
75
76         zIndex: function( zIndex ) {
77                 if ( zIndex !== undefined ) {
78                         return this.css( "zIndex", zIndex );
79                 }
80
81                 if ( this.length ) {
82                         var elem = $( this[ 0 ] ), position, value;
83                         while ( elem.length && elem[ 0 ] !== document ) {
84                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
85                                 // This makes behavior of this function consistent across browsers
86                                 // WebKit always returns auto if the element is positioned
87                                 position = elem.css( "position" );
88                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
89                                         // IE returns 0 when zIndex is not specified
90                                         // other browsers return a string
91                                         // we ignore the case of nested elements with an explicit value of 0
92                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
93                                         value = parseInt( elem.css( "zIndex" ), 10 );
94                                         if ( !isNaN( value ) && value !== 0 ) {
95                                                 return value;
96                                         }
97                                 }
98                                 elem = elem.parent();
99                         }
100                 }
101
102                 return 0;
103         },
104
105         uniqueId: function() {
106                 return this.each(function() {
107                         if ( !this.id ) {
108                                 this.id = "ui-id-" + (++uuid);
109                         }
110                 });
111         },
112
113         removeUniqueId: function() {
114                 return this.each(function() {
115                         if ( runiqueId.test( this.id ) ) {
116                                 $( this ).removeAttr( "id" );
117                         }
118                 });
119         }
120 });
121
122 // selectors
123 function focusable( element, isTabIndexNotNaN ) {
124         var map, mapName, img,
125                 nodeName = element.nodeName.toLowerCase();
126         if ( "area" === nodeName ) {
127                 map = element.parentNode;
128                 mapName = map.name;
129                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
130                         return false;
131                 }
132                 img = $( "img[usemap=#" + mapName + "]" )[0];
133                 return !!img && visible( img );
134         }
135         return ( /input|select|textarea|button|object/.test( nodeName ) ?
136                 !element.disabled :
137                 "a" === nodeName ?
138                         element.href || isTabIndexNotNaN :
139                         isTabIndexNotNaN) &&
140                 // the element and all of its ancestors must be visible
141                 visible( element );
142 }
143
144 function visible( element ) {
145         return $.expr.filters.visible( element ) &&
146                 !$( element ).parents().addBack().filter(function() {
147                         return $.css( this, "visibility" ) === "hidden";
148                 }).length;
149 }
150
151 $.extend( $.expr[ ":" ], {
152         data: $.expr.createPseudo ?
153                 $.expr.createPseudo(function( dataName ) {
154                         return function( elem ) {
155                                 return !!$.data( elem, dataName );
156                         };
157                 }) :
158                 // support: jQuery <1.8
159                 function( elem, i, match ) {
160                         return !!$.data( elem, match[ 3 ] );
161                 },
162
163         focusable: function( element ) {
164                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
165         },
166
167         tabbable: function( element ) {
168                 var tabIndex = $.attr( element, "tabindex" ),
169                         isTabIndexNaN = isNaN( tabIndex );
170                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
171         }
172 });
173
174 // support: jQuery <1.8
175 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
176         $.each( [ "Width", "Height" ], function( i, name ) {
177                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
178                         type = name.toLowerCase(),
179                         orig = {
180                                 innerWidth: $.fn.innerWidth,
181                                 innerHeight: $.fn.innerHeight,
182                                 outerWidth: $.fn.outerWidth,
183                                 outerHeight: $.fn.outerHeight
184                         };
185
186                 function reduce( elem, size, border, margin ) {
187                         $.each( side, function() {
188                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
189                                 if ( border ) {
190                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
191                                 }
192                                 if ( margin ) {
193                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
194                                 }
195                         });
196                         return size;
197                 }
198
199                 $.fn[ "inner" + name ] = function( size ) {
200                         if ( size === undefined ) {
201                                 return orig[ "inner" + name ].call( this );
202                         }
203
204                         return this.each(function() {
205                                 $( this ).css( type, reduce( this, size ) + "px" );
206                         });
207                 };
208
209                 $.fn[ "outer" + name] = function( size, margin ) {
210                         if ( typeof size !== "number" ) {
211                                 return orig[ "outer" + name ].call( this, size );
212                         }
213
214                         return this.each(function() {
215                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
216                         });
217                 };
218         });
219 }
220
221 // support: jQuery <1.8
222 if ( !$.fn.addBack ) {
223         $.fn.addBack = function( selector ) {
224                 return this.add( selector == null ?
225                         this.prevObject : this.prevObject.filter( selector )
226                 );
227         };
228 }
229
230 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
231 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
232         $.fn.removeData = (function( removeData ) {
233                 return function( key ) {
234                         if ( arguments.length ) {
235                                 return removeData.call( this, $.camelCase( key ) );
236                         } else {
237                                 return removeData.call( this );
238                         }
239                 };
240         })( $.fn.removeData );
241 }
242
243
244
245
246
247 // deprecated
248 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
249
250 $.support.selectstart = "onselectstart" in document.createElement( "div" );
251 $.fn.extend({
252         disableSelection: function() {
253                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
254                         ".ui-disableSelection", function( event ) {
255                                 event.preventDefault();
256                         });
257         },
258
259         enableSelection: function() {
260                 return this.unbind( ".ui-disableSelection" );
261         }
262 });
263
264 $.extend( $.ui, {
265         // $.ui.plugin is deprecated. Use $.widget() extensions instead.
266         plugin: {
267                 add: function( module, option, set ) {
268                         var i,
269                                 proto = $.ui[ module ].prototype;
270                         for ( i in set ) {
271                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
272                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
273                         }
274                 },
275                 call: function( instance, name, args ) {
276                         var i,
277                                 set = instance.plugins[ name ];
278                         if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
279                                 return;
280                         }
281
282                         for ( i = 0; i < set.length; i++ ) {
283                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
284                                         set[ i ][ 1 ].apply( instance.element, args );
285                                 }
286                         }
287                 }
288         },
289
290         // only used by resizable
291         hasScroll: function( el, a ) {
292
293                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
294                 if ( $( el ).css( "overflow" ) === "hidden") {
295                         return false;
296                 }
297
298                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
299                         has = false;
300
301                 if ( el[ scroll ] > 0 ) {
302                         return true;
303                 }
304
305                 // TODO: determine which cases actually cause this to happen
306                 // if the element doesn't have the scroll set, see if it's possible to
307                 // set the scroll
308                 el[ scroll ] = 1;
309                 has = ( el[ scroll ] > 0 );
310                 el[ scroll ] = 0;
311                 return has;
312         }
313 });
314
315 })( jQuery );
316 (function( $, undefined ) {
317
318 var uuid = 0,
319         slice = Array.prototype.slice,
320         _cleanData = $.cleanData;
321 $.cleanData = function( elems ) {
322         for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323                 try {
324                         $( elem ).triggerHandler( "remove" );
325                 // http://bugs.jquery.com/ticket/8235
326                 } catch( e ) {}
327         }
328         _cleanData( elems );
329 };
330
331 $.widget = function( name, base, prototype ) {
332         var fullName, existingConstructor, constructor, basePrototype,
333                 // proxiedPrototype allows the provided prototype to remain unmodified
334                 // so that it can be used as a mixin for multiple widgets (#8876)
335                 proxiedPrototype = {},
336                 namespace = name.split( "." )[ 0 ];
337
338         name = name.split( "." )[ 1 ];
339         fullName = namespace + "-" + name;
340
341         if ( !prototype ) {
342                 prototype = base;
343                 base = $.Widget;
344         }
345
346         // create selector for plugin
347         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348                 return !!$.data( elem, fullName );
349         };
350
351         $[ namespace ] = $[ namespace ] || {};
352         existingConstructor = $[ namespace ][ name ];
353         constructor = $[ namespace ][ name ] = function( options, element ) {
354                 // allow instantiation without "new" keyword
355                 if ( !this._createWidget ) {
356                         return new constructor( options, element );
357                 }
358
359                 // allow instantiation without initializing for simple inheritance
360                 // must use "new" keyword (the code above always passes args)
361                 if ( arguments.length ) {
362                         this._createWidget( options, element );
363                 }
364         };
365         // extend with the existing constructor to carry over any static properties
366         $.extend( constructor, existingConstructor, {
367                 version: prototype.version,
368                 // copy the object used to create the prototype in case we need to
369                 // redefine the widget later
370                 _proto: $.extend( {}, prototype ),
371                 // track widgets that inherit from this widget in case this widget is
372                 // redefined after a widget inherits from it
373                 _childConstructors: []
374         });
375
376         basePrototype = new base();
377         // we need to make the options hash a property directly on the new instance
378         // otherwise we'll modify the options hash on the prototype that we're
379         // inheriting from
380         basePrototype.options = $.widget.extend( {}, basePrototype.options );
381         $.each( prototype, function( prop, value ) {
382                 if ( !$.isFunction( value ) ) {
383                         proxiedPrototype[ prop ] = value;
384                         return;
385                 }
386                 proxiedPrototype[ prop ] = (function() {
387                         var _super = function() {
388                                         return base.prototype[ prop ].apply( this, arguments );
389                                 },
390                                 _superApply = function( args ) {
391                                         return base.prototype[ prop ].apply( this, args );
392                                 };
393                         return function() {
394                                 var __super = this._super,
395                                         __superApply = this._superApply,
396                                         returnValue;
397
398                                 this._super = _super;
399                                 this._superApply = _superApply;
400
401                                 returnValue = value.apply( this, arguments );
402
403                                 this._super = __super;
404                                 this._superApply = __superApply;
405
406                                 return returnValue;
407                         };
408                 })();
409         });
410         constructor.prototype = $.widget.extend( basePrototype, {
411                 // TODO: remove support for widgetEventPrefix
412                 // always use the name + a colon as the prefix, e.g., draggable:start
413                 // don't prefix for widgets that aren't DOM-based
414                 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
415         }, proxiedPrototype, {
416                 constructor: constructor,
417                 namespace: namespace,
418                 widgetName: name,
419                 widgetFullName: fullName
420         });
421
422         // If this widget is being redefined then we need to find all widgets that
423         // are inheriting from it and redefine all of them so that they inherit from
424         // the new version of this widget. We're essentially trying to replace one
425         // level in the prototype chain.
426         if ( existingConstructor ) {
427                 $.each( existingConstructor._childConstructors, function( i, child ) {
428                         var childPrototype = child.prototype;
429
430                         // redefine the child widget using the same prototype that was
431                         // originally used, but inherit from the new version of the base
432                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433                 });
434                 // remove the list of existing child constructors from the old constructor
435                 // so the old child constructors can be garbage collected
436                 delete existingConstructor._childConstructors;
437         } else {
438                 base._childConstructors.push( constructor );
439         }
440
441         $.widget.bridge( name, constructor );
442 };
443
444 $.widget.extend = function( target ) {
445         var input = slice.call( arguments, 1 ),
446                 inputIndex = 0,
447                 inputLength = input.length,
448                 key,
449                 value;
450         for ( ; inputIndex < inputLength; inputIndex++ ) {
451                 for ( key in input[ inputIndex ] ) {
452                         value = input[ inputIndex ][ key ];
453                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454                                 // Clone objects
455                                 if ( $.isPlainObject( value ) ) {
456                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
457                                                 $.widget.extend( {}, target[ key ], value ) :
458                                                 // Don't extend strings, arrays, etc. with objects
459                                                 $.widget.extend( {}, value );
460                                 // Copy everything else by reference
461                                 } else {
462                                         target[ key ] = value;
463                                 }
464                         }
465                 }
466         }
467         return target;
468 };
469
470 $.widget.bridge = function( name, object ) {
471         var fullName = object.prototype.widgetFullName || name;
472         $.fn[ name ] = function( options ) {
473                 var isMethodCall = typeof options === "string",
474                         args = slice.call( arguments, 1 ),
475                         returnValue = this;
476
477                 // allow multiple hashes to be passed on init
478                 options = !isMethodCall && args.length ?
479                         $.widget.extend.apply( null, [ options ].concat(args) ) :
480                         options;
481
482                 if ( isMethodCall ) {
483                         this.each(function() {
484                                 var methodValue,
485                                         instance = $.data( this, fullName );
486                                 if ( !instance ) {
487                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
488                                                 "attempted to call method '" + options + "'" );
489                                 }
490                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492                                 }
493                                 methodValue = instance[ options ].apply( instance, args );
494                                 if ( methodValue !== instance && methodValue !== undefined ) {
495                                         returnValue = methodValue && methodValue.jquery ?
496                                                 returnValue.pushStack( methodValue.get() ) :
497                                                 methodValue;
498                                         return false;
499                                 }
500                         });
501                 } else {
502                         this.each(function() {
503                                 var instance = $.data( this, fullName );
504                                 if ( instance ) {
505                                         instance.option( options || {} )._init();
506                                 } else {
507                                         $.data( this, fullName, new object( options, this ) );
508                                 }
509                         });
510                 }
511
512                 return returnValue;
513         };
514 };
515
516 $.Widget = function( /* options, element */ ) {};
517 $.Widget._childConstructors = [];
518
519 $.Widget.prototype = {
520         widgetName: "widget",
521         widgetEventPrefix: "",
522         defaultElement: "<div>",
523         options: {
524                 disabled: false,
525
526                 // callbacks
527                 create: null
528         },
529         _createWidget: function( options, element ) {
530                 element = $( element || this.defaultElement || this )[ 0 ];
531                 this.element = $( element );
532                 this.uuid = uuid++;
533                 this.eventNamespace = "." + this.widgetName + this.uuid;
534                 this.options = $.widget.extend( {},
535                         this.options,
536                         this._getCreateOptions(),
537                         options );
538
539                 this.bindings = $();
540                 this.hoverable = $();
541                 this.focusable = $();
542
543                 if ( element !== this ) {
544                         $.data( element, this.widgetFullName, this );
545                         this._on( true, this.element, {
546                                 remove: function( event ) {
547                                         if ( event.target === element ) {
548                                                 this.destroy();
549                                         }
550                                 }
551                         });
552                         this.document = $( element.style ?
553                                 // element within the document
554                                 element.ownerDocument :
555                                 // element is window or document
556                                 element.document || element );
557                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558                 }
559
560                 this._create();
561                 this._trigger( "create", null, this._getCreateEventData() );
562                 this._init();
563         },
564         _getCreateOptions: $.noop,
565         _getCreateEventData: $.noop,
566         _create: $.noop,
567         _init: $.noop,
568
569         destroy: function() {
570                 this._destroy();
571                 // we can probably remove the unbind calls in 2.0
572                 // all event bindings should go through this._on()
573                 this.element
574                         .unbind( this.eventNamespace )
575                         // 1.9 BC for #7810
576                         // TODO remove dual storage
577                         .removeData( this.widgetName )
578                         .removeData( this.widgetFullName )
579                         // support: jquery <1.6.3
580                         // http://bugs.jquery.com/ticket/9413
581                         .removeData( $.camelCase( this.widgetFullName ) );
582                 this.widget()
583                         .unbind( this.eventNamespace )
584                         .removeAttr( "aria-disabled" )
585                         .removeClass(
586                                 this.widgetFullName + "-disabled " +
587                                 "ui-state-disabled" );
588
589                 // clean up events and states
590                 this.bindings.unbind( this.eventNamespace );
591                 this.hoverable.removeClass( "ui-state-hover" );
592                 this.focusable.removeClass( "ui-state-focus" );
593         },
594         _destroy: $.noop,
595
596         widget: function() {
597                 return this.element;
598         },
599
600         option: function( key, value ) {
601                 var options = key,
602                         parts,
603                         curOption,
604                         i;
605
606                 if ( arguments.length === 0 ) {
607                         // don't return a reference to the internal hash
608                         return $.widget.extend( {}, this.options );
609                 }
610
611                 if ( typeof key === "string" ) {
612                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613                         options = {};
614                         parts = key.split( "." );
615                         key = parts.shift();
616                         if ( parts.length ) {
617                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618                                 for ( i = 0; i < parts.length - 1; i++ ) {
619                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620                                         curOption = curOption[ parts[ i ] ];
621                                 }
622                                 key = parts.pop();
623                                 if ( value === undefined ) {
624                                         return curOption[ key ] === undefined ? null : curOption[ key ];
625                                 }
626                                 curOption[ key ] = value;
627                         } else {
628                                 if ( value === undefined ) {
629                                         return this.options[ key ] === undefined ? null : this.options[ key ];
630                                 }
631                                 options[ key ] = value;
632                         }
633                 }
634
635                 this._setOptions( options );
636
637                 return this;
638         },
639         _setOptions: function( options ) {
640                 var key;
641
642                 for ( key in options ) {
643                         this._setOption( key, options[ key ] );
644                 }
645
646                 return this;
647         },
648         _setOption: function( key, value ) {
649                 this.options[ key ] = value;
650
651                 if ( key === "disabled" ) {
652                         this.widget()
653                                 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654                                 .attr( "aria-disabled", value );
655                         this.hoverable.removeClass( "ui-state-hover" );
656                         this.focusable.removeClass( "ui-state-focus" );
657                 }
658
659                 return this;
660         },
661
662         enable: function() {
663                 return this._setOption( "disabled", false );
664         },
665         disable: function() {
666                 return this._setOption( "disabled", true );
667         },
668
669         _on: function( suppressDisabledCheck, element, handlers ) {
670                 var delegateElement,
671                         instance = this;
672
673                 // no suppressDisabledCheck flag, shuffle arguments
674                 if ( typeof suppressDisabledCheck !== "boolean" ) {
675                         handlers = element;
676                         element = suppressDisabledCheck;
677                         suppressDisabledCheck = false;
678                 }
679
680                 // no element argument, shuffle and use this.element
681                 if ( !handlers ) {
682                         handlers = element;
683                         element = this.element;
684                         delegateElement = this.widget();
685                 } else {
686                         // accept selectors, DOM elements
687                         element = delegateElement = $( element );
688                         this.bindings = this.bindings.add( element );
689                 }
690
691                 $.each( handlers, function( event, handler ) {
692                         function handlerProxy() {
693                                 // allow widgets to customize the disabled handling
694                                 // - disabled as an array instead of boolean
695                                 // - disabled class as method for disabling individual parts
696                                 if ( !suppressDisabledCheck &&
697                                                 ( instance.options.disabled === true ||
698                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
699                                         return;
700                                 }
701                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
702                                         .apply( instance, arguments );
703                         }
704
705                         // copy the guid so direct unbinding works
706                         if ( typeof handler !== "string" ) {
707                                 handlerProxy.guid = handler.guid =
708                                         handler.guid || handlerProxy.guid || $.guid++;
709                         }
710
711                         var match = event.match( /^(\w+)\s*(.*)$/ ),
712                                 eventName = match[1] + instance.eventNamespace,
713                                 selector = match[2];
714                         if ( selector ) {
715                                 delegateElement.delegate( selector, eventName, handlerProxy );
716                         } else {
717                                 element.bind( eventName, handlerProxy );
718                         }
719                 });
720         },
721
722         _off: function( element, eventName ) {
723                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724                 element.unbind( eventName ).undelegate( eventName );
725         },
726
727         _delay: function( handler, delay ) {
728                 function handlerProxy() {
729                         return ( typeof handler === "string" ? instance[ handler ] : handler )
730                                 .apply( instance, arguments );
731                 }
732                 var instance = this;
733                 return setTimeout( handlerProxy, delay || 0 );
734         },
735
736         _hoverable: function( element ) {
737                 this.hoverable = this.hoverable.add( element );
738                 this._on( element, {
739                         mouseenter: function( event ) {
740                                 $( event.currentTarget ).addClass( "ui-state-hover" );
741                         },
742                         mouseleave: function( event ) {
743                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
744                         }
745                 });
746         },
747
748         _focusable: function( element ) {
749                 this.focusable = this.focusable.add( element );
750                 this._on( element, {
751                         focusin: function( event ) {
752                                 $( event.currentTarget ).addClass( "ui-state-focus" );
753                         },
754                         focusout: function( event ) {
755                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
756                         }
757                 });
758         },
759
760         _trigger: function( type, event, data ) {
761                 var prop, orig,
762                         callback = this.options[ type ];
763
764                 data = data || {};
765                 event = $.Event( event );
766                 event.type = ( type === this.widgetEventPrefix ?
767                         type :
768                         this.widgetEventPrefix + type ).toLowerCase();
769                 // the original event may come from any element
770                 // so we need to reset the target on the new event
771                 event.target = this.element[ 0 ];
772
773                 // copy original event properties over to the new event
774                 orig = event.originalEvent;
775                 if ( orig ) {
776                         for ( prop in orig ) {
777                                 if ( !( prop in event ) ) {
778                                         event[ prop ] = orig[ prop ];
779                                 }
780                         }
781                 }
782
783                 this.element.trigger( event, data );
784                 return !( $.isFunction( callback ) &&
785                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786                         event.isDefaultPrevented() );
787         }
788 };
789
790 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792                 if ( typeof options === "string" ) {
793                         options = { effect: options };
794                 }
795                 var hasOptions,
796                         effectName = !options ?
797                                 method :
798                                 options === true || typeof options === "number" ?
799                                         defaultEffect :
800                                         options.effect || defaultEffect;
801                 options = options || {};
802                 if ( typeof options === "number" ) {
803                         options = { duration: options };
804                 }
805                 hasOptions = !$.isEmptyObject( options );
806                 options.complete = callback;
807                 if ( options.delay ) {
808                         element.delay( options.delay );
809                 }
810                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811                         element[ method ]( options );
812                 } else if ( effectName !== method && element[ effectName ] ) {
813                         element[ effectName ]( options.duration, options.easing, callback );
814                 } else {
815                         element.queue(function( next ) {
816                                 $( this )[ method ]();
817                                 if ( callback ) {
818                                         callback.call( element[ 0 ] );
819                                 }
820                                 next();
821                         });
822                 }
823         };
824 });
825
826 })( jQuery );
827 (function( $, undefined ) {
828
829 var mouseHandled = false;
830 $( document ).mouseup( function() {
831         mouseHandled = false;
832 });
833
834 $.widget("ui.mouse", {
835         version: "1.10.3",
836         options: {
837                 cancel: "input,textarea,button,select,option",
838                 distance: 1,
839                 delay: 0
840         },
841         _mouseInit: function() {
842                 var that = this;
843
844                 this.element
845                         .bind("mousedown."+this.widgetName, function(event) {
846                                 return that._mouseDown(event);
847                         })
848                         .bind("click."+this.widgetName, function(event) {
849                                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
850                                         $.removeData(event.target, that.widgetName + ".preventClickEvent");
851                                         event.stopImmediatePropagation();
852                                         return false;
853                                 }
854                         });
855
856                 this.started = false;
857         },
858
859         // TODO: make sure destroying one instance of mouse doesn't mess with
860         // other instances of mouse
861         _mouseDestroy: function() {
862                 this.element.unbind("."+this.widgetName);
863                 if ( this._mouseMoveDelegate ) {
864                         $(document)
865                                 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
866                                 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
867                 }
868         },
869
870         _mouseDown: function(event) {
871                 // don't let more than one widget handle mouseStart
872                 if( mouseHandled ) { return; }
873
874                 // we may have missed mouseup (out of window)
875                 (this._mouseStarted && this._mouseUp(event));
876
877                 this._mouseDownEvent = event;
878
879                 var that = this,
880                         btnIsLeft = (event.which === 1),
881                         // event.target.nodeName works around a bug in IE 8 with
882                         // disabled inputs (#7620)
883                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
884                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
885                         return true;
886                 }
887
888                 this.mouseDelayMet = !this.options.delay;
889                 if (!this.mouseDelayMet) {
890                         this._mouseDelayTimer = setTimeout(function() {
891                                 that.mouseDelayMet = true;
892                         }, this.options.delay);
893                 }
894
895                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
896                         this._mouseStarted = (this._mouseStart(event) !== false);
897                         if (!this._mouseStarted) {
898                                 event.preventDefault();
899                                 return true;
900                         }
901                 }
902
903                 // Click event may never have fired (Gecko & Opera)
904                 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
905                         $.removeData(event.target, this.widgetName + ".preventClickEvent");
906                 }
907
908                 // these delegates are required to keep context
909                 this._mouseMoveDelegate = function(event) {
910                         return that._mouseMove(event);
911                 };
912                 this._mouseUpDelegate = function(event) {
913                         return that._mouseUp(event);
914                 };
915                 $(document)
916                         .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
917                         .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
918
919                 event.preventDefault();
920
921                 mouseHandled = true;
922                 return true;
923         },
924
925         _mouseMove: function(event) {
926                 // IE mouseup check - mouseup happened when mouse was out of window
927                 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
928                         return this._mouseUp(event);
929                 }
930
931                 if (this._mouseStarted) {
932                         this._mouseDrag(event);
933                         return event.preventDefault();
934                 }
935
936                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
937                         this._mouseStarted =
938                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
939                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
940                 }
941
942                 return !this._mouseStarted;
943         },
944
945         _mouseUp: function(event) {
946                 $(document)
947                         .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
948                         .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
949
950                 if (this._mouseStarted) {
951                         this._mouseStarted = false;
952
953                         if (event.target === this._mouseDownEvent.target) {
954                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
955                         }
956
957                         this._mouseStop(event);
958                 }
959
960                 return false;
961         },
962
963         _mouseDistanceMet: function(event) {
964                 return (Math.max(
965                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
966                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
967                         ) >= this.options.distance
968                 );
969         },
970
971         _mouseDelayMet: function(/* event */) {
972                 return this.mouseDelayMet;
973         },
974
975         // These are placeholder methods, to be overriden by extending plugin
976         _mouseStart: function(/* event */) {},
977         _mouseDrag: function(/* event */) {},
978         _mouseStop: function(/* event */) {},
979         _mouseCapture: function(/* event */) { return true; }
980 });
981
982 })(jQuery);
983 (function( $, undefined ) {
984
985 $.ui = $.ui || {};
986
987 var cachedScrollbarWidth,
988         max = Math.max,
989         abs = Math.abs,
990         round = Math.round,
991         rhorizontal = /left|center|right/,
992         rvertical = /top|center|bottom/,
993         roffset = /[\+\-]\d+(\.[\d]+)?%?/,
994         rposition = /^\w+/,
995         rpercent = /%$/,
996         _position = $.fn.position;
997
998 function getOffsets( offsets, width, height ) {
999         return [
1000                 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1001                 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1002         ];
1003 }
1004
1005 function parseCss( element, property ) {
1006         return parseInt( $.css( element, property ), 10 ) || 0;
1007 }
1008
1009 function getDimensions( elem ) {
1010         var raw = elem[0];
1011         if ( raw.nodeType === 9 ) {
1012                 return {
1013                         width: elem.width(),
1014                         height: elem.height(),
1015                         offset: { top: 0, left: 0 }
1016                 };
1017         }
1018         if ( $.isWindow( raw ) ) {
1019                 return {
1020                         width: elem.width(),
1021                         height: elem.height(),
1022                         offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1023                 };
1024         }
1025         if ( raw.preventDefault ) {
1026                 return {
1027                         width: 0,
1028                         height: 0,
1029                         offset: { top: raw.pageY, left: raw.pageX }
1030                 };
1031         }
1032         return {
1033                 width: elem.outerWidth(),
1034                 height: elem.outerHeight(),
1035                 offset: elem.offset()
1036         };
1037 }
1038
1039 $.position = {
1040         scrollbarWidth: function() {
1041                 if ( cachedScrollbarWidth !== undefined ) {
1042                         return cachedScrollbarWidth;
1043                 }
1044                 var w1, w2,
1045                         div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1046                         innerDiv = div.children()[0];
1047
1048                 $( "body" ).append( div );
1049                 w1 = innerDiv.offsetWidth;
1050                 div.css( "overflow", "scroll" );
1051
1052                 w2 = innerDiv.offsetWidth;
1053
1054                 if ( w1 === w2 ) {
1055                         w2 = div[0].clientWidth;
1056                 }
1057
1058                 div.remove();
1059
1060                 return (cachedScrollbarWidth = w1 - w2);
1061         },
1062         getScrollInfo: function( within ) {
1063                 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
1064                         overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
1065                         hasOverflowX = overflowX === "scroll" ||
1066                                 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1067                         hasOverflowY = overflowY === "scroll" ||
1068                                 ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1069                 return {
1070                         width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1071                         height: hasOverflowX ? $.position.scrollbarWidth() : 0
1072                 };
1073         },
1074         getWithinInfo: function( element ) {
1075                 var withinElement = $( element || window ),
1076                         isWindow = $.isWindow( withinElement[0] );
1077                 return {
1078                         element: withinElement,
1079                         isWindow: isWindow,
1080                         offset: withinElement.offset() || { left: 0, top: 0 },
1081                         scrollLeft: withinElement.scrollLeft(),
1082                         scrollTop: withinElement.scrollTop(),
1083                         width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1084                         height: isWindow ? withinElement.height() : withinElement.outerHeight()
1085                 };
1086         }
1087 };
1088
1089 $.fn.position = function( options ) {
1090         if ( !options || !options.of ) {
1091                 return _position.apply( this, arguments );
1092         }
1093
1094         // make a copy, we don't want to modify arguments
1095         options = $.extend( {}, options );
1096
1097         var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1098                 target = $( options.of ),
1099                 within = $.position.getWithinInfo( options.within ),
1100                 scrollInfo = $.position.getScrollInfo( within ),
1101                 collision = ( options.collision || "flip" ).split( " " ),
1102                 offsets = {};
1103
1104         dimensions = getDimensions( target );
1105         if ( target[0].preventDefault ) {
1106                 // force left top to allow flipping
1107                 options.at = "left top";
1108         }
1109         targetWidth = dimensions.width;
1110         targetHeight = dimensions.height;
1111         targetOffset = dimensions.offset;
1112         // clone to reuse original targetOffset later
1113         basePosition = $.extend( {}, targetOffset );
1114
1115         // force my and at to have valid horizontal and vertical positions
1116         // if a value is missing or invalid, it will be converted to center
1117         $.each( [ "my", "at" ], function() {
1118                 var pos = ( options[ this ] || "" ).split( " " ),
1119                         horizontalOffset,
1120                         verticalOffset;
1121
1122                 if ( pos.length === 1) {
1123                         pos = rhorizontal.test( pos[ 0 ] ) ?
1124                                 pos.concat( [ "center" ] ) :
1125                                 rvertical.test( pos[ 0 ] ) ?
1126                                         [ "center" ].concat( pos ) :
1127                                         [ "center", "center" ];
1128                 }
1129                 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1130                 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1131
1132                 // calculate offsets
1133                 horizontalOffset = roffset.exec( pos[ 0 ] );
1134                 verticalOffset = roffset.exec( pos[ 1 ] );
1135                 offsets[ this ] = [
1136                         horizontalOffset ? horizontalOffset[ 0 ] : 0,
1137                         verticalOffset ? verticalOffset[ 0 ] : 0
1138                 ];
1139
1140                 // reduce to just the positions without the offsets
1141                 options[ this ] = [
1142                         rposition.exec( pos[ 0 ] )[ 0 ],
1143                         rposition.exec( pos[ 1 ] )[ 0 ]
1144                 ];
1145         });
1146
1147         // normalize collision option
1148         if ( collision.length === 1 ) {
1149                 collision[ 1 ] = collision[ 0 ];
1150         }
1151
1152         if ( options.at[ 0 ] === "right" ) {
1153                 basePosition.left += targetWidth;
1154         } else if ( options.at[ 0 ] === "center" ) {
1155                 basePosition.left += targetWidth / 2;
1156         }
1157
1158         if ( options.at[ 1 ] === "bottom" ) {
1159                 basePosition.top += targetHeight;
1160         } else if ( options.at[ 1 ] === "center" ) {
1161                 basePosition.top += targetHeight / 2;
1162         }
1163
1164         atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1165         basePosition.left += atOffset[ 0 ];
1166         basePosition.top += atOffset[ 1 ];
1167
1168         return this.each(function() {
1169                 var collisionPosition, using,
1170                         elem = $( this ),
1171                         elemWidth = elem.outerWidth(),
1172                         elemHeight = elem.outerHeight(),
1173                         marginLeft = parseCss( this, "marginLeft" ),
1174                         marginTop = parseCss( this, "marginTop" ),
1175                         collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1176                         collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1177                         position = $.extend( {}, basePosition ),
1178                         myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1179
1180                 if ( options.my[ 0 ] === "right" ) {
1181                         position.left -= elemWidth;
1182                 } else if ( options.my[ 0 ] === "center" ) {
1183                         position.left -= elemWidth / 2;
1184                 }
1185
1186                 if ( options.my[ 1 ] === "bottom" ) {
1187                         position.top -= elemHeight;
1188                 } else if ( options.my[ 1 ] === "center" ) {
1189                         position.top -= elemHeight / 2;
1190                 }
1191
1192                 position.left += myOffset[ 0 ];
1193                 position.top += myOffset[ 1 ];
1194
1195                 // if the browser doesn't support fractions, then round for consistent results
1196                 if ( !$.support.offsetFractions ) {
1197                         position.left = round( position.left );
1198                         position.top = round( position.top );
1199                 }
1200
1201                 collisionPosition = {
1202                         marginLeft: marginLeft,
1203                         marginTop: marginTop
1204                 };
1205
1206                 $.each( [ "left", "top" ], function( i, dir ) {
1207                         if ( $.ui.position[ collision[ i ] ] ) {
1208                                 $.ui.position[ collision[ i ] ][ dir ]( position, {
1209                                         targetWidth: targetWidth,
1210                                         targetHeight: targetHeight,
1211                                         elemWidth: elemWidth,
1212                                         elemHeight: elemHeight,
1213                                         collisionPosition: collisionPosition,
1214                                         collisionWidth: collisionWidth,
1215                                         collisionHeight: collisionHeight,
1216                                         offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1217                                         my: options.my,
1218                                         at: options.at,
1219                                         within: within,
1220                                         elem : elem
1221                                 });
1222                         }
1223                 });
1224
1225                 if ( options.using ) {
1226                         // adds feedback as second argument to using callback, if present
1227                         using = function( props ) {
1228                                 var left = targetOffset.left - position.left,
1229                                         right = left + targetWidth - elemWidth,
1230                                         top = targetOffset.top - position.top,
1231                                         bottom = top + targetHeight - elemHeight,
1232                                         feedback = {
1233                                                 target: {
1234                                                         element: target,
1235                                                         left: targetOffset.left,
1236                                                         top: targetOffset.top,
1237                                                         width: targetWidth,
1238                                                         height: targetHeight
1239                                                 },
1240                                                 element: {
1241                                                         element: elem,
1242                                                         left: position.left,
1243                                                         top: position.top,
1244                                                         width: elemWidth,
1245                                                         height: elemHeight
1246                                                 },
1247                                                 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1248                                                 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1249                                         };
1250                                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1251                                         feedback.horizontal = "center";
1252                                 }
1253                                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1254                                         feedback.vertical = "middle";
1255                                 }
1256                                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1257                                         feedback.important = "horizontal";
1258                                 } else {
1259                                         feedback.important = "vertical";
1260                                 }
1261                                 options.using.call( this, props, feedback );
1262                         };
1263                 }
1264
1265                 elem.offset( $.extend( position, { using: using } ) );
1266         });
1267 };
1268
1269 $.ui.position = {
1270         fit: {
1271                 left: function( position, data ) {
1272                         var within = data.within,
1273                                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1274                                 outerWidth = within.width,
1275                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1276                                 overLeft = withinOffset - collisionPosLeft,
1277                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1278                                 newOverRight;
1279
1280                         // element is wider than within
1281                         if ( data.collisionWidth > outerWidth ) {
1282                                 // element is initially over the left side of within
1283                                 if ( overLeft > 0 && overRight <= 0 ) {
1284                                         newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1285                                         position.left += overLeft - newOverRight;
1286                                 // element is initially over right side of within
1287                                 } else if ( overRight > 0 && overLeft <= 0 ) {
1288                                         position.left = withinOffset;
1289                                 // element is initially over both left and right sides of within
1290                                 } else {
1291                                         if ( overLeft > overRight ) {
1292                                                 position.left = withinOffset + outerWidth - data.collisionWidth;
1293                                         } else {
1294                                                 position.left = withinOffset;
1295                                         }
1296                                 }
1297                         // too far left -> align with left edge
1298                         } else if ( overLeft > 0 ) {
1299                                 position.left += overLeft;
1300                         // too far right -> align with right edge
1301                         } else if ( overRight > 0 ) {
1302                                 position.left -= overRight;
1303                         // adjust based on position and margin
1304                         } else {
1305                                 position.left = max( position.left - collisionPosLeft, position.left );
1306                         }
1307                 },
1308                 top: function( position, data ) {
1309                         var within = data.within,
1310                                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1311                                 outerHeight = data.within.height,
1312                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1313                                 overTop = withinOffset - collisionPosTop,
1314                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1315                                 newOverBottom;
1316
1317                         // element is taller than within
1318                         if ( data.collisionHeight > outerHeight ) {
1319                                 // element is initially over the top of within
1320                                 if ( overTop > 0 && overBottom <= 0 ) {
1321                                         newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1322                                         position.top += overTop - newOverBottom;
1323                                 // element is initially over bottom of within
1324                                 } else if ( overBottom > 0 && overTop <= 0 ) {
1325                                         position.top = withinOffset;
1326                                 // element is initially over both top and bottom of within
1327                                 } else {
1328                                         if ( overTop > overBottom ) {
1329                                                 position.top = withinOffset + outerHeight - data.collisionHeight;
1330                                         } else {
1331                                                 position.top = withinOffset;
1332                                         }
1333                                 }
1334                         // too far up -> align with top
1335                         } else if ( overTop > 0 ) {
1336                                 position.top += overTop;
1337                         // too far down -> align with bottom edge
1338                         } else if ( overBottom > 0 ) {
1339                                 position.top -= overBottom;
1340                         // adjust based on position and margin
1341                         } else {
1342                                 position.top = max( position.top - collisionPosTop, position.top );
1343                         }
1344                 }
1345         },
1346         flip: {
1347                 left: function( position, data ) {
1348                         var within = data.within,
1349                                 withinOffset = within.offset.left + within.scrollLeft,
1350                                 outerWidth = within.width,
1351                                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1352                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1353                                 overLeft = collisionPosLeft - offsetLeft,
1354                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1355                                 myOffset = data.my[ 0 ] === "left" ?
1356                                         -data.elemWidth :
1357                                         data.my[ 0 ] === "right" ?
1358                                                 data.elemWidth :
1359                                                 0,
1360                                 atOffset = data.at[ 0 ] === "left" ?
1361                                         data.targetWidth :
1362                                         data.at[ 0 ] === "right" ?
1363                                                 -data.targetWidth :
1364                                                 0,
1365                                 offset = -2 * data.offset[ 0 ],
1366                                 newOverRight,
1367                                 newOverLeft;
1368
1369                         if ( overLeft < 0 ) {
1370                                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1371                                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1372                                         position.left += myOffset + atOffset + offset;
1373                                 }
1374                         }
1375                         else if ( overRight > 0 ) {
1376                                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1377                                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1378                                         position.left += myOffset + atOffset + offset;
1379                                 }
1380                         }
1381                 },
1382                 top: function( position, data ) {
1383                         var within = data.within,
1384                                 withinOffset = within.offset.top + within.scrollTop,
1385                                 outerHeight = within.height,
1386                                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1387                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1388                                 overTop = collisionPosTop - offsetTop,
1389                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1390                                 top = data.my[ 1 ] === "top",
1391                                 myOffset = top ?
1392                                         -data.elemHeight :
1393                                         data.my[ 1 ] === "bottom" ?
1394                                                 data.elemHeight :
1395                                                 0,
1396                                 atOffset = data.at[ 1 ] === "top" ?
1397                                         data.targetHeight :
1398                                         data.at[ 1 ] === "bottom" ?
1399                                                 -data.targetHeight :
1400                                                 0,
1401                                 offset = -2 * data.offset[ 1 ],
1402                                 newOverTop,
1403                                 newOverBottom;
1404                         if ( overTop < 0 ) {
1405                                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1406                                 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1407                                         position.top += myOffset + atOffset + offset;
1408                                 }
1409                         }
1410                         else if ( overBottom > 0 ) {
1411                                 newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1412                                 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1413                                         position.top += myOffset + atOffset + offset;
1414                                 }
1415                         }
1416                 }
1417         },
1418         flipfit: {
1419                 left: function() {
1420                         $.ui.position.flip.left.apply( this, arguments );
1421                         $.ui.position.fit.left.apply( this, arguments );
1422                 },
1423                 top: function() {
1424                         $.ui.position.flip.top.apply( this, arguments );
1425                         $.ui.position.fit.top.apply( this, arguments );
1426                 }
1427         }
1428 };
1429
1430 // fraction support test
1431 (function () {
1432         var testElement, testElementParent, testElementStyle, offsetLeft, i,
1433                 body = document.getElementsByTagName( "body" )[ 0 ],
1434                 div = document.createElement( "div" );
1435
1436         //Create a "fake body" for testing based on method used in jQuery.support
1437         testElement = document.createElement( body ? "div" : "body" );
1438         testElementStyle = {
1439                 visibility: "hidden",
1440                 width: 0,
1441                 height: 0,
1442                 border: 0,
1443                 margin: 0,
1444                 background: "none"
1445         };
1446         if ( body ) {
1447                 $.extend( testElementStyle, {
1448                         position: "absolute",
1449                         left: "-1000px",
1450                         top: "-1000px"
1451                 });
1452         }
1453         for ( i in testElementStyle ) {
1454                 testElement.style[ i ] = testElementStyle[ i ];
1455         }
1456         testElement.appendChild( div );
1457         testElementParent = body || document.documentElement;
1458         testElementParent.insertBefore( testElement, testElementParent.firstChild );
1459
1460         div.style.cssText = "position: absolute; left: 10.7432222px;";
1461
1462         offsetLeft = $( div ).offset().left;
1463         $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1464
1465         testElement.innerHTML = "";
1466         testElementParent.removeChild( testElement );
1467 })();
1468
1469 }( jQuery ) );
1470 (function( $, undefined ) {
1471
1472 $.widget("ui.draggable", $.ui.mouse, {
1473         version: "1.10.3",
1474         widgetEventPrefix: "drag",
1475         options: {
1476                 addClasses: true,
1477                 appendTo: "parent",
1478                 axis: false,
1479                 connectToSortable: false,
1480                 containment: false,
1481                 cursor: "auto",
1482                 cursorAt: false,
1483                 grid: false,
1484                 handle: false,
1485                 helper: "original",
1486                 iframeFix: false,
1487                 opacity: false,
1488                 refreshPositions: false,
1489                 revert: false,
1490                 revertDuration: 500,
1491                 scope: "default",
1492                 scroll: true,
1493                 scrollSensitivity: 20,
1494                 scrollSpeed: 20,
1495                 snap: false,
1496                 snapMode: "both",
1497                 snapTolerance: 20,
1498                 stack: false,
1499                 zIndex: false,
1500
1501                 // callbacks
1502                 drag: null,
1503                 start: null,
1504                 stop: null
1505         },
1506         _create: function() {
1507
1508                 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1509                         this.element[0].style.position = "relative";
1510                 }
1511                 if (this.options.addClasses){
1512                         this.element.addClass("ui-draggable");
1513                 }
1514                 if (this.options.disabled){
1515                         this.element.addClass("ui-draggable-disabled");
1516                 }
1517
1518                 this._mouseInit();
1519
1520         },
1521
1522         _destroy: function() {
1523                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1524                 this._mouseDestroy();
1525         },
1526
1527         _mouseCapture: function(event) {
1528
1529                 var o = this.options;
1530
1531                 // among others, prevent a drag on a resizable-handle
1532                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1533                         return false;
1534                 }
1535
1536                 //Quit if we're not on a valid handle
1537                 this.handle = this._getHandle(event);
1538                 if (!this.handle) {
1539                         return false;
1540                 }
1541
1542                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1543                         $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1544                         .css({
1545                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1546                                 position: "absolute", opacity: "0.001", zIndex: 1000
1547                         })
1548                         .css($(this).offset())
1549                         .appendTo("body");
1550                 });
1551
1552                 return true;
1553
1554         },
1555
1556         _mouseStart: function(event) {
1557
1558                 var o = this.options;
1559
1560                 //Create and append the visible helper
1561                 this.helper = this._createHelper(event);
1562
1563                 this.helper.addClass("ui-draggable-dragging");
1564
1565                 //Cache the helper size
1566                 this._cacheHelperProportions();
1567
1568                 //If ddmanager is used for droppables, set the global draggable
1569                 if($.ui.ddmanager) {
1570                         $.ui.ddmanager.current = this;
1571                 }
1572
1573                 /*
1574                  * - Position generation -
1575                  * This block generates everything position related - it's the core of draggables.
1576                  */
1577
1578                 //Cache the margins of the original element
1579                 this._cacheMargins();
1580
1581                 //Store the helper's css position
1582                 this.cssPosition = this.helper.css( "position" );
1583                 this.scrollParent = this.helper.scrollParent();
1584                 this.offsetParent = this.helper.offsetParent();
1585                 this.offsetParentCssPosition = this.offsetParent.css( "position" );
1586
1587                 //The element's absolute position on the page minus margins
1588                 this.offset = this.positionAbs = this.element.offset();
1589                 this.offset = {
1590                         top: this.offset.top - this.margins.top,
1591                         left: this.offset.left - this.margins.left
1592                 };
1593
1594                 //Reset scroll cache
1595                 this.offset.scroll = false;
1596
1597                 $.extend(this.offset, {
1598                         click: { //Where the click happened, relative to the element
1599                                 left: event.pageX - this.offset.left,
1600                                 top: event.pageY - this.offset.top
1601                         },
1602                         parent: this._getParentOffset(),
1603                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1604                 });
1605
1606                 //Generate the original position
1607                 this.originalPosition = this.position = this._generatePosition(event);
1608                 this.originalPageX = event.pageX;
1609                 this.originalPageY = event.pageY;
1610
1611                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1612                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1613
1614                 //Set a containment if given in the options
1615                 this._setContainment();
1616
1617                 //Trigger event + callbacks
1618                 if(this._trigger("start", event) === false) {
1619                         this._clear();
1620                         return false;
1621                 }
1622
1623                 //Recache the helper size
1624                 this._cacheHelperProportions();
1625
1626                 //Prepare the droppable offsets
1627                 if ($.ui.ddmanager && !o.dropBehaviour) {
1628                         $.ui.ddmanager.prepareOffsets(this, event);
1629                 }
1630
1631
1632                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1633
1634                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1635                 if ( $.ui.ddmanager ) {
1636                         $.ui.ddmanager.dragStart(this, event);
1637                 }
1638
1639                 return true;
1640         },
1641
1642         _mouseDrag: function(event, noPropagation) {
1643                 // reset any necessary cached properties (see #5009)
1644                 if ( this.offsetParentCssPosition === "fixed" ) {
1645                         this.offset.parent = this._getParentOffset();
1646                 }
1647
1648                 //Compute the helpers position
1649                 this.position = this._generatePosition(event);
1650                 this.positionAbs = this._convertPositionTo("absolute");
1651
1652                 //Call plugins and callbacks and use the resulting position if something is returned
1653                 if (!noPropagation) {
1654                         var ui = this._uiHash();
1655                         if(this._trigger("drag", event, ui) === false) {
1656                                 this._mouseUp({});
1657                                 return false;
1658                         }
1659                         this.position = ui.position;
1660                 }
1661
1662                 if(!this.options.axis || this.options.axis !== "y") {
1663                         this.helper[0].style.left = this.position.left+"px";
1664                 }
1665                 if(!this.options.axis || this.options.axis !== "x") {
1666                         this.helper[0].style.top = this.position.top+"px";
1667                 }
1668                 if($.ui.ddmanager) {
1669                         $.ui.ddmanager.drag(this, event);
1670                 }
1671
1672                 return false;
1673         },
1674
1675         _mouseStop: function(event) {
1676
1677                 //If we are using droppables, inform the manager about the drop
1678                 var that = this,
1679                         dropped = false;
1680                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1681                         dropped = $.ui.ddmanager.drop(this, event);
1682                 }
1683
1684                 //if a drop comes from outside (a sortable)
1685                 if(this.dropped) {
1686                         dropped = this.dropped;
1687                         this.dropped = false;
1688                 }
1689
1690                 //if the original element is no longer in the DOM don't bother to continue (see #8269)
1691                 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1692                         return false;
1693                 }
1694
1695                 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))) {
1696                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1697                                 if(that._trigger("stop", event) !== false) {
1698                                         that._clear();
1699                                 }
1700                         });
1701                 } else {
1702                         if(this._trigger("stop", event) !== false) {
1703                                 this._clear();
1704                         }
1705                 }
1706
1707                 return false;
1708         },
1709
1710         _mouseUp: function(event) {
1711                 //Remove frame helpers
1712                 $("div.ui-draggable-iframeFix").each(function() {
1713                         this.parentNode.removeChild(this);
1714                 });
1715
1716                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1717                 if( $.ui.ddmanager ) {
1718                         $.ui.ddmanager.dragStop(this, event);
1719                 }
1720
1721                 return $.ui.mouse.prototype._mouseUp.call(this, event);
1722         },
1723
1724         cancel: function() {
1725
1726                 if(this.helper.is(".ui-draggable-dragging")) {
1727                         this._mouseUp({});
1728                 } else {
1729                         this._clear();
1730                 }
1731
1732                 return this;
1733
1734         },
1735
1736         _getHandle: function(event) {
1737                 return this.options.handle ?
1738                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1739                         true;
1740         },
1741
1742         _createHelper: function(event) {
1743
1744                 var o = this.options,
1745                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1746
1747                 if(!helper.parents("body").length) {
1748                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1749                 }
1750
1751                 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1752                         helper.css("position", "absolute");
1753                 }
1754
1755                 return helper;
1756
1757         },
1758
1759         _adjustOffsetFromHelper: function(obj) {
1760                 if (typeof obj === "string") {
1761                         obj = obj.split(" ");
1762                 }
1763                 if ($.isArray(obj)) {
1764                         obj = {left: +obj[0], top: +obj[1] || 0};
1765                 }
1766                 if ("left" in obj) {
1767                         this.offset.click.left = obj.left + this.margins.left;
1768                 }
1769                 if ("right" in obj) {
1770                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1771                 }
1772                 if ("top" in obj) {
1773                         this.offset.click.top = obj.top + this.margins.top;
1774                 }
1775                 if ("bottom" in obj) {
1776                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1777                 }
1778         },
1779
1780         _getParentOffset: function() {
1781
1782                 //Get the offsetParent and cache its position
1783                 var po = this.offsetParent.offset();
1784
1785                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1786                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1787                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1788                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1789                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1790                         po.left += this.scrollParent.scrollLeft();
1791                         po.top += this.scrollParent.scrollTop();
1792                 }
1793
1794                 //This needs to be actually done for all browsers, since pageX/pageY includes this information
1795                 //Ugly IE fix
1796                 if((this.offsetParent[0] === document.body) ||
1797                         (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1798                         po = { top: 0, left: 0 };
1799                 }
1800
1801                 return {
1802                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1803                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1804                 };
1805
1806         },
1807
1808         _getRelativeOffset: function() {
1809
1810                 if(this.cssPosition === "relative") {
1811                         var p = this.element.position();
1812                         return {
1813                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1814                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1815                         };
1816                 } else {
1817                         return { top: 0, left: 0 };
1818                 }
1819
1820         },
1821
1822         _cacheMargins: function() {
1823                 this.margins = {
1824                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
1825                         top: (parseInt(this.element.css("marginTop"),10) || 0),
1826                         right: (parseInt(this.element.css("marginRight"),10) || 0),
1827                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1828                 };
1829         },
1830
1831         _cacheHelperProportions: function() {
1832                 this.helperProportions = {
1833                         width: this.helper.outerWidth(),
1834                         height: this.helper.outerHeight()
1835                 };
1836         },
1837
1838         _setContainment: function() {
1839
1840                 var over, c, ce,
1841                         o = this.options;
1842
1843                 if ( !o.containment ) {
1844                         this.containment = null;
1845                         return;
1846                 }
1847
1848                 if ( o.containment === "window" ) {
1849                         this.containment = [
1850                                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1851                                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1852                                 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1853                                 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1854                         ];
1855                         return;
1856                 }
1857
1858                 if ( o.containment === "document") {
1859                         this.containment = [
1860                                 0,
1861                                 0,
1862                                 $( document ).width() - this.helperProportions.width - this.margins.left,
1863                                 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1864                         ];
1865                         return;
1866                 }
1867
1868                 if ( o.containment.constructor === Array ) {
1869                         this.containment = o.containment;
1870                         return;
1871                 }
1872
1873                 if ( o.containment === "parent" ) {
1874                         o.containment = this.helper[ 0 ].parentNode;
1875                 }
1876
1877                 c = $( o.containment );
1878                 ce = c[ 0 ];
1879
1880                 if( !ce ) {
1881                         return;
1882                 }
1883
1884                 over = c.css( "overflow" ) !== "hidden";
1885
1886                 this.containment = [
1887                         ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1888                         ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1889                         ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
1890                         ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1891                 ];
1892                 this.relative_container = c;
1893         },
1894
1895         _convertPositionTo: function(d, pos) {
1896
1897                 if(!pos) {
1898                         pos = this.position;
1899                 }
1900
1901                 var mod = d === "absolute" ? 1 : -1,
1902                         scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1903
1904                 //Cache the scroll
1905                 if (!this.offset.scroll) {
1906                         this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1907                 }
1908
1909                 return {
1910                         top: (
1911                                 pos.top +                                                                                                                               // The absolute mouse position
1912                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1913                                 this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
1914                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1915                         ),
1916                         left: (
1917                                 pos.left +                                                                                                                              // The absolute mouse position
1918                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
1919                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
1920                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1921                         )
1922                 };
1923
1924         },
1925
1926         _generatePosition: function(event) {
1927
1928                 var containment, co, top, left,
1929                         o = this.options,
1930                         scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1931                         pageX = event.pageX,
1932                         pageY = event.pageY;
1933
1934                 //Cache the scroll
1935                 if (!this.offset.scroll) {
1936                         this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1937                 }
1938
1939                 /*
1940                  * - Position constraining -
1941                  * Constrain the position to a mix of grid, containment.
1942                  */
1943
1944                 // If we are not dragging yet, we won't check for options
1945                 if ( this.originalPosition ) {
1946                         if ( this.containment ) {
1947                                 if ( this.relative_container ){
1948                                         co = this.relative_container.offset();
1949                                         containment = [
1950                                                 this.containment[ 0 ] + co.left,
1951                                                 this.containment[ 1 ] + co.top,
1952                                                 this.containment[ 2 ] + co.left,
1953                                                 this.containment[ 3 ] + co.top
1954                                         ];
1955                                 }
1956                                 else {
1957                                         containment = this.containment;
1958                                 }
1959
1960                                 if(event.pageX - this.offset.click.left < containment[0]) {
1961                                         pageX = containment[0] + this.offset.click.left;
1962                                 }
1963                                 if(event.pageY - this.offset.click.top < containment[1]) {
1964                                         pageY = containment[1] + this.offset.click.top;
1965                                 }
1966                                 if(event.pageX - this.offset.click.left > containment[2]) {
1967                                         pageX = containment[2] + this.offset.click.left;
1968                                 }
1969                                 if(event.pageY - this.offset.click.top > containment[3]) {
1970                                         pageY = containment[3] + this.offset.click.top;
1971                                 }
1972                         }
1973
1974                         if(o.grid) {
1975                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1976                                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1977                                 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;
1978
1979                                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1980                                 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;
1981                         }
1982
1983                 }
1984
1985                 return {
1986                         top: (
1987                                 pageY -                                                                                                                                 // The absolute mouse position
1988                                 this.offset.click.top   -                                                                                               // Click offset (relative to the element)
1989                                 this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
1990                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
1991                                 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1992                         ),
1993                         left: (
1994                                 pageX -                                                                                                                                 // The absolute mouse position
1995                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
1996                                 this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
1997                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
1998                                 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
1999                         )
2000                 };
2001
2002         },
2003
2004         _clear: function() {
2005                 this.helper.removeClass("ui-draggable-dragging");
2006                 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2007                         this.helper.remove();
2008                 }
2009                 this.helper = null;
2010                 this.cancelHelperRemoval = false;
2011         },
2012
2013         // From now on bulk stuff - mainly helpers
2014
2015         _trigger: function(type, event, ui) {
2016                 ui = ui || this._uiHash();
2017                 $.ui.plugin.call(this, type, [event, ui]);
2018                 //The absolute position has to be recalculated after plugins
2019                 if(type === "drag") {
2020                         this.positionAbs = this._convertPositionTo("absolute");
2021                 }
2022                 return $.Widget.prototype._trigger.call(this, type, event, ui);
2023         },
2024
2025         plugins: {},
2026
2027         _uiHash: function() {
2028                 return {
2029                         helper: this.helper,
2030                         position: this.position,
2031                         originalPosition: this.originalPosition,
2032                         offset: this.positionAbs
2033                 };
2034         }
2035
2036 });
2037
2038 $.ui.plugin.add("draggable", "connectToSortable", {
2039         start: function(event, ui) {
2040
2041                 var inst = $(this).data("ui-draggable"), o = inst.options,
2042                         uiSortable = $.extend({}, ui, { item: inst.element });
2043                 inst.sortables = [];
2044                 $(o.connectToSortable).each(function() {
2045                         var sortable = $.data(this, "ui-sortable");
2046                         if (sortable && !sortable.options.disabled) {
2047                                 inst.sortables.push({
2048                                         instance: sortable,
2049                                         shouldRevert: sortable.options.revert
2050                                 });
2051                                 sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
2052                                 sortable._trigger("activate", event, uiSortable);
2053                         }
2054                 });
2055
2056         },
2057         stop: function(event, ui) {
2058
2059                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2060                 var inst = $(this).data("ui-draggable"),
2061                         uiSortable = $.extend({}, ui, { item: inst.element });
2062
2063                 $.each(inst.sortables, function() {
2064                         if(this.instance.isOver) {
2065
2066                                 this.instance.isOver = 0;
2067
2068                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2069                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2070
2071                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
2072                                 if(this.shouldRevert) {
2073                                         this.instance.options.revert = this.shouldRevert;
2074                                 }
2075
2076                                 //Trigger the stop of the sortable
2077                                 this.instance._mouseStop(event);
2078
2079                                 this.instance.options.helper = this.instance.options._helper;
2080
2081                                 //If the helper has been the original item, restore properties in the sortable
2082                                 if(inst.options.helper === "original") {
2083                                         this.instance.currentItem.css({ top: "auto", left: "auto" });
2084                                 }
2085
2086                         } else {
2087                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2088                                 this.instance._trigger("deactivate", event, uiSortable);
2089                         }
2090
2091                 });
2092
2093         },
2094         drag: function(event, ui) {
2095
2096                 var inst = $(this).data("ui-draggable"), that = this;
2097
2098                 $.each(inst.sortables, function() {
2099
2100                         var innermostIntersecting = false,
2101                                 thisSortable = this;
2102
2103                         //Copy over some variables to allow calling the sortable's native _intersectsWith
2104                         this.instance.positionAbs = inst.positionAbs;
2105                         this.instance.helperProportions = inst.helperProportions;
2106                         this.instance.offset.click = inst.offset.click;
2107
2108                         if(this.instance._intersectsWith(this.instance.containerCache)) {
2109                                 innermostIntersecting = true;
2110                                 $.each(inst.sortables, function () {
2111                                         this.instance.positionAbs = inst.positionAbs;
2112                                         this.instance.helperProportions = inst.helperProportions;
2113                                         this.instance.offset.click = inst.offset.click;
2114                                         if (this !== thisSortable &&
2115                                                 this.instance._intersectsWith(this.instance.containerCache) &&
2116                                                 $.contains(thisSortable.instance.element[0], this.instance.element[0])
2117                                         ) {
2118                                                 innermostIntersecting = false;
2119                                         }
2120                                         return innermostIntersecting;
2121                                 });
2122                         }
2123
2124
2125                         if(innermostIntersecting) {
2126                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2127                                 if(!this.instance.isOver) {
2128
2129                                         this.instance.isOver = 1;
2130                                         //Now we fake the start of dragging for the sortable instance,
2131                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2132                                         //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
2133                                         this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
2134                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2135                                         this.instance.options.helper = function() { return ui.helper[0]; };
2136
2137                                         event.target = this.instance.currentItem[0];
2138                                         this.instance._mouseCapture(event, true);
2139                                         this.instance._mouseStart(event, true, true);
2140
2141                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2142                                         this.instance.offset.click.top = inst.offset.click.top;
2143                                         this.instance.offset.click.left = inst.offset.click.left;
2144                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2145                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2146
2147                                         inst._trigger("toSortable", event);
2148                                         inst.dropped = this.instance.element; //draggable revert needs that
2149                                         //hack so receive/update callbacks work (mostly)
2150                                         inst.currentItem = inst.element;
2151                                         this.instance.fromOutside = inst;
2152
2153                                 }
2154
2155                                 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
2156                                 if(this.instance.currentItem) {
2157                                         this.instance._mouseDrag(event);
2158                                 }
2159
2160                         } else {
2161
2162                                 //If it doesn't intersect with the sortable, and it intersected before,
2163                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2164                                 if(this.instance.isOver) {
2165
2166                                         this.instance.isOver = 0;
2167                                         this.instance.cancelHelperRemoval = true;
2168
2169                                         //Prevent reverting on this forced stop
2170                                         this.instance.options.revert = false;
2171
2172                                         // The out event needs to be triggered independently
2173                                         this.instance._trigger("out", event, this.instance._uiHash(this.instance));
2174
2175                                         this.instance._mouseStop(event, true);
2176                                         this.instance.options.helper = this.instance.options._helper;
2177
2178                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2179                                         this.instance.currentItem.remove();
2180                                         if(this.instance.placeholder) {
2181                                                 this.instance.placeholder.remove();
2182                                         }
2183
2184                                         inst._trigger("fromSortable", event);
2185                                         inst.dropped = false; //draggable revert needs that
2186                                 }
2187
2188                         }
2189
2190                 });
2191
2192         }
2193 });
2194
2195 $.ui.plugin.add("draggable", "cursor", {
2196         start: function() {
2197                 var t = $("body"), o = $(this).data("ui-draggable").options;
2198                 if (t.css("cursor")) {
2199                         o._cursor = t.css("cursor");
2200                 }
2201                 t.css("cursor", o.cursor);
2202         },
2203         stop: function() {
2204                 var o = $(this).data("ui-draggable").options;
2205                 if (o._cursor) {
2206                         $("body").css("cursor", o._cursor);
2207                 }
2208         }
2209 });
2210
2211 $.ui.plugin.add("draggable", "opacity", {
2212         start: function(event, ui) {
2213                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
2214                 if(t.css("opacity")) {
2215                         o._opacity = t.css("opacity");
2216                 }
2217                 t.css("opacity", o.opacity);
2218         },
2219         stop: function(event, ui) {
2220                 var o = $(this).data("ui-draggable").options;
2221                 if(o._opacity) {
2222                         $(ui.helper).css("opacity", o._opacity);
2223                 }
2224         }
2225 });
2226
2227 $.ui.plugin.add("draggable", "scroll", {
2228         start: function() {
2229                 var i = $(this).data("ui-draggable");
2230                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
2231                         i.overflowOffset = i.scrollParent.offset();
2232                 }
2233         },
2234         drag: function( event ) {
2235
2236                 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
2237
2238                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
2239
2240                         if(!o.axis || o.axis !== "x") {
2241                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
2242                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2243                                 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
2244                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2245                                 }
2246                         }
2247
2248                         if(!o.axis || o.axis !== "y") {
2249                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
2250                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2251                                 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
2252                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2253                                 }
2254                         }
2255
2256                 } else {
2257
2258                         if(!o.axis || o.axis !== "x") {
2259                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2260                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2261                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2262                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2263                                 }
2264                         }
2265
2266                         if(!o.axis || o.axis !== "y") {
2267                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2268                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2269                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2270                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2271                                 }
2272                         }
2273
2274                 }
2275
2276                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2277                         $.ui.ddmanager.prepareOffsets(i, event);
2278                 }
2279
2280         }
2281 });
2282
2283 $.ui.plugin.add("draggable", "snap", {
2284         start: function() {
2285
2286                 var i = $(this).data("ui-draggable"),
2287                         o = i.options;
2288
2289                 i.snapElements = [];
2290
2291                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2292                         var $t = $(this),
2293                                 $o = $t.offset();
2294                         if(this !== i.element[0]) {
2295                                 i.snapElements.push({
2296                                         item: this,
2297                                         width: $t.outerWidth(), height: $t.outerHeight(),
2298                                         top: $o.top, left: $o.left
2299                                 });
2300                         }
2301                 });
2302
2303         },
2304         drag: function(event, ui) {
2305
2306                 var ts, bs, ls, rs, l, r, t, b, i, first,
2307                         inst = $(this).data("ui-draggable"),
2308                         o = inst.options,
2309                         d = o.snapTolerance,
2310                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2311                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2312
2313                 for (i = inst.snapElements.length - 1; i >= 0; i--){
2314
2315                         l = inst.snapElements[i].left;
2316                         r = l + inst.snapElements[i].width;
2317                         t = inst.snapElements[i].top;
2318                         b = t + inst.snapElements[i].height;
2319
2320                         if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2321                                 if(inst.snapElements[i].snapping) {
2322                                         (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2323                                 }
2324                                 inst.snapElements[i].snapping = false;
2325                                 continue;
2326                         }
2327
2328                         if(o.snapMode !== "inner") {
2329                                 ts = Math.abs(t - y2) <= d;
2330                                 bs = Math.abs(b - y1) <= d;
2331                                 ls = Math.abs(l - x2) <= d;
2332                                 rs = Math.abs(r - x1) <= d;
2333                                 if(ts) {
2334                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2335                                 }
2336                                 if(bs) {
2337                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2338                                 }
2339                                 if(ls) {
2340                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2341                                 }
2342                                 if(rs) {
2343                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2344                                 }
2345                         }
2346
2347                         first = (ts || bs || ls || rs);
2348
2349                         if(o.snapMode !== "outer") {
2350                                 ts = Math.abs(t - y1) <= d;
2351                                 bs = Math.abs(b - y2) <= d;
2352                                 ls = Math.abs(l - x1) <= d;
2353                                 rs = Math.abs(r - x2) <= d;
2354                                 if(ts) {
2355                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2356                                 }
2357                                 if(bs) {
2358                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2359                                 }
2360                                 if(ls) {
2361                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2362                                 }
2363                                 if(rs) {
2364                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2365                                 }
2366                         }
2367
2368                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2369                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2370                         }
2371                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2372
2373                 }
2374
2375         }
2376 });
2377
2378 $.ui.plugin.add("draggable", "stack", {
2379         start: function() {
2380                 var min,
2381                         o = this.data("ui-draggable").options,
2382                         group = $.makeArray($(o.stack)).sort(function(a,b) {
2383                                 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2384                         });
2385
2386                 if (!group.length) { return; }
2387
2388                 min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2389                 $(group).each(function(i) {
2390                         $(this).css("zIndex", min + i);
2391                 });
2392                 this.css("zIndex", (min + group.length));
2393         }
2394 });
2395
2396 $.ui.plugin.add("draggable", "zIndex", {
2397         start: function(event, ui) {
2398                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
2399                 if(t.css("zIndex")) {
2400                         o._zIndex = t.css("zIndex");
2401                 }
2402                 t.css("zIndex", o.zIndex);
2403         },
2404         stop: function(event, ui) {
2405                 var o = $(this).data("ui-draggable").options;
2406                 if(o._zIndex) {
2407                         $(ui.helper).css("zIndex", o._zIndex);
2408                 }
2409         }
2410 });
2411
2412 })(jQuery);
2413 (function( $, undefined ) {
2414
2415 function isOverAxis( x, reference, size ) {
2416         return ( x > reference ) && ( x < ( reference + size ) );
2417 }
2418
2419 $.widget("ui.droppable", {
2420         version: "1.10.3",
2421         widgetEventPrefix: "drop",
2422         options: {
2423                 accept: "*",
2424                 activeClass: false,
2425                 addClasses: true,
2426                 greedy: false,
2427                 hoverClass: false,
2428                 scope: "default",
2429                 tolerance: "intersect",
2430
2431                 // callbacks
2432                 activate: null,
2433                 deactivate: null,
2434                 drop: null,
2435                 out: null,
2436                 over: null
2437         },
2438         _create: function() {
2439
2440                 var o = this.options,
2441                         accept = o.accept;
2442
2443                 this.isover = false;
2444                 this.isout = true;
2445
2446                 this.accept = $.isFunction(accept) ? accept : function(d) {
2447                         return d.is(accept);
2448                 };
2449
2450                 //Store the droppable's proportions
2451                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
2452
2453                 // Add the reference and positions to the manager
2454                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
2455                 $.ui.ddmanager.droppables[o.scope].push(this);
2456
2457                 (o.addClasses && this.element.addClass("ui-droppable"));
2458
2459         },
2460
2461         _destroy: function() {
2462                 var i = 0,
2463                         drop = $.ui.ddmanager.droppables[this.options.scope];
2464
2465                 for ( ; i < drop.length; i++ ) {
2466                         if ( drop[i] === this ) {
2467                                 drop.splice(i, 1);
2468                         }
2469                 }
2470
2471                 this.element.removeClass("ui-droppable ui-droppable-disabled");
2472         },
2473
2474         _setOption: function(key, value) {
2475
2476                 if(key === "accept") {
2477                         this.accept = $.isFunction(value) ? value : function(d) {
2478                                 return d.is(value);
2479                         };
2480                 }
2481                 $.Widget.prototype._setOption.apply(this, arguments);
2482         },
2483
2484         _activate: function(event) {
2485                 var draggable = $.ui.ddmanager.current;
2486                 if(this.options.activeClass) {
2487                         this.element.addClass(this.options.activeClass);
2488                 }
2489                 if(draggable){
2490                         this._trigger("activate", event, this.ui(draggable));
2491                 }
2492         },
2493
2494         _deactivate: function(event) {
2495                 var draggable = $.ui.ddmanager.current;
2496                 if(this.options.activeClass) {
2497                         this.element.removeClass(this.options.activeClass);
2498                 }
2499                 if(draggable){
2500                         this._trigger("deactivate", event, this.ui(draggable));
2501                 }
2502         },
2503
2504         _over: function(event) {
2505
2506                 var draggable = $.ui.ddmanager.current;
2507
2508                 // Bail if draggable and droppable are same element
2509                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2510                         return;
2511                 }
2512
2513                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2514                         if(this.options.hoverClass) {
2515                                 this.element.addClass(this.options.hoverClass);
2516                         }
2517                         this._trigger("over", event, this.ui(draggable));
2518                 }
2519
2520         },
2521
2522         _out: function(event) {
2523
2524                 var draggable = $.ui.ddmanager.current;
2525
2526                 // Bail if draggable and droppable are same element
2527                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2528                         return;
2529                 }
2530
2531                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2532                         if(this.options.hoverClass) {
2533                                 this.element.removeClass(this.options.hoverClass);
2534                         }
2535                         this._trigger("out", event, this.ui(draggable));
2536                 }
2537
2538         },
2539
2540         _drop: function(event,custom) {
2541
2542                 var draggable = custom || $.ui.ddmanager.current,
2543                         childrenIntersection = false;
2544
2545                 // Bail if draggable and droppable are same element
2546                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2547                         return false;
2548                 }
2549
2550                 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2551                         var inst = $.data(this, "ui-droppable");
2552                         if(
2553                                 inst.options.greedy &&
2554                                 !inst.options.disabled &&
2555                                 inst.options.scope === draggable.options.scope &&
2556                                 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2557                                 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2558                         ) { childrenIntersection = true; return false; }
2559                 });
2560                 if(childrenIntersection) {
2561                         return false;
2562                 }
2563
2564                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2565                         if(this.options.activeClass) {
2566                                 this.element.removeClass(this.options.activeClass);
2567                         }
2568                         if(this.options.hoverClass) {
2569                                 this.element.removeClass(this.options.hoverClass);
2570                         }
2571                         this._trigger("drop", event, this.ui(draggable));
2572                         return this.element;
2573                 }
2574
2575                 return false;
2576
2577         },
2578
2579         ui: function(c) {
2580                 return {
2581                         draggable: (c.currentItem || c.element),
2582                         helper: c.helper,
2583                         position: c.position,
2584                         offset: c.positionAbs
2585                 };
2586         }
2587
2588 });
2589
2590 $.ui.intersect = function(draggable, droppable, toleranceMode) {
2591
2592         if (!droppable.offset) {
2593                 return false;
2594         }
2595
2596         var draggableLeft, draggableTop,
2597                 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2598                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
2599                 l = droppable.offset.left, r = l + droppable.proportions.width,
2600                 t = droppable.offset.top, b = t + droppable.proportions.height;
2601
2602         switch (toleranceMode) {
2603                 case "fit":
2604                         return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2605                 case "intersect":
2606                         return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2607                                 x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2608                                 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2609                                 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2610                 case "pointer":
2611                         draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2612                         draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2613                         return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
2614                 case "touch":
2615                         return (
2616                                 (y1 >= t && y1 <= b) || // Top edge touching
2617                                 (y2 >= t && y2 <= b) || // Bottom edge touching
2618                                 (y1 < t && y2 > b)              // Surrounded vertically
2619                         ) && (
2620                                 (x1 >= l && x1 <= r) || // Left edge touching
2621                                 (x2 >= l && x2 <= r) || // Right edge touching
2622                                 (x1 < l && x2 > r)              // Surrounded horizontally
2623                         );
2624                 default:
2625                         return false;
2626                 }
2627
2628 };
2629
2630 /*
2631         This manager tracks offsets of draggables and droppables
2632 */
2633 $.ui.ddmanager = {
2634         current: null,
2635         droppables: { "default": [] },
2636         prepareOffsets: function(t, event) {
2637
2638                 var i, j,
2639                         m = $.ui.ddmanager.droppables[t.options.scope] || [],
2640                         type = event ? event.type : null, // workaround for #2317
2641                         list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2642
2643                 droppablesLoop: for (i = 0; i < m.length; i++) {
2644
2645                         //No disabled and non-accepted
2646                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2647                                 continue;
2648                         }
2649
2650                         // Filter out elements in the current dragged item
2651                         for (j=0; j < list.length; j++) {
2652                                 if(list[j] === m[i].element[0]) {
2653                                         m[i].proportions.height = 0;
2654                                         continue droppablesLoop;
2655                                 }
2656                         }
2657
2658                         m[i].visible = m[i].element.css("display") !== "none";
2659                         if(!m[i].visible) {
2660                                 continue;
2661                         }
2662
2663                         //Activate the droppable if used directly from draggables
2664                         if(type === "mousedown") {
2665                                 m[i]._activate.call(m[i], event);
2666                         }
2667
2668                         m[i].offset = m[i].element.offset();
2669                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2670
2671                 }
2672
2673         },
2674         drop: function(draggable, event) {
2675
2676                 var dropped = false;
2677                 // Create a copy of the droppables in case the list changes during the drop (#9116)
2678                 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2679
2680                         if(!this.options) {
2681                                 return;
2682                         }
2683                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2684                                 dropped = this._drop.call(this, event) || dropped;
2685                         }
2686
2687                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2688                                 this.isout = true;
2689                                 this.isover = false;
2690                                 this._deactivate.call(this, event);
2691                         }
2692
2693                 });
2694                 return dropped;
2695
2696         },
2697         dragStart: function( draggable, event ) {
2698                 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2699                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2700                         if( !draggable.options.refreshPositions ) {
2701                                 $.ui.ddmanager.prepareOffsets( draggable, event );
2702                         }
2703                 });
2704         },
2705         drag: function(draggable, event) {
2706
2707                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2708                 if(draggable.options.refreshPositions) {
2709                         $.ui.ddmanager.prepareOffsets(draggable, event);
2710                 }
2711
2712                 //Run through all droppables and check their positions based on specific tolerance options
2713                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2714
2715                         if(this.options.disabled || this.greedyChild || !this.visible) {
2716                                 return;
2717                         }
2718
2719                         var parentInstance, scope, parent,
2720                                 intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2721                                 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2722                         if(!c) {
2723                                 return;
2724                         }
2725
2726                         if (this.options.greedy) {
2727                                 // find droppable parents with same scope
2728                                 scope = this.options.scope;
2729                                 parent = this.element.parents(":data(ui-droppable)").filter(function () {
2730                                         return $.data(this, "ui-droppable").options.scope === scope;
2731                                 });
2732
2733                                 if (parent.length) {
2734                                         parentInstance = $.data(parent[0], "ui-droppable");
2735                                         parentInstance.greedyChild = (c === "isover");
2736                                 }
2737                         }
2738
2739                         // we just moved into a greedy child
2740                         if (parentInstance && c === "isover") {
2741                                 parentInstance.isover = false;
2742                                 parentInstance.isout = true;
2743                                 parentInstance._out.call(parentInstance, event);
2744                         }
2745
2746                         this[c] = true;
2747                         this[c === "isout" ? "isover" : "isout"] = false;
2748                         this[c === "isover" ? "_over" : "_out"].call(this, event);
2749
2750                         // we just moved out of a greedy child
2751                         if (parentInstance && c === "isout") {
2752                                 parentInstance.isout = false;
2753                                 parentInstance.isover = true;
2754                                 parentInstance._over.call(parentInstance, event);
2755                         }
2756                 });
2757
2758         },
2759         dragStop: function( draggable, event ) {
2760                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2761                 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2762                 if( !draggable.options.refreshPositions ) {
2763                         $.ui.ddmanager.prepareOffsets( draggable, event );
2764                 }
2765         }
2766 };
2767
2768 })(jQuery);
2769 (function( $, undefined ) {
2770
2771 function num(v) {
2772         return parseInt(v, 10) || 0;
2773 }
2774
2775 function isNumber(value) {
2776         return !isNaN(parseInt(value, 10));
2777 }
2778
2779 $.widget("ui.resizable", $.ui.mouse, {
2780         version: "1.10.3",
2781         widgetEventPrefix: "resize",
2782         options: {
2783                 alsoResize: false,
2784                 animate: false,
2785                 animateDuration: "slow",
2786                 animateEasing: "swing",
2787                 aspectRatio: false,
2788                 autoHide: false,
2789                 containment: false,
2790                 ghost: false,
2791                 grid: false,
2792                 handles: "e,s,se",
2793                 helper: false,
2794                 maxHeight: null,
2795                 maxWidth: null,
2796                 minHeight: 10,
2797                 minWidth: 10,
2798                 // See #7960
2799                 zIndex: 90,
2800
2801                 // callbacks
2802                 resize: null,
2803                 start: null,
2804                 stop: null
2805         },
2806         _create: function() {
2807
2808                 var n, i, handle, axis, hname,
2809                         that = this,
2810                         o = this.options;
2811                 this.element.addClass("ui-resizable");
2812
2813                 $.extend(this, {
2814                         _aspectRatio: !!(o.aspectRatio),
2815                         aspectRatio: o.aspectRatio,
2816                         originalElement: this.element,
2817                         _proportionallyResizeElements: [],
2818                         _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2819                 });
2820
2821                 //Wrap the element if it cannot hold child nodes
2822                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2823
2824                         //Create a wrapper element and set the wrapper to the new current internal element
2825                         this.element.wrap(
2826                                 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2827                                         position: this.element.css("position"),
2828                                         width: this.element.outerWidth(),
2829                                         height: this.element.outerHeight(),
2830                                         top: this.element.css("top"),
2831                                         left: this.element.css("left")
2832                                 })
2833                         );
2834
2835                         //Overwrite the original this.element
2836                         this.element = this.element.parent().data(
2837                                 "ui-resizable", this.element.data("ui-resizable")
2838                         );
2839
2840                         this.elementIsWrapper = true;
2841
2842                         //Move margins to the wrapper
2843                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2844                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2845
2846                         //Prevent Safari textarea resize
2847                         this.originalResizeStyle = this.originalElement.css("resize");
2848                         this.originalElement.css("resize", "none");
2849
2850                         //Push the actual element to our proportionallyResize internal array
2851                         this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2852
2853                         // avoid IE jump (hard set the margin)
2854                         this.originalElement.css({ margin: this.originalElement.css("margin") });
2855
2856                         // fix handlers offset
2857                         this._proportionallyResize();
2858
2859                 }
2860
2861                 this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
2862                 if(this.handles.constructor === String) {
2863
2864                         if ( this.handles === "all") {
2865                                 this.handles = "n,e,s,w,se,sw,ne,nw";
2866                         }
2867
2868                         n = this.handles.split(",");
2869                         this.handles = {};
2870
2871                         for(i = 0; i < n.length; i++) {
2872
2873                                 handle = $.trim(n[i]);
2874                                 hname = "ui-resizable-"+handle;
2875                                 axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2876
2877                                 // Apply zIndex to all handles - see #7960
2878                                 axis.css({ zIndex: o.zIndex });
2879
2880                                 //TODO : What's going on here?
2881                                 if ("se" === handle) {
2882                                         axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2883                                 }
2884
2885                                 //Insert into internal handles object and append to element
2886                                 this.handles[handle] = ".ui-resizable-"+handle;
2887                                 this.element.append(axis);
2888                         }
2889
2890                 }
2891
2892                 this._renderAxis = function(target) {
2893
2894                         var i, axis, padPos, padWrapper;
2895
2896                         target = target || this.element;
2897
2898                         for(i in this.handles) {
2899
2900                                 if(this.handles[i].constructor === String) {
2901                                         this.handles[i] = $(this.handles[i], this.element).show();
2902                                 }
2903
2904                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2905                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2906
2907                                         axis = $(this.handles[i], this.element);
2908
2909                                         //Checking the correct pad and border
2910                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2911
2912                                         //The padding type i have to apply...
2913                                         padPos = [ "padding",
2914                                                 /ne|nw|n/.test(i) ? "Top" :
2915                                                 /se|sw|s/.test(i) ? "Bottom" :
2916                                                 /^e$/.test(i) ? "Right" : "Left" ].join("");
2917
2918                                         target.css(padPos, padWrapper);
2919
2920                                         this._proportionallyResize();
2921
2922                                 }
2923
2924                                 //TODO: What's that good for? There's not anything to be executed left
2925                                 if(!$(this.handles[i]).length) {
2926                                         continue;
2927                                 }
2928                         }
2929                 };
2930
2931                 //TODO: make renderAxis a prototype function
2932                 this._renderAxis(this.element);
2933
2934                 this._handles = $(".ui-resizable-handle", this.element)
2935                         .disableSelection();
2936
2937                 //Matching axis name
2938                 this._handles.mouseover(function() {
2939                         if (!that.resizing) {
2940                                 if (this.className) {
2941                                         axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2942                                 }
2943                                 //Axis, default = se
2944                                 that.axis = axis && axis[1] ? axis[1] : "se";
2945                         }
2946                 });
2947
2948                 //If we want to auto hide the elements
2949                 if (o.autoHide) {
2950                         this._handles.hide();
2951                         $(this.element)
2952                                 .addClass("ui-resizable-autohide")
2953                                 .mouseenter(function() {
2954                                         if (o.disabled) {
2955                                                 return;
2956                                         }
2957                                         $(this).removeClass("ui-resizable-autohide");
2958                                         that._handles.show();
2959                                 })
2960                                 .mouseleave(function(){
2961                                         if (o.disabled) {
2962                                                 return;
2963                                         }
2964                                         if (!that.resizing) {
2965                                                 $(this).addClass("ui-resizable-autohide");
2966                                                 that._handles.hide();
2967                                         }
2968                                 });
2969                 }
2970
2971                 //Initialize the mouse interaction
2972                 this._mouseInit();
2973
2974         },
2975
2976         _destroy: function() {
2977
2978                 this._mouseDestroy();
2979
2980                 var wrapper,
2981                         _destroy = function(exp) {
2982                                 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2983                                         .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2984                         };
2985
2986                 //TODO: Unwrap at same DOM position
2987                 if (this.elementIsWrapper) {
2988                         _destroy(this.element);
2989                         wrapper = this.element;
2990                         this.originalElement.css({
2991                                 position: wrapper.css("position"),
2992                                 width: wrapper.outerWidth(),
2993                                 height: wrapper.outerHeight(),
2994                                 top: wrapper.css("top"),
2995                                 left: wrapper.css("left")
2996                         }).insertAfter( wrapper );
2997                         wrapper.remove();
2998                 }
2999
3000                 this.originalElement.css("resize", this.originalResizeStyle);
3001                 _destroy(this.originalElement);
3002
3003                 return this;
3004         },
3005
3006         _mouseCapture: function(event) {
3007                 var i, handle,
3008                         capture = false;
3009
3010                 for (i in this.handles) {
3011                         handle = $(this.handles[i])[0];
3012                         if (handle === event.target || $.contains(handle, event.target)) {
3013                                 capture = true;
3014                         }
3015                 }
3016
3017                 return !this.options.disabled && capture;
3018         },
3019
3020         _mouseStart: function(event) {
3021
3022                 var curleft, curtop, cursor,
3023                         o = this.options,
3024                         iniPos = this.element.position(),
3025                         el = this.element;
3026
3027                 this.resizing = true;
3028
3029                 // bugfix for http://dev.jquery.com/ticket/1749
3030                 if ( (/absolute/).test( el.css("position") ) ) {
3031                         el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
3032                 } else if (el.is(".ui-draggable")) {
3033                         el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
3034                 }
3035
3036                 this._renderProxy();
3037
3038                 curleft = num(this.helper.css("left"));
3039                 curtop = num(this.helper.css("top"));
3040
3041                 if (o.containment) {
3042                         curleft += $(o.containment).scrollLeft() || 0;
3043                         curtop += $(o.containment).scrollTop() || 0;
3044                 }
3045
3046                 //Store needed variables
3047                 this.offset = this.helper.offset();
3048                 this.position = { left: curleft, top: curtop };
3049                 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
3050                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
3051                 this.originalPosition = { left: curleft, top: curtop };
3052                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
3053                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
3054
3055                 //Aspect Ratio
3056                 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
3057
3058                 cursor = $(".ui-resizable-" + this.axis).css("cursor");
3059                 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3060
3061                 el.addClass("ui-resizable-resizing");
3062                 this._propagate("start", event);
3063                 return true;
3064         },
3065
3066         _mouseDrag: function(event) {
3067
3068                 //Increase performance, avoid regex
3069                 var data,
3070                         el = this.helper, props = {},
3071                         smp = this.originalMousePosition,
3072                         a = this.axis,
3073                         prevTop = this.position.top,
3074                         prevLeft = this.position.left,
3075                         prevWidth = this.size.width,
3076                         prevHeight = this.size.height,
3077                         dx = (event.pageX-smp.left)||0,
3078                         dy = (event.pageY-smp.top)||0,
3079                         trigger = this._change[a];
3080
3081                 if (!trigger) {
3082                         return false;
3083                 }
3084
3085                 // Calculate the attrs that will be change
3086                 data = trigger.apply(this, [event, dx, dy]);
3087
3088                 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
3089                 this._updateVirtualBoundaries(event.shiftKey);
3090                 if (this._aspectRatio || event.shiftKey) {
3091                         data = this._updateRatio(data, event);
3092                 }
3093
3094                 data = this._respectSize(data, event);
3095
3096                 this._updateCache(data);
3097
3098                 // plugins callbacks need to be called first
3099                 this._propagate("resize", event);
3100
3101                 if (this.position.top !== prevTop) {
3102                         props.top = this.position.top + "px";
3103                 }
3104                 if (this.position.left !== prevLeft) {
3105                         props.left = this.position.left + "px";
3106                 }
3107                 if (this.size.width !== prevWidth) {
3108                         props.width = this.size.width + "px";
3109                 }
3110                 if (this.size.height !== prevHeight) {
3111                         props.height = this.size.height + "px";
3112                 }
3113                 el.css(props);
3114
3115                 if (!this._helper && this._proportionallyResizeElements.length) {
3116                         this._proportionallyResize();
3117                 }
3118
3119                 // Call the user callback if the element was resized
3120                 if ( ! $.isEmptyObject(props) ) {
3121                         this._trigger("resize", event, this.ui());
3122                 }
3123
3124                 return false;
3125         },
3126
3127         _mouseStop: function(event) {
3128
3129                 this.resizing = false;
3130                 var pr, ista, soffseth, soffsetw, s, left, top,
3131                         o = this.options, that = this;
3132
3133                 if(this._helper) {
3134
3135                         pr = this._proportionallyResizeElements;
3136                         ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3137                         soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
3138                         soffsetw = ista ? 0 : that.sizeDiff.width;
3139
3140                         s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
3141                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
3142                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
3143
3144                         if (!o.animate) {
3145                                 this.element.css($.extend(s, { top: top, left: left }));
3146                         }
3147
3148                         that.helper.height(that.size.height);
3149                         that.helper.width(that.size.width);
3150
3151                         if (this._helper && !o.animate) {
3152                                 this._proportionallyResize();
3153                         }
3154                 }
3155
3156                 $("body").css("cursor", "auto");
3157
3158                 this.element.removeClass("ui-resizable-resizing");
3159
3160                 this._propagate("stop", event);
3161
3162                 if (this._helper) {
3163                         this.helper.remove();
3164                 }
3165
3166                 return false;
3167
3168         },
3169
3170         _updateVirtualBoundaries: function(forceAspectRatio) {
3171                 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3172                         o = this.options;
3173
3174                 b = {
3175                         minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
3176                         maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3177                         minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
3178                         maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
3179                 };
3180
3181                 if(this._aspectRatio || forceAspectRatio) {
3182                         // We want to create an enclosing box whose aspect ration is the requested one
3183                         // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
3184                         pMinWidth = b.minHeight * this.aspectRatio;
3185                         pMinHeight = b.minWidth / this.aspectRatio;
3186                         pMaxWidth = b.maxHeight * this.aspectRatio;
3187                         pMaxHeight = b.maxWidth / this.aspectRatio;
3188
3189                         if(pMinWidth > b.minWidth) {
3190                                 b.minWidth = pMinWidth;
3191                         }
3192                         if(pMinHeight > b.minHeight) {
3193                                 b.minHeight = pMinHeight;
3194                         }
3195                         if(pMaxWidth < b.maxWidth) {
3196                                 b.maxWidth = pMaxWidth;
3197                         }
3198                         if(pMaxHeight < b.maxHeight) {
3199                                 b.maxHeight = pMaxHeight;
3200                         }
3201                 }
3202                 this._vBoundaries = b;
3203         },
3204
3205         _updateCache: function(data) {
3206                 this.offset = this.helper.offset();
3207                 if (isNumber(data.left)) {
3208                         this.position.left = data.left;
3209                 }
3210                 if (isNumber(data.top)) {
3211                         this.position.top = data.top;
3212                 }
3213                 if (isNumber(data.height)) {
3214                         this.size.height = data.height;
3215                 }
3216                 if (isNumber(data.width)) {
3217                         this.size.width = data.width;
3218                 }
3219         },
3220
3221         _updateRatio: function( data ) {
3222
3223                 var cpos = this.position,
3224                         csize = this.size,
3225                         a = this.axis;
3226
3227                 if (isNumber(data.height)) {
3228                         data.width = (data.height * this.aspectRatio);
3229                 } else if (isNumber(data.width)) {
3230                         data.height = (data.width / this.aspectRatio);
3231                 }
3232
3233                 if (a === "sw") {
3234                         data.left = cpos.left + (csize.width - data.width);
3235                         data.top = null;
3236                 }
3237                 if (a === "nw") {
3238                         data.top = cpos.top + (csize.height - data.height);
3239                         data.left = cpos.left + (csize.width - data.width);
3240                 }
3241
3242                 return data;
3243         },
3244
3245         _respectSize: function( data ) {
3246
3247                 var o = this._vBoundaries,
3248                         a = this.axis,
3249                         ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3250                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3251                         dw = this.originalPosition.left + this.originalSize.width,
3252                         dh = this.position.top + this.size.height,
3253                         cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3254                 if (isminw) {
3255                         data.width = o.minWidth;
3256                 }
3257                 if (isminh) {
3258                         data.height = o.minHeight;
3259                 }
3260                 if (ismaxw) {
3261                         data.width = o.maxWidth;
3262                 }
3263                 if (ismaxh) {
3264                         data.height = o.maxHeight;
3265                 }
3266
3267                 if (isminw && cw) {
3268                         data.left = dw - o.minWidth;
3269                 }
3270                 if (ismaxw && cw) {
3271                         data.left = dw - o.maxWidth;
3272                 }
3273                 if (isminh && ch) {
3274                         data.top = dh - o.minHeight;
3275                 }
3276                 if (ismaxh && ch) {
3277                         data.top = dh - o.maxHeight;
3278                 }
3279
3280                 // fixing jump error on top/left - bug #2330
3281                 if (!data.width && !data.height && !data.left && data.top) {
3282                         data.top = null;
3283                 } else if (!data.width && !data.height && !data.top && data.left) {
3284                         data.left = null;
3285                 }
3286
3287                 return data;
3288         },
3289
3290         _proportionallyResize: function() {
3291
3292                 if (!this._proportionallyResizeElements.length) {
3293                         return;
3294                 }
3295
3296                 var i, j, borders, paddings, prel,
3297                         element = this.helper || this.element;
3298
3299                 for ( i=0; i < this._proportionallyResizeElements.length; i++) {
3300
3301                         prel = this._proportionallyResizeElements[i];
3302
3303                         if (!this.borderDif) {
3304                                 this.borderDif = [];
3305                                 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
3306                                 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
3307
3308                                 for ( j = 0; j < borders.length; j++ ) {
3309                                         this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
3310                                 }
3311                         }
3312
3313                         prel.css({
3314                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
3315                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
3316                         });
3317
3318                 }
3319
3320         },
3321
3322         _renderProxy: function() {
3323
3324                 var el = this.element, o = this.options;
3325                 this.elementOffset = el.offset();
3326
3327                 if(this._helper) {
3328
3329                         this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3330
3331                         this.helper.addClass(this._helper).css({
3332                                 width: this.element.outerWidth() - 1,
3333                                 height: this.element.outerHeight() - 1,
3334                                 position: "absolute",
3335                                 left: this.elementOffset.left +"px",
3336                                 top: this.elementOffset.top +"px",
3337                                 zIndex: ++o.zIndex //TODO: Don't modify option
3338                         });
3339
3340                         this.helper
3341                                 .appendTo("body")
3342                                 .disableSelection();
3343
3344                 } else {
3345                         this.helper = this.element;
3346                 }
3347
3348         },
3349
3350         _change: {
3351                 e: function(event, dx) {
3352                         return { width: this.originalSize.width + dx };
3353                 },
3354                 w: function(event, dx) {
3355                         var cs = this.originalSize, sp = this.originalPosition;
3356                         return { left: sp.left + dx, width: cs.width - dx };
3357                 },
3358                 n: function(event, dx, dy) {
3359                         var cs = this.originalSize, sp = this.originalPosition;
3360                         return { top: sp.top + dy, height: cs.height - dy };
3361                 },
3362                 s: function(event, dx, dy) {
3363                         return { height: this.originalSize.height + dy };
3364                 },
3365                 se: function(event, dx, dy) {
3366                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3367                 },
3368                 sw: function(event, dx, dy) {
3369                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3370                 },
3371                 ne: function(event, dx, dy) {
3372                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3373                 },
3374                 nw: function(event, dx, dy) {
3375                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3376                 }
3377         },
3378
3379         _propagate: function(n, event) {
3380                 $.ui.plugin.call(this, n, [event, this.ui()]);
3381                 (n !== "resize" && this._trigger(n, event, this.ui()));
3382         },
3383
3384         plugins: {},
3385
3386         ui: function() {
3387                 return {
3388                         originalElement: this.originalElement,
3389                         element: this.element,
3390                         helper: this.helper,
3391                         position: this.position,
3392                         size: this.size,
3393                         originalSize: this.originalSize,
3394                         originalPosition: this.originalPosition
3395                 };
3396         }
3397
3398 });
3399
3400 /*
3401  * Resizable Extensions
3402  */
3403
3404 $.ui.plugin.add("resizable", "animate", {
3405
3406         stop: function( event ) {
3407                 var that = $(this).data("ui-resizable"),
3408                         o = that.options,
3409                         pr = that._proportionallyResizeElements,
3410                         ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3411                         soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
3412                         soffsetw = ista ? 0 : that.sizeDiff.width,
3413                         style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3414                         left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
3415                         top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
3416
3417                 that.element.animate(
3418                         $.extend(style, top && left ? { top: top, left: left } : {}), {
3419                                 duration: o.animateDuration,
3420                                 easing: o.animateEasing,
3421                                 step: function() {
3422
3423                                         var data = {
3424                                                 width: parseInt(that.element.css("width"), 10),
3425                                                 height: parseInt(that.element.css("height"), 10),
3426                                                 top: parseInt(that.element.css("top"), 10),
3427                                                 left: parseInt(that.element.css("left"), 10)
3428                                         };
3429
3430                                         if (pr && pr.length) {
3431                                                 $(pr[0]).css({ width: data.width, height: data.height });
3432                                         }
3433
3434                                         // propagating resize, and updating values for each animation step
3435                                         that._updateCache(data);
3436                                         that._propagate("resize", event);
3437
3438                                 }
3439                         }
3440                 );
3441         }
3442
3443 });
3444
3445 $.ui.plugin.add("resizable", "containment", {
3446
3447         start: function() {
3448                 var element, p, co, ch, cw, width, height,
3449                         that = $(this).data("ui-resizable"),
3450                         o = that.options,
3451                         el = that.element,
3452                         oc = o.containment,
3453                         ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
3454
3455                 if (!ce) {
3456                         return;
3457                 }
3458
3459                 that.containerElement = $(ce);
3460
3461                 if (/document/.test(oc) || oc === document) {
3462                         that.containerOffset = { left: 0, top: 0 };
3463                         that.containerPosition = { left: 0, top: 0 };
3464
3465                         that.parentData = {
3466                                 element: $(document), left: 0, top: 0,
3467                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3468                         };
3469                 }
3470
3471                 // i'm a node, so compute top, left, right, bottom
3472                 else {
3473                         element = $(ce);
3474                         p = [];
3475                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3476
3477                         that.containerOffset = element.offset();
3478                         that.containerPosition = element.position();
3479                         that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3480
3481                         co = that.containerOffset;
3482                         ch = that.containerSize.height;
3483                         cw = that.containerSize.width;
3484                         width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
3485                         height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3486
3487                         that.parentData = {
3488                                 element: ce, left: co.left, top: co.top, width: width, height: height
3489                         };
3490                 }
3491         },
3492
3493         resize: function( event ) {
3494                 var woset, hoset, isParent, isOffsetRelative,
3495                         that = $(this).data("ui-resizable"),
3496                         o = that.options,
3497                         co = that.containerOffset, cp = that.position,
3498                         pRatio = that._aspectRatio || event.shiftKey,
3499                         cop = { top:0, left:0 }, ce = that.containerElement;
3500
3501                 if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3502                         cop = co;
3503                 }
3504
3505                 if (cp.left < (that._helper ? co.left : 0)) {
3506                         that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3507                         if (pRatio) {
3508                                 that.size.height = that.size.width / that.aspectRatio;
3509                         }
3510                         that.position.left = o.helper ? co.left : 0;
3511                 }
3512
3513                 if (cp.top < (that._helper ? co.top : 0)) {
3514                         that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3515                         if (pRatio) {
3516                                 that.size.width = that.size.height * that.aspectRatio;
3517                         }
3518                         that.position.top = that._helper ? co.top : 0;
3519                 }
3520
3521                 that.offset.left = that.parentData.left+that.position.left;
3522                 that.offset.top = that.parentData.top+that.position.top;
3523
3524                 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3525                 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3526
3527                 isParent = that.containerElement.get(0) === that.element.parent().get(0);
3528                 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3529
3530                 if(isParent && isOffsetRelative) {
3531                         woset -= that.parentData.left;
3532                 }
3533
3534                 if (woset + that.size.width >= that.parentData.width) {
3535                         that.size.width = that.parentData.width - woset;
3536                         if (pRatio) {
3537                                 that.size.height = that.size.width / that.aspectRatio;
3538                         }
3539                 }
3540
3541                 if (hoset + that.size.height >= that.parentData.height) {
3542                         that.size.height = that.parentData.height - hoset;
3543                         if (pRatio) {
3544                                 that.size.width = that.size.height * that.aspectRatio;
3545                         }
3546                 }
3547         },
3548
3549         stop: function(){
3550                 var that = $(this).data("ui-resizable"),
3551                         o = that.options,
3552                         co = that.containerOffset,
3553                         cop = that.containerPosition,
3554                         ce = that.containerElement,
3555                         helper = $(that.helper),
3556                         ho = helper.offset(),
3557                         w = helper.outerWidth() - that.sizeDiff.width,
3558                         h = helper.outerHeight() - that.sizeDiff.height;
3559
3560                 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3561                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3562                 }
3563
3564                 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3565                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3566                 }
3567
3568         }
3569 });
3570
3571 $.ui.plugin.add("resizable", "alsoResize", {
3572
3573         start: function () {
3574                 var that = $(this).data("ui-resizable"),
3575                         o = that.options,
3576                         _store = function (exp) {
3577                                 $(exp).each(function() {
3578                                         var el = $(this);
3579                                         el.data("ui-resizable-alsoresize", {
3580                                                 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3581                                                 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3582                                         });
3583                                 });
3584                         };
3585
3586                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3587                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3588                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3589                 }else{
3590                         _store(o.alsoResize);
3591                 }
3592         },
3593
3594         resize: function (event, ui) {
3595                 var that = $(this).data("ui-resizable"),
3596                         o = that.options,
3597                         os = that.originalSize,
3598                         op = that.originalPosition,
3599                         delta = {
3600                                 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3601                                 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3602                         },
3603
3604                         _alsoResize = function (exp, c) {
3605                                 $(exp).each(function() {
3606                                         var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3607                                                 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3608
3609                                         $.each(css, function (i, prop) {
3610                                                 var sum = (start[prop]||0) + (delta[prop]||0);
3611                                                 if (sum && sum >= 0) {
3612                                                         style[prop] = sum || null;
3613                                                 }
3614                                         });
3615
3616                                         el.css(style);
3617                                 });
3618                         };
3619
3620                 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3621                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3622                 }else{
3623                         _alsoResize(o.alsoResize);
3624                 }
3625         },
3626
3627         stop: function () {
3628                 $(this).removeData("resizable-alsoresize");
3629         }
3630 });
3631
3632 $.ui.plugin.add("resizable", "ghost", {
3633
3634         start: function() {
3635
3636                 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3637
3638                 that.ghost = that.originalElement.clone();
3639                 that.ghost
3640                         .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3641                         .addClass("ui-resizable-ghost")
3642                         .addClass(typeof o.ghost === "string" ? o.ghost : "");
3643
3644                 that.ghost.appendTo(that.helper);
3645
3646         },
3647
3648         resize: function(){
3649                 var that = $(this).data("ui-resizable");
3650                 if (that.ghost) {
3651                         that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3652                 }
3653         },
3654
3655         stop: function() {
3656                 var that = $(this).data("ui-resizable");
3657                 if (that.ghost && that.helper) {
3658                         that.helper.get(0).removeChild(that.ghost.get(0));
3659                 }
3660         }
3661
3662 });
3663
3664 $.ui.plugin.add("resizable", "grid", {
3665
3666         resize: function() {
3667                 var that = $(this).data("ui-resizable"),
3668                         o = that.options,
3669                         cs = that.size,
3670                         os = that.originalSize,
3671                         op = that.originalPosition,
3672                         a = that.axis,
3673                         grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3674                         gridX = (grid[0]||1),
3675                         gridY = (grid[1]||1),
3676                         ox = Math.round((cs.width - os.width) / gridX) * gridX,
3677                         oy = Math.round((cs.height - os.height) / gridY) * gridY,
3678                         newWidth = os.width + ox,
3679                         newHeight = os.height + oy,
3680                         isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3681                         isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3682                         isMinWidth = o.minWidth && (o.minWidth > newWidth),
3683                         isMinHeight = o.minHeight && (o.minHeight > newHeight);
3684
3685                 o.grid = grid;
3686
3687                 if (isMinWidth) {
3688                         newWidth = newWidth + gridX;
3689                 }
3690                 if (isMinHeight) {
3691                         newHeight = newHeight + gridY;
3692                 }
3693                 if (isMaxWidth) {
3694                         newWidth = newWidth - gridX;
3695                 }
3696                 if (isMaxHeight) {
3697                         newHeight = newHeight - gridY;
3698                 }
3699
3700                 if (/^(se|s|e)$/.test(a)) {
3701                         that.size.width = newWidth;
3702                         that.size.height = newHeight;
3703                 } else if (/^(ne)$/.test(a)) {
3704                         that.size.width = newWidth;
3705                         that.size.height = newHeight;
3706                         that.position.top = op.top - oy;
3707                 } else if (/^(sw)$/.test(a)) {
3708                         that.size.width = newWidth;
3709                         that.size.height = newHeight;
3710                         that.position.left = op.left - ox;
3711                 } else {
3712                         that.size.width = newWidth;
3713                         that.size.height = newHeight;
3714                         that.position.top = op.top - oy;
3715                         that.position.left = op.left - ox;
3716                 }
3717         }
3718
3719 });
3720
3721 })(jQuery);
3722 (function( $, undefined ) {
3723
3724 $.widget("ui.selectable", $.ui.mouse, {
3725         version: "1.10.3",
3726         options: {
3727                 appendTo: "body",
3728                 autoRefresh: true,
3729                 distance: 0,
3730                 filter: "*",
3731                 tolerance: "touch",
3732
3733                 // callbacks
3734                 selected: null,
3735                 selecting: null,
3736                 start: null,
3737                 stop: null,
3738                 unselected: null,
3739                 unselecting: null
3740         },
3741         _create: function() {
3742                 var selectees,
3743                         that = this;
3744
3745                 this.element.addClass("ui-selectable");
3746
3747                 this.dragged = false;
3748
3749                 // cache selectee children based on filter
3750                 this.refresh = function() {
3751                         selectees = $(that.options.filter, that.element[0]);
3752                         selectees.addClass("ui-selectee");
3753                         selectees.each(function() {
3754                                 var $this = $(this),
3755                                         pos = $this.offset();
3756                                 $.data(this, "selectable-item", {
3757                                         element: this,
3758                                         $element: $this,
3759                                         left: pos.left,
3760                                         top: pos.top,
3761                                         right: pos.left + $this.outerWidth(),
3762                                         bottom: pos.top + $this.outerHeight(),
3763                                         startselected: false,
3764                                         selected: $this.hasClass("ui-selected"),
3765                                         selecting: $this.hasClass("ui-selecting"),
3766                                         unselecting: $this.hasClass("ui-unselecting")
3767                                 });
3768                         });
3769                 };
3770                 this.refresh();
3771
3772                 this.selectees = selectees.addClass("ui-selectee");
3773
3774                 this._mouseInit();
3775
3776                 this.helper = $("<div class='ui-selectable-helper'></div>");
3777         },
3778
3779         _destroy: function() {
3780                 this.selectees
3781                         .removeClass("ui-selectee")
3782                         .removeData("selectable-item");
3783                 this.element
3784                         .removeClass("ui-selectable ui-selectable-disabled");
3785                 this._mouseDestroy();
3786         },
3787
3788         _mouseStart: function(event) {
3789                 var that = this,
3790                         options = this.options;
3791
3792                 this.opos = [event.pageX, event.pageY];
3793
3794                 if (this.options.disabled) {
3795                         return;
3796                 }
3797
3798                 this.selectees = $(options.filter, this.element[0]);
3799
3800                 this._trigger("start", event);
3801
3802                 $(options.appendTo).append(this.helper);
3803                 // position helper (lasso)
3804                 this.helper.css({
3805                         "left": event.pageX,
3806                         "top": event.pageY,
3807                         "width": 0,
3808                         "height": 0
3809                 });
3810
3811                 if (options.autoRefresh) {
3812                         this.refresh();
3813                 }
3814
3815                 this.selectees.filter(".ui-selected").each(function() {
3816                         var selectee = $.data(this, "selectable-item");
3817                         selectee.startselected = true;
3818                         if (!event.metaKey && !event.ctrlKey) {
3819                                 selectee.$element.removeClass("ui-selected");
3820                                 selectee.selected = false;
3821                                 selectee.$element.addClass("ui-unselecting");
3822                                 selectee.unselecting = true;
3823                                 // selectable UNSELECTING callback
3824                                 that._trigger("unselecting", event, {
3825                                         unselecting: selectee.element
3826                                 });
3827                         }
3828                 });
3829
3830                 $(event.target).parents().addBack().each(function() {
3831                         var doSelect,
3832                                 selectee = $.data(this, "selectable-item");
3833                         if (selectee) {
3834                                 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3835                                 selectee.$element
3836                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3837                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3838                                 selectee.unselecting = !doSelect;
3839                                 selectee.selecting = doSelect;
3840                                 selectee.selected = doSelect;
3841                                 // selectable (UN)SELECTING callback
3842                                 if (doSelect) {
3843                                         that._trigger("selecting", event, {
3844                                                 selecting: selectee.element
3845                                         });
3846                                 } else {
3847                                         that._trigger("unselecting", event, {
3848                                                 unselecting: selectee.element
3849                                         });
3850                                 }
3851                                 return false;
3852                         }
3853                 });
3854
3855         },
3856
3857         _mouseDrag: function(event) {
3858
3859                 this.dragged = true;
3860
3861                 if (this.options.disabled) {
3862                         return;
3863                 }
3864
3865                 var tmp,
3866                         that = this,
3867                         options = this.options,
3868                         x1 = this.opos[0],
3869                         y1 = this.opos[1],
3870                         x2 = event.pageX,
3871                         y2 = event.pageY;
3872
3873                 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3874                 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3875                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3876
3877                 this.selectees.each(function() {
3878                         var selectee = $.data(this, "selectable-item"),
3879                                 hit = false;
3880
3881                         //prevent helper from being selected if appendTo: selectable
3882                         if (!selectee || selectee.element === that.element[0]) {
3883                                 return;
3884                         }
3885
3886                         if (options.tolerance === "touch") {
3887                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3888                         } else if (options.tolerance === "fit") {
3889                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3890                         }
3891
3892                         if (hit) {
3893                                 // SELECT
3894                                 if (selectee.selected) {
3895                                         selectee.$element.removeClass("ui-selected");
3896                                         selectee.selected = false;
3897                                 }
3898                                 if (selectee.unselecting) {
3899                                         selectee.$element.removeClass("ui-unselecting");
3900                                         selectee.unselecting = false;
3901                                 }
3902                                 if (!selectee.selecting) {
3903                                         selectee.$element.addClass("ui-selecting");
3904                                         selectee.selecting = true;
3905                                         // selectable SELECTING callback
3906                                         that._trigger("selecting", event, {
3907                                                 selecting: selectee.element
3908                                         });
3909                                 }
3910                         } else {
3911                                 // UNSELECT
3912                                 if (selectee.selecting) {
3913                                         if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3914                                                 selectee.$element.removeClass("ui-selecting");
3915                                                 selectee.selecting = false;
3916                                                 selectee.$element.addClass("ui-selected");
3917                                                 selectee.selected = true;
3918                                         } else {
3919                                                 selectee.$element.removeClass("ui-selecting");
3920                                                 selectee.selecting = false;
3921                                                 if (selectee.startselected) {
3922                                                         selectee.$element.addClass("ui-unselecting");
3923                                                         selectee.unselecting = true;
3924                                                 }
3925                                                 // selectable UNSELECTING callback
3926                                                 that._trigger("unselecting", event, {
3927                                                         unselecting: selectee.element
3928                                                 });
3929                                         }
3930                                 }
3931                                 if (selectee.selected) {
3932                                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3933                                                 selectee.$element.removeClass("ui-selected");
3934                                                 selectee.selected = false;
3935
3936                                                 selectee.$element.addClass("ui-unselecting");
3937                                                 selectee.unselecting = true;
3938                                                 // selectable UNSELECTING callback
3939                                                 that._trigger("unselecting", event, {
3940                                                         unselecting: selectee.element
3941                                                 });
3942                                         }
3943                                 }
3944                         }
3945                 });
3946
3947                 return false;
3948         },
3949
3950         _mouseStop: function(event) {
3951                 var that = this;
3952
3953                 this.dragged = false;
3954
3955                 $(".ui-unselecting", this.element[0]).each(function() {
3956                         var selectee = $.data(this, "selectable-item");
3957                         selectee.$element.removeClass("ui-unselecting");
3958                         selectee.unselecting = false;
3959                         selectee.startselected = false;
3960                         that._trigger("unselected", event, {
3961                                 unselected: selectee.element
3962                         });
3963                 });
3964                 $(".ui-selecting", this.element[0]).each(function() {
3965                         var selectee = $.data(this, "selectable-item");
3966                         selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3967                         selectee.selecting = false;
3968                         selectee.selected = true;
3969                         selectee.startselected = true;
3970                         that._trigger("selected", event, {
3971                                 selected: selectee.element
3972                         });
3973                 });
3974                 this._trigger("stop", event);
3975
3976                 this.helper.remove();
3977
3978                 return false;
3979         }
3980
3981 });
3982
3983 })(jQuery);
3984 (function( $, undefined ) {
3985
3986 /*jshint loopfunc: true */
3987
3988 function isOverAxis( x, reference, size ) {
3989         return ( x > reference ) && ( x < ( reference + size ) );
3990 }
3991
3992 function isFloating(item) {
3993         return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3994 }
3995
3996 $.widget("ui.sortable", $.ui.mouse, {
3997         version: "1.10.3",
3998         widgetEventPrefix: "sort",
3999         ready: false,
4000         options: {
4001                 appendTo: "parent",
4002                 axis: false,
4003                 connectWith: false,
4004                 containment: false,
4005                 cursor: "auto",
4006                 cursorAt: false,
4007                 dropOnEmpty: true,
4008                 forcePlaceholderSize: false,
4009                 forceHelperSize: false,
4010                 grid: false,
4011                 handle: false,
4012                 helper: "original",
4013                 items: "> *",
4014                 opacity: false,
4015                 placeholder: false,
4016                 revert: false,
4017                 scroll: true,
4018                 scrollSensitivity: 20,
4019                 scrollSpeed: 20,
4020                 scope: "default",
4021                 tolerance: "intersect",
4022                 zIndex: 1000,
4023
4024                 // callbacks
4025                 activate: null,
4026                 beforeStop: null,
4027                 change: null,
4028                 deactivate: null,
4029                 out: null,
4030                 over: null,
4031                 receive: null,
4032                 remove: null,
4033                 sort: null,
4034                 start: null,
4035                 stop: null,
4036                 update: null
4037         },
4038         _create: function() {
4039
4040                 var o = this.options;
4041                 this.containerCache = {};
4042                 this.element.addClass("ui-sortable");
4043
4044                 //Get the items
4045                 this.refresh();
4046
4047                 //Let's determine if the items are being displayed horizontally
4048                 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
4049
4050                 //Let's determine the parent's offset
4051                 this.offset = this.element.offset();
4052
4053                 //Initialize mouse events for interaction
4054                 this._mouseInit();
4055
4056                 //We're ready to go
4057                 this.ready = true;
4058
4059         },
4060
4061         _destroy: function() {
4062                 this.element
4063                         .removeClass("ui-sortable ui-sortable-disabled");
4064                 this._mouseDestroy();
4065
4066                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
4067                         this.items[i].item.removeData(this.widgetName + "-item");
4068                 }
4069
4070                 return this;
4071         },
4072
4073         _setOption: function(key, value){
4074                 if ( key === "disabled" ) {
4075                         this.options[ key ] = value;
4076
4077                         this.widget().toggleClass( "ui-sortable-disabled", !!value );
4078                 } else {
4079                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
4080                         $.Widget.prototype._setOption.apply(this, arguments);
4081                 }
4082         },
4083
4084         _mouseCapture: function(event, overrideHandle) {
4085                 var currentItem = null,
4086                         validHandle = false,
4087                         that = this;
4088
4089                 if (this.reverting) {
4090                         return false;
4091                 }
4092
4093                 if(this.options.disabled || this.options.type === "static") {
4094                         return false;
4095                 }
4096
4097                 //We have to refresh the items data once first
4098                 this._refreshItems(event);
4099
4100                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
4101                 $(event.target).parents().each(function() {
4102                         if($.data(this, that.widgetName + "-item") === that) {
4103                                 currentItem = $(this);
4104                                 return false;
4105                         }
4106                 });
4107                 if($.data(event.target, that.widgetName + "-item") === that) {
4108                         currentItem = $(event.target);
4109                 }
4110
4111                 if(!currentItem) {
4112                         return false;
4113                 }
4114                 if(this.options.handle && !overrideHandle) {
4115                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
4116                                 if(this === event.target) {
4117                                         validHandle = true;
4118                                 }
4119                         });
4120                         if(!validHandle) {
4121                                 return false;
4122                         }
4123                 }
4124
4125                 this.currentItem = currentItem;
4126                 this._removeCurrentsFromItems();
4127                 return true;
4128
4129         },
4130
4131         _mouseStart: function(event, overrideHandle, noActivation) {
4132
4133                 var i, body,
4134                         o = this.options;
4135
4136                 this.currentContainer = this;
4137
4138                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4139                 this.refreshPositions();
4140
4141                 //Create and append the visible helper
4142                 this.helper = this._createHelper(event);
4143
4144                 //Cache the helper size
4145                 this._cacheHelperProportions();
4146
4147                 /*
4148                  * - Position generation -
4149                  * This block generates everything position related - it's the core of draggables.
4150                  */
4151
4152                 //Cache the margins of the original element
4153                 this._cacheMargins();
4154
4155                 //Get the next scrolling parent
4156                 this.scrollParent = this.helper.scrollParent();
4157
4158                 //The element's absolute position on the page minus margins
4159                 this.offset = this.currentItem.offset();
4160                 this.offset = {
4161                         top: this.offset.top - this.margins.top,
4162                         left: this.offset.left - this.margins.left
4163                 };
4164
4165                 $.extend(this.offset, {
4166                         click: { //Where the click happened, relative to the element
4167                                 left: event.pageX - this.offset.left,
4168                                 top: event.pageY - this.offset.top
4169                         },
4170                         parent: this._getParentOffset(),
4171                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4172                 });
4173
4174                 // Only after we got the offset, we can change the helper's position to absolute
4175                 // TODO: Still need to figure out a way to make relative sorting possible
4176                 this.helper.css("position", "absolute");
4177                 this.cssPosition = this.helper.css("position");
4178
4179                 //Generate the original position
4180                 this.originalPosition = this._generatePosition(event);
4181                 this.originalPageX = event.pageX;
4182                 this.originalPageY = event.pageY;
4183
4184                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4185                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4186
4187                 //Cache the former DOM position
4188                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4189
4190                 //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
4191                 if(this.helper[0] !== this.currentItem[0]) {
4192                         this.currentItem.hide();
4193                 }
4194
4195                 //Create the placeholder
4196                 this._createPlaceholder();
4197
4198                 //Set a containment if given in the options
4199                 if(o.containment) {
4200                         this._setContainment();
4201                 }
4202
4203                 if( o.cursor && o.cursor !== "auto" ) { // cursor option
4204                         body = this.document.find( "body" );
4205
4206                         // support: IE
4207                         this.storedCursor = body.css( "cursor" );
4208                         body.css( "cursor", o.cursor );
4209
4210                         this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4211                 }
4212
4213                 if(o.opacity) { // opacity option
4214                         if (this.helper.css("opacity")) {
4215                                 this._storedOpacity = this.helper.css("opacity");
4216                         }
4217                         this.helper.css("opacity", o.opacity);
4218                 }
4219
4220                 if(o.zIndex) { // zIndex option
4221                         if (this.helper.css("zIndex")) {
4222                                 this._storedZIndex = this.helper.css("zIndex");
4223                         }
4224                         this.helper.css("zIndex", o.zIndex);
4225                 }
4226
4227                 //Prepare scrolling
4228                 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4229                         this.overflowOffset = this.scrollParent.offset();
4230                 }
4231
4232                 //Call callbacks
4233                 this._trigger("start", event, this._uiHash());
4234
4235                 //Recache the helper size
4236                 if(!this._preserveHelperProportions) {
4237                         this._cacheHelperProportions();
4238                 }
4239
4240
4241                 //Post "activate" events to possible containers
4242                 if( !noActivation ) {
4243                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
4244                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4245                         }
4246                 }
4247
4248                 //Prepare possible droppables
4249                 if($.ui.ddmanager) {
4250                         $.ui.ddmanager.current = this;
4251                 }
4252
4253                 if ($.ui.ddmanager && !o.dropBehaviour) {
4254                         $.ui.ddmanager.prepareOffsets(this, event);
4255                 }
4256
4257                 this.dragging = true;
4258
4259                 this.helper.addClass("ui-sortable-helper");
4260                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4261                 return true;
4262
4263         },
4264
4265         _mouseDrag: function(event) {
4266                 var i, item, itemElement, intersection,
4267                         o = this.options,
4268                         scrolled = false;
4269
4270                 //Compute the helpers position
4271                 this.position = this._generatePosition(event);
4272                 this.positionAbs = this._convertPositionTo("absolute");
4273
4274                 if (!this.lastPositionAbs) {
4275                         this.lastPositionAbs = this.positionAbs;
4276                 }
4277
4278                 //Do scrolling
4279                 if(this.options.scroll) {
4280                         if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4281
4282                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4283                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4284                                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4285                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4286                                 }
4287
4288                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4289                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4290                                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4291                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4292                                 }
4293
4294                         } else {
4295
4296                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
4297                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
4298                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
4299                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
4300                                 }
4301
4302                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
4303                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
4304                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
4305                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
4306                                 }
4307
4308                         }
4309
4310                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4311                                 $.ui.ddmanager.prepareOffsets(this, event);
4312                         }
4313                 }
4314
4315                 //Regenerate the absolute position used for position checks
4316                 this.positionAbs = this._convertPositionTo("absolute");
4317
4318                 //Set the helper position
4319                 if(!this.options.axis || this.options.axis !== "y") {
4320                         this.helper[0].style.left = this.position.left+"px";
4321                 }
4322                 if(!this.options.axis || this.options.axis !== "x") {
4323                         this.helper[0].style.top = this.position.top+"px";
4324                 }
4325
4326                 //Rearrange
4327                 for (i = this.items.length - 1; i >= 0; i--) {
4328
4329                         //Cache variables and intersection, continue if no intersection
4330                         item = this.items[i];
4331                         itemElement = item.item[0];
4332                         intersection = this._intersectsWithPointer(item);
4333                         if (!intersection) {
4334                                 continue;
4335                         }
4336
4337                         // Only put the placeholder inside the current Container, skip all
4338                         // items form other containers. This works because when moving
4339                         // an item from one container to another the
4340                         // currentContainer is switched before the placeholder is moved.
4341                         //
4342                         // Without this moving items in "sub-sortables" can cause the placeholder to jitter
4343                         // beetween the outer and inner container.
4344                         if (item.instance !== this.currentContainer) {
4345                                 continue;
4346                         }
4347
4348                         // cannot intersect with itself
4349                         // no useless actions that have been done before
4350                         // no action if the item moved is the parent of the item checked
4351                         if (itemElement !== this.currentItem[0] &&
4352                                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4353                                 !$.contains(this.placeholder[0], itemElement) &&
4354                                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4355                         ) {
4356
4357                                 this.direction = intersection === 1 ? "down" : "up";
4358
4359                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4360                                         this._rearrange(event, item);
4361                                 } else {
4362                                         break;
4363                                 }
4364
4365                                 this._trigger("change", event, this._uiHash());
4366                                 break;
4367                         }
4368                 }
4369
4370                 //Post events to containers
4371                 this._contactContainers(event);
4372
4373                 //Interconnect with droppables
4374                 if($.ui.ddmanager) {
4375                         $.ui.ddmanager.drag(this, event);
4376                 }
4377
4378                 //Call callbacks
4379                 this._trigger("sort", event, this._uiHash());
4380
4381                 this.lastPositionAbs = this.positionAbs;
4382                 return false;
4383
4384         },
4385
4386         _mouseStop: function(event, noPropagation) {
4387
4388                 if(!event) {
4389                         return;
4390                 }
4391
4392                 //If we are using droppables, inform the manager about the drop
4393                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
4394                         $.ui.ddmanager.drop(this, event);
4395                 }
4396
4397                 if(this.options.revert) {
4398                         var that = this,
4399                                 cur = this.placeholder.offset(),
4400                                 axis = this.options.axis,
4401                                 animation = {};
4402
4403                         if ( !axis || axis === "x" ) {
4404                                 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
4405                         }
4406                         if ( !axis || axis === "y" ) {
4407                                 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
4408                         }
4409                         this.reverting = true;
4410                         $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4411                                 that._clear(event);
4412                         });
4413                 } else {
4414                         this._clear(event, noPropagation);
4415                 }
4416
4417                 return false;
4418
4419         },
4420
4421         cancel: function() {
4422
4423                 if(this.dragging) {
4424
4425                         this._mouseUp({ target: null });
4426
4427                         if(this.options.helper === "original") {
4428                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4429                         } else {
4430                                 this.currentItem.show();
4431                         }
4432
4433                         //Post deactivating events to containers
4434                         for (var i = this.containers.length - 1; i >= 0; i--){
4435                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4436                                 if(this.containers[i].containerCache.over) {
4437                                         this.containers[i]._trigger("out", null, this._uiHash(this));
4438                                         this.containers[i].containerCache.over = 0;
4439                                 }
4440                         }
4441
4442                 }
4443
4444                 if (this.placeholder) {
4445                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4446                         if(this.placeholder[0].parentNode) {
4447                                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4448                         }
4449                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4450                                 this.helper.remove();
4451                         }
4452
4453                         $.extend(this, {
4454                                 helper: null,
4455                                 dragging: false,
4456                                 reverting: false,
4457                                 _noFinalSort: null
4458                         });
4459
4460                         if(this.domPosition.prev) {
4461                                 $(this.domPosition.prev).after(this.currentItem);
4462                         } else {
4463                                 $(this.domPosition.parent).prepend(this.currentItem);
4464                         }
4465                 }
4466
4467                 return this;
4468
4469         },
4470
4471         serialize: function(o) {
4472
4473                 var items = this._getItemsAsjQuery(o && o.connected),
4474                         str = [];
4475                 o = o || {};
4476
4477                 $(items).each(function() {
4478                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4479                         if (res) {
4480                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4481                         }
4482                 });
4483
4484                 if(!str.length && o.key) {
4485                         str.push(o.key + "=");
4486                 }
4487
4488                 return str.join("&");
4489
4490         },
4491
4492         toArray: function(o) {
4493
4494                 var items = this._getItemsAsjQuery(o && o.connected),
4495                         ret = [];
4496
4497                 o = o || {};
4498
4499                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4500                 return ret;
4501
4502         },
4503
4504         /* Be careful with the following core functions */
4505         _intersectsWith: function(item) {
4506
4507                 var x1 = this.positionAbs.left,
4508                         x2 = x1 + this.helperProportions.width,
4509                         y1 = this.positionAbs.top,
4510                         y2 = y1 + this.helperProportions.height,
4511                         l = item.left,
4512                         r = l + item.width,
4513                         t = item.top,
4514                         b = t + item.height,
4515                         dyClick = this.offset.click.top,
4516                         dxClick = this.offset.click.left,
4517                         isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4518                         isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4519                         isOverElement = isOverElementHeight && isOverElementWidth;
4520
4521                 if ( this.options.tolerance === "pointer" ||
4522                         this.options.forcePointerForContainers ||
4523                         (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4524                 ) {
4525                         return isOverElement;
4526                 } else {
4527
4528                         return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4529                                 x2 - (this.helperProportions.width / 2) < r && // Left Half
4530                                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4531                                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
4532
4533                 }
4534         },
4535
4536         _intersectsWithPointer: function(item) {
4537
4538                 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4539                         isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4540                         isOverElement = isOverElementHeight && isOverElementWidth,
4541                         verticalDirection = this._getDragVerticalDirection(),
4542                         horizontalDirection = this._getDragHorizontalDirection();
4543
4544                 if (!isOverElement) {
4545                         return false;
4546                 }
4547
4548                 return this.floating ?
4549                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4550                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4551
4552         },
4553
4554         _intersectsWithSides: function(item) {
4555
4556                 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4557                         isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4558                         verticalDirection = this._getDragVerticalDirection(),
4559                         horizontalDirection = this._getDragHorizontalDirection();
4560
4561                 if (this.floating && horizontalDirection) {
4562                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4563                 } else {
4564                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4565                 }
4566
4567         },
4568
4569         _getDragVerticalDirection: function() {
4570                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
4571                 return delta !== 0 && (delta > 0 ? "down" : "up");
4572         },
4573
4574         _getDragHorizontalDirection: function() {
4575                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
4576                 return delta !== 0 && (delta > 0 ? "right" : "left");
4577         },
4578
4579         refresh: function(event) {
4580                 this._refreshItems(event);
4581                 this.refreshPositions();
4582                 return this;
4583         },
4584
4585         _connectWith: function() {
4586                 var options = this.options;
4587                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4588         },
4589
4590         _getItemsAsjQuery: function(connected) {
4591
4592                 var i, j, cur, inst,
4593                         items = [],
4594                         queries = [],
4595                         connectWith = this._connectWith();
4596
4597                 if(connectWith && connected) {
4598                         for (i = connectWith.length - 1; i >= 0; i--){
4599                                 cur = $(connectWith[i]);
4600                                 for ( j = cur.length - 1; j >= 0; j--){
4601                                         inst = $.data(cur[j], this.widgetFullName);
4602                                         if(inst && inst !== this && !inst.options.disabled) {
4603                                                 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]);
4604                                         }
4605                                 }
4606                         }
4607                 }
4608
4609                 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]);
4610
4611                 for (i = queries.length - 1; i >= 0; i--){
4612                         queries[i][0].each(function() {
4613                                 items.push(this);
4614                         });
4615                 }
4616
4617                 return $(items);
4618
4619         },
4620
4621         _removeCurrentsFromItems: function() {
4622
4623                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4624
4625                 this.items = $.grep(this.items, function (item) {
4626                         for (var j=0; j < list.length; j++) {
4627                                 if(list[j] === item.item[0]) {
4628                                         return false;
4629                                 }
4630                         }
4631                         return true;
4632                 });
4633
4634         },
4635
4636         _refreshItems: function(event) {
4637
4638                 this.items = [];
4639                 this.containers = [this];
4640
4641                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
4642                         items = this.items,
4643                         queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4644                         connectWith = this._connectWith();
4645
4646                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4647                         for (i = connectWith.length - 1; i >= 0; i--){
4648                                 cur = $(connectWith[i]);
4649                                 for (j = cur.length - 1; j >= 0; j--){
4650                                         inst = $.data(cur[j], this.widgetFullName);
4651                                         if(inst && inst !== this && !inst.options.disabled) {
4652                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4653                                                 this.containers.push(inst);
4654                                         }
4655                                 }
4656                         }
4657                 }
4658
4659                 for (i = queries.length - 1; i >= 0; i--) {
4660                         targetData = queries[i][1];
4661                         _queries = queries[i][0];
4662
4663                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4664                                 item = $(_queries[j]);
4665
4666                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4667
4668                                 items.push({
4669                                         item: item,
4670                                         instance: targetData,
4671                                         width: 0, height: 0,
4672                                         left: 0, top: 0
4673                                 });
4674                         }
4675                 }
4676
4677         },
4678
4679         refreshPositions: function(fast) {
4680
4681                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4682                 if(this.offsetParent && this.helper) {
4683                         this.offset.parent = this._getParentOffset();
4684                 }
4685
4686                 var i, item, t, p;
4687
4688                 for (i = this.items.length - 1; i >= 0; i--){
4689                         item = this.items[i];
4690
4691                         //We ignore calculating positions of all connected containers when we're not over them
4692                         if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4693                                 continue;
4694                         }
4695
4696                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4697
4698                         if (!fast) {
4699                                 item.width = t.outerWidth();
4700                                 item.height = t.outerHeight();
4701                         }
4702
4703                         p = t.offset();
4704                         item.left = p.left;
4705                         item.top = p.top;
4706                 }
4707
4708                 if(this.options.custom && this.options.custom.refreshContainers) {
4709                         this.options.custom.refreshContainers.call(this);
4710                 } else {
4711                         for (i = this.containers.length - 1; i >= 0; i--){
4712                                 p = this.containers[i].element.offset();
4713                                 this.containers[i].containerCache.left = p.left;
4714                                 this.containers[i].containerCache.top = p.top;
4715                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
4716                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4717                         }
4718                 }
4719
4720                 return this;
4721         },
4722
4723         _createPlaceholder: function(that) {
4724                 that = that || this;
4725                 var className,
4726                         o = that.options;
4727
4728                 if(!o.placeholder || o.placeholder.constructor === String) {
4729                         className = o.placeholder;
4730                         o.placeholder = {
4731                                 element: function() {
4732
4733                                         var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4734                                                 element = $( "<" + nodeName + ">", that.document[0] )
4735                                                         .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4736                                                         .removeClass("ui-sortable-helper");
4737
4738                                         if ( nodeName === "tr" ) {
4739                                                 that.currentItem.children().each(function() {
4740                                                         $( "<td>&#160;</td>", that.document[0] )
4741                                                                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4742                                                                 .appendTo( element );
4743                                                 });
4744                                         } else if ( nodeName === "img" ) {
4745                                                 element.attr( "src", that.currentItem.attr( "src" ) );
4746                                         }
4747
4748                                         if ( !className ) {
4749                                                 element.css( "visibility", "hidden" );
4750                                         }
4751
4752                                         return element;
4753                                 },
4754                                 update: function(container, p) {
4755
4756                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4757                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4758                                         if(className && !o.forcePlaceholderSize) {
4759                                                 return;
4760                                         }
4761
4762                                         //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
4763                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4764                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4765                                 }
4766                         };
4767                 }
4768
4769                 //Create the placeholder
4770                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4771
4772                 //Append it after the actual current item
4773                 that.currentItem.after(that.placeholder);
4774
4775                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4776                 o.placeholder.update(that, that.placeholder);
4777
4778         },
4779
4780         _contactContainers: function(event) {
4781                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4782                         innermostContainer = null,
4783                         innermostIndex = null;
4784
4785                 // get innermost container that intersects with item
4786                 for (i = this.containers.length - 1; i >= 0; i--) {
4787
4788                         // never consider a container that's located within the item itself
4789                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4790                                 continue;
4791                         }
4792
4793                         if(this._intersectsWith(this.containers[i].containerCache)) {
4794
4795                                 // if we've already found a container and it's more "inner" than this, then continue
4796                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4797                                         continue;
4798                                 }
4799
4800                                 innermostContainer = this.containers[i];
4801                                 innermostIndex = i;
4802
4803                         } else {
4804                                 // container doesn't intersect. trigger "out" event if necessary
4805                                 if(this.containers[i].containerCache.over) {
4806                                         this.containers[i]._trigger("out", event, this._uiHash(this));
4807                                         this.containers[i].containerCache.over = 0;
4808                                 }
4809                         }
4810
4811                 }
4812
4813                 // if no intersecting containers found, return
4814                 if(!innermostContainer) {
4815                         return;
4816                 }
4817
4818                 // move the item into the container if it's not there already
4819                 if(this.containers.length === 1) {
4820                         if (!this.containers[innermostIndex].containerCache.over) {
4821                                 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4822                                 this.containers[innermostIndex].containerCache.over = 1;
4823                         }
4824                 } else {
4825
4826                         //When entering a new container, we will find the item with the least distance and append our item near it
4827                         dist = 10000;
4828                         itemWithLeastDistance = null;
4829                         floating = innermostContainer.floating || isFloating(this.currentItem);
4830                         posProperty = floating ? "left" : "top";
4831                         sizeProperty = floating ? "width" : "height";
4832                         base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4833                         for (j = this.items.length - 1; j >= 0; j--) {
4834                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4835                                         continue;
4836                                 }
4837                                 if(this.items[j].item[0] === this.currentItem[0]) {
4838                                         continue;
4839                                 }
4840                                 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4841                                         continue;
4842                                 }
4843                                 cur = this.items[j].item.offset()[posProperty];
4844                                 nearBottom = false;
4845                                 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4846                                         nearBottom = true;
4847                                         cur += this.items[j][sizeProperty];
4848                                 }
4849
4850                                 if(Math.abs(cur - base) < dist) {
4851                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4852                                         this.direction = nearBottom ? "up": "down";
4853                                 }
4854                         }
4855
4856                         //Check if dropOnEmpty is enabled
4857                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4858                                 return;
4859                         }
4860
4861                         if(this.currentContainer === this.containers[innermostIndex]) {
4862                                 return;
4863                         }
4864
4865                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4866                         this._trigger("change", event, this._uiHash());
4867                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4868                         this.currentContainer = this.containers[innermostIndex];
4869
4870                         //Update the placeholder
4871                         this.options.placeholder.update(this.currentContainer, this.placeholder);
4872
4873                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4874                         this.containers[innermostIndex].containerCache.over = 1;
4875                 }
4876
4877
4878         },
4879
4880         _createHelper: function(event) {
4881
4882                 var o = this.options,
4883                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4884
4885                 //Add the helper to the DOM if that didn't happen already
4886                 if(!helper.parents("body").length) {
4887                         $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4888                 }
4889
4890                 if(helper[0] === this.currentItem[0]) {
4891                         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") };
4892                 }
4893
4894                 if(!helper[0].style.width || o.forceHelperSize) {
4895                         helper.width(this.currentItem.width());
4896                 }
4897                 if(!helper[0].style.height || o.forceHelperSize) {
4898                         helper.height(this.currentItem.height());
4899                 }
4900
4901                 return helper;
4902
4903         },
4904
4905         _adjustOffsetFromHelper: function(obj) {
4906                 if (typeof obj === "string") {
4907                         obj = obj.split(" ");
4908                 }
4909                 if ($.isArray(obj)) {
4910                         obj = {left: +obj[0], top: +obj[1] || 0};
4911                 }
4912                 if ("left" in obj) {
4913                         this.offset.click.left = obj.left + this.margins.left;
4914                 }
4915                 if ("right" in obj) {
4916                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4917                 }
4918                 if ("top" in obj) {
4919                         this.offset.click.top = obj.top + this.margins.top;
4920                 }
4921                 if ("bottom" in obj) {
4922                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4923                 }
4924         },
4925
4926         _getParentOffset: function() {
4927
4928
4929                 //Get the offsetParent and cache its position
4930                 this.offsetParent = this.helper.offsetParent();
4931                 var po = this.offsetParent.offset();
4932
4933                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4934                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4935                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4936                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4937                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4938                         po.left += this.scrollParent.scrollLeft();
4939                         po.top += this.scrollParent.scrollTop();
4940                 }
4941
4942                 // This needs to be actually done for all browsers, since pageX/pageY includes this information
4943                 // with an ugly IE fix
4944                 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4945                         po = { top: 0, left: 0 };
4946                 }
4947
4948                 return {
4949                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4950                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4951                 };
4952
4953         },
4954
4955         _getRelativeOffset: function() {
4956
4957                 if(this.cssPosition === "relative") {
4958                         var p = this.currentItem.position();
4959                         return {
4960                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4961                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4962                         };
4963                 } else {
4964                         return { top: 0, left: 0 };
4965                 }
4966
4967         },
4968
4969         _cacheMargins: function() {
4970                 this.margins = {
4971                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4972                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4973                 };
4974         },
4975
4976         _cacheHelperProportions: function() {
4977                 this.helperProportions = {
4978                         width: this.helper.outerWidth(),
4979                         height: this.helper.outerHeight()
4980                 };
4981         },
4982
4983         _setContainment: function() {
4984
4985                 var ce, co, over,
4986                         o = this.options;
4987                 if(o.containment === "parent") {
4988                         o.containment = this.helper[0].parentNode;
4989                 }
4990                 if(o.containment === "document" || o.containment === "window") {
4991                         this.containment = [
4992                                 0 - this.offset.relative.left - this.offset.parent.left,
4993                                 0 - this.offset.relative.top - this.offset.parent.top,
4994                                 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4995                                 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4996                         ];
4997                 }
4998
4999                 if(!(/^(document|window|parent)$/).test(o.containment)) {
5000                         ce = $(o.containment)[0];
5001                         co = $(o.containment).offset();
5002                         over = ($(ce).css("overflow") !== "hidden");
5003
5004                         this.containment = [
5005                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5006                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5007                                 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,
5008                                 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
5009                         ];
5010                 }
5011
5012         },
5013
5014         _convertPositionTo: function(d, pos) {
5015
5016                 if(!pos) {
5017                         pos = this.position;
5018                 }
5019                 var mod = d === "absolute" ? 1 : -1,
5020                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5021                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5022
5023                 return {
5024                         top: (
5025                                 pos.top +                                                                                                                               // The absolute mouse position
5026                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
5027                                 this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
5028                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5029                         ),
5030                         left: (
5031                                 pos.left +                                                                                                                              // The absolute mouse position
5032                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
5033                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
5034                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5035                         )
5036                 };
5037
5038         },
5039
5040         _generatePosition: function(event) {
5041
5042                 var top, left,
5043                         o = this.options,
5044                         pageX = event.pageX,
5045                         pageY = event.pageY,
5046                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5047
5048                 // This is another very weird special case that only happens for relative elements:
5049                 // 1. If the css position is relative
5050                 // 2. and the scroll parent is the document or similar to the offset parent
5051                 // we have to refresh the relative offset during the scroll so there are no jumps
5052                 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
5053                         this.offset.relative = this._getRelativeOffset();
5054                 }
5055
5056                 /*
5057                  * - Position constraining -
5058                  * Constrain the position to a mix of grid, containment.
5059                  */
5060
5061                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5062
5063                         if(this.containment) {
5064                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
5065                                         pageX = this.containment[0] + this.offset.click.left;
5066                                 }
5067                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
5068                                         pageY = this.containment[1] + this.offset.click.top;
5069                                 }
5070                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
5071                                         pageX = this.containment[2] + this.offset.click.left;
5072                                 }
5073                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
5074                                         pageY = this.containment[3] + this.offset.click.top;
5075                                 }
5076                         }
5077
5078                         if(o.grid) {
5079                                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5080                                 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;
5081
5082                                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5083                                 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;
5084                         }
5085
5086                 }
5087
5088                 return {
5089                         top: (
5090                                 pageY -                                                                                                                         // The absolute mouse position
5091                                 this.offset.click.top -                                                                                                 // Click offset (relative to the element)
5092                                 this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
5093                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
5094                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5095                         ),
5096                         left: (
5097                                 pageX -                                                                                                                         // The absolute mouse position
5098                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
5099                                 this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
5100                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
5101                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5102                         )
5103                 };
5104
5105         },
5106
5107         _rearrange: function(event, i, a, hardRefresh) {
5108
5109                 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));
5110
5111                 //Various things done here to improve the performance:
5112                 // 1. we create a setTimeout, that calls refreshPositions
5113                 // 2. on the instance, we have a counter variable, that get's higher after every append
5114                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5115                 // 4. this lets only the last addition to the timeout stack through
5116                 this.counter = this.counter ? ++this.counter : 1;
5117                 var counter = this.counter;
5118
5119                 this._delay(function() {
5120                         if(counter === this.counter) {
5121                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5122                         }
5123                 });
5124
5125         },
5126
5127         _clear: function(event, noPropagation) {
5128
5129                 this.reverting = false;
5130                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
5131                 // everything else normalized again
5132                 var i,
5133                         delayedTriggers = [];
5134
5135                 // We first have to update the dom position of the actual currentItem
5136                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5137                 if(!this._noFinalSort && this.currentItem.parent().length) {
5138                         this.placeholder.before(this.currentItem);
5139                 }
5140                 this._noFinalSort = null;
5141
5142                 if(this.helper[0] === this.currentItem[0]) {
5143                         for(i in this._storedCSS) {
5144                                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5145                                         this._storedCSS[i] = "";
5146                                 }
5147                         }
5148                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5149                 } else {
5150                         this.currentItem.show();
5151                 }
5152
5153                 if(this.fromOutside && !noPropagation) {
5154                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5155                 }
5156                 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5157                         delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5158                 }
5159
5160                 // Check if the items Container has Changed and trigger appropriate
5161                 // events.
5162                 if (this !== this.currentContainer) {
5163                         if(!noPropagation) {
5164                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5165                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
5166                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
5167                         }
5168                 }
5169
5170
5171                 //Post events to containers
5172                 for (i = this.containers.length - 1; i >= 0; i--){
5173                         if(!noPropagation) {
5174                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
5175                         }
5176                         if(this.containers[i].containerCache.over) {
5177                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
5178                                 this.containers[i].containerCache.over = 0;
5179                         }
5180                 }
5181
5182                 //Do what was originally in plugins
5183                 if ( this.storedCursor ) {
5184                         this.document.find( "body" ).css( "cursor", this.storedCursor );
5185                         this.storedStylesheet.remove();
5186                 }
5187                 if(this._storedOpacity) {
5188                         this.helper.css("opacity", this._storedOpacity);
5189                 }
5190                 if(this._storedZIndex) {
5191                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5192                 }
5193
5194                 this.dragging = false;
5195                 if(this.cancelHelperRemoval) {
5196                         if(!noPropagation) {
5197                                 this._trigger("beforeStop", event, this._uiHash());
5198                                 for (i=0; i < delayedTriggers.length; i++) {
5199                                         delayedTriggers[i].call(this, event);
5200                                 } //Trigger all delayed events
5201                                 this._trigger("stop", event, this._uiHash());
5202                         }
5203
5204                         this.fromOutside = false;
5205                         return false;
5206                 }
5207
5208                 if(!noPropagation) {
5209                         this._trigger("beforeStop", event, this._uiHash());
5210                 }
5211
5212                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5213                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5214
5215                 if(this.helper[0] !== this.currentItem[0]) {
5216                         this.helper.remove();
5217                 }
5218                 this.helper = null;
5219
5220                 if(!noPropagation) {
5221                         for (i=0; i < delayedTriggers.length; i++) {
5222                                 delayedTriggers[i].call(this, event);
5223                         } //Trigger all delayed events
5224                         this._trigger("stop", event, this._uiHash());
5225                 }
5226
5227                 this.fromOutside = false;
5228                 return true;
5229
5230         },
5231
5232         _trigger: function() {
5233                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5234                         this.cancel();
5235                 }
5236         },
5237
5238         _uiHash: function(_inst) {
5239                 var inst = _inst || this;
5240                 return {
5241                         helper: inst.helper,
5242                         placeholder: inst.placeholder || $([]),
5243                         position: inst.position,
5244                         originalPosition: inst.originalPosition,
5245                         offset: inst.positionAbs,
5246                         item: inst.currentItem,
5247                         sender: _inst ? _inst.element : null
5248                 };
5249         }
5250
5251 });
5252
5253 })(jQuery);
5254 (function( $, undefined ) {
5255
5256 var uid = 0,
5257         hideProps = {},
5258         showProps = {};
5259
5260 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
5261         hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
5262 showProps.height = showProps.paddingTop = showProps.paddingBottom =
5263         showProps.borderTopWidth = showProps.borderBottomWidth = "show";
5264
5265 $.widget( "ui.accordion", {
5266         version: "1.10.3",
5267         options: {
5268                 active: 0,
5269                 animate: {},
5270                 collapsible: false,
5271                 event: "click",
5272                 header: "> li > :first-child,> :not(li):even",
5273                 heightStyle: "auto",
5274                 icons: {
5275                         activeHeader: "ui-icon-triangle-1-s",
5276                         header: "ui-icon-triangle-1-e"
5277                 },
5278
5279                 // callbacks
5280                 activate: null,
5281                 beforeActivate: null
5282         },
5283
5284         _create: function() {
5285                 var options = this.options;
5286                 this.prevShow = this.prevHide = $();
5287                 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5288                         // ARIA
5289                         .attr( "role", "tablist" );
5290
5291                 // don't allow collapsible: false and active: false / null
5292                 if ( !options.collapsible && (options.active === false || options.active == null) ) {
5293                         options.active = 0;
5294                 }
5295
5296                 this._processPanels();
5297                 // handle negative values
5298                 if ( options.active < 0 ) {
5299                         options.active += this.headers.length;
5300                 }
5301                 this._refresh();
5302         },
5303
5304         _getCreateEventData: function() {
5305                 return {
5306                         header: this.active,
5307                         panel: !this.active.length ? $() : this.active.next(),
5308                         content: !this.active.length ? $() : this.active.next()
5309                 };
5310         },
5311
5312         _createIcons: function() {
5313                 var icons = this.options.icons;
5314                 if ( icons ) {
5315                         $( "<span>" )
5316                                 .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5317                                 .prependTo( this.headers );
5318                         this.active.children( ".ui-accordion-header-icon" )
5319                                 .removeClass( icons.header )
5320                                 .addClass( icons.activeHeader );
5321                         this.headers.addClass( "ui-accordion-icons" );
5322                 }
5323         },
5324
5325         _destroyIcons: function() {
5326                 this.headers
5327                         .removeClass( "ui-accordion-icons" )
5328                         .children( ".ui-accordion-header-icon" )
5329                                 .remove();
5330         },
5331
5332         _destroy: function() {
5333                 var contents;
5334
5335                 // clean up main element
5336                 this.element
5337                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5338                         .removeAttr( "role" );
5339
5340                 // clean up headers
5341                 this.headers
5342                         .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5343                         .removeAttr( "role" )
5344                         .removeAttr( "aria-selected" )
5345                         .removeAttr( "aria-controls" )
5346                         .removeAttr( "tabIndex" )
5347                         .each(function() {
5348                                 if ( /^ui-accordion/.test( this.id ) ) {
5349                                         this.removeAttribute( "id" );
5350                                 }
5351                         });
5352                 this._destroyIcons();
5353
5354                 // clean up content panels
5355                 contents = this.headers.next()
5356                         .css( "display", "" )
5357                         .removeAttr( "role" )
5358                         .removeAttr( "aria-expanded" )
5359                         .removeAttr( "aria-hidden" )
5360                         .removeAttr( "aria-labelledby" )
5361                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5362                         .each(function() {
5363                                 if ( /^ui-accordion/.test( this.id ) ) {
5364                                         this.removeAttribute( "id" );
5365                                 }
5366                         });
5367                 if ( this.options.heightStyle !== "content" ) {
5368                         contents.css( "height", "" );
5369                 }
5370         },
5371
5372         _setOption: function( key, value ) {
5373                 if ( key === "active" ) {
5374                         // _activate() will handle invalid values and update this.options
5375                         this._activate( value );
5376                         return;
5377                 }
5378
5379                 if ( key === "event" ) {
5380                         if ( this.options.event ) {
5381                                 this._off( this.headers, this.options.event );
5382                         }
5383                         this._setupEvents( value );
5384                 }
5385
5386                 this._super( key, value );
5387
5388                 // setting collapsible: false while collapsed; open first panel
5389                 if ( key === "collapsible" && !value && this.options.active === false ) {
5390                         this._activate( 0 );
5391                 }
5392
5393                 if ( key === "icons" ) {
5394                         this._destroyIcons();
5395                         if ( value ) {
5396                                 this._createIcons();
5397                         }
5398                 }
5399
5400                 // #5332 - opacity doesn't cascade to positioned elements in IE
5401                 // so we need to add the disabled class to the headers and panels
5402                 if ( key === "disabled" ) {
5403                         this.headers.add( this.headers.next() )
5404                                 .toggleClass( "ui-state-disabled", !!value );
5405                 }
5406         },
5407
5408         _keydown: function( event ) {
5409                 /*jshint maxcomplexity:15*/
5410                 if ( event.altKey || event.ctrlKey ) {
5411                         return;
5412                 }
5413
5414                 var keyCode = $.ui.keyCode,
5415                         length = this.headers.length,
5416                         currentIndex = this.headers.index( event.target ),
5417                         toFocus = false;
5418
5419                 switch ( event.keyCode ) {
5420                         case keyCode.RIGHT:
5421                         case keyCode.DOWN:
5422                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5423                                 break;
5424                         case keyCode.LEFT:
5425                         case keyCode.UP:
5426                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5427                                 break;
5428                         case keyCode.SPACE:
5429                         case keyCode.ENTER:
5430                                 this._eventHandler( event );
5431                                 break;
5432                         case keyCode.HOME:
5433                                 toFocus = this.headers[ 0 ];
5434                                 break;
5435                         case keyCode.END:
5436                                 toFocus = this.headers[ length - 1 ];
5437                                 break;
5438                 }
5439
5440                 if ( toFocus ) {
5441                         $( event.target ).attr( "tabIndex", -1 );
5442                         $( toFocus ).attr( "tabIndex", 0 );
5443                         toFocus.focus();
5444                         event.preventDefault();
5445                 }
5446         },
5447
5448         _panelKeyDown : function( event ) {
5449                 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5450                         $( event.currentTarget ).prev().focus();
5451                 }
5452         },
5453
5454         refresh: function() {
5455                 var options = this.options;
5456                 this._processPanels();
5457
5458                 // was collapsed or no panel
5459                 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
5460                         options.active = false;
5461                         this.active = $();
5462                 // active false only when collapsible is true
5463                 } else if ( options.active === false ) {
5464                         this._activate( 0 );
5465                 // was active, but active panel is gone
5466                 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5467                         // all remaining panel are disabled
5468                         if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
5469                                 options.active = false;
5470                                 this.active = $();
5471                         // activate previous panel
5472                         } else {
5473                                 this._activate( Math.max( 0, options.active - 1 ) );
5474                         }
5475                 // was active, active panel still exists
5476                 } else {
5477                         // make sure active index is correct
5478                         options.active = this.headers.index( this.active );
5479                 }
5480
5481                 this._destroyIcons();
5482
5483                 this._refresh();
5484         },
5485
5486         _processPanels: function() {
5487                 this.headers = this.element.find( this.options.header )
5488                         .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
5489
5490                 this.headers.next()
5491                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
5492                         .filter(":not(.ui-accordion-content-active)")
5493                         .hide();
5494         },
5495
5496         _refresh: function() {
5497                 var maxHeight,
5498                         options = this.options,
5499                         heightStyle = options.heightStyle,
5500                         parent = this.element.parent(),
5501                         accordionId = this.accordionId = "ui-accordion-" +
5502                                 (this.element.attr( "id" ) || ++uid);
5503
5504                 this.active = this._findActive( options.active )
5505                         .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
5506                         .removeClass( "ui-corner-all" );
5507                 this.active.next()
5508                         .addClass( "ui-accordion-content-active" )
5509                         .show();
5510
5511                 this.headers
5512                         .attr( "role", "tab" )
5513                         .each(function( i ) {
5514                                 var header = $( this ),
5515                                         headerId = header.attr( "id" ),
5516                                         panel = header.next(),
5517                                         panelId = panel.attr( "id" );
5518                                 if ( !headerId ) {
5519                                         headerId = accordionId + "-header-" + i;
5520                                         header.attr( "id", headerId );
5521                                 }
5522                                 if ( !panelId ) {
5523                                         panelId = accordionId + "-panel-" + i;
5524                                         panel.attr( "id", panelId );
5525                                 }
5526                                 header.attr( "aria-controls", panelId );
5527                                 panel.attr( "aria-labelledby", headerId );
5528                         })
5529                         .next()
5530                                 .attr( "role", "tabpanel" );
5531
5532                 this.headers
5533                         .not( this.active )
5534                         .attr({
5535                                 "aria-selected": "false",
5536                                 tabIndex: -1
5537                         })
5538                         .next()
5539                                 .attr({
5540                                         "aria-expanded": "false",
5541                                         "aria-hidden": "true"
5542                                 })
5543                                 .hide();
5544
5545                 // make sure at least one header is in the tab order
5546                 if ( !this.active.length ) {
5547                         this.headers.eq( 0 ).attr( "tabIndex", 0 );
5548                 } else {
5549                         this.active.attr({
5550                                 "aria-selected": "true",
5551                                 tabIndex: 0
5552                         })
5553                         .next()
5554                                 .attr({
5555                                         "aria-expanded": "true",
5556                                         "aria-hidden": "false"
5557                                 });
5558                 }
5559
5560                 this._createIcons();
5561
5562                 this._setupEvents( options.event );
5563
5564                 if ( heightStyle === "fill" ) {
5565                         maxHeight = parent.height();
5566                         this.element.siblings( ":visible" ).each(function() {
5567                                 var elem = $( this ),
5568                                         position = elem.css( "position" );
5569
5570                                 if ( position === "absolute" || position === "fixed" ) {
5571                                         return;
5572                                 }
5573                                 maxHeight -= elem.outerHeight( true );
5574                         });
5575
5576                         this.headers.each(function() {
5577                                 maxHeight -= $( this ).outerHeight( true );
5578                         });
5579
5580                         this.headers.next()
5581                                 .each(function() {
5582                                         $( this ).height( Math.max( 0, maxHeight -
5583                                                 $( this ).innerHeight() + $( this ).height() ) );
5584                                 })
5585                                 .css( "overflow", "auto" );
5586                 } else if ( heightStyle === "auto" ) {
5587                         maxHeight = 0;
5588                         this.headers.next()
5589                                 .each(function() {
5590                                         maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5591                                 })
5592                                 .height( maxHeight );
5593                 }
5594         },
5595
5596         _activate: function( index ) {
5597                 var active = this._findActive( index )[ 0 ];
5598
5599                 // trying to activate the already active panel
5600                 if ( active === this.active[ 0 ] ) {
5601                         return;
5602                 }
5603
5604                 // trying to collapse, simulate a click on the currently active header
5605                 active = active || this.active[ 0 ];
5606
5607                 this._eventHandler({
5608                         target: active,
5609                         currentTarget: active,
5610                         preventDefault: $.noop
5611                 });
5612         },
5613
5614         _findActive: function( selector ) {
5615                 return typeof selector === "number" ? this.headers.eq( selector ) : $();
5616         },
5617
5618         _setupEvents: function( event ) {
5619                 var events = {
5620                         keydown: "_keydown"
5621                 };
5622                 if ( event ) {
5623                         $.each( event.split(" "), function( index, eventName ) {
5624                                 events[ eventName ] = "_eventHandler";
5625                         });
5626                 }
5627
5628                 this._off( this.headers.add( this.headers.next() ) );
5629                 this._on( this.headers, events );
5630                 this._on( this.headers.next(), { keydown: "_panelKeyDown" });
5631                 this._hoverable( this.headers );
5632                 this._focusable( this.headers );
5633         },
5634
5635         _eventHandler: function( event ) {
5636                 var options = this.options,
5637                         active = this.active,
5638                         clicked = $( event.currentTarget ),
5639                         clickedIsActive = clicked[ 0 ] === active[ 0 ],
5640                         collapsing = clickedIsActive && options.collapsible,
5641                         toShow = collapsing ? $() : clicked.next(),
5642                         toHide = active.next(),
5643                         eventData = {
5644                                 oldHeader: active,
5645                                 oldPanel: toHide,
5646                                 newHeader: collapsing ? $() : clicked,
5647                                 newPanel: toShow
5648                         };
5649
5650                 event.preventDefault();
5651
5652                 if (
5653                                 // click on active header, but not collapsible
5654                                 ( clickedIsActive && !options.collapsible ) ||
5655                                 // allow canceling activation
5656                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5657                         return;
5658                 }
5659
5660                 options.active = collapsing ? false : this.headers.index( clicked );
5661
5662                 // when the call to ._toggle() comes after the class changes
5663                 // it causes a very odd bug in IE 8 (see #6720)
5664                 this.active = clickedIsActive ? $() : clicked;
5665                 this._toggle( eventData );
5666
5667                 // switch classes
5668                 // corner classes on the previously active header stay after the animation
5669                 active.removeClass( "ui-accordion-header-active ui-state-active" );
5670                 if ( options.icons ) {
5671                         active.children( ".ui-accordion-header-icon" )
5672                                 .removeClass( options.icons.activeHeader )
5673                                 .addClass( options.icons.header );
5674                 }
5675
5676                 if ( !clickedIsActive ) {
5677                         clicked
5678                                 .removeClass( "ui-corner-all" )
5679                                 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5680                         if ( options.icons ) {
5681                                 clicked.children( ".ui-accordion-header-icon" )
5682                                         .removeClass( options.icons.header )
5683                                         .addClass( options.icons.activeHeader );
5684                         }
5685
5686                         clicked
5687                                 .next()
5688                                 .addClass( "ui-accordion-content-active" );
5689                 }
5690         },
5691
5692         _toggle: function( data ) {
5693                 var toShow = data.newPanel,
5694                         toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5695
5696                 // handle activating a panel during the animation for another activation
5697                 this.prevShow.add( this.prevHide ).stop( true, true );
5698                 this.prevShow = toShow;
5699                 this.prevHide = toHide;
5700
5701                 if ( this.options.animate ) {
5702                         this._animate( toShow, toHide, data );
5703                 } else {
5704                         toHide.hide();
5705                         toShow.show();
5706                         this._toggleComplete( data );
5707                 }
5708
5709                 toHide.attr({
5710                         "aria-expanded": "false",
5711                         "aria-hidden": "true"
5712                 });
5713                 toHide.prev().attr( "aria-selected", "false" );
5714                 // if we're switching panels, remove the old header from the tab order
5715                 // if we're opening from collapsed state, remove the previous header from the tab order
5716                 // if we're collapsing, then keep the collapsing header in the tab order
5717                 if ( toShow.length && toHide.length ) {
5718                         toHide.prev().attr( "tabIndex", -1 );
5719                 } else if ( toShow.length ) {
5720                         this.headers.filter(function() {
5721                                 return $( this ).attr( "tabIndex" ) === 0;
5722                         })
5723                         .attr( "tabIndex", -1 );
5724                 }
5725
5726                 toShow
5727                         .attr({
5728                                 "aria-expanded": "true",
5729                                 "aria-hidden": "false"
5730                         })
5731                         .prev()
5732                                 .attr({
5733                                         "aria-selected": "true",
5734                                         tabIndex: 0
5735                                 });
5736         },
5737
5738         _animate: function( toShow, toHide, data ) {
5739                 var total, easing, duration,
5740                         that = this,
5741                         adjust = 0,
5742                         down = toShow.length &&
5743                                 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
5744                         animate = this.options.animate || {},
5745                         options = down && animate.down || animate,
5746                         complete = function() {
5747                                 that._toggleComplete( data );
5748                         };
5749
5750                 if ( typeof options === "number" ) {
5751                         duration = options;
5752                 }
5753                 if ( typeof options === "string" ) {
5754                         easing = options;
5755                 }
5756                 // fall back from options to animation in case of partial down settings
5757                 easing = easing || options.easing || animate.easing;
5758                 duration = duration || options.duration || animate.duration;
5759
5760                 if ( !toHide.length ) {
5761                         return toShow.animate( showProps, duration, easing, complete );
5762                 }
5763                 if ( !toShow.length ) {
5764                         return toHide.animate( hideProps, duration, easing, complete );
5765                 }
5766
5767                 total = toShow.show().outerHeight();
5768                 toHide.animate( hideProps, {
5769                         duration: duration,
5770                         easing: easing,
5771                         step: function( now, fx ) {
5772                                 fx.now = Math.round( now );
5773                         }
5774                 });
5775                 toShow
5776                         .hide()
5777                         .animate( showProps, {
5778                                 duration: duration,
5779                                 easing: easing,
5780                                 complete: complete,
5781                                 step: function( now, fx ) {
5782                                         fx.now = Math.round( now );
5783                                         if ( fx.prop !== "height" ) {
5784                                                 adjust += fx.now;
5785                                         } else if ( that.options.heightStyle !== "content" ) {
5786                                                 fx.now = Math.round( total - toHide.outerHeight() - adjust );
5787                                                 adjust = 0;
5788                                         }
5789                                 }
5790                         });
5791         },
5792
5793         _toggleComplete: function( data ) {
5794                 var toHide = data.oldPanel;
5795
5796                 toHide
5797                         .removeClass( "ui-accordion-content-active" )
5798                         .prev()
5799                                 .removeClass( "ui-corner-top" )
5800                                 .addClass( "ui-corner-all" );
5801
5802                 // Work around for rendering bug in IE (#5421)
5803                 if ( toHide.length ) {
5804                         toHide.parent()[0].className = toHide.parent()[0].className;
5805                 }
5806
5807                 this._trigger( "activate", null, data );
5808         }
5809 });
5810
5811 })( jQuery );
5812 (function( $, undefined ) {
5813
5814 // used to prevent race conditions with remote data sources
5815 var requestIndex = 0;
5816
5817 $.widget( "ui.autocomplete", {
5818         version: "1.10.3",
5819         defaultElement: "<input>",
5820         options: {
5821                 appendTo: null,
5822                 autoFocus: false,
5823                 delay: 300,
5824                 minLength: 1,
5825                 position: {
5826                         my: "left top",
5827                         at: "left bottom",
5828                         collision: "none"
5829                 },
5830                 source: null,
5831
5832                 // callbacks
5833                 change: null,
5834                 close: null,
5835                 focus: null,
5836                 open: null,
5837                 response: null,
5838                 search: null,
5839                 select: null
5840         },
5841
5842         pending: 0,
5843
5844         _create: function() {
5845                 // Some browsers only repeat keydown events, not keypress events,
5846                 // so we use the suppressKeyPress flag to determine if we've already
5847                 // handled the keydown event. #7269
5848                 // Unfortunately the code for & in keypress is the same as the up arrow,
5849                 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
5850                 // events when we know the keydown event was used to modify the
5851                 // search term. #7799
5852                 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5853                         nodeName = this.element[0].nodeName.toLowerCase(),
5854                         isTextarea = nodeName === "textarea",
5855                         isInput = nodeName === "input";
5856
5857                 this.isMultiLine =
5858                         // Textareas are always multi-line
5859                         isTextarea ? true :
5860                         // Inputs are always single-line, even if inside a contentEditable element
5861                         // IE also treats inputs as contentEditable
5862                         isInput ? false :
5863                         // All other element types are determined by whether or not they're contentEditable
5864                         this.element.prop( "isContentEditable" );
5865
5866                 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5867                 this.isNewMenu = true;
5868
5869                 this.element
5870                         .addClass( "ui-autocomplete-input" )
5871                         .attr( "autocomplete", "off" );
5872
5873                 this._on( this.element, {
5874                         keydown: function( event ) {
5875                                 /*jshint maxcomplexity:15*/
5876                                 if ( this.element.prop( "readOnly" ) ) {
5877                                         suppressKeyPress = true;
5878                                         suppressInput = true;
5879                                         suppressKeyPressRepeat = true;
5880                                         return;
5881                                 }
5882
5883                                 suppressKeyPress = false;
5884                                 suppressInput = false;
5885                                 suppressKeyPressRepeat = false;
5886                                 var keyCode = $.ui.keyCode;
5887                                 switch( event.keyCode ) {
5888                                 case keyCode.PAGE_UP:
5889                                         suppressKeyPress = true;
5890                                         this._move( "previousPage", event );
5891                                         break;
5892                                 case keyCode.PAGE_DOWN:
5893                                         suppressKeyPress = true;
5894                                         this._move( "nextPage", event );
5895                                         break;
5896                                 case keyCode.UP:
5897                                         suppressKeyPress = true;
5898                                         this._keyEvent( "previous", event );
5899                                         break;
5900                                 case keyCode.DOWN:
5901                                         suppressKeyPress = true;
5902                                         this._keyEvent( "next", event );
5903                                         break;
5904                                 case keyCode.ENTER:
5905                                 case keyCode.NUMPAD_ENTER:
5906                                         // when menu is open and has focus
5907                                         if ( this.menu.active ) {
5908                                                 // #6055 - Opera still allows the keypress to occur
5909                                                 // which causes forms to submit
5910                                                 suppressKeyPress = true;
5911                                                 event.preventDefault();
5912                                                 this.menu.select( event );
5913                                         }
5914                                         break;
5915                                 case keyCode.TAB:
5916                                         if ( this.menu.active ) {
5917                                                 this.menu.select( event );
5918                                         }
5919                                         break;
5920                                 case keyCode.ESCAPE:
5921                                         if ( this.menu.element.is( ":visible" ) ) {
5922                                                 this._value( this.term );
5923                                                 this.close( event );
5924                                                 // Different browsers have different default behavior for escape
5925                                                 // Single press can mean undo or clear
5926                                                 // Double press in IE means clear the whole form
5927                                                 event.preventDefault();
5928                                         }
5929                                         break;
5930                                 default:
5931                                         suppressKeyPressRepeat = true;
5932                                         // search timeout should be triggered before the input value is changed
5933                                         this._searchTimeout( event );
5934                                         break;
5935                                 }
5936                         },
5937                         keypress: function( event ) {
5938                                 if ( suppressKeyPress ) {
5939                                         suppressKeyPress = false;
5940                                         if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5941                                                 event.preventDefault();
5942                                         }
5943                                         return;
5944                                 }
5945                                 if ( suppressKeyPressRepeat ) {
5946                                         return;
5947                                 }
5948
5949                                 // replicate some key handlers to allow them to repeat in Firefox and Opera
5950                                 var keyCode = $.ui.keyCode;
5951                                 switch( event.keyCode ) {
5952                                 case keyCode.PAGE_UP:
5953                                         this._move( "previousPage", event );
5954                                         break;
5955                                 case keyCode.PAGE_DOWN:
5956                                         this._move( "nextPage", event );
5957                                         break;
5958                                 case keyCode.UP:
5959                                         this._keyEvent( "previous", event );
5960                                         break;
5961                                 case keyCode.DOWN:
5962                                         this._keyEvent( "next", event );
5963                                         break;
5964                                 }
5965                         },
5966                         input: function( event ) {
5967                                 if ( suppressInput ) {
5968                                         suppressInput = false;
5969                                         event.preventDefault();
5970                                         return;
5971                                 }
5972                                 this._searchTimeout( event );
5973                         },
5974                         focus: function() {
5975                                 this.selectedItem = null;
5976                                 this.previous = this._value();
5977                         },
5978                         blur: function( event ) {
5979                                 if ( this.cancelBlur ) {
5980                                         delete this.cancelBlur;
5981                                         return;
5982                                 }
5983
5984                                 clearTimeout( this.searching );
5985                                 this.close( event );
5986                                 this._change( event );
5987                         }
5988                 });
5989
5990                 this._initSource();
5991                 this.menu = $( "<ul>" )
5992                         .addClass( "ui-autocomplete ui-front" )
5993                         .appendTo( this._appendTo() )
5994                         .menu({
5995                                 // disable ARIA support, the live region takes care of that
5996                                 role: null
5997                         })
5998                         .hide()
5999                         .data( "ui-menu" );
6000
6001                 this._on( this.menu.element, {
6002                         mousedown: function( event ) {
6003                                 // prevent moving focus out of the text field
6004                                 event.preventDefault();
6005
6006                                 // IE doesn't prevent moving focus even with event.preventDefault()
6007                                 // so we set a flag to know when we should ignore the blur event
6008                                 this.cancelBlur = true;
6009                                 this._delay(function() {
6010                                         delete this.cancelBlur;
6011                                 });
6012
6013                                 // clicking on the scrollbar causes focus to shift to the body
6014                                 // but we can't detect a mouseup or a click immediately afterward
6015                                 // so we have to track the next mousedown and close the menu if
6016                                 // the user clicks somewhere outside of the autocomplete
6017                                 var menuElement = this.menu.element[ 0 ];
6018                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6019                                         this._delay(function() {
6020                                                 var that = this;
6021                                                 this.document.one( "mousedown", function( event ) {
6022                                                         if ( event.target !== that.element[ 0 ] &&
6023                                                                         event.target !== menuElement &&
6024                                                                         !$.contains( menuElement, event.target ) ) {
6025                                                                 that.close();
6026                                                         }
6027                                                 });
6028                                         });
6029                                 }
6030                         },
6031                         menufocus: function( event, ui ) {
6032                                 // support: Firefox
6033                                 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
6034                                 if ( this.isNewMenu ) {
6035                                         this.isNewMenu = false;
6036                                         if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6037                                                 this.menu.blur();
6038
6039                                                 this.document.one( "mousemove", function() {
6040                                                         $( event.target ).trigger( event.originalEvent );
6041                                                 });
6042
6043                                                 return;
6044                                         }
6045                                 }
6046
6047                                 var item = ui.item.data( "ui-autocomplete-item" );
6048                                 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6049                                         // use value to match what will end up in the input, if it was a key event
6050                                         if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6051                                                 this._value( item.value );
6052                                         }
6053                                 } else {
6054                                         // Normally the input is populated with the item's value as the
6055                                         // menu is navigated, causing screen readers to notice a change and
6056                                         // announce the item. Since the focus event was canceled, this doesn't
6057                                         // happen, so we update the live region so that screen readers can
6058                                         // still notice the change and announce it.
6059                                         this.liveRegion.text( item.value );
6060                                 }
6061                         },
6062                         menuselect: function( event, ui ) {
6063                                 var item = ui.item.data( "ui-autocomplete-item" ),
6064                                         previous = this.previous;
6065
6066                                 // only trigger when focus was lost (click on menu)
6067                                 if ( this.element[0] !== this.document[0].activeElement ) {
6068                                         this.element.focus();
6069                                         this.previous = previous;
6070                                         // #6109 - IE triggers two focus events and the second
6071                                         // is asynchronous, so we need to reset the previous
6072                                         // term synchronously and asynchronously :-(
6073                                         this._delay(function() {
6074                                                 this.previous = previous;
6075                                                 this.selectedItem = item;
6076                                         });
6077                                 }
6078
6079                                 if ( false !== this._trigger( "select", event, { item: item } ) ) {
6080                                         this._value( item.value );
6081                                 }
6082                                 // reset the term after the select event
6083                                 // this allows custom select handling to work properly
6084                                 this.term = this._value();
6085
6086                                 this.close( event );
6087                                 this.selectedItem = item;
6088                         }
6089                 });
6090
6091                 this.liveRegion = $( "<span>", {
6092                                 role: "status",
6093                                 "aria-live": "polite"
6094                         })
6095                         .addClass( "ui-helper-hidden-accessible" )
6096                         .insertBefore( this.element );
6097
6098                 // turning off autocomplete prevents the browser from remembering the
6099                 // value when navigating through history, so we re-enable autocomplete
6100                 // if the page is unloaded before the widget is destroyed. #7790
6101                 this._on( this.window, {
6102                         beforeunload: function() {
6103                                 this.element.removeAttr( "autocomplete" );
6104                         }
6105                 });
6106         },
6107
6108         _destroy: function() {
6109                 clearTimeout( this.searching );
6110                 this.element
6111                         .removeClass( "ui-autocomplete-input" )
6112                         .removeAttr( "autocomplete" );
6113                 this.menu.element.remove();
6114                 this.liveRegion.remove();
6115         },
6116
6117         _setOption: function( key, value ) {
6118                 this._super( key, value );
6119                 if ( key === "source" ) {
6120                         this._initSource();
6121                 }
6122                 if ( key === "appendTo" ) {
6123                         this.menu.element.appendTo( this._appendTo() );
6124                 }
6125                 if ( key === "disabled" && value && this.xhr ) {
6126                         this.xhr.abort();
6127                 }
6128         },
6129
6130         _appendTo: function() {
6131                 var element = this.options.appendTo;
6132
6133                 if ( element ) {
6134                         element = element.jquery || element.nodeType ?
6135                                 $( element ) :
6136                                 this.document.find( element ).eq( 0 );
6137                 }
6138
6139                 if ( !element ) {
6140                         element = this.element.closest( ".ui-front" );
6141                 }
6142
6143                 if ( !element.length ) {
6144                         element = this.document[0].body;
6145                 }
6146
6147                 return element;
6148         },
6149
6150         _initSource: function() {
6151                 var array, url,
6152                         that = this;
6153                 if ( $.isArray(this.options.source) ) {
6154                         array = this.options.source;
6155                         this.source = function( request, response ) {
6156                                 response( $.ui.autocomplete.filter( array, request.term ) );
6157                         };
6158                 } else if ( typeof this.options.source === "string" ) {
6159                         url = this.options.source;
6160                         this.source = function( request, response ) {
6161                                 if ( that.xhr ) {
6162                                         that.xhr.abort();
6163                                 }
6164                                 that.xhr = $.ajax({
6165                                         url: url,
6166                                         data: request,
6167                                         dataType: "json",
6168                                         success: function( data ) {
6169                                                 response( data );
6170                                         },
6171                                         error: function() {
6172                                                 response( [] );
6173                                         }
6174                                 });
6175                         };
6176                 } else {
6177                         this.source = this.options.source;
6178                 }
6179         },
6180
6181         _searchTimeout: function( event ) {
6182                 clearTimeout( this.searching );
6183                 this.searching = this._delay(function() {
6184                         // only search if the value has changed
6185                         if ( this.term !== this._value() ) {
6186                                 this.selectedItem = null;
6187                                 this.search( null, event );
6188                         }
6189                 }, this.options.delay );
6190         },
6191
6192         search: function( value, event ) {
6193                 value = value != null ? value : this._value();
6194
6195                 // always save the actual value, not the one passed as an argument
6196                 this.term = this._value();
6197
6198                 if ( value.length < this.options.minLength ) {
6199                         return this.close( event );
6200                 }
6201
6202                 if ( this._trigger( "search", event ) === false ) {
6203                         return;
6204                 }
6205
6206                 return this._search( value );
6207         },
6208
6209         _search: function( value ) {
6210                 this.pending++;
6211                 this.element.addClass( "ui-autocomplete-loading" );
6212                 this.cancelSearch = false;
6213
6214                 this.source( { term: value }, this._response() );
6215         },
6216
6217         _response: function() {
6218                 var that = this,
6219                         index = ++requestIndex;
6220
6221                 return function( content ) {
6222                         if ( index === requestIndex ) {
6223                                 that.__response( content );
6224                         }
6225
6226                         that.pending--;
6227                         if ( !that.pending ) {
6228                                 that.element.removeClass( "ui-autocomplete-loading" );
6229                         }
6230                 };
6231         },
6232
6233         __response: function( content ) {
6234                 if ( content ) {
6235                         content = this._normalize( content );
6236                 }
6237                 this._trigger( "response", null, { content: content } );
6238                 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6239                         this._suggest( content );
6240                         this._trigger( "open" );
6241                 } else {
6242                         // use ._close() instead of .close() so we don't cancel future searches
6243                         this._close();
6244                 }
6245         },
6246
6247         close: function( event ) {
6248                 this.cancelSearch = true;
6249                 this._close( event );
6250         },
6251
6252         _close: function( event ) {
6253                 if ( this.menu.element.is( ":visible" ) ) {
6254                         this.menu.element.hide();
6255                         this.menu.blur();
6256                         this.isNewMenu = true;
6257                         this._trigger( "close", event );
6258                 }
6259         },
6260
6261         _change: function( event ) {
6262                 if ( this.previous !== this._value() ) {
6263                         this._trigger( "change", event, { item: this.selectedItem } );
6264                 }
6265         },
6266
6267         _normalize: function( items ) {
6268                 // assume all items have the right format when the first item is complete
6269                 if ( items.length && items[0].label && items[0].value ) {
6270                         return items;
6271                 }
6272                 return $.map( items, function( item ) {
6273                         if ( typeof item === "string" ) {
6274                                 return {
6275                                         label: item,
6276                                         value: item
6277                                 };
6278                         }
6279                         return $.extend({
6280                                 label: item.label || item.value,
6281                                 value: item.value || item.label
6282                         }, item );
6283                 });
6284         },
6285
6286         _suggest: function( items ) {
6287                 var ul = this.menu.element.empty();
6288                 this._renderMenu( ul, items );
6289                 this.isNewMenu = true;
6290                 this.menu.refresh();
6291
6292                 // size and position menu
6293                 ul.show();
6294                 this._resizeMenu();
6295                 ul.position( $.extend({
6296                         of: this.element
6297                 }, this.options.position ));
6298
6299                 if ( this.options.autoFocus ) {
6300                         this.menu.next();
6301                 }
6302         },
6303
6304         _resizeMenu: function() {
6305                 var ul = this.menu.element;
6306                 ul.outerWidth( Math.max(
6307                         // Firefox wraps long text (possibly a rounding bug)
6308                         // so we add 1px to avoid the wrapping (#7513)
6309                         ul.width( "" ).outerWidth() + 1,
6310                         this.element.outerWidth()
6311                 ) );
6312         },
6313
6314         _renderMenu: function( ul, items ) {
6315                 var that = this;
6316                 $.each( items, function( index, item ) {
6317                         that._renderItemData( ul, item );
6318                 });
6319         },
6320
6321         _renderItemData: function( ul, item ) {
6322                 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6323         },
6324
6325         _renderItem: function( ul, item ) {
6326                 return $( "<li>" )
6327                         .append( $( "<a>" ).text( item.label ) )
6328                         .appendTo( ul );
6329         },
6330
6331         _move: function( direction, event ) {
6332                 if ( !this.menu.element.is( ":visible" ) ) {
6333                         this.search( null, event );
6334                         return;
6335                 }
6336                 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6337                                 this.menu.isLastItem() && /^next/.test( direction ) ) {
6338                         this._value( this.term );
6339                         this.menu.blur();
6340                         return;
6341                 }
6342                 this.menu[ direction ]( event );
6343         },
6344
6345         widget: function() {
6346                 return this.menu.element;
6347         },
6348
6349         _value: function() {
6350                 return this.valueMethod.apply( this.element, arguments );
6351         },
6352
6353         _keyEvent: function( keyEvent, event ) {
6354                 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6355                         this._move( keyEvent, event );
6356
6357                         // prevents moving cursor to beginning/end of the text field in some browsers
6358                         event.preventDefault();
6359                 }
6360         }
6361 });
6362
6363 $.extend( $.ui.autocomplete, {
6364         escapeRegex: function( value ) {
6365                 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
6366         },
6367         filter: function(array, term) {
6368                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6369                 return $.grep( array, function(value) {
6370                         return matcher.test( value.label || value.value || value );
6371                 });
6372         }
6373 });
6374
6375
6376 // live region extension, adding a `messages` option
6377 // NOTE: This is an experimental API. We are still investigating
6378 // a full solution for string manipulation and internationalization.
6379 $.widget( "ui.autocomplete", $.ui.autocomplete, {
6380         options: {
6381                 messages: {
6382                         noResults: "No search results.",
6383                         results: function( amount ) {
6384                                 return amount + ( amount > 1 ? " results are" : " result is" ) +
6385                                         " available, use up and down arrow keys to navigate.";
6386                         }
6387                 }
6388         },
6389
6390         __response: function( content ) {
6391                 var message;
6392                 this._superApply( arguments );
6393                 if ( this.options.disabled || this.cancelSearch ) {
6394                         return;
6395                 }
6396                 if ( content && content.length ) {
6397                         message = this.options.messages.results( content.length );
6398                 } else {
6399                         message = this.options.messages.noResults;
6400                 }
6401                 this.liveRegion.text( message );
6402         }
6403 });
6404
6405 }( jQuery ));
6406 (function( $, undefined ) {
6407
6408 var lastActive, startXPos, startYPos, clickDragged,
6409         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6410         stateClasses = "ui-state-hover ui-state-active ",
6411         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",
6412         formResetHandler = function() {
6413                 var form = $( this );
6414                 setTimeout(function() {
6415                         form.find( ":ui-button" ).button( "refresh" );
6416                 }, 1 );
6417         },
6418         radioGroup = function( radio ) {
6419                 var name = radio.name,
6420                         form = radio.form,
6421                         radios = $( [] );
6422                 if ( name ) {
6423                         name = name.replace( /'/g, "\\'" );
6424                         if ( form ) {
6425                                 radios = $( form ).find( "[name='" + name + "']" );
6426                         } else {
6427                                 radios = $( "[name='" + name + "']", radio.ownerDocument )
6428                                         .filter(function() {
6429                                                 return !this.form;
6430                                         });
6431                         }
6432                 }
6433                 return radios;
6434         };
6435
6436 $.widget( "ui.button", {
6437         version: "1.10.3",
6438         defaultElement: "<button>",
6439         options: {
6440                 disabled: null,
6441                 text: true,
6442                 label: null,
6443                 icons: {
6444                         primary: null,
6445                         secondary: null
6446                 }
6447         },
6448         _create: function() {
6449                 this.element.closest( "form" )
6450                         .unbind( "reset" + this.eventNamespace )
6451                         .bind( "reset" + this.eventNamespace, formResetHandler );
6452
6453                 if ( typeof this.options.disabled !== "boolean" ) {
6454                         this.options.disabled = !!this.element.prop( "disabled" );
6455                 } else {
6456                         this.element.prop( "disabled", this.options.disabled );
6457                 }
6458
6459                 this._determineButtonType();
6460                 this.hasTitle = !!this.buttonElement.attr( "title" );
6461
6462                 var that = this,
6463                         options = this.options,
6464                         toggleButton = this.type === "checkbox" || this.type === "radio",
6465                         activeClass = !toggleButton ? "ui-state-active" : "",
6466                         focusClass = "ui-state-focus";
6467
6468                 if ( options.label === null ) {
6469                         options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6470                 }
6471
6472                 this._hoverable( this.buttonElement );
6473
6474                 this.buttonElement
6475                         .addClass( baseClasses )
6476                         .attr( "role", "button" )
6477                         .bind( "mouseenter" + this.eventNamespace, function() {
6478                                 if ( options.disabled ) {
6479                                         return;
6480                                 }
6481                                 if ( this === lastActive ) {
6482                                         $( this ).addClass( "ui-state-active" );
6483                                 }
6484                         })
6485                         .bind( "mouseleave" + this.eventNamespace, function() {
6486                                 if ( options.disabled ) {
6487                                         return;
6488                                 }
6489                                 $( this ).removeClass( activeClass );
6490                         })
6491                         .bind( "click" + this.eventNamespace, function( event ) {
6492                                 if ( options.disabled ) {
6493                                         event.preventDefault();
6494                                         event.stopImmediatePropagation();
6495                                 }
6496                         });
6497
6498                 this.element
6499                         .bind( "focus" + this.eventNamespace, function() {
6500                                 // no need to check disabled, focus won't be triggered anyway
6501                                 that.buttonElement.addClass( focusClass );
6502                         })
6503                         .bind( "blur" + this.eventNamespace, function() {
6504                                 that.buttonElement.removeClass( focusClass );
6505                         });
6506
6507                 if ( toggleButton ) {
6508                         this.element.bind( "change" + this.eventNamespace, function() {
6509                                 if ( clickDragged ) {
6510                                         return;
6511                                 }
6512                                 that.refresh();
6513                         });
6514                         // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6515                         // prevents issue where button state changes but checkbox/radio checked state
6516                         // does not in Firefox (see ticket #6970)
6517                         this.buttonElement
6518                                 .bind( "mousedown" + this.eventNamespace, function( event ) {
6519                                         if ( options.disabled ) {
6520                                                 return;
6521                                         }
6522                                         clickDragged = false;
6523                                         startXPos = event.pageX;
6524                                         startYPos = event.pageY;
6525                                 })
6526                                 .bind( "mouseup" + this.eventNamespace, function( event ) {
6527                                         if ( options.disabled ) {
6528                                                 return;
6529                                         }
6530                                         if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6531                                                 clickDragged = true;
6532                                         }
6533                         });
6534                 }
6535
6536                 if ( this.type === "checkbox" ) {
6537                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
6538                                 if ( options.disabled || clickDragged ) {
6539                                         return false;
6540                                 }
6541                         });
6542                 } else if ( this.type === "radio" ) {
6543                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
6544                                 if ( options.disabled || clickDragged ) {
6545                                         return false;
6546                                 }
6547                                 $( this ).addClass( "ui-state-active" );
6548                                 that.buttonElement.attr( "aria-pressed", "true" );
6549
6550                                 var radio = that.element[ 0 ];
6551                                 radioGroup( radio )
6552                                         .not( radio )
6553                                         .map(function() {
6554                                                 return $( this ).button( "widget" )[ 0 ];
6555                                         })
6556                                         .removeClass( "ui-state-active" )
6557                                         .attr( "aria-pressed", "false" );
6558                         });
6559                 } else {
6560                         this.buttonElement
6561                                 .bind( "mousedown" + this.eventNamespace, function() {
6562                                         if ( options.disabled ) {
6563                                                 return false;
6564                                         }
6565                                         $( this ).addClass( "ui-state-active" );
6566                                         lastActive = this;
6567                                         that.document.one( "mouseup", function() {
6568                                                 lastActive = null;
6569                                         });
6570                                 })
6571                                 .bind( "mouseup" + this.eventNamespace, function() {
6572                                         if ( options.disabled ) {
6573                                                 return false;
6574                                         }
6575                                         $( this ).removeClass( "ui-state-active" );
6576                                 })
6577                                 .bind( "keydown" + this.eventNamespace, function(event) {
6578                                         if ( options.disabled ) {
6579                                                 return false;
6580                                         }
6581                                         if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6582                                                 $( this ).addClass( "ui-state-active" );
6583                                         }
6584                                 })
6585                                 // see #8559, we bind to blur here in case the button element loses
6586                                 // focus between keydown and keyup, it would be left in an "active" state
6587                                 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
6588                                         $( this ).removeClass( "ui-state-active" );
6589                                 });
6590
6591                         if ( this.buttonElement.is("a") ) {
6592                                 this.buttonElement.keyup(function(event) {
6593                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
6594                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
6595                                                 $( this ).click();
6596                                         }
6597                                 });
6598                         }
6599                 }
6600
6601                 // TODO: pull out $.Widget's handling for the disabled option into
6602                 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
6603                 // be overridden by individual plugins
6604                 this._setOption( "disabled", options.disabled );
6605                 this._resetButton();
6606         },
6607
6608         _determineButtonType: function() {
6609                 var ancestor, labelSelector, checked;
6610
6611                 if ( this.element.is("[type=checkbox]") ) {
6612                         this.type = "checkbox";
6613                 } else if ( this.element.is("[type=radio]") ) {
6614                         this.type = "radio";
6615                 } else if ( this.element.is("input") ) {
6616                         this.type = "input";
6617                 } else {
6618                         this.type = "button";
6619                 }
6620
6621                 if ( this.type === "checkbox" || this.type === "radio" ) {
6622                         // we don't search against the document in case the element
6623                         // is disconnected from the DOM
6624                         ancestor = this.element.parents().last();
6625                         labelSelector = "label[for='" + this.element.attr("id") + "']";
6626                         this.buttonElement = ancestor.find( labelSelector );
6627                         if ( !this.buttonElement.length ) {
6628                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
6629                                 this.buttonElement = ancestor.filter( labelSelector );
6630                                 if ( !this.buttonElement.length ) {
6631                                         this.buttonElement = ancestor.find( labelSelector );
6632                                 }
6633                         }
6634                         this.element.addClass( "ui-helper-hidden-accessible" );
6635
6636                         checked = this.element.is( ":checked" );
6637                         if ( checked ) {
6638                                 this.buttonElement.addClass( "ui-state-active" );
6639                         }
6640                         this.buttonElement.prop( "aria-pressed", checked );
6641                 } else {
6642                         this.buttonElement = this.element;
6643                 }
6644         },
6645
6646         widget: function() {
6647                 return this.buttonElement;
6648         },
6649
6650         _destroy: function() {
6651                 this.element
6652                         .removeClass( "ui-helper-hidden-accessible" );
6653                 this.buttonElement
6654                         .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
6655                         .removeAttr( "role" )
6656                         .removeAttr( "aria-pressed" )
6657                         .html( this.buttonElement.find(".ui-button-text").html() );
6658
6659                 if ( !this.hasTitle ) {
6660                         this.buttonElement.removeAttr( "title" );
6661                 }
6662         },
6663
6664         _setOption: function( key, value ) {
6665                 this._super( key, value );
6666                 if ( key === "disabled" ) {
6667                         if ( value ) {
6668                                 this.element.prop( "disabled", true );
6669                         } else {
6670                                 this.element.prop( "disabled", false );
6671                         }
6672                         return;
6673                 }
6674                 this._resetButton();
6675         },
6676
6677         refresh: function() {
6678                 //See #8237 & #8828
6679                 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
6680
6681                 if ( isDisabled !== this.options.disabled ) {
6682                         this._setOption( "disabled", isDisabled );
6683                 }
6684                 if ( this.type === "radio" ) {
6685                         radioGroup( this.element[0] ).each(function() {
6686                                 if ( $( this ).is( ":checked" ) ) {
6687                                         $( this ).button( "widget" )
6688                                                 .addClass( "ui-state-active" )
6689                                                 .attr( "aria-pressed", "true" );
6690                                 } else {
6691                                         $( this ).button( "widget" )
6692                                                 .removeClass( "ui-state-active" )
6693                                                 .attr( "aria-pressed", "false" );
6694                                 }
6695                         });
6696                 } else if ( this.type === "checkbox" ) {
6697                         if ( this.element.is( ":checked" ) ) {
6698                                 this.buttonElement
6699                                         .addClass( "ui-state-active" )
6700                                         .attr( "aria-pressed", "true" );
6701                         } else {
6702                                 this.buttonElement
6703                                         .removeClass( "ui-state-active" )
6704                                         .attr( "aria-pressed", "false" );
6705                         }
6706                 }
6707         },
6708
6709         _resetButton: function() {
6710                 if ( this.type === "input" ) {
6711                         if ( this.options.label ) {
6712                                 this.element.val( this.options.label );
6713                         }
6714                         return;
6715                 }
6716                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
6717                         buttonText = $( "<span></span>", this.document[0] )
6718                                 .addClass( "ui-button-text" )
6719                                 .html( this.options.label )
6720                                 .appendTo( buttonElement.empty() )
6721                                 .text(),
6722                         icons = this.options.icons,
6723                         multipleIcons = icons.primary && icons.secondary,
6724                         buttonClasses = [];
6725
6726                 if ( icons.primary || icons.secondary ) {
6727                         if ( this.options.text ) {
6728                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
6729                         }
6730
6731                         if ( icons.primary ) {
6732                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
6733                         }
6734
6735                         if ( icons.secondary ) {
6736                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
6737                         }
6738
6739                         if ( !this.options.text ) {
6740                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
6741
6742                                 if ( !this.hasTitle ) {
6743                                         buttonElement.attr( "title", $.trim( buttonText ) );
6744                                 }
6745                         }
6746                 } else {
6747                         buttonClasses.push( "ui-button-text-only" );
6748                 }
6749                 buttonElement.addClass( buttonClasses.join( " " ) );
6750         }
6751 });
6752
6753 $.widget( "ui.buttonset", {
6754         version: "1.10.3",
6755         options: {
6756                 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
6757         },
6758
6759         _create: function() {
6760                 this.element.addClass( "ui-buttonset" );
6761         },
6762
6763         _init: function() {
6764                 this.refresh();
6765         },
6766
6767         _setOption: function( key, value ) {
6768                 if ( key === "disabled" ) {
6769                         this.buttons.button( "option", key, value );
6770                 }
6771
6772                 this._super( key, value );
6773         },
6774
6775         refresh: function() {
6776                 var rtl = this.element.css( "direction" ) === "rtl";
6777
6778                 this.buttons = this.element.find( this.options.items )
6779                         .filter( ":ui-button" )
6780                                 .button( "refresh" )
6781                         .end()
6782                         .not( ":ui-button" )
6783                                 .button()
6784                         .end()
6785                         .map(function() {
6786                                 return $( this ).button( "widget" )[ 0 ];
6787                         })
6788                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
6789                                 .filter( ":first" )
6790                                         .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
6791                                 .end()
6792                                 .filter( ":last" )
6793                                         .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
6794                                 .end()
6795                         .end();
6796         },
6797
6798         _destroy: function() {
6799                 this.element.removeClass( "ui-buttonset" );
6800                 this.buttons
6801                         .map(function() {
6802                                 return $( this ).button( "widget" )[ 0 ];
6803                         })
6804                                 .removeClass( "ui-corner-left ui-corner-right" )
6805                         .end()
6806                         .button( "destroy" );
6807         }
6808 });
6809
6810 }( jQuery ) );
6811 (function( $, undefined ) {
6812
6813 $.extend($.ui, { datepicker: { version: "1.10.3" } });
6814
6815 var PROP_NAME = "datepicker",
6816         instActive;
6817
6818 /* Date picker manager.
6819    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
6820    Settings for (groups of) date pickers are maintained in an instance object,
6821    allowing multiple different settings on the same page. */
6822
6823 function Datepicker() {
6824         this._curInst = null; // The current instance in use
6825         this._keyEvent = false; // If the last event was a key event
6826         this._disabledInputs = []; // List of date picker inputs that have been disabled
6827         this._datepickerShowing = false; // True if the popup picker is showing , false if not
6828         this._inDialog = false; // True if showing within a "dialog", false if not
6829         this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
6830         this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
6831         this._appendClass = "ui-datepicker-append"; // The name of the append marker class
6832         this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
6833         this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
6834         this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
6835         this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
6836         this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
6837         this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
6838         this.regional = []; // Available regional settings, indexed by language code
6839         this.regional[""] = { // Default regional settings
6840                 closeText: "Done", // Display text for close link
6841                 prevText: "Prev", // Display text for previous month link
6842                 nextText: "Next", // Display text for next month link
6843                 currentText: "Today", // Display text for current month link
6844                 monthNames: ["January","February","March","April","May","June",
6845                         "July","August","September","October","November","December"], // Names of months for drop-down and formatting
6846                 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
6847                 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
6848                 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
6849                 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
6850                 weekHeader: "Wk", // Column header for week of the year
6851                 dateFormat: "mm/dd/yy", // See format options on parseDate
6852                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
6853                 isRTL: false, // True if right-to-left language, false if left-to-right
6854                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
6855                 yearSuffix: "" // Additional text to append to the year in the month headers
6856         };
6857         this._defaults = { // Global defaults for all the date picker instances
6858                 showOn: "focus", // "focus" for popup on focus,
6859                         // "button" for trigger button, or "both" for either
6860                 showAnim: "fadeIn", // Name of jQuery animation for popup
6861                 showOptions: {}, // Options for enhanced animations
6862                 defaultDate: null, // Used when field is blank: actual date,
6863                         // +/-number for offset from today, null for today
6864                 appendText: "", // Display text following the input box, e.g. showing the format
6865                 buttonText: "...", // Text for trigger button
6866                 buttonImage: "", // URL for trigger button image
6867                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
6868                 hideIfNoPrevNext: false, // True to hide next/previous month links
6869                         // if not applicable, false to just disable them
6870                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
6871                 gotoCurrent: false, // True if today link goes back to current selection instead
6872                 changeMonth: false, // True if month can be selected directly, false if only prev/next
6873                 changeYear: false, // True if year can be selected directly, false if only prev/next
6874                 yearRange: "c-10:c+10", // Range of years to display in drop-down,
6875                         // either relative to today's year (-nn:+nn), relative to currently displayed year
6876                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
6877                 showOtherMonths: false, // True to show dates in other months, false to leave blank
6878                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
6879                 showWeek: false, // True to show week of the year, false to not show it
6880                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
6881                         // takes a Date and returns the number of the week for it
6882                 shortYearCutoff: "+10", // Short year values < this are in the current century,
6883                         // > this are in the previous century,
6884                         // string value starting with "+" for current year + value
6885                 minDate: null, // The earliest selectable date, or null for no limit
6886                 maxDate: null, // The latest selectable date, or null for no limit
6887                 duration: "fast", // Duration of display/closure
6888                 beforeShowDay: null, // Function that takes a date and returns an array with
6889                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
6890                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
6891                 beforeShow: null, // Function that takes an input field and
6892                         // returns a set of custom settings for the date picker
6893                 onSelect: null, // Define a callback function when a date is selected
6894                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
6895                 onClose: null, // Define a callback function when the datepicker is closed
6896                 numberOfMonths: 1, // Number of months to show at a time
6897                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
6898                 stepMonths: 1, // Number of months to step back/forward
6899                 stepBigMonths: 12, // Number of months to step back/forward for the big links
6900                 altField: "", // Selector for an alternate field to store selected dates into
6901                 altFormat: "", // The date format to use for the alternate field
6902                 constrainInput: true, // The input is constrained by the current date format
6903                 showButtonPanel: false, // True to show button panel, false to not show it
6904                 autoSize: false, // True to size the input for the date format, false to leave as is
6905                 disabled: false // The initial disabled state
6906         };
6907         $.extend(this._defaults, this.regional[""]);
6908         this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
6909 }
6910
6911 $.extend(Datepicker.prototype, {
6912         /* Class name added to elements to indicate already configured with a date picker. */
6913         markerClassName: "hasDatepicker",
6914
6915         //Keep track of the maximum number of rows displayed (see #7043)
6916         maxRows: 4,
6917
6918         // TODO rename to "widget" when switching to widget factory
6919         _widgetDatepicker: function() {
6920                 return this.dpDiv;
6921         },
6922
6923         /* Override the default settings for all instances of the date picker.
6924          * @param  settings  object - the new settings to use as defaults (anonymous object)
6925          * @return the manager object
6926          */
6927         setDefaults: function(settings) {
6928                 extendRemove(this._defaults, settings || {});
6929                 return this;
6930         },
6931
6932         /* Attach the date picker to a jQuery selection.
6933          * @param  target       element - the target input field or division or span
6934          * @param  settings  object - the new settings to use for this date picker instance (anonymous)
6935          */
6936         _attachDatepicker: function(target, settings) {
6937                 var nodeName, inline, inst;
6938                 nodeName = target.nodeName.toLowerCase();
6939                 inline = (nodeName === "div" || nodeName === "span");
6940                 if (!target.id) {
6941                         this.uuid += 1;
6942                         target.id = "dp" + this.uuid;
6943                 }
6944                 inst = this._newInst($(target), inline);
6945                 inst.settings = $.extend({}, settings || {});
6946                 if (nodeName === "input") {
6947                         this._connectDatepicker(target, inst);
6948                 } else if (inline) {
6949                         this._inlineDatepicker(target, inst);
6950                 }
6951         },
6952
6953         /* Create a new instance object. */
6954         _newInst: function(target, inline) {
6955                 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
6956                 return {id: id, input: target, // associated target
6957                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
6958                         drawMonth: 0, drawYear: 0, // month being drawn
6959                         inline: inline, // is datepicker inline or not
6960                         dpDiv: (!inline ? this.dpDiv : // presentation div
6961                         bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
6962         },
6963
6964         /* Attach the date picker to an input field. */
6965         _connectDatepicker: function(target, inst) {
6966                 var input = $(target);
6967                 inst.append = $([]);
6968                 inst.trigger = $([]);
6969                 if (input.hasClass(this.markerClassName)) {
6970                         return;
6971                 }
6972                 this._attachments(input, inst);
6973                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
6974                         keypress(this._doKeyPress).keyup(this._doKeyUp);
6975                 this._autoSize(inst);
6976                 $.data(target, PROP_NAME, inst);
6977                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
6978                 if( inst.settings.disabled ) {
6979                         this._disableDatepicker( target );
6980                 }
6981         },
6982
6983         /* Make attachments based on settings. */
6984         _attachments: function(input, inst) {
6985                 var showOn, buttonText, buttonImage,
6986                         appendText = this._get(inst, "appendText"),
6987                         isRTL = this._get(inst, "isRTL");
6988
6989                 if (inst.append) {
6990                         inst.append.remove();
6991                 }
6992                 if (appendText) {
6993                         inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
6994                         input[isRTL ? "before" : "after"](inst.append);
6995                 }
6996
6997                 input.unbind("focus", this._showDatepicker);
6998
6999                 if (inst.trigger) {
7000                         inst.trigger.remove();
7001                 }
7002
7003                 showOn = this._get(inst, "showOn");
7004                 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7005                         input.focus(this._showDatepicker);
7006                 }
7007                 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7008                         buttonText = this._get(inst, "buttonText");
7009                         buttonImage = this._get(inst, "buttonImage");
7010                         inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7011                                 $("<img/>").addClass(this._triggerClass).
7012                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7013                                 $("<button type='button'></button>").addClass(this._triggerClass).
7014                                         html(!buttonImage ? buttonText : $("<img/>").attr(
7015                                         { src:buttonImage, alt:buttonText, title:buttonText })));
7016                         input[isRTL ? "before" : "after"](inst.trigger);
7017                         inst.trigger.click(function() {
7018                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7019                                         $.datepicker._hideDatepicker();
7020                                 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7021                                         $.datepicker._hideDatepicker();
7022                                         $.datepicker._showDatepicker(input[0]);
7023                                 } else {
7024                                         $.datepicker._showDatepicker(input[0]);
7025                                 }
7026                                 return false;
7027                         });
7028                 }
7029         },
7030
7031         /* Apply the maximum length for the date format. */
7032         _autoSize: function(inst) {
7033                 if (this._get(inst, "autoSize") && !inst.inline) {
7034                         var findMax, max, maxI, i,
7035                                 date = new Date(2009, 12 - 1, 20), // Ensure double digits
7036                                 dateFormat = this._get(inst, "dateFormat");
7037
7038                         if (dateFormat.match(/[DM]/)) {
7039                                 findMax = function(names) {
7040                                         max = 0;
7041                                         maxI = 0;
7042                                         for (i = 0; i < names.length; i++) {
7043                                                 if (names[i].length > max) {
7044                                                         max = names[i].length;
7045                                                         maxI = i;
7046                                                 }
7047                                         }
7048                                         return maxI;
7049                                 };
7050                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7051                                         "monthNames" : "monthNamesShort"))));
7052                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7053                                         "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7054                         }
7055                         inst.input.attr("size", this._formatDate(inst, date).length);
7056                 }
7057         },
7058
7059         /* Attach an inline date picker to a div. */
7060         _inlineDatepicker: function(target, inst) {
7061                 var divSpan = $(target);
7062                 if (divSpan.hasClass(this.markerClassName)) {
7063                         return;
7064                 }
7065                 divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7066                 $.data(target, PROP_NAME, inst);
7067                 this._setDate(inst, this._getDefaultDate(inst), true);
7068                 this._updateDatepicker(inst);
7069                 this._updateAlternate(inst);
7070                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7071                 if( inst.settings.disabled ) {
7072                         this._disableDatepicker( target );
7073                 }
7074                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7075                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7076                 inst.dpDiv.css( "display", "block" );
7077         },
7078
7079         /* Pop-up the date picker in a "dialog" box.
7080          * @param  input element - ignored
7081          * @param  date string or Date - the initial date to display
7082          * @param  onSelect  function - the function to call when a date is selected
7083          * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7084          * @param  pos int[2] - coordinates for the dialog's position within the screen or
7085          *                                      event - with x/y coordinates or
7086          *                                      leave empty for default (screen centre)
7087          * @return the manager object
7088          */
7089         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7090                 var id, browserWidth, browserHeight, scrollX, scrollY,
7091                         inst = this._dialogInst; // internal instance
7092
7093                 if (!inst) {
7094                         this.uuid += 1;
7095                         id = "dp" + this.uuid;
7096                         this._dialogInput = $("<input type='text' id='" + id +
7097                                 "' style='position: absolute; top: -100px; width: 0px;'/>");
7098                         this._dialogInput.keydown(this._doKeyDown);
7099                         $("body").append(this._dialogInput);
7100                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
7101                         inst.settings = {};
7102                         $.data(this._dialogInput[0], PROP_NAME, inst);
7103                 }
7104                 extendRemove(inst.settings, settings || {});
7105                 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7106                 this._dialogInput.val(date);
7107
7108                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7109                 if (!this._pos) {
7110                         browserWidth = document.documentElement.clientWidth;
7111                         browserHeight = document.documentElement.clientHeight;
7112                         scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7113                         scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7114                         this._pos = // should use actual width/height below
7115                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7116                 }
7117
7118                 // move input on screen for focus, but hidden behind dialog
7119                 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7120                 inst.settings.onSelect = onSelect;
7121                 this._inDialog = true;
7122                 this.dpDiv.addClass(this._dialogClass);
7123                 this._showDatepicker(this._dialogInput[0]);
7124                 if ($.blockUI) {
7125                         $.blockUI(this.dpDiv);
7126                 }
7127                 $.data(this._dialogInput[0], PROP_NAME, inst);
7128                 return this;
7129         },
7130
7131         /* Detach a datepicker from its control.
7132          * @param  target       element - the target input field or division or span
7133          */
7134         _destroyDatepicker: function(target) {
7135                 var nodeName,
7136                         $target = $(target),
7137                         inst = $.data(target, PROP_NAME);
7138
7139                 if (!$target.hasClass(this.markerClassName)) {
7140                         return;
7141                 }
7142
7143                 nodeName = target.nodeName.toLowerCase();
7144                 $.removeData(target, PROP_NAME);
7145                 if (nodeName === "input") {
7146                         inst.append.remove();
7147                         inst.trigger.remove();
7148                         $target.removeClass(this.markerClassName).
7149                                 unbind("focus", this._showDatepicker).
7150                                 unbind("keydown", this._doKeyDown).
7151                                 unbind("keypress", this._doKeyPress).
7152                                 unbind("keyup", this._doKeyUp);
7153                 } else if (nodeName === "div" || nodeName === "span") {
7154                         $target.removeClass(this.markerClassName).empty();
7155                 }
7156         },
7157
7158         /* Enable the date picker to a jQuery selection.
7159          * @param  target       element - the target input field or division or span
7160          */
7161         _enableDatepicker: function(target) {
7162                 var nodeName, inline,
7163                         $target = $(target),
7164                         inst = $.data(target, PROP_NAME);
7165
7166                 if (!$target.hasClass(this.markerClassName)) {
7167                         return;
7168                 }
7169
7170                 nodeName = target.nodeName.toLowerCase();
7171                 if (nodeName === "input") {
7172                         target.disabled = false;
7173                         inst.trigger.filter("button").
7174                                 each(function() { this.disabled = false; }).end().
7175                                 filter("img").css({opacity: "1.0", cursor: ""});
7176                 } else if (nodeName === "div" || nodeName === "span") {
7177                         inline = $target.children("." + this._inlineClass);
7178                         inline.children().removeClass("ui-state-disabled");
7179                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7180                                 prop("disabled", false);
7181                 }
7182                 this._disabledInputs = $.map(this._disabledInputs,
7183                         function(value) { return (value === target ? null : value); }); // delete entry
7184         },
7185
7186         /* Disable the date picker to a jQuery selection.
7187          * @param  target       element - the target input field or division or span
7188          */
7189         _disableDatepicker: function(target) {
7190                 var nodeName, inline,
7191                         $target = $(target),
7192                         inst = $.data(target, PROP_NAME);
7193
7194                 if (!$target.hasClass(this.markerClassName)) {
7195                         return;
7196                 }
7197
7198                 nodeName = target.nodeName.toLowerCase();
7199                 if (nodeName === "input") {
7200                         target.disabled = true;
7201                         inst.trigger.filter("button").
7202                                 each(function() { this.disabled = true; }).end().
7203                                 filter("img").css({opacity: "0.5", cursor: "default"});
7204                 } else if (nodeName === "div" || nodeName === "span") {
7205                         inline = $target.children("." + this._inlineClass);
7206                         inline.children().addClass("ui-state-disabled");
7207                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7208                                 prop("disabled", true);
7209                 }
7210                 this._disabledInputs = $.map(this._disabledInputs,
7211                         function(value) { return (value === target ? null : value); }); // delete entry
7212                 this._disabledInputs[this._disabledInputs.length] = target;
7213         },
7214
7215         /* Is the first field in a jQuery collection disabled as a datepicker?
7216          * @param  target       element - the target input field or division or span
7217          * @return boolean - true if disabled, false if enabled
7218          */
7219         _isDisabledDatepicker: function(target) {
7220                 if (!target) {
7221                         return false;
7222                 }
7223                 for (var i = 0; i < this._disabledInputs.length; i++) {
7224                         if (this._disabledInputs[i] === target) {
7225                                 return true;
7226                         }
7227                 }
7228                 return false;
7229         },
7230
7231         /* Retrieve the instance data for the target control.
7232          * @param  target  element - the target input field or division or span
7233          * @return  object - the associated instance data
7234          * @throws  error if a jQuery problem getting data
7235          */
7236         _getInst: function(target) {
7237                 try {
7238                         return $.data(target, PROP_NAME);
7239                 }
7240                 catch (err) {
7241                         throw "Missing instance data for this datepicker";
7242                 }
7243         },
7244
7245         /* Update or retrieve the settings for a date picker attached to an input field or division.
7246          * @param  target  element - the target input field or division or span
7247          * @param  name object - the new settings to update or
7248          *                              string - the name of the setting to change or retrieve,
7249          *                              when retrieving also "all" for all instance settings or
7250          *                              "defaults" for all global defaults
7251          * @param  value   any - the new value for the setting
7252          *                              (omit if above is an object or to retrieve a value)
7253          */
7254         _optionDatepicker: function(target, name, value) {
7255                 var settings, date, minDate, maxDate,
7256                         inst = this._getInst(target);
7257
7258                 if (arguments.length === 2 && typeof name === "string") {
7259                         return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
7260                                 (inst ? (name === "all" ? $.extend({}, inst.settings) :
7261                                 this._get(inst, name)) : null));
7262                 }
7263
7264                 settings = name || {};
7265                 if (typeof name === "string") {
7266                         settings = {};
7267                         settings[name] = value;
7268                 }
7269
7270                 if (inst) {
7271                         if (this._curInst === inst) {
7272                                 this._hideDatepicker();
7273                         }
7274
7275                         date = this._getDateDatepicker(target, true);
7276                         minDate = this._getMinMaxDate(inst, "min");
7277                         maxDate = this._getMinMaxDate(inst, "max");
7278                         extendRemove(inst.settings, settings);
7279                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7280                         if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
7281                                 inst.settings.minDate = this._formatDate(inst, minDate);
7282                         }
7283                         if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
7284                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
7285                         }
7286                         if ( "disabled" in settings ) {
7287                                 if ( settings.disabled ) {
7288                                         this._disableDatepicker(target);
7289                                 } else {
7290                                         this._enableDatepicker(target);
7291                                 }
7292                         }
7293                         this._attachments($(target), inst);
7294                         this._autoSize(inst);
7295                         this._setDate(inst, date);
7296                         this._updateAlternate(inst);
7297                         this._updateDatepicker(inst);
7298                 }
7299         },
7300
7301         // change method deprecated
7302         _changeDatepicker: function(target, name, value) {
7303                 this._optionDatepicker(target, name, value);
7304         },
7305
7306         /* Redraw the date picker attached to an input field or division.
7307          * @param  target  element - the target input field or division or span
7308          */
7309         _refreshDatepicker: function(target) {
7310                 var inst = this._getInst(target);
7311                 if (inst) {
7312                         this._updateDatepicker(inst);
7313                 }
7314         },
7315
7316         /* Set the dates for a jQuery selection.
7317          * @param  target element - the target input field or division or span
7318          * @param  date Date - the new date
7319          */
7320         _setDateDatepicker: function(target, date) {
7321                 var inst = this._getInst(target);
7322                 if (inst) {
7323                         this._setDate(inst, date);
7324                         this._updateDatepicker(inst);
7325                         this._updateAlternate(inst);
7326                 }
7327         },
7328
7329         /* Get the date(s) for the first entry in a jQuery selection.
7330          * @param  target element - the target input field or division or span
7331          * @param  noDefault boolean - true if no default date is to be used
7332          * @return Date - the current date
7333          */
7334         _getDateDatepicker: function(target, noDefault) {
7335                 var inst = this._getInst(target);
7336                 if (inst && !inst.inline) {
7337                         this._setDateFromField(inst, noDefault);
7338                 }
7339                 return (inst ? this._getDate(inst) : null);
7340         },
7341
7342         /* Handle keystrokes. */
7343         _doKeyDown: function(event) {
7344                 var onSelect, dateStr, sel,
7345                         inst = $.datepicker._getInst(event.target),
7346                         handled = true,
7347                         isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
7348
7349                 inst._keyEvent = true;
7350                 if ($.datepicker._datepickerShowing) {
7351                         switch (event.keyCode) {
7352                                 case 9: $.datepicker._hideDatepicker();
7353                                                 handled = false;
7354                                                 break; // hide on tab out
7355                                 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
7356                                                                         $.datepicker._currentClass + ")", inst.dpDiv);
7357                                                 if (sel[0]) {
7358                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7359                                                 }
7360
7361                                                 onSelect = $.datepicker._get(inst, "onSelect");
7362                                                 if (onSelect) {
7363                                                         dateStr = $.datepicker._formatDate(inst);
7364
7365                                                         // trigger custom callback
7366                                                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7367                                                 } else {
7368                                                         $.datepicker._hideDatepicker();
7369                                                 }
7370
7371                                                 return false; // don't submit the form
7372                                 case 27: $.datepicker._hideDatepicker();
7373                                                 break; // hide on escape
7374                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7375                                                         -$.datepicker._get(inst, "stepBigMonths") :
7376                                                         -$.datepicker._get(inst, "stepMonths")), "M");
7377                                                 break; // previous month/year on page up/+ ctrl
7378                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7379                                                         +$.datepicker._get(inst, "stepBigMonths") :
7380                                                         +$.datepicker._get(inst, "stepMonths")), "M");
7381                                                 break; // next month/year on page down/+ ctrl
7382                                 case 35: if (event.ctrlKey || event.metaKey) {
7383                                                         $.datepicker._clearDate(event.target);
7384                                                 }
7385                                                 handled = event.ctrlKey || event.metaKey;
7386                                                 break; // clear on ctrl or command +end
7387                                 case 36: if (event.ctrlKey || event.metaKey) {
7388                                                         $.datepicker._gotoToday(event.target);
7389                                                 }
7390                                                 handled = event.ctrlKey || event.metaKey;
7391                                                 break; // current on ctrl or command +home
7392                                 case 37: if (event.ctrlKey || event.metaKey) {
7393                                                         $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
7394                                                 }
7395                                                 handled = event.ctrlKey || event.metaKey;
7396                                                 // -1 day on ctrl or command +left
7397                                                 if (event.originalEvent.altKey) {
7398                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7399                                                                 -$.datepicker._get(inst, "stepBigMonths") :
7400                                                                 -$.datepicker._get(inst, "stepMonths")), "M");
7401                                                 }
7402                                                 // next month/year on alt +left on Mac
7403                                                 break;
7404                                 case 38: if (event.ctrlKey || event.metaKey) {
7405                                                         $.datepicker._adjustDate(event.target, -7, "D");
7406                                                 }
7407                                                 handled = event.ctrlKey || event.metaKey;
7408                                                 break; // -1 week on ctrl or command +up
7409                                 case 39: if (event.ctrlKey || event.metaKey) {
7410                                                         $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
7411                                                 }
7412                                                 handled = event.ctrlKey || event.metaKey;
7413                                                 // +1 day on ctrl or command +right
7414                                                 if (event.originalEvent.altKey) {
7415                                                         $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7416                                                                 +$.datepicker._get(inst, "stepBigMonths") :
7417                                                                 +$.datepicker._get(inst, "stepMonths")), "M");
7418                                                 }
7419                                                 // next month/year on alt +right
7420                                                 break;
7421                                 case 40: if (event.ctrlKey || event.metaKey) {
7422                                                         $.datepicker._adjustDate(event.target, +7, "D");
7423                                                 }
7424                                                 handled = event.ctrlKey || event.metaKey;
7425                                                 break; // +1 week on ctrl or command +down
7426                                 default: handled = false;
7427                         }
7428                 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
7429                         $.datepicker._showDatepicker(this);
7430                 } else {
7431                         handled = false;
7432                 }
7433
7434                 if (handled) {
7435                         event.preventDefault();
7436                         event.stopPropagation();
7437                 }
7438         },
7439
7440         /* Filter entered characters - based on date format. */
7441         _doKeyPress: function(event) {
7442                 var chars, chr,
7443                         inst = $.datepicker._getInst(event.target);
7444
7445                 if ($.datepicker._get(inst, "constrainInput")) {
7446                         chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
7447                         chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
7448                         return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
7449                 }
7450         },
7451
7452         /* Synchronise manual entry and field/alternate field. */
7453         _doKeyUp: function(event) {
7454                 var date,
7455                         inst = $.datepicker._getInst(event.target);
7456
7457                 if (inst.input.val() !== inst.lastVal) {
7458                         try {
7459                                 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
7460                                         (inst.input ? inst.input.val() : null),
7461                                         $.datepicker._getFormatConfig(inst));
7462
7463                                 if (date) { // only if valid
7464                                         $.datepicker._setDateFromField(inst);
7465                                         $.datepicker._updateAlternate(inst);
7466                                         $.datepicker._updateDatepicker(inst);
7467                                 }
7468                         }
7469                         catch (err) {
7470                         }
7471                 }
7472                 return true;
7473         },
7474
7475         /* Pop-up the date picker for a given input field.
7476          * If false returned from beforeShow event handler do not show.
7477          * @param  input  element - the input field attached to the date picker or
7478          *                                      event - if triggered by focus
7479          */
7480         _showDatepicker: function(input) {
7481                 input = input.target || input;
7482                 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
7483                         input = $("input", input.parentNode)[0];
7484                 }
7485
7486                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
7487                         return;
7488                 }
7489
7490                 var inst, beforeShow, beforeShowSettings, isFixed,
7491                         offset, showAnim, duration;
7492
7493                 inst = $.datepicker._getInst(input);
7494                 if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
7495                         $.datepicker._curInst.dpDiv.stop(true, true);
7496                         if ( inst && $.datepicker._datepickerShowing ) {
7497                                 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7498                         }
7499                 }
7500
7501                 beforeShow = $.datepicker._get(inst, "beforeShow");
7502                 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7503                 if(beforeShowSettings === false){
7504                         return;
7505                 }
7506                 extendRemove(inst.settings, beforeShowSettings);
7507
7508                 inst.lastVal = null;
7509                 $.datepicker._lastInput = input;
7510                 $.datepicker._setDateFromField(inst);
7511
7512                 if ($.datepicker._inDialog) { // hide cursor
7513                         input.value = "";
7514                 }
7515                 if (!$.datepicker._pos) { // position below input
7516                         $.datepicker._pos = $.datepicker._findPos(input);
7517                         $.datepicker._pos[1] += input.offsetHeight; // add the height
7518                 }
7519
7520                 isFixed = false;
7521                 $(input).parents().each(function() {
7522                         isFixed |= $(this).css("position") === "fixed";
7523                         return !isFixed;
7524                 });
7525
7526                 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7527                 $.datepicker._pos = null;
7528                 //to avoid flashes on Firefox
7529                 inst.dpDiv.empty();
7530                 // determine sizing offscreen
7531                 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
7532                 $.datepicker._updateDatepicker(inst);
7533                 // fix width for dynamic number of date pickers
7534                 // and adjust position before showing
7535                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
7536                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7537                         "static" : (isFixed ? "fixed" : "absolute")), display: "none",
7538                         left: offset.left + "px", top: offset.top + "px"});
7539
7540                 if (!inst.inline) {
7541                         showAnim = $.datepicker._get(inst, "showAnim");
7542                         duration = $.datepicker._get(inst, "duration");
7543                         inst.dpDiv.zIndex($(input).zIndex()+1);
7544                         $.datepicker._datepickerShowing = true;
7545
7546                         if ( $.effects && $.effects.effect[ showAnim ] ) {
7547                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
7548                         } else {
7549                                 inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
7550                         }
7551
7552                         if ( $.datepicker._shouldFocusInput( inst ) ) {
7553                                 inst.input.focus();
7554                         }
7555
7556                         $.datepicker._curInst = inst;
7557                 }
7558         },
7559
7560         /* Generate the date picker content. */
7561         _updateDatepicker: function(inst) {
7562                 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7563                 instActive = inst; // for delegate hover events
7564                 inst.dpDiv.empty().append(this._generateHTML(inst));
7565                 this._attachHandlers(inst);
7566                 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
7567
7568                 var origyearshtml,
7569                         numMonths = this._getNumberOfMonths(inst),
7570                         cols = numMonths[1],
7571                         width = 17;
7572
7573                 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
7574                 if (cols > 1) {
7575                         inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
7576                 }
7577                 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
7578                         "Class"]("ui-datepicker-multi");
7579                 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
7580                         "Class"]("ui-datepicker-rtl");
7581
7582                 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7583                         inst.input.focus();
7584                 }
7585
7586                 // deffered render of the years select (to avoid flashes on Firefox)
7587                 if( inst.yearshtml ){
7588                         origyearshtml = inst.yearshtml;
7589                         setTimeout(function(){
7590                                 //assure that inst.yearshtml didn't change.
7591                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7592                                         inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
7593                                 }
7594                                 origyearshtml = inst.yearshtml = null;
7595                         }, 0);
7596                 }
7597         },
7598
7599         // #6694 - don't focus the input if it's already focused
7600         // this breaks the change event in IE
7601         // Support: IE and jQuery <1.9
7602         _shouldFocusInput: function( inst ) {
7603                 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
7604         },
7605
7606         /* Check positioning to remain on screen. */
7607         _checkOffset: function(inst, offset, isFixed) {
7608                 var dpWidth = inst.dpDiv.outerWidth(),
7609                         dpHeight = inst.dpDiv.outerHeight(),
7610                         inputWidth = inst.input ? inst.input.outerWidth() : 0,
7611                         inputHeight = inst.input ? inst.input.outerHeight() : 0,
7612                         viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
7613                         viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7614
7615                 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
7616                 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
7617                 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7618
7619                 // now check if datepicker is showing outside window viewport - move to a better place if so.
7620                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7621                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
7622                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7623                         Math.abs(dpHeight + inputHeight) : 0);
7624
7625                 return offset;
7626         },
7627
7628         /* Find an object's position on the screen. */
7629         _findPos: function(obj) {
7630                 var position,
7631                         inst = this._getInst(obj),
7632                         isRTL = this._get(inst, "isRTL");
7633
7634                 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
7635                         obj = obj[isRTL ? "previousSibling" : "nextSibling"];
7636                 }
7637
7638                 position = $(obj).offset();
7639                 return [position.left, position.top];
7640         },
7641
7642         /* Hide the date picker from view.
7643          * @param  input  element - the input field attached to the date picker
7644          */
7645         _hideDatepicker: function(input) {
7646                 var showAnim, duration, postProcess, onClose,
7647                         inst = this._curInst;
7648
7649                 if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
7650                         return;
7651                 }
7652
7653                 if (this._datepickerShowing) {
7654                         showAnim = this._get(inst, "showAnim");
7655                         duration = this._get(inst, "duration");
7656                         postProcess = function() {
7657                                 $.datepicker._tidyDialog(inst);
7658                         };
7659
7660                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7661                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
7662                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
7663                         } else {
7664                                 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
7665                                         (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
7666                         }
7667
7668                         if (!showAnim) {
7669                                 postProcess();
7670                         }
7671                         this._datepickerShowing = false;
7672
7673                         onClose = this._get(inst, "onClose");
7674                         if (onClose) {
7675                                 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
7676                         }
7677
7678                         this._lastInput = null;
7679                         if (this._inDialog) {
7680                                 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
7681                                 if ($.blockUI) {
7682                                         $.unblockUI();
7683                                         $("body").append(this.dpDiv);
7684                                 }
7685                         }
7686                         this._inDialog = false;
7687                 }
7688         },
7689
7690         /* Tidy up after a dialog display. */
7691         _tidyDialog: function(inst) {
7692                 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
7693         },
7694
7695         /* Close date picker if clicked elsewhere. */
7696         _checkExternalClick: function(event) {
7697                 if (!$.datepicker._curInst) {
7698                         return;
7699                 }
7700
7701                 var $target = $(event.target),
7702                         inst = $.datepicker._getInst($target[0]);
7703
7704                 if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
7705                                 $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
7706                                 !$target.hasClass($.datepicker.markerClassName) &&
7707                                 !$target.closest("." + $.datepicker._triggerClass).length &&
7708                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
7709                         ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
7710                                 $.datepicker._hideDatepicker();
7711                 }
7712         },
7713
7714         /* Adjust one of the date sub-fields. */
7715         _adjustDate: function(id, offset, period) {
7716                 var target = $(id),
7717                         inst = this._getInst(target[0]);
7718
7719                 if (this._isDisabledDatepicker(target[0])) {
7720                         return;
7721                 }
7722                 this._adjustInstDate(inst, offset +
7723                         (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
7724                         period);
7725                 this._updateDatepicker(inst);
7726         },
7727
7728         /* Action for current link. */
7729         _gotoToday: function(id) {
7730                 var date,
7731                         target = $(id),
7732                         inst = this._getInst(target[0]);
7733
7734                 if (this._get(inst, "gotoCurrent") && inst.currentDay) {
7735                         inst.selectedDay = inst.currentDay;
7736                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
7737                         inst.drawYear = inst.selectedYear = inst.currentYear;
7738                 } else {
7739                         date = new Date();
7740                         inst.selectedDay = date.getDate();
7741                         inst.drawMonth = inst.selectedMonth = date.getMonth();
7742                         inst.drawYear = inst.selectedYear = date.getFullYear();
7743                 }
7744                 this._notifyChange(inst);
7745                 this._adjustDate(target);
7746         },
7747
7748         /* Action for selecting a new month/year. */
7749         _selectMonthYear: function(id, select, period) {
7750                 var target = $(id),
7751                         inst = this._getInst(target[0]);
7752
7753                 inst["selected" + (period === "M" ? "Month" : "Year")] =
7754                 inst["draw" + (period === "M" ? "Month" : "Year")] =
7755                         parseInt(select.options[select.selectedIndex].value,10);
7756
7757                 this._notifyChange(inst);
7758                 this._adjustDate(target);
7759         },
7760
7761         /* Action for selecting a day. */
7762         _selectDay: function(id, month, year, td) {
7763                 var inst,
7764                         target = $(id);
7765
7766                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7767                         return;
7768                 }
7769
7770                 inst = this._getInst(target[0]);
7771                 inst.selectedDay = inst.currentDay = $("a", td).html();
7772                 inst.selectedMonth = inst.currentMonth = month;
7773                 inst.selectedYear = inst.currentYear = year;
7774                 this._selectDate(id, this._formatDate(inst,
7775                         inst.currentDay, inst.currentMonth, inst.currentYear));
7776         },
7777
7778         /* Erase the input field and hide the date picker. */
7779         _clearDate: function(id) {
7780                 var target = $(id);
7781                 this._selectDate(target, "");
7782         },
7783
7784         /* Update the input field with the selected date. */
7785         _selectDate: function(id, dateStr) {
7786                 var onSelect,
7787                         target = $(id),
7788                         inst = this._getInst(target[0]);
7789
7790                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7791                 if (inst.input) {
7792                         inst.input.val(dateStr);
7793                 }
7794                 this._updateAlternate(inst);
7795
7796                 onSelect = this._get(inst, "onSelect");
7797                 if (onSelect) {
7798                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
7799                 } else if (inst.input) {
7800                         inst.input.trigger("change"); // fire the change event
7801                 }
7802
7803                 if (inst.inline){
7804                         this._updateDatepicker(inst);
7805                 } else {
7806                         this._hideDatepicker();
7807                         this._lastInput = inst.input[0];
7808                         if (typeof(inst.input[0]) !== "object") {
7809                                 inst.input.focus(); // restore focus
7810                         }
7811                         this._lastInput = null;
7812                 }
7813         },
7814
7815         /* Update any alternate field to synchronise with the main field. */
7816         _updateAlternate: function(inst) {
7817                 var altFormat, date, dateStr,
7818                         altField = this._get(inst, "altField");
7819
7820                 if (altField) { // update alternate field too
7821                         altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
7822                         date = this._getDate(inst);
7823                         dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7824                         $(altField).each(function() { $(this).val(dateStr); });
7825                 }
7826         },
7827
7828         /* Set as beforeShowDay function to prevent selection of weekends.
7829          * @param  date  Date - the date to customise
7830          * @return [boolean, string] - is this date selectable?, what is its CSS class?
7831          */
7832         noWeekends: function(date) {
7833                 var day = date.getDay();
7834                 return [(day > 0 && day < 6), ""];
7835         },
7836
7837         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7838          * @param  date  Date - the date to get the week for
7839          * @return  number - the number of the week within the year that contains this date
7840          */
7841         iso8601Week: function(date) {
7842                 var time,
7843                         checkDate = new Date(date.getTime());
7844
7845                 // Find Thursday of this week starting on Monday
7846                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7847
7848                 time = checkDate.getTime();
7849                 checkDate.setMonth(0); // Compare with Jan 1
7850                 checkDate.setDate(1);
7851                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7852         },
7853
7854         /* Parse a string value into a date object.
7855          * See formatDate below for the possible formats.
7856          *
7857          * @param  format string - the expected format of the date
7858          * @param  value string - the date in the above format
7859          * @param  settings Object - attributes include:
7860          *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
7861          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
7862          *                                      dayNames                string[7] - names of the days from Sunday (optional)
7863          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
7864          *                                      monthNames              string[12] - names of the months (optional)
7865          * @return  Date - the extracted date value or null if value is blank
7866          */
7867         parseDate: function (format, value, settings) {
7868                 if (format == null || value == null) {
7869                         throw "Invalid arguments";
7870                 }
7871
7872                 value = (typeof value === "object" ? value.toString() : value + "");
7873                 if (value === "") {
7874                         return null;
7875                 }
7876
7877                 var iFormat, dim, extra,
7878                         iValue = 0,
7879                         shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
7880                         shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
7881                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
7882                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
7883                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
7884                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
7885                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
7886                         year = -1,
7887                         month = -1,
7888                         day = -1,
7889                         doy = -1,
7890                         literal = false,
7891                         date,
7892                         // Check whether a format character is doubled
7893                         lookAhead = function(match) {
7894                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7895                                 if (matches) {
7896                                         iFormat++;
7897                                 }
7898                                 return matches;
7899                         },
7900                         // Extract a number from the string value
7901                         getNumber = function(match) {
7902                                 var isDoubled = lookAhead(match),
7903                                         size = (match === "@" ? 14 : (match === "!" ? 20 :
7904                                         (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
7905                                         digits = new RegExp("^\\d{1," + size + "}"),
7906                                         num = value.substring(iValue).match(digits);
7907                                 if (!num) {
7908                                         throw "Missing number at position " + iValue;
7909                                 }
7910                                 iValue += num[0].length;
7911                                 return parseInt(num[0], 10);
7912                         },
7913                         // Extract a name from the string value and convert to an index
7914                         getName = function(match, shortNames, longNames) {
7915                                 var index = -1,
7916                                         names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
7917                                                 return [ [k, v] ];
7918                                         }).sort(function (a, b) {
7919                                                 return -(a[1].length - b[1].length);
7920                                         });
7921
7922                                 $.each(names, function (i, pair) {
7923                                         var name = pair[1];
7924                                         if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
7925                                                 index = pair[0];
7926                                                 iValue += name.length;
7927                                                 return false;
7928                                         }
7929                                 });
7930                                 if (index !== -1) {
7931                                         return index + 1;
7932                                 } else {
7933                                         throw "Unknown name at position " + iValue;
7934                                 }
7935                         },
7936                         // Confirm that a literal character matches the string value
7937                         checkLiteral = function() {
7938                                 if (value.charAt(iValue) !== format.charAt(iFormat)) {
7939                                         throw "Unexpected literal at position " + iValue;
7940                                 }
7941                                 iValue++;
7942                         };
7943
7944                 for (iFormat = 0; iFormat < format.length; iFormat++) {
7945                         if (literal) {
7946                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7947                                         literal = false;
7948                                 } else {
7949                                         checkLiteral();
7950                                 }
7951                         } else {
7952                                 switch (format.charAt(iFormat)) {
7953                                         case "d":
7954                                                 day = getNumber("d");
7955                                                 break;
7956                                         case "D":
7957                                                 getName("D", dayNamesShort, dayNames);
7958                                                 break;
7959                                         case "o":
7960                                                 doy = getNumber("o");
7961                                                 break;
7962                                         case "m":
7963                                                 month = getNumber("m");
7964                                                 break;
7965                                         case "M":
7966                                                 month = getName("M", monthNamesShort, monthNames);
7967                                                 break;
7968                                         case "y":
7969                                                 year = getNumber("y");
7970                                                 break;
7971                                         case "@":
7972                                                 date = new Date(getNumber("@"));
7973                                                 year = date.getFullYear();
7974                                                 month = date.getMonth() + 1;
7975                                                 day = date.getDate();
7976                                                 break;
7977                                         case "!":
7978                                                 date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
7979                                                 year = date.getFullYear();
7980                                                 month = date.getMonth() + 1;
7981                                                 day = date.getDate();
7982                                                 break;
7983                                         case "'":
7984                                                 if (lookAhead("'")){
7985                                                         checkLiteral();
7986                                                 } else {
7987                                                         literal = true;
7988                                                 }
7989                                                 break;
7990                                         default:
7991                                                 checkLiteral();
7992                                 }
7993                         }
7994                 }
7995
7996                 if (iValue < value.length){
7997                         extra = value.substr(iValue);
7998                         if (!/^\s+/.test(extra)) {
7999                                 throw "Extra/unparsed characters found in date: " + extra;
8000                         }
8001                 }
8002
8003                 if (year === -1) {
8004                         year = new Date().getFullYear();
8005                 } else if (year < 100) {
8006                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8007                                 (year <= shortYearCutoff ? 0 : -100);
8008                 }
8009
8010                 if (doy > -1) {
8011                         month = 1;
8012                         day = doy;
8013                         do {
8014                                 dim = this._getDaysInMonth(year, month - 1);
8015                                 if (day <= dim) {
8016                                         break;
8017                                 }
8018                                 month++;
8019                                 day -= dim;
8020                         } while (true);
8021                 }
8022
8023                 date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8024                 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8025                         throw "Invalid date"; // E.g. 31/02/00
8026                 }
8027                 return date;
8028         },
8029
8030         /* Standard date formats. */
8031         ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8032         COOKIE: "D, dd M yy",
8033         ISO_8601: "yy-mm-dd",
8034         RFC_822: "D, d M y",
8035         RFC_850: "DD, dd-M-y",
8036         RFC_1036: "D, d M y",
8037         RFC_1123: "D, d M yy",
8038         RFC_2822: "D, d M yy",
8039         RSS: "D, d M y", // RFC 822
8040         TICKS: "!",
8041         TIMESTAMP: "@",
8042         W3C: "yy-mm-dd", // ISO 8601
8043
8044         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8045                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8046
8047         /* Format a date object into a string value.
8048          * The format can be combinations of the following:
8049          * d  - day of month (no leading zero)
8050          * dd - day of month (two digit)
8051          * o  - day of year (no leading zeros)
8052          * oo - day of year (three digit)
8053          * D  - day name short
8054          * DD - day name long
8055          * m  - month of year (no leading zero)
8056          * mm - month of year (two digit)
8057          * M  - month name short
8058          * MM - month name long
8059          * y  - year (two digit)
8060          * yy - year (four digit)
8061          * @ - Unix timestamp (ms since 01/01/1970)
8062          * ! - Windows ticks (100ns since 01/01/0001)
8063          * "..." - literal text
8064          * '' - single quote
8065          *
8066          * @param  format string - the desired format of the date
8067          * @param  date Date - the date value to format
8068          * @param  settings Object - attributes include:
8069          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8070          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8071          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8072          *                                      monthNames              string[12] - names of the months (optional)
8073          * @return  string - the date in the above format
8074          */
8075         formatDate: function (format, date, settings) {
8076                 if (!date) {
8077                         return "";
8078                 }
8079
8080                 var iFormat,
8081                         dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8082                         dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8083                         monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8084                         monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8085                         // Check whether a format character is doubled
8086                         lookAhead = function(match) {
8087                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8088                                 if (matches) {
8089                                         iFormat++;
8090                                 }
8091                                 return matches;
8092                         },
8093                         // Format a number, with leading zero if necessary
8094                         formatNumber = function(match, value, len) {
8095                                 var num = "" + value;
8096                                 if (lookAhead(match)) {
8097                                         while (num.length < len) {
8098                                                 num = "0" + num;
8099                                         }
8100                                 }
8101                                 return num;
8102                         },
8103                         // Format a name, short or long as requested
8104                         formatName = function(match, value, shortNames, longNames) {
8105                                 return (lookAhead(match) ? longNames[value] : shortNames[value]);
8106                         },
8107                         output = "",
8108                         literal = false;
8109
8110                 if (date) {
8111                         for (iFormat = 0; iFormat < format.length; iFormat++) {
8112                                 if (literal) {
8113                                         if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8114                                                 literal = false;
8115                                         } else {
8116                                                 output += format.charAt(iFormat);
8117                                         }
8118                                 } else {
8119                                         switch (format.charAt(iFormat)) {
8120                                                 case "d":
8121                                                         output += formatNumber("d", date.getDate(), 2);
8122                                                         break;
8123                                                 case "D":
8124                                                         output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8125                                                         break;
8126                                                 case "o":
8127                                                         output += formatNumber("o",
8128                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8129                                                         break;
8130                                                 case "m":
8131                                                         output += formatNumber("m", date.getMonth() + 1, 2);
8132                                                         break;
8133                                                 case "M":
8134                                                         output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8135                                                         break;
8136                                                 case "y":
8137                                                         output += (lookAhead("y") ? date.getFullYear() :
8138                                                                 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8139                                                         break;
8140                                                 case "@":
8141                                                         output += date.getTime();
8142                                                         break;
8143                                                 case "!":
8144                                                         output += date.getTime() * 10000 + this._ticksTo1970;
8145                                                         break;
8146                                                 case "'":
8147                                                         if (lookAhead("'")) {
8148                                                                 output += "'";
8149                                                         } else {
8150                                                                 literal = true;
8151                                                         }
8152                                                         break;
8153                                                 default:
8154                                                         output += format.charAt(iFormat);
8155                                         }
8156                                 }
8157                         }
8158                 }
8159                 return output;
8160         },
8161
8162         /* Extract all possible characters from the date format. */
8163         _possibleChars: function (format) {
8164                 var iFormat,
8165                         chars = "",
8166                         literal = false,
8167                         // Check whether a format character is doubled
8168                         lookAhead = function(match) {
8169                                 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8170                                 if (matches) {
8171                                         iFormat++;
8172                                 }
8173                                 return matches;
8174                         };
8175
8176                 for (iFormat = 0; iFormat < format.length; iFormat++) {
8177                         if (literal) {
8178                                 if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8179                                         literal = false;
8180                                 } else {
8181                                         chars += format.charAt(iFormat);
8182                                 }
8183                         } else {
8184                                 switch (format.charAt(iFormat)) {
8185                                         case "d": case "m": case "y": case "@":
8186                                                 chars += "0123456789";
8187                                                 break;
8188                                         case "D": case "M":
8189                                                 return null; // Accept anything
8190                                         case "'":
8191                                                 if (lookAhead("'")) {
8192                                                         chars += "'";
8193                                                 } else {
8194                                                         literal = true;
8195                                                 }
8196                                                 break;
8197                                         default:
8198                                                 chars += format.charAt(iFormat);
8199                                 }
8200                         }
8201                 }
8202                 return chars;
8203         },
8204
8205         /* Get a setting value, defaulting if necessary. */
8206         _get: function(inst, name) {
8207                 return inst.settings[name] !== undefined ?
8208                         inst.settings[name] : this._defaults[name];
8209         },
8210
8211         /* Parse existing date and initialise date picker. */
8212         _setDateFromField: function(inst, noDefault) {
8213                 if (inst.input.val() === inst.lastVal) {
8214                         return;
8215                 }
8216
8217                 var dateFormat = this._get(inst, "dateFormat"),
8218                         dates = inst.lastVal = inst.input ? inst.input.val() : null,
8219                         defaultDate = this._getDefaultDate(inst),
8220                         date = defaultDate,
8221                         settings = this._getFormatConfig(inst);
8222
8223                 try {
8224                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8225                 } catch (event) {
8226                         dates = (noDefault ? "" : dates);
8227                 }
8228                 inst.selectedDay = date.getDate();
8229                 inst.drawMonth = inst.selectedMonth = date.getMonth();
8230                 inst.drawYear = inst.selectedYear = date.getFullYear();
8231                 inst.currentDay = (dates ? date.getDate() : 0);
8232                 inst.currentMonth = (dates ? date.getMonth() : 0);
8233                 inst.currentYear = (dates ? date.getFullYear() : 0);
8234                 this._adjustInstDate(inst);
8235         },
8236
8237         /* Retrieve the default date shown on opening. */
8238         _getDefaultDate: function(inst) {
8239                 return this._restrictMinMax(inst,
8240                         this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
8241         },
8242
8243         /* A date may be specified as an exact value or a relative one. */
8244         _determineDate: function(inst, date, defaultDate) {
8245                 var offsetNumeric = function(offset) {
8246                                 var date = new Date();
8247                                 date.setDate(date.getDate() + offset);
8248                                 return date;
8249                         },
8250                         offsetString = function(offset) {
8251                                 try {
8252                                         return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8253                                                 offset, $.datepicker._getFormatConfig(inst));
8254                                 }
8255                                 catch (e) {
8256                                         // Ignore
8257                                 }
8258
8259                                 var date = (offset.toLowerCase().match(/^c/) ?
8260                                         $.datepicker._getDate(inst) : null) || new Date(),
8261                                         year = date.getFullYear(),
8262                                         month = date.getMonth(),
8263                                         day = date.getDate(),
8264                                         pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8265                                         matches = pattern.exec(offset);
8266
8267                                 while (matches) {
8268                                         switch (matches[2] || "d") {
8269                                                 case "d" : case "D" :
8270                                                         day += parseInt(matches[1],10); break;
8271                                                 case "w" : case "W" :
8272                                                         day += parseInt(matches[1],10) * 7; break;
8273                                                 case "m" : case "M" :
8274                                                         month += parseInt(matches[1],10);
8275                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8276                                                         break;
8277                                                 case "y": case "Y" :
8278                                                         year += parseInt(matches[1],10);
8279                                                         day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8280                                                         break;
8281                                         }
8282                                         matches = pattern.exec(offset);
8283                                 }
8284                                 return new Date(year, month, day);
8285                         },
8286                         newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
8287                                 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8288
8289                 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
8290                 if (newDate) {
8291                         newDate.setHours(0);
8292                         newDate.setMinutes(0);
8293                         newDate.setSeconds(0);
8294                         newDate.setMilliseconds(0);
8295                 }
8296                 return this._daylightSavingAdjust(newDate);
8297         },
8298
8299         /* Handle switch to/from daylight saving.
8300          * Hours may be non-zero on daylight saving cut-over:
8301          * > 12 when midnight changeover, but then cannot generate
8302          * midnight datetime, so jump to 1AM, otherwise reset.
8303          * @param  date  (Date) the date to check
8304          * @return  (Date) the corrected date
8305          */
8306         _daylightSavingAdjust: function(date) {
8307                 if (!date) {
8308                         return null;
8309                 }
8310                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8311                 return date;
8312         },
8313
8314         /* Set the date(s) directly. */
8315         _setDate: function(inst, date, noChange) {
8316                 var clear = !date,
8317                         origMonth = inst.selectedMonth,
8318                         origYear = inst.selectedYear,
8319                         newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8320
8321                 inst.selectedDay = inst.currentDay = newDate.getDate();
8322                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8323                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8324                 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
8325                         this._notifyChange(inst);
8326                 }
8327                 this._adjustInstDate(inst);
8328                 if (inst.input) {
8329                         inst.input.val(clear ? "" : this._formatDate(inst));
8330                 }
8331         },
8332
8333         /* Retrieve the date(s) directly. */
8334         _getDate: function(inst) {
8335                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
8336                         this._daylightSavingAdjust(new Date(
8337                         inst.currentYear, inst.currentMonth, inst.currentDay)));
8338                         return startDate;
8339         },
8340
8341         /* Attach the onxxx handlers.  These are declared statically so
8342          * they work with static code transformers like Caja.
8343          */
8344         _attachHandlers: function(inst) {
8345                 var stepMonths = this._get(inst, "stepMonths"),
8346                         id = "#" + inst.id.replace( /\\\\/g, "\\" );
8347                 inst.dpDiv.find("[data-handler]").map(function () {
8348                         var handler = {
8349                                 prev: function () {
8350                                         $.datepicker._adjustDate(id, -stepMonths, "M");
8351                                 },
8352                                 next: function () {
8353                                         $.datepicker._adjustDate(id, +stepMonths, "M");
8354                                 },
8355                                 hide: function () {
8356                                         $.datepicker._hideDatepicker();
8357                                 },
8358                                 today: function () {
8359                                         $.datepicker._gotoToday(id);
8360                                 },
8361                                 selectDay: function () {
8362                                         $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
8363                                         return false;
8364                                 },
8365                                 selectMonth: function () {
8366                                         $.datepicker._selectMonthYear(id, this, "M");
8367                                         return false;
8368                                 },
8369                                 selectYear: function () {
8370                                         $.datepicker._selectMonthYear(id, this, "Y");
8371                                         return false;
8372                                 }
8373                         };
8374                         $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
8375                 });
8376         },
8377
8378         /* Generate the HTML for the current state of the date picker. */
8379         _generateHTML: function(inst) {
8380                 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8381                         controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8382                         monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8383                         selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8384                         cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8385                         printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8386                         tempDate = new Date(),
8387                         today = this._daylightSavingAdjust(
8388                                 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
8389                         isRTL = this._get(inst, "isRTL"),
8390                         showButtonPanel = this._get(inst, "showButtonPanel"),
8391                         hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
8392                         navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
8393                         numMonths = this._getNumberOfMonths(inst),
8394                         showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
8395                         stepMonths = this._get(inst, "stepMonths"),
8396                         isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
8397                         currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8398                                 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
8399                         minDate = this._getMinMaxDate(inst, "min"),
8400                         maxDate = this._getMinMaxDate(inst, "max"),
8401                         drawMonth = inst.drawMonth - showCurrentAtPos,
8402                         drawYear = inst.drawYear;
8403
8404                 if (drawMonth < 0) {
8405                         drawMonth += 12;
8406                         drawYear--;
8407                 }
8408                 if (maxDate) {
8409                         maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8410                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8411                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8412                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8413                                 drawMonth--;
8414                                 if (drawMonth < 0) {
8415                                         drawMonth = 11;
8416                                         drawYear--;
8417                                 }
8418                         }
8419                 }
8420                 inst.drawMonth = drawMonth;
8421                 inst.drawYear = drawYear;
8422
8423                 prevText = this._get(inst, "prevText");
8424                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8425                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8426                         this._getFormatConfig(inst)));
8427
8428                 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8429                         "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8430                         " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
8431                         (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>"));
8432
8433                 nextText = this._get(inst, "nextText");
8434                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8435                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8436                         this._getFormatConfig(inst)));
8437
8438                 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8439                         "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8440                         " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
8441                         (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>"));
8442
8443                 currentText = this._get(inst, "currentText");
8444                 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
8445                 currentText = (!navigationAsDateFormat ? currentText :
8446                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8447
8448                 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'>" +
8449                         this._get(inst, "closeText") + "</button>" : "");
8450
8451                 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
8452                         (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'" +
8453                         ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
8454
8455                 firstDay = parseInt(this._get(inst, "firstDay"),10);
8456                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
8457
8458                 showWeek = this._get(inst, "showWeek");
8459                 dayNames = this._get(inst, "dayNames");
8460                 dayNamesMin = this._get(inst, "dayNamesMin");
8461                 monthNames = this._get(inst, "monthNames");
8462                 monthNamesShort = this._get(inst, "monthNamesShort");
8463                 beforeShowDay = this._get(inst, "beforeShowDay");
8464                 showOtherMonths = this._get(inst, "showOtherMonths");
8465                 selectOtherMonths = this._get(inst, "selectOtherMonths");
8466                 defaultDate = this._getDefaultDate(inst);
8467                 html = "";
8468                 dow;
8469                 for (row = 0; row < numMonths[0]; row++) {
8470                         group = "";
8471                         this.maxRows = 4;
8472                         for (col = 0; col < numMonths[1]; col++) {
8473                                 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8474                                 cornerClass = " ui-corner-all";
8475                                 calender = "";
8476                                 if (isMultiMonth) {
8477                                         calender += "<div class='ui-datepicker-group";
8478                                         if (numMonths[1] > 1) {
8479                                                 switch (col) {
8480                                                         case 0: calender += " ui-datepicker-group-first";
8481                                                                 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
8482                                                         case numMonths[1]-1: calender += " ui-datepicker-group-last";
8483                                                                 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
8484                                                         default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8485                                                 }
8486                                         }
8487                                         calender += "'>";
8488                                 }
8489                                 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8490                                         (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
8491                                         (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
8492                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8493                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8494                                         "</div><table class='ui-datepicker-calendar'><thead>" +
8495                                         "<tr>";
8496                                 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
8497                                 for (dow = 0; dow < 7; dow++) { // days of the week
8498                                         day = (dow + firstDay) % 7;
8499                                         thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
8500                                                 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
8501                                 }
8502                                 calender += thead + "</tr></thead><tbody>";
8503                                 daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8504                                 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
8505                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8506                                 }
8507                                 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8508                                 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8509                                 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8510                                 this.maxRows = numRows;
8511                                 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8512                                 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8513                                         calender += "<tr>";
8514                                         tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8515                                                 this._get(inst, "calculateWeek")(printDate) + "</td>");
8516                                         for (dow = 0; dow < 7; dow++) { // create date picker days
8517                                                 daySettings = (beforeShowDay ?
8518                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
8519                                                 otherMonth = (printDate.getMonth() !== drawMonth);
8520                                                 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8521                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8522                                                 tbody += "<td class='" +
8523                                                         ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
8524                                                         (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
8525                                                         ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
8526                                                         (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
8527                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
8528                                                         " " + this._dayOverClass : "") + // highlight selected day
8529                                                         (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
8530                                                         (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
8531                                                         (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
8532                                                         (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
8533                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
8534                                                         (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
8535                                                         (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8536                                                         (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8537                                                         (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
8538                                                         (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
8539                                                         (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
8540                                                         "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
8541                                                 printDate.setDate(printDate.getDate() + 1);
8542                                                 printDate = this._daylightSavingAdjust(printDate);
8543                                         }
8544                                         calender += tbody + "</tr>";
8545                                 }
8546                                 drawMonth++;
8547                                 if (drawMonth > 11) {
8548                                         drawMonth = 0;
8549                                         drawYear++;
8550                                 }
8551                                 calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
8552                                                         ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
8553                                 group += calender;
8554                         }
8555                         html += group;
8556                 }
8557                 html += buttonPanel;
8558                 inst._keyEvent = false;
8559                 return html;
8560         },
8561
8562         /* Generate the month and year header. */
8563         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8564                         secondary, monthNames, monthNamesShort) {
8565
8566                 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8567                         changeMonth = this._get(inst, "changeMonth"),
8568                         changeYear = this._get(inst, "changeYear"),
8569                         showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
8570                         html = "<div class='ui-datepicker-title'>",
8571                         monthHtml = "";
8572
8573                 // month selection
8574                 if (secondary || !changeMonth) {
8575                         monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
8576                 } else {
8577                         inMinYear = (minDate && minDate.getFullYear() === drawYear);
8578                         inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
8579                         monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
8580                         for ( month = 0; month < 12; month++) {
8581                                 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
8582                                         monthHtml += "<option value='" + month + "'" +
8583                                                 (month === drawMonth ? " selected='selected'" : "") +
8584                                                 ">" + monthNamesShort[month] + "</option>";
8585                                 }
8586                         }
8587                         monthHtml += "</select>";
8588                 }
8589
8590                 if (!showMonthAfterYear) {
8591                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
8592                 }
8593
8594                 // year selection
8595                 if ( !inst.yearshtml ) {
8596                         inst.yearshtml = "";
8597                         if (secondary || !changeYear) {
8598                                 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
8599                         } else {
8600                                 // determine range of years to display
8601                                 years = this._get(inst, "yearRange").split(":");
8602                                 thisYear = new Date().getFullYear();
8603                                 determineYear = function(value) {
8604                                         var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8605                                                 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
8606                                                 parseInt(value, 10)));
8607                                         return (isNaN(year) ? thisYear : year);
8608                                 };
8609                                 year = determineYear(years[0]);
8610                                 endYear = Math.max(year, determineYear(years[1] || ""));
8611                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8612                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8613                                 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
8614                                 for (; year <= endYear; year++) {
8615                                         inst.yearshtml += "<option value='" + year + "'" +
8616                                                 (year === drawYear ? " selected='selected'" : "") +
8617                                                 ">" + year + "</option>";
8618                                 }
8619                                 inst.yearshtml += "</select>";
8620
8621                                 html += inst.yearshtml;
8622                                 inst.yearshtml = null;
8623                         }
8624                 }
8625
8626                 html += this._get(inst, "yearSuffix");
8627                 if (showMonthAfterYear) {
8628                         html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
8629                 }
8630                 html += "</div>"; // Close datepicker_header
8631                 return html;
8632         },
8633
8634         /* Adjust one of the date sub-fields. */
8635         _adjustInstDate: function(inst, offset, period) {
8636                 var year = inst.drawYear + (period === "Y" ? offset : 0),
8637                         month = inst.drawMonth + (period === "M" ? offset : 0),
8638                         day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
8639                         date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
8640
8641                 inst.selectedDay = date.getDate();
8642                 inst.drawMonth = inst.selectedMonth = date.getMonth();
8643                 inst.drawYear = inst.selectedYear = date.getFullYear();
8644                 if (period === "M" || period === "Y") {
8645                         this._notifyChange(inst);
8646                 }
8647         },
8648
8649         /* Ensure a date is within any min/max bounds. */
8650         _restrictMinMax: function(inst, date) {
8651                 var minDate = this._getMinMaxDate(inst, "min"),
8652                         maxDate = this._getMinMaxDate(inst, "max"),
8653                         newDate = (minDate && date < minDate ? minDate : date);
8654                 return (maxDate && newDate > maxDate ? maxDate : newDate);
8655         },
8656
8657         /* Notify change of month/year. */
8658         _notifyChange: function(inst) {
8659                 var onChange = this._get(inst, "onChangeMonthYear");
8660                 if (onChange) {
8661                         onChange.apply((inst.input ? inst.input[0] : null),
8662                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
8663                 }
8664         },
8665
8666         /* Determine the number of months to show. */
8667         _getNumberOfMonths: function(inst) {
8668                 var numMonths = this._get(inst, "numberOfMonths");
8669                 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
8670         },
8671
8672         /* Determine the current maximum date - ensure no time components are set. */
8673         _getMinMaxDate: function(inst, minMax) {
8674                 return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
8675         },
8676
8677         /* Find the number of days in a given month. */
8678         _getDaysInMonth: function(year, month) {
8679                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8680         },
8681
8682         /* Find the day of the week of the first of a month. */
8683         _getFirstDayOfMonth: function(year, month) {
8684                 return new Date(year, month, 1).getDay();
8685         },
8686
8687         /* Determines if we should allow a "next/prev" month display change. */
8688         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
8689                 var numMonths = this._getNumberOfMonths(inst),
8690                         date = this._daylightSavingAdjust(new Date(curYear,
8691                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8692
8693                 if (offset < 0) {
8694                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8695                 }
8696                 return this._isInRange(inst, date);
8697         },
8698
8699         /* Is the given date in the accepted range? */
8700         _isInRange: function(inst, date) {
8701                 var yearSplit, currentYear,
8702                         minDate = this._getMinMaxDate(inst, "min"),
8703                         maxDate = this._getMinMaxDate(inst, "max"),
8704                         minYear = null,
8705                         maxYear = null,
8706                         years = this._get(inst, "yearRange");
8707                         if (years){
8708                                 yearSplit = years.split(":");
8709                                 currentYear = new Date().getFullYear();
8710                                 minYear = parseInt(yearSplit[0], 10);
8711                                 maxYear = parseInt(yearSplit[1], 10);
8712                                 if ( yearSplit[0].match(/[+\-].*/) ) {
8713                                         minYear += currentYear;
8714                                 }
8715                                 if ( yearSplit[1].match(/[+\-].*/) ) {
8716                                         maxYear += currentYear;
8717                                 }
8718                         }
8719
8720                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
8721                         (!maxDate || date.getTime() <= maxDate.getTime()) &&
8722                         (!minYear || date.getFullYear() >= minYear) &&
8723                         (!maxYear || date.getFullYear() <= maxYear));
8724         },
8725
8726         /* Provide the configuration settings for formatting/parsing. */
8727         _getFormatConfig: function(inst) {
8728                 var shortYearCutoff = this._get(inst, "shortYearCutoff");
8729                 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
8730                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8731                 return {shortYearCutoff: shortYearCutoff,
8732                         dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
8733                         monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
8734         },
8735
8736         /* Format the given date for display. */
8737         _formatDate: function(inst, day, month, year) {
8738                 if (!day) {
8739                         inst.currentDay = inst.selectedDay;
8740                         inst.currentMonth = inst.selectedMonth;
8741                         inst.currentYear = inst.selectedYear;
8742                 }
8743                 var date = (day ? (typeof day === "object" ? day :
8744                         this._daylightSavingAdjust(new Date(year, month, day))) :
8745                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8746                 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
8747         }
8748 });
8749
8750 /*
8751  * Bind hover events for datepicker elements.
8752  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8753  * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8754  */
8755 function bindHover(dpDiv) {
8756         var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
8757         return dpDiv.delegate(selector, "mouseout", function() {
8758                         $(this).removeClass("ui-state-hover");
8759                         if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8760                                 $(this).removeClass("ui-datepicker-prev-hover");
8761                         }
8762                         if (this.className.indexOf("ui-datepicker-next") !== -1) {
8763                                 $(this).removeClass("ui-datepicker-next-hover");
8764                         }
8765                 })
8766                 .delegate(selector, "mouseover", function(){
8767                         if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
8768                                 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
8769                                 $(this).addClass("ui-state-hover");
8770                                 if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8771                                         $(this).addClass("ui-datepicker-prev-hover");
8772                                 }
8773                                 if (this.className.indexOf("ui-datepicker-next") !== -1) {
8774                                         $(this).addClass("ui-datepicker-next-hover");
8775                                 }
8776                         }
8777                 });
8778 }
8779
8780 /* jQuery extend now ignores nulls! */
8781 function extendRemove(target, props) {
8782         $.extend(target, props);
8783         for (var name in props) {
8784                 if (props[name] == null) {
8785                         target[name] = props[name];
8786                 }
8787         }
8788         return target;
8789 }
8790
8791 /* Invoke the datepicker functionality.
8792    @param  options  string - a command, optionally followed by additional parameters or
8793                                         Object - settings for attaching new datepicker functionality
8794    @return  jQuery object */
8795 $.fn.datepicker = function(options){
8796
8797         /* Verify an empty collection wasn't passed - Fixes #6976 */
8798         if ( !this.length ) {
8799                 return this;
8800         }
8801
8802         /* Initialise the date picker. */
8803         if (!$.datepicker.initialized) {
8804                 $(document).mousedown($.datepicker._checkExternalClick);
8805                 $.datepicker.initialized = true;
8806         }
8807
8808         /* Append datepicker main container to body if not exist. */
8809         if ($("#"+$.datepicker._mainDivId).length === 0) {
8810                 $("body").append($.datepicker.dpDiv);
8811         }
8812
8813         var otherArgs = Array.prototype.slice.call(arguments, 1);
8814         if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
8815                 return $.datepicker["_" + options + "Datepicker"].
8816                         apply($.datepicker, [this[0]].concat(otherArgs));
8817         }
8818         if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
8819                 return $.datepicker["_" + options + "Datepicker"].
8820                         apply($.datepicker, [this[0]].concat(otherArgs));
8821         }
8822         return this.each(function() {
8823                 typeof options === "string" ?
8824                         $.datepicker["_" + options + "Datepicker"].
8825                                 apply($.datepicker, [this].concat(otherArgs)) :
8826                         $.datepicker._attachDatepicker(this, options);
8827         });
8828 };
8829
8830 $.datepicker = new Datepicker(); // singleton instance
8831 $.datepicker.initialized = false;
8832 $.datepicker.uuid = new Date().getTime();
8833 $.datepicker.version = "1.10.3";
8834
8835 })(jQuery);
8836 (function( $, undefined ) {
8837
8838 var sizeRelatedOptions = {
8839                 buttons: true,
8840                 height: true,
8841                 maxHeight: true,
8842                 maxWidth: true,
8843                 minHeight: true,
8844                 minWidth: true,
8845                 width: true
8846         },
8847         resizableRelatedOptions = {
8848                 maxHeight: true,
8849                 maxWidth: true,
8850                 minHeight: true,
8851                 minWidth: true
8852         };
8853
8854 $.widget( "ui.dialog", {
8855         version: "1.10.3",
8856         options: {
8857                 appendTo: "body",
8858                 autoOpen: true,
8859                 buttons: [],
8860                 closeOnEscape: true,
8861                 closeText: "close",
8862                 dialogClass: "",
8863                 draggable: true,
8864                 hide: null,
8865                 height: "auto",
8866                 maxHeight: null,
8867                 maxWidth: null,
8868                 minHeight: 150,
8869                 minWidth: 150,
8870                 modal: false,
8871                 position: {
8872                         my: "center",
8873                         at: "center",
8874                         of: window,
8875                         collision: "fit",
8876                         // Ensure the titlebar is always visible
8877                         using: function( pos ) {
8878                                 var topOffset = $( this ).css( pos ).offset().top;
8879                                 if ( topOffset < 0 ) {
8880                                         $( this ).css( "top", pos.top - topOffset );
8881                                 }
8882                         }
8883                 },
8884                 resizable: true,
8885                 show: null,
8886                 title: null,
8887                 width: 300,
8888
8889                 // callbacks
8890                 beforeClose: null,
8891                 close: null,
8892                 drag: null,
8893                 dragStart: null,
8894                 dragStop: null,
8895                 focus: null,
8896                 open: null,
8897                 resize: null,
8898                 resizeStart: null,
8899                 resizeStop: null
8900         },
8901
8902         _create: function() {
8903                 this.originalCss = {
8904                         display: this.element[0].style.display,
8905                         width: this.element[0].style.width,
8906                         minHeight: this.element[0].style.minHeight,
8907                         maxHeight: this.element[0].style.maxHeight,
8908                         height: this.element[0].style.height
8909                 };
8910                 this.originalPosition = {
8911                         parent: this.element.parent(),
8912                         index: this.element.parent().children().index( this.element )
8913                 };
8914                 this.originalTitle = this.element.attr("title");
8915                 this.options.title = this.options.title || this.originalTitle;
8916
8917                 this._createWrapper();
8918
8919                 this.element
8920                         .show()
8921                         .removeAttr("title")
8922                         .addClass("ui-dialog-content ui-widget-content")
8923                         .appendTo( this.uiDialog );
8924
8925                 this._createTitlebar();
8926                 this._createButtonPane();
8927
8928                 if ( this.options.draggable && $.fn.draggable ) {
8929                         this._makeDraggable();
8930                 }
8931                 if ( this.options.resizable && $.fn.resizable ) {
8932                         this._makeResizable();
8933                 }
8934
8935                 this._isOpen = false;
8936         },
8937
8938         _init: function() {
8939                 if ( this.options.autoOpen ) {
8940                         this.open();
8941                 }
8942         },
8943
8944         _appendTo: function() {
8945                 var element = this.options.appendTo;
8946                 if ( element && (element.jquery || element.nodeType) ) {
8947                         return $( element );
8948                 }
8949                 return this.document.find( element || "body" ).eq( 0 );
8950         },
8951
8952         _destroy: function() {
8953                 var next,
8954                         originalPosition = this.originalPosition;
8955
8956                 this._destroyOverlay();
8957
8958                 this.element
8959                         .removeUniqueId()
8960                         .removeClass("ui-dialog-content ui-widget-content")
8961                         .css( this.originalCss )
8962                         // Without detaching first, the following becomes really slow
8963                         .detach();
8964
8965                 this.uiDialog.stop( true, true ).remove();
8966
8967                 if ( this.originalTitle ) {
8968                         this.element.attr( "title", this.originalTitle );
8969                 }
8970
8971                 next = originalPosition.parent.children().eq( originalPosition.index );
8972                 // Don't try to place the dialog next to itself (#8613)
8973                 if ( next.length && next[0] !== this.element[0] ) {
8974                         next.before( this.element );
8975                 } else {
8976                         originalPosition.parent.append( this.element );
8977                 }
8978         },
8979
8980         widget: function() {
8981                 return this.uiDialog;
8982         },
8983
8984         disable: $.noop,
8985         enable: $.noop,
8986
8987         close: function( event ) {
8988                 var that = this;
8989
8990                 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8991                         return;
8992                 }
8993
8994                 this._isOpen = false;
8995                 this._destroyOverlay();
8996
8997                 if ( !this.opener.filter(":focusable").focus().length ) {
8998                         // Hiding a focused element doesn't trigger blur in WebKit
8999                         // so in case we have nothing to focus on, explicitly blur the active element
9000                         // https://bugs.webkit.org/show_bug.cgi?id=47182
9001                         $( this.document[0].activeElement ).blur();
9002                 }
9003
9004                 this._hide( this.uiDialog, this.options.hide, function() {
9005                         that._trigger( "close", event );
9006                 });
9007         },
9008
9009         isOpen: function() {
9010                 return this._isOpen;
9011         },
9012
9013         moveToTop: function() {
9014                 this._moveToTop();
9015         },
9016
9017         _moveToTop: function( event, silent ) {
9018                 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9019                 if ( moved && !silent ) {
9020                         this._trigger( "focus", event );
9021                 }
9022                 return moved;
9023         },
9024
9025         open: function() {
9026                 var that = this;
9027                 if ( this._isOpen ) {
9028                         if ( this._moveToTop() ) {
9029                                 this._focusTabbable();
9030                         }
9031                         return;
9032                 }
9033
9034                 this._isOpen = true;
9035                 this.opener = $( this.document[0].activeElement );
9036
9037                 this._size();
9038                 this._position();
9039                 this._createOverlay();
9040                 this._moveToTop( null, true );
9041                 this._show( this.uiDialog, this.options.show, function() {
9042                         that._focusTabbable();
9043                         that._trigger("focus");
9044                 });
9045
9046                 this._trigger("open");
9047         },
9048
9049         _focusTabbable: function() {
9050                 // Set focus to the first match:
9051                 // 1. First element inside the dialog matching [autofocus]
9052                 // 2. Tabbable element inside the content element
9053                 // 3. Tabbable element inside the buttonpane
9054                 // 4. The close button
9055                 // 5. The dialog itself
9056                 var hasFocus = this.element.find("[autofocus]");
9057                 if ( !hasFocus.length ) {
9058                         hasFocus = this.element.find(":tabbable");
9059                 }
9060                 if ( !hasFocus.length ) {
9061                         hasFocus = this.uiDialogButtonPane.find(":tabbable");
9062                 }
9063                 if ( !hasFocus.length ) {
9064                         hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9065                 }
9066                 if ( !hasFocus.length ) {
9067                         hasFocus = this.uiDialog;
9068                 }
9069                 hasFocus.eq( 0 ).focus();
9070         },
9071
9072         _keepFocus: function( event ) {
9073                 function checkFocus() {
9074                         var activeElement = this.document[0].activeElement,
9075                                 isActive = this.uiDialog[0] === activeElement ||
9076                                         $.contains( this.uiDialog[0], activeElement );
9077                         if ( !isActive ) {
9078                                 this._focusTabbable();
9079                         }
9080                 }
9081                 event.preventDefault();
9082                 checkFocus.call( this );
9083                 // support: IE
9084                 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9085                 // so we check again later
9086                 this._delay( checkFocus );
9087         },
9088
9089         _createWrapper: function() {
9090                 this.uiDialog = $("<div>")
9091                         .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9092                                 this.options.dialogClass )
9093                         .hide()
9094                         .attr({
9095                                 // Setting tabIndex makes the div focusable
9096                                 tabIndex: -1,
9097                                 role: "dialog"
9098                         })
9099                         .appendTo( this._appendTo() );
9100
9101                 this._on( this.uiDialog, {
9102                         keydown: function( event ) {
9103                                 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9104                                                 event.keyCode === $.ui.keyCode.ESCAPE ) {
9105                                         event.preventDefault();
9106                                         this.close( event );
9107                                         return;
9108                                 }
9109
9110                                 // prevent tabbing out of dialogs
9111                                 if ( event.keyCode !== $.ui.keyCode.TAB ) {
9112                                         return;
9113                                 }
9114                                 var tabbables = this.uiDialog.find(":tabbable"),
9115                                         first = tabbables.filter(":first"),
9116                                         last  = tabbables.filter(":last");
9117
9118                                 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9119                                         first.focus( 1 );
9120                                         event.preventDefault();
9121                                 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9122                                         last.focus( 1 );
9123                                         event.preventDefault();
9124                                 }
9125                         },
9126                         mousedown: function( event ) {
9127                                 if ( this._moveToTop( event ) ) {
9128                                         this._focusTabbable();
9129                                 }
9130                         }
9131                 });
9132
9133                 // We assume that any existing aria-describedby attribute means
9134                 // that the dialog content is marked up properly
9135                 // otherwise we brute force the content as the description
9136                 if ( !this.element.find("[aria-describedby]").length ) {
9137                         this.uiDialog.attr({
9138                                 "aria-describedby": this.element.uniqueId().attr("id")
9139                         });
9140                 }
9141         },
9142
9143         _createTitlebar: function() {
9144                 var uiDialogTitle;
9145
9146                 this.uiDialogTitlebar = $("<div>")
9147                         .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9148                         .prependTo( this.uiDialog );
9149                 this._on( this.uiDialogTitlebar, {
9150                         mousedown: function( event ) {
9151                                 // Don't prevent click on close button (#8838)
9152                                 // Focusing a dialog that is partially scrolled out of view
9153                                 // causes the browser to scroll it into view, preventing the click event
9154                                 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9155                                         // Dialog isn't getting focus when dragging (#8063)
9156                                         this.uiDialog.focus();
9157                                 }
9158                         }
9159                 });
9160
9161                 this.uiDialogTitlebarClose = $("<button></button>")
9162                         .button({
9163                                 label: this.options.closeText,
9164                                 icons: {
9165                                         primary: "ui-icon-closethick"
9166                                 },
9167                                 text: false
9168                         })
9169                         .addClass("ui-dialog-titlebar-close")
9170                         .appendTo( this.uiDialogTitlebar );
9171                 this._on( this.uiDialogTitlebarClose, {
9172                         click: function( event ) {
9173                                 event.preventDefault();
9174                                 this.close( event );
9175                         }
9176                 });
9177
9178                 uiDialogTitle = $("<span>")
9179                         .uniqueId()
9180                         .addClass("ui-dialog-title")
9181                         .prependTo( this.uiDialogTitlebar );
9182                 this._title( uiDialogTitle );
9183
9184                 this.uiDialog.attr({
9185                         "aria-labelledby": uiDialogTitle.attr("id")
9186                 });
9187         },
9188
9189         _title: function( title ) {
9190                 if ( !this.options.title ) {
9191                         title.html("&#160;");
9192                 }
9193                 title.text( this.options.title );
9194         },
9195
9196         _createButtonPane: function() {
9197                 this.uiDialogButtonPane = $("<div>")
9198                         .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
9199
9200                 this.uiButtonSet = $("<div>")
9201                         .addClass("ui-dialog-buttonset")
9202                         .appendTo( this.uiDialogButtonPane );
9203
9204                 this._createButtons();
9205         },
9206
9207         _createButtons: function() {
9208                 var that = this,
9209                         buttons = this.options.buttons;
9210
9211                 // if we already have a button pane, remove it
9212                 this.uiDialogButtonPane.remove();
9213                 this.uiButtonSet.empty();
9214
9215                 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
9216                         this.uiDialog.removeClass("ui-dialog-buttons");
9217                         return;
9218                 }
9219
9220                 $.each( buttons, function( name, props ) {
9221                         var click, buttonOptions;
9222                         props = $.isFunction( props ) ?
9223                                 { click: props, text: name } :
9224                                 props;
9225                         // Default to a non-submitting button
9226                         props = $.extend( { type: "button" }, props );
9227                         // Change the context for the click callback to be the main element
9228                         click = props.click;
9229                         props.click = function() {
9230                                 click.apply( that.element[0], arguments );
9231                         };
9232                         buttonOptions = {
9233                                 icons: props.icons,
9234                                 text: props.showText
9235                         };
9236                         delete props.icons;
9237                         delete props.showText;
9238                         $( "<button></button>", props )
9239                                 .button( buttonOptions )
9240                                 .appendTo( that.uiButtonSet );
9241                 });
9242                 this.uiDialog.addClass("ui-dialog-buttons");
9243                 this.uiDialogButtonPane.appendTo( this.uiDialog );
9244         },
9245
9246         _makeDraggable: function() {
9247                 var that = this,
9248                         options = this.options;
9249
9250                 function filteredUi( ui ) {
9251                         return {
9252                                 position: ui.position,
9253                                 offset: ui.offset
9254                         };
9255                 }
9256
9257                 this.uiDialog.draggable({
9258                         cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
9259                         handle: ".ui-dialog-titlebar",
9260                         containment: "document",
9261                         start: function( event, ui ) {
9262                                 $( this ).addClass("ui-dialog-dragging");
9263                                 that._blockFrames();
9264                                 that._trigger( "dragStart", event, filteredUi( ui ) );
9265                         },
9266                         drag: function( event, ui ) {
9267                                 that._trigger( "drag", event, filteredUi( ui ) );
9268                         },
9269                         stop: function( event, ui ) {
9270                                 options.position = [
9271                                         ui.position.left - that.document.scrollLeft(),
9272                                         ui.position.top - that.document.scrollTop()
9273                                 ];
9274                                 $( this ).removeClass("ui-dialog-dragging");
9275                                 that._unblockFrames();
9276                                 that._trigger( "dragStop", event, filteredUi( ui ) );
9277                         }
9278                 });
9279         },
9280
9281         _makeResizable: function() {
9282                 var that = this,
9283                         options = this.options,
9284                         handles = options.resizable,
9285                         // .ui-resizable has position: relative defined in the stylesheet
9286                         // but dialogs have to use absolute or fixed positioning
9287                         position = this.uiDialog.css("position"),
9288                         resizeHandles = typeof handles === "string" ?
9289                                 handles :
9290                                 "n,e,s,w,se,sw,ne,nw";
9291
9292                 function filteredUi( ui ) {
9293                         return {
9294                                 originalPosition: ui.originalPosition,
9295                                 originalSize: ui.originalSize,
9296                                 position: ui.position,
9297                                 size: ui.size
9298                         };
9299                 }
9300
9301                 this.uiDialog.resizable({
9302                         cancel: ".ui-dialog-content",
9303                         containment: "document",
9304                         alsoResize: this.element,
9305                         maxWidth: options.maxWidth,
9306                         maxHeight: options.maxHeight,
9307                         minWidth: options.minWidth,
9308                         minHeight: this._minHeight(),
9309                         handles: resizeHandles,
9310                         start: function( event, ui ) {
9311                                 $( this ).addClass("ui-dialog-resizing");
9312                                 that._blockFrames();
9313                                 that._trigger( "resizeStart", event, filteredUi( ui ) );
9314                         },
9315                         resize: function( event, ui ) {
9316                                 that._trigger( "resize", event, filteredUi( ui ) );
9317                         },
9318                         stop: function( event, ui ) {
9319                                 options.height = $( this ).height();
9320                                 options.width = $( this ).width();
9321                                 $( this ).removeClass("ui-dialog-resizing");
9322                                 that._unblockFrames();
9323                                 that._trigger( "resizeStop", event, filteredUi( ui ) );
9324                         }
9325                 })
9326                 .css( "position", position );
9327         },
9328
9329         _minHeight: function() {
9330                 var options = this.options;
9331
9332                 return options.height === "auto" ?
9333                         options.minHeight :
9334                         Math.min( options.minHeight, options.height );
9335         },
9336
9337         _position: function() {
9338                 // Need to show the dialog to get the actual offset in the position plugin
9339                 var isVisible = this.uiDialog.is(":visible");
9340                 if ( !isVisible ) {
9341                         this.uiDialog.show();
9342                 }
9343                 this.uiDialog.position( this.options.position );
9344                 if ( !isVisible ) {
9345                         this.uiDialog.hide();
9346                 }
9347         },
9348
9349         _setOptions: function( options ) {
9350                 var that = this,
9351                         resize = false,
9352                         resizableOptions = {};
9353
9354                 $.each( options, function( key, value ) {
9355                         that._setOption( key, value );
9356
9357                         if ( key in sizeRelatedOptions ) {
9358                                 resize = true;
9359                         }
9360                         if ( key in resizableRelatedOptions ) {
9361                                 resizableOptions[ key ] = value;
9362                         }
9363                 });
9364
9365                 if ( resize ) {
9366                         this._size();
9367                         this._position();
9368                 }
9369                 if ( this.uiDialog.is(":data(ui-resizable)") ) {
9370                         this.uiDialog.resizable( "option", resizableOptions );
9371                 }
9372         },
9373
9374         _setOption: function( key, value ) {
9375                 /*jshint maxcomplexity:15*/
9376                 var isDraggable, isResizable,
9377                         uiDialog = this.uiDialog;
9378
9379                 if ( key === "dialogClass" ) {
9380                         uiDialog
9381                                 .removeClass( this.options.dialogClass )
9382                                 .addClass( value );
9383                 }
9384
9385                 if ( key === "disabled" ) {
9386                         return;
9387                 }
9388
9389                 this._super( key, value );
9390
9391                 if ( key === "appendTo" ) {
9392                         this.uiDialog.appendTo( this._appendTo() );
9393                 }
9394
9395                 if ( key === "buttons" ) {
9396                         this._createButtons();
9397                 }
9398
9399                 if ( key === "closeText" ) {
9400                         this.uiDialogTitlebarClose.button({
9401                                 // Ensure that we always pass a string
9402                                 label: "" + value
9403                         });
9404                 }
9405
9406                 if ( key === "draggable" ) {
9407                         isDraggable = uiDialog.is(":data(ui-draggable)");
9408                         if ( isDraggable && !value ) {
9409                                 uiDialog.draggable("destroy");
9410                         }
9411
9412                         if ( !isDraggable && value ) {
9413                                 this._makeDraggable();
9414                         }
9415                 }
9416
9417                 if ( key === "position" ) {
9418                         this._position();
9419                 }
9420
9421                 if ( key === "resizable" ) {
9422                         // currently resizable, becoming non-resizable
9423                         isResizable = uiDialog.is(":data(ui-resizable)");
9424                         if ( isResizable && !value ) {
9425                                 uiDialog.resizable("destroy");
9426                         }
9427
9428                         // currently resizable, changing handles
9429                         if ( isResizable && typeof value === "string" ) {
9430                                 uiDialog.resizable( "option", "handles", value );
9431                         }
9432
9433                         // currently non-resizable, becoming resizable
9434                         if ( !isResizable && value !== false ) {
9435                                 this._makeResizable();
9436                         }
9437                 }
9438
9439                 if ( key === "title" ) {
9440                         this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
9441                 }
9442         },
9443
9444         _size: function() {
9445                 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9446                 // divs will both have width and height set, so we need to reset them
9447                 var nonContentHeight, minContentHeight, maxContentHeight,
9448                         options = this.options;
9449
9450                 // Reset content sizing
9451                 this.element.show().css({
9452                         width: "auto",
9453                         minHeight: 0,
9454                         maxHeight: "none",
9455                         height: 0
9456                 });
9457
9458                 if ( options.minWidth > options.width ) {
9459                         options.width = options.minWidth;
9460                 }
9461
9462                 // reset wrapper sizing
9463                 // determine the height of all the non-content elements
9464                 nonContentHeight = this.uiDialog.css({
9465                                 height: "auto",
9466                                 width: options.width
9467                         })
9468                         .outerHeight();
9469                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9470                 maxContentHeight = typeof options.maxHeight === "number" ?
9471                         Math.max( 0, options.maxHeight - nonContentHeight ) :
9472                         "none";
9473
9474                 if ( options.height === "auto" ) {
9475                         this.element.css({
9476                                 minHeight: minContentHeight,
9477                                 maxHeight: maxContentHeight,
9478                                 height: "auto"
9479                         });
9480                 } else {
9481                         this.element.height( Math.max( 0, options.height - nonContentHeight ) );
9482                 }
9483
9484                 if (this.uiDialog.is(":data(ui-resizable)") ) {
9485                         this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
9486                 }
9487         },
9488
9489         _blockFrames: function() {
9490                 this.iframeBlocks = this.document.find( "iframe" ).map(function() {
9491                         var iframe = $( this );
9492
9493                         return $( "<div>" )
9494                                 .css({
9495                                         position: "absolute",
9496                                         width: iframe.outerWidth(),
9497                                         height: iframe.outerHeight()
9498                                 })
9499                                 .appendTo( iframe.parent() )
9500                                 .offset( iframe.offset() )[0];
9501                 });
9502         },
9503
9504         _unblockFrames: function() {
9505                 if ( this.iframeBlocks ) {
9506                         this.iframeBlocks.remove();
9507                         delete this.iframeBlocks;
9508                 }
9509         },
9510
9511         _allowInteraction: function( event ) {
9512                 if ( $( event.target ).closest(".ui-dialog").length ) {
9513                         return true;
9514                 }
9515
9516                 // TODO: Remove hack when datepicker implements
9517                 // the .ui-front logic (#8989)
9518                 return !!$( event.target ).closest(".ui-datepicker").length;
9519         },
9520
9521         _createOverlay: function() {
9522                 if ( !this.options.modal ) {
9523                         return;
9524                 }
9525
9526                 var that = this,
9527                         widgetFullName = this.widgetFullName;
9528                 if ( !$.ui.dialog.overlayInstances ) {
9529                         // Prevent use of anchors and inputs.
9530                         // We use a delay in case the overlay is created from an
9531                         // event that we're going to be cancelling. (#2804)
9532                         this._delay(function() {
9533                                 // Handle .dialog().dialog("close") (#4065)
9534                                 if ( $.ui.dialog.overlayInstances ) {
9535                                         this.document.bind( "focusin.dialog", function( event ) {
9536                                                 if ( !that._allowInteraction( event ) ) {
9537                                                         event.preventDefault();
9538                                                         $(".ui-dialog:visible:last .ui-dialog-content")
9539                                                                 .data( widgetFullName )._focusTabbable();
9540                                                 }
9541                                         });
9542                                 }
9543                         });
9544                 }
9545
9546                 this.overlay = $("<div>")
9547                         .addClass("ui-widget-overlay ui-front")
9548                         .appendTo( this._appendTo() );
9549                 this._on( this.overlay, {
9550                         mousedown: "_keepFocus"
9551                 });
9552                 $.ui.dialog.overlayInstances++;
9553         },
9554
9555         _destroyOverlay: function() {
9556                 if ( !this.options.modal ) {
9557                         return;
9558                 }
9559
9560                 if ( this.overlay ) {
9561                         $.ui.dialog.overlayInstances--;
9562
9563                         if ( !$.ui.dialog.overlayInstances ) {
9564                                 this.document.unbind( "focusin.dialog" );
9565                         }
9566                         this.overlay.remove();
9567                         this.overlay = null;
9568                 }
9569         }
9570 });
9571
9572 $.ui.dialog.overlayInstances = 0;
9573
9574 // DEPRECATED
9575 if ( $.uiBackCompat !== false ) {
9576         // position option with array notation
9577         // just override with old implementation
9578         $.widget( "ui.dialog", $.ui.dialog, {
9579                 _position: function() {
9580                         var position = this.options.position,
9581                                 myAt = [],
9582                                 offset = [ 0, 0 ],
9583                                 isVisible;
9584
9585                         if ( position ) {
9586                                 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
9587                                         myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
9588                                         if ( myAt.length === 1 ) {
9589                                                 myAt[1] = myAt[0];
9590                                         }
9591
9592                                         $.each( [ "left", "top" ], function( i, offsetPosition ) {
9593                                                 if ( +myAt[ i ] === myAt[ i ] ) {
9594                                                         offset[ i ] = myAt[ i ];
9595                                                         myAt[ i ] = offsetPosition;
9596                                                 }
9597                                         });
9598
9599                                         position = {
9600                                                 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
9601                                                         myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
9602                                                 at: myAt.join(" ")
9603                                         };
9604                                 }
9605
9606                                 position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
9607                         } else {
9608                                 position = $.ui.dialog.prototype.options.position;
9609                         }
9610
9611                         // need to show the dialog to get the actual offset in the position plugin
9612                         isVisible = this.uiDialog.is(":visible");
9613                         if ( !isVisible ) {
9614                                 this.uiDialog.show();
9615                         }
9616                         this.uiDialog.position( position );
9617                         if ( !isVisible ) {
9618                                 this.uiDialog.hide();
9619                         }
9620                 }
9621         });
9622 }
9623
9624 }( jQuery ) );
9625 (function( $, undefined ) {
9626
9627 $.widget( "ui.menu", {
9628         version: "1.10.3",
9629         defaultElement: "<ul>",
9630         delay: 300,
9631         options: {
9632                 icons: {
9633                         submenu: "ui-icon-carat-1-e"
9634                 },
9635                 menus: "ul",
9636                 position: {
9637                         my: "left top",
9638                         at: "right top"
9639                 },
9640                 role: "menu",
9641
9642                 // callbacks
9643                 blur: null,
9644                 focus: null,
9645                 select: null
9646         },
9647
9648         _create: function() {
9649                 this.activeMenu = this.element;
9650                 // flag used to prevent firing of the click handler
9651                 // as the event bubbles up through nested menus
9652                 this.mouseHandled = false;
9653                 this.element
9654                         .uniqueId()
9655                         .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9656                         .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
9657                         .attr({
9658                                 role: this.options.role,
9659                                 tabIndex: 0
9660                         })
9661                         // need to catch all clicks on disabled menu
9662                         // not possible through _on
9663                         .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
9664                                 if ( this.options.disabled ) {
9665                                         event.preventDefault();
9666                                 }
9667                         }, this ));
9668
9669                 if ( this.options.disabled ) {
9670                         this.element
9671                                 .addClass( "ui-state-disabled" )
9672                                 .attr( "aria-disabled", "true" );
9673                 }
9674
9675                 this._on({
9676                         // Prevent focus from sticking to links inside menu after clicking
9677                         // them (focus should always stay on UL during navigation).
9678                         "mousedown .ui-menu-item > a": function( event ) {
9679                                 event.preventDefault();
9680                         },
9681                         "click .ui-state-disabled > a": function( event ) {
9682                                 event.preventDefault();
9683                         },
9684                         "click .ui-menu-item:has(a)": function( event ) {
9685                                 var target = $( event.target ).closest( ".ui-menu-item" );
9686                                 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
9687                                         this.mouseHandled = true;
9688
9689                                         this.select( event );
9690                                         // Open submenu on click
9691                                         if ( target.has( ".ui-menu" ).length ) {
9692                                                 this.expand( event );
9693                                         } else if ( !this.element.is( ":focus" ) ) {
9694                                                 // Redirect focus to the menu
9695                                                 this.element.trigger( "focus", [ true ] );
9696
9697                                                 // If the active item is on the top level, let it stay active.
9698                                                 // Otherwise, blur the active item since it is no longer visible.
9699                                                 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
9700                                                         clearTimeout( this.timer );
9701                                                 }
9702                                         }
9703                                 }
9704                         },
9705                         "mouseenter .ui-menu-item": function( event ) {
9706                                 var target = $( event.currentTarget );
9707                                 // Remove ui-state-active class from siblings of the newly focused menu item
9708                                 // to avoid a jump caused by adjacent elements both having a class with a border
9709                                 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
9710                                 this.focus( event, target );
9711                         },
9712                         mouseleave: "collapseAll",
9713                         "mouseleave .ui-menu": "collapseAll",
9714                         focus: function( event, keepActiveItem ) {
9715                                 // If there's already an active item, keep it active
9716                                 // If not, activate the first item
9717                                 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
9718
9719                                 if ( !keepActiveItem ) {
9720                                         this.focus( event, item );
9721                                 }
9722                         },
9723                         blur: function( event ) {
9724                                 this._delay(function() {
9725                                         if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
9726                                                 this.collapseAll( event );
9727                                         }
9728                                 });
9729                         },
9730                         keydown: "_keydown"
9731                 });
9732
9733                 this.refresh();
9734
9735                 // Clicks outside of a menu collapse any open menus
9736                 this._on( this.document, {
9737                         click: function( event ) {
9738                                 if ( !$( event.target ).closest( ".ui-menu" ).length ) {
9739                                         this.collapseAll( event );
9740                                 }
9741
9742                                 // Reset the mouseHandled flag
9743                                 this.mouseHandled = false;
9744                         }
9745                 });
9746         },
9747
9748         _destroy: function() {
9749                 // Destroy (sub)menus
9750                 this.element
9751                         .removeAttr( "aria-activedescendant" )
9752                         .find( ".ui-menu" ).addBack()
9753                                 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
9754                                 .removeAttr( "role" )
9755                                 .removeAttr( "tabIndex" )
9756                                 .removeAttr( "aria-labelledby" )
9757                                 .removeAttr( "aria-expanded" )
9758                                 .removeAttr( "aria-hidden" )
9759                                 .removeAttr( "aria-disabled" )
9760                                 .removeUniqueId()
9761                                 .show();
9762
9763                 // Destroy menu items
9764                 this.element.find( ".ui-menu-item" )
9765                         .removeClass( "ui-menu-item" )
9766                         .removeAttr( "role" )
9767                         .removeAttr( "aria-disabled" )
9768                         .children( "a" )
9769                                 .removeUniqueId()
9770                                 .removeClass( "ui-corner-all ui-state-hover" )
9771                                 .removeAttr( "tabIndex" )
9772                                 .removeAttr( "role" )
9773                                 .removeAttr( "aria-haspopup" )
9774                                 .children().each( function() {
9775                                         var elem = $( this );
9776                                         if ( elem.data( "ui-menu-submenu-carat" ) ) {
9777                                                 elem.remove();
9778                                         }
9779                                 });
9780
9781                 // Destroy menu dividers
9782                 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
9783         },
9784
9785         _keydown: function( event ) {
9786                 /*jshint maxcomplexity:20*/
9787                 var match, prev, character, skip, regex,
9788                         preventDefault = true;
9789
9790                 function escape( value ) {
9791                         return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
9792                 }
9793
9794                 switch ( event.keyCode ) {
9795                 case $.ui.keyCode.PAGE_UP:
9796                         this.previousPage( event );
9797                         break;
9798                 case $.ui.keyCode.PAGE_DOWN:
9799                         this.nextPage( event );
9800                         break;
9801                 case $.ui.keyCode.HOME:
9802                         this._move( "first", "first", event );
9803                         break;
9804                 case $.ui.keyCode.END:
9805                         this._move( "last", "last", event );
9806                         break;
9807                 case $.ui.keyCode.UP:
9808                         this.previous( event );
9809                         break;
9810                 case $.ui.keyCode.DOWN:
9811                         this.next( event );
9812                         break;
9813                 case $.ui.keyCode.LEFT:
9814                         this.collapse( event );
9815                         break;
9816                 case $.ui.keyCode.RIGHT:
9817                         if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
9818                                 this.expand( event );
9819                         }
9820                         break;
9821                 case $.ui.keyCode.ENTER:
9822                 case $.ui.keyCode.SPACE:
9823                         this._activate( event );
9824                         break;
9825                 case $.ui.keyCode.ESCAPE:
9826                         this.collapse( event );
9827                         break;
9828                 default:
9829                         preventDefault = false;
9830                         prev = this.previousFilter || "";
9831                         character = String.fromCharCode( event.keyCode );
9832                         skip = false;
9833
9834                         clearTimeout( this.filterTimer );
9835
9836                         if ( character === prev ) {
9837                                 skip = true;
9838                         } else {
9839                                 character = prev + character;
9840                         }
9841
9842                         regex = new RegExp( "^" + escape( character ), "i" );
9843                         match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9844                                 return regex.test( $( this ).children( "a" ).text() );
9845                         });
9846                         match = skip && match.index( this.active.next() ) !== -1 ?
9847                                 this.active.nextAll( ".ui-menu-item" ) :
9848                                 match;
9849
9850                         // If no matches on the current filter, reset to the last character pressed
9851                         // to move down the menu to the first item that starts with that character
9852                         if ( !match.length ) {
9853                                 character = String.fromCharCode( event.keyCode );
9854                                 regex = new RegExp( "^" + escape( character ), "i" );
9855                                 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9856                                         return regex.test( $( this ).children( "a" ).text() );
9857                                 });
9858                         }
9859
9860                         if ( match.length ) {
9861                                 this.focus( event, match );
9862                                 if ( match.length > 1 ) {
9863                                         this.previousFilter = character;
9864                                         this.filterTimer = this._delay(function() {
9865                                                 delete this.previousFilter;
9866                                         }, 1000 );
9867                                 } else {
9868                                         delete this.previousFilter;
9869                                 }
9870                         } else {
9871                                 delete this.previousFilter;
9872                         }
9873                 }
9874
9875                 if ( preventDefault ) {
9876                         event.preventDefault();
9877                 }
9878         },
9879
9880         _activate: function( event ) {
9881                 if ( !this.active.is( ".ui-state-disabled" ) ) {
9882                         if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
9883                                 this.expand( event );
9884                         } else {
9885                                 this.select( event );
9886                         }
9887                 }
9888         },
9889
9890         refresh: function() {
9891                 var menus,
9892                         icon = this.options.icons.submenu,
9893                         submenus = this.element.find( this.options.menus );
9894
9895                 // Initialize nested menus
9896                 submenus.filter( ":not(.ui-menu)" )
9897                         .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9898                         .hide()
9899                         .attr({
9900                                 role: this.options.role,
9901                                 "aria-hidden": "true",
9902                                 "aria-expanded": "false"
9903                         })
9904                         .each(function() {
9905                                 var menu = $( this ),
9906                                         item = menu.prev( "a" ),
9907                                         submenuCarat = $( "<span>" )
9908                                                 .addClass( "ui-menu-icon ui-icon " + icon )
9909                                                 .data( "ui-menu-submenu-carat", true );
9910
9911                                 item
9912                                         .attr( "aria-haspopup", "true" )
9913                                         .prepend( submenuCarat );
9914                                 menu.attr( "aria-labelledby", item.attr( "id" ) );
9915                         });
9916
9917                 menus = submenus.add( this.element );
9918
9919                 // Don't refresh list items that are already adapted
9920                 menus.children( ":not(.ui-menu-item):has(a)" )
9921                         .addClass( "ui-menu-item" )
9922                         .attr( "role", "presentation" )
9923                         .children( "a" )
9924                                 .uniqueId()
9925                                 .addClass( "ui-corner-all" )
9926                                 .attr({
9927                                         tabIndex: -1,
9928                                         role: this._itemRole()
9929                                 });
9930
9931                 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
9932                 menus.children( ":not(.ui-menu-item)" ).each(function() {
9933                         var item = $( this );
9934                         // hyphen, em dash, en dash
9935                         if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
9936                                 item.addClass( "ui-widget-content ui-menu-divider" );
9937                         }
9938                 });
9939
9940                 // Add aria-disabled attribute to any disabled menu item
9941                 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
9942
9943                 // If the active item has been removed, blur the menu
9944                 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
9945                         this.blur();
9946                 }
9947         },
9948
9949         _itemRole: function() {
9950                 return {
9951                         menu: "menuitem",
9952                         listbox: "option"
9953                 }[ this.options.role ];
9954         },
9955
9956         _setOption: function( key, value ) {
9957                 if ( key === "icons" ) {
9958                         this.element.find( ".ui-menu-icon" )
9959                                 .removeClass( this.options.icons.submenu )
9960                                 .addClass( value.submenu );
9961                 }
9962                 this._super( key, value );
9963         },
9964
9965         focus: function( event, item ) {
9966                 var nested, focused;
9967                 this.blur( event, event && event.type === "focus" );
9968
9969                 this._scrollIntoView( item );
9970
9971                 this.active = item.first();
9972                 focused = this.active.children( "a" ).addClass( "ui-state-focus" );
9973                 // Only update aria-activedescendant if there's a role
9974                 // otherwise we assume focus is managed elsewhere
9975                 if ( this.options.role ) {
9976                         this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
9977                 }
9978
9979                 // Highlight active parent menu item, if any
9980                 this.active
9981                         .parent()
9982                         .closest( ".ui-menu-item" )
9983                         .children( "a:first" )
9984                         .addClass( "ui-state-active" );
9985
9986                 if ( event && event.type === "keydown" ) {
9987                         this._close();
9988                 } else {
9989                         this.timer = this._delay(function() {
9990                                 this._close();
9991                         }, this.delay );
9992                 }
9993
9994                 nested = item.children( ".ui-menu" );
9995                 if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
9996                         this._startOpening(nested);
9997                 }
9998                 this.activeMenu = item.parent();
9999
10000                 this._trigger( "focus", event, { item: item } );
10001         },
10002
10003         _scrollIntoView: function( item ) {
10004                 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
10005                 if ( this._hasScroll() ) {
10006                         borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
10007                         paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
10008                         offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
10009                         scroll = this.activeMenu.scrollTop();
10010                         elementHeight = this.activeMenu.height();
10011                         itemHeight = item.height();
10012
10013                         if ( offset < 0 ) {
10014                                 this.activeMenu.scrollTop( scroll + offset );
10015                         } else if ( offset + itemHeight > elementHeight ) {
10016                                 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
10017                         }
10018                 }
10019         },
10020
10021         blur: function( event, fromFocus ) {
10022                 if ( !fromFocus ) {
10023                         clearTimeout( this.timer );
10024                 }
10025
10026                 if ( !this.active ) {
10027                         return;
10028                 }
10029
10030                 this.active.children( "a" ).removeClass( "ui-state-focus" );
10031                 this.active = null;
10032
10033                 this._trigger( "blur", event, { item: this.active } );
10034         },
10035
10036         _startOpening: function( submenu ) {
10037                 clearTimeout( this.timer );
10038
10039                 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
10040                 // shift in the submenu position when mousing over the carat icon
10041                 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
10042                         return;
10043                 }
10044
10045                 this.timer = this._delay(function() {
10046                         this._close();
10047                         this._open( submenu );
10048                 }, this.delay );
10049         },
10050
10051         _open: function( submenu ) {
10052                 var position = $.extend({
10053                         of: this.active
10054                 }, this.options.position );
10055
10056                 clearTimeout( this.timer );
10057                 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
10058                         .hide()
10059                         .attr( "aria-hidden", "true" );
10060
10061                 submenu
10062                         .show()
10063                         .removeAttr( "aria-hidden" )
10064                         .attr( "aria-expanded", "true" )
10065                         .position( position );
10066         },
10067
10068         collapseAll: function( event, all ) {
10069                 clearTimeout( this.timer );
10070                 this.timer = this._delay(function() {
10071                         // If we were passed an event, look for the submenu that contains the event
10072                         var currentMenu = all ? this.element :
10073                                 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
10074
10075                         // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
10076                         if ( !currentMenu.length ) {
10077                                 currentMenu = this.element;
10078                         }
10079
10080                         this._close( currentMenu );
10081
10082                         this.blur( event );
10083                         this.activeMenu = currentMenu;
10084                 }, this.delay );
10085         },
10086
10087         // With no arguments, closes the currently active menu - if nothing is active
10088         // it closes all menus.  If passed an argument, it will search for menus BELOW
10089         _close: function( startMenu ) {
10090                 if ( !startMenu ) {
10091                         startMenu = this.active ? this.active.parent() : this.element;
10092                 }
10093
10094                 startMenu
10095                         .find( ".ui-menu" )
10096                                 .hide()
10097                                 .attr( "aria-hidden", "true" )
10098                                 .attr( "aria-expanded", "false" )
10099                         .end()
10100                         .find( "a.ui-state-active" )
10101                                 .removeClass( "ui-state-active" );
10102         },
10103
10104         collapse: function( event ) {
10105                 var newItem = this.active &&
10106                         this.active.parent().closest( ".ui-menu-item", this.element );
10107                 if ( newItem && newItem.length ) {
10108                         this._close();
10109                         this.focus( event, newItem );
10110                 }
10111         },
10112
10113         expand: function( event ) {
10114                 var newItem = this.active &&
10115                         this.active
10116                                 .children( ".ui-menu " )
10117                                 .children( ".ui-menu-item" )
10118                                 .first();
10119
10120                 if ( newItem && newItem.length ) {
10121                         this._open( newItem.parent() );
10122
10123                         // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
10124                         this._delay(function() {
10125                                 this.focus( event, newItem );
10126                         });
10127                 }
10128         },
10129
10130         next: function( event ) {
10131                 this._move( "next", "first", event );
10132         },
10133
10134         previous: function( event ) {
10135                 this._move( "prev", "last", event );
10136         },
10137
10138         isFirstItem: function() {
10139                 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
10140         },
10141
10142         isLastItem: function() {
10143                 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
10144         },
10145
10146         _move: function( direction, filter, event ) {
10147                 var next;
10148                 if ( this.active ) {
10149                         if ( direction === "first" || direction === "last" ) {
10150                                 next = this.active
10151                                         [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
10152                                         .eq( -1 );
10153                         } else {
10154                                 next = this.active
10155                                         [ direction + "All" ]( ".ui-menu-item" )
10156                                         .eq( 0 );
10157                         }
10158                 }
10159                 if ( !next || !next.length || !this.active ) {
10160                         next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
10161                 }
10162
10163                 this.focus( event, next );
10164         },
10165
10166         nextPage: function( event ) {
10167                 var item, base, height;
10168
10169                 if ( !this.active ) {
10170                         this.next( event );
10171                         return;
10172                 }
10173                 if ( this.isLastItem() ) {
10174                         return;
10175                 }
10176                 if ( this._hasScroll() ) {
10177                         base = this.active.offset().top;
10178                         height = this.element.height();
10179                         this.active.nextAll( ".ui-menu-item" ).each(function() {
10180                                 item = $( this );
10181                                 return item.offset().top - base - height < 0;
10182                         });
10183
10184                         this.focus( event, item );
10185                 } else {
10186                         this.focus( event, this.activeMenu.children( ".ui-menu-item" )
10187                                 [ !this.active ? "first" : "last" ]() );
10188                 }
10189         },
10190
10191         previousPage: function( event ) {
10192                 var item, base, height;
10193                 if ( !this.active ) {
10194                         this.next( event );
10195                         return;
10196                 }
10197                 if ( this.isFirstItem() ) {
10198                         return;
10199                 }
10200                 if ( this._hasScroll() ) {
10201                         base = this.active.offset().top;
10202                         height = this.element.height();
10203                         this.active.prevAll( ".ui-menu-item" ).each(function() {
10204                                 item = $( this );
10205                                 return item.offset().top - base + height > 0;
10206                         });
10207
10208                         this.focus( event, item );
10209                 } else {
10210                         this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
10211                 }
10212         },
10213
10214         _hasScroll: function() {
10215                 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
10216         },
10217
10218         select: function( event ) {
10219                 // TODO: It should never be possible to not have an active item at this
10220                 // point, but the tests don't trigger mouseenter before click.
10221                 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
10222                 var ui = { item: this.active };
10223                 if ( !this.active.has( ".ui-menu" ).length ) {
10224                         this.collapseAll( event, true );
10225                 }
10226                 this._trigger( "select", event, ui );
10227         }
10228 });
10229
10230 }( jQuery ));
10231 (function( $, undefined ) {
10232
10233 $.widget( "ui.progressbar", {
10234         version: "1.10.3",
10235         options: {
10236                 max: 100,
10237                 value: 0,
10238
10239                 change: null,
10240                 complete: null
10241         },
10242
10243         min: 0,
10244
10245         _create: function() {
10246                 // Constrain initial value
10247                 this.oldValue = this.options.value = this._constrainedValue();
10248
10249                 this.element
10250                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10251                         .attr({
10252                                 // Only set static values, aria-valuenow and aria-valuemax are
10253                                 // set inside _refreshValue()
10254                                 role: "progressbar",
10255                                 "aria-valuemin": this.min
10256                         });
10257
10258                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10259                         .appendTo( this.element );
10260
10261                 this._refreshValue();
10262         },
10263
10264         _destroy: function() {
10265                 this.element
10266                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10267                         .removeAttr( "role" )
10268                         .removeAttr( "aria-valuemin" )
10269                         .removeAttr( "aria-valuemax" )
10270                         .removeAttr( "aria-valuenow" );
10271
10272                 this.valueDiv.remove();
10273         },
10274
10275         value: function( newValue ) {
10276                 if ( newValue === undefined ) {
10277                         return this.options.value;
10278                 }
10279
10280                 this.options.value = this._constrainedValue( newValue );
10281                 this._refreshValue();
10282         },
10283
10284         _constrainedValue: function( newValue ) {
10285                 if ( newValue === undefined ) {
10286                         newValue = this.options.value;
10287                 }
10288
10289                 this.indeterminate = newValue === false;
10290
10291                 // sanitize value
10292                 if ( typeof newValue !== "number" ) {
10293                         newValue = 0;
10294                 }
10295
10296                 return this.indeterminate ? false :
10297                         Math.min( this.options.max, Math.max( this.min, newValue ) );
10298         },
10299
10300         _setOptions: function( options ) {
10301                 // Ensure "value" option is set after other values (like max)
10302                 var value = options.value;
10303                 delete options.value;
10304
10305                 this._super( options );
10306
10307                 this.options.value = this._constrainedValue( value );
10308                 this._refreshValue();
10309         },
10310
10311         _setOption: function( key, value ) {
10312                 if ( key === "max" ) {
10313                         // Don't allow a max less than min
10314                         value = Math.max( this.min, value );
10315                 }
10316
10317                 this._super( key, value );
10318         },
10319
10320         _percentage: function() {
10321                 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
10322         },
10323
10324         _refreshValue: function() {
10325                 var value = this.options.value,
10326                         percentage = this._percentage();
10327
10328                 this.valueDiv
10329                         .toggle( this.indeterminate || value > this.min )
10330                         .toggleClass( "ui-corner-right", value === this.options.max )
10331                         .width( percentage.toFixed(0) + "%" );
10332
10333                 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
10334
10335                 if ( this.indeterminate ) {
10336                         this.element.removeAttr( "aria-valuenow" );
10337                         if ( !this.overlayDiv ) {
10338                                 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
10339                         }
10340                 } else {
10341                         this.element.attr({
10342                                 "aria-valuemax": this.options.max,
10343                                 "aria-valuenow": value
10344                         });
10345                         if ( this.overlayDiv ) {
10346                                 this.overlayDiv.remove();
10347                                 this.overlayDiv = null;
10348                         }
10349                 }
10350
10351                 if ( this.oldValue !== value ) {
10352                         this.oldValue = value;
10353                         this._trigger( "change" );
10354                 }
10355                 if ( value === this.options.max ) {
10356                         this._trigger( "complete" );
10357                 }
10358         }
10359 });
10360
10361 })( jQuery );
10362 (function( $, undefined ) {
10363
10364 // number of pages in a slider
10365 // (how many times can you page up/down to go through the whole range)
10366 var numPages = 5;
10367
10368 $.widget( "ui.slider", $.ui.mouse, {
10369         version: "1.10.3",
10370         widgetEventPrefix: "slide",
10371
10372         options: {
10373                 animate: false,
10374                 distance: 0,
10375                 max: 100,
10376                 min: 0,
10377                 orientation: "horizontal",
10378                 range: false,
10379                 step: 1,
10380                 value: 0,
10381                 values: null,
10382
10383                 // callbacks
10384                 change: null,
10385                 slide: null,
10386                 start: null,
10387                 stop: null
10388         },
10389
10390         _create: function() {
10391                 this._keySliding = false;
10392                 this._mouseSliding = false;
10393                 this._animateOff = true;
10394                 this._handleIndex = null;
10395                 this._detectOrientation();
10396                 this._mouseInit();
10397
10398                 this.element
10399                         .addClass( "ui-slider" +
10400                                 " ui-slider-" + this.orientation +
10401                                 " ui-widget" +
10402                                 " ui-widget-content" +
10403                                 " ui-corner-all");
10404
10405                 this._refresh();
10406                 this._setOption( "disabled", this.options.disabled );
10407
10408                 this._animateOff = false;
10409         },
10410
10411         _refresh: function() {
10412                 this._createRange();
10413                 this._createHandles();
10414                 this._setupEvents();
10415                 this._refreshValue();
10416         },
10417
10418         _createHandles: function() {
10419                 var i, handleCount,
10420                         options = this.options,
10421                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
10422                         handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
10423                         handles = [];
10424
10425                 handleCount = ( options.values && options.values.length ) || 1;
10426
10427                 if ( existingHandles.length > handleCount ) {
10428                         existingHandles.slice( handleCount ).remove();
10429                         existingHandles = existingHandles.slice( 0, handleCount );
10430                 }
10431
10432                 for ( i = existingHandles.length; i < handleCount; i++ ) {
10433                         handles.push( handle );
10434                 }
10435
10436                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
10437
10438                 this.handle = this.handles.eq( 0 );
10439
10440                 this.handles.each(function( i ) {
10441                         $( this ).data( "ui-slider-handle-index", i );
10442                 });
10443         },
10444
10445         _createRange: function() {
10446                 var options = this.options,
10447                         classes = "";
10448
10449                 if ( options.range ) {
10450                         if ( options.range === true ) {
10451                                 if ( !options.values ) {
10452                                         options.values = [ this._valueMin(), this._valueMin() ];
10453                                 } else if ( options.values.length && options.values.length !== 2 ) {
10454                                         options.values = [ options.values[0], options.values[0] ];
10455                                 } else if ( $.isArray( options.values ) ) {
10456                                         options.values = options.values.slice(0);
10457                                 }
10458                         }
10459
10460                         if ( !this.range || !this.range.length ) {
10461                                 this.range = $( "<div></div>" )
10462                                         .appendTo( this.element );
10463
10464                                 classes = "ui-slider-range" +
10465                                 // note: this isn't the most fittingly semantic framework class for this element,
10466                                 // but worked best visually with a variety of themes
10467                                 " ui-widget-header ui-corner-all";
10468                         } else {
10469                                 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
10470                                         // Handle range switching from true to min/max
10471                                         .css({
10472                                                 "left": "",
10473                                                 "bottom": ""
10474                                         });
10475                         }
10476
10477                         this.range.addClass( classes +
10478                                 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
10479                 } else {
10480                         this.range = $([]);
10481                 }
10482         },
10483
10484         _setupEvents: function() {
10485                 var elements = this.handles.add( this.range ).filter( "a" );
10486                 this._off( elements );
10487                 this._on( elements, this._handleEvents );
10488                 this._hoverable( elements );
10489                 this._focusable( elements );
10490         },
10491
10492         _destroy: function() {
10493                 this.handles.remove();
10494                 this.range.remove();
10495
10496                 this.element
10497                         .removeClass( "ui-slider" +
10498                                 " ui-slider-horizontal" +
10499                                 " ui-slider-vertical" +
10500                                 " ui-widget" +
10501                                 " ui-widget-content" +
10502                                 " ui-corner-all" );
10503
10504                 this._mouseDestroy();
10505         },
10506
10507         _mouseCapture: function( event ) {
10508                 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
10509                         that = this,
10510                         o = this.options;
10511
10512                 if ( o.disabled ) {
10513                         return false;
10514                 }
10515
10516                 this.elementSize = {
10517                         width: this.element.outerWidth(),
10518                         height: this.element.outerHeight()
10519                 };
10520                 this.elementOffset = this.element.offset();
10521
10522                 position = { x: event.pageX, y: event.pageY };
10523                 normValue = this._normValueFromMouse( position );
10524                 distance = this._valueMax() - this._valueMin() + 1;
10525                 this.handles.each(function( i ) {
10526                         var thisDistance = Math.abs( normValue - that.values(i) );
10527                         if (( distance > thisDistance ) ||
10528                                 ( distance === thisDistance &&
10529                                         (i === that._lastChangedValue || that.values(i) === o.min ))) {
10530                                 distance = thisDistance;
10531                                 closestHandle = $( this );
10532                                 index = i;
10533                         }
10534                 });
10535
10536                 allowed = this._start( event, index );
10537                 if ( allowed === false ) {
10538                         return false;
10539                 }
10540                 this._mouseSliding = true;
10541
10542                 this._handleIndex = index;
10543
10544                 closestHandle
10545                         .addClass( "ui-state-active" )
10546                         .focus();
10547
10548                 offset = closestHandle.offset();
10549                 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
10550                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10551                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10552                         top: event.pageY - offset.top -
10553                                 ( closestHandle.height() / 2 ) -
10554                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10555                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10556                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10557                 };
10558
10559                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10560                         this._slide( event, index, normValue );
10561                 }
10562                 this._animateOff = true;
10563                 return true;
10564         },
10565
10566         _mouseStart: function() {
10567                 return true;
10568         },
10569
10570         _mouseDrag: function( event ) {
10571                 var position = { x: event.pageX, y: event.pageY },
10572                         normValue = this._normValueFromMouse( position );
10573
10574                 this._slide( event, this._handleIndex, normValue );
10575
10576                 return false;
10577         },
10578
10579         _mouseStop: function( event ) {
10580                 this.handles.removeClass( "ui-state-active" );
10581                 this._mouseSliding = false;
10582
10583                 this._stop( event, this._handleIndex );
10584                 this._change( event, this._handleIndex );
10585
10586                 this._handleIndex = null;
10587                 this._clickOffset = null;
10588                 this._animateOff = false;
10589
10590                 return false;
10591         },
10592
10593         _detectOrientation: function() {
10594                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10595         },
10596
10597         _normValueFromMouse: function( position ) {
10598                 var pixelTotal,
10599                         pixelMouse,
10600                         percentMouse,
10601                         valueTotal,
10602                         valueMouse;
10603
10604                 if ( this.orientation === "horizontal" ) {
10605                         pixelTotal = this.elementSize.width;
10606                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10607                 } else {
10608                         pixelTotal = this.elementSize.height;
10609                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10610                 }
10611
10612                 percentMouse = ( pixelMouse / pixelTotal );
10613                 if ( percentMouse > 1 ) {
10614                         percentMouse = 1;
10615                 }
10616                 if ( percentMouse < 0 ) {
10617                         percentMouse = 0;
10618                 }
10619                 if ( this.orientation === "vertical" ) {
10620                         percentMouse = 1 - percentMouse;
10621                 }
10622
10623                 valueTotal = this._valueMax() - this._valueMin();
10624                 valueMouse = this._valueMin() + percentMouse * valueTotal;
10625
10626                 return this._trimAlignValue( valueMouse );
10627         },
10628
10629         _start: function( event, index ) {
10630                 var uiHash = {
10631                         handle: this.handles[ index ],
10632                         value: this.value()
10633                 };
10634                 if ( this.options.values && this.options.values.length ) {
10635                         uiHash.value = this.values( index );
10636                         uiHash.values = this.values();
10637                 }
10638                 return this._trigger( "start", event, uiHash );
10639         },
10640
10641         _slide: function( event, index, newVal ) {
10642                 var otherVal,
10643                         newValues,
10644                         allowed;
10645
10646                 if ( this.options.values && this.options.values.length ) {
10647                         otherVal = this.values( index ? 0 : 1 );
10648
10649                         if ( ( this.options.values.length === 2 && this.options.range === true ) &&
10650                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10651                                 ) {
10652                                 newVal = otherVal;
10653                         }
10654
10655                         if ( newVal !== this.values( index ) ) {
10656                                 newValues = this.values();
10657                                 newValues[ index ] = newVal;
10658                                 // A slide can be canceled by returning false from the slide callback
10659                                 allowed = this._trigger( "slide", event, {
10660                                         handle: this.handles[ index ],
10661                                         value: newVal,
10662                                         values: newValues
10663                                 } );
10664                                 otherVal = this.values( index ? 0 : 1 );
10665                                 if ( allowed !== false ) {
10666                                         this.values( index, newVal, true );
10667                                 }
10668                         }
10669                 } else {
10670                         if ( newVal !== this.value() ) {
10671                                 // A slide can be canceled by returning false from the slide callback
10672                                 allowed = this._trigger( "slide", event, {
10673                                         handle: this.handles[ index ],
10674                                         value: newVal
10675                                 } );
10676                                 if ( allowed !== false ) {
10677                                         this.value( newVal );
10678                                 }
10679                         }
10680                 }
10681         },
10682
10683         _stop: function( event, index ) {
10684                 var uiHash = {
10685                         handle: this.handles[ index ],
10686                         value: this.value()
10687                 };
10688                 if ( this.options.values && this.options.values.length ) {
10689                         uiHash.value = this.values( index );
10690                         uiHash.values = this.values();
10691                 }
10692
10693                 this._trigger( "stop", event, uiHash );
10694         },
10695
10696         _change: function( event, index ) {
10697                 if ( !this._keySliding && !this._mouseSliding ) {
10698                         var uiHash = {
10699                                 handle: this.handles[ index ],
10700                                 value: this.value()
10701                         };
10702                         if ( this.options.values && this.options.values.length ) {
10703                                 uiHash.value = this.values( index );
10704                                 uiHash.values = this.values();
10705                         }
10706
10707                         //store the last changed value index for reference when handles overlap
10708                         this._lastChangedValue = index;
10709
10710                         this._trigger( "change", event, uiHash );
10711                 }
10712         },
10713
10714         value: function( newValue ) {
10715                 if ( arguments.length ) {
10716                         this.options.value = this._trimAlignValue( newValue );
10717                         this._refreshValue();
10718                         this._change( null, 0 );
10719                         return;
10720                 }
10721
10722                 return this._value();
10723         },
10724
10725         values: function( index, newValue ) {
10726                 var vals,
10727                         newValues,
10728                         i;
10729
10730                 if ( arguments.length > 1 ) {
10731                         this.options.values[ index ] = this._trimAlignValue( newValue );
10732                         this._refreshValue();
10733                         this._change( null, index );
10734                         return;
10735                 }
10736
10737                 if ( arguments.length ) {
10738                         if ( $.isArray( arguments[ 0 ] ) ) {
10739                                 vals = this.options.values;
10740                                 newValues = arguments[ 0 ];
10741                                 for ( i = 0; i < vals.length; i += 1 ) {
10742                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
10743                                         this._change( null, i );
10744                                 }
10745                                 this._refreshValue();
10746                         } else {
10747                                 if ( this.options.values && this.options.values.length ) {
10748                                         return this._values( index );
10749                                 } else {
10750                                         return this.value();
10751                                 }
10752                         }
10753                 } else {
10754                         return this._values();
10755                 }
10756         },
10757
10758         _setOption: function( key, value ) {
10759                 var i,
10760                         valsLength = 0;
10761
10762                 if ( key === "range" && this.options.range === true ) {
10763                         if ( value === "min" ) {
10764                                 this.options.value = this._values( 0 );
10765                                 this.options.values = null;
10766                         } else if ( value === "max" ) {
10767                                 this.options.value = this._values( this.options.values.length-1 );
10768                                 this.options.values = null;
10769                         }
10770                 }
10771
10772                 if ( $.isArray( this.options.values ) ) {
10773                         valsLength = this.options.values.length;
10774                 }
10775
10776                 $.Widget.prototype._setOption.apply( this, arguments );
10777
10778                 switch ( key ) {
10779                         case "orientation":
10780                                 this._detectOrientation();
10781                                 this.element
10782                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
10783                                         .addClass( "ui-slider-" + this.orientation );
10784                                 this._refreshValue();
10785                                 break;
10786                         case "value":
10787                                 this._animateOff = true;
10788                                 this._refreshValue();
10789                                 this._change( null, 0 );
10790                                 this._animateOff = false;
10791                                 break;
10792                         case "values":
10793                                 this._animateOff = true;
10794                                 this._refreshValue();
10795                                 for ( i = 0; i < valsLength; i += 1 ) {
10796                                         this._change( null, i );
10797                                 }
10798                                 this._animateOff = false;
10799                                 break;
10800                         case "min":
10801                         case "max":
10802                                 this._animateOff = true;
10803                                 this._refreshValue();
10804                                 this._animateOff = false;
10805                                 break;
10806                         case "range":
10807                                 this._animateOff = true;
10808                                 this._refresh();
10809                                 this._animateOff = false;
10810                                 break;
10811                 }
10812         },
10813
10814         //internal value getter
10815         // _value() returns value trimmed by min and max, aligned by step
10816         _value: function() {
10817                 var val = this.options.value;
10818                 val = this._trimAlignValue( val );
10819
10820                 return val;
10821         },
10822
10823         //internal values getter
10824         // _values() returns array of values trimmed by min and max, aligned by step
10825         // _values( index ) returns single value trimmed by min and max, aligned by step
10826         _values: function( index ) {
10827                 var val,
10828                         vals,
10829                         i;
10830
10831                 if ( arguments.length ) {
10832                         val = this.options.values[ index ];
10833                         val = this._trimAlignValue( val );
10834
10835                         return val;
10836                 } else if ( this.options.values && this.options.values.length ) {
10837                         // .slice() creates a copy of the array
10838                         // this copy gets trimmed by min and max and then returned
10839                         vals = this.options.values.slice();
10840                         for ( i = 0; i < vals.length; i+= 1) {
10841                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
10842                         }
10843
10844                         return vals;
10845                 } else {
10846                         return [];
10847                 }
10848         },
10849
10850         // returns the step-aligned value that val is closest to, between (inclusive) min and max
10851         _trimAlignValue: function( val ) {
10852                 if ( val <= this._valueMin() ) {
10853                         return this._valueMin();
10854                 }
10855                 if ( val >= this._valueMax() ) {
10856                         return this._valueMax();
10857                 }
10858                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
10859                         valModStep = (val - this._valueMin()) % step,
10860                         alignValue = val - valModStep;
10861
10862                 if ( Math.abs(valModStep) * 2 >= step ) {
10863                         alignValue += ( valModStep > 0 ) ? step : ( -step );
10864                 }
10865
10866                 // Since JavaScript has problems with large floats, round
10867                 // the final value to 5 digits after the decimal point (see #4124)
10868                 return parseFloat( alignValue.toFixed(5) );
10869         },
10870
10871         _valueMin: function() {
10872                 return this.options.min;
10873         },
10874
10875         _valueMax: function() {
10876                 return this.options.max;
10877         },
10878
10879         _refreshValue: function() {
10880                 var lastValPercent, valPercent, value, valueMin, valueMax,
10881                         oRange = this.options.range,
10882                         o = this.options,
10883                         that = this,
10884                         animate = ( !this._animateOff ) ? o.animate : false,
10885                         _set = {};
10886
10887                 if ( this.options.values && this.options.values.length ) {
10888                         this.handles.each(function( i ) {
10889                                 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
10890                                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10891                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10892                                 if ( that.options.range === true ) {
10893                                         if ( that.orientation === "horizontal" ) {
10894                                                 if ( i === 0 ) {
10895                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10896                                                 }
10897                                                 if ( i === 1 ) {
10898                                                         that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10899                                                 }
10900                                         } else {
10901                                                 if ( i === 0 ) {
10902                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10903                                                 }
10904                                                 if ( i === 1 ) {
10905                                                         that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10906                                                 }
10907                                         }
10908                                 }
10909                                 lastValPercent = valPercent;
10910                         });
10911                 } else {
10912                         value = this.value();
10913                         valueMin = this._valueMin();
10914                         valueMax = this._valueMax();
10915                         valPercent = ( valueMax !== valueMin ) ?
10916                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10917                                         0;
10918                         _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10919                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10920
10921                         if ( oRange === "min" && this.orientation === "horizontal" ) {
10922                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10923                         }
10924                         if ( oRange === "max" && this.orientation === "horizontal" ) {
10925                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10926                         }
10927                         if ( oRange === "min" && this.orientation === "vertical" ) {
10928                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10929                         }
10930                         if ( oRange === "max" && this.orientation === "vertical" ) {
10931                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10932                         }
10933                 }
10934         },
10935
10936         _handleEvents: {
10937                 keydown: function( event ) {
10938                         /*jshint maxcomplexity:25*/
10939                         var allowed, curVal, newVal, step,
10940                                 index = $( event.target ).data( "ui-slider-handle-index" );
10941
10942                         switch ( event.keyCode ) {
10943                                 case $.ui.keyCode.HOME:
10944                                 case $.ui.keyCode.END:
10945                                 case $.ui.keyCode.PAGE_UP:
10946                                 case $.ui.keyCode.PAGE_DOWN:
10947                                 case $.ui.keyCode.UP:
10948                                 case $.ui.keyCode.RIGHT:
10949                                 case $.ui.keyCode.DOWN:
10950                                 case $.ui.keyCode.LEFT:
10951                                         event.preventDefault();
10952                                         if ( !this._keySliding ) {
10953                                                 this._keySliding = true;
10954                                                 $( event.target ).addClass( "ui-state-active" );
10955                                                 allowed = this._start( event, index );
10956                                                 if ( allowed === false ) {
10957                                                         return;
10958                                                 }
10959                                         }
10960                                         break;
10961                         }
10962
10963                         step = this.options.step;
10964                         if ( this.options.values && this.options.values.length ) {
10965                                 curVal = newVal = this.values( index );
10966                         } else {
10967                                 curVal = newVal = this.value();
10968                         }
10969
10970                         switch ( event.keyCode ) {
10971                                 case $.ui.keyCode.HOME:
10972                                         newVal = this._valueMin();
10973                                         break;
10974                                 case $.ui.keyCode.END:
10975                                         newVal = this._valueMax();
10976                                         break;
10977                                 case $.ui.keyCode.PAGE_UP:
10978                                         newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
10979                                         break;
10980                                 case $.ui.keyCode.PAGE_DOWN:
10981                                         newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
10982                                         break;
10983                                 case $.ui.keyCode.UP:
10984                                 case $.ui.keyCode.RIGHT:
10985                                         if ( curVal === this._valueMax() ) {
10986                                                 return;
10987                                         }
10988                                         newVal = this._trimAlignValue( curVal + step );
10989                                         break;
10990                                 case $.ui.keyCode.DOWN:
10991                                 case $.ui.keyCode.LEFT:
10992                                         if ( curVal === this._valueMin() ) {
10993                                                 return;
10994                                         }
10995                                         newVal = this._trimAlignValue( curVal - step );
10996                                         break;
10997                         }
10998
10999                         this._slide( event, index, newVal );
11000                 },
11001                 click: function( event ) {
11002                         event.preventDefault();
11003                 },
11004                 keyup: function( event ) {
11005                         var index = $( event.target ).data( "ui-slider-handle-index" );
11006
11007                         if ( this._keySliding ) {
11008                                 this._keySliding = false;
11009                                 this._stop( event, index );
11010                                 this._change( event, index );
11011                                 $( event.target ).removeClass( "ui-state-active" );
11012                         }
11013                 }
11014         }
11015
11016 });
11017
11018 }(jQuery));
11019 (function( $ ) {
11020
11021 function modifier( fn ) {
11022         return function() {
11023                 var previous = this.element.val();
11024                 fn.apply( this, arguments );
11025                 this._refresh();
11026                 if ( previous !== this.element.val() ) {
11027                         this._trigger( "change" );
11028                 }
11029         };
11030 }
11031
11032 $.widget( "ui.spinner", {
11033         version: "1.10.3",
11034         defaultElement: "<input>",
11035         widgetEventPrefix: "spin",
11036         options: {
11037                 culture: null,
11038                 icons: {
11039                         down: "ui-icon-triangle-1-s",
11040                         up: "ui-icon-triangle-1-n"
11041                 },
11042                 incremental: true,
11043                 max: null,
11044                 min: null,
11045                 numberFormat: null,
11046                 page: 10,
11047                 step: 1,
11048
11049                 change: null,
11050                 spin: null,
11051                 start: null,
11052                 stop: null
11053         },
11054
11055         _create: function() {
11056                 // handle string values that need to be parsed
11057                 this._setOption( "max", this.options.max );
11058                 this._setOption( "min", this.options.min );
11059                 this._setOption( "step", this.options.step );
11060
11061                 // format the value, but don't constrain
11062                 this._value( this.element.val(), true );
11063
11064                 this._draw();
11065                 this._on( this._events );
11066                 this._refresh();
11067
11068                 // turning off autocomplete prevents the browser from remembering the
11069                 // value when navigating through history, so we re-enable autocomplete
11070                 // if the page is unloaded before the widget is destroyed. #7790
11071                 this._on( this.window, {
11072                         beforeunload: function() {
11073                                 this.element.removeAttr( "autocomplete" );
11074                         }
11075                 });
11076         },
11077
11078         _getCreateOptions: function() {
11079                 var options = {},
11080                         element = this.element;
11081
11082                 $.each( [ "min", "max", "step" ], function( i, option ) {
11083                         var value = element.attr( option );
11084                         if ( value !== undefined && value.length ) {
11085                                 options[ option ] = value;
11086                         }
11087                 });
11088
11089                 return options;
11090         },
11091
11092         _events: {
11093                 keydown: function( event ) {
11094                         if ( this._start( event ) && this._keydown( event ) ) {
11095                                 event.preventDefault();
11096                         }
11097                 },
11098                 keyup: "_stop",
11099                 focus: function() {
11100                         this.previous = this.element.val();
11101                 },
11102                 blur: function( event ) {
11103                         if ( this.cancelBlur ) {
11104                                 delete this.cancelBlur;
11105                                 return;
11106                         }
11107
11108                         this._stop();
11109                         this._refresh();
11110                         if ( this.previous !== this.element.val() ) {
11111                                 this._trigger( "change", event );
11112                         }
11113                 },
11114                 mousewheel: function( event, delta ) {
11115                         if ( !delta ) {
11116                                 return;
11117                         }
11118                         if ( !this.spinning && !this._start( event ) ) {
11119                                 return false;
11120                         }
11121
11122                         this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
11123                         clearTimeout( this.mousewheelTimer );
11124                         this.mousewheelTimer = this._delay(function() {
11125                                 if ( this.spinning ) {
11126                                         this._stop( event );
11127                                 }
11128                         }, 100 );
11129                         event.preventDefault();
11130                 },
11131                 "mousedown .ui-spinner-button": function( event ) {
11132                         var previous;
11133
11134                         // We never want the buttons to have focus; whenever the user is
11135                         // interacting with the spinner, the focus should be on the input.
11136                         // If the input is focused then this.previous is properly set from
11137                         // when the input first received focus. If the input is not focused
11138                         // then we need to set this.previous based on the value before spinning.
11139                         previous = this.element[0] === this.document[0].activeElement ?
11140                                 this.previous : this.element.val();
11141                         function checkFocus() {
11142                                 var isActive = this.element[0] === this.document[0].activeElement;
11143                                 if ( !isActive ) {
11144                                         this.element.focus();
11145                                         this.previous = previous;
11146                                         // support: IE
11147                                         // IE sets focus asynchronously, so we need to check if focus
11148                                         // moved off of the input because the user clicked on the button.
11149                                         this._delay(function() {
11150                                                 this.previous = previous;
11151                                         });
11152                                 }
11153                         }
11154
11155                         // ensure focus is on (or stays on) the text field
11156                         event.preventDefault();
11157                         checkFocus.call( this );
11158
11159                         // support: IE
11160                         // IE doesn't prevent moving focus even with event.preventDefault()
11161                         // so we set a flag to know when we should ignore the blur event
11162                         // and check (again) if focus moved off of the input.
11163                         this.cancelBlur = true;
11164                         this._delay(function() {
11165                                 delete this.cancelBlur;
11166                                 checkFocus.call( this );
11167                         });
11168
11169                         if ( this._start( event ) === false ) {
11170                                 return;
11171                         }
11172
11173                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
11174                 },
11175                 "mouseup .ui-spinner-button": "_stop",
11176                 "mouseenter .ui-spinner-button": function( event ) {
11177                         // button will add ui-state-active if mouse was down while mouseleave and kept down
11178                         if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
11179                                 return;
11180                         }
11181
11182                         if ( this._start( event ) === false ) {
11183                                 return false;
11184                         }
11185                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
11186                 },
11187                 // TODO: do we really want to consider this a stop?
11188                 // shouldn't we just stop the repeater and wait until mouseup before
11189                 // we trigger the stop event?
11190                 "mouseleave .ui-spinner-button": "_stop"
11191         },
11192
11193         _draw: function() {
11194                 var uiSpinner = this.uiSpinner = this.element
11195                         .addClass( "ui-spinner-input" )
11196                         .attr( "autocomplete", "off" )
11197                         .wrap( this._uiSpinnerHtml() )
11198                         .parent()
11199                                 // add buttons
11200                                 .append( this._buttonHtml() );
11201
11202                 this.element.attr( "role", "spinbutton" );
11203
11204                 // button bindings
11205                 this.buttons = uiSpinner.find( ".ui-spinner-button" )
11206                         .attr( "tabIndex", -1 )
11207                         .button()
11208                         .removeClass( "ui-corner-all" );
11209
11210                 // IE 6 doesn't understand height: 50% for the buttons
11211                 // unless the wrapper has an explicit height
11212                 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
11213                                 uiSpinner.height() > 0 ) {
11214                         uiSpinner.height( uiSpinner.height() );
11215                 }
11216
11217                 // disable spinner if element was already disabled
11218                 if ( this.options.disabled ) {
11219                         this.disable();
11220                 }
11221         },
11222
11223         _keydown: function( event ) {
11224                 var options = this.options,
11225                         keyCode = $.ui.keyCode;
11226
11227                 switch ( event.keyCode ) {
11228                 case keyCode.UP:
11229                         this._repeat( null, 1, event );
11230                         return true;
11231                 case keyCode.DOWN:
11232                         this._repeat( null, -1, event );
11233                         return true;
11234                 case keyCode.PAGE_UP:
11235                         this._repeat( null, options.page, event );
11236                         return true;
11237                 case keyCode.PAGE_DOWN:
11238                         this._repeat( null, -options.page, event );
11239                         return true;
11240                 }
11241
11242                 return false;
11243         },
11244
11245         _uiSpinnerHtml: function() {
11246                 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
11247         },
11248
11249         _buttonHtml: function() {
11250                 return "" +
11251                         "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
11252                                 "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
11253                         "</a>" +
11254                         "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
11255                                 "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
11256                         "</a>";
11257         },
11258
11259         _start: function( event ) {
11260                 if ( !this.spinning && this._trigger( "start", event ) === false ) {
11261                         return false;
11262                 }
11263
11264                 if ( !this.counter ) {
11265                         this.counter = 1;
11266                 }
11267                 this.spinning = true;
11268                 return true;
11269         },
11270
11271         _repeat: function( i, steps, event ) {
11272                 i = i || 500;
11273
11274                 clearTimeout( this.timer );
11275                 this.timer = this._delay(function() {
11276                         this._repeat( 40, steps, event );
11277                 }, i );
11278
11279                 this._spin( steps * this.options.step, event );
11280         },
11281
11282         _spin: function( step, event ) {
11283                 var value = this.value() || 0;
11284
11285                 if ( !this.counter ) {
11286                         this.counter = 1;
11287                 }
11288
11289                 value = this._adjustValue( value + step * this._increment( this.counter ) );
11290
11291                 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
11292                         this._value( value );
11293                         this.counter++;
11294                 }
11295         },
11296
11297         _increment: function( i ) {
11298                 var incremental = this.options.incremental;
11299
11300                 if ( incremental ) {
11301                         return $.isFunction( incremental ) ?
11302                                 incremental( i ) :
11303                                 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
11304                 }
11305
11306                 return 1;
11307         },
11308
11309         _precision: function() {
11310                 var precision = this._precisionOf( this.options.step );
11311                 if ( this.options.min !== null ) {
11312                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
11313                 }
11314                 return precision;
11315         },
11316
11317         _precisionOf: function( num ) {
11318                 var str = num.toString(),
11319                         decimal = str.indexOf( "." );
11320                 return decimal === -1 ? 0 : str.length - decimal - 1;
11321         },
11322
11323         _adjustValue: function( value ) {
11324                 var base, aboveMin,
11325                         options = this.options;
11326
11327                 // make sure we're at a valid step
11328                 // - find out where we are relative to the base (min or 0)
11329                 base = options.min !== null ? options.min : 0;
11330                 aboveMin = value - base;
11331                 // - round to the nearest step
11332                 aboveMin = Math.round(aboveMin / options.step) * options.step;
11333                 // - rounding is based on 0, so adjust back to our base
11334                 value = base + aboveMin;
11335
11336                 // fix precision from bad JS floating point math
11337                 value = parseFloat( value.toFixed( this._precision() ) );
11338
11339                 // clamp the value
11340                 if ( options.max !== null && value > options.max) {
11341                         return options.max;
11342                 }
11343                 if ( options.min !== null && value < options.min ) {
11344                         return options.min;
11345                 }
11346
11347                 return value;
11348         },
11349
11350         _stop: function( event ) {
11351                 if ( !this.spinning ) {
11352                         return;
11353                 }
11354
11355                 clearTimeout( this.timer );
11356                 clearTimeout( this.mousewheelTimer );
11357                 this.counter = 0;
11358                 this.spinning = false;
11359                 this._trigger( "stop", event );
11360         },
11361
11362         _setOption: function( key, value ) {
11363                 if ( key === "culture" || key === "numberFormat" ) {
11364                         var prevValue = this._parse( this.element.val() );
11365                         this.options[ key ] = value;
11366                         this.element.val( this._format( prevValue ) );
11367                         return;
11368                 }
11369
11370                 if ( key === "max" || key === "min" || key === "step" ) {
11371                         if ( typeof value === "string" ) {
11372                                 value = this._parse( value );
11373                         }
11374                 }
11375                 if ( key === "icons" ) {
11376                         this.buttons.first().find( ".ui-icon" )
11377                                 .removeClass( this.options.icons.up )
11378                                 .addClass( value.up );
11379                         this.buttons.last().find( ".ui-icon" )
11380                                 .removeClass( this.options.icons.down )
11381                                 .addClass( value.down );
11382                 }
11383
11384                 this._super( key, value );
11385
11386                 if ( key === "disabled" ) {
11387                         if ( value ) {
11388                                 this.element.prop( "disabled", true );
11389                                 this.buttons.button( "disable" );
11390                         } else {
11391                                 this.element.prop( "disabled", false );
11392                                 this.buttons.button( "enable" );
11393                         }
11394                 }
11395         },
11396
11397         _setOptions: modifier(function( options ) {
11398                 this._super( options );
11399                 this._value( this.element.val() );
11400         }),
11401
11402         _parse: function( val ) {
11403                 if ( typeof val === "string" && val !== "" ) {
11404                         val = window.Globalize && this.options.numberFormat ?
11405                                 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
11406                 }
11407                 return val === "" || isNaN( val ) ? null : val;
11408         },
11409
11410         _format: function( value ) {
11411                 if ( value === "" ) {
11412                         return "";
11413                 }
11414                 return window.Globalize && this.options.numberFormat ?
11415                         Globalize.format( value, this.options.numberFormat, this.options.culture ) :
11416                         value;
11417         },
11418
11419         _refresh: function() {
11420                 this.element.attr({
11421                         "aria-valuemin": this.options.min,
11422                         "aria-valuemax": this.options.max,
11423                         // TODO: what should we do with values that can't be parsed?
11424                         "aria-valuenow": this._parse( this.element.val() )
11425                 });
11426         },
11427
11428         // update the value without triggering change
11429         _value: function( value, allowAny ) {
11430                 var parsed;
11431                 if ( value !== "" ) {
11432                         parsed = this._parse( value );
11433                         if ( parsed !== null ) {
11434                                 if ( !allowAny ) {
11435                                         parsed = this._adjustValue( parsed );
11436                                 }
11437                                 value = this._format( parsed );
11438                         }
11439                 }
11440                 this.element.val( value );
11441                 this._refresh();
11442         },
11443
11444         _destroy: function() {
11445                 this.element
11446                         .removeClass( "ui-spinner-input" )
11447                         .prop( "disabled", false )
11448                         .removeAttr( "autocomplete" )
11449                         .removeAttr( "role" )
11450                         .removeAttr( "aria-valuemin" )
11451                         .removeAttr( "aria-valuemax" )
11452                         .removeAttr( "aria-valuenow" );
11453                 this.uiSpinner.replaceWith( this.element );
11454         },
11455
11456         stepUp: modifier(function( steps ) {
11457                 this._stepUp( steps );
11458         }),
11459         _stepUp: function( steps ) {
11460                 if ( this._start() ) {
11461                         this._spin( (steps || 1) * this.options.step );
11462                         this._stop();
11463                 }
11464         },
11465
11466         stepDown: modifier(function( steps ) {
11467                 this._stepDown( steps );
11468         }),
11469         _stepDown: function( steps ) {
11470                 if ( this._start() ) {
11471                         this._spin( (steps || 1) * -this.options.step );
11472                         this._stop();
11473                 }
11474         },
11475
11476         pageUp: modifier(function( pages ) {
11477                 this._stepUp( (pages || 1) * this.options.page );
11478         }),
11479
11480         pageDown: modifier(function( pages ) {
11481                 this._stepDown( (pages || 1) * this.options.page );
11482         }),
11483
11484         value: function( newVal ) {
11485                 if ( !arguments.length ) {
11486                         return this._parse( this.element.val() );
11487                 }
11488                 modifier( this._value ).call( this, newVal );
11489         },
11490
11491         widget: function() {
11492                 return this.uiSpinner;
11493         }
11494 });
11495
11496 }( jQuery ) );
11497 (function( $, undefined ) {
11498
11499 var tabId = 0,
11500         rhash = /#.*$/;
11501
11502 function getNextTabId() {
11503         return ++tabId;
11504 }
11505
11506 function isLocal( anchor ) {
11507         return anchor.hash.length > 1 &&
11508                 decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
11509                         decodeURIComponent( location.href.replace( rhash, "" ) );
11510 }
11511
11512 $.widget( "ui.tabs", {
11513         version: "1.10.3",
11514         delay: 300,
11515         options: {
11516                 active: null,
11517                 collapsible: false,
11518                 event: "click",
11519                 heightStyle: "content",
11520                 hide: null,
11521                 show: null,
11522
11523                 // callbacks
11524                 activate: null,
11525                 beforeActivate: null,
11526                 beforeLoad: null,
11527                 load: null
11528         },
11529
11530         _create: function() {
11531                 var that = this,
11532                         options = this.options;
11533
11534                 this.running = false;
11535
11536                 this.element
11537                         .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
11538                         .toggleClass( "ui-tabs-collapsible", options.collapsible )
11539                         // Prevent users from focusing disabled tabs via click
11540                         .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
11541                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
11542                                         event.preventDefault();
11543                                 }
11544                         })
11545                         // support: IE <9
11546                         // Preventing the default action in mousedown doesn't prevent IE
11547                         // from focusing the element, so if the anchor gets focused, blur.
11548                         // We don't have to worry about focusing the previously focused
11549                         // element since clicking on a non-focusable element should focus
11550                         // the body anyway.
11551                         .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
11552                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
11553                                         this.blur();
11554                                 }
11555                         });
11556
11557                 this._processTabs();
11558                 options.active = this._initialActive();
11559
11560                 // Take disabling tabs via class attribute from HTML
11561                 // into account and update option properly.
11562                 if ( $.isArray( options.disabled ) ) {
11563                         options.disabled = $.unique( options.disabled.concat(
11564                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
11565                                         return that.tabs.index( li );
11566                                 })
11567                         ) ).sort();
11568                 }
11569
11570                 // check for length avoids error when initializing empty list
11571                 if ( this.options.active !== false && this.anchors.length ) {
11572                         this.active = this._findActive( options.active );
11573                 } else {
11574                         this.active = $();
11575                 }
11576
11577                 this._refresh();
11578
11579                 if ( this.active.length ) {
11580                         this.load( options.active );
11581                 }
11582         },
11583
11584         _initialActive: function() {
11585                 var active = this.options.active,
11586                         collapsible = this.options.collapsible,
11587                         locationHash = location.hash.substring( 1 );
11588
11589                 if ( active === null ) {
11590                         // check the fragment identifier in the URL
11591                         if ( locationHash ) {
11592                                 this.tabs.each(function( i, tab ) {
11593                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
11594                                                 active = i;
11595                                                 return false;
11596                                         }
11597                                 });
11598                         }
11599
11600                         // check for a tab marked active via a class
11601                         if ( active === null ) {
11602                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
11603                         }
11604
11605                         // no active tab, set to false
11606                         if ( active === null || active === -1 ) {
11607                                 active = this.tabs.length ? 0 : false;
11608                         }
11609                 }
11610
11611                 // handle numbers: negative, out of range
11612                 if ( active !== false ) {
11613                         active = this.tabs.index( this.tabs.eq( active ) );
11614                         if ( active === -1 ) {
11615                                 active = collapsible ? false : 0;
11616                         }
11617                 }
11618
11619                 // don't allow collapsible: false and active: false
11620                 if ( !collapsible && active === false && this.anchors.length ) {
11621                         active = 0;
11622                 }
11623
11624                 return active;
11625         },
11626
11627         _getCreateEventData: function() {
11628                 return {
11629                         tab: this.active,
11630                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
11631                 };
11632         },
11633
11634         _tabKeydown: function( event ) {
11635                 /*jshint maxcomplexity:15*/
11636                 var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
11637                         selectedIndex = this.tabs.index( focusedTab ),
11638                         goingForward = true;
11639
11640                 if ( this._handlePageNav( event ) ) {
11641                         return;
11642                 }
11643
11644                 switch ( event.keyCode ) {
11645                         case $.ui.keyCode.RIGHT:
11646                         case $.ui.keyCode.DOWN:
11647                                 selectedIndex++;
11648                                 break;
11649                         case $.ui.keyCode.UP:
11650                         case $.ui.keyCode.LEFT:
11651                                 goingForward = false;
11652                                 selectedIndex--;
11653                                 break;
11654                         case $.ui.keyCode.END:
11655                                 selectedIndex = this.anchors.length - 1;
11656                                 break;
11657                         case $.ui.keyCode.HOME:
11658                                 selectedIndex = 0;
11659                                 break;
11660                         case $.ui.keyCode.SPACE:
11661                                 // Activate only, no collapsing
11662                                 event.preventDefault();
11663                                 clearTimeout( this.activating );
11664                                 this._activate( selectedIndex );
11665                                 return;
11666                         case $.ui.keyCode.ENTER:
11667                                 // Toggle (cancel delayed activation, allow collapsing)
11668                                 event.preventDefault();
11669                                 clearTimeout( this.activating );
11670                                 // Determine if we should collapse or activate
11671                                 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
11672                                 return;
11673                         default:
11674                                 return;
11675                 }
11676
11677                 // Focus the appropriate tab, based on which key was pressed
11678                 event.preventDefault();
11679                 clearTimeout( this.activating );
11680                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
11681
11682                 // Navigating with control key will prevent automatic activation
11683                 if ( !event.ctrlKey ) {
11684                         // Update aria-selected immediately so that AT think the tab is already selected.
11685                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
11686                         // but the tab will already be activated by the time the announcement finishes.
11687                         focusedTab.attr( "aria-selected", "false" );
11688                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
11689
11690                         this.activating = this._delay(function() {
11691                                 this.option( "active", selectedIndex );
11692                         }, this.delay );
11693                 }
11694         },
11695
11696         _panelKeydown: function( event ) {
11697                 if ( this._handlePageNav( event ) ) {
11698                         return;
11699                 }
11700
11701                 // Ctrl+up moves focus to the current tab
11702                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
11703                         event.preventDefault();
11704                         this.active.focus();
11705                 }
11706         },
11707
11708         // Alt+page up/down moves focus to the previous/next tab (and activates)
11709         _handlePageNav: function( event ) {
11710                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
11711                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
11712                         return true;
11713                 }
11714                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
11715                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
11716                         return true;
11717                 }
11718         },
11719
11720         _findNextTab: function( index, goingForward ) {
11721                 var lastTabIndex = this.tabs.length - 1;
11722
11723                 function constrain() {
11724                         if ( index > lastTabIndex ) {
11725                                 index = 0;
11726                         }
11727                         if ( index < 0 ) {
11728                                 index = lastTabIndex;
11729                         }
11730                         return index;
11731                 }
11732
11733                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
11734                         index = goingForward ? index + 1 : index - 1;
11735                 }
11736
11737                 return index;
11738         },
11739
11740         _focusNextTab: function( index, goingForward ) {
11741                 index = this._findNextTab( index, goingForward );
11742                 this.tabs.eq( index ).focus();
11743                 return index;
11744         },
11745
11746         _setOption: function( key, value ) {
11747                 if ( key === "active" ) {
11748                         // _activate() will handle invalid values and update this.options
11749                         this._activate( value );
11750                         return;
11751                 }
11752
11753                 if ( key === "disabled" ) {
11754                         // don't use the widget factory's disabled handling
11755                         this._setupDisabled( value );
11756                         return;
11757                 }
11758
11759                 this._super( key, value);
11760
11761                 if ( key === "collapsible" ) {
11762                         this.element.toggleClass( "ui-tabs-collapsible", value );
11763                         // Setting collapsible: false while collapsed; open first panel
11764                         if ( !value && this.options.active === false ) {
11765                                 this._activate( 0 );
11766                         }
11767                 }
11768
11769                 if ( key === "event" ) {
11770                         this._setupEvents( value );
11771                 }
11772
11773                 if ( key === "heightStyle" ) {
11774                         this._setupHeightStyle( value );
11775                 }
11776         },
11777
11778         _tabId: function( tab ) {
11779                 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
11780         },
11781
11782         _sanitizeSelector: function( hash ) {
11783                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
11784         },
11785
11786         refresh: function() {
11787                 var options = this.options,
11788                         lis = this.tablist.children( ":has(a[href])" );
11789
11790                 // get disabled tabs from class attribute from HTML
11791                 // this will get converted to a boolean if needed in _refresh()
11792                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
11793                         return lis.index( tab );
11794                 });
11795
11796                 this._processTabs();
11797
11798                 // was collapsed or no tabs
11799                 if ( options.active === false || !this.anchors.length ) {
11800                         options.active = false;
11801                         this.active = $();
11802                 // was active, but active tab is gone
11803                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
11804                         // all remaining tabs are disabled
11805                         if ( this.tabs.length === options.disabled.length ) {
11806                                 options.active = false;
11807                                 this.active = $();
11808                         // activate previous tab
11809                         } else {
11810                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
11811                         }
11812                 // was active, active tab still exists
11813                 } else {
11814                         // make sure active index is correct
11815                         options.active = this.tabs.index( this.active );
11816                 }
11817
11818                 this._refresh();
11819         },
11820
11821         _refresh: function() {
11822                 this._setupDisabled( this.options.disabled );
11823                 this._setupEvents( this.options.event );
11824                 this._setupHeightStyle( this.options.heightStyle );
11825
11826                 this.tabs.not( this.active ).attr({
11827                         "aria-selected": "false",
11828                         tabIndex: -1
11829                 });
11830                 this.panels.not( this._getPanelForTab( this.active ) )
11831                         .hide()
11832                         .attr({
11833                                 "aria-expanded": "false",
11834                                 "aria-hidden": "true"
11835                         });
11836
11837                 // Make sure one tab is in the tab order
11838                 if ( !this.active.length ) {
11839                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
11840                 } else {
11841                         this.active
11842                                 .addClass( "ui-tabs-active ui-state-active" )
11843                                 .attr({
11844                                         "aria-selected": "true",
11845                                         tabIndex: 0
11846                                 });
11847                         this._getPanelForTab( this.active )
11848                                 .show()
11849                                 .attr({
11850                                         "aria-expanded": "true",
11851                                         "aria-hidden": "false"
11852                                 });
11853                 }
11854         },
11855
11856         _processTabs: function() {
11857                 var that = this;
11858
11859                 this.tablist = this._getList()
11860                         .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11861                         .attr( "role", "tablist" );
11862
11863                 this.tabs = this.tablist.find( "> li:has(a[href])" )
11864                         .addClass( "ui-state-default ui-corner-top" )
11865                         .attr({
11866                                 role: "tab",
11867                                 tabIndex: -1
11868                         });
11869
11870                 this.anchors = this.tabs.map(function() {
11871                                 return $( "a", this )[ 0 ];
11872                         })
11873                         .addClass( "ui-tabs-anchor" )
11874                         .attr({
11875                                 role: "presentation",
11876                                 tabIndex: -1
11877                         });
11878
11879                 this.panels = $();
11880
11881                 this.anchors.each(function( i, anchor ) {
11882                         var selector, panel, panelId,
11883                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
11884                                 tab = $( anchor ).closest( "li" ),
11885                                 originalAriaControls = tab.attr( "aria-controls" );
11886
11887                         // inline tab
11888                         if ( isLocal( anchor ) ) {
11889                                 selector = anchor.hash;
11890                                 panel = that.element.find( that._sanitizeSelector( selector ) );
11891                         // remote tab
11892                         } else {
11893                                 panelId = that._tabId( tab );
11894                                 selector = "#" + panelId;
11895                                 panel = that.element.find( selector );
11896                                 if ( !panel.length ) {
11897                                         panel = that._createPanel( panelId );
11898                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
11899                                 }
11900                                 panel.attr( "aria-live", "polite" );
11901                         }
11902
11903                         if ( panel.length) {
11904                                 that.panels = that.panels.add( panel );
11905                         }
11906                         if ( originalAriaControls ) {
11907                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
11908                         }
11909                         tab.attr({
11910                                 "aria-controls": selector.substring( 1 ),
11911                                 "aria-labelledby": anchorId
11912                         });
11913                         panel.attr( "aria-labelledby", anchorId );
11914                 });
11915
11916                 this.panels
11917                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11918                         .attr( "role", "tabpanel" );
11919         },
11920
11921         // allow overriding how to find the list for rare usage scenarios (#7715)
11922         _getList: function() {
11923                 return this.element.find( "ol,ul" ).eq( 0 );
11924         },
11925
11926         _createPanel: function( id ) {
11927                 return $( "<div>" )
11928                         .attr( "id", id )
11929                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11930                         .data( "ui-tabs-destroy", true );
11931         },
11932
11933         _setupDisabled: function( disabled ) {
11934                 if ( $.isArray( disabled ) ) {
11935                         if ( !disabled.length ) {
11936                                 disabled = false;
11937                         } else if ( disabled.length === this.anchors.length ) {
11938                                 disabled = true;
11939                         }
11940                 }
11941
11942                 // disable tabs
11943                 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
11944                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
11945                                 $( li )
11946                                         .addClass( "ui-state-disabled" )
11947                                         .attr( "aria-disabled", "true" );
11948                         } else {
11949                                 $( li )
11950                                         .removeClass( "ui-state-disabled" )
11951                                         .removeAttr( "aria-disabled" );
11952                         }
11953                 }
11954
11955                 this.options.disabled = disabled;
11956         },
11957
11958         _setupEvents: function( event ) {
11959                 var events = {
11960                         click: function( event ) {
11961                                 event.preventDefault();
11962                         }
11963                 };
11964                 if ( event ) {
11965                         $.each( event.split(" "), function( index, eventName ) {
11966                                 events[ eventName ] = "_eventHandler";
11967                         });
11968                 }
11969
11970                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
11971                 this._on( this.anchors, events );
11972                 this._on( this.tabs, { keydown: "_tabKeydown" } );
11973                 this._on( this.panels, { keydown: "_panelKeydown" } );
11974
11975                 this._focusable( this.tabs );
11976                 this._hoverable( this.tabs );
11977         },
11978
11979         _setupHeightStyle: function( heightStyle ) {
11980                 var maxHeight,
11981                         parent = this.element.parent();
11982
11983                 if ( heightStyle === "fill" ) {
11984                         maxHeight = parent.height();
11985                         maxHeight -= this.element.outerHeight() - this.element.height();
11986
11987                         this.element.siblings( ":visible" ).each(function() {
11988                                 var elem = $( this ),
11989                                         position = elem.css( "position" );
11990
11991                                 if ( position === "absolute" || position === "fixed" ) {
11992                                         return;
11993                                 }
11994                                 maxHeight -= elem.outerHeight( true );
11995                         });
11996
11997                         this.element.children().not( this.panels ).each(function() {
11998                                 maxHeight -= $( this ).outerHeight( true );
11999                         });
12000
12001                         this.panels.each(function() {
12002                                 $( this ).height( Math.max( 0, maxHeight -
12003                                         $( this ).innerHeight() + $( this ).height() ) );
12004                         })
12005                         .css( "overflow", "auto" );
12006                 } else if ( heightStyle === "auto" ) {
12007                         maxHeight = 0;
12008                         this.panels.each(function() {
12009                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
12010                         }).height( maxHeight );
12011                 }
12012         },
12013
12014         _eventHandler: function( event ) {
12015                 var options = this.options,
12016                         active = this.active,
12017                         anchor = $( event.currentTarget ),
12018                         tab = anchor.closest( "li" ),
12019                         clickedIsActive = tab[ 0 ] === active[ 0 ],
12020                         collapsing = clickedIsActive && options.collapsible,
12021                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
12022                         toHide = !active.length ? $() : this._getPanelForTab( active ),
12023                         eventData = {
12024                                 oldTab: active,
12025                                 oldPanel: toHide,
12026                                 newTab: collapsing ? $() : tab,
12027                                 newPanel: toShow
12028                         };
12029
12030                 event.preventDefault();
12031
12032                 if ( tab.hasClass( "ui-state-disabled" ) ||
12033                                 // tab is already loading
12034                                 tab.hasClass( "ui-tabs-loading" ) ||
12035                                 // can't switch durning an animation
12036                                 this.running ||
12037                                 // click on active header, but not collapsible
12038                                 ( clickedIsActive && !options.collapsible ) ||
12039                                 // allow canceling activation
12040                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
12041                         return;
12042                 }
12043
12044                 options.active = collapsing ? false : this.tabs.index( tab );
12045
12046                 this.active = clickedIsActive ? $() : tab;
12047                 if ( this.xhr ) {
12048                         this.xhr.abort();
12049                 }
12050
12051                 if ( !toHide.length && !toShow.length ) {
12052                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
12053                 }
12054
12055                 if ( toShow.length ) {
12056                         this.load( this.tabs.index( tab ), event );
12057                 }
12058                 this._toggle( event, eventData );
12059         },
12060
12061         // handles show/hide for selecting tabs
12062         _toggle: function( event, eventData ) {
12063                 var that = this,
12064                         toShow = eventData.newPanel,
12065                         toHide = eventData.oldPanel;
12066
12067                 this.running = true;
12068
12069                 function complete() {
12070                         that.running = false;
12071                         that._trigger( "activate", event, eventData );
12072                 }
12073
12074                 function show() {
12075                         eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
12076
12077                         if ( toShow.length && that.options.show ) {
12078                                 that._show( toShow, that.options.show, complete );
12079                         } else {
12080                                 toShow.show();
12081                                 complete();
12082                         }
12083                 }
12084
12085                 // start out by hiding, then showing, then completing
12086                 if ( toHide.length && this.options.hide ) {
12087                         this._hide( toHide, this.options.hide, function() {
12088                                 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12089                                 show();
12090                         });
12091                 } else {
12092                         eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12093                         toHide.hide();
12094                         show();
12095                 }
12096
12097                 toHide.attr({
12098                         "aria-expanded": "false",
12099                         "aria-hidden": "true"
12100                 });
12101                 eventData.oldTab.attr( "aria-selected", "false" );
12102                 // If we're switching tabs, remove the old tab from the tab order.
12103                 // If we're opening from collapsed state, remove the previous tab from the tab order.
12104                 // If we're collapsing, then keep the collapsing tab in the tab order.
12105                 if ( toShow.length && toHide.length ) {
12106                         eventData.oldTab.attr( "tabIndex", -1 );
12107                 } else if ( toShow.length ) {
12108                         this.tabs.filter(function() {
12109                                 return $( this ).attr( "tabIndex" ) === 0;
12110                         })
12111                         .attr( "tabIndex", -1 );
12112                 }
12113
12114                 toShow.attr({
12115                         "aria-expanded": "true",
12116                         "aria-hidden": "false"
12117                 });
12118                 eventData.newTab.attr({
12119                         "aria-selected": "true",
12120                         tabIndex: 0
12121                 });
12122         },
12123
12124         _activate: function( index ) {
12125                 var anchor,
12126                         active = this._findActive( index );
12127
12128                 // trying to activate the already active panel
12129                 if ( active[ 0 ] === this.active[ 0 ] ) {
12130                         return;
12131                 }
12132
12133                 // trying to collapse, simulate a click on the current active header
12134                 if ( !active.length ) {
12135                         active = this.active;
12136                 }
12137
12138                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
12139                 this._eventHandler({
12140                         target: anchor,
12141                         currentTarget: anchor,
12142                         preventDefault: $.noop
12143                 });
12144         },
12145
12146         _findActive: function( index ) {
12147                 return index === false ? $() : this.tabs.eq( index );
12148         },
12149
12150         _getIndex: function( index ) {
12151                 // meta-function to give users option to provide a href string instead of a numerical index.
12152                 if ( typeof index === "string" ) {
12153                         index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
12154                 }
12155
12156                 return index;
12157         },
12158
12159         _destroy: function() {
12160                 if ( this.xhr ) {
12161                         this.xhr.abort();
12162                 }
12163
12164                 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
12165
12166                 this.tablist
12167                         .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
12168                         .removeAttr( "role" );
12169
12170                 this.anchors
12171                         .removeClass( "ui-tabs-anchor" )
12172                         .removeAttr( "role" )
12173                         .removeAttr( "tabIndex" )
12174                         .removeUniqueId();
12175
12176                 this.tabs.add( this.panels ).each(function() {
12177                         if ( $.data( this, "ui-tabs-destroy" ) ) {
12178                                 $( this ).remove();
12179                         } else {
12180                                 $( this )
12181                                         .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
12182                                                 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
12183                                         .removeAttr( "tabIndex" )
12184                                         .removeAttr( "aria-live" )
12185                                         .removeAttr( "aria-busy" )
12186                                         .removeAttr( "aria-selected" )
12187                                         .removeAttr( "aria-labelledby" )
12188                                         .removeAttr( "aria-hidden" )
12189                                         .removeAttr( "aria-expanded" )
12190                                         .removeAttr( "role" );
12191                         }
12192                 });
12193
12194                 this.tabs.each(function() {
12195                         var li = $( this ),
12196                                 prev = li.data( "ui-tabs-aria-controls" );
12197                         if ( prev ) {
12198                                 li
12199                                         .attr( "aria-controls", prev )
12200                                         .removeData( "ui-tabs-aria-controls" );
12201                         } else {
12202                                 li.removeAttr( "aria-controls" );
12203                         }
12204                 });
12205
12206                 this.panels.show();
12207
12208                 if ( this.options.heightStyle !== "content" ) {
12209                         this.panels.css( "height", "" );
12210                 }
12211         },
12212
12213         enable: function( index ) {
12214                 var disabled = this.options.disabled;
12215                 if ( disabled === false ) {
12216                         return;
12217                 }
12218
12219                 if ( index === undefined ) {
12220                         disabled = false;
12221                 } else {
12222                         index = this._getIndex( index );
12223                         if ( $.isArray( disabled ) ) {
12224                                 disabled = $.map( disabled, function( num ) {
12225                                         return num !== index ? num : null;
12226                                 });
12227                         } else {
12228                                 disabled = $.map( this.tabs, function( li, num ) {
12229                                         return num !== index ? num : null;
12230                                 });
12231                         }
12232                 }
12233                 this._setupDisabled( disabled );
12234         },
12235
12236         disable: function( index ) {
12237                 var disabled = this.options.disabled;
12238                 if ( disabled === true ) {
12239                         return;
12240                 }
12241
12242                 if ( index === undefined ) {
12243                         disabled = true;
12244                 } else {
12245                         index = this._getIndex( index );
12246                         if ( $.inArray( index, disabled ) !== -1 ) {
12247                                 return;
12248                         }
12249                         if ( $.isArray( disabled ) ) {
12250                                 disabled = $.merge( [ index ], disabled ).sort();
12251                         } else {
12252                                 disabled = [ index ];
12253                         }
12254                 }
12255                 this._setupDisabled( disabled );
12256         },
12257
12258         load: function( index, event ) {
12259                 index = this._getIndex( index );
12260                 var that = this,
12261                         tab = this.tabs.eq( index ),
12262                         anchor = tab.find( ".ui-tabs-anchor" ),
12263                         panel = this._getPanelForTab( tab ),
12264                         eventData = {
12265                                 tab: tab,
12266                                 panel: panel
12267                         };
12268
12269                 // not remote
12270                 if ( isLocal( anchor[ 0 ] ) ) {
12271                         return;
12272                 }
12273
12274                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
12275
12276                 // support: jQuery <1.8
12277                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
12278                 // but as of 1.8, $.ajax() always returns a jqXHR object.
12279                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
12280                         tab.addClass( "ui-tabs-loading" );
12281                         panel.attr( "aria-busy", "true" );
12282
12283                         this.xhr
12284                                 .success(function( response ) {
12285                                         // support: jQuery <1.8
12286                                         // http://bugs.jquery.com/ticket/11778
12287                                         setTimeout(function() {
12288                                                 panel.html( response );
12289                                                 that._trigger( "load", event, eventData );
12290                                         }, 1 );
12291                                 })
12292                                 .complete(function( jqXHR, status ) {
12293                                         // support: jQuery <1.8
12294                                         // http://bugs.jquery.com/ticket/11778
12295                                         setTimeout(function() {
12296                                                 if ( status === "abort" ) {
12297                                                         that.panels.stop( false, true );
12298                                                 }
12299
12300                                                 tab.removeClass( "ui-tabs-loading" );
12301                                                 panel.removeAttr( "aria-busy" );
12302
12303                                                 if ( jqXHR === that.xhr ) {
12304                                                         delete that.xhr;
12305                                                 }
12306                                         }, 1 );
12307                                 });
12308                 }
12309         },
12310
12311         _ajaxSettings: function( anchor, event, eventData ) {
12312                 var that = this;
12313                 return {
12314                         url: anchor.attr( "href" ),
12315                         beforeSend: function( jqXHR, settings ) {
12316                                 return that._trigger( "beforeLoad", event,
12317                                         $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
12318                         }
12319                 };
12320         },
12321
12322         _getPanelForTab: function( tab ) {
12323                 var id = $( tab ).attr( "aria-controls" );
12324                 return this.element.find( this._sanitizeSelector( "#" + id ) );
12325         }
12326 });
12327
12328 })( jQuery );
12329 (function( $ ) {
12330
12331 var increments = 0;
12332
12333 function addDescribedBy( elem, id ) {
12334         var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
12335         describedby.push( id );
12336         elem
12337                 .data( "ui-tooltip-id", id )
12338                 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
12339 }
12340
12341 function removeDescribedBy( elem ) {
12342         var id = elem.data( "ui-tooltip-id" ),
12343                 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
12344                 index = $.inArray( id, describedby );
12345         if ( index !== -1 ) {
12346                 describedby.splice( index, 1 );
12347         }
12348
12349         elem.removeData( "ui-tooltip-id" );
12350         describedby = $.trim( describedby.join( " " ) );
12351         if ( describedby ) {
12352                 elem.attr( "aria-describedby", describedby );
12353         } else {
12354                 elem.removeAttr( "aria-describedby" );
12355         }
12356 }
12357
12358 $.widget( "ui.tooltip", {
12359         version: "1.10.3",
12360         options: {
12361                 content: function() {
12362                         // support: IE<9, Opera in jQuery <1.7
12363                         // .text() can't accept undefined, so coerce to a string
12364                         var title = $( this ).attr( "title" ) || "";
12365                         // Escape title, since we're going from an attribute to raw HTML
12366                         return $( "<a>" ).text( title ).html();
12367                 },
12368                 hide: true,
12369                 // Disabled elements have inconsistent behavior across browsers (#8661)
12370                 items: "[title]:not([disabled])",
12371                 position: {
12372                         my: "left top+15",
12373                         at: "left bottom",
12374                         collision: "flipfit flip"
12375                 },
12376                 show: true,
12377                 tooltipClass: null,
12378                 track: false,
12379
12380                 // callbacks
12381                 close: null,
12382                 open: null
12383         },
12384
12385         _create: function() {
12386                 this._on({
12387                         mouseover: "open",
12388                         focusin: "open"
12389                 });
12390
12391                 // IDs of generated tooltips, needed for destroy
12392                 this.tooltips = {};
12393                 // IDs of parent tooltips where we removed the title attribute
12394                 this.parents = {};
12395
12396                 if ( this.options.disabled ) {
12397                         this._disable();
12398                 }
12399         },
12400
12401         _setOption: function( key, value ) {
12402                 var that = this;
12403
12404                 if ( key === "disabled" ) {
12405                         this[ value ? "_disable" : "_enable" ]();
12406                         this.options[ key ] = value;
12407                         // disable element style changes
12408                         return;
12409                 }
12410
12411                 this._super( key, value );
12412
12413                 if ( key === "content" ) {
12414                         $.each( this.tooltips, function( id, element ) {
12415                                 that._updateContent( element );
12416                         });
12417                 }
12418         },
12419
12420         _disable: function() {
12421                 var that = this;
12422
12423                 // close open tooltips
12424                 $.each( this.tooltips, function( id, element ) {
12425                         var event = $.Event( "blur" );
12426                         event.target = event.currentTarget = element[0];
12427                         that.close( event, true );
12428                 });
12429
12430                 // remove title attributes to prevent native tooltips
12431                 this.element.find( this.options.items ).addBack().each(function() {
12432                         var element = $( this );
12433                         if ( element.is( "[title]" ) ) {
12434                                 element
12435                                         .data( "ui-tooltip-title", element.attr( "title" ) )
12436                                         .attr( "title", "" );
12437                         }
12438                 });
12439         },
12440
12441         _enable: function() {
12442                 // restore title attributes
12443                 this.element.find( this.options.items ).addBack().each(function() {
12444                         var element = $( this );
12445                         if ( element.data( "ui-tooltip-title" ) ) {
12446                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
12447                         }
12448                 });
12449         },
12450
12451         open: function( event ) {
12452                 var that = this,
12453                         target = $( event ? event.target : this.element )
12454                                 // we need closest here due to mouseover bubbling,
12455                                 // but always pointing at the same event target
12456                                 .closest( this.options.items );
12457
12458                 // No element to show a tooltip for or the tooltip is already open
12459                 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
12460                         return;
12461                 }
12462
12463                 if ( target.attr( "title" ) ) {
12464                         target.data( "ui-tooltip-title", target.attr( "title" ) );
12465                 }
12466
12467                 target.data( "ui-tooltip-open", true );
12468
12469                 // kill parent tooltips, custom or native, for hover
12470                 if ( event && event.type === "mouseover" ) {
12471                         target.parents().each(function() {
12472                                 var parent = $( this ),
12473                                         blurEvent;
12474                                 if ( parent.data( "ui-tooltip-open" ) ) {
12475                                         blurEvent = $.Event( "blur" );
12476                                         blurEvent.target = blurEvent.currentTarget = this;
12477                                         that.close( blurEvent, true );
12478                                 }
12479                                 if ( parent.attr( "title" ) ) {
12480                                         parent.uniqueId();
12481                                         that.parents[ this.id ] = {
12482                                                 element: this,
12483                                                 title: parent.attr( "title" )
12484                                         };
12485                                         parent.attr( "title", "" );
12486                                 }
12487                         });
12488                 }
12489
12490                 this._updateContent( target, event );
12491         },
12492
12493         _updateContent: function( target, event ) {
12494                 var content,
12495                         contentOption = this.options.content,
12496                         that = this,
12497                         eventType = event ? event.type : null;
12498
12499                 if ( typeof contentOption === "string" ) {
12500                         return this._open( event, target, contentOption );
12501                 }
12502
12503                 content = contentOption.call( target[0], function( response ) {
12504                         // ignore async response if tooltip was closed already
12505                         if ( !target.data( "ui-tooltip-open" ) ) {
12506                                 return;
12507                         }
12508                         // IE may instantly serve a cached response for ajax requests
12509                         // delay this call to _open so the other call to _open runs first
12510                         that._delay(function() {
12511                                 // jQuery creates a special event for focusin when it doesn't
12512                                 // exist natively. To improve performance, the native event
12513                                 // object is reused and the type is changed. Therefore, we can't
12514                                 // rely on the type being correct after the event finished
12515                                 // bubbling, so we set it back to the previous value. (#8740)
12516                                 if ( event ) {
12517                                         event.type = eventType;
12518                                 }
12519                                 this._open( event, target, response );
12520                         });
12521                 });
12522                 if ( content ) {
12523                         this._open( event, target, content );
12524                 }
12525         },
12526
12527         _open: function( event, target, content ) {
12528                 var tooltip, events, delayedShow,
12529                         positionOption = $.extend( {}, this.options.position );
12530
12531                 if ( !content ) {
12532                         return;
12533                 }
12534
12535                 // Content can be updated multiple times. If the tooltip already
12536                 // exists, then just update the content and bail.
12537                 tooltip = this._find( target );
12538                 if ( tooltip.length ) {
12539                         tooltip.find( ".ui-tooltip-content" ).html( content );
12540                         return;
12541                 }
12542
12543                 // if we have a title, clear it to prevent the native tooltip
12544                 // we have to check first to avoid defining a title if none exists
12545                 // (we don't want to cause an element to start matching [title])
12546                 //
12547                 // We use removeAttr only for key events, to allow IE to export the correct
12548                 // accessible attributes. For mouse events, set to empty string to avoid
12549                 // native tooltip showing up (happens only when removing inside mouseover).
12550                 if ( target.is( "[title]" ) ) {
12551                         if ( event && event.type === "mouseover" ) {
12552                                 target.attr( "title", "" );
12553                         } else {
12554                                 target.removeAttr( "title" );
12555                         }
12556                 }
12557
12558                 tooltip = this._tooltip( target );
12559                 addDescribedBy( target, tooltip.attr( "id" ) );
12560                 tooltip.find( ".ui-tooltip-content" ).html( content );
12561
12562                 function position( event ) {
12563                         positionOption.of = event;
12564                         if ( tooltip.is( ":hidden" ) ) {
12565                                 return;
12566                         }
12567                         tooltip.position( positionOption );
12568                 }
12569                 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
12570                         this._on( this.document, {
12571                                 mousemove: position
12572                         });
12573                         // trigger once to override element-relative positioning
12574                         position( event );
12575                 } else {
12576                         tooltip.position( $.extend({
12577                                 of: target
12578                         }, this.options.position ) );
12579                 }
12580
12581                 tooltip.hide();
12582
12583                 this._show( tooltip, this.options.show );
12584                 // Handle tracking tooltips that are shown with a delay (#8644). As soon
12585                 // as the tooltip is visible, position the tooltip using the most recent
12586                 // event.
12587                 if ( this.options.show && this.options.show.delay ) {
12588                         delayedShow = this.delayedShow = setInterval(function() {
12589                                 if ( tooltip.is( ":visible" ) ) {
12590                                         position( positionOption.of );
12591                                         clearInterval( delayedShow );
12592                                 }
12593                         }, $.fx.interval );
12594                 }
12595
12596                 this._trigger( "open", event, { tooltip: tooltip } );
12597
12598                 events = {
12599                         keyup: function( event ) {
12600                                 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
12601                                         var fakeEvent = $.Event(event);
12602                                         fakeEvent.currentTarget = target[0];
12603                                         this.close( fakeEvent, true );
12604                                 }
12605                         },
12606                         remove: function() {
12607                                 this._removeTooltip( tooltip );
12608                         }
12609                 };
12610                 if ( !event || event.type === "mouseover" ) {
12611                         events.mouseleave = "close";
12612                 }
12613                 if ( !event || event.type === "focusin" ) {
12614                         events.focusout = "close";
12615                 }
12616                 this._on( true, target, events );
12617         },
12618
12619         close: function( event ) {
12620                 var that = this,
12621                         target = $( event ? event.currentTarget : this.element ),
12622                         tooltip = this._find( target );
12623
12624                 // disabling closes the tooltip, so we need to track when we're closing
12625                 // to avoid an infinite loop in case the tooltip becomes disabled on close
12626                 if ( this.closing ) {
12627                         return;
12628                 }
12629
12630                 // Clear the interval for delayed tracking tooltips
12631                 clearInterval( this.delayedShow );
12632
12633                 // only set title if we had one before (see comment in _open())
12634                 if ( target.data( "ui-tooltip-title" ) ) {
12635                         target.attr( "title", target.data( "ui-tooltip-title" ) );
12636                 }
12637
12638                 removeDescribedBy( target );
12639
12640                 tooltip.stop( true );
12641                 this._hide( tooltip, this.options.hide, function() {
12642                         that._removeTooltip( $( this ) );
12643                 });
12644
12645                 target.removeData( "ui-tooltip-open" );
12646                 this._off( target, "mouseleave focusout keyup" );
12647                 // Remove 'remove' binding only on delegated targets
12648                 if ( target[0] !== this.element[0] ) {
12649                         this._off( target, "remove" );
12650                 }
12651                 this._off( this.document, "mousemove" );
12652
12653                 if ( event && event.type === "mouseleave" ) {
12654                         $.each( this.parents, function( id, parent ) {
12655                                 $( parent.element ).attr( "title", parent.title );
12656                                 delete that.parents[ id ];
12657                         });
12658                 }
12659
12660                 this.closing = true;
12661                 this._trigger( "close", event, { tooltip: tooltip } );
12662                 this.closing = false;
12663         },
12664
12665         _tooltip: function( element ) {
12666                 var id = "ui-tooltip-" + increments++,
12667                         tooltip = $( "<div>" )
12668                                 .attr({
12669                                         id: id,
12670                                         role: "tooltip"
12671                                 })
12672                                 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
12673                                         ( this.options.tooltipClass || "" ) );
12674                 $( "<div>" )
12675                         .addClass( "ui-tooltip-content" )
12676                         .appendTo( tooltip );
12677                 tooltip.appendTo( this.document[0].body );
12678                 this.tooltips[ id ] = element;
12679                 return tooltip;
12680         },
12681
12682         _find: function( target ) {
12683                 var id = target.data( "ui-tooltip-id" );
12684                 return id ? $( "#" + id ) : $();
12685         },
12686
12687         _removeTooltip: function( tooltip ) {
12688                 tooltip.remove();
12689                 delete this.tooltips[ tooltip.attr( "id" ) ];
12690         },
12691
12692         _destroy: function() {
12693                 var that = this;
12694
12695                 // close open tooltips
12696                 $.each( this.tooltips, function( id, element ) {
12697                         // Delegate to close method to handle common cleanup
12698                         var event = $.Event( "blur" );
12699                         event.target = event.currentTarget = element[0];
12700                         that.close( event, true );
12701
12702                         // Remove immediately; destroying an open tooltip doesn't use the
12703                         // hide animation
12704                         $( "#" + id ).remove();
12705
12706                         // Restore the title
12707                         if ( element.data( "ui-tooltip-title" ) ) {
12708                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
12709                                 element.removeData( "ui-tooltip-title" );
12710                         }
12711                 });
12712         }
12713 });
12714
12715 }( jQuery ) );
12716 (function($, undefined) {
12717
12718 var dataSpace = "ui-effects-";
12719
12720 $.effects = {
12721         effect: {}
12722 };
12723
12724 /*!
12725  * jQuery Color Animations v2.1.2
12726  * https://github.com/jquery/jquery-color
12727  *
12728  * Copyright 2013 jQuery Foundation and other contributors
12729  * Released under the MIT license.
12730  * http://jquery.org/license
12731  *
12732  * Date: Wed Jan 16 08:47:09 2013 -0600
12733  */
12734 (function( jQuery, undefined ) {
12735
12736         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
12737
12738         // plusequals test for += 100 -= 100
12739         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
12740         // a set of RE's that can match strings and generate color tuples.
12741         stringParsers = [{
12742                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12743                         parse: function( execResult ) {
12744                                 return [
12745                                         execResult[ 1 ],
12746                                         execResult[ 2 ],
12747                                         execResult[ 3 ],
12748                                         execResult[ 4 ]
12749                                 ];
12750                         }
12751                 }, {
12752                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12753                         parse: function( execResult ) {
12754                                 return [
12755                                         execResult[ 1 ] * 2.55,
12756                                         execResult[ 2 ] * 2.55,
12757                                         execResult[ 3 ] * 2.55,
12758                                         execResult[ 4 ]
12759                                 ];
12760                         }
12761                 }, {
12762                         // this regex ignores A-F because it's compared against an already lowercased string
12763                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
12764                         parse: function( execResult ) {
12765                                 return [
12766                                         parseInt( execResult[ 1 ], 16 ),
12767                                         parseInt( execResult[ 2 ], 16 ),
12768                                         parseInt( execResult[ 3 ], 16 )
12769                                 ];
12770                         }
12771                 }, {
12772                         // this regex ignores A-F because it's compared against an already lowercased string
12773                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
12774                         parse: function( execResult ) {
12775                                 return [
12776                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
12777                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
12778                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
12779                                 ];
12780                         }
12781                 }, {
12782                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12783                         space: "hsla",
12784                         parse: function( execResult ) {
12785                                 return [
12786                                         execResult[ 1 ],
12787                                         execResult[ 2 ] / 100,
12788                                         execResult[ 3 ] / 100,
12789                                         execResult[ 4 ]
12790                                 ];
12791                         }
12792                 }],
12793
12794         // jQuery.Color( )
12795         color = jQuery.Color = function( color, green, blue, alpha ) {
12796                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
12797         },
12798         spaces = {
12799                 rgba: {
12800                         props: {
12801                                 red: {
12802                                         idx: 0,
12803                                         type: "byte"
12804                                 },
12805                                 green: {
12806                                         idx: 1,
12807                                         type: "byte"
12808                                 },
12809                                 blue: {
12810                                         idx: 2,
12811                                         type: "byte"
12812                                 }
12813                         }
12814                 },
12815
12816                 hsla: {
12817                         props: {
12818                                 hue: {
12819                                         idx: 0,
12820                                         type: "degrees"
12821                                 },
12822                                 saturation: {
12823                                         idx: 1,
12824                                         type: "percent"
12825                                 },
12826                                 lightness: {
12827                                         idx: 2,
12828                                         type: "percent"
12829                                 }
12830                         }
12831                 }
12832         },
12833         propTypes = {
12834                 "byte": {
12835                         floor: true,
12836                         max: 255
12837                 },
12838                 "percent": {
12839                         max: 1
12840                 },
12841                 "degrees": {
12842                         mod: 360,
12843                         floor: true
12844                 }
12845         },
12846         support = color.support = {},
12847
12848         // element for support tests
12849         supportElem = jQuery( "<p>" )[ 0 ],
12850
12851         // colors = jQuery.Color.names
12852         colors,
12853
12854         // local aliases of functions called often
12855         each = jQuery.each;
12856
12857 // determine rgba support immediately
12858 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
12859 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
12860
12861 // define cache name and alpha properties
12862 // for rgba and hsla spaces
12863 each( spaces, function( spaceName, space ) {
12864         space.cache = "_" + spaceName;
12865         space.props.alpha = {
12866                 idx: 3,
12867                 type: "percent",
12868                 def: 1
12869         };
12870 });
12871
12872 function clamp( value, prop, allowEmpty ) {
12873         var type = propTypes[ prop.type ] || {};
12874
12875         if ( value == null ) {
12876                 return (allowEmpty || !prop.def) ? null : prop.def;
12877         }
12878
12879         // ~~ is an short way of doing floor for positive numbers
12880         value = type.floor ? ~~value : parseFloat( value );
12881
12882         // IE will pass in empty strings as value for alpha,
12883         // which will hit this case
12884         if ( isNaN( value ) ) {
12885                 return prop.def;
12886         }
12887
12888         if ( type.mod ) {
12889                 // we add mod before modding to make sure that negatives values
12890                 // get converted properly: -10 -> 350
12891                 return (value + type.mod) % type.mod;
12892         }
12893
12894         // for now all property types without mod have min and max
12895         return 0 > value ? 0 : type.max < value ? type.max : value;
12896 }
12897
12898 function stringParse( string ) {
12899         var inst = color(),
12900                 rgba = inst._rgba = [];
12901
12902         string = string.toLowerCase();
12903
12904         each( stringParsers, function( i, parser ) {
12905                 var parsed,
12906                         match = parser.re.exec( string ),
12907                         values = match && parser.parse( match ),
12908                         spaceName = parser.space || "rgba";
12909
12910                 if ( values ) {
12911                         parsed = inst[ spaceName ]( values );
12912
12913                         // if this was an rgba parse the assignment might happen twice
12914                         // oh well....
12915                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
12916                         rgba = inst._rgba = parsed._rgba;
12917
12918                         // exit each( stringParsers ) here because we matched
12919                         return false;
12920                 }
12921         });
12922
12923         // Found a stringParser that handled it
12924         if ( rgba.length ) {
12925
12926                 // if this came from a parsed string, force "transparent" when alpha is 0
12927                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
12928                 if ( rgba.join() === "0,0,0,0" ) {
12929                         jQuery.extend( rgba, colors.transparent );
12930                 }
12931                 return inst;
12932         }
12933
12934         // named colors
12935         return colors[ string ];
12936 }
12937
12938 color.fn = jQuery.extend( color.prototype, {
12939         parse: function( red, green, blue, alpha ) {
12940                 if ( red === undefined ) {
12941                         this._rgba = [ null, null, null, null ];
12942                         return this;
12943                 }
12944                 if ( red.jquery || red.nodeType ) {
12945                         red = jQuery( red ).css( green );
12946                         green = undefined;
12947                 }
12948
12949                 var inst = this,
12950                         type = jQuery.type( red ),
12951                         rgba = this._rgba = [];
12952
12953                 // more than 1 argument specified - assume ( red, green, blue, alpha )
12954                 if ( green !== undefined ) {
12955                         red = [ red, green, blue, alpha ];
12956                         type = "array";
12957                 }
12958
12959                 if ( type === "string" ) {
12960                         return this.parse( stringParse( red ) || colors._default );
12961                 }
12962
12963                 if ( type === "array" ) {
12964                         each( spaces.rgba.props, function( key, prop ) {
12965                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
12966                         });
12967                         return this;
12968                 }
12969
12970                 if ( type === "object" ) {
12971                         if ( red instanceof color ) {
12972                                 each( spaces, function( spaceName, space ) {
12973                                         if ( red[ space.cache ] ) {
12974                                                 inst[ space.cache ] = red[ space.cache ].slice();
12975                                         }
12976                                 });
12977                         } else {
12978                                 each( spaces, function( spaceName, space ) {
12979                                         var cache = space.cache;
12980                                         each( space.props, function( key, prop ) {
12981
12982                                                 // if the cache doesn't exist, and we know how to convert
12983                                                 if ( !inst[ cache ] && space.to ) {
12984
12985                                                         // if the value was null, we don't need to copy it
12986                                                         // if the key was alpha, we don't need to copy it either
12987                                                         if ( key === "alpha" || red[ key ] == null ) {
12988                                                                 return;
12989                                                         }
12990                                                         inst[ cache ] = space.to( inst._rgba );
12991                                                 }
12992
12993                                                 // this is the only case where we allow nulls for ALL properties.
12994                                                 // call clamp with alwaysAllowEmpty
12995                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
12996                                         });
12997
12998                                         // everything defined but alpha?
12999                                         if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
13000                                                 // use the default of 1
13001                                                 inst[ cache ][ 3 ] = 1;
13002                                                 if ( space.from ) {
13003                                                         inst._rgba = space.from( inst[ cache ] );
13004                                                 }
13005                                         }
13006                                 });
13007                         }
13008                         return this;
13009                 }
13010         },
13011         is: function( compare ) {
13012                 var is = color( compare ),
13013                         same = true,
13014                         inst = this;
13015
13016                 each( spaces, function( _, space ) {
13017                         var localCache,
13018                                 isCache = is[ space.cache ];
13019                         if (isCache) {
13020                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
13021                                 each( space.props, function( _, prop ) {
13022                                         if ( isCache[ prop.idx ] != null ) {
13023                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
13024                                                 return same;
13025                                         }
13026                                 });
13027                         }
13028                         return same;
13029                 });
13030                 return same;
13031         },
13032         _space: function() {
13033                 var used = [],
13034                         inst = this;
13035                 each( spaces, function( spaceName, space ) {
13036                         if ( inst[ space.cache ] ) {
13037                                 used.push( spaceName );
13038                         }
13039                 });
13040                 return used.pop();
13041         },
13042         transition: function( other, distance ) {
13043                 var end = color( other ),
13044                         spaceName = end._space(),
13045                         space = spaces[ spaceName ],
13046                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
13047                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
13048                         result = start.slice();
13049
13050                 end = end[ space.cache ];
13051                 each( space.props, function( key, prop ) {
13052                         var index = prop.idx,
13053                                 startValue = start[ index ],
13054                                 endValue = end[ index ],
13055                                 type = propTypes[ prop.type ] || {};
13056
13057                         // if null, don't override start value
13058                         if ( endValue === null ) {
13059                                 return;
13060                         }
13061                         // if null - use end
13062                         if ( startValue === null ) {
13063                                 result[ index ] = endValue;
13064                         } else {
13065                                 if ( type.mod ) {
13066                                         if ( endValue - startValue > type.mod / 2 ) {
13067                                                 startValue += type.mod;
13068                                         } else if ( startValue - endValue > type.mod / 2 ) {
13069                                                 startValue -= type.mod;
13070                                         }
13071                                 }
13072                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
13073                         }
13074                 });
13075                 return this[ spaceName ]( result );
13076         },
13077         blend: function( opaque ) {
13078                 // if we are already opaque - return ourself
13079                 if ( this._rgba[ 3 ] === 1 ) {
13080                         return this;
13081                 }
13082
13083                 var rgb = this._rgba.slice(),
13084                         a = rgb.pop(),
13085                         blend = color( opaque )._rgba;
13086
13087                 return color( jQuery.map( rgb, function( v, i ) {
13088                         return ( 1 - a ) * blend[ i ] + a * v;
13089                 }));
13090         },
13091         toRgbaString: function() {
13092                 var prefix = "rgba(",
13093                         rgba = jQuery.map( this._rgba, function( v, i ) {
13094                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
13095                         });
13096
13097                 if ( rgba[ 3 ] === 1 ) {
13098                         rgba.pop();
13099                         prefix = "rgb(";
13100                 }
13101
13102                 return prefix + rgba.join() + ")";
13103         },
13104         toHslaString: function() {
13105                 var prefix = "hsla(",
13106                         hsla = jQuery.map( this.hsla(), function( v, i ) {
13107                                 if ( v == null ) {
13108                                         v = i > 2 ? 1 : 0;
13109                                 }
13110
13111                                 // catch 1 and 2
13112                                 if ( i && i < 3 ) {
13113                                         v = Math.round( v * 100 ) + "%";
13114                                 }
13115                                 return v;
13116                         });
13117
13118                 if ( hsla[ 3 ] === 1 ) {
13119                         hsla.pop();
13120                         prefix = "hsl(";
13121                 }
13122                 return prefix + hsla.join() + ")";
13123         },
13124         toHexString: function( includeAlpha ) {
13125                 var rgba = this._rgba.slice(),
13126                         alpha = rgba.pop();
13127
13128                 if ( includeAlpha ) {
13129                         rgba.push( ~~( alpha * 255 ) );
13130                 }
13131
13132                 return "#" + jQuery.map( rgba, function( v ) {
13133
13134                         // default to 0 when nulls exist
13135                         v = ( v || 0 ).toString( 16 );
13136                         return v.length === 1 ? "0" + v : v;
13137                 }).join("");
13138         },
13139         toString: function() {
13140                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
13141         }
13142 });
13143 color.fn.parse.prototype = color.fn;
13144
13145 // hsla conversions adapted from:
13146 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
13147
13148 function hue2rgb( p, q, h ) {
13149         h = ( h + 1 ) % 1;
13150         if ( h * 6 < 1 ) {
13151                 return p + (q - p) * h * 6;
13152         }
13153         if ( h * 2 < 1) {
13154                 return q;
13155         }
13156         if ( h * 3 < 2 ) {
13157                 return p + (q - p) * ((2/3) - h) * 6;
13158         }
13159         return p;
13160 }
13161
13162 spaces.hsla.to = function ( rgba ) {
13163         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
13164                 return [ null, null, null, rgba[ 3 ] ];
13165         }
13166         var r = rgba[ 0 ] / 255,
13167                 g = rgba[ 1 ] / 255,
13168                 b = rgba[ 2 ] / 255,
13169                 a = rgba[ 3 ],
13170                 max = Math.max( r, g, b ),
13171                 min = Math.min( r, g, b ),
13172                 diff = max - min,
13173                 add = max + min,
13174                 l = add * 0.5,
13175                 h, s;
13176
13177         if ( min === max ) {
13178                 h = 0;
13179         } else if ( r === max ) {
13180                 h = ( 60 * ( g - b ) / diff ) + 360;
13181         } else if ( g === max ) {
13182                 h = ( 60 * ( b - r ) / diff ) + 120;
13183         } else {
13184                 h = ( 60 * ( r - g ) / diff ) + 240;
13185         }
13186
13187         // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
13188         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
13189         if ( diff === 0 ) {
13190                 s = 0;
13191         } else if ( l <= 0.5 ) {
13192                 s = diff / add;
13193         } else {
13194                 s = diff / ( 2 - add );
13195         }
13196         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
13197 };
13198
13199 spaces.hsla.from = function ( hsla ) {
13200         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
13201                 return [ null, null, null, hsla[ 3 ] ];
13202         }
13203         var h = hsla[ 0 ] / 360,
13204                 s = hsla[ 1 ],
13205                 l = hsla[ 2 ],
13206                 a = hsla[ 3 ],
13207                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
13208                 p = 2 * l - q;
13209
13210         return [
13211                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
13212                 Math.round( hue2rgb( p, q, h ) * 255 ),
13213                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
13214                 a
13215         ];
13216 };
13217
13218
13219 each( spaces, function( spaceName, space ) {
13220         var props = space.props,
13221                 cache = space.cache,
13222                 to = space.to,
13223                 from = space.from;
13224
13225         // makes rgba() and hsla()
13226         color.fn[ spaceName ] = function( value ) {
13227
13228                 // generate a cache for this space if it doesn't exist
13229                 if ( to && !this[ cache ] ) {
13230                         this[ cache ] = to( this._rgba );
13231                 }
13232                 if ( value === undefined ) {
13233                         return this[ cache ].slice();
13234                 }
13235
13236                 var ret,
13237                         type = jQuery.type( value ),
13238                         arr = ( type === "array" || type === "object" ) ? value : arguments,
13239                         local = this[ cache ].slice();
13240
13241                 each( props, function( key, prop ) {
13242                         var val = arr[ type === "object" ? key : prop.idx ];
13243                         if ( val == null ) {
13244                                 val = local[ prop.idx ];
13245                         }
13246                         local[ prop.idx ] = clamp( val, prop );
13247                 });
13248
13249                 if ( from ) {
13250                         ret = color( from( local ) );
13251                         ret[ cache ] = local;
13252                         return ret;
13253                 } else {
13254                         return color( local );
13255                 }
13256         };
13257
13258         // makes red() green() blue() alpha() hue() saturation() lightness()
13259         each( props, function( key, prop ) {
13260                 // alpha is included in more than one space
13261                 if ( color.fn[ key ] ) {
13262                         return;
13263                 }
13264                 color.fn[ key ] = function( value ) {
13265                         var vtype = jQuery.type( value ),
13266                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
13267                                 local = this[ fn ](),
13268                                 cur = local[ prop.idx ],
13269                                 match;
13270
13271                         if ( vtype === "undefined" ) {
13272                                 return cur;
13273                         }
13274
13275                         if ( vtype === "function" ) {
13276                                 value = value.call( this, cur );
13277                                 vtype = jQuery.type( value );
13278                         }
13279                         if ( value == null && prop.empty ) {
13280                                 return this;
13281                         }
13282                         if ( vtype === "string" ) {
13283                                 match = rplusequals.exec( value );
13284                                 if ( match ) {
13285                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
13286                                 }
13287                         }
13288                         local[ prop.idx ] = value;
13289                         return this[ fn ]( local );
13290                 };
13291         });
13292 });
13293
13294 // add cssHook and .fx.step function for each named hook.
13295 // accept a space separated string of properties
13296 color.hook = function( hook ) {
13297         var hooks = hook.split( " " );
13298         each( hooks, function( i, hook ) {
13299                 jQuery.cssHooks[ hook ] = {
13300                         set: function( elem, value ) {
13301                                 var parsed, curElem,
13302                                         backgroundColor = "";
13303
13304                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
13305                                         value = color( parsed || value );
13306                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
13307                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
13308                                                 while (
13309                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
13310                                                         curElem && curElem.style
13311                                                 ) {
13312                                                         try {
13313                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
13314                                                                 curElem = curElem.parentNode;
13315                                                         } catch ( e ) {
13316                                                         }
13317                                                 }
13318
13319                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
13320                                                         backgroundColor :
13321                                                         "_default" );
13322                                         }
13323
13324                                         value = value.toRgbaString();
13325                                 }
13326                                 try {
13327                                         elem.style[ hook ] = value;
13328                                 } catch( e ) {
13329                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
13330                                 }
13331                         }
13332                 };
13333                 jQuery.fx.step[ hook ] = function( fx ) {
13334                         if ( !fx.colorInit ) {
13335                                 fx.start = color( fx.elem, hook );
13336                                 fx.end = color( fx.end );
13337                                 fx.colorInit = true;
13338                         }
13339                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
13340                 };
13341         });
13342
13343 };
13344
13345 color.hook( stepHooks );
13346
13347 jQuery.cssHooks.borderColor = {
13348         expand: function( value ) {
13349                 var expanded = {};
13350
13351                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
13352                         expanded[ "border" + part + "Color" ] = value;
13353                 });
13354                 return expanded;
13355         }
13356 };
13357
13358 // Basic color names only.
13359 // Usage of any of the other color names requires adding yourself or including
13360 // jquery.color.svg-names.js.
13361 colors = jQuery.Color.names = {
13362         // 4.1. Basic color keywords
13363         aqua: "#00ffff",
13364         black: "#000000",
13365         blue: "#0000ff",
13366         fuchsia: "#ff00ff",
13367         gray: "#808080",
13368         green: "#008000",
13369         lime: "#00ff00",
13370         maroon: "#800000",
13371         navy: "#000080",
13372         olive: "#808000",
13373         purple: "#800080",
13374         red: "#ff0000",
13375         silver: "#c0c0c0",
13376         teal: "#008080",
13377         white: "#ffffff",
13378         yellow: "#ffff00",
13379
13380         // 4.2.3. "transparent" color keyword
13381         transparent: [ null, null, null, 0 ],
13382
13383         _default: "#ffffff"
13384 };
13385
13386 })( jQuery );
13387
13388
13389 /******************************************************************************/
13390 /****************************** CLASS ANIMATIONS ******************************/
13391 /******************************************************************************/
13392 (function() {
13393
13394 var classAnimationActions = [ "add", "remove", "toggle" ],
13395         shorthandStyles = {
13396                 border: 1,
13397                 borderBottom: 1,
13398                 borderColor: 1,
13399                 borderLeft: 1,
13400                 borderRight: 1,
13401                 borderTop: 1,
13402                 borderWidth: 1,
13403                 margin: 1,
13404                 padding: 1
13405         };
13406
13407 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
13408         $.fx.step[ prop ] = function( fx ) {
13409                 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
13410                         jQuery.style( fx.elem, prop, fx.end );
13411                         fx.setAttr = true;
13412                 }
13413         };
13414 });
13415
13416 function getElementStyles( elem ) {
13417         var key, len,
13418                 style = elem.ownerDocument.defaultView ?
13419                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
13420                         elem.currentStyle,
13421                 styles = {};
13422
13423         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
13424                 len = style.length;
13425                 while ( len-- ) {
13426                         key = style[ len ];
13427                         if ( typeof style[ key ] === "string" ) {
13428                                 styles[ $.camelCase( key ) ] = style[ key ];
13429                         }
13430                 }
13431         // support: Opera, IE <9
13432         } else {
13433                 for ( key in style ) {
13434                         if ( typeof style[ key ] === "string" ) {
13435                                 styles[ key ] = style[ key ];
13436                         }
13437                 }
13438         }
13439
13440         return styles;
13441 }
13442
13443
13444 function styleDifference( oldStyle, newStyle ) {
13445         var diff = {},
13446                 name, value;
13447
13448         for ( name in newStyle ) {
13449                 value = newStyle[ name ];
13450                 if ( oldStyle[ name ] !== value ) {
13451                         if ( !shorthandStyles[ name ] ) {
13452                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
13453                                         diff[ name ] = value;
13454                                 }
13455                         }
13456                 }
13457         }
13458
13459         return diff;
13460 }
13461
13462 // support: jQuery <1.8
13463 if ( !$.fn.addBack ) {
13464         $.fn.addBack = function( selector ) {
13465                 return this.add( selector == null ?
13466                         this.prevObject : this.prevObject.filter( selector )
13467                 );
13468         };
13469 }
13470
13471 $.effects.animateClass = function( value, duration, easing, callback ) {
13472         var o = $.speed( duration, easing, callback );
13473
13474         return this.queue( function() {
13475                 var animated = $( this ),
13476                         baseClass = animated.attr( "class" ) || "",
13477                         applyClassChange,
13478                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
13479
13480                 // map the animated objects to store the original styles.
13481                 allAnimations = allAnimations.map(function() {
13482                         var el = $( this );
13483                         return {
13484                                 el: el,
13485                                 start: getElementStyles( this )
13486                         };
13487                 });
13488
13489                 // apply class change
13490                 applyClassChange = function() {
13491                         $.each( classAnimationActions, function(i, action) {
13492                                 if ( value[ action ] ) {
13493                                         animated[ action + "Class" ]( value[ action ] );
13494                                 }
13495                         });
13496                 };
13497                 applyClassChange();
13498
13499                 // map all animated objects again - calculate new styles and diff
13500                 allAnimations = allAnimations.map(function() {
13501                         this.end = getElementStyles( this.el[ 0 ] );
13502                         this.diff = styleDifference( this.start, this.end );
13503                         return this;
13504                 });
13505
13506                 // apply original class
13507                 animated.attr( "class", baseClass );
13508
13509                 // map all animated objects again - this time collecting a promise
13510                 allAnimations = allAnimations.map(function() {
13511                         var styleInfo = this,
13512                                 dfd = $.Deferred(),
13513                                 opts = $.extend({}, o, {
13514                                         queue: false,
13515                                         complete: function() {
13516                                                 dfd.resolve( styleInfo );
13517                                         }
13518                                 });
13519
13520                         this.el.animate( this.diff, opts );
13521                         return dfd.promise();
13522                 });
13523
13524                 // once all animations have completed:
13525                 $.when.apply( $, allAnimations.get() ).done(function() {
13526
13527                         // set the final class
13528                         applyClassChange();
13529
13530                         // for each animated element,
13531                         // clear all css properties that were animated
13532                         $.each( arguments, function() {
13533                                 var el = this.el;
13534                                 $.each( this.diff, function(key) {
13535                                         el.css( key, "" );
13536                                 });
13537                         });
13538
13539                         // this is guarnteed to be there if you use jQuery.speed()
13540                         // it also handles dequeuing the next anim...
13541                         o.complete.call( animated[ 0 ] );
13542                 });
13543         });
13544 };
13545
13546 $.fn.extend({
13547         addClass: (function( orig ) {
13548                 return function( classNames, speed, easing, callback ) {
13549                         return speed ?
13550                                 $.effects.animateClass.call( this,
13551                                         { add: classNames }, speed, easing, callback ) :
13552                                 orig.apply( this, arguments );
13553                 };
13554         })( $.fn.addClass ),
13555
13556         removeClass: (function( orig ) {
13557                 return function( classNames, speed, easing, callback ) {
13558                         return arguments.length > 1 ?
13559                                 $.effects.animateClass.call( this,
13560                                         { remove: classNames }, speed, easing, callback ) :
13561                                 orig.apply( this, arguments );
13562                 };
13563         })( $.fn.removeClass ),
13564
13565         toggleClass: (function( orig ) {
13566                 return function( classNames, force, speed, easing, callback ) {
13567                         if ( typeof force === "boolean" || force === undefined ) {
13568                                 if ( !speed ) {
13569                                         // without speed parameter
13570                                         return orig.apply( this, arguments );
13571                                 } else {
13572                                         return $.effects.animateClass.call( this,
13573                                                 (force ? { add: classNames } : { remove: classNames }),
13574                                                 speed, easing, callback );
13575                                 }
13576                         } else {
13577                                 // without force parameter
13578                                 return $.effects.animateClass.call( this,
13579                                         { toggle: classNames }, force, speed, easing );
13580                         }
13581                 };
13582         })( $.fn.toggleClass ),
13583
13584         switchClass: function( remove, add, speed, easing, callback) {
13585                 return $.effects.animateClass.call( this, {
13586                         add: add,
13587                         remove: remove
13588                 }, speed, easing, callback );
13589         }
13590 });
13591
13592 })();
13593
13594 /******************************************************************************/
13595 /*********************************** EFFECTS **********************************/
13596 /******************************************************************************/
13597
13598 (function() {
13599
13600 $.extend( $.effects, {
13601         version: "1.10.3",
13602
13603         // Saves a set of properties in a data storage
13604         save: function( element, set ) {
13605                 for( var i=0; i < set.length; i++ ) {
13606                         if ( set[ i ] !== null ) {
13607                                 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
13608                         }
13609                 }
13610         },
13611
13612         // Restores a set of previously saved properties from a data storage
13613         restore: function( element, set ) {
13614                 var val, i;
13615                 for( i=0; i < set.length; i++ ) {
13616                         if ( set[ i ] !== null ) {
13617                                 val = element.data( dataSpace + set[ i ] );
13618                                 // support: jQuery 1.6.2
13619                                 // http://bugs.jquery.com/ticket/9917
13620                                 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
13621                                 // We can't differentiate between "" and 0 here, so we just assume
13622                                 // empty string since it's likely to be a more common value...
13623                                 if ( val === undefined ) {
13624                                         val = "";
13625                                 }
13626                                 element.css( set[ i ], val );
13627                         }
13628                 }
13629         },
13630
13631         setMode: function( el, mode ) {
13632                 if (mode === "toggle") {
13633                         mode = el.is( ":hidden" ) ? "show" : "hide";
13634                 }
13635                 return mode;
13636         },
13637
13638         // Translates a [top,left] array into a baseline value
13639         // this should be a little more flexible in the future to handle a string & hash
13640         getBaseline: function( origin, original ) {
13641                 var y, x;
13642                 switch ( origin[ 0 ] ) {
13643                         case "top": y = 0; break;
13644                         case "middle": y = 0.5; break;
13645                         case "bottom": y = 1; break;
13646                         default: y = origin[ 0 ] / original.height;
13647                 }
13648                 switch ( origin[ 1 ] ) {
13649                         case "left": x = 0; break;
13650                         case "center": x = 0.5; break;
13651                         case "right": x = 1; break;
13652                         default: x = origin[ 1 ] / original.width;
13653                 }
13654                 return {
13655                         x: x,
13656                         y: y
13657                 };
13658         },
13659
13660         // Wraps the element around a wrapper that copies position properties
13661         createWrapper: function( element ) {
13662
13663                 // if the element is already wrapped, return it
13664                 if ( element.parent().is( ".ui-effects-wrapper" )) {
13665                         return element.parent();
13666                 }
13667
13668                 // wrap the element
13669                 var props = {
13670                                 width: element.outerWidth(true),
13671                                 height: element.outerHeight(true),
13672                                 "float": element.css( "float" )
13673                         },
13674                         wrapper = $( "<div></div>" )
13675                                 .addClass( "ui-effects-wrapper" )
13676                                 .css({
13677                                         fontSize: "100%",
13678                                         background: "transparent",
13679                                         border: "none",
13680                                         margin: 0,
13681                                         padding: 0
13682                                 }),
13683                         // Store the size in case width/height are defined in % - Fixes #5245
13684                         size = {
13685                                 width: element.width(),
13686                                 height: element.height()
13687                         },
13688                         active = document.activeElement;
13689
13690                 // support: Firefox
13691                 // Firefox incorrectly exposes anonymous content
13692                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
13693                 try {
13694                         active.id;
13695                 } catch( e ) {
13696                         active = document.body;
13697                 }
13698
13699                 element.wrap( wrapper );
13700
13701                 // Fixes #7595 - Elements lose focus when wrapped.
13702                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13703                         $( active ).focus();
13704                 }
13705
13706                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
13707
13708                 // transfer positioning properties to the wrapper
13709                 if ( element.css( "position" ) === "static" ) {
13710                         wrapper.css({ position: "relative" });
13711                         element.css({ position: "relative" });
13712                 } else {
13713                         $.extend( props, {
13714                                 position: element.css( "position" ),
13715                                 zIndex: element.css( "z-index" )
13716                         });
13717                         $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
13718                                 props[ pos ] = element.css( pos );
13719                                 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
13720                                         props[ pos ] = "auto";
13721                                 }
13722                         });
13723                         element.css({
13724                                 position: "relative",
13725                                 top: 0,
13726                                 left: 0,
13727                                 right: "auto",
13728                                 bottom: "auto"
13729                         });
13730                 }
13731                 element.css(size);
13732
13733                 return wrapper.css( props ).show();
13734         },
13735
13736         removeWrapper: function( element ) {
13737                 var active = document.activeElement;
13738
13739                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
13740                         element.parent().replaceWith( element );
13741
13742                         // Fixes #7595 - Elements lose focus when wrapped.
13743                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13744                                 $( active ).focus();
13745                         }
13746                 }
13747
13748
13749                 return element;
13750         },
13751
13752         setTransition: function( element, list, factor, value ) {
13753                 value = value || {};
13754                 $.each( list, function( i, x ) {
13755                         var unit = element.cssUnit( x );
13756                         if ( unit[ 0 ] > 0 ) {
13757                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
13758                         }
13759                 });
13760                 return value;
13761         }
13762 });
13763
13764 // return an effect options object for the given parameters:
13765 function _normalizeArguments( effect, options, speed, callback ) {
13766
13767         // allow passing all options as the first parameter
13768         if ( $.isPlainObject( effect ) ) {
13769                 options = effect;
13770                 effect = effect.effect;
13771         }
13772
13773         // convert to an object
13774         effect = { effect: effect };
13775
13776         // catch (effect, null, ...)
13777         if ( options == null ) {
13778                 options = {};
13779         }
13780
13781         // catch (effect, callback)
13782         if ( $.isFunction( options ) ) {
13783                 callback = options;
13784                 speed = null;
13785                 options = {};
13786         }
13787
13788         // catch (effect, speed, ?)
13789         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13790                 callback = speed;
13791                 speed = options;
13792                 options = {};
13793         }
13794
13795         // catch (effect, options, callback)
13796         if ( $.isFunction( speed ) ) {
13797                 callback = speed;
13798                 speed = null;
13799         }
13800
13801         // add options to effect
13802         if ( options ) {
13803                 $.extend( effect, options );
13804         }
13805
13806         speed = speed || options.duration;
13807         effect.duration = $.fx.off ? 0 :
13808                 typeof speed === "number" ? speed :
13809                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13810                 $.fx.speeds._default;
13811
13812         effect.complete = callback || options.complete;
13813
13814         return effect;
13815 }
13816
13817 function standardAnimationOption( option ) {
13818         // Valid standard speeds (nothing, number, named speed)
13819         if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
13820                 return true;
13821         }
13822
13823         // Invalid strings - treat as "normal" speed
13824         if ( typeof option === "string" && !$.effects.effect[ option ] ) {
13825                 return true;
13826         }
13827
13828         // Complete callback
13829         if ( $.isFunction( option ) ) {
13830                 return true;
13831         }
13832
13833         // Options hash (but not naming an effect)
13834         if ( typeof option === "object" && !option.effect ) {
13835                 return true;
13836         }
13837
13838         // Didn't match any standard API
13839         return false;
13840 }
13841
13842 $.fn.extend({
13843         effect: function( /* effect, options, speed, callback */ ) {
13844                 var args = _normalizeArguments.apply( this, arguments ),
13845                         mode = args.mode,
13846                         queue = args.queue,
13847                         effectMethod = $.effects.effect[ args.effect ];
13848
13849                 if ( $.fx.off || !effectMethod ) {
13850                         // delegate to the original method (e.g., .show()) if possible
13851                         if ( mode ) {
13852                                 return this[ mode ]( args.duration, args.complete );
13853                         } else {
13854                                 return this.each( function() {
13855                                         if ( args.complete ) {
13856                                                 args.complete.call( this );
13857                                         }
13858                                 });
13859                         }
13860                 }
13861
13862                 function run( next ) {
13863                         var elem = $( this ),
13864                                 complete = args.complete,
13865                                 mode = args.mode;
13866
13867                         function done() {
13868                                 if ( $.isFunction( complete ) ) {
13869                                         complete.call( elem[0] );
13870                                 }
13871                                 if ( $.isFunction( next ) ) {
13872                                         next();
13873                                 }
13874                         }
13875
13876                         // If the element already has the correct final state, delegate to
13877                         // the core methods so the internal tracking of "olddisplay" works.
13878                         if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13879                                 elem[ mode ]();
13880                                 done();
13881                         } else {
13882                                 effectMethod.call( elem[0], args, done );
13883                         }
13884                 }
13885
13886                 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
13887         },
13888
13889         show: (function( orig ) {
13890                 return function( option ) {
13891                         if ( standardAnimationOption( option ) ) {
13892                                 return orig.apply( this, arguments );
13893                         } else {
13894                                 var args = _normalizeArguments.apply( this, arguments );
13895                                 args.mode = "show";
13896                                 return this.effect.call( this, args );
13897                         }
13898                 };
13899         })( $.fn.show ),
13900
13901         hide: (function( orig ) {
13902                 return function( option ) {
13903                         if ( standardAnimationOption( option ) ) {
13904                                 return orig.apply( this, arguments );
13905                         } else {
13906                                 var args = _normalizeArguments.apply( this, arguments );
13907                                 args.mode = "hide";
13908                                 return this.effect.call( this, args );
13909                         }
13910                 };
13911         })( $.fn.hide ),
13912
13913         toggle: (function( orig ) {
13914                 return function( option ) {
13915                         if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
13916                                 return orig.apply( this, arguments );
13917                         } else {
13918                                 var args = _normalizeArguments.apply( this, arguments );
13919                                 args.mode = "toggle";
13920                                 return this.effect.call( this, args );
13921                         }
13922                 };
13923         })( $.fn.toggle ),
13924
13925         // helper functions
13926         cssUnit: function(key) {
13927                 var style = this.css( key ),
13928                         val = [];
13929
13930                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13931                         if ( style.indexOf( unit ) > 0 ) {
13932                                 val = [ parseFloat( style ), unit ];
13933                         }
13934                 });
13935                 return val;
13936         }
13937 });
13938
13939 })();
13940
13941 /******************************************************************************/
13942 /*********************************** EASING ***********************************/
13943 /******************************************************************************/
13944
13945 (function() {
13946
13947 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
13948
13949 var baseEasings = {};
13950
13951 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13952         baseEasings[ name ] = function( p ) {
13953                 return Math.pow( p, i + 2 );
13954         };
13955 });
13956
13957 $.extend( baseEasings, {
13958         Sine: function ( p ) {
13959                 return 1 - Math.cos( p * Math.PI / 2 );
13960         },
13961         Circ: function ( p ) {
13962                 return 1 - Math.sqrt( 1 - p * p );
13963         },
13964         Elastic: function( p ) {
13965                 return p === 0 || p === 1 ? p :
13966                         -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
13967         },
13968         Back: function( p ) {
13969                 return p * p * ( 3 * p - 2 );
13970         },
13971         Bounce: function ( p ) {
13972                 var pow2,
13973                         bounce = 4;
13974
13975                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
13976                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
13977         }
13978 });
13979
13980 $.each( baseEasings, function( name, easeIn ) {
13981         $.easing[ "easeIn" + name ] = easeIn;
13982         $.easing[ "easeOut" + name ] = function( p ) {
13983                 return 1 - easeIn( 1 - p );
13984         };
13985         $.easing[ "easeInOut" + name ] = function( p ) {
13986                 return p < 0.5 ?
13987                         easeIn( p * 2 ) / 2 :
13988                         1 - easeIn( p * -2 + 2 ) / 2;
13989         };
13990 });
13991
13992 })();
13993
13994 })(jQuery);
13995 (function( $, undefined ) {
13996
13997 var rvertical = /up|down|vertical/,
13998         rpositivemotion = /up|left|vertical|horizontal/;
13999
14000 $.effects.effect.blind = function( o, done ) {
14001         // Create element
14002         var el = $( this ),
14003                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14004                 mode = $.effects.setMode( el, o.mode || "hide" ),
14005                 direction = o.direction || "up",
14006                 vertical = rvertical.test( direction ),
14007                 ref = vertical ? "height" : "width",
14008                 ref2 = vertical ? "top" : "left",
14009                 motion = rpositivemotion.test( direction ),
14010                 animation = {},
14011                 show = mode === "show",
14012                 wrapper, distance, margin;
14013
14014         // if already wrapped, the wrapper's properties are my property. #6245
14015         if ( el.parent().is( ".ui-effects-wrapper" ) ) {
14016                 $.effects.save( el.parent(), props );
14017         } else {
14018                 $.effects.save( el, props );
14019         }
14020         el.show();
14021         wrapper = $.effects.createWrapper( el ).css({
14022                 overflow: "hidden"
14023         });
14024
14025         distance = wrapper[ ref ]();
14026         margin = parseFloat( wrapper.css( ref2 ) ) || 0;
14027
14028         animation[ ref ] = show ? distance : 0;
14029         if ( !motion ) {
14030                 el
14031                         .css( vertical ? "bottom" : "right", 0 )
14032                         .css( vertical ? "top" : "left", "auto" )
14033                         .css({ position: "absolute" });
14034
14035                 animation[ ref2 ] = show ? margin : distance + margin;
14036         }
14037
14038         // start at 0 if we are showing
14039         if ( show ) {
14040                 wrapper.css( ref, 0 );
14041                 if ( ! motion ) {
14042                         wrapper.css( ref2, margin + distance );
14043                 }
14044         }
14045
14046         // Animate
14047         wrapper.animate( animation, {
14048                 duration: o.duration,
14049                 easing: o.easing,
14050                 queue: false,
14051                 complete: function() {
14052                         if ( mode === "hide" ) {
14053                                 el.hide();
14054                         }
14055                         $.effects.restore( el, props );
14056                         $.effects.removeWrapper( el );
14057                         done();
14058                 }
14059         });
14060
14061 };
14062
14063 })(jQuery);
14064 (function( $, undefined ) {
14065
14066 $.effects.effect.bounce = function( o, done ) {
14067         var el = $( this ),
14068                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14069
14070                 // defaults:
14071                 mode = $.effects.setMode( el, o.mode || "effect" ),
14072                 hide = mode === "hide",
14073                 show = mode === "show",
14074                 direction = o.direction || "up",
14075                 distance = o.distance,
14076                 times = o.times || 5,
14077
14078                 // number of internal animations
14079                 anims = times * 2 + ( show || hide ? 1 : 0 ),
14080                 speed = o.duration / anims,
14081                 easing = o.easing,
14082
14083                 // utility:
14084                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14085                 motion = ( direction === "up" || direction === "left" ),
14086                 i,
14087                 upAnim,
14088                 downAnim,
14089
14090                 // we will need to re-assemble the queue to stack our animations in place
14091                 queue = el.queue(),
14092                 queuelen = queue.length;
14093
14094         // Avoid touching opacity to prevent clearType and PNG issues in IE
14095         if ( show || hide ) {
14096                 props.push( "opacity" );
14097         }
14098
14099         $.effects.save( el, props );
14100         el.show();
14101         $.effects.createWrapper( el ); // Create Wrapper
14102
14103         // default distance for the BIGGEST bounce is the outer Distance / 3
14104         if ( !distance ) {
14105                 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
14106         }
14107
14108         if ( show ) {
14109                 downAnim = { opacity: 1 };
14110                 downAnim[ ref ] = 0;
14111
14112                 // if we are showing, force opacity 0 and set the initial position
14113                 // then do the "first" animation
14114                 el.css( "opacity", 0 )
14115                         .css( ref, motion ? -distance * 2 : distance * 2 )
14116                         .animate( downAnim, speed, easing );
14117         }
14118
14119         // start at the smallest distance if we are hiding
14120         if ( hide ) {
14121                 distance = distance / Math.pow( 2, times - 1 );
14122         }
14123
14124         downAnim = {};
14125         downAnim[ ref ] = 0;
14126         // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
14127         for ( i = 0; i < times; i++ ) {
14128                 upAnim = {};
14129                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14130
14131                 el.animate( upAnim, speed, easing )
14132                         .animate( downAnim, speed, easing );
14133
14134                 distance = hide ? distance * 2 : distance / 2;
14135         }
14136
14137         // Last Bounce when Hiding
14138         if ( hide ) {
14139                 upAnim = { opacity: 0 };
14140                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14141
14142                 el.animate( upAnim, speed, easing );
14143         }
14144
14145         el.queue(function() {
14146                 if ( hide ) {
14147                         el.hide();
14148                 }
14149                 $.effects.restore( el, props );
14150                 $.effects.removeWrapper( el );
14151                 done();
14152         });
14153
14154         // inject all the animations we just queued to be first in line (after "inprogress")
14155         if ( queuelen > 1) {
14156                 queue.splice.apply( queue,
14157                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14158         }
14159         el.dequeue();
14160
14161 };
14162
14163 })(jQuery);
14164 (function( $, undefined ) {
14165
14166 $.effects.effect.clip = function( o, done ) {
14167         // Create element
14168         var el = $( this ),
14169                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14170                 mode = $.effects.setMode( el, o.mode || "hide" ),
14171                 show = mode === "show",
14172                 direction = o.direction || "vertical",
14173                 vert = direction === "vertical",
14174                 size = vert ? "height" : "width",
14175                 position = vert ? "top" : "left",
14176                 animation = {},
14177                 wrapper, animate, distance;
14178
14179         // Save & Show
14180         $.effects.save( el, props );
14181         el.show();
14182
14183         // Create Wrapper
14184         wrapper = $.effects.createWrapper( el ).css({
14185                 overflow: "hidden"
14186         });
14187         animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
14188         distance = animate[ size ]();
14189
14190         // Shift
14191         if ( show ) {
14192                 animate.css( size, 0 );
14193                 animate.css( position, distance / 2 );
14194         }
14195
14196         // Create Animation Object:
14197         animation[ size ] = show ? distance : 0;
14198         animation[ position ] = show ? 0 : distance / 2;
14199
14200         // Animate
14201         animate.animate( animation, {
14202                 queue: false,
14203                 duration: o.duration,
14204                 easing: o.easing,
14205                 complete: function() {
14206                         if ( !show ) {
14207                                 el.hide();
14208                         }
14209                         $.effects.restore( el, props );
14210                         $.effects.removeWrapper( el );
14211                         done();
14212                 }
14213         });
14214
14215 };
14216
14217 })(jQuery);
14218 (function( $, undefined ) {
14219
14220 $.effects.effect.drop = function( o, done ) {
14221
14222         var el = $( this ),
14223                 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
14224                 mode = $.effects.setMode( el, o.mode || "hide" ),
14225                 show = mode === "show",
14226                 direction = o.direction || "left",
14227                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14228                 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
14229                 animation = {
14230                         opacity: show ? 1 : 0
14231                 },
14232                 distance;
14233
14234         // Adjust
14235         $.effects.save( el, props );
14236         el.show();
14237         $.effects.createWrapper( el );
14238
14239         distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
14240
14241         if ( show ) {
14242                 el
14243                         .css( "opacity", 0 )
14244                         .css( ref, motion === "pos" ? -distance : distance );
14245         }
14246
14247         // Animation
14248         animation[ ref ] = ( show ?
14249                 ( motion === "pos" ? "+=" : "-=" ) :
14250                 ( motion === "pos" ? "-=" : "+=" ) ) +
14251                 distance;
14252
14253         // Animate
14254         el.animate( animation, {
14255                 queue: false,
14256                 duration: o.duration,
14257                 easing: o.easing,
14258                 complete: function() {
14259                         if ( mode === "hide" ) {
14260                                 el.hide();
14261                         }
14262                         $.effects.restore( el, props );
14263                         $.effects.removeWrapper( el );
14264                         done();
14265                 }
14266         });
14267 };
14268
14269 })(jQuery);
14270 (function( $, undefined ) {
14271
14272 $.effects.effect.explode = function( o, done ) {
14273
14274         var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
14275                 cells = rows,
14276                 el = $( this ),
14277                 mode = $.effects.setMode( el, o.mode || "hide" ),
14278                 show = mode === "show",
14279
14280                 // show and then visibility:hidden the element before calculating offset
14281                 offset = el.show().css( "visibility", "hidden" ).offset(),
14282
14283                 // width and height of a piece
14284                 width = Math.ceil( el.outerWidth() / cells ),
14285                 height = Math.ceil( el.outerHeight() / rows ),
14286                 pieces = [],
14287
14288                 // loop
14289                 i, j, left, top, mx, my;
14290
14291         // children animate complete:
14292         function childComplete() {
14293                 pieces.push( this );
14294                 if ( pieces.length === rows * cells ) {
14295                         animComplete();
14296                 }
14297         }
14298
14299         // clone the element for each row and cell.
14300         for( i = 0; i < rows ; i++ ) { // ===>
14301                 top = offset.top + i * height;
14302                 my = i - ( rows - 1 ) / 2 ;
14303
14304                 for( j = 0; j < cells ; j++ ) { // |||
14305                         left = offset.left + j * width;
14306                         mx = j - ( cells - 1 ) / 2 ;
14307
14308                         // Create a clone of the now hidden main element that will be absolute positioned
14309                         // within a wrapper div off the -left and -top equal to size of our pieces
14310                         el
14311                                 .clone()
14312                                 .appendTo( "body" )
14313                                 .wrap( "<div></div>" )
14314                                 .css({
14315                                         position: "absolute",
14316                                         visibility: "visible",
14317                                         left: -j * width,
14318                                         top: -i * height
14319                                 })
14320
14321                         // select the wrapper - make it overflow: hidden and absolute positioned based on
14322                         // where the original was located +left and +top equal to the size of pieces
14323                                 .parent()
14324                                 .addClass( "ui-effects-explode" )
14325                                 .css({
14326                                         position: "absolute",
14327                                         overflow: "hidden",
14328                                         width: width,
14329                                         height: height,
14330                                         left: left + ( show ? mx * width : 0 ),
14331                                         top: top + ( show ? my * height : 0 ),
14332                                         opacity: show ? 0 : 1
14333                                 }).animate({
14334                                         left: left + ( show ? 0 : mx * width ),
14335                                         top: top + ( show ? 0 : my * height ),
14336                                         opacity: show ? 1 : 0
14337                                 }, o.duration || 500, o.easing, childComplete );
14338                 }
14339         }
14340
14341         function animComplete() {
14342                 el.css({
14343                         visibility: "visible"
14344                 });
14345                 $( pieces ).remove();
14346                 if ( !show ) {
14347                         el.hide();
14348                 }
14349                 done();
14350         }
14351 };
14352
14353 })(jQuery);
14354 (function( $, undefined ) {
14355
14356 $.effects.effect.fade = function( o, done ) {
14357         var el = $( this ),
14358                 mode = $.effects.setMode( el, o.mode || "toggle" );
14359
14360         el.animate({
14361                 opacity: mode
14362         }, {
14363                 queue: false,
14364                 duration: o.duration,
14365                 easing: o.easing,
14366                 complete: done
14367         });
14368 };
14369
14370 })( jQuery );
14371 (function( $, undefined ) {
14372
14373 $.effects.effect.fold = function( o, done ) {
14374
14375         // Create element
14376         var el = $( this ),
14377                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14378                 mode = $.effects.setMode( el, o.mode || "hide" ),
14379                 show = mode === "show",
14380                 hide = mode === "hide",
14381                 size = o.size || 15,
14382                 percent = /([0-9]+)%/.exec( size ),
14383                 horizFirst = !!o.horizFirst,
14384                 widthFirst = show !== horizFirst,
14385                 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
14386                 duration = o.duration / 2,
14387                 wrapper, distance,
14388                 animation1 = {},
14389                 animation2 = {};
14390
14391         $.effects.save( el, props );
14392         el.show();
14393
14394         // Create Wrapper
14395         wrapper = $.effects.createWrapper( el ).css({
14396                 overflow: "hidden"
14397         });
14398         distance = widthFirst ?
14399                 [ wrapper.width(), wrapper.height() ] :
14400                 [ wrapper.height(), wrapper.width() ];
14401
14402         if ( percent ) {
14403                 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
14404         }
14405         if ( show ) {
14406                 wrapper.css( horizFirst ? {
14407                         height: 0,
14408                         width: size
14409                 } : {
14410                         height: size,
14411                         width: 0
14412                 });
14413         }
14414
14415         // Animation
14416         animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
14417         animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
14418
14419         // Animate
14420         wrapper
14421                 .animate( animation1, duration, o.easing )
14422                 .animate( animation2, duration, o.easing, function() {
14423                         if ( hide ) {
14424                                 el.hide();
14425                         }
14426                         $.effects.restore( el, props );
14427                         $.effects.removeWrapper( el );
14428                         done();
14429                 });
14430
14431 };
14432
14433 })(jQuery);
14434 (function( $, undefined ) {
14435
14436 $.effects.effect.highlight = function( o, done ) {
14437         var elem = $( this ),
14438                 props = [ "backgroundImage", "backgroundColor", "opacity" ],
14439                 mode = $.effects.setMode( elem, o.mode || "show" ),
14440                 animation = {
14441                         backgroundColor: elem.css( "backgroundColor" )
14442                 };
14443
14444         if (mode === "hide") {
14445                 animation.opacity = 0;
14446         }
14447
14448         $.effects.save( elem, props );
14449
14450         elem
14451                 .show()
14452                 .css({
14453                         backgroundImage: "none",
14454                         backgroundColor: o.color || "#ffff99"
14455                 })
14456                 .animate( animation, {
14457                         queue: false,
14458                         duration: o.duration,
14459                         easing: o.easing,
14460                         complete: function() {
14461                                 if ( mode === "hide" ) {
14462                                         elem.hide();
14463                                 }
14464                                 $.effects.restore( elem, props );
14465                                 done();
14466                         }
14467                 });
14468 };
14469
14470 })(jQuery);
14471 (function( $, undefined ) {
14472
14473 $.effects.effect.pulsate = function( o, done ) {
14474         var elem = $( this ),
14475                 mode = $.effects.setMode( elem, o.mode || "show" ),
14476                 show = mode === "show",
14477                 hide = mode === "hide",
14478                 showhide = ( show || mode === "hide" ),
14479
14480                 // showing or hiding leaves of the "last" animation
14481                 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
14482                 duration = o.duration / anims,
14483                 animateTo = 0,
14484                 queue = elem.queue(),
14485                 queuelen = queue.length,
14486                 i;
14487
14488         if ( show || !elem.is(":visible")) {
14489                 elem.css( "opacity", 0 ).show();
14490                 animateTo = 1;
14491         }
14492
14493         // anims - 1 opacity "toggles"
14494         for ( i = 1; i < anims; i++ ) {
14495                 elem.animate({
14496                         opacity: animateTo
14497                 }, duration, o.easing );
14498                 animateTo = 1 - animateTo;
14499         }
14500
14501         elem.animate({
14502                 opacity: animateTo
14503         }, duration, o.easing);
14504
14505         elem.queue(function() {
14506                 if ( hide ) {
14507                         elem.hide();
14508                 }
14509                 done();
14510         });
14511
14512         // We just queued up "anims" animations, we need to put them next in the queue
14513         if ( queuelen > 1 ) {
14514                 queue.splice.apply( queue,
14515                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14516         }
14517         elem.dequeue();
14518 };
14519
14520 })(jQuery);
14521 (function( $, undefined ) {
14522
14523 $.effects.effect.puff = function( o, done ) {
14524         var elem = $( this ),
14525                 mode = $.effects.setMode( elem, o.mode || "hide" ),
14526                 hide = mode === "hide",
14527                 percent = parseInt( o.percent, 10 ) || 150,
14528                 factor = percent / 100,
14529                 original = {
14530                         height: elem.height(),
14531                         width: elem.width(),
14532                         outerHeight: elem.outerHeight(),
14533                         outerWidth: elem.outerWidth()
14534                 };
14535
14536         $.extend( o, {
14537                 effect: "scale",
14538                 queue: false,
14539                 fade: true,
14540                 mode: mode,
14541                 complete: done,
14542                 percent: hide ? percent : 100,
14543                 from: hide ?
14544                         original :
14545                         {
14546                                 height: original.height * factor,
14547                                 width: original.width * factor,
14548                                 outerHeight: original.outerHeight * factor,
14549                                 outerWidth: original.outerWidth * factor
14550                         }
14551         });
14552
14553         elem.effect( o );
14554 };
14555
14556 $.effects.effect.scale = function( o, done ) {
14557
14558         // Create element
14559         var el = $( this ),
14560                 options = $.extend( true, {}, o ),
14561                 mode = $.effects.setMode( el, o.mode || "effect" ),
14562                 percent = parseInt( o.percent, 10 ) ||
14563                         ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
14564                 direction = o.direction || "both",
14565                 origin = o.origin,
14566                 original = {
14567                         height: el.height(),
14568                         width: el.width(),
14569                         outerHeight: el.outerHeight(),
14570                         outerWidth: el.outerWidth()
14571                 },
14572                 factor = {
14573                         y: direction !== "horizontal" ? (percent / 100) : 1,
14574                         x: direction !== "vertical" ? (percent / 100) : 1
14575                 };
14576
14577         // We are going to pass this effect to the size effect:
14578         options.effect = "size";
14579         options.queue = false;
14580         options.complete = done;
14581
14582         // Set default origin and restore for show/hide
14583         if ( mode !== "effect" ) {
14584                 options.origin = origin || ["middle","center"];
14585                 options.restore = true;
14586         }
14587
14588         options.from = o.from || ( mode === "show" ? {
14589                 height: 0,
14590                 width: 0,
14591                 outerHeight: 0,
14592                 outerWidth: 0
14593         } : original );
14594         options.to = {
14595                 height: original.height * factor.y,
14596                 width: original.width * factor.x,
14597                 outerHeight: original.outerHeight * factor.y,
14598                 outerWidth: original.outerWidth * factor.x
14599         };
14600
14601         // Fade option to support puff
14602         if ( options.fade ) {
14603                 if ( mode === "show" ) {
14604                         options.from.opacity = 0;
14605                         options.to.opacity = 1;
14606                 }
14607                 if ( mode === "hide" ) {
14608                         options.from.opacity = 1;
14609                         options.to.opacity = 0;
14610                 }
14611         }
14612
14613         // Animate
14614         el.effect( options );
14615
14616 };
14617
14618 $.effects.effect.size = function( o, done ) {
14619
14620         // Create element
14621         var original, baseline, factor,
14622                 el = $( this ),
14623                 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
14624
14625                 // Always restore
14626                 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
14627
14628                 // Copy for children
14629                 props2 = [ "width", "height", "overflow" ],
14630                 cProps = [ "fontSize" ],
14631                 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
14632                 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
14633
14634                 // Set options
14635                 mode = $.effects.setMode( el, o.mode || "effect" ),
14636                 restore = o.restore || mode !== "effect",
14637                 scale = o.scale || "both",
14638                 origin = o.origin || [ "middle", "center" ],
14639                 position = el.css( "position" ),
14640                 props = restore ? props0 : props1,
14641                 zero = {
14642                         height: 0,
14643                         width: 0,
14644                         outerHeight: 0,
14645                         outerWidth: 0
14646                 };
14647
14648         if ( mode === "show" ) {
14649                 el.show();
14650         }
14651         original = {
14652                 height: el.height(),
14653                 width: el.width(),
14654                 outerHeight: el.outerHeight(),
14655                 outerWidth: el.outerWidth()
14656         };
14657
14658         if ( o.mode === "toggle" && mode === "show" ) {
14659                 el.from = o.to || zero;
14660                 el.to = o.from || original;
14661         } else {
14662                 el.from = o.from || ( mode === "show" ? zero : original );
14663                 el.to = o.to || ( mode === "hide" ? zero : original );
14664         }
14665
14666         // Set scaling factor
14667         factor = {
14668                 from: {
14669                         y: el.from.height / original.height,
14670                         x: el.from.width / original.width
14671                 },
14672                 to: {
14673                         y: el.to.height / original.height,
14674                         x: el.to.width / original.width
14675                 }
14676         };
14677
14678         // Scale the css box
14679         if ( scale === "box" || scale === "both" ) {
14680
14681                 // Vertical props scaling
14682                 if ( factor.from.y !== factor.to.y ) {
14683                         props = props.concat( vProps );
14684                         el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
14685                         el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
14686                 }
14687
14688                 // Horizontal props scaling
14689                 if ( factor.from.x !== factor.to.x ) {
14690                         props = props.concat( hProps );
14691                         el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
14692                         el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
14693                 }
14694         }
14695
14696         // Scale the content
14697         if ( scale === "content" || scale === "both" ) {
14698
14699                 // Vertical props scaling
14700                 if ( factor.from.y !== factor.to.y ) {
14701                         props = props.concat( cProps ).concat( props2 );
14702                         el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
14703                         el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
14704                 }
14705         }
14706
14707         $.effects.save( el, props );
14708         el.show();
14709         $.effects.createWrapper( el );
14710         el.css( "overflow", "hidden" ).css( el.from );
14711
14712         // Adjust
14713         if (origin) { // Calculate baseline shifts
14714                 baseline = $.effects.getBaseline( origin, original );
14715                 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
14716                 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
14717                 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
14718                 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
14719         }
14720         el.css( el.from ); // set top & left
14721
14722         // Animate
14723         if ( scale === "content" || scale === "both" ) { // Scale the children
14724
14725                 // Add margins/font-size
14726                 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
14727                 hProps = hProps.concat([ "marginLeft", "marginRight" ]);
14728                 props2 = props0.concat(vProps).concat(hProps);
14729
14730                 el.find( "*[width]" ).each( function(){
14731                         var child = $( this ),
14732                                 c_original = {
14733                                         height: child.height(),
14734                                         width: child.width(),
14735                                         outerHeight: child.outerHeight(),
14736                                         outerWidth: child.outerWidth()
14737                                 };
14738                         if (restore) {
14739                                 $.effects.save(child, props2);
14740                         }
14741
14742                         child.from = {
14743                                 height: c_original.height * factor.from.y,
14744                                 width: c_original.width * factor.from.x,
14745                                 outerHeight: c_original.outerHeight * factor.from.y,
14746                                 outerWidth: c_original.outerWidth * factor.from.x
14747                         };
14748                         child.to = {
14749                                 height: c_original.height * factor.to.y,
14750                                 width: c_original.width * factor.to.x,
14751                                 outerHeight: c_original.height * factor.to.y,
14752                                 outerWidth: c_original.width * factor.to.x
14753                         };
14754
14755                         // Vertical props scaling
14756                         if ( factor.from.y !== factor.to.y ) {
14757                                 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
14758                                 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
14759                         }
14760
14761                         // Horizontal props scaling
14762                         if ( factor.from.x !== factor.to.x ) {
14763                                 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
14764                                 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
14765                         }
14766
14767                         // Animate children
14768                         child.css( child.from );
14769                         child.animate( child.to, o.duration, o.easing, function() {
14770
14771                                 // Restore children
14772                                 if ( restore ) {
14773                                         $.effects.restore( child, props2 );
14774                                 }
14775                         });
14776                 });
14777         }
14778
14779         // Animate
14780         el.animate( el.to, {
14781                 queue: false,
14782                 duration: o.duration,
14783                 easing: o.easing,
14784                 complete: function() {
14785                         if ( el.to.opacity === 0 ) {
14786                                 el.css( "opacity", el.from.opacity );
14787                         }
14788                         if( mode === "hide" ) {
14789                                 el.hide();
14790                         }
14791                         $.effects.restore( el, props );
14792                         if ( !restore ) {
14793
14794                                 // we need to calculate our new positioning based on the scaling
14795                                 if ( position === "static" ) {
14796                                         el.css({
14797                                                 position: "relative",
14798                                                 top: el.to.top,
14799                                                 left: el.to.left
14800                                         });
14801                                 } else {
14802                                         $.each([ "top", "left" ], function( idx, pos ) {
14803                                                 el.css( pos, function( _, str ) {
14804                                                         var val = parseInt( str, 10 ),
14805                                                                 toRef = idx ? el.to.left : el.to.top;
14806
14807                                                         // if original was "auto", recalculate the new value from wrapper
14808                                                         if ( str === "auto" ) {
14809                                                                 return toRef + "px";
14810                                                         }
14811
14812                                                         return val + toRef + "px";
14813                                                 });
14814                                         });
14815                                 }
14816                         }
14817
14818                         $.effects.removeWrapper( el );
14819                         done();
14820                 }
14821         });
14822
14823 };
14824
14825 })(jQuery);
14826 (function( $, undefined ) {
14827
14828 $.effects.effect.shake = function( o, done ) {
14829
14830         var el = $( this ),
14831                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14832                 mode = $.effects.setMode( el, o.mode || "effect" ),
14833                 direction = o.direction || "left",
14834                 distance = o.distance || 20,
14835                 times = o.times || 3,
14836                 anims = times * 2 + 1,
14837                 speed = Math.round(o.duration/anims),
14838                 ref = (direction === "up" || direction === "down") ? "top" : "left",
14839                 positiveMotion = (direction === "up" || direction === "left"),
14840                 animation = {},
14841                 animation1 = {},
14842                 animation2 = {},
14843                 i,
14844
14845                 // we will need to re-assemble the queue to stack our animations in place
14846                 queue = el.queue(),
14847                 queuelen = queue.length;
14848
14849         $.effects.save( el, props );
14850         el.show();
14851         $.effects.createWrapper( el );
14852
14853         // Animation
14854         animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
14855         animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
14856         animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
14857
14858         // Animate
14859         el.animate( animation, speed, o.easing );
14860
14861         // Shakes
14862         for ( i = 1; i < times; i++ ) {
14863                 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
14864         }
14865         el
14866                 .animate( animation1, speed, o.easing )
14867                 .animate( animation, speed / 2, o.easing )
14868                 .queue(function() {
14869                         if ( mode === "hide" ) {
14870                                 el.hide();
14871                         }
14872                         $.effects.restore( el, props );
14873                         $.effects.removeWrapper( el );
14874                         done();
14875                 });
14876
14877         // inject all the animations we just queued to be first in line (after "inprogress")
14878         if ( queuelen > 1) {
14879                 queue.splice.apply( queue,
14880                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14881         }
14882         el.dequeue();
14883
14884 };
14885
14886 })(jQuery);
14887 (function( $, undefined ) {
14888
14889 $.effects.effect.slide = function( o, done ) {
14890
14891         // Create element
14892         var el = $( this ),
14893                 props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
14894                 mode = $.effects.setMode( el, o.mode || "show" ),
14895                 show = mode === "show",
14896                 direction = o.direction || "left",
14897                 ref = (direction === "up" || direction === "down") ? "top" : "left",
14898                 positiveMotion = (direction === "up" || direction === "left"),
14899                 distance,
14900                 animation = {};
14901
14902         // Adjust
14903         $.effects.save( el, props );
14904         el.show();
14905         distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
14906
14907         $.effects.createWrapper( el ).css({
14908                 overflow: "hidden"
14909         });
14910
14911         if ( show ) {
14912                 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
14913         }
14914
14915         // Animation
14916         animation[ ref ] = ( show ?
14917                 ( positiveMotion ? "+=" : "-=") :
14918                 ( positiveMotion ? "-=" : "+=")) +
14919                 distance;
14920
14921         // Animate
14922         el.animate( animation, {
14923                 queue: false,
14924                 duration: o.duration,
14925                 easing: o.easing,
14926                 complete: function() {
14927                         if ( mode === "hide" ) {
14928                                 el.hide();
14929                         }
14930                         $.effects.restore( el, props );
14931                         $.effects.removeWrapper( el );
14932                         done();
14933                 }
14934         });
14935 };
14936
14937 })(jQuery);
14938 (function( $, undefined ) {
14939
14940 $.effects.effect.transfer = function( o, done ) {
14941         var elem = $( this ),
14942                 target = $( o.to ),
14943                 targetFixed = target.css( "position" ) === "fixed",
14944                 body = $("body"),
14945                 fixTop = targetFixed ? body.scrollTop() : 0,
14946                 fixLeft = targetFixed ? body.scrollLeft() : 0,
14947                 endPosition = target.offset(),
14948                 animation = {
14949                         top: endPosition.top - fixTop ,
14950                         left: endPosition.left - fixLeft ,
14951                         height: target.innerHeight(),
14952                         width: target.innerWidth()
14953                 },
14954                 startPosition = elem.offset(),
14955                 transfer = $( "<div class='ui-effects-transfer'></div>" )
14956                         .appendTo( document.body )
14957                         .addClass( o.className )
14958                         .css({
14959                                 top: startPosition.top - fixTop ,
14960                                 left: startPosition.left - fixLeft ,
14961                                 height: elem.innerHeight(),
14962                                 width: elem.innerWidth(),
14963                                 position: targetFixed ? "fixed" : "absolute"
14964                         })
14965                         .animate( animation, o.duration, o.easing, function() {
14966                                 transfer.remove();
14967                                 done();
14968                         });
14969 };
14970
14971 })(jQuery);

UCC git Repository :: git.ucc.asn.au