Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / static / fusion / js / layout / jquery-ui-latest.js
1 /*! jQuery UI - v1.9.2 - 2012-11-23
2 * http://jqueryui.com
3 * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.draggable.js, jquery.ui.droppable.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, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.slider.js, jquery.ui.sortable.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
4 * Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
5
6 (function( $, undefined ) {
7
8 var uuid = 0,
9         runiqueId = /^ui-id-\d+$/;
10
11 // prevent duplicate loading
12 // this is only a problem because we proxy existing functions
13 // and we don't want to double proxy them
14 $.ui = $.ui || {};
15 if ( $.ui.version ) {
16         return;
17 }
18
19 $.extend( $.ui, {
20         version: "1.9.2",
21
22         keyCode: {
23                 BACKSPACE: 8,
24                 COMMA: 188,
25                 DELETE: 46,
26                 DOWN: 40,
27                 END: 35,
28                 ENTER: 13,
29                 ESCAPE: 27,
30                 HOME: 36,
31                 LEFT: 37,
32                 NUMPAD_ADD: 107,
33                 NUMPAD_DECIMAL: 110,
34                 NUMPAD_DIVIDE: 111,
35                 NUMPAD_ENTER: 108,
36                 NUMPAD_MULTIPLY: 106,
37                 NUMPAD_SUBTRACT: 109,
38                 PAGE_DOWN: 34,
39                 PAGE_UP: 33,
40                 PERIOD: 190,
41                 RIGHT: 39,
42                 SPACE: 32,
43                 TAB: 9,
44                 UP: 38
45         }
46 });
47
48 // plugins
49 $.fn.extend({
50         _focus: $.fn.focus,
51         focus: function( delay, fn ) {
52                 return typeof delay === "number" ?
53                         this.each(function() {
54                                 var elem = this;
55                                 setTimeout(function() {
56                                         $( elem ).focus();
57                                         if ( fn ) {
58                                                 fn.call( elem );
59                                         }
60                                 }, delay );
61                         }) :
62                         this._focus.apply( this, arguments );
63         },
64
65         scrollParent: function() {
66                 var scrollParent;
67                 if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
68                         scrollParent = this.parents().filter(function() {
69                                 return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
70                         }).eq(0);
71                 } else {
72                         scrollParent = this.parents().filter(function() {
73                                 return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
74                         }).eq(0);
75                 }
76
77                 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
78         },
79
80         zIndex: function( zIndex ) {
81                 if ( zIndex !== undefined ) {
82                         return this.css( "zIndex", zIndex );
83                 }
84
85                 if ( this.length ) {
86                         var elem = $( this[ 0 ] ), position, value;
87                         while ( elem.length && elem[ 0 ] !== document ) {
88                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
89                                 // This makes behavior of this function consistent across browsers
90                                 // WebKit always returns auto if the element is positioned
91                                 position = elem.css( "position" );
92                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
93                                         // IE returns 0 when zIndex is not specified
94                                         // other browsers return a string
95                                         // we ignore the case of nested elements with an explicit value of 0
96                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
97                                         value = parseInt( elem.css( "zIndex" ), 10 );
98                                         if ( !isNaN( value ) && value !== 0 ) {
99                                                 return value;
100                                         }
101                                 }
102                                 elem = elem.parent();
103                         }
104                 }
105
106                 return 0;
107         },
108
109         uniqueId: function() {
110                 return this.each(function() {
111                         if ( !this.id ) {
112                                 this.id = "ui-id-" + (++uuid);
113                         }
114                 });
115         },
116
117         removeUniqueId: function() {
118                 return this.each(function() {
119                         if ( runiqueId.test( this.id ) ) {
120                                 $( this ).removeAttr( "id" );
121                         }
122                 });
123         }
124 });
125
126 // selectors
127 function focusable( element, isTabIndexNotNaN ) {
128         var map, mapName, img,
129                 nodeName = element.nodeName.toLowerCase();
130         if ( "area" === nodeName ) {
131                 map = element.parentNode;
132                 mapName = map.name;
133                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
134                         return false;
135                 }
136                 img = $( "img[usemap=#" + mapName + "]" )[0];
137                 return !!img && visible( img );
138         }
139         return ( /input|select|textarea|button|object/.test( nodeName ) ?
140                 !element.disabled :
141                 "a" === nodeName ?
142                         element.href || isTabIndexNotNaN :
143                         isTabIndexNotNaN) &&
144                 // the element and all of its ancestors must be visible
145                 visible( element );
146 }
147
148 function visible( element ) {
149         return $.expr.filters.visible( element ) &&
150                 !$( element ).parents().andSelf().filter(function() {
151                         return $.css( this, "visibility" ) === "hidden";
152                 }).length;
153 }
154
155 $.extend( $.expr[ ":" ], {
156         data: $.expr.createPseudo ?
157                 $.expr.createPseudo(function( dataName ) {
158                         return function( elem ) {
159                                 return !!$.data( elem, dataName );
160                         };
161                 }) :
162                 // support: jQuery <1.8
163                 function( elem, i, match ) {
164                         return !!$.data( elem, match[ 3 ] );
165                 },
166
167         focusable: function( element ) {
168                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
169         },
170
171         tabbable: function( element ) {
172                 var tabIndex = $.attr( element, "tabindex" ),
173                         isTabIndexNaN = isNaN( tabIndex );
174                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
175         }
176 });
177
178 // support
179 $(function() {
180         var body = document.body,
181                 div = body.appendChild( div = document.createElement( "div" ) );
182
183         // access offsetHeight before setting the style to prevent a layout bug
184         // in IE 9 which causes the element to continue to take up space even
185         // after it is removed from the DOM (#8026)
186         div.offsetHeight;
187
188         $.extend( div.style, {
189                 minHeight: "100px",
190                 height: "auto",
191                 padding: 0,
192                 borderWidth: 0
193         });
194
195         $.support.minHeight = div.offsetHeight === 100;
196         $.support.selectstart = "onselectstart" in div;
197
198         // set display to none to avoid a layout bug in IE
199         // http://dev.jquery.com/ticket/4014
200         body.removeChild( div ).style.display = "none";
201 });
202
203 // support: jQuery <1.8
204 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
205         $.each( [ "Width", "Height" ], function( i, name ) {
206                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
207                         type = name.toLowerCase(),
208                         orig = {
209                                 innerWidth: $.fn.innerWidth,
210                                 innerHeight: $.fn.innerHeight,
211                                 outerWidth: $.fn.outerWidth,
212                                 outerHeight: $.fn.outerHeight
213                         };
214
215                 function reduce( elem, size, border, margin ) {
216                         $.each( side, function() {
217                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
218                                 if ( border ) {
219                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
220                                 }
221                                 if ( margin ) {
222                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
223                                 }
224                         });
225                         return size;
226                 }
227
228                 $.fn[ "inner" + name ] = function( size ) {
229                         if ( size === undefined ) {
230                                 return orig[ "inner" + name ].call( this );
231                         }
232
233                         return this.each(function() {
234                                 $( this ).css( type, reduce( this, size ) + "px" );
235                         });
236                 };
237
238                 $.fn[ "outer" + name] = function( size, margin ) {
239                         if ( typeof size !== "number" ) {
240                                 return orig[ "outer" + name ].call( this, size );
241                         }
242
243                         return this.each(function() {
244                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
245                         });
246                 };
247         });
248 }
249
250 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
251 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
252         $.fn.removeData = (function( removeData ) {
253                 return function( key ) {
254                         if ( arguments.length ) {
255                                 return removeData.call( this, $.camelCase( key ) );
256                         } else {
257                                 return removeData.call( this );
258                         }
259                 };
260         })( $.fn.removeData );
261 }
262
263
264
265
266
267 // deprecated
268
269 (function() {
270         var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
271         $.ui.ie = uaMatch.length ? true : false;
272         $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
273 })();
274
275 $.fn.extend({
276         disableSelection: function() {
277                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
278                         ".ui-disableSelection", function( event ) {
279                                 event.preventDefault();
280                         });
281         },
282
283         enableSelection: function() {
284                 return this.unbind( ".ui-disableSelection" );
285         }
286 });
287
288 $.extend( $.ui, {
289         // $.ui.plugin is deprecated.  Use the proxy pattern instead.
290         plugin: {
291                 add: function( module, option, set ) {
292                         var i,
293                                 proto = $.ui[ module ].prototype;
294                         for ( i in set ) {
295                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
296                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
297                         }
298                 },
299                 call: function( instance, name, args ) {
300                         var i,
301                                 set = instance.plugins[ name ];
302                         if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
303                                 return;
304                         }
305
306                         for ( i = 0; i < set.length; i++ ) {
307                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
308                                         set[ i ][ 1 ].apply( instance.element, args );
309                                 }
310                         }
311                 }
312         },
313
314         contains: $.contains,
315
316         // only used by resizable
317         hasScroll: function( el, a ) {
318
319                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
320                 if ( $( el ).css( "overflow" ) === "hidden") {
321                         return false;
322                 }
323
324                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
325                         has = false;
326
327                 if ( el[ scroll ] > 0 ) {
328                         return true;
329                 }
330
331                 // TODO: determine which cases actually cause this to happen
332                 // if the element doesn't have the scroll set, see if it's possible to
333                 // set the scroll
334                 el[ scroll ] = 1;
335                 has = ( el[ scroll ] > 0 );
336                 el[ scroll ] = 0;
337                 return has;
338         },
339
340         // these are odd functions, fix the API or move into individual plugins
341         isOverAxis: function( x, reference, size ) {
342                 //Determines when x coordinate is over "b" element axis
343                 return ( x > reference ) && ( x < ( reference + size ) );
344         },
345         isOver: function( y, x, top, left, height, width ) {
346                 //Determines when x, y coordinates is over "b" element
347                 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
348         }
349 });
350
351 })( jQuery );
352 (function( $, undefined ) {
353
354 var uuid = 0,
355         slice = Array.prototype.slice,
356         _cleanData = $.cleanData;
357 $.cleanData = function( elems ) {
358         for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
359                 try {
360                         $( elem ).triggerHandler( "remove" );
361                 // http://bugs.jquery.com/ticket/8235
362                 } catch( e ) {}
363         }
364         _cleanData( elems );
365 };
366
367 $.widget = function( name, base, prototype ) {
368         var fullName, existingConstructor, constructor, basePrototype,
369                 namespace = name.split( "." )[ 0 ];
370
371         name = name.split( "." )[ 1 ];
372         fullName = namespace + "-" + name;
373
374         if ( !prototype ) {
375                 prototype = base;
376                 base = $.Widget;
377         }
378
379         // create selector for plugin
380         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
381                 return !!$.data( elem, fullName );
382         };
383
384         $[ namespace ] = $[ namespace ] || {};
385         existingConstructor = $[ namespace ][ name ];
386         constructor = $[ namespace ][ name ] = function( options, element ) {
387                 // allow instantiation without "new" keyword
388                 if ( !this._createWidget ) {
389                         return new constructor( options, element );
390                 }
391
392                 // allow instantiation without initializing for simple inheritance
393                 // must use "new" keyword (the code above always passes args)
394                 if ( arguments.length ) {
395                         this._createWidget( options, element );
396                 }
397         };
398         // extend with the existing constructor to carry over any static properties
399         $.extend( constructor, existingConstructor, {
400                 version: prototype.version,
401                 // copy the object used to create the prototype in case we need to
402                 // redefine the widget later
403                 _proto: $.extend( {}, prototype ),
404                 // track widgets that inherit from this widget in case this widget is
405                 // redefined after a widget inherits from it
406                 _childConstructors: []
407         });
408
409         basePrototype = new base();
410         // we need to make the options hash a property directly on the new instance
411         // otherwise we'll modify the options hash on the prototype that we're
412         // inheriting from
413         basePrototype.options = $.widget.extend( {}, basePrototype.options );
414         $.each( prototype, function( prop, value ) {
415                 if ( $.isFunction( value ) ) {
416                         prototype[ prop ] = (function() {
417                                 var _super = function() {
418                                                 return base.prototype[ prop ].apply( this, arguments );
419                                         },
420                                         _superApply = function( args ) {
421                                                 return base.prototype[ prop ].apply( this, args );
422                                         };
423                                 return function() {
424                                         var __super = this._super,
425                                                 __superApply = this._superApply,
426                                                 returnValue;
427
428                                         this._super = _super;
429                                         this._superApply = _superApply;
430
431                                         returnValue = value.apply( this, arguments );
432
433                                         this._super = __super;
434                                         this._superApply = __superApply;
435
436                                         return returnValue;
437                                 };
438                         })();
439                 }
440         });
441         constructor.prototype = $.widget.extend( basePrototype, {
442                 // TODO: remove support for widgetEventPrefix
443                 // always use the name + a colon as the prefix, e.g., draggable:start
444                 // don't prefix for widgets that aren't DOM-based
445                 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
446         }, prototype, {
447                 constructor: constructor,
448                 namespace: namespace,
449                 widgetName: name,
450                 // TODO remove widgetBaseClass, see #8155
451                 widgetBaseClass: fullName,
452                 widgetFullName: fullName
453         });
454
455         // If this widget is being redefined then we need to find all widgets that
456         // are inheriting from it and redefine all of them so that they inherit from
457         // the new version of this widget. We're essentially trying to replace one
458         // level in the prototype chain.
459         if ( existingConstructor ) {
460                 $.each( existingConstructor._childConstructors, function( i, child ) {
461                         var childPrototype = child.prototype;
462
463                         // redefine the child widget using the same prototype that was
464                         // originally used, but inherit from the new version of the base
465                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
466                 });
467                 // remove the list of existing child constructors from the old constructor
468                 // so the old child constructors can be garbage collected
469                 delete existingConstructor._childConstructors;
470         } else {
471                 base._childConstructors.push( constructor );
472         }
473
474         $.widget.bridge( name, constructor );
475 };
476
477 $.widget.extend = function( target ) {
478         var input = slice.call( arguments, 1 ),
479                 inputIndex = 0,
480                 inputLength = input.length,
481                 key,
482                 value;
483         for ( ; inputIndex < inputLength; inputIndex++ ) {
484                 for ( key in input[ inputIndex ] ) {
485                         value = input[ inputIndex ][ key ];
486                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
487                                 // Clone objects
488                                 if ( $.isPlainObject( value ) ) {
489                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
490                                                 $.widget.extend( {}, target[ key ], value ) :
491                                                 // Don't extend strings, arrays, etc. with objects
492                                                 $.widget.extend( {}, value );
493                                 // Copy everything else by reference
494                                 } else {
495                                         target[ key ] = value;
496                                 }
497                         }
498                 }
499         }
500         return target;
501 };
502
503 $.widget.bridge = function( name, object ) {
504         var fullName = object.prototype.widgetFullName || name;
505         $.fn[ name ] = function( options ) {
506                 var isMethodCall = typeof options === "string",
507                         args = slice.call( arguments, 1 ),
508                         returnValue = this;
509
510                 // allow multiple hashes to be passed on init
511                 options = !isMethodCall && args.length ?
512                         $.widget.extend.apply( null, [ options ].concat(args) ) :
513                         options;
514
515                 if ( isMethodCall ) {
516                         this.each(function() {
517                                 var methodValue,
518                                         instance = $.data( this, fullName );
519                                 if ( !instance ) {
520                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
521                                                 "attempted to call method '" + options + "'" );
522                                 }
523                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
524                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
525                                 }
526                                 methodValue = instance[ options ].apply( instance, args );
527                                 if ( methodValue !== instance && methodValue !== undefined ) {
528                                         returnValue = methodValue && methodValue.jquery ?
529                                                 returnValue.pushStack( methodValue.get() ) :
530                                                 methodValue;
531                                         return false;
532                                 }
533                         });
534                 } else {
535                         this.each(function() {
536                                 var instance = $.data( this, fullName );
537                                 if ( instance ) {
538                                         instance.option( options || {} )._init();
539                                 } else {
540                                         $.data( this, fullName, new object( options, this ) );
541                                 }
542                         });
543                 }
544
545                 return returnValue;
546         };
547 };
548
549 $.Widget = function( /* options, element */ ) {};
550 $.Widget._childConstructors = [];
551
552 $.Widget.prototype = {
553         widgetName: "widget",
554         widgetEventPrefix: "",
555         defaultElement: "<div>",
556         options: {
557                 disabled: false,
558
559                 // callbacks
560                 create: null
561         },
562         _createWidget: function( options, element ) {
563                 element = $( element || this.defaultElement || this )[ 0 ];
564                 this.element = $( element );
565                 this.uuid = uuid++;
566                 this.eventNamespace = "." + this.widgetName + this.uuid;
567                 this.options = $.widget.extend( {},
568                         this.options,
569                         this._getCreateOptions(),
570                         options );
571
572                 this.bindings = $();
573                 this.hoverable = $();
574                 this.focusable = $();
575
576                 if ( element !== this ) {
577                         // 1.9 BC for #7810
578                         // TODO remove dual storage
579                         $.data( element, this.widgetName, this );
580                         $.data( element, this.widgetFullName, this );
581                         this._on( true, this.element, {
582                                 remove: function( event ) {
583                                         if ( event.target === element ) {
584                                                 this.destroy();
585                                         }
586                                 }
587                         });
588                         this.document = $( element.style ?
589                                 // element within the document
590                                 element.ownerDocument :
591                                 // element is window or document
592                                 element.document || element );
593                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
594                 }
595
596                 this._create();
597                 this._trigger( "create", null, this._getCreateEventData() );
598                 this._init();
599         },
600         _getCreateOptions: $.noop,
601         _getCreateEventData: $.noop,
602         _create: $.noop,
603         _init: $.noop,
604
605         destroy: function() {
606                 this._destroy();
607                 // we can probably remove the unbind calls in 2.0
608                 // all event bindings should go through this._on()
609                 this.element
610                         .unbind( this.eventNamespace )
611                         // 1.9 BC for #7810
612                         // TODO remove dual storage
613                         .removeData( this.widgetName )
614                         .removeData( this.widgetFullName )
615                         // support: jquery <1.6.3
616                         // http://bugs.jquery.com/ticket/9413
617                         .removeData( $.camelCase( this.widgetFullName ) );
618                 this.widget()
619                         .unbind( this.eventNamespace )
620                         .removeAttr( "aria-disabled" )
621                         .removeClass(
622                                 this.widgetFullName + "-disabled " +
623                                 "ui-state-disabled" );
624
625                 // clean up events and states
626                 this.bindings.unbind( this.eventNamespace );
627                 this.hoverable.removeClass( "ui-state-hover" );
628                 this.focusable.removeClass( "ui-state-focus" );
629         },
630         _destroy: $.noop,
631
632         widget: function() {
633                 return this.element;
634         },
635
636         option: function( key, value ) {
637                 var options = key,
638                         parts,
639                         curOption,
640                         i;
641
642                 if ( arguments.length === 0 ) {
643                         // don't return a reference to the internal hash
644                         return $.widget.extend( {}, this.options );
645                 }
646
647                 if ( typeof key === "string" ) {
648                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
649                         options = {};
650                         parts = key.split( "." );
651                         key = parts.shift();
652                         if ( parts.length ) {
653                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
654                                 for ( i = 0; i < parts.length - 1; i++ ) {
655                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
656                                         curOption = curOption[ parts[ i ] ];
657                                 }
658                                 key = parts.pop();
659                                 if ( value === undefined ) {
660                                         return curOption[ key ] === undefined ? null : curOption[ key ];
661                                 }
662                                 curOption[ key ] = value;
663                         } else {
664                                 if ( value === undefined ) {
665                                         return this.options[ key ] === undefined ? null : this.options[ key ];
666                                 }
667                                 options[ key ] = value;
668                         }
669                 }
670
671                 this._setOptions( options );
672
673                 return this;
674         },
675         _setOptions: function( options ) {
676                 var key;
677
678                 for ( key in options ) {
679                         this._setOption( key, options[ key ] );
680                 }
681
682                 return this;
683         },
684         _setOption: function( key, value ) {
685                 this.options[ key ] = value;
686
687                 if ( key === "disabled" ) {
688                         this.widget()
689                                 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
690                                 .attr( "aria-disabled", value );
691                         this.hoverable.removeClass( "ui-state-hover" );
692                         this.focusable.removeClass( "ui-state-focus" );
693                 }
694
695                 return this;
696         },
697
698         enable: function() {
699                 return this._setOption( "disabled", false );
700         },
701         disable: function() {
702                 return this._setOption( "disabled", true );
703         },
704
705         _on: function( suppressDisabledCheck, element, handlers ) {
706                 var delegateElement,
707                         instance = this;
708
709                 // no suppressDisabledCheck flag, shuffle arguments
710                 if ( typeof suppressDisabledCheck !== "boolean" ) {
711                         handlers = element;
712                         element = suppressDisabledCheck;
713                         suppressDisabledCheck = false;
714                 }
715
716                 // no element argument, shuffle and use this.element
717                 if ( !handlers ) {
718                         handlers = element;
719                         element = this.element;
720                         delegateElement = this.widget();
721                 } else {
722                         // accept selectors, DOM elements
723                         element = delegateElement = $( element );
724                         this.bindings = this.bindings.add( element );
725                 }
726
727                 $.each( handlers, function( event, handler ) {
728                         function handlerProxy() {
729                                 // allow widgets to customize the disabled handling
730                                 // - disabled as an array instead of boolean
731                                 // - disabled class as method for disabling individual parts
732                                 if ( !suppressDisabledCheck &&
733                                                 ( instance.options.disabled === true ||
734                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
735                                         return;
736                                 }
737                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
738                                         .apply( instance, arguments );
739                         }
740
741                         // copy the guid so direct unbinding works
742                         if ( typeof handler !== "string" ) {
743                                 handlerProxy.guid = handler.guid =
744                                         handler.guid || handlerProxy.guid || $.guid++;
745                         }
746
747                         var match = event.match( /^(\w+)\s*(.*)$/ ),
748                                 eventName = match[1] + instance.eventNamespace,
749                                 selector = match[2];
750                         if ( selector ) {
751                                 delegateElement.delegate( selector, eventName, handlerProxy );
752                         } else {
753                                 element.bind( eventName, handlerProxy );
754                         }
755                 });
756         },
757
758         _off: function( element, eventName ) {
759                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
760                 element.unbind( eventName ).undelegate( eventName );
761         },
762
763         _delay: function( handler, delay ) {
764                 function handlerProxy() {
765                         return ( typeof handler === "string" ? instance[ handler ] : handler )
766                                 .apply( instance, arguments );
767                 }
768                 var instance = this;
769                 return setTimeout( handlerProxy, delay || 0 );
770         },
771
772         _hoverable: function( element ) {
773                 this.hoverable = this.hoverable.add( element );
774                 this._on( element, {
775                         mouseenter: function( event ) {
776                                 $( event.currentTarget ).addClass( "ui-state-hover" );
777                         },
778                         mouseleave: function( event ) {
779                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
780                         }
781                 });
782         },
783
784         _focusable: function( element ) {
785                 this.focusable = this.focusable.add( element );
786                 this._on( element, {
787                         focusin: function( event ) {
788                                 $( event.currentTarget ).addClass( "ui-state-focus" );
789                         },
790                         focusout: function( event ) {
791                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
792                         }
793                 });
794         },
795
796         _trigger: function( type, event, data ) {
797                 var prop, orig,
798                         callback = this.options[ type ];
799
800                 data = data || {};
801                 event = $.Event( event );
802                 event.type = ( type === this.widgetEventPrefix ?
803                         type :
804                         this.widgetEventPrefix + type ).toLowerCase();
805                 // the original event may come from any element
806                 // so we need to reset the target on the new event
807                 event.target = this.element[ 0 ];
808
809                 // copy original event properties over to the new event
810                 orig = event.originalEvent;
811                 if ( orig ) {
812                         for ( prop in orig ) {
813                                 if ( !( prop in event ) ) {
814                                         event[ prop ] = orig[ prop ];
815                                 }
816                         }
817                 }
818
819                 this.element.trigger( event, data );
820                 return !( $.isFunction( callback ) &&
821                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
822                         event.isDefaultPrevented() );
823         }
824 };
825
826 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
827         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
828                 if ( typeof options === "string" ) {
829                         options = { effect: options };
830                 }
831                 var hasOptions,
832                         effectName = !options ?
833                                 method :
834                                 options === true || typeof options === "number" ?
835                                         defaultEffect :
836                                         options.effect || defaultEffect;
837                 options = options || {};
838                 if ( typeof options === "number" ) {
839                         options = { duration: options };
840                 }
841                 hasOptions = !$.isEmptyObject( options );
842                 options.complete = callback;
843                 if ( options.delay ) {
844                         element.delay( options.delay );
845                 }
846                 if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
847                         element[ method ]( options );
848                 } else if ( effectName !== method && element[ effectName ] ) {
849                         element[ effectName ]( options.duration, options.easing, callback );
850                 } else {
851                         element.queue(function( next ) {
852                                 $( this )[ method ]();
853                                 if ( callback ) {
854                                         callback.call( element[ 0 ] );
855                                 }
856                                 next();
857                         });
858                 }
859         };
860 });
861
862 // DEPRECATED
863 if ( $.uiBackCompat !== false ) {
864         $.Widget.prototype._getCreateOptions = function() {
865                 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
866         };
867 }
868
869 })( jQuery );
870 (function( $, undefined ) {
871
872 var mouseHandled = false;
873 $( document ).mouseup( function( e ) {
874         mouseHandled = false;
875 });
876
877 $.widget("ui.mouse", {
878         version: "1.9.2",
879         options: {
880                 cancel: 'input,textarea,button,select,option',
881                 distance: 1,
882                 delay: 0
883         },
884         _mouseInit: function() {
885                 var that = this;
886
887                 this.element
888                         .bind('mousedown.'+this.widgetName, function(event) {
889                                 return that._mouseDown(event);
890                         })
891                         .bind('click.'+this.widgetName, function(event) {
892                                 if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
893                                         $.removeData(event.target, that.widgetName + '.preventClickEvent');
894                                         event.stopImmediatePropagation();
895                                         return false;
896                                 }
897                         });
898
899                 this.started = false;
900         },
901
902         // TODO: make sure destroying one instance of mouse doesn't mess with
903         // other instances of mouse
904         _mouseDestroy: function() {
905                 this.element.unbind('.'+this.widgetName);
906                 if ( this._mouseMoveDelegate ) {
907                         $(document)
908                                 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
909                                 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
910                 }
911         },
912
913         _mouseDown: function(event) {
914                 // don't let more than one widget handle mouseStart
915                 if( mouseHandled ) { return; }
916
917                 // we may have missed mouseup (out of window)
918                 (this._mouseStarted && this._mouseUp(event));
919
920                 this._mouseDownEvent = event;
921
922                 var that = this,
923                         btnIsLeft = (event.which === 1),
924                         // event.target.nodeName works around a bug in IE 8 with
925                         // disabled inputs (#7620)
926                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
927                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
928                         return true;
929                 }
930
931                 this.mouseDelayMet = !this.options.delay;
932                 if (!this.mouseDelayMet) {
933                         this._mouseDelayTimer = setTimeout(function() {
934                                 that.mouseDelayMet = true;
935                         }, this.options.delay);
936                 }
937
938                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
939                         this._mouseStarted = (this._mouseStart(event) !== false);
940                         if (!this._mouseStarted) {
941                                 event.preventDefault();
942                                 return true;
943                         }
944                 }
945
946                 // Click event may never have fired (Gecko & Opera)
947                 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
948                         $.removeData(event.target, this.widgetName + '.preventClickEvent');
949                 }
950
951                 // these delegates are required to keep context
952                 this._mouseMoveDelegate = function(event) {
953                         return that._mouseMove(event);
954                 };
955                 this._mouseUpDelegate = function(event) {
956                         return that._mouseUp(event);
957                 };
958                 $(document)
959                         .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
960                         .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
961
962                 event.preventDefault();
963
964                 mouseHandled = true;
965                 return true;
966         },
967
968         _mouseMove: function(event) {
969                 // IE mouseup check - mouseup happened when mouse was out of window
970                 if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
971                         return this._mouseUp(event);
972                 }
973
974                 if (this._mouseStarted) {
975                         this._mouseDrag(event);
976                         return event.preventDefault();
977                 }
978
979                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
980                         this._mouseStarted =
981                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
982                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
983                 }
984
985                 return !this._mouseStarted;
986         },
987
988         _mouseUp: function(event) {
989                 $(document)
990                         .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
991                         .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
992
993                 if (this._mouseStarted) {
994                         this._mouseStarted = false;
995
996                         if (event.target === this._mouseDownEvent.target) {
997                                 $.data(event.target, this.widgetName + '.preventClickEvent', true);
998                         }
999
1000                         this._mouseStop(event);
1001                 }
1002
1003                 return false;
1004         },
1005
1006         _mouseDistanceMet: function(event) {
1007                 return (Math.max(
1008                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
1009                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
1010                         ) >= this.options.distance
1011                 );
1012         },
1013
1014         _mouseDelayMet: function(event) {
1015                 return this.mouseDelayMet;
1016         },
1017
1018         // These are placeholder methods, to be overriden by extending plugin
1019         _mouseStart: function(event) {},
1020         _mouseDrag: function(event) {},
1021         _mouseStop: function(event) {},
1022         _mouseCapture: function(event) { return true; }
1023 });
1024
1025 })(jQuery);
1026 (function( $, undefined ) {
1027
1028 $.ui = $.ui || {};
1029
1030 var cachedScrollbarWidth,
1031         max = Math.max,
1032         abs = Math.abs,
1033         round = Math.round,
1034         rhorizontal = /left|center|right/,
1035         rvertical = /top|center|bottom/,
1036         roffset = /[\+\-]\d+%?/,
1037         rposition = /^\w+/,
1038         rpercent = /%$/,
1039         _position = $.fn.position;
1040
1041 function getOffsets( offsets, width, height ) {
1042         return [
1043                 parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1044                 parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1045         ];
1046 }
1047 function parseCss( element, property ) {
1048         return parseInt( $.css( element, property ), 10 ) || 0;
1049 }
1050
1051 $.position = {
1052         scrollbarWidth: function() {
1053                 if ( cachedScrollbarWidth !== undefined ) {
1054                         return cachedScrollbarWidth;
1055                 }
1056                 var w1, w2,
1057                         div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1058                         innerDiv = div.children()[0];
1059
1060                 $( "body" ).append( div );
1061                 w1 = innerDiv.offsetWidth;
1062                 div.css( "overflow", "scroll" );
1063
1064                 w2 = innerDiv.offsetWidth;
1065
1066                 if ( w1 === w2 ) {
1067                         w2 = div[0].clientWidth;
1068                 }
1069
1070                 div.remove();
1071
1072                 return (cachedScrollbarWidth = w1 - w2);
1073         },
1074         getScrollInfo: function( within ) {
1075                 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
1076                         overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
1077                         hasOverflowX = overflowX === "scroll" ||
1078                                 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1079                         hasOverflowY = overflowY === "scroll" ||
1080                                 ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1081                 return {
1082                         width: hasOverflowX ? $.position.scrollbarWidth() : 0,
1083                         height: hasOverflowY ? $.position.scrollbarWidth() : 0
1084                 };
1085         },
1086         getWithinInfo: function( element ) {
1087                 var withinElement = $( element || window ),
1088                         isWindow = $.isWindow( withinElement[0] );
1089                 return {
1090                         element: withinElement,
1091                         isWindow: isWindow,
1092                         offset: withinElement.offset() || { left: 0, top: 0 },
1093                         scrollLeft: withinElement.scrollLeft(),
1094                         scrollTop: withinElement.scrollTop(),
1095                         width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1096                         height: isWindow ? withinElement.height() : withinElement.outerHeight()
1097                 };
1098         }
1099 };
1100
1101 $.fn.position = function( options ) {
1102         if ( !options || !options.of ) {
1103                 return _position.apply( this, arguments );
1104         }
1105
1106         // make a copy, we don't want to modify arguments
1107         options = $.extend( {}, options );
1108
1109         var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
1110                 target = $( options.of ),
1111                 within = $.position.getWithinInfo( options.within ),
1112                 scrollInfo = $.position.getScrollInfo( within ),
1113                 targetElem = target[0],
1114                 collision = ( options.collision || "flip" ).split( " " ),
1115                 offsets = {};
1116
1117         if ( targetElem.nodeType === 9 ) {
1118                 targetWidth = target.width();
1119                 targetHeight = target.height();
1120                 targetOffset = { top: 0, left: 0 };
1121         } else if ( $.isWindow( targetElem ) ) {
1122                 targetWidth = target.width();
1123                 targetHeight = target.height();
1124                 targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
1125         } else if ( targetElem.preventDefault ) {
1126                 // force left top to allow flipping
1127                 options.at = "left top";
1128                 targetWidth = targetHeight = 0;
1129                 targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
1130         } else {
1131                 targetWidth = target.outerWidth();
1132                 targetHeight = target.outerHeight();
1133                 targetOffset = target.offset();
1134         }
1135         // clone to reuse original targetOffset later
1136         basePosition = $.extend( {}, targetOffset );
1137
1138         // force my and at to have valid horizontal and vertical positions
1139         // if a value is missing or invalid, it will be converted to center
1140         $.each( [ "my", "at" ], function() {
1141                 var pos = ( options[ this ] || "" ).split( " " ),
1142                         horizontalOffset,
1143                         verticalOffset;
1144
1145                 if ( pos.length === 1) {
1146                         pos = rhorizontal.test( pos[ 0 ] ) ?
1147                                 pos.concat( [ "center" ] ) :
1148                                 rvertical.test( pos[ 0 ] ) ?
1149                                         [ "center" ].concat( pos ) :
1150                                         [ "center", "center" ];
1151                 }
1152                 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1153                 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1154
1155                 // calculate offsets
1156                 horizontalOffset = roffset.exec( pos[ 0 ] );
1157                 verticalOffset = roffset.exec( pos[ 1 ] );
1158                 offsets[ this ] = [
1159                         horizontalOffset ? horizontalOffset[ 0 ] : 0,
1160                         verticalOffset ? verticalOffset[ 0 ] : 0
1161                 ];
1162
1163                 // reduce to just the positions without the offsets
1164                 options[ this ] = [
1165                         rposition.exec( pos[ 0 ] )[ 0 ],
1166                         rposition.exec( pos[ 1 ] )[ 0 ]
1167                 ];
1168         });
1169
1170         // normalize collision option
1171         if ( collision.length === 1 ) {
1172                 collision[ 1 ] = collision[ 0 ];
1173         }
1174
1175         if ( options.at[ 0 ] === "right" ) {
1176                 basePosition.left += targetWidth;
1177         } else if ( options.at[ 0 ] === "center" ) {
1178                 basePosition.left += targetWidth / 2;
1179         }
1180
1181         if ( options.at[ 1 ] === "bottom" ) {
1182                 basePosition.top += targetHeight;
1183         } else if ( options.at[ 1 ] === "center" ) {
1184                 basePosition.top += targetHeight / 2;
1185         }
1186
1187         atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1188         basePosition.left += atOffset[ 0 ];
1189         basePosition.top += atOffset[ 1 ];
1190
1191         return this.each(function() {
1192                 var collisionPosition, using,
1193                         elem = $( this ),
1194                         elemWidth = elem.outerWidth(),
1195                         elemHeight = elem.outerHeight(),
1196                         marginLeft = parseCss( this, "marginLeft" ),
1197                         marginTop = parseCss( this, "marginTop" ),
1198                         collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1199                         collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1200                         position = $.extend( {}, basePosition ),
1201                         myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1202
1203                 if ( options.my[ 0 ] === "right" ) {
1204                         position.left -= elemWidth;
1205                 } else if ( options.my[ 0 ] === "center" ) {
1206                         position.left -= elemWidth / 2;
1207                 }
1208
1209                 if ( options.my[ 1 ] === "bottom" ) {
1210                         position.top -= elemHeight;
1211                 } else if ( options.my[ 1 ] === "center" ) {
1212                         position.top -= elemHeight / 2;
1213                 }
1214
1215                 position.left += myOffset[ 0 ];
1216                 position.top += myOffset[ 1 ];
1217
1218                 // if the browser doesn't support fractions, then round for consistent results
1219                 if ( !$.support.offsetFractions ) {
1220                         position.left = round( position.left );
1221                         position.top = round( position.top );
1222                 }
1223
1224                 collisionPosition = {
1225                         marginLeft: marginLeft,
1226                         marginTop: marginTop
1227                 };
1228
1229                 $.each( [ "left", "top" ], function( i, dir ) {
1230                         if ( $.ui.position[ collision[ i ] ] ) {
1231                                 $.ui.position[ collision[ i ] ][ dir ]( position, {
1232                                         targetWidth: targetWidth,
1233                                         targetHeight: targetHeight,
1234                                         elemWidth: elemWidth,
1235                                         elemHeight: elemHeight,
1236                                         collisionPosition: collisionPosition,
1237                                         collisionWidth: collisionWidth,
1238                                         collisionHeight: collisionHeight,
1239                                         offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1240                                         my: options.my,
1241                                         at: options.at,
1242                                         within: within,
1243                                         elem : elem
1244                                 });
1245                         }
1246                 });
1247
1248                 if ( $.fn.bgiframe ) {
1249                         elem.bgiframe();
1250                 }
1251
1252                 if ( options.using ) {
1253                         // adds feedback as second argument to using callback, if present
1254                         using = function( props ) {
1255                                 var left = targetOffset.left - position.left,
1256                                         right = left + targetWidth - elemWidth,
1257                                         top = targetOffset.top - position.top,
1258                                         bottom = top + targetHeight - elemHeight,
1259                                         feedback = {
1260                                                 target: {
1261                                                         element: target,
1262                                                         left: targetOffset.left,
1263                                                         top: targetOffset.top,
1264                                                         width: targetWidth,
1265                                                         height: targetHeight
1266                                                 },
1267                                                 element: {
1268                                                         element: elem,
1269                                                         left: position.left,
1270                                                         top: position.top,
1271                                                         width: elemWidth,
1272                                                         height: elemHeight
1273                                                 },
1274                                                 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1275                                                 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1276                                         };
1277                                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1278                                         feedback.horizontal = "center";
1279                                 }
1280                                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1281                                         feedback.vertical = "middle";
1282                                 }
1283                                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1284                                         feedback.important = "horizontal";
1285                                 } else {
1286                                         feedback.important = "vertical";
1287                                 }
1288                                 options.using.call( this, props, feedback );
1289                         };
1290                 }
1291
1292                 elem.offset( $.extend( position, { using: using } ) );
1293         });
1294 };
1295
1296 $.ui.position = {
1297         fit: {
1298                 left: function( position, data ) {
1299                         var within = data.within,
1300                                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1301                                 outerWidth = within.width,
1302                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1303                                 overLeft = withinOffset - collisionPosLeft,
1304                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1305                                 newOverRight;
1306
1307                         // element is wider than within
1308                         if ( data.collisionWidth > outerWidth ) {
1309                                 // element is initially over the left side of within
1310                                 if ( overLeft > 0 && overRight <= 0 ) {
1311                                         newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1312                                         position.left += overLeft - newOverRight;
1313                                 // element is initially over right side of within
1314                                 } else if ( overRight > 0 && overLeft <= 0 ) {
1315                                         position.left = withinOffset;
1316                                 // element is initially over both left and right sides of within
1317                                 } else {
1318                                         if ( overLeft > overRight ) {
1319                                                 position.left = withinOffset + outerWidth - data.collisionWidth;
1320                                         } else {
1321                                                 position.left = withinOffset;
1322                                         }
1323                                 }
1324                         // too far left -> align with left edge
1325                         } else if ( overLeft > 0 ) {
1326                                 position.left += overLeft;
1327                         // too far right -> align with right edge
1328                         } else if ( overRight > 0 ) {
1329                                 position.left -= overRight;
1330                         // adjust based on position and margin
1331                         } else {
1332                                 position.left = max( position.left - collisionPosLeft, position.left );
1333                         }
1334                 },
1335                 top: function( position, data ) {
1336                         var within = data.within,
1337                                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1338                                 outerHeight = data.within.height,
1339                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1340                                 overTop = withinOffset - collisionPosTop,
1341                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1342                                 newOverBottom;
1343
1344                         // element is taller than within
1345                         if ( data.collisionHeight > outerHeight ) {
1346                                 // element is initially over the top of within
1347                                 if ( overTop > 0 && overBottom <= 0 ) {
1348                                         newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1349                                         position.top += overTop - newOverBottom;
1350                                 // element is initially over bottom of within
1351                                 } else if ( overBottom > 0 && overTop <= 0 ) {
1352                                         position.top = withinOffset;
1353                                 // element is initially over both top and bottom of within
1354                                 } else {
1355                                         if ( overTop > overBottom ) {
1356                                                 position.top = withinOffset + outerHeight - data.collisionHeight;
1357                                         } else {
1358                                                 position.top = withinOffset;
1359                                         }
1360                                 }
1361                         // too far up -> align with top
1362                         } else if ( overTop > 0 ) {
1363                                 position.top += overTop;
1364                         // too far down -> align with bottom edge
1365                         } else if ( overBottom > 0 ) {
1366                                 position.top -= overBottom;
1367                         // adjust based on position and margin
1368                         } else {
1369                                 position.top = max( position.top - collisionPosTop, position.top );
1370                         }
1371                 }
1372         },
1373         flip: {
1374                 left: function( position, data ) {
1375                         var within = data.within,
1376                                 withinOffset = within.offset.left + within.scrollLeft,
1377                                 outerWidth = within.width,
1378                                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1379                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1380                                 overLeft = collisionPosLeft - offsetLeft,
1381                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1382                                 myOffset = data.my[ 0 ] === "left" ?
1383                                         -data.elemWidth :
1384                                         data.my[ 0 ] === "right" ?
1385                                                 data.elemWidth :
1386                                                 0,
1387                                 atOffset = data.at[ 0 ] === "left" ?
1388                                         data.targetWidth :
1389                                         data.at[ 0 ] === "right" ?
1390                                                 -data.targetWidth :
1391                                                 0,
1392                                 offset = -2 * data.offset[ 0 ],
1393                                 newOverRight,
1394                                 newOverLeft;
1395
1396                         if ( overLeft < 0 ) {
1397                                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1398                                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1399                                         position.left += myOffset + atOffset + offset;
1400                                 }
1401                         }
1402                         else if ( overRight > 0 ) {
1403                                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1404                                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1405                                         position.left += myOffset + atOffset + offset;
1406                                 }
1407                         }
1408                 },
1409                 top: function( position, data ) {
1410                         var within = data.within,
1411                                 withinOffset = within.offset.top + within.scrollTop,
1412                                 outerHeight = within.height,
1413                                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1414                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1415                                 overTop = collisionPosTop - offsetTop,
1416                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1417                                 top = data.my[ 1 ] === "top",
1418                                 myOffset = top ?
1419                                         -data.elemHeight :
1420                                         data.my[ 1 ] === "bottom" ?
1421                                                 data.elemHeight :
1422                                                 0,
1423                                 atOffset = data.at[ 1 ] === "top" ?
1424                                         data.targetHeight :
1425                                         data.at[ 1 ] === "bottom" ?
1426                                                 -data.targetHeight :
1427                                                 0,
1428                                 offset = -2 * data.offset[ 1 ],
1429                                 newOverTop,
1430                                 newOverBottom;
1431                         if ( overTop < 0 ) {
1432                                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1433                                 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1434                                         position.top += myOffset + atOffset + offset;
1435                                 }
1436                         }
1437                         else if ( overBottom > 0 ) {
1438                                 newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1439                                 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1440                                         position.top += myOffset + atOffset + offset;
1441                                 }
1442                         }
1443                 }
1444         },
1445         flipfit: {
1446                 left: function() {
1447                         $.ui.position.flip.left.apply( this, arguments );
1448                         $.ui.position.fit.left.apply( this, arguments );
1449                 },
1450                 top: function() {
1451                         $.ui.position.flip.top.apply( this, arguments );
1452                         $.ui.position.fit.top.apply( this, arguments );
1453                 }
1454         }
1455 };
1456
1457 // fraction support test
1458 (function () {
1459         var testElement, testElementParent, testElementStyle, offsetLeft, i,
1460                 body = document.getElementsByTagName( "body" )[ 0 ],
1461                 div = document.createElement( "div" );
1462
1463         //Create a "fake body" for testing based on method used in jQuery.support
1464         testElement = document.createElement( body ? "div" : "body" );
1465         testElementStyle = {
1466                 visibility: "hidden",
1467                 width: 0,
1468                 height: 0,
1469                 border: 0,
1470                 margin: 0,
1471                 background: "none"
1472         };
1473         if ( body ) {
1474                 $.extend( testElementStyle, {
1475                         position: "absolute",
1476                         left: "-1000px",
1477                         top: "-1000px"
1478                 });
1479         }
1480         for ( i in testElementStyle ) {
1481                 testElement.style[ i ] = testElementStyle[ i ];
1482         }
1483         testElement.appendChild( div );
1484         testElementParent = body || document.documentElement;
1485         testElementParent.insertBefore( testElement, testElementParent.firstChild );
1486
1487         div.style.cssText = "position: absolute; left: 10.7432222px;";
1488
1489         offsetLeft = $( div ).offset().left;
1490         $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1491
1492         testElement.innerHTML = "";
1493         testElementParent.removeChild( testElement );
1494 })();
1495
1496 // DEPRECATED
1497 if ( $.uiBackCompat !== false ) {
1498         // offset option
1499         (function( $ ) {
1500                 var _position = $.fn.position;
1501                 $.fn.position = function( options ) {
1502                         if ( !options || !options.offset ) {
1503                                 return _position.call( this, options );
1504                         }
1505                         var offset = options.offset.split( " " ),
1506                                 at = options.at.split( " " );
1507                         if ( offset.length === 1 ) {
1508                                 offset[ 1 ] = offset[ 0 ];
1509                         }
1510                         if ( /^\d/.test( offset[ 0 ] ) ) {
1511                                 offset[ 0 ] = "+" + offset[ 0 ];
1512                         }
1513                         if ( /^\d/.test( offset[ 1 ] ) ) {
1514                                 offset[ 1 ] = "+" + offset[ 1 ];
1515                         }
1516                         if ( at.length === 1 ) {
1517                                 if ( /left|center|right/.test( at[ 0 ] ) ) {
1518                                         at[ 1 ] = "center";
1519                                 } else {
1520                                         at[ 1 ] = at[ 0 ];
1521                                         at[ 0 ] = "center";
1522                                 }
1523                         }
1524                         return _position.call( this, $.extend( options, {
1525                                 at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
1526                                 offset: undefined
1527                         } ) );
1528                 };
1529         }( jQuery ) );
1530 }
1531
1532 }( jQuery ) );
1533 (function( $, undefined ) {
1534
1535 var uid = 0,
1536         hideProps = {},
1537         showProps = {};
1538
1539 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
1540         hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
1541 showProps.height = showProps.paddingTop = showProps.paddingBottom =
1542         showProps.borderTopWidth = showProps.borderBottomWidth = "show";
1543
1544 $.widget( "ui.accordion", {
1545         version: "1.9.2",
1546         options: {
1547                 active: 0,
1548                 animate: {},
1549                 collapsible: false,
1550                 event: "click",
1551                 header: "> li > :first-child,> :not(li):even",
1552                 heightStyle: "auto",
1553                 icons: {
1554                         activeHeader: "ui-icon-triangle-1-s",
1555                         header: "ui-icon-triangle-1-e"
1556                 },
1557
1558                 // callbacks
1559                 activate: null,
1560                 beforeActivate: null
1561         },
1562
1563         _create: function() {
1564                 var accordionId = this.accordionId = "ui-accordion-" +
1565                                 (this.element.attr( "id" ) || ++uid),
1566                         options = this.options;
1567
1568                 this.prevShow = this.prevHide = $();
1569                 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
1570
1571                 this.headers = this.element.find( options.header )
1572                         .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
1573                 this._hoverable( this.headers );
1574                 this._focusable( this.headers );
1575
1576                 this.headers.next()
1577                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
1578                         .hide();
1579
1580                 // don't allow collapsible: false and active: false / null
1581                 if ( !options.collapsible && (options.active === false || options.active == null) ) {
1582                         options.active = 0;
1583                 }
1584                 // handle negative values
1585                 if ( options.active < 0 ) {
1586                         options.active += this.headers.length;
1587                 }
1588                 this.active = this._findActive( options.active )
1589                         .addClass( "ui-accordion-header-active ui-state-active" )
1590                         .toggleClass( "ui-corner-all ui-corner-top" );
1591                 this.active.next()
1592                         .addClass( "ui-accordion-content-active" )
1593                         .show();
1594
1595                 this._createIcons();
1596                 this.refresh();
1597
1598                 // ARIA
1599                 this.element.attr( "role", "tablist" );
1600
1601                 this.headers
1602                         .attr( "role", "tab" )
1603                         .each(function( i ) {
1604                                 var header = $( this ),
1605                                         headerId = header.attr( "id" ),
1606                                         panel = header.next(),
1607                                         panelId = panel.attr( "id" );
1608                                 if ( !headerId ) {
1609                                         headerId = accordionId + "-header-" + i;
1610                                         header.attr( "id", headerId );
1611                                 }
1612                                 if ( !panelId ) {
1613                                         panelId = accordionId + "-panel-" + i;
1614                                         panel.attr( "id", panelId );
1615                                 }
1616                                 header.attr( "aria-controls", panelId );
1617                                 panel.attr( "aria-labelledby", headerId );
1618                         })
1619                         .next()
1620                                 .attr( "role", "tabpanel" );
1621
1622                 this.headers
1623                         .not( this.active )
1624                         .attr({
1625                                 "aria-selected": "false",
1626                                 tabIndex: -1
1627                         })
1628                         .next()
1629                                 .attr({
1630                                         "aria-expanded": "false",
1631                                         "aria-hidden": "true"
1632                                 })
1633                                 .hide();
1634
1635                 // make sure at least one header is in the tab order
1636                 if ( !this.active.length ) {
1637                         this.headers.eq( 0 ).attr( "tabIndex", 0 );
1638                 } else {
1639                         this.active.attr({
1640                                 "aria-selected": "true",
1641                                 tabIndex: 0
1642                         })
1643                         .next()
1644                                 .attr({
1645                                         "aria-expanded": "true",
1646                                         "aria-hidden": "false"
1647                                 });
1648                 }
1649
1650                 this._on( this.headers, { keydown: "_keydown" });
1651                 this._on( this.headers.next(), { keydown: "_panelKeyDown" });
1652                 this._setupEvents( options.event );
1653         },
1654
1655         _getCreateEventData: function() {
1656                 return {
1657                         header: this.active,
1658                         content: !this.active.length ? $() : this.active.next()
1659                 };
1660         },
1661
1662         _createIcons: function() {
1663                 var icons = this.options.icons;
1664                 if ( icons ) {
1665                         $( "<span>" )
1666                                 .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
1667                                 .prependTo( this.headers );
1668                         this.active.children( ".ui-accordion-header-icon" )
1669                                 .removeClass( icons.header )
1670                                 .addClass( icons.activeHeader );
1671                         this.headers.addClass( "ui-accordion-icons" );
1672                 }
1673         },
1674
1675         _destroyIcons: function() {
1676                 this.headers
1677                         .removeClass( "ui-accordion-icons" )
1678                         .children( ".ui-accordion-header-icon" )
1679                                 .remove();
1680         },
1681
1682         _destroy: function() {
1683                 var contents;
1684
1685                 // clean up main element
1686                 this.element
1687                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
1688                         .removeAttr( "role" );
1689
1690                 // clean up headers
1691                 this.headers
1692                         .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" )
1693                         .removeAttr( "role" )
1694                         .removeAttr( "aria-selected" )
1695                         .removeAttr( "aria-controls" )
1696                         .removeAttr( "tabIndex" )
1697                         .each(function() {
1698                                 if ( /^ui-accordion/.test( this.id ) ) {
1699                                         this.removeAttribute( "id" );
1700                                 }
1701                         });
1702                 this._destroyIcons();
1703
1704                 // clean up content panels
1705                 contents = this.headers.next()
1706                         .css( "display", "" )
1707                         .removeAttr( "role" )
1708                         .removeAttr( "aria-expanded" )
1709                         .removeAttr( "aria-hidden" )
1710                         .removeAttr( "aria-labelledby" )
1711                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
1712                         .each(function() {
1713                                 if ( /^ui-accordion/.test( this.id ) ) {
1714                                         this.removeAttribute( "id" );
1715                                 }
1716                         });
1717                 if ( this.options.heightStyle !== "content" ) {
1718                         contents.css( "height", "" );
1719                 }
1720         },
1721
1722         _setOption: function( key, value ) {
1723                 if ( key === "active" ) {
1724                         // _activate() will handle invalid values and update this.options
1725                         this._activate( value );
1726                         return;
1727                 }
1728
1729                 if ( key === "event" ) {
1730                         if ( this.options.event ) {
1731                                 this._off( this.headers, this.options.event );
1732                         }
1733                         this._setupEvents( value );
1734                 }
1735
1736                 this._super( key, value );
1737
1738                 // setting collapsible: false while collapsed; open first panel
1739                 if ( key === "collapsible" && !value && this.options.active === false ) {
1740                         this._activate( 0 );
1741                 }
1742
1743                 if ( key === "icons" ) {
1744                         this._destroyIcons();
1745                         if ( value ) {
1746                                 this._createIcons();
1747                         }
1748                 }
1749
1750                 // #5332 - opacity doesn't cascade to positioned elements in IE
1751                 // so we need to add the disabled class to the headers and panels
1752                 if ( key === "disabled" ) {
1753                         this.headers.add( this.headers.next() )
1754                                 .toggleClass( "ui-state-disabled", !!value );
1755                 }
1756         },
1757
1758         _keydown: function( event ) {
1759                 if ( event.altKey || event.ctrlKey ) {
1760                         return;
1761                 }
1762
1763                 var keyCode = $.ui.keyCode,
1764                         length = this.headers.length,
1765                         currentIndex = this.headers.index( event.target ),
1766                         toFocus = false;
1767
1768                 switch ( event.keyCode ) {
1769                         case keyCode.RIGHT:
1770                         case keyCode.DOWN:
1771                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
1772                                 break;
1773                         case keyCode.LEFT:
1774                         case keyCode.UP:
1775                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
1776                                 break;
1777                         case keyCode.SPACE:
1778                         case keyCode.ENTER:
1779                                 this._eventHandler( event );
1780                                 break;
1781                         case keyCode.HOME:
1782                                 toFocus = this.headers[ 0 ];
1783                                 break;
1784                         case keyCode.END:
1785                                 toFocus = this.headers[ length - 1 ];
1786                                 break;
1787                 }
1788
1789                 if ( toFocus ) {
1790                         $( event.target ).attr( "tabIndex", -1 );
1791                         $( toFocus ).attr( "tabIndex", 0 );
1792                         toFocus.focus();
1793                         event.preventDefault();
1794                 }
1795         },
1796
1797         _panelKeyDown : function( event ) {
1798                 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
1799                         $( event.currentTarget ).prev().focus();
1800                 }
1801         },
1802
1803         refresh: function() {
1804                 var maxHeight, overflow,
1805                         heightStyle = this.options.heightStyle,
1806                         parent = this.element.parent();
1807
1808
1809                 if ( heightStyle === "fill" ) {
1810                         // IE 6 treats height like minHeight, so we need to turn off overflow
1811                         // in order to get a reliable height
1812                         // we use the minHeight support test because we assume that only
1813                         // browsers that don't support minHeight will treat height as minHeight
1814                         if ( !$.support.minHeight ) {
1815                                 overflow = parent.css( "overflow" );
1816                                 parent.css( "overflow", "hidden");
1817                         }
1818                         maxHeight = parent.height();
1819                         this.element.siblings( ":visible" ).each(function() {
1820                                 var elem = $( this ),
1821                                         position = elem.css( "position" );
1822
1823                                 if ( position === "absolute" || position === "fixed" ) {
1824                                         return;
1825                                 }
1826                                 maxHeight -= elem.outerHeight( true );
1827                         });
1828                         if ( overflow ) {
1829                                 parent.css( "overflow", overflow );
1830                         }
1831
1832                         this.headers.each(function() {
1833                                 maxHeight -= $( this ).outerHeight( true );
1834                         });
1835
1836                         this.headers.next()
1837                                 .each(function() {
1838                                         $( this ).height( Math.max( 0, maxHeight -
1839                                                 $( this ).innerHeight() + $( this ).height() ) );
1840                                 })
1841                                 .css( "overflow", "auto" );
1842                 } else if ( heightStyle === "auto" ) {
1843                         maxHeight = 0;
1844                         this.headers.next()
1845                                 .each(function() {
1846                                         maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
1847                                 })
1848                                 .height( maxHeight );
1849                 }
1850         },
1851
1852         _activate: function( index ) {
1853                 var active = this._findActive( index )[ 0 ];
1854
1855                 // trying to activate the already active panel
1856                 if ( active === this.active[ 0 ] ) {
1857                         return;
1858                 }
1859
1860                 // trying to collapse, simulate a click on the currently active header
1861                 active = active || this.active[ 0 ];
1862
1863                 this._eventHandler({
1864                         target: active,
1865                         currentTarget: active,
1866                         preventDefault: $.noop
1867                 });
1868         },
1869
1870         _findActive: function( selector ) {
1871                 return typeof selector === "number" ? this.headers.eq( selector ) : $();
1872         },
1873
1874         _setupEvents: function( event ) {
1875                 var events = {};
1876                 if ( !event ) {
1877                         return;
1878                 }
1879                 $.each( event.split(" "), function( index, eventName ) {
1880                         events[ eventName ] = "_eventHandler";
1881                 });
1882                 this._on( this.headers, events );
1883         },
1884
1885         _eventHandler: function( event ) {
1886                 var options = this.options,
1887                         active = this.active,
1888                         clicked = $( event.currentTarget ),
1889                         clickedIsActive = clicked[ 0 ] === active[ 0 ],
1890                         collapsing = clickedIsActive && options.collapsible,
1891                         toShow = collapsing ? $() : clicked.next(),
1892                         toHide = active.next(),
1893                         eventData = {
1894                                 oldHeader: active,
1895                                 oldPanel: toHide,
1896                                 newHeader: collapsing ? $() : clicked,
1897                                 newPanel: toShow
1898                         };
1899
1900                 event.preventDefault();
1901
1902                 if (
1903                                 // click on active header, but not collapsible
1904                                 ( clickedIsActive && !options.collapsible ) ||
1905                                 // allow canceling activation
1906                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
1907                         return;
1908                 }
1909
1910                 options.active = collapsing ? false : this.headers.index( clicked );
1911
1912                 // when the call to ._toggle() comes after the class changes
1913                 // it causes a very odd bug in IE 8 (see #6720)
1914                 this.active = clickedIsActive ? $() : clicked;
1915                 this._toggle( eventData );
1916
1917                 // switch classes
1918                 // corner classes on the previously active header stay after the animation
1919                 active.removeClass( "ui-accordion-header-active ui-state-active" );
1920                 if ( options.icons ) {
1921                         active.children( ".ui-accordion-header-icon" )
1922                                 .removeClass( options.icons.activeHeader )
1923                                 .addClass( options.icons.header );
1924                 }
1925
1926                 if ( !clickedIsActive ) {
1927                         clicked
1928                                 .removeClass( "ui-corner-all" )
1929                                 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
1930                         if ( options.icons ) {
1931                                 clicked.children( ".ui-accordion-header-icon" )
1932                                         .removeClass( options.icons.header )
1933                                         .addClass( options.icons.activeHeader );
1934                         }
1935
1936                         clicked
1937                                 .next()
1938                                 .addClass( "ui-accordion-content-active" );
1939                 }
1940         },
1941
1942         _toggle: function( data ) {
1943                 var toShow = data.newPanel,
1944                         toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
1945
1946                 // handle activating a panel during the animation for another activation
1947                 this.prevShow.add( this.prevHide ).stop( true, true );
1948                 this.prevShow = toShow;
1949                 this.prevHide = toHide;
1950
1951                 if ( this.options.animate ) {
1952                         this._animate( toShow, toHide, data );
1953                 } else {
1954                         toHide.hide();
1955                         toShow.show();
1956                         this._toggleComplete( data );
1957                 }
1958
1959                 toHide.attr({
1960                         "aria-expanded": "false",
1961                         "aria-hidden": "true"
1962                 });
1963                 toHide.prev().attr( "aria-selected", "false" );
1964                 // if we're switching panels, remove the old header from the tab order
1965                 // if we're opening from collapsed state, remove the previous header from the tab order
1966                 // if we're collapsing, then keep the collapsing header in the tab order
1967                 if ( toShow.length && toHide.length ) {
1968                         toHide.prev().attr( "tabIndex", -1 );
1969                 } else if ( toShow.length ) {
1970                         this.headers.filter(function() {
1971                                 return $( this ).attr( "tabIndex" ) === 0;
1972                         })
1973                         .attr( "tabIndex", -1 );
1974                 }
1975
1976                 toShow
1977                         .attr({
1978                                 "aria-expanded": "true",
1979                                 "aria-hidden": "false"
1980                         })
1981                         .prev()
1982                                 .attr({
1983                                         "aria-selected": "true",
1984                                         tabIndex: 0
1985                                 });
1986         },
1987
1988         _animate: function( toShow, toHide, data ) {
1989                 var total, easing, duration,
1990                         that = this,
1991                         adjust = 0,
1992                         down = toShow.length &&
1993                                 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
1994                         animate = this.options.animate || {},
1995                         options = down && animate.down || animate,
1996                         complete = function() {
1997                                 that._toggleComplete( data );
1998                         };
1999
2000                 if ( typeof options === "number" ) {
2001                         duration = options;
2002                 }
2003                 if ( typeof options === "string" ) {
2004                         easing = options;
2005                 }
2006                 // fall back from options to animation in case of partial down settings
2007                 easing = easing || options.easing || animate.easing;
2008                 duration = duration || options.duration || animate.duration;
2009
2010                 if ( !toHide.length ) {
2011                         return toShow.animate( showProps, duration, easing, complete );
2012                 }
2013                 if ( !toShow.length ) {
2014                         return toHide.animate( hideProps, duration, easing, complete );
2015                 }
2016
2017                 total = toShow.show().outerHeight();
2018                 toHide.animate( hideProps, {
2019                         duration: duration,
2020                         easing: easing,
2021                         step: function( now, fx ) {
2022                                 fx.now = Math.round( now );
2023                         }
2024                 });
2025                 toShow
2026                         .hide()
2027                         .animate( showProps, {
2028                                 duration: duration,
2029                                 easing: easing,
2030                                 complete: complete,
2031                                 step: function( now, fx ) {
2032                                         fx.now = Math.round( now );
2033                                         if ( fx.prop !== "height" ) {
2034                                                 adjust += fx.now;
2035                                         } else if ( that.options.heightStyle !== "content" ) {
2036                                                 fx.now = Math.round( total - toHide.outerHeight() - adjust );
2037                                                 adjust = 0;
2038                                         }
2039                                 }
2040                         });
2041         },
2042
2043         _toggleComplete: function( data ) {
2044                 var toHide = data.oldPanel;
2045
2046                 toHide
2047                         .removeClass( "ui-accordion-content-active" )
2048                         .prev()
2049                                 .removeClass( "ui-corner-top" )
2050                                 .addClass( "ui-corner-all" );
2051
2052                 // Work around for rendering bug in IE (#5421)
2053                 if ( toHide.length ) {
2054                         toHide.parent()[0].className = toHide.parent()[0].className;
2055                 }
2056
2057                 this._trigger( "activate", null, data );
2058         }
2059 });
2060
2061
2062
2063 // DEPRECATED
2064 if ( $.uiBackCompat !== false ) {
2065         // navigation options
2066         (function( $, prototype ) {
2067                 $.extend( prototype.options, {
2068                         navigation: false,
2069                         navigationFilter: function() {
2070                                 return this.href.toLowerCase() === location.href.toLowerCase();
2071                         }
2072                 });
2073
2074                 var _create = prototype._create;
2075                 prototype._create = function() {
2076                         if ( this.options.navigation ) {
2077                                 var that = this,
2078                                         headers = this.element.find( this.options.header ),
2079                                         content = headers.next(),
2080                                         current = headers.add( content )
2081                                                 .find( "a" )
2082                                                 .filter( this.options.navigationFilter )
2083                                                 [ 0 ];
2084                                 if ( current ) {
2085                                         headers.add( content ).each( function( index ) {
2086                                                 if ( $.contains( this, current ) ) {
2087                                                         that.options.active = Math.floor( index / 2 );
2088                                                         return false;
2089                                                 }
2090                                         });
2091                                 }
2092                         }
2093                         _create.call( this );
2094                 };
2095         }( jQuery, jQuery.ui.accordion.prototype ) );
2096
2097         // height options
2098         (function( $, prototype ) {
2099                 $.extend( prototype.options, {
2100                         heightStyle: null, // remove default so we fall back to old values
2101                         autoHeight: true, // use heightStyle: "auto"
2102                         clearStyle: false, // use heightStyle: "content"
2103                         fillSpace: false // use heightStyle: "fill"
2104                 });
2105
2106                 var _create = prototype._create,
2107                         _setOption = prototype._setOption;
2108
2109                 $.extend( prototype, {
2110                         _create: function() {
2111                                 this.options.heightStyle = this.options.heightStyle ||
2112                                         this._mergeHeightStyle();
2113
2114                                 _create.call( this );
2115                         },
2116
2117                         _setOption: function( key ) {
2118                                 if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
2119                                         this.options.heightStyle = this._mergeHeightStyle();
2120                                 }
2121                                 _setOption.apply( this, arguments );
2122                         },
2123
2124                         _mergeHeightStyle: function() {
2125                                 var options = this.options;
2126
2127                                 if ( options.fillSpace ) {
2128                                         return "fill";
2129                                 }
2130
2131                                 if ( options.clearStyle ) {
2132                                         return "content";
2133                                 }
2134
2135                                 if ( options.autoHeight ) {
2136                                         return "auto";
2137                                 }
2138                         }
2139                 });
2140         }( jQuery, jQuery.ui.accordion.prototype ) );
2141
2142         // icon options
2143         (function( $, prototype ) {
2144                 $.extend( prototype.options.icons, {
2145                         activeHeader: null, // remove default so we fall back to old values
2146                         headerSelected: "ui-icon-triangle-1-s"
2147                 });
2148
2149                 var _createIcons = prototype._createIcons;
2150                 prototype._createIcons = function() {
2151                         if ( this.options.icons ) {
2152                                 this.options.icons.activeHeader = this.options.icons.activeHeader ||
2153                                         this.options.icons.headerSelected;
2154                         }
2155                         _createIcons.call( this );
2156                 };
2157         }( jQuery, jQuery.ui.accordion.prototype ) );
2158
2159         // expanded active option, activate method
2160         (function( $, prototype ) {
2161                 prototype.activate = prototype._activate;
2162
2163                 var _findActive = prototype._findActive;
2164                 prototype._findActive = function( index ) {
2165                         if ( index === -1 ) {
2166                                 index = false;
2167                         }
2168                         if ( index && typeof index !== "number" ) {
2169                                 index = this.headers.index( this.headers.filter( index ) );
2170                                 if ( index === -1 ) {
2171                                         index = false;
2172                                 }
2173                         }
2174                         return _findActive.call( this, index );
2175                 };
2176         }( jQuery, jQuery.ui.accordion.prototype ) );
2177
2178         // resize method
2179         jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
2180
2181         // change events
2182         (function( $, prototype ) {
2183                 $.extend( prototype.options, {
2184                         change: null,
2185                         changestart: null
2186                 });
2187
2188                 var _trigger = prototype._trigger;
2189                 prototype._trigger = function( type, event, data ) {
2190                         var ret = _trigger.apply( this, arguments );
2191                         if ( !ret ) {
2192                                 return false;
2193                         }
2194
2195                         if ( type === "beforeActivate" ) {
2196                                 ret = _trigger.call( this, "changestart", event, {
2197                                         oldHeader: data.oldHeader,
2198                                         oldContent: data.oldPanel,
2199                                         newHeader: data.newHeader,
2200                                         newContent: data.newPanel
2201                                 });
2202                         } else if ( type === "activate" ) {
2203                                 ret = _trigger.call( this, "change", event, {
2204                                         oldHeader: data.oldHeader,
2205                                         oldContent: data.oldPanel,
2206                                         newHeader: data.newHeader,
2207                                         newContent: data.newPanel
2208                                 });
2209                         }
2210                         return ret;
2211                 };
2212         }( jQuery, jQuery.ui.accordion.prototype ) );
2213
2214         // animated option
2215         // NOTE: this only provides support for "slide", "bounceslide", and easings
2216         // not the full $.ui.accordion.animations API
2217         (function( $, prototype ) {
2218                 $.extend( prototype.options, {
2219                         animate: null,
2220                         animated: "slide"
2221                 });
2222
2223                 var _create = prototype._create;
2224                 prototype._create = function() {
2225                         var options = this.options;
2226                         if ( options.animate === null ) {
2227                                 if ( !options.animated ) {
2228                                         options.animate = false;
2229                                 } else if ( options.animated === "slide" ) {
2230                                         options.animate = 300;
2231                                 } else if ( options.animated === "bounceslide" ) {
2232                                         options.animate = {
2233                                                 duration: 200,
2234                                                 down: {
2235                                                         easing: "easeOutBounce",
2236                                                         duration: 1000
2237                                                 }
2238                                         };
2239                                 } else {
2240                                         options.animate = options.animated;
2241                                 }
2242                         }
2243
2244                         _create.call( this );
2245                 };
2246         }( jQuery, jQuery.ui.accordion.prototype ) );
2247 }
2248
2249 })( jQuery );
2250 (function( $, undefined ) {
2251
2252 // used to prevent race conditions with remote data sources
2253 var requestIndex = 0;
2254
2255 $.widget( "ui.autocomplete", {
2256         version: "1.9.2",
2257         defaultElement: "<input>",
2258         options: {
2259                 appendTo: "body",
2260                 autoFocus: false,
2261                 delay: 300,
2262                 minLength: 1,
2263                 position: {
2264                         my: "left top",
2265                         at: "left bottom",
2266                         collision: "none"
2267                 },
2268                 source: null,
2269
2270                 // callbacks
2271                 change: null,
2272                 close: null,
2273                 focus: null,
2274                 open: null,
2275                 response: null,
2276                 search: null,
2277                 select: null
2278         },
2279
2280         pending: 0,
2281
2282         _create: function() {
2283                 // Some browsers only repeat keydown events, not keypress events,
2284                 // so we use the suppressKeyPress flag to determine if we've already
2285                 // handled the keydown event. #7269
2286                 // Unfortunately the code for & in keypress is the same as the up arrow,
2287                 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
2288                 // events when we know the keydown event was used to modify the
2289                 // search term. #7799
2290                 var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
2291
2292                 this.isMultiLine = this._isMultiLine();
2293                 this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
2294                 this.isNewMenu = true;
2295
2296                 this.element
2297                         .addClass( "ui-autocomplete-input" )
2298                         .attr( "autocomplete", "off" );
2299
2300                 this._on( this.element, {
2301                         keydown: function( event ) {
2302                                 if ( this.element.prop( "readOnly" ) ) {
2303                                         suppressKeyPress = true;
2304                                         suppressInput = true;
2305                                         suppressKeyPressRepeat = true;
2306                                         return;
2307                                 }
2308
2309                                 suppressKeyPress = false;
2310                                 suppressInput = false;
2311                                 suppressKeyPressRepeat = false;
2312                                 var keyCode = $.ui.keyCode;
2313                                 switch( event.keyCode ) {
2314                                 case keyCode.PAGE_UP:
2315                                         suppressKeyPress = true;
2316                                         this._move( "previousPage", event );
2317                                         break;
2318                                 case keyCode.PAGE_DOWN:
2319                                         suppressKeyPress = true;
2320                                         this._move( "nextPage", event );
2321                                         break;
2322                                 case keyCode.UP:
2323                                         suppressKeyPress = true;
2324                                         this._keyEvent( "previous", event );
2325                                         break;
2326                                 case keyCode.DOWN:
2327                                         suppressKeyPress = true;
2328                                         this._keyEvent( "next", event );
2329                                         break;
2330                                 case keyCode.ENTER:
2331                                 case keyCode.NUMPAD_ENTER:
2332                                         // when menu is open and has focus
2333                                         if ( this.menu.active ) {
2334                                                 // #6055 - Opera still allows the keypress to occur
2335                                                 // which causes forms to submit
2336                                                 suppressKeyPress = true;
2337                                                 event.preventDefault();
2338                                                 this.menu.select( event );
2339                                         }
2340                                         break;
2341                                 case keyCode.TAB:
2342                                         if ( this.menu.active ) {
2343                                                 this.menu.select( event );
2344                                         }
2345                                         break;
2346                                 case keyCode.ESCAPE:
2347                                         if ( this.menu.element.is( ":visible" ) ) {
2348                                                 this._value( this.term );
2349                                                 this.close( event );
2350                                                 // Different browsers have different default behavior for escape
2351                                                 // Single press can mean undo or clear
2352                                                 // Double press in IE means clear the whole form
2353                                                 event.preventDefault();
2354                                         }
2355                                         break;
2356                                 default:
2357                                         suppressKeyPressRepeat = true;
2358                                         // search timeout should be triggered before the input value is changed
2359                                         this._searchTimeout( event );
2360                                         break;
2361                                 }
2362                         },
2363                         keypress: function( event ) {
2364                                 if ( suppressKeyPress ) {
2365                                         suppressKeyPress = false;
2366                                         event.preventDefault();
2367                                         return;
2368                                 }
2369                                 if ( suppressKeyPressRepeat ) {
2370                                         return;
2371                                 }
2372
2373                                 // replicate some key handlers to allow them to repeat in Firefox and Opera
2374                                 var keyCode = $.ui.keyCode;
2375                                 switch( event.keyCode ) {
2376                                 case keyCode.PAGE_UP:
2377                                         this._move( "previousPage", event );
2378                                         break;
2379                                 case keyCode.PAGE_DOWN:
2380                                         this._move( "nextPage", event );
2381                                         break;
2382                                 case keyCode.UP:
2383                                         this._keyEvent( "previous", event );
2384                                         break;
2385                                 case keyCode.DOWN:
2386                                         this._keyEvent( "next", event );
2387                                         break;
2388                                 }
2389                         },
2390                         input: function( event ) {
2391                                 if ( suppressInput ) {
2392                                         suppressInput = false;
2393                                         event.preventDefault();
2394                                         return;
2395                                 }
2396                                 this._searchTimeout( event );
2397                         },
2398                         focus: function() {
2399                                 this.selectedItem = null;
2400                                 this.previous = this._value();
2401                         },
2402                         blur: function( event ) {
2403                                 if ( this.cancelBlur ) {
2404                                         delete this.cancelBlur;
2405                                         return;
2406                                 }
2407
2408                                 clearTimeout( this.searching );
2409                                 this.close( event );
2410                                 this._change( event );
2411                         }
2412                 });
2413
2414                 this._initSource();
2415                 this.menu = $( "<ul>" )
2416                         .addClass( "ui-autocomplete" )
2417                         .appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
2418                         .menu({
2419                                 // custom key handling for now
2420                                 input: $(),
2421                                 // disable ARIA support, the live region takes care of that
2422                                 role: null
2423                         })
2424                         .zIndex( this.element.zIndex() + 1 )
2425                         .hide()
2426                         .data( "menu" );
2427
2428                 this._on( this.menu.element, {
2429                         mousedown: function( event ) {
2430                                 // prevent moving focus out of the text field
2431                                 event.preventDefault();
2432
2433                                 // IE doesn't prevent moving focus even with event.preventDefault()
2434                                 // so we set a flag to know when we should ignore the blur event
2435                                 this.cancelBlur = true;
2436                                 this._delay(function() {
2437                                         delete this.cancelBlur;
2438                                 });
2439
2440                                 // clicking on the scrollbar causes focus to shift to the body
2441                                 // but we can't detect a mouseup or a click immediately afterward
2442                                 // so we have to track the next mousedown and close the menu if
2443                                 // the user clicks somewhere outside of the autocomplete
2444                                 var menuElement = this.menu.element[ 0 ];
2445                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2446                                         this._delay(function() {
2447                                                 var that = this;
2448                                                 this.document.one( "mousedown", function( event ) {
2449                                                         if ( event.target !== that.element[ 0 ] &&
2450                                                                         event.target !== menuElement &&
2451                                                                         !$.contains( menuElement, event.target ) ) {
2452                                                                 that.close();
2453                                                         }
2454                                                 });
2455                                         });
2456                                 }
2457                         },
2458                         menufocus: function( event, ui ) {
2459                                 // #7024 - Prevent accidental activation of menu items in Firefox
2460                                 if ( this.isNewMenu ) {
2461                                         this.isNewMenu = false;
2462                                         if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2463                                                 this.menu.blur();
2464
2465                                                 this.document.one( "mousemove", function() {
2466                                                         $( event.target ).trigger( event.originalEvent );
2467                                                 });
2468
2469                                                 return;
2470                                         }
2471                                 }
2472
2473                                 // back compat for _renderItem using item.autocomplete, via #7810
2474                                 // TODO remove the fallback, see #8156
2475                                 var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
2476                                 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
2477                                         // use value to match what will end up in the input, if it was a key event
2478                                         if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
2479                                                 this._value( item.value );
2480                                         }
2481                                 } else {
2482                                         // Normally the input is populated with the item's value as the
2483                                         // menu is navigated, causing screen readers to notice a change and
2484                                         // announce the item. Since the focus event was canceled, this doesn't
2485                                         // happen, so we update the live region so that screen readers can
2486                                         // still notice the change and announce it.
2487                                         this.liveRegion.text( item.value );
2488                                 }
2489                         },
2490                         menuselect: function( event, ui ) {
2491                                 // back compat for _renderItem using item.autocomplete, via #7810
2492                                 // TODO remove the fallback, see #8156
2493                                 var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
2494                                         previous = this.previous;
2495
2496                                 // only trigger when focus was lost (click on menu)
2497                                 if ( this.element[0] !== this.document[0].activeElement ) {
2498                                         this.element.focus();
2499                                         this.previous = previous;
2500                                         // #6109 - IE triggers two focus events and the second
2501                                         // is asynchronous, so we need to reset the previous
2502                                         // term synchronously and asynchronously :-(
2503                                         this._delay(function() {
2504                                                 this.previous = previous;
2505                                                 this.selectedItem = item;
2506                                         });
2507                                 }
2508
2509                                 if ( false !== this._trigger( "select", event, { item: item } ) ) {
2510                                         this._value( item.value );
2511                                 }
2512                                 // reset the term after the select event
2513                                 // this allows custom select handling to work properly
2514                                 this.term = this._value();
2515
2516                                 this.close( event );
2517                                 this.selectedItem = item;
2518                         }
2519                 });
2520
2521                 this.liveRegion = $( "<span>", {
2522                                 role: "status",
2523                                 "aria-live": "polite"
2524                         })
2525                         .addClass( "ui-helper-hidden-accessible" )
2526                         .insertAfter( this.element );
2527
2528                 if ( $.fn.bgiframe ) {
2529                         this.menu.element.bgiframe();
2530                 }
2531
2532                 // turning off autocomplete prevents the browser from remembering the
2533                 // value when navigating through history, so we re-enable autocomplete
2534                 // if the page is unloaded before the widget is destroyed. #7790
2535                 this._on( this.window, {
2536                         beforeunload: function() {
2537                                 this.element.removeAttr( "autocomplete" );
2538                         }
2539                 });
2540         },
2541
2542         _destroy: function() {
2543                 clearTimeout( this.searching );
2544                 this.element
2545                         .removeClass( "ui-autocomplete-input" )
2546                         .removeAttr( "autocomplete" );
2547                 this.menu.element.remove();
2548                 this.liveRegion.remove();
2549         },
2550
2551         _setOption: function( key, value ) {
2552                 this._super( key, value );
2553                 if ( key === "source" ) {
2554                         this._initSource();
2555                 }
2556                 if ( key === "appendTo" ) {
2557                         this.menu.element.appendTo( this.document.find( value || "body" )[0] );
2558                 }
2559                 if ( key === "disabled" && value && this.xhr ) {
2560                         this.xhr.abort();
2561                 }
2562         },
2563
2564         _isMultiLine: function() {
2565                 // Textareas are always multi-line
2566                 if ( this.element.is( "textarea" ) ) {
2567                         return true;
2568                 }
2569                 // Inputs are always single-line, even if inside a contentEditable element
2570                 // IE also treats inputs as contentEditable
2571                 if ( this.element.is( "input" ) ) {
2572                         return false;
2573                 }
2574                 // All other element types are determined by whether or not they're contentEditable
2575                 return this.element.prop( "isContentEditable" );
2576         },
2577
2578         _initSource: function() {
2579                 var array, url,
2580                         that = this;
2581                 if ( $.isArray(this.options.source) ) {
2582                         array = this.options.source;
2583                         this.source = function( request, response ) {
2584                                 response( $.ui.autocomplete.filter( array, request.term ) );
2585                         };
2586                 } else if ( typeof this.options.source === "string" ) {
2587                         url = this.options.source;
2588                         this.source = function( request, response ) {
2589                                 if ( that.xhr ) {
2590                                         that.xhr.abort();
2591                                 }
2592                                 that.xhr = $.ajax({
2593                                         url: url,
2594                                         data: request,
2595                                         dataType: "json",
2596                                         success: function( data ) {
2597                                                 response( data );
2598                                         },
2599                                         error: function() {
2600                                                 response( [] );
2601                                         }
2602                                 });
2603                         };
2604                 } else {
2605                         this.source = this.options.source;
2606                 }
2607         },
2608
2609         _searchTimeout: function( event ) {
2610                 clearTimeout( this.searching );
2611                 this.searching = this._delay(function() {
2612                         // only search if the value has changed
2613                         if ( this.term !== this._value() ) {
2614                                 this.selectedItem = null;
2615                                 this.search( null, event );
2616                         }
2617                 }, this.options.delay );
2618         },
2619
2620         search: function( value, event ) {
2621                 value = value != null ? value : this._value();
2622
2623                 // always save the actual value, not the one passed as an argument
2624                 this.term = this._value();
2625
2626                 if ( value.length < this.options.minLength ) {
2627                         return this.close( event );
2628                 }
2629
2630                 if ( this._trigger( "search", event ) === false ) {
2631                         return;
2632                 }
2633
2634                 return this._search( value );
2635         },
2636
2637         _search: function( value ) {
2638                 this.pending++;
2639                 this.element.addClass( "ui-autocomplete-loading" );
2640                 this.cancelSearch = false;
2641
2642                 this.source( { term: value }, this._response() );
2643         },
2644
2645         _response: function() {
2646                 var that = this,
2647                         index = ++requestIndex;
2648
2649                 return function( content ) {
2650                         if ( index === requestIndex ) {
2651                                 that.__response( content );
2652                         }
2653
2654                         that.pending--;
2655                         if ( !that.pending ) {
2656                                 that.element.removeClass( "ui-autocomplete-loading" );
2657                         }
2658                 };
2659         },
2660
2661         __response: function( content ) {
2662                 if ( content ) {
2663                         content = this._normalize( content );
2664                 }
2665                 this._trigger( "response", null, { content: content } );
2666                 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
2667                         this._suggest( content );
2668                         this._trigger( "open" );
2669                 } else {
2670                         // use ._close() instead of .close() so we don't cancel future searches
2671                         this._close();
2672                 }
2673         },
2674
2675         close: function( event ) {
2676                 this.cancelSearch = true;
2677                 this._close( event );
2678         },
2679
2680         _close: function( event ) {
2681                 if ( this.menu.element.is( ":visible" ) ) {
2682                         this.menu.element.hide();
2683                         this.menu.blur();
2684                         this.isNewMenu = true;
2685                         this._trigger( "close", event );
2686                 }
2687         },
2688
2689         _change: function( event ) {
2690                 if ( this.previous !== this._value() ) {
2691                         this._trigger( "change", event, { item: this.selectedItem } );
2692                 }
2693         },
2694
2695         _normalize: function( items ) {
2696                 // assume all items have the right format when the first item is complete
2697                 if ( items.length && items[0].label && items[0].value ) {
2698                         return items;
2699                 }
2700                 return $.map( items, function( item ) {
2701                         if ( typeof item === "string" ) {
2702                                 return {
2703                                         label: item,
2704                                         value: item
2705                                 };
2706                         }
2707                         return $.extend({
2708                                 label: item.label || item.value,
2709                                 value: item.value || item.label
2710                         }, item );
2711                 });
2712         },
2713
2714         _suggest: function( items ) {
2715                 var ul = this.menu.element
2716                         .empty()
2717                         .zIndex( this.element.zIndex() + 1 );
2718                 this._renderMenu( ul, items );
2719                 this.menu.refresh();
2720
2721                 // size and position menu
2722                 ul.show();
2723                 this._resizeMenu();
2724                 ul.position( $.extend({
2725                         of: this.element
2726                 }, this.options.position ));
2727
2728                 if ( this.options.autoFocus ) {
2729                         this.menu.next();
2730                 }
2731         },
2732
2733         _resizeMenu: function() {
2734                 var ul = this.menu.element;
2735                 ul.outerWidth( Math.max(
2736                         // Firefox wraps long text (possibly a rounding bug)
2737                         // so we add 1px to avoid the wrapping (#7513)
2738                         ul.width( "" ).outerWidth() + 1,
2739                         this.element.outerWidth()
2740                 ) );
2741         },
2742
2743         _renderMenu: function( ul, items ) {
2744                 var that = this;
2745                 $.each( items, function( index, item ) {
2746                         that._renderItemData( ul, item );
2747                 });
2748         },
2749
2750         _renderItemData: function( ul, item ) {
2751                 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
2752         },
2753
2754         _renderItem: function( ul, item ) {
2755                 return $( "<li>" )
2756                         .append( $( "<a>" ).text( item.label ) )
2757                         .appendTo( ul );
2758         },
2759
2760         _move: function( direction, event ) {
2761                 if ( !this.menu.element.is( ":visible" ) ) {
2762                         this.search( null, event );
2763                         return;
2764                 }
2765                 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
2766                                 this.menu.isLastItem() && /^next/.test( direction ) ) {
2767                         this._value( this.term );
2768                         this.menu.blur();
2769                         return;
2770                 }
2771                 this.menu[ direction ]( event );
2772         },
2773
2774         widget: function() {
2775                 return this.menu.element;
2776         },
2777
2778         _value: function() {
2779                 return this.valueMethod.apply( this.element, arguments );
2780         },
2781
2782         _keyEvent: function( keyEvent, event ) {
2783                 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2784                         this._move( keyEvent, event );
2785
2786                         // prevents moving cursor to beginning/end of the text field in some browsers
2787                         event.preventDefault();
2788                 }
2789         }
2790 });
2791
2792 $.extend( $.ui.autocomplete, {
2793         escapeRegex: function( value ) {
2794                 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
2795         },
2796         filter: function(array, term) {
2797                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
2798                 return $.grep( array, function(value) {
2799                         return matcher.test( value.label || value.value || value );
2800                 });
2801         }
2802 });
2803
2804
2805 // live region extension, adding a `messages` option
2806 // NOTE: This is an experimental API. We are still investigating
2807 // a full solution for string manipulation and internationalization.
2808 $.widget( "ui.autocomplete", $.ui.autocomplete, {
2809         options: {
2810                 messages: {
2811                         noResults: "No search results.",
2812                         results: function( amount ) {
2813                                 return amount + ( amount > 1 ? " results are" : " result is" ) +
2814                                         " available, use up and down arrow keys to navigate.";
2815                         }
2816                 }
2817         },
2818
2819         __response: function( content ) {
2820                 var message;
2821                 this._superApply( arguments );
2822                 if ( this.options.disabled || this.cancelSearch ) {
2823                         return;
2824                 }
2825                 if ( content && content.length ) {
2826                         message = this.options.messages.results( content.length );
2827                 } else {
2828                         message = this.options.messages.noResults;
2829                 }
2830                 this.liveRegion.text( message );
2831         }
2832 });
2833
2834
2835 }( jQuery ));
2836 (function( $, undefined ) {
2837
2838 var lastActive, startXPos, startYPos, clickDragged,
2839         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
2840         stateClasses = "ui-state-hover ui-state-active ",
2841         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",
2842         formResetHandler = function() {
2843                 var buttons = $( this ).find( ":ui-button" );
2844                 setTimeout(function() {
2845                         buttons.button( "refresh" );
2846                 }, 1 );
2847         },
2848         radioGroup = function( radio ) {
2849                 var name = radio.name,
2850                         form = radio.form,
2851                         radios = $( [] );
2852                 if ( name ) {
2853                         if ( form ) {
2854                                 radios = $( form ).find( "[name='" + name + "']" );
2855                         } else {
2856                                 radios = $( "[name='" + name + "']", radio.ownerDocument )
2857                                         .filter(function() {
2858                                                 return !this.form;
2859                                         });
2860                         }
2861                 }
2862                 return radios;
2863         };
2864
2865 $.widget( "ui.button", {
2866         version: "1.9.2",
2867         defaultElement: "<button>",
2868         options: {
2869                 disabled: null,
2870                 text: true,
2871                 label: null,
2872                 icons: {
2873                         primary: null,
2874                         secondary: null
2875                 }
2876         },
2877         _create: function() {
2878                 this.element.closest( "form" )
2879                         .unbind( "reset" + this.eventNamespace )
2880                         .bind( "reset" + this.eventNamespace, formResetHandler );
2881
2882                 if ( typeof this.options.disabled !== "boolean" ) {
2883                         this.options.disabled = !!this.element.prop( "disabled" );
2884                 } else {
2885                         this.element.prop( "disabled", this.options.disabled );
2886                 }
2887
2888                 this._determineButtonType();
2889                 this.hasTitle = !!this.buttonElement.attr( "title" );
2890
2891                 var that = this,
2892                         options = this.options,
2893                         toggleButton = this.type === "checkbox" || this.type === "radio",
2894                         activeClass = !toggleButton ? "ui-state-active" : "",
2895                         focusClass = "ui-state-focus";
2896
2897                 if ( options.label === null ) {
2898                         options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
2899                 }
2900
2901                 this._hoverable( this.buttonElement );
2902
2903                 this.buttonElement
2904                         .addClass( baseClasses )
2905                         .attr( "role", "button" )
2906                         .bind( "mouseenter" + this.eventNamespace, function() {
2907                                 if ( options.disabled ) {
2908                                         return;
2909                                 }
2910                                 if ( this === lastActive ) {
2911                                         $( this ).addClass( "ui-state-active" );
2912                                 }
2913                         })
2914                         .bind( "mouseleave" + this.eventNamespace, function() {
2915                                 if ( options.disabled ) {
2916                                         return;
2917                                 }
2918                                 $( this ).removeClass( activeClass );
2919                         })
2920                         .bind( "click" + this.eventNamespace, function( event ) {
2921                                 if ( options.disabled ) {
2922                                         event.preventDefault();
2923                                         event.stopImmediatePropagation();
2924                                 }
2925                         });
2926
2927                 this.element
2928                         .bind( "focus" + this.eventNamespace, function() {
2929                                 // no need to check disabled, focus won't be triggered anyway
2930                                 that.buttonElement.addClass( focusClass );
2931                         })
2932                         .bind( "blur" + this.eventNamespace, function() {
2933                                 that.buttonElement.removeClass( focusClass );
2934                         });
2935
2936                 if ( toggleButton ) {
2937                         this.element.bind( "change" + this.eventNamespace, function() {
2938                                 if ( clickDragged ) {
2939                                         return;
2940                                 }
2941                                 that.refresh();
2942                         });
2943                         // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
2944                         // prevents issue where button state changes but checkbox/radio checked state
2945                         // does not in Firefox (see ticket #6970)
2946                         this.buttonElement
2947                                 .bind( "mousedown" + this.eventNamespace, function( event ) {
2948                                         if ( options.disabled ) {
2949                                                 return;
2950                                         }
2951                                         clickDragged = false;
2952                                         startXPos = event.pageX;
2953                                         startYPos = event.pageY;
2954                                 })
2955                                 .bind( "mouseup" + this.eventNamespace, function( event ) {
2956                                         if ( options.disabled ) {
2957                                                 return;
2958                                         }
2959                                         if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
2960                                                 clickDragged = true;
2961                                         }
2962                         });
2963                 }
2964
2965                 if ( this.type === "checkbox" ) {
2966                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
2967                                 if ( options.disabled || clickDragged ) {
2968                                         return false;
2969                                 }
2970                                 $( this ).toggleClass( "ui-state-active" );
2971                                 that.buttonElement.attr( "aria-pressed", that.element[0].checked );
2972                         });
2973                 } else if ( this.type === "radio" ) {
2974                         this.buttonElement.bind( "click" + this.eventNamespace, function() {
2975                                 if ( options.disabled || clickDragged ) {
2976                                         return false;
2977                                 }
2978                                 $( this ).addClass( "ui-state-active" );
2979                                 that.buttonElement.attr( "aria-pressed", "true" );
2980
2981                                 var radio = that.element[ 0 ];
2982                                 radioGroup( radio )
2983                                         .not( radio )
2984                                         .map(function() {
2985                                                 return $( this ).button( "widget" )[ 0 ];
2986                                         })
2987                                         .removeClass( "ui-state-active" )
2988                                         .attr( "aria-pressed", "false" );
2989                         });
2990                 } else {
2991                         this.buttonElement
2992                                 .bind( "mousedown" + this.eventNamespace, function() {
2993                                         if ( options.disabled ) {
2994                                                 return false;
2995                                         }
2996                                         $( this ).addClass( "ui-state-active" );
2997                                         lastActive = this;
2998                                         that.document.one( "mouseup", function() {
2999                                                 lastActive = null;
3000                                         });
3001                                 })
3002                                 .bind( "mouseup" + this.eventNamespace, function() {
3003                                         if ( options.disabled ) {
3004                                                 return false;
3005                                         }
3006                                         $( this ).removeClass( "ui-state-active" );
3007                                 })
3008                                 .bind( "keydown" + this.eventNamespace, function(event) {
3009                                         if ( options.disabled ) {
3010                                                 return false;
3011                                         }
3012                                         if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3013                                                 $( this ).addClass( "ui-state-active" );
3014                                         }
3015                                 })
3016                                 .bind( "keyup" + this.eventNamespace, function() {
3017                                         $( this ).removeClass( "ui-state-active" );
3018                                 });
3019
3020                         if ( this.buttonElement.is("a") ) {
3021                                 this.buttonElement.keyup(function(event) {
3022                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
3023                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
3024                                                 $( this ).click();
3025                                         }
3026                                 });
3027                         }
3028                 }
3029
3030                 // TODO: pull out $.Widget's handling for the disabled option into
3031                 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
3032                 // be overridden by individual plugins
3033                 this._setOption( "disabled", options.disabled );
3034                 this._resetButton();
3035         },
3036
3037         _determineButtonType: function() {
3038                 var ancestor, labelSelector, checked;
3039
3040                 if ( this.element.is("[type=checkbox]") ) {
3041                         this.type = "checkbox";
3042                 } else if ( this.element.is("[type=radio]") ) {
3043                         this.type = "radio";
3044                 } else if ( this.element.is("input") ) {
3045                         this.type = "input";
3046                 } else {
3047                         this.type = "button";
3048                 }
3049
3050                 if ( this.type === "checkbox" || this.type === "radio" ) {
3051                         // we don't search against the document in case the element
3052                         // is disconnected from the DOM
3053                         ancestor = this.element.parents().last();
3054                         labelSelector = "label[for='" + this.element.attr("id") + "']";
3055                         this.buttonElement = ancestor.find( labelSelector );
3056                         if ( !this.buttonElement.length ) {
3057                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3058                                 this.buttonElement = ancestor.filter( labelSelector );
3059                                 if ( !this.buttonElement.length ) {
3060                                         this.buttonElement = ancestor.find( labelSelector );
3061                                 }
3062                         }
3063                         this.element.addClass( "ui-helper-hidden-accessible" );
3064
3065                         checked = this.element.is( ":checked" );
3066                         if ( checked ) {
3067                                 this.buttonElement.addClass( "ui-state-active" );
3068                         }
3069                         this.buttonElement.prop( "aria-pressed", checked );
3070                 } else {
3071                         this.buttonElement = this.element;
3072                 }
3073         },
3074
3075         widget: function() {
3076                 return this.buttonElement;
3077         },
3078
3079         _destroy: function() {
3080                 this.element
3081                         .removeClass( "ui-helper-hidden-accessible" );
3082                 this.buttonElement
3083                         .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
3084                         .removeAttr( "role" )
3085                         .removeAttr( "aria-pressed" )
3086                         .html( this.buttonElement.find(".ui-button-text").html() );
3087
3088                 if ( !this.hasTitle ) {
3089                         this.buttonElement.removeAttr( "title" );
3090                 }
3091         },
3092
3093         _setOption: function( key, value ) {
3094                 this._super( key, value );
3095                 if ( key === "disabled" ) {
3096                         if ( value ) {
3097                                 this.element.prop( "disabled", true );
3098                         } else {
3099                                 this.element.prop( "disabled", false );
3100                         }
3101                         return;
3102                 }
3103                 this._resetButton();
3104         },
3105
3106         refresh: function() {
3107                 //See #8237 & #8828
3108                 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
3109
3110                 if ( isDisabled !== this.options.disabled ) {
3111                         this._setOption( "disabled", isDisabled );
3112                 }
3113                 if ( this.type === "radio" ) {
3114                         radioGroup( this.element[0] ).each(function() {
3115                                 if ( $( this ).is( ":checked" ) ) {
3116                                         $( this ).button( "widget" )
3117                                                 .addClass( "ui-state-active" )
3118                                                 .attr( "aria-pressed", "true" );
3119                                 } else {
3120                                         $( this ).button( "widget" )
3121                                                 .removeClass( "ui-state-active" )
3122                                                 .attr( "aria-pressed", "false" );
3123                                 }
3124                         });
3125                 } else if ( this.type === "checkbox" ) {
3126                         if ( this.element.is( ":checked" ) ) {
3127                                 this.buttonElement
3128                                         .addClass( "ui-state-active" )
3129                                         .attr( "aria-pressed", "true" );
3130                         } else {
3131                                 this.buttonElement
3132                                         .removeClass( "ui-state-active" )
3133                                         .attr( "aria-pressed", "false" );
3134                         }
3135                 }
3136         },
3137
3138         _resetButton: function() {
3139                 if ( this.type === "input" ) {
3140                         if ( this.options.label ) {
3141                                 this.element.val( this.options.label );
3142                         }
3143                         return;
3144                 }
3145                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
3146                         buttonText = $( "<span></span>", this.document[0] )
3147                                 .addClass( "ui-button-text" )
3148                                 .html( this.options.label )
3149                                 .appendTo( buttonElement.empty() )
3150                                 .text(),
3151                         icons = this.options.icons,
3152                         multipleIcons = icons.primary && icons.secondary,
3153                         buttonClasses = [];
3154
3155                 if ( icons.primary || icons.secondary ) {
3156                         if ( this.options.text ) {
3157                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
3158                         }
3159
3160                         if ( icons.primary ) {
3161                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
3162                         }
3163
3164                         if ( icons.secondary ) {
3165                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
3166                         }
3167
3168                         if ( !this.options.text ) {
3169                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
3170
3171                                 if ( !this.hasTitle ) {
3172                                         buttonElement.attr( "title", $.trim( buttonText ) );
3173                                 }
3174                         }
3175                 } else {
3176                         buttonClasses.push( "ui-button-text-only" );
3177                 }
3178                 buttonElement.addClass( buttonClasses.join( " " ) );
3179         }
3180 });
3181
3182 $.widget( "ui.buttonset", {
3183         version: "1.9.2",
3184         options: {
3185                 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
3186         },
3187
3188         _create: function() {
3189                 this.element.addClass( "ui-buttonset" );
3190         },
3191
3192         _init: function() {
3193                 this.refresh();
3194         },
3195
3196         _setOption: function( key, value ) {
3197                 if ( key === "disabled" ) {
3198                         this.buttons.button( "option", key, value );
3199                 }
3200
3201                 this._super( key, value );
3202         },
3203
3204         refresh: function() {
3205                 var rtl = this.element.css( "direction" ) === "rtl";
3206
3207                 this.buttons = this.element.find( this.options.items )
3208                         .filter( ":ui-button" )
3209                                 .button( "refresh" )
3210                         .end()
3211                         .not( ":ui-button" )
3212                                 .button()
3213                         .end()
3214                         .map(function() {
3215                                 return $( this ).button( "widget" )[ 0 ];
3216                         })
3217                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
3218                                 .filter( ":first" )
3219                                         .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
3220                                 .end()
3221                                 .filter( ":last" )
3222                                         .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
3223                                 .end()
3224                         .end();
3225         },
3226
3227         _destroy: function() {
3228                 this.element.removeClass( "ui-buttonset" );
3229                 this.buttons
3230                         .map(function() {
3231                                 return $( this ).button( "widget" )[ 0 ];
3232                         })
3233                                 .removeClass( "ui-corner-left ui-corner-right" )
3234                         .end()
3235                         .button( "destroy" );
3236         }
3237 });
3238
3239 }( jQuery ) );
3240 (function( $, undefined ) {
3241
3242 $.extend($.ui, { datepicker: { version: "1.9.2" } });
3243
3244 var PROP_NAME = 'datepicker';
3245 var dpuuid = new Date().getTime();
3246 var instActive;
3247
3248 /* Date picker manager.
3249    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
3250    Settings for (groups of) date pickers are maintained in an instance object,
3251    allowing multiple different settings on the same page. */
3252
3253 function Datepicker() {
3254         this.debug = false; // Change this to true to start debugging
3255         this._curInst = null; // The current instance in use
3256         this._keyEvent = false; // If the last event was a key event
3257         this._disabledInputs = []; // List of date picker inputs that have been disabled
3258         this._datepickerShowing = false; // True if the popup picker is showing , false if not
3259         this._inDialog = false; // True if showing within a "dialog", false if not
3260         this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
3261         this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
3262         this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
3263         this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
3264         this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
3265         this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
3266         this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
3267         this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
3268         this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
3269         this.regional = []; // Available regional settings, indexed by language code
3270         this.regional[''] = { // Default regional settings
3271                 closeText: 'Done', // Display text for close link
3272                 prevText: 'Prev', // Display text for previous month link
3273                 nextText: 'Next', // Display text for next month link
3274                 currentText: 'Today', // Display text for current month link
3275                 monthNames: ['January','February','March','April','May','June',
3276                         'July','August','September','October','November','December'], // Names of months for drop-down and formatting
3277                 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
3278                 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
3279                 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
3280                 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
3281                 weekHeader: 'Wk', // Column header for week of the year
3282                 dateFormat: 'mm/dd/yy', // See format options on parseDate
3283                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
3284                 isRTL: false, // True if right-to-left language, false if left-to-right
3285                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
3286                 yearSuffix: '' // Additional text to append to the year in the month headers
3287         };
3288         this._defaults = { // Global defaults for all the date picker instances
3289                 showOn: 'focus', // 'focus' for popup on focus,
3290                         // 'button' for trigger button, or 'both' for either
3291                 showAnim: 'fadeIn', // Name of jQuery animation for popup
3292                 showOptions: {}, // Options for enhanced animations
3293                 defaultDate: null, // Used when field is blank: actual date,
3294                         // +/-number for offset from today, null for today
3295                 appendText: '', // Display text following the input box, e.g. showing the format
3296                 buttonText: '...', // Text for trigger button
3297                 buttonImage: '', // URL for trigger button image
3298                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
3299                 hideIfNoPrevNext: false, // True to hide next/previous month links
3300                         // if not applicable, false to just disable them
3301                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
3302                 gotoCurrent: false, // True if today link goes back to current selection instead
3303                 changeMonth: false, // True if month can be selected directly, false if only prev/next
3304                 changeYear: false, // True if year can be selected directly, false if only prev/next
3305                 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
3306                         // either relative to today's year (-nn:+nn), relative to currently displayed year
3307                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
3308                 showOtherMonths: false, // True to show dates in other months, false to leave blank
3309                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
3310                 showWeek: false, // True to show week of the year, false to not show it
3311                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
3312                         // takes a Date and returns the number of the week for it
3313                 shortYearCutoff: '+10', // Short year values < this are in the current century,
3314                         // > this are in the previous century,
3315                         // string value starting with '+' for current year + value
3316                 minDate: null, // The earliest selectable date, or null for no limit
3317                 maxDate: null, // The latest selectable date, or null for no limit
3318                 duration: 'fast', // Duration of display/closure
3319                 beforeShowDay: null, // Function that takes a date and returns an array with
3320                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
3321                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
3322                 beforeShow: null, // Function that takes an input field and
3323                         // returns a set of custom settings for the date picker
3324                 onSelect: null, // Define a callback function when a date is selected
3325                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
3326                 onClose: null, // Define a callback function when the datepicker is closed
3327                 numberOfMonths: 1, // Number of months to show at a time
3328                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
3329                 stepMonths: 1, // Number of months to step back/forward
3330                 stepBigMonths: 12, // Number of months to step back/forward for the big links
3331                 altField: '', // Selector for an alternate field to store selected dates into
3332                 altFormat: '', // The date format to use for the alternate field
3333                 constrainInput: true, // The input is constrained by the current date format
3334                 showButtonPanel: false, // True to show button panel, false to not show it
3335                 autoSize: false, // True to size the input for the date format, false to leave as is
3336                 disabled: false // The initial disabled state
3337         };
3338         $.extend(this._defaults, this.regional['']);
3339         this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
3340 }
3341
3342 $.extend(Datepicker.prototype, {
3343         /* Class name added to elements to indicate already configured with a date picker. */
3344         markerClassName: 'hasDatepicker',
3345
3346         //Keep track of the maximum number of rows displayed (see #7043)
3347         maxRows: 4,
3348
3349         /* Debug logging (if enabled). */
3350         log: function () {
3351                 if (this.debug)
3352                         console.log.apply('', arguments);
3353         },
3354
3355         // TODO rename to "widget" when switching to widget factory
3356         _widgetDatepicker: function() {
3357                 return this.dpDiv;
3358         },
3359
3360         /* Override the default settings for all instances of the date picker.
3361            @param  settings  object - the new settings to use as defaults (anonymous object)
3362            @return the manager object */
3363         setDefaults: function(settings) {
3364                 extendRemove(this._defaults, settings || {});
3365                 return this;
3366         },
3367
3368         /* Attach the date picker to a jQuery selection.
3369            @param  target    element - the target input field or division or span
3370            @param  settings  object - the new settings to use for this date picker instance (anonymous) */
3371         _attachDatepicker: function(target, settings) {
3372                 // check for settings on the control itself - in namespace 'date:'
3373                 var inlineSettings = null;
3374                 for (var attrName in this._defaults) {
3375                         var attrValue = target.getAttribute('date:' + attrName);
3376                         if (attrValue) {
3377                                 inlineSettings = inlineSettings || {};
3378                                 try {
3379                                         inlineSettings[attrName] = eval(attrValue);
3380                                 } catch (err) {
3381                                         inlineSettings[attrName] = attrValue;
3382                                 }
3383                         }
3384                 }
3385                 var nodeName = target.nodeName.toLowerCase();
3386                 var inline = (nodeName == 'div' || nodeName == 'span');
3387                 if (!target.id) {
3388                         this.uuid += 1;
3389                         target.id = 'dp' + this.uuid;
3390                 }
3391                 var inst = this._newInst($(target), inline);
3392                 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
3393                 if (nodeName == 'input') {
3394                         this._connectDatepicker(target, inst);
3395                 } else if (inline) {
3396                         this._inlineDatepicker(target, inst);
3397                 }
3398         },
3399
3400         /* Create a new instance object. */
3401         _newInst: function(target, inline) {
3402                 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
3403                 return {id: id, input: target, // associated target
3404                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
3405                         drawMonth: 0, drawYear: 0, // month being drawn
3406                         inline: inline, // is datepicker inline or not
3407                         dpDiv: (!inline ? this.dpDiv : // presentation div
3408                         bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
3409         },
3410
3411         /* Attach the date picker to an input field. */
3412         _connectDatepicker: function(target, inst) {
3413                 var input = $(target);
3414                 inst.append = $([]);
3415                 inst.trigger = $([]);
3416                 if (input.hasClass(this.markerClassName))
3417                         return;
3418                 this._attachments(input, inst);
3419                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
3420                         keypress(this._doKeyPress).keyup(this._doKeyUp).
3421                         bind("setData.datepicker", function(event, key, value) {
3422                                 inst.settings[key] = value;
3423                         }).bind("getData.datepicker", function(event, key) {
3424                                 return this._get(inst, key);
3425                         });
3426                 this._autoSize(inst);
3427                 $.data(target, PROP_NAME, inst);
3428                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
3429                 if( inst.settings.disabled ) {
3430                         this._disableDatepicker( target );
3431                 }
3432         },
3433
3434         /* Make attachments based on settings. */
3435         _attachments: function(input, inst) {
3436                 var appendText = this._get(inst, 'appendText');
3437                 var isRTL = this._get(inst, 'isRTL');
3438                 if (inst.append)
3439                         inst.append.remove();
3440                 if (appendText) {
3441                         inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
3442                         input[isRTL ? 'before' : 'after'](inst.append);
3443                 }
3444                 input.unbind('focus', this._showDatepicker);
3445                 if (inst.trigger)
3446                         inst.trigger.remove();
3447                 var showOn = this._get(inst, 'showOn');
3448                 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
3449                         input.focus(this._showDatepicker);
3450                 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
3451                         var buttonText = this._get(inst, 'buttonText');
3452                         var buttonImage = this._get(inst, 'buttonImage');
3453                         inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
3454                                 $('<img/>').addClass(this._triggerClass).
3455                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
3456                                 $('<button type="button"></button>').addClass(this._triggerClass).
3457                                         html(buttonImage == '' ? buttonText : $('<img/>').attr(
3458                                         { src:buttonImage, alt:buttonText, title:buttonText })));
3459                         input[isRTL ? 'before' : 'after'](inst.trigger);
3460                         inst.trigger.click(function() {
3461                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
3462                                         $.datepicker._hideDatepicker();
3463                                 else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
3464                                         $.datepicker._hideDatepicker();
3465                                         $.datepicker._showDatepicker(input[0]);
3466                                 } else
3467                                         $.datepicker._showDatepicker(input[0]);
3468                                 return false;
3469                         });
3470                 }
3471         },
3472
3473         /* Apply the maximum length for the date format. */
3474         _autoSize: function(inst) {
3475                 if (this._get(inst, 'autoSize') && !inst.inline) {
3476                         var date = new Date(2009, 12 - 1, 20); // Ensure double digits
3477                         var dateFormat = this._get(inst, 'dateFormat');
3478                         if (dateFormat.match(/[DM]/)) {
3479                                 var findMax = function(names) {
3480                                         var max = 0;
3481                                         var maxI = 0;
3482                                         for (var i = 0; i < names.length; i++) {
3483                                                 if (names[i].length > max) {
3484                                                         max = names[i].length;
3485                                                         maxI = i;
3486                                                 }
3487                                         }
3488                                         return maxI;
3489                                 };
3490                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
3491                                         'monthNames' : 'monthNamesShort'))));
3492                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
3493                                         'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
3494                         }
3495                         inst.input.attr('size', this._formatDate(inst, date).length);
3496                 }
3497         },
3498
3499         /* Attach an inline date picker to a div. */
3500         _inlineDatepicker: function(target, inst) {
3501                 var divSpan = $(target);
3502                 if (divSpan.hasClass(this.markerClassName))
3503                         return;
3504                 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
3505                         bind("setData.datepicker", function(event, key, value){
3506                                 inst.settings[key] = value;
3507                         }).bind("getData.datepicker", function(event, key){
3508                                 return this._get(inst, key);
3509                         });
3510                 $.data(target, PROP_NAME, inst);
3511                 this._setDate(inst, this._getDefaultDate(inst), true);
3512                 this._updateDatepicker(inst);
3513                 this._updateAlternate(inst);
3514                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
3515                 if( inst.settings.disabled ) {
3516                         this._disableDatepicker( target );
3517                 }
3518                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
3519                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
3520                 inst.dpDiv.css( "display", "block" );
3521         },
3522
3523         /* Pop-up the date picker in a "dialog" box.
3524            @param  input     element - ignored
3525            @param  date      string or Date - the initial date to display
3526            @param  onSelect  function - the function to call when a date is selected
3527            @param  settings  object - update the dialog date picker instance's settings (anonymous object)
3528            @param  pos       int[2] - coordinates for the dialog's position within the screen or
3529                              event - with x/y coordinates or
3530                              leave empty for default (screen centre)
3531            @return the manager object */
3532         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
3533                 var inst = this._dialogInst; // internal instance
3534                 if (!inst) {
3535                         this.uuid += 1;
3536                         var id = 'dp' + this.uuid;
3537                         this._dialogInput = $('<input type="text" id="' + id +
3538                                 '" style="position: absolute; top: -100px; width: 0px;"/>');
3539                         this._dialogInput.keydown(this._doKeyDown);
3540                         $('body').append(this._dialogInput);
3541                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
3542                         inst.settings = {};
3543                         $.data(this._dialogInput[0], PROP_NAME, inst);
3544                 }
3545                 extendRemove(inst.settings, settings || {});
3546                 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
3547                 this._dialogInput.val(date);
3548
3549                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
3550                 if (!this._pos) {
3551                         var browserWidth = document.documentElement.clientWidth;
3552                         var browserHeight = document.documentElement.clientHeight;
3553                         var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
3554                         var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
3555                         this._pos = // should use actual width/height below
3556                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
3557                 }
3558
3559                 // move input on screen for focus, but hidden behind dialog
3560                 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
3561                 inst.settings.onSelect = onSelect;
3562                 this._inDialog = true;
3563                 this.dpDiv.addClass(this._dialogClass);
3564                 this._showDatepicker(this._dialogInput[0]);
3565                 if ($.blockUI)
3566                         $.blockUI(this.dpDiv);
3567                 $.data(this._dialogInput[0], PROP_NAME, inst);
3568                 return this;
3569         },
3570
3571         /* Detach a datepicker from its control.
3572            @param  target    element - the target input field or division or span */
3573         _destroyDatepicker: function(target) {
3574                 var $target = $(target);
3575                 var inst = $.data(target, PROP_NAME);
3576                 if (!$target.hasClass(this.markerClassName)) {
3577                         return;
3578                 }
3579                 var nodeName = target.nodeName.toLowerCase();
3580                 $.removeData(target, PROP_NAME);
3581                 if (nodeName == 'input') {
3582                         inst.append.remove();
3583                         inst.trigger.remove();
3584                         $target.removeClass(this.markerClassName).
3585                                 unbind('focus', this._showDatepicker).
3586                                 unbind('keydown', this._doKeyDown).
3587                                 unbind('keypress', this._doKeyPress).
3588                                 unbind('keyup', this._doKeyUp);
3589                 } else if (nodeName == 'div' || nodeName == 'span')
3590                         $target.removeClass(this.markerClassName).empty();
3591         },
3592
3593         /* Enable the date picker to a jQuery selection.
3594            @param  target    element - the target input field or division or span */
3595         _enableDatepicker: function(target) {
3596                 var $target = $(target);
3597                 var inst = $.data(target, PROP_NAME);
3598                 if (!$target.hasClass(this.markerClassName)) {
3599                         return;
3600                 }
3601                 var nodeName = target.nodeName.toLowerCase();
3602                 if (nodeName == 'input') {
3603                         target.disabled = false;
3604                         inst.trigger.filter('button').
3605                                 each(function() { this.disabled = false; }).end().
3606                                 filter('img').css({opacity: '1.0', cursor: ''});
3607                 }
3608                 else if (nodeName == 'div' || nodeName == 'span') {
3609                         var inline = $target.children('.' + this._inlineClass);
3610                         inline.children().removeClass('ui-state-disabled');
3611                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
3612                                 prop("disabled", false);
3613                 }
3614                 this._disabledInputs = $.map(this._disabledInputs,
3615                         function(value) { return (value == target ? null : value); }); // delete entry
3616         },
3617
3618         /* Disable the date picker to a jQuery selection.
3619            @param  target    element - the target input field or division or span */
3620         _disableDatepicker: function(target) {
3621                 var $target = $(target);
3622                 var inst = $.data(target, PROP_NAME);
3623                 if (!$target.hasClass(this.markerClassName)) {
3624                         return;
3625                 }
3626                 var nodeName = target.nodeName.toLowerCase();
3627                 if (nodeName == 'input') {
3628                         target.disabled = true;
3629                         inst.trigger.filter('button').
3630                                 each(function() { this.disabled = true; }).end().
3631                                 filter('img').css({opacity: '0.5', cursor: 'default'});
3632                 }
3633                 else if (nodeName == 'div' || nodeName == 'span') {
3634                         var inline = $target.children('.' + this._inlineClass);
3635                         inline.children().addClass('ui-state-disabled');
3636                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
3637                                 prop("disabled", true);
3638                 }
3639                 this._disabledInputs = $.map(this._disabledInputs,
3640                         function(value) { return (value == target ? null : value); }); // delete entry
3641                 this._disabledInputs[this._disabledInputs.length] = target;
3642         },
3643
3644         /* Is the first field in a jQuery collection disabled as a datepicker?
3645            @param  target    element - the target input field or division or span
3646            @return boolean - true if disabled, false if enabled */
3647         _isDisabledDatepicker: function(target) {
3648                 if (!target) {
3649                         return false;
3650                 }
3651                 for (var i = 0; i < this._disabledInputs.length; i++) {
3652                         if (this._disabledInputs[i] == target)
3653                                 return true;
3654                 }
3655                 return false;
3656         },
3657
3658         /* Retrieve the instance data for the target control.
3659            @param  target  element - the target input field or division or span
3660            @return  object - the associated instance data
3661            @throws  error if a jQuery problem getting data */
3662         _getInst: function(target) {
3663                 try {
3664                         return $.data(target, PROP_NAME);
3665                 }
3666                 catch (err) {
3667                         throw 'Missing instance data for this datepicker';
3668                 }
3669         },
3670
3671         /* Update or retrieve the settings for a date picker attached to an input field or division.
3672            @param  target  element - the target input field or division or span
3673            @param  name    object - the new settings to update or
3674                            string - the name of the setting to change or retrieve,
3675                            when retrieving also 'all' for all instance settings or
3676                            'defaults' for all global defaults
3677            @param  value   any - the new value for the setting
3678                            (omit if above is an object or to retrieve a value) */
3679         _optionDatepicker: function(target, name, value) {
3680                 var inst = this._getInst(target);
3681                 if (arguments.length == 2 && typeof name == 'string') {
3682                         return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
3683                                 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
3684                                 this._get(inst, name)) : null));
3685                 }
3686                 var settings = name || {};
3687                 if (typeof name == 'string') {
3688                         settings = {};
3689                         settings[name] = value;
3690                 }
3691                 if (inst) {
3692                         if (this._curInst == inst) {
3693                                 this._hideDatepicker();
3694                         }
3695                         var date = this._getDateDatepicker(target, true);
3696                         var minDate = this._getMinMaxDate(inst, 'min');
3697                         var maxDate = this._getMinMaxDate(inst, 'max');
3698                         extendRemove(inst.settings, settings);
3699                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
3700                         if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
3701                                 inst.settings.minDate = this._formatDate(inst, minDate);
3702                         if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
3703                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
3704                         this._attachments($(target), inst);
3705                         this._autoSize(inst);
3706                         this._setDate(inst, date);
3707                         this._updateAlternate(inst);
3708                         this._updateDatepicker(inst);
3709                 }
3710         },
3711
3712         // change method deprecated
3713         _changeDatepicker: function(target, name, value) {
3714                 this._optionDatepicker(target, name, value);
3715         },
3716
3717         /* Redraw the date picker attached to an input field or division.
3718            @param  target  element - the target input field or division or span */
3719         _refreshDatepicker: function(target) {
3720                 var inst = this._getInst(target);
3721                 if (inst) {
3722                         this._updateDatepicker(inst);
3723                 }
3724         },
3725
3726         /* Set the dates for a jQuery selection.
3727            @param  target   element - the target input field or division or span
3728            @param  date     Date - the new date */
3729         _setDateDatepicker: function(target, date) {
3730                 var inst = this._getInst(target);
3731                 if (inst) {
3732                         this._setDate(inst, date);
3733                         this._updateDatepicker(inst);
3734                         this._updateAlternate(inst);
3735                 }
3736         },
3737
3738         /* Get the date(s) for the first entry in a jQuery selection.
3739            @param  target     element - the target input field or division or span
3740            @param  noDefault  boolean - true if no default date is to be used
3741            @return Date - the current date */
3742         _getDateDatepicker: function(target, noDefault) {
3743                 var inst = this._getInst(target);
3744                 if (inst && !inst.inline)
3745                         this._setDateFromField(inst, noDefault);
3746                 return (inst ? this._getDate(inst) : null);
3747         },
3748
3749         /* Handle keystrokes. */
3750         _doKeyDown: function(event) {
3751                 var inst = $.datepicker._getInst(event.target);
3752                 var handled = true;
3753                 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
3754                 inst._keyEvent = true;
3755                 if ($.datepicker._datepickerShowing)
3756                         switch (event.keyCode) {
3757                                 case 9: $.datepicker._hideDatepicker();
3758                                                 handled = false;
3759                                                 break; // hide on tab out
3760                                 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
3761                                                                         $.datepicker._currentClass + ')', inst.dpDiv);
3762                                                 if (sel[0])
3763                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
3764                                                         var onSelect = $.datepicker._get(inst, 'onSelect');
3765                                                         if (onSelect) {
3766                                                                 var dateStr = $.datepicker._formatDate(inst);
3767
3768                                                                 // trigger custom callback
3769                                                                 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
3770                                                         }
3771                                                 else
3772                                                         $.datepicker._hideDatepicker();
3773                                                 return false; // don't submit the form
3774                                                 break; // select the value on enter
3775                                 case 27: $.datepicker._hideDatepicker();
3776                                                 break; // hide on escape
3777                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
3778                                                         -$.datepicker._get(inst, 'stepBigMonths') :
3779                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
3780                                                 break; // previous month/year on page up/+ ctrl
3781                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
3782                                                         +$.datepicker._get(inst, 'stepBigMonths') :
3783                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
3784                                                 break; // next month/year on page down/+ ctrl
3785                                 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
3786                                                 handled = event.ctrlKey || event.metaKey;
3787                                                 break; // clear on ctrl or command +end
3788                                 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
3789                                                 handled = event.ctrlKey || event.metaKey;
3790                                                 break; // current on ctrl or command +home
3791                                 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
3792                                                 handled = event.ctrlKey || event.metaKey;
3793                                                 // -1 day on ctrl or command +left
3794                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
3795                                                                         -$.datepicker._get(inst, 'stepBigMonths') :
3796                                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
3797                                                 // next month/year on alt +left on Mac
3798                                                 break;
3799                                 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
3800                                                 handled = event.ctrlKey || event.metaKey;
3801                                                 break; // -1 week on ctrl or command +up
3802                                 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
3803                                                 handled = event.ctrlKey || event.metaKey;
3804                                                 // +1 day on ctrl or command +right
3805                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
3806                                                                         +$.datepicker._get(inst, 'stepBigMonths') :
3807                                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
3808                                                 // next month/year on alt +right
3809                                                 break;
3810                                 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
3811                                                 handled = event.ctrlKey || event.metaKey;
3812                                                 break; // +1 week on ctrl or command +down
3813                                 default: handled = false;
3814                         }
3815                 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
3816                         $.datepicker._showDatepicker(this);
3817                 else {
3818                         handled = false;
3819                 }
3820                 if (handled) {
3821                         event.preventDefault();
3822                         event.stopPropagation();
3823                 }
3824         },
3825
3826         /* Filter entered characters - based on date format. */
3827         _doKeyPress: function(event) {
3828                 var inst = $.datepicker._getInst(event.target);
3829                 if ($.datepicker._get(inst, 'constrainInput')) {
3830                         var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
3831                         var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
3832                         return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
3833                 }
3834         },
3835
3836         /* Synchronise manual entry and field/alternate field. */
3837         _doKeyUp: function(event) {
3838                 var inst = $.datepicker._getInst(event.target);
3839                 if (inst.input.val() != inst.lastVal) {
3840                         try {
3841                                 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
3842                                         (inst.input ? inst.input.val() : null),
3843                                         $.datepicker._getFormatConfig(inst));
3844                                 if (date) { // only if valid
3845                                         $.datepicker._setDateFromField(inst);
3846                                         $.datepicker._updateAlternate(inst);
3847                                         $.datepicker._updateDatepicker(inst);
3848                                 }
3849                         }
3850                         catch (err) {
3851                                 $.datepicker.log(err);
3852                         }
3853                 }
3854                 return true;
3855         },
3856
3857         /* Pop-up the date picker for a given input field.
3858            If false returned from beforeShow event handler do not show.
3859            @param  input  element - the input field attached to the date picker or
3860                           event - if triggered by focus */
3861         _showDatepicker: function(input) {
3862                 input = input.target || input;
3863                 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
3864                         input = $('input', input.parentNode)[0];
3865                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
3866                         return;
3867                 var inst = $.datepicker._getInst(input);
3868                 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
3869                         $.datepicker._curInst.dpDiv.stop(true, true);
3870                         if ( inst && $.datepicker._datepickerShowing ) {
3871                                 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
3872                         }
3873                 }
3874                 var beforeShow = $.datepicker._get(inst, 'beforeShow');
3875                 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
3876                 if(beforeShowSettings === false){
3877                         //false
3878                         return;
3879                 }
3880                 extendRemove(inst.settings, beforeShowSettings);
3881                 inst.lastVal = null;
3882                 $.datepicker._lastInput = input;
3883                 $.datepicker._setDateFromField(inst);
3884                 if ($.datepicker._inDialog) // hide cursor
3885                         input.value = '';
3886                 if (!$.datepicker._pos) { // position below input
3887                         $.datepicker._pos = $.datepicker._findPos(input);
3888                         $.datepicker._pos[1] += input.offsetHeight; // add the height
3889                 }
3890                 var isFixed = false;
3891                 $(input).parents().each(function() {
3892                         isFixed |= $(this).css('position') == 'fixed';
3893                         return !isFixed;
3894                 });
3895                 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
3896                 $.datepicker._pos = null;
3897                 //to avoid flashes on Firefox
3898                 inst.dpDiv.empty();
3899                 // determine sizing offscreen
3900                 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
3901                 $.datepicker._updateDatepicker(inst);
3902                 // fix width for dynamic number of date pickers
3903                 // and adjust position before showing
3904                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
3905                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
3906                         'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
3907                         left: offset.left + 'px', top: offset.top + 'px'});
3908                 if (!inst.inline) {
3909                         var showAnim = $.datepicker._get(inst, 'showAnim');
3910                         var duration = $.datepicker._get(inst, 'duration');
3911                         var postProcess = function() {
3912                                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
3913                                 if( !! cover.length ){
3914                                         var borders = $.datepicker._getBorders(inst.dpDiv);
3915                                         cover.css({left: -borders[0], top: -borders[1],
3916                                                 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
3917                                 }
3918                         };
3919                         inst.dpDiv.zIndex($(input).zIndex()+1);
3920                         $.datepicker._datepickerShowing = true;
3921
3922                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
3923                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
3924                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
3925                         else
3926                                 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
3927                         if (!showAnim || !duration)
3928                                 postProcess();
3929                         if (inst.input.is(':visible') && !inst.input.is(':disabled'))
3930                                 inst.input.focus();
3931                         $.datepicker._curInst = inst;
3932                 }
3933         },
3934
3935         /* Generate the date picker content. */
3936         _updateDatepicker: function(inst) {
3937                 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
3938                 var borders = $.datepicker._getBorders(inst.dpDiv);
3939                 instActive = inst; // for delegate hover events
3940                 inst.dpDiv.empty().append(this._generateHTML(inst));
3941                 this._attachHandlers(inst);
3942                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
3943                 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
3944                         cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
3945                 }
3946                 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
3947                 var numMonths = this._getNumberOfMonths(inst);
3948                 var cols = numMonths[1];
3949                 var width = 17;
3950                 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
3951                 if (cols > 1)
3952                         inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
3953                 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
3954                         'Class']('ui-datepicker-multi');
3955                 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
3956                         'Class']('ui-datepicker-rtl');
3957                 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
3958                                 // #6694 - don't focus the input if it's already focused
3959                                 // this breaks the change event in IE
3960                                 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
3961                         inst.input.focus();
3962                 // deffered render of the years select (to avoid flashes on Firefox)
3963                 if( inst.yearshtml ){
3964                         var origyearshtml = inst.yearshtml;
3965                         setTimeout(function(){
3966                                 //assure that inst.yearshtml didn't change.
3967                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
3968                                         inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
3969                                 }
3970                                 origyearshtml = inst.yearshtml = null;
3971                         }, 0);
3972                 }
3973         },
3974
3975         /* Retrieve the size of left and top borders for an element.
3976            @param  elem  (jQuery object) the element of interest
3977            @return  (number[2]) the left and top borders */
3978         _getBorders: function(elem) {
3979                 var convert = function(value) {
3980                         return {thin: 1, medium: 2, thick: 3}[value] || value;
3981                 };
3982                 return [parseFloat(convert(elem.css('border-left-width'))),
3983                         parseFloat(convert(elem.css('border-top-width')))];
3984         },
3985
3986         /* Check positioning to remain on screen. */
3987         _checkOffset: function(inst, offset, isFixed) {
3988                 var dpWidth = inst.dpDiv.outerWidth();
3989                 var dpHeight = inst.dpDiv.outerHeight();
3990                 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
3991                 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
3992                 var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
3993                 var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
3994
3995                 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
3996                 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
3997                 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
3998
3999                 // now check if datepicker is showing outside window viewport - move to a better place if so.
4000                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4001                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
4002                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4003                         Math.abs(dpHeight + inputHeight) : 0);
4004
4005                 return offset;
4006         },
4007
4008         /* Find an object's position on the screen. */
4009         _findPos: function(obj) {
4010                 var inst = this._getInst(obj);
4011                 var isRTL = this._get(inst, 'isRTL');
4012                 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
4013                         obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
4014                 }
4015                 var position = $(obj).offset();
4016                 return [position.left, position.top];
4017         },
4018
4019         /* Hide the date picker from view.
4020            @param  input  element - the input field attached to the date picker */
4021         _hideDatepicker: function(input) {
4022                 var inst = this._curInst;
4023                 if (!inst || (input && inst != $.data(input, PROP_NAME)))
4024                         return;
4025                 if (this._datepickerShowing) {
4026                         var showAnim = this._get(inst, 'showAnim');
4027                         var duration = this._get(inst, 'duration');
4028                         var postProcess = function() {
4029                                 $.datepicker._tidyDialog(inst);
4030                         };
4031
4032                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
4033                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
4034                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
4035                         else
4036                                 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
4037                                         (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
4038                         if (!showAnim)
4039                                 postProcess();
4040                         this._datepickerShowing = false;
4041                         var onClose = this._get(inst, 'onClose');
4042                         if (onClose)
4043                                 onClose.apply((inst.input ? inst.input[0] : null),
4044                                         [(inst.input ? inst.input.val() : ''), inst]);
4045                         this._lastInput = null;
4046                         if (this._inDialog) {
4047                                 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
4048                                 if ($.blockUI) {
4049                                         $.unblockUI();
4050                                         $('body').append(this.dpDiv);
4051                                 }
4052                         }
4053                         this._inDialog = false;
4054                 }
4055         },
4056
4057         /* Tidy up after a dialog display. */
4058         _tidyDialog: function(inst) {
4059                 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
4060         },
4061
4062         /* Close date picker if clicked elsewhere. */
4063         _checkExternalClick: function(event) {
4064                 if (!$.datepicker._curInst)
4065                         return;
4066
4067                 var $target = $(event.target),
4068                         inst = $.datepicker._getInst($target[0]);
4069
4070                 if ( ( ( $target[0].id != $.datepicker._mainDivId &&
4071                                 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
4072                                 !$target.hasClass($.datepicker.markerClassName) &&
4073                                 !$target.closest("." + $.datepicker._triggerClass).length &&
4074                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
4075                         ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
4076                         $.datepicker._hideDatepicker();
4077         },
4078
4079         /* Adjust one of the date sub-fields. */
4080         _adjustDate: function(id, offset, period) {
4081                 var target = $(id);
4082                 var inst = this._getInst(target[0]);
4083                 if (this._isDisabledDatepicker(target[0])) {
4084                         return;
4085                 }
4086                 this._adjustInstDate(inst, offset +
4087                         (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
4088                         period);
4089                 this._updateDatepicker(inst);
4090         },
4091
4092         /* Action for current link. */
4093         _gotoToday: function(id) {
4094                 var target = $(id);
4095                 var inst = this._getInst(target[0]);
4096                 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
4097                         inst.selectedDay = inst.currentDay;
4098                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
4099                         inst.drawYear = inst.selectedYear = inst.currentYear;
4100                 }
4101                 else {
4102                         var date = new Date();
4103                         inst.selectedDay = date.getDate();
4104                         inst.drawMonth = inst.selectedMonth = date.getMonth();
4105                         inst.drawYear = inst.selectedYear = date.getFullYear();
4106                 }
4107                 this._notifyChange(inst);
4108                 this._adjustDate(target);
4109         },
4110
4111         /* Action for selecting a new month/year. */
4112         _selectMonthYear: function(id, select, period) {
4113                 var target = $(id);
4114                 var inst = this._getInst(target[0]);
4115                 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
4116                 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
4117                         parseInt(select.options[select.selectedIndex].value,10);
4118                 this._notifyChange(inst);
4119                 this._adjustDate(target);
4120         },
4121
4122         /* Action for selecting a day. */
4123         _selectDay: function(id, month, year, td) {
4124                 var target = $(id);
4125                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
4126                         return;
4127                 }
4128                 var inst = this._getInst(target[0]);
4129                 inst.selectedDay = inst.currentDay = $('a', td).html();
4130                 inst.selectedMonth = inst.currentMonth = month;
4131                 inst.selectedYear = inst.currentYear = year;
4132                 this._selectDate(id, this._formatDate(inst,
4133                         inst.currentDay, inst.currentMonth, inst.currentYear));
4134         },
4135
4136         /* Erase the input field and hide the date picker. */
4137         _clearDate: function(id) {
4138                 var target = $(id);
4139                 var inst = this._getInst(target[0]);
4140                 this._selectDate(target, '');
4141         },
4142
4143         /* Update the input field with the selected date. */
4144         _selectDate: function(id, dateStr) {
4145                 var target = $(id);
4146                 var inst = this._getInst(target[0]);
4147                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
4148                 if (inst.input)
4149                         inst.input.val(dateStr);
4150                 this._updateAlternate(inst);
4151                 var onSelect = this._get(inst, 'onSelect');
4152                 if (onSelect)
4153                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
4154                 else if (inst.input)
4155                         inst.input.trigger('change'); // fire the change event
4156                 if (inst.inline)
4157                         this._updateDatepicker(inst);
4158                 else {
4159                         this._hideDatepicker();
4160                         this._lastInput = inst.input[0];
4161                         if (typeof(inst.input[0]) != 'object')
4162                                 inst.input.focus(); // restore focus
4163                         this._lastInput = null;
4164                 }
4165         },
4166
4167         /* Update any alternate field to synchronise with the main field. */
4168         _updateAlternate: function(inst) {
4169                 var altField = this._get(inst, 'altField');
4170                 if (altField) { // update alternate field too
4171                         var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
4172                         var date = this._getDate(inst);
4173                         var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
4174                         $(altField).each(function() { $(this).val(dateStr); });
4175                 }
4176         },
4177
4178         /* Set as beforeShowDay function to prevent selection of weekends.
4179            @param  date  Date - the date to customise
4180            @return [boolean, string] - is this date selectable?, what is its CSS class? */
4181         noWeekends: function(date) {
4182                 var day = date.getDay();
4183                 return [(day > 0 && day < 6), ''];
4184         },
4185
4186         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
4187            @param  date  Date - the date to get the week for
4188            @return  number - the number of the week within the year that contains this date */
4189         iso8601Week: function(date) {
4190                 var checkDate = new Date(date.getTime());
4191                 // Find Thursday of this week starting on Monday
4192                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
4193                 var time = checkDate.getTime();
4194                 checkDate.setMonth(0); // Compare with Jan 1
4195                 checkDate.setDate(1);
4196                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
4197         },
4198
4199         /* Parse a string value into a date object.
4200            See formatDate below for the possible formats.
4201
4202            @param  format    string - the expected format of the date
4203            @param  value     string - the date in the above format
4204            @param  settings  Object - attributes include:
4205                              shortYearCutoff  number - the cutoff year for determining the century (optional)
4206                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
4207                              dayNames         string[7] - names of the days from Sunday (optional)
4208                              monthNamesShort  string[12] - abbreviated names of the months (optional)
4209                              monthNames       string[12] - names of the months (optional)
4210            @return  Date - the extracted date value or null if value is blank */
4211         parseDate: function (format, value, settings) {
4212                 if (format == null || value == null)
4213                         throw 'Invalid arguments';
4214                 value = (typeof value == 'object' ? value.toString() : value + '');
4215                 if (value == '')
4216                         return null;
4217                 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
4218                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
4219                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
4220                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
4221                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
4222                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
4223                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
4224                 var year = -1;
4225                 var month = -1;
4226                 var day = -1;
4227                 var doy = -1;
4228                 var literal = false;
4229                 // Check whether a format character is doubled
4230                 var lookAhead = function(match) {
4231                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
4232                         if (matches)
4233                                 iFormat++;
4234                         return matches;
4235                 };
4236                 // Extract a number from the string value
4237                 var getNumber = function(match) {
4238                         var isDoubled = lookAhead(match);
4239                         var size = (match == '@' ? 14 : (match == '!' ? 20 :
4240                                 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
4241                         var digits = new RegExp('^\\d{1,' + size + '}');
4242                         var num = value.substring(iValue).match(digits);
4243                         if (!num)
4244                                 throw 'Missing number at position ' + iValue;
4245                         iValue += num[0].length;
4246                         return parseInt(num[0], 10);
4247                 };
4248                 // Extract a name from the string value and convert to an index
4249                 var getName = function(match, shortNames, longNames) {
4250                         var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
4251                                 return [ [k, v] ];
4252                         }).sort(function (a, b) {
4253                                 return -(a[1].length - b[1].length);
4254                         });
4255                         var index = -1;
4256                         $.each(names, function (i, pair) {
4257                                 var name = pair[1];
4258                                 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
4259                                         index = pair[0];
4260                                         iValue += name.length;
4261                                         return false;
4262                                 }
4263                         });
4264                         if (index != -1)
4265                                 return index + 1;
4266                         else
4267                                 throw 'Unknown name at position ' + iValue;
4268                 };
4269                 // Confirm that a literal character matches the string value
4270                 var checkLiteral = function() {
4271                         if (value.charAt(iValue) != format.charAt(iFormat))
4272                                 throw 'Unexpected literal at position ' + iValue;
4273                         iValue++;
4274                 };
4275                 var iValue = 0;
4276                 for (var iFormat = 0; iFormat < format.length; iFormat++) {
4277                         if (literal)
4278                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
4279                                         literal = false;
4280                                 else
4281                                         checkLiteral();
4282                         else
4283                                 switch (format.charAt(iFormat)) {
4284                                         case 'd':
4285                                                 day = getNumber('d');
4286                                                 break;
4287                                         case 'D':
4288                                                 getName('D', dayNamesShort, dayNames);
4289                                                 break;
4290                                         case 'o':
4291                                                 doy = getNumber('o');
4292                                                 break;
4293                                         case 'm':
4294                                                 month = getNumber('m');
4295                                                 break;
4296                                         case 'M':
4297                                                 month = getName('M', monthNamesShort, monthNames);
4298                                                 break;
4299                                         case 'y':
4300                                                 year = getNumber('y');
4301                                                 break;
4302                                         case '@':
4303                                                 var date = new Date(getNumber('@'));
4304                                                 year = date.getFullYear();
4305                                                 month = date.getMonth() + 1;
4306                                                 day = date.getDate();
4307                                                 break;
4308                                         case '!':
4309                                                 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
4310                                                 year = date.getFullYear();
4311                                                 month = date.getMonth() + 1;
4312                                                 day = date.getDate();
4313                                                 break;
4314                                         case "'":
4315                                                 if (lookAhead("'"))
4316                                                         checkLiteral();
4317                                                 else
4318                                                         literal = true;
4319                                                 break;
4320                                         default:
4321                                                 checkLiteral();
4322                                 }
4323                 }
4324                 if (iValue < value.length){
4325                         var extra = value.substr(iValue);
4326                         if (!/^\s+/.test(extra)) {
4327                                 throw "Extra/unparsed characters found in date: " + extra;
4328                         }
4329                 }
4330                 if (year == -1)
4331                         year = new Date().getFullYear();
4332                 else if (year < 100)
4333                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
4334                                 (year <= shortYearCutoff ? 0 : -100);
4335                 if (doy > -1) {
4336                         month = 1;
4337                         day = doy;
4338                         do {
4339                                 var dim = this._getDaysInMonth(year, month - 1);
4340                                 if (day <= dim)
4341                                         break;
4342                                 month++;
4343                                 day -= dim;
4344                         } while (true);
4345                 }
4346                 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
4347                 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
4348                         throw 'Invalid date'; // E.g. 31/02/00
4349                 return date;
4350         },
4351
4352         /* Standard date formats. */
4353         ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
4354         COOKIE: 'D, dd M yy',
4355         ISO_8601: 'yy-mm-dd',
4356         RFC_822: 'D, d M y',
4357         RFC_850: 'DD, dd-M-y',
4358         RFC_1036: 'D, d M y',
4359         RFC_1123: 'D, d M yy',
4360         RFC_2822: 'D, d M yy',
4361         RSS: 'D, d M y', // RFC 822
4362         TICKS: '!',
4363         TIMESTAMP: '@',
4364         W3C: 'yy-mm-dd', // ISO 8601
4365
4366         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
4367                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
4368
4369         /* Format a date object into a string value.
4370            The format can be combinations of the following:
4371            d  - day of month (no leading zero)
4372            dd - day of month (two digit)
4373            o  - day of year (no leading zeros)
4374            oo - day of year (three digit)
4375            D  - day name short
4376            DD - day name long
4377            m  - month of year (no leading zero)
4378            mm - month of year (two digit)
4379            M  - month name short
4380            MM - month name long
4381            y  - year (two digit)
4382            yy - year (four digit)
4383            @ - Unix timestamp (ms since 01/01/1970)
4384            ! - Windows ticks (100ns since 01/01/0001)
4385            '...' - literal text
4386            '' - single quote
4387
4388            @param  format    string - the desired format of the date
4389            @param  date      Date - the date value to format
4390            @param  settings  Object - attributes include:
4391                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
4392                              dayNames         string[7] - names of the days from Sunday (optional)
4393                              monthNamesShort  string[12] - abbreviated names of the months (optional)
4394                              monthNames       string[12] - names of the months (optional)
4395            @return  string - the date in the above format */
4396         formatDate: function (format, date, settings) {
4397                 if (!date)
4398                         return '';
4399                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
4400                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
4401                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
4402                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
4403                 // Check whether a format character is doubled
4404                 var lookAhead = function(match) {
4405                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
4406                         if (matches)
4407                                 iFormat++;
4408                         return matches;
4409                 };
4410                 // Format a number, with leading zero if necessary
4411                 var formatNumber = function(match, value, len) {
4412                         var num = '' + value;
4413                         if (lookAhead(match))
4414                                 while (num.length < len)
4415                                         num = '0' + num;
4416                         return num;
4417                 };
4418                 // Format a name, short or long as requested
4419                 var formatName = function(match, value, shortNames, longNames) {
4420                         return (lookAhead(match) ? longNames[value] : shortNames[value]);
4421                 };
4422                 var output = '';
4423                 var literal = false;
4424                 if (date)
4425                         for (var iFormat = 0; iFormat < format.length; iFormat++) {
4426                                 if (literal)
4427                                         if (format.charAt(iFormat) == "'" && !lookAhead("'"))
4428                                                 literal = false;
4429                                         else
4430                                                 output += format.charAt(iFormat);
4431                                 else
4432                                         switch (format.charAt(iFormat)) {
4433                                                 case 'd':
4434                                                         output += formatNumber('d', date.getDate(), 2);
4435                                                         break;
4436                                                 case 'D':
4437                                                         output += formatName('D', date.getDay(), dayNamesShort, dayNames);
4438                                                         break;
4439                                                 case 'o':
4440                                                         output += formatNumber('o',
4441                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
4442                                                         break;
4443                                                 case 'm':
4444                                                         output += formatNumber('m', date.getMonth() + 1, 2);
4445                                                         break;
4446                                                 case 'M':
4447                                                         output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
4448                                                         break;
4449                                                 case 'y':
4450                                                         output += (lookAhead('y') ? date.getFullYear() :
4451                                                                 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
4452                                                         break;
4453                                                 case '@':
4454                                                         output += date.getTime();
4455                                                         break;
4456                                                 case '!':
4457                                                         output += date.getTime() * 10000 + this._ticksTo1970;
4458                                                         break;
4459                                                 case "'":
4460                                                         if (lookAhead("'"))
4461                                                                 output += "'";
4462                                                         else
4463                                                                 literal = true;
4464                                                         break;
4465                                                 default:
4466                                                         output += format.charAt(iFormat);
4467                                         }
4468                         }
4469                 return output;
4470         },
4471
4472         /* Extract all possible characters from the date format. */
4473         _possibleChars: function (format) {
4474                 var chars = '';
4475                 var literal = false;
4476                 // Check whether a format character is doubled
4477                 var lookAhead = function(match) {
4478                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
4479                         if (matches)
4480                                 iFormat++;
4481                         return matches;
4482                 };
4483                 for (var iFormat = 0; iFormat < format.length; iFormat++)
4484                         if (literal)
4485                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
4486                                         literal = false;
4487                                 else
4488                                         chars += format.charAt(iFormat);
4489                         else
4490                                 switch (format.charAt(iFormat)) {
4491                                         case 'd': case 'm': case 'y': case '@':
4492                                                 chars += '0123456789';
4493                                                 break;
4494                                         case 'D': case 'M':
4495                                                 return null; // Accept anything
4496                                         case "'":
4497                                                 if (lookAhead("'"))
4498                                                         chars += "'";
4499                                                 else
4500                                                         literal = true;
4501                                                 break;
4502                                         default:
4503                                                 chars += format.charAt(iFormat);
4504                                 }
4505                 return chars;
4506         },
4507
4508         /* Get a setting value, defaulting if necessary. */
4509         _get: function(inst, name) {
4510                 return inst.settings[name] !== undefined ?
4511                         inst.settings[name] : this._defaults[name];
4512         },
4513
4514         /* Parse existing date and initialise date picker. */
4515         _setDateFromField: function(inst, noDefault) {
4516                 if (inst.input.val() == inst.lastVal) {
4517                         return;
4518                 }
4519                 var dateFormat = this._get(inst, 'dateFormat');
4520                 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
4521                 var date, defaultDate;
4522                 date = defaultDate = this._getDefaultDate(inst);
4523                 var settings = this._getFormatConfig(inst);
4524                 try {
4525                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
4526                 } catch (event) {
4527                         this.log(event);
4528                         dates = (noDefault ? '' : dates);
4529                 }
4530                 inst.selectedDay = date.getDate();
4531                 inst.drawMonth = inst.selectedMonth = date.getMonth();
4532                 inst.drawYear = inst.selectedYear = date.getFullYear();
4533                 inst.currentDay = (dates ? date.getDate() : 0);
4534                 inst.currentMonth = (dates ? date.getMonth() : 0);
4535                 inst.currentYear = (dates ? date.getFullYear() : 0);
4536                 this._adjustInstDate(inst);
4537         },
4538
4539         /* Retrieve the default date shown on opening. */
4540         _getDefaultDate: function(inst) {
4541                 return this._restrictMinMax(inst,
4542                         this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
4543         },
4544
4545         /* A date may be specified as an exact value or a relative one. */
4546         _determineDate: function(inst, date, defaultDate) {
4547                 var offsetNumeric = function(offset) {
4548                         var date = new Date();
4549                         date.setDate(date.getDate() + offset);
4550                         return date;
4551                 };
4552                 var offsetString = function(offset) {
4553                         try {
4554                                 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
4555                                         offset, $.datepicker._getFormatConfig(inst));
4556                         }
4557                         catch (e) {
4558                                 // Ignore
4559                         }
4560                         var date = (offset.toLowerCase().match(/^c/) ?
4561                                 $.datepicker._getDate(inst) : null) || new Date();
4562                         var year = date.getFullYear();
4563                         var month = date.getMonth();
4564                         var day = date.getDate();
4565                         var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
4566                         var matches = pattern.exec(offset);
4567                         while (matches) {
4568                                 switch (matches[2] || 'd') {
4569                                         case 'd' : case 'D' :
4570                                                 day += parseInt(matches[1],10); break;
4571                                         case 'w' : case 'W' :
4572                                                 day += parseInt(matches[1],10) * 7; break;
4573                                         case 'm' : case 'M' :
4574                                                 month += parseInt(matches[1],10);
4575                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
4576                                                 break;
4577                                         case 'y': case 'Y' :
4578                                                 year += parseInt(matches[1],10);
4579                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
4580                                                 break;
4581                                 }
4582                                 matches = pattern.exec(offset);
4583                         }
4584                         return new Date(year, month, day);
4585                 };
4586                 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
4587                         (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
4588                 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
4589                 if (newDate) {
4590                         newDate.setHours(0);
4591                         newDate.setMinutes(0);
4592                         newDate.setSeconds(0);
4593                         newDate.setMilliseconds(0);
4594                 }
4595                 return this._daylightSavingAdjust(newDate);
4596         },
4597
4598         /* Handle switch to/from daylight saving.
4599            Hours may be non-zero on daylight saving cut-over:
4600            > 12 when midnight changeover, but then cannot generate
4601            midnight datetime, so jump to 1AM, otherwise reset.
4602            @param  date  (Date) the date to check
4603            @return  (Date) the corrected date */
4604         _daylightSavingAdjust: function(date) {
4605                 if (!date) return null;
4606                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
4607                 return date;
4608         },
4609
4610         /* Set the date(s) directly. */
4611         _setDate: function(inst, date, noChange) {
4612                 var clear = !date;
4613                 var origMonth = inst.selectedMonth;
4614                 var origYear = inst.selectedYear;
4615                 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
4616                 inst.selectedDay = inst.currentDay = newDate.getDate();
4617                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
4618                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
4619                 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
4620                         this._notifyChange(inst);
4621                 this._adjustInstDate(inst);
4622                 if (inst.input) {
4623                         inst.input.val(clear ? '' : this._formatDate(inst));
4624                 }
4625         },
4626
4627         /* Retrieve the date(s) directly. */
4628         _getDate: function(inst) {
4629                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
4630                         this._daylightSavingAdjust(new Date(
4631                         inst.currentYear, inst.currentMonth, inst.currentDay)));
4632                         return startDate;
4633         },
4634
4635         /* Attach the onxxx handlers.  These are declared statically so
4636          * they work with static code transformers like Caja.
4637          */
4638         _attachHandlers: function(inst) {
4639                 var stepMonths = this._get(inst, 'stepMonths');
4640                 var id = '#' + inst.id.replace( /\\\\/g, "\\" );
4641                 inst.dpDiv.find('[data-handler]').map(function () {
4642                         var handler = {
4643                                 prev: function () {
4644                                         window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
4645                                 },
4646                                 next: function () {
4647                                         window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
4648                                 },
4649                                 hide: function () {
4650                                         window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
4651                                 },
4652                                 today: function () {
4653                                         window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
4654                                 },
4655                                 selectDay: function () {
4656                                         window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
4657                                         return false;
4658                                 },
4659                                 selectMonth: function () {
4660                                         window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
4661                                         return false;
4662                                 },
4663                                 selectYear: function () {
4664                                         window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
4665                                         return false;
4666                                 }
4667                         };
4668                         $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
4669                 });
4670         },
4671
4672         /* Generate the HTML for the current state of the date picker. */
4673         _generateHTML: function(inst) {
4674                 var today = new Date();
4675                 today = this._daylightSavingAdjust(
4676                         new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
4677                 var isRTL = this._get(inst, 'isRTL');
4678                 var showButtonPanel = this._get(inst, 'showButtonPanel');
4679                 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
4680                 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
4681                 var numMonths = this._getNumberOfMonths(inst);
4682                 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
4683                 var stepMonths = this._get(inst, 'stepMonths');
4684                 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
4685                 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
4686                         new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
4687                 var minDate = this._getMinMaxDate(inst, 'min');
4688                 var maxDate = this._getMinMaxDate(inst, 'max');
4689                 var drawMonth = inst.drawMonth - showCurrentAtPos;
4690                 var drawYear = inst.drawYear;
4691                 if (drawMonth < 0) {
4692                         drawMonth += 12;
4693                         drawYear--;
4694                 }
4695                 if (maxDate) {
4696                         var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
4697                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
4698                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
4699                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
4700                                 drawMonth--;
4701                                 if (drawMonth < 0) {
4702                                         drawMonth = 11;
4703                                         drawYear--;
4704                                 }
4705                         }
4706                 }
4707                 inst.drawMonth = drawMonth;
4708                 inst.drawYear = drawYear;
4709                 var prevText = this._get(inst, 'prevText');
4710                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
4711                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
4712                         this._getFormatConfig(inst)));
4713                 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
4714                         '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
4715                         ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
4716                         (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>'));
4717                 var nextText = this._get(inst, 'nextText');
4718                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
4719                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
4720                         this._getFormatConfig(inst)));
4721                 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
4722                         '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
4723                         ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
4724                         (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>'));
4725                 var currentText = this._get(inst, 'currentText');
4726                 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
4727                 currentText = (!navigationAsDateFormat ? currentText :
4728                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
4729                 var 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">' +
4730                         this._get(inst, 'closeText') + '</button>' : '');
4731                 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
4732                         (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"' +
4733                         '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
4734                 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
4735                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
4736                 var showWeek = this._get(inst, 'showWeek');
4737                 var dayNames = this._get(inst, 'dayNames');
4738                 var dayNamesShort = this._get(inst, 'dayNamesShort');
4739                 var dayNamesMin = this._get(inst, 'dayNamesMin');
4740                 var monthNames = this._get(inst, 'monthNames');
4741                 var monthNamesShort = this._get(inst, 'monthNamesShort');
4742                 var beforeShowDay = this._get(inst, 'beforeShowDay');
4743                 var showOtherMonths = this._get(inst, 'showOtherMonths');
4744                 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
4745                 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
4746                 var defaultDate = this._getDefaultDate(inst);
4747                 var html = '';
4748                 for (var row = 0; row < numMonths[0]; row++) {
4749                         var group = '';
4750                         this.maxRows = 4;
4751                         for (var col = 0; col < numMonths[1]; col++) {
4752                                 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
4753                                 var cornerClass = ' ui-corner-all';
4754                                 var calender = '';
4755                                 if (isMultiMonth) {
4756                                         calender += '<div class="ui-datepicker-group';
4757                                         if (numMonths[1] > 1)
4758                                                 switch (col) {
4759                                                         case 0: calender += ' ui-datepicker-group-first';
4760                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
4761                                                         case numMonths[1]-1: calender += ' ui-datepicker-group-last';
4762                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
4763                                                         default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
4764                                                 }
4765                                         calender += '">';
4766                                 }
4767                                 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
4768                                         (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
4769                                         (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
4770                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
4771                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
4772                                         '</div><table class="ui-datepicker-calendar"><thead>' +
4773                                         '<tr>';
4774                                 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
4775                                 for (var dow = 0; dow < 7; dow++) { // days of the week
4776                                         var day = (dow + firstDay) % 7;
4777                                         thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
4778                                                 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
4779                                 }
4780                                 calender += thead + '</tr></thead><tbody>';
4781                                 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
4782                                 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
4783                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
4784                                 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
4785                                 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
4786                                 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
4787                                 this.maxRows = numRows;
4788                                 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
4789                                 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
4790                                         calender += '<tr>';
4791                                         var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
4792                                                 this._get(inst, 'calculateWeek')(printDate) + '</td>');
4793                                         for (var dow = 0; dow < 7; dow++) { // create date picker days
4794                                                 var daySettings = (beforeShowDay ?
4795                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
4796                                                 var otherMonth = (printDate.getMonth() != drawMonth);
4797                                                 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
4798                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
4799                                                 tbody += '<td class="' +
4800                                                         ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
4801                                                         (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
4802                                                         ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
4803                                                         (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
4804                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
4805                                                         ' ' + this._dayOverClass : '') + // highlight selected day
4806                                                         (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
4807                                                         (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
4808                                                         (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
4809                                                         (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
4810                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
4811                                                         (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
4812                                                         (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
4813                                                         (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
4814                                                         (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
4815                                                         (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
4816                                                         (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
4817                                                         '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
4818                                                 printDate.setDate(printDate.getDate() + 1);
4819                                                 printDate = this._daylightSavingAdjust(printDate);
4820                                         }
4821                                         calender += tbody + '</tr>';
4822                                 }
4823                                 drawMonth++;
4824                                 if (drawMonth > 11) {
4825                                         drawMonth = 0;
4826                                         drawYear++;
4827                                 }
4828                                 calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
4829                                                         ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
4830                                 group += calender;
4831                         }
4832                         html += group;
4833                 }
4834                 html += buttonPanel + ($.ui.ie6 && !inst.inline ?
4835                         '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
4836                 inst._keyEvent = false;
4837                 return html;
4838         },
4839
4840         /* Generate the month and year header. */
4841         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
4842                         secondary, monthNames, monthNamesShort) {
4843                 var changeMonth = this._get(inst, 'changeMonth');
4844                 var changeYear = this._get(inst, 'changeYear');
4845                 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
4846                 var html = '<div class="ui-datepicker-title">';
4847                 var monthHtml = '';
4848                 // month selection
4849                 if (secondary || !changeMonth)
4850                         monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
4851                 else {
4852                         var inMinYear = (minDate && minDate.getFullYear() == drawYear);
4853                         var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
4854                         monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
4855                         for (var month = 0; month < 12; month++) {
4856                                 if ((!inMinYear || month >= minDate.getMonth()) &&
4857                                                 (!inMaxYear || month <= maxDate.getMonth()))
4858                                         monthHtml += '<option value="' + month + '"' +
4859                                                 (month == drawMonth ? ' selected="selected"' : '') +
4860                                                 '>' + monthNamesShort[month] + '</option>';
4861                         }
4862                         monthHtml += '</select>';
4863                 }
4864                 if (!showMonthAfterYear)
4865                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
4866                 // year selection
4867                 if ( !inst.yearshtml ) {
4868                         inst.yearshtml = '';
4869                         if (secondary || !changeYear)
4870                                 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
4871                         else {
4872                                 // determine range of years to display
4873                                 var years = this._get(inst, 'yearRange').split(':');
4874                                 var thisYear = new Date().getFullYear();
4875                                 var determineYear = function(value) {
4876                                         var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
4877                                                 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
4878                                                 parseInt(value, 10)));
4879                                         return (isNaN(year) ? thisYear : year);
4880                                 };
4881                                 var year = determineYear(years[0]);
4882                                 var endYear = Math.max(year, determineYear(years[1] || ''));
4883                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
4884                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
4885                                 inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
4886                                 for (; year <= endYear; year++) {
4887                                         inst.yearshtml += '<option value="' + year + '"' +
4888                                                 (year == drawYear ? ' selected="selected"' : '') +
4889                                                 '>' + year + '</option>';
4890                                 }
4891                                 inst.yearshtml += '</select>';
4892
4893                                 html += inst.yearshtml;
4894                                 inst.yearshtml = null;
4895                         }
4896                 }
4897                 html += this._get(inst, 'yearSuffix');
4898                 if (showMonthAfterYear)
4899                         html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
4900                 html += '</div>'; // Close datepicker_header
4901                 return html;
4902         },
4903
4904         /* Adjust one of the date sub-fields. */
4905         _adjustInstDate: function(inst, offset, period) {
4906                 var year = inst.drawYear + (period == 'Y' ? offset : 0);
4907                 var month = inst.drawMonth + (period == 'M' ? offset : 0);
4908                 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
4909                         (period == 'D' ? offset : 0);
4910                 var date = this._restrictMinMax(inst,
4911                         this._daylightSavingAdjust(new Date(year, month, day)));
4912                 inst.selectedDay = date.getDate();
4913                 inst.drawMonth = inst.selectedMonth = date.getMonth();
4914                 inst.drawYear = inst.selectedYear = date.getFullYear();
4915                 if (period == 'M' || period == 'Y')
4916                         this._notifyChange(inst);
4917         },
4918
4919         /* Ensure a date is within any min/max bounds. */
4920         _restrictMinMax: function(inst, date) {
4921                 var minDate = this._getMinMaxDate(inst, 'min');
4922                 var maxDate = this._getMinMaxDate(inst, 'max');
4923                 var newDate = (minDate && date < minDate ? minDate : date);
4924                 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
4925                 return newDate;
4926         },
4927
4928         /* Notify change of month/year. */
4929         _notifyChange: function(inst) {
4930                 var onChange = this._get(inst, 'onChangeMonthYear');
4931                 if (onChange)
4932                         onChange.apply((inst.input ? inst.input[0] : null),
4933                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
4934         },
4935
4936         /* Determine the number of months to show. */
4937         _getNumberOfMonths: function(inst) {
4938                 var numMonths = this._get(inst, 'numberOfMonths');
4939                 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
4940         },
4941
4942         /* Determine the current maximum date - ensure no time components are set. */
4943         _getMinMaxDate: function(inst, minMax) {
4944                 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
4945         },
4946
4947         /* Find the number of days in a given month. */
4948         _getDaysInMonth: function(year, month) {
4949                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
4950         },
4951
4952         /* Find the day of the week of the first of a month. */
4953         _getFirstDayOfMonth: function(year, month) {
4954                 return new Date(year, month, 1).getDay();
4955         },
4956
4957         /* Determines if we should allow a "next/prev" month display change. */
4958         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
4959                 var numMonths = this._getNumberOfMonths(inst);
4960                 var date = this._daylightSavingAdjust(new Date(curYear,
4961                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
4962                 if (offset < 0)
4963                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
4964                 return this._isInRange(inst, date);
4965         },
4966
4967         /* Is the given date in the accepted range? */
4968         _isInRange: function(inst, date) {
4969                 var minDate = this._getMinMaxDate(inst, 'min');
4970                 var maxDate = this._getMinMaxDate(inst, 'max');
4971                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
4972                         (!maxDate || date.getTime() <= maxDate.getTime()));
4973         },
4974
4975         /* Provide the configuration settings for formatting/parsing. */
4976         _getFormatConfig: function(inst) {
4977                 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
4978                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
4979                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
4980                 return {shortYearCutoff: shortYearCutoff,
4981                         dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
4982                         monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
4983         },
4984
4985         /* Format the given date for display. */
4986         _formatDate: function(inst, day, month, year) {
4987                 if (!day) {
4988                         inst.currentDay = inst.selectedDay;
4989                         inst.currentMonth = inst.selectedMonth;
4990                         inst.currentYear = inst.selectedYear;
4991                 }
4992                 var date = (day ? (typeof day == 'object' ? day :
4993                         this._daylightSavingAdjust(new Date(year, month, day))) :
4994                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
4995                 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
4996         }
4997 });
4998
4999 /*
5000  * Bind hover events for datepicker elements.
5001  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
5002  * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
5003  */
5004 function bindHover(dpDiv) {
5005         var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
5006         return dpDiv.delegate(selector, 'mouseout', function() {
5007                         $(this).removeClass('ui-state-hover');
5008                         if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
5009                         if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
5010                 })
5011                 .delegate(selector, 'mouseover', function(){
5012                         if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
5013                                 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
5014                                 $(this).addClass('ui-state-hover');
5015                                 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
5016                                 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
5017                         }
5018                 });
5019 }
5020
5021 /* jQuery extend now ignores nulls! */
5022 function extendRemove(target, props) {
5023         $.extend(target, props);
5024         for (var name in props)
5025                 if (props[name] == null || props[name] == undefined)
5026                         target[name] = props[name];
5027         return target;
5028 };
5029
5030 /* Invoke the datepicker functionality.
5031    @param  options  string - a command, optionally followed by additional parameters or
5032                         Object - settings for attaching new datepicker functionality
5033    @return  jQuery object */
5034 $.fn.datepicker = function(options){
5035
5036         /* Verify an empty collection wasn't passed - Fixes #6976 */
5037         if ( !this.length ) {
5038                 return this;
5039         }
5040
5041         /* Initialise the date picker. */
5042         if (!$.datepicker.initialized) {
5043                 $(document).mousedown($.datepicker._checkExternalClick).
5044                         find(document.body).append($.datepicker.dpDiv);
5045                 $.datepicker.initialized = true;
5046         }
5047
5048         var otherArgs = Array.prototype.slice.call(arguments, 1);
5049         if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
5050                 return $.datepicker['_' + options + 'Datepicker'].
5051                         apply($.datepicker, [this[0]].concat(otherArgs));
5052         if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
5053                 return $.datepicker['_' + options + 'Datepicker'].
5054                         apply($.datepicker, [this[0]].concat(otherArgs));
5055         return this.each(function() {
5056                 typeof options == 'string' ?
5057                         $.datepicker['_' + options + 'Datepicker'].
5058                                 apply($.datepicker, [this].concat(otherArgs)) :
5059                         $.datepicker._attachDatepicker(this, options);
5060         });
5061 };
5062
5063 $.datepicker = new Datepicker(); // singleton instance
5064 $.datepicker.initialized = false;
5065 $.datepicker.uuid = new Date().getTime();
5066 $.datepicker.version = "1.9.2";
5067
5068 // Workaround for #4055
5069 // Add another global to avoid noConflict issues with inline event handlers
5070 window['DP_jQuery_' + dpuuid] = $;
5071
5072 })(jQuery);
5073 (function( $, undefined ) {
5074
5075 var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
5076         sizeRelatedOptions = {
5077                 buttons: true,
5078                 height: true,
5079                 maxHeight: true,
5080                 maxWidth: true,
5081                 minHeight: true,
5082                 minWidth: true,
5083                 width: true
5084         },
5085         resizableRelatedOptions = {
5086                 maxHeight: true,
5087                 maxWidth: true,
5088                 minHeight: true,
5089                 minWidth: true
5090         };
5091
5092 $.widget("ui.dialog", {
5093         version: "1.9.2",
5094         options: {
5095                 autoOpen: true,
5096                 buttons: {},
5097                 closeOnEscape: true,
5098                 closeText: "close",
5099                 dialogClass: "",
5100                 draggable: true,
5101                 hide: null,
5102                 height: "auto",
5103                 maxHeight: false,
5104                 maxWidth: false,
5105                 minHeight: 150,
5106                 minWidth: 150,
5107                 modal: false,
5108                 position: {
5109                         my: "center",
5110                         at: "center",
5111                         of: window,
5112                         collision: "fit",
5113                         // ensure that the titlebar is never outside the document
5114                         using: function( pos ) {
5115                                 var topOffset = $( this ).css( pos ).offset().top;
5116                                 if ( topOffset < 0 ) {
5117                                         $( this ).css( "top", pos.top - topOffset );
5118                                 }
5119                         }
5120                 },
5121                 resizable: true,
5122                 show: null,
5123                 stack: true,
5124                 title: "",
5125                 width: 300,
5126                 zIndex: 1000
5127         },
5128
5129         _create: function() {
5130                 this.originalTitle = this.element.attr( "title" );
5131                 // #5742 - .attr() might return a DOMElement
5132                 if ( typeof this.originalTitle !== "string" ) {
5133                         this.originalTitle = "";
5134                 }
5135                 this.oldPosition = {
5136                         parent: this.element.parent(),
5137                         index: this.element.parent().children().index( this.element )
5138                 };
5139                 this.options.title = this.options.title || this.originalTitle;
5140                 var that = this,
5141                         options = this.options,
5142
5143                         title = options.title || "&#160;",
5144                         uiDialog,
5145                         uiDialogTitlebar,
5146                         uiDialogTitlebarClose,
5147                         uiDialogTitle,
5148                         uiDialogButtonPane;
5149
5150                         uiDialog = ( this.uiDialog = $( "<div>" ) )
5151                                 .addClass( uiDialogClasses + options.dialogClass )
5152                                 .css({
5153                                         display: "none",
5154                                         outline: 0, // TODO: move to stylesheet
5155                                         zIndex: options.zIndex
5156                                 })
5157                                 // setting tabIndex makes the div focusable
5158                                 .attr( "tabIndex", -1)
5159                                 .keydown(function( event ) {
5160                                         if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
5161                                                         event.keyCode === $.ui.keyCode.ESCAPE ) {
5162                                                 that.close( event );
5163                                                 event.preventDefault();
5164                                         }
5165                                 })
5166                                 .mousedown(function( event ) {
5167                                         that.moveToTop( false, event );
5168                                 })
5169                                 .appendTo( "body" );
5170
5171                         this.element
5172                                 .show()
5173                                 .removeAttr( "title" )
5174                                 .addClass( "ui-dialog-content ui-widget-content" )
5175                                 .appendTo( uiDialog );
5176
5177                         uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
5178                                 .addClass( "ui-dialog-titlebar  ui-widget-header  " +
5179                                         "ui-corner-all  ui-helper-clearfix" )
5180                                 .bind( "mousedown", function() {
5181                                         // Dialog isn't getting focus when dragging (#8063)
5182                                         uiDialog.focus();
5183                                 })
5184                                 .prependTo( uiDialog );
5185
5186                         uiDialogTitlebarClose = $( "<a href='#'></a>" )
5187                                 .addClass( "ui-dialog-titlebar-close  ui-corner-all" )
5188                                 .attr( "role", "button" )
5189                                 .click(function( event ) {
5190                                         event.preventDefault();
5191                                         that.close( event );
5192                                 })
5193                                 .appendTo( uiDialogTitlebar );
5194
5195                         ( this.uiDialogTitlebarCloseText = $( "<span>" ) )
5196                                 .addClass( "ui-icon ui-icon-closethick" )
5197                                 .text( options.closeText )
5198                                 .appendTo( uiDialogTitlebarClose );
5199
5200                         uiDialogTitle = $( "<span>" )
5201                                 .uniqueId()
5202                                 .addClass( "ui-dialog-title" )
5203                                 .html( title )
5204                                 .prependTo( uiDialogTitlebar );
5205
5206                         uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
5207                                 .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
5208
5209                         ( this.uiButtonSet = $( "<div>" ) )
5210                                 .addClass( "ui-dialog-buttonset" )
5211                                 .appendTo( uiDialogButtonPane );
5212
5213                 uiDialog.attr({
5214                         role: "dialog",
5215                         "aria-labelledby": uiDialogTitle.attr( "id" )
5216                 });
5217
5218                 uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
5219                 this._hoverable( uiDialogTitlebarClose );
5220                 this._focusable( uiDialogTitlebarClose );
5221
5222                 if ( options.draggable && $.fn.draggable ) {
5223                         this._makeDraggable();
5224                 }
5225                 if ( options.resizable && $.fn.resizable ) {
5226                         this._makeResizable();
5227                 }
5228
5229                 this._createButtons( options.buttons );
5230                 this._isOpen = false;
5231
5232                 if ( $.fn.bgiframe ) {
5233                         uiDialog.bgiframe();
5234                 }
5235
5236                 // prevent tabbing out of modal dialogs
5237                 this._on( uiDialog, { keydown: function( event ) {
5238                         if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
5239                                 return;
5240                         }
5241
5242                         var tabbables = $( ":tabbable", uiDialog ),
5243                                 first = tabbables.filter( ":first" ),
5244                                 last  = tabbables.filter( ":last" );
5245
5246                         if ( event.target === last[0] && !event.shiftKey ) {
5247                                 first.focus( 1 );
5248                                 return false;
5249                         } else if ( event.target === first[0] && event.shiftKey ) {
5250                                 last.focus( 1 );
5251                                 return false;
5252                         }
5253                 }});
5254         },
5255
5256         _init: function() {
5257                 if ( this.options.autoOpen ) {
5258                         this.open();
5259                 }
5260         },
5261
5262         _destroy: function() {
5263                 var next,
5264                         oldPosition = this.oldPosition;
5265
5266                 if ( this.overlay ) {
5267                         this.overlay.destroy();
5268                 }
5269                 this.uiDialog.hide();
5270                 this.element
5271                         .removeClass( "ui-dialog-content ui-widget-content" )
5272                         .hide()
5273                         .appendTo( "body" );
5274                 this.uiDialog.remove();
5275
5276                 if ( this.originalTitle ) {
5277                         this.element.attr( "title", this.originalTitle );
5278                 }
5279
5280                 next = oldPosition.parent.children().eq( oldPosition.index );
5281                 // Don't try to place the dialog next to itself (#8613)
5282                 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
5283                         next.before( this.element );
5284                 } else {
5285                         oldPosition.parent.append( this.element );
5286                 }
5287         },
5288
5289         widget: function() {
5290                 return this.uiDialog;
5291         },
5292
5293         close: function( event ) {
5294                 var that = this,
5295                         maxZ, thisZ;
5296
5297                 if ( !this._isOpen ) {
5298                         return;
5299                 }
5300
5301                 if ( false === this._trigger( "beforeClose", event ) ) {
5302                         return;
5303                 }
5304
5305                 this._isOpen = false;
5306
5307                 if ( this.overlay ) {
5308                         this.overlay.destroy();
5309                 }
5310
5311                 if ( this.options.hide ) {
5312                         this._hide( this.uiDialog, this.options.hide, function() {
5313                                 that._trigger( "close", event );
5314                         });
5315                 } else {
5316                         this.uiDialog.hide();
5317                         this._trigger( "close", event );
5318                 }
5319
5320                 $.ui.dialog.overlay.resize();
5321
5322                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
5323                 if ( this.options.modal ) {
5324                         maxZ = 0;
5325                         $( ".ui-dialog" ).each(function() {
5326                                 if ( this !== that.uiDialog[0] ) {
5327                                         thisZ = $( this ).css( "z-index" );
5328                                         if ( !isNaN( thisZ ) ) {
5329                                                 maxZ = Math.max( maxZ, thisZ );
5330                                         }
5331                                 }
5332                         });
5333                         $.ui.dialog.maxZ = maxZ;
5334                 }
5335
5336                 return this;
5337         },
5338
5339         isOpen: function() {
5340                 return this._isOpen;
5341         },
5342
5343         // the force parameter allows us to move modal dialogs to their correct
5344         // position on open
5345         moveToTop: function( force, event ) {
5346                 var options = this.options,
5347                         saveScroll;
5348
5349                 if ( ( options.modal && !force ) ||
5350                                 ( !options.stack && !options.modal ) ) {
5351                         return this._trigger( "focus", event );
5352                 }
5353
5354                 if ( options.zIndex > $.ui.dialog.maxZ ) {
5355                         $.ui.dialog.maxZ = options.zIndex;
5356                 }
5357                 if ( this.overlay ) {
5358                         $.ui.dialog.maxZ += 1;
5359                         $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
5360                         this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
5361                 }
5362
5363                 // Save and then restore scroll
5364                 // Opera 9.5+ resets when parent z-index is changed.
5365                 // http://bugs.jqueryui.com/ticket/3193
5366                 saveScroll = {
5367                         scrollTop: this.element.scrollTop(),
5368                         scrollLeft: this.element.scrollLeft()
5369                 };
5370                 $.ui.dialog.maxZ += 1;
5371                 this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
5372                 this.element.attr( saveScroll );
5373                 this._trigger( "focus", event );
5374
5375                 return this;
5376         },
5377
5378         open: function() {
5379                 if ( this._isOpen ) {
5380                         return;
5381                 }
5382
5383                 var hasFocus,
5384                         options = this.options,
5385                         uiDialog = this.uiDialog;
5386
5387                 this._size();
5388                 this._position( options.position );
5389                 uiDialog.show( options.show );
5390                 this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
5391                 this.moveToTop( true );
5392
5393                 // set focus to the first tabbable element in the content area or the first button
5394                 // if there are no tabbable elements, set focus on the dialog itself
5395                 hasFocus = this.element.find( ":tabbable" );
5396                 if ( !hasFocus.length ) {
5397                         hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
5398                         if ( !hasFocus.length ) {
5399                                 hasFocus = uiDialog;
5400                         }
5401                 }
5402                 hasFocus.eq( 0 ).focus();
5403
5404                 this._isOpen = true;
5405                 this._trigger( "open" );
5406
5407                 return this;
5408         },
5409
5410         _createButtons: function( buttons ) {
5411                 var that = this,
5412                         hasButtons = false;
5413
5414                 // if we already have a button pane, remove it
5415                 this.uiDialogButtonPane.remove();
5416                 this.uiButtonSet.empty();
5417
5418                 if ( typeof buttons === "object" && buttons !== null ) {
5419                         $.each( buttons, function() {
5420                                 return !(hasButtons = true);
5421                         });
5422                 }
5423                 if ( hasButtons ) {
5424                         $.each( buttons, function( name, props ) {
5425                                 var button, click;
5426                                 props = $.isFunction( props ) ?
5427                                         { click: props, text: name } :
5428                                         props;
5429                                 // Default to a non-submitting button
5430                                 props = $.extend( { type: "button" }, props );
5431                                 // Change the context for the click callback to be the main element
5432                                 click = props.click;
5433                                 props.click = function() {
5434                                         click.apply( that.element[0], arguments );
5435                                 };
5436                                 button = $( "<button></button>", props )
5437                                         .appendTo( that.uiButtonSet );
5438                                 if ( $.fn.button ) {
5439                                         button.button();
5440                                 }
5441                         });
5442                         this.uiDialog.addClass( "ui-dialog-buttons" );
5443                         this.uiDialogButtonPane.appendTo( this.uiDialog );
5444                 } else {
5445                         this.uiDialog.removeClass( "ui-dialog-buttons" );
5446                 }
5447         },
5448
5449         _makeDraggable: function() {
5450                 var that = this,
5451                         options = this.options;
5452
5453                 function filteredUi( ui ) {
5454                         return {
5455                                 position: ui.position,
5456                                 offset: ui.offset
5457                         };
5458                 }
5459
5460                 this.uiDialog.draggable({
5461                         cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
5462                         handle: ".ui-dialog-titlebar",
5463                         containment: "document",
5464                         start: function( event, ui ) {
5465                                 $( this )
5466                                         .addClass( "ui-dialog-dragging" );
5467                                 that._trigger( "dragStart", event, filteredUi( ui ) );
5468                         },
5469                         drag: function( event, ui ) {
5470                                 that._trigger( "drag", event, filteredUi( ui ) );
5471                         },
5472                         stop: function( event, ui ) {
5473                                 options.position = [
5474                                         ui.position.left - that.document.scrollLeft(),
5475                                         ui.position.top - that.document.scrollTop()
5476                                 ];
5477                                 $( this )
5478                                         .removeClass( "ui-dialog-dragging" );
5479                                 that._trigger( "dragStop", event, filteredUi( ui ) );
5480                                 $.ui.dialog.overlay.resize();
5481                         }
5482                 });
5483         },
5484
5485         _makeResizable: function( handles ) {
5486                 handles = (handles === undefined ? this.options.resizable : handles);
5487                 var that = this,
5488                         options = this.options,
5489                         // .ui-resizable has position: relative defined in the stylesheet
5490                         // but dialogs have to use absolute or fixed positioning
5491                         position = this.uiDialog.css( "position" ),
5492                         resizeHandles = typeof handles === 'string' ?
5493                                 handles :
5494                                 "n,e,s,w,se,sw,ne,nw";
5495
5496                 function filteredUi( ui ) {
5497                         return {
5498                                 originalPosition: ui.originalPosition,
5499                                 originalSize: ui.originalSize,
5500                                 position: ui.position,
5501                                 size: ui.size
5502                         };
5503                 }
5504
5505                 this.uiDialog.resizable({
5506                         cancel: ".ui-dialog-content",
5507                         containment: "document",
5508                         alsoResize: this.element,
5509                         maxWidth: options.maxWidth,
5510                         maxHeight: options.maxHeight,
5511                         minWidth: options.minWidth,
5512                         minHeight: this._minHeight(),
5513                         handles: resizeHandles,
5514                         start: function( event, ui ) {
5515                                 $( this ).addClass( "ui-dialog-resizing" );
5516                                 that._trigger( "resizeStart", event, filteredUi( ui ) );
5517                         },
5518                         resize: function( event, ui ) {
5519                                 that._trigger( "resize", event, filteredUi( ui ) );
5520                         },
5521                         stop: function( event, ui ) {
5522                                 $( this ).removeClass( "ui-dialog-resizing" );
5523                                 options.height = $( this ).height();
5524                                 options.width = $( this ).width();
5525                                 that._trigger( "resizeStop", event, filteredUi( ui ) );
5526                                 $.ui.dialog.overlay.resize();
5527                         }
5528                 })
5529                 .css( "position", position )
5530                 .find( ".ui-resizable-se" )
5531                         .addClass( "ui-icon ui-icon-grip-diagonal-se" );
5532         },
5533
5534         _minHeight: function() {
5535                 var options = this.options;
5536
5537                 if ( options.height === "auto" ) {
5538                         return options.minHeight;
5539                 } else {
5540                         return Math.min( options.minHeight, options.height );
5541                 }
5542         },
5543
5544         _position: function( position ) {
5545                 var myAt = [],
5546                         offset = [ 0, 0 ],
5547                         isVisible;
5548
5549                 if ( position ) {
5550                         // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
5551         //              if (typeof position == 'string' || $.isArray(position)) {
5552         //                      myAt = $.isArray(position) ? position : position.split(' ');
5553
5554                         if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
5555                                 myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
5556                                 if ( myAt.length === 1 ) {
5557                                         myAt[ 1 ] = myAt[ 0 ];
5558                                 }
5559
5560                                 $.each( [ "left", "top" ], function( i, offsetPosition ) {
5561                                         if ( +myAt[ i ] === myAt[ i ] ) {
5562                                                 offset[ i ] = myAt[ i ];
5563                                                 myAt[ i ] = offsetPosition;
5564                                         }
5565                                 });
5566
5567                                 position = {
5568                                         my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
5569                                                 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
5570                                         at: myAt.join( " " )
5571                                 };
5572                         }
5573
5574                         position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
5575                 } else {
5576                         position = $.ui.dialog.prototype.options.position;
5577                 }
5578
5579                 // need to show the dialog to get the actual offset in the position plugin
5580                 isVisible = this.uiDialog.is( ":visible" );
5581                 if ( !isVisible ) {
5582                         this.uiDialog.show();
5583                 }
5584                 this.uiDialog.position( position );
5585                 if ( !isVisible ) {
5586                         this.uiDialog.hide();
5587                 }
5588         },
5589
5590         _setOptions: function( options ) {
5591                 var that = this,
5592                         resizableOptions = {},
5593                         resize = false;
5594
5595                 $.each( options, function( key, value ) {
5596                         that._setOption( key, value );
5597
5598                         if ( key in sizeRelatedOptions ) {
5599                                 resize = true;
5600                         }
5601                         if ( key in resizableRelatedOptions ) {
5602                                 resizableOptions[ key ] = value;
5603                         }
5604                 });
5605
5606                 if ( resize ) {
5607                         this._size();
5608                 }
5609                 if ( this.uiDialog.is( ":data(resizable)" ) ) {
5610                         this.uiDialog.resizable( "option", resizableOptions );
5611                 }
5612         },
5613
5614         _setOption: function( key, value ) {
5615                 var isDraggable, isResizable,
5616                         uiDialog = this.uiDialog;
5617
5618                 switch ( key ) {
5619                         case "buttons":
5620                                 this._createButtons( value );
5621                                 break;
5622                         case "closeText":
5623                                 // ensure that we always pass a string
5624                                 this.uiDialogTitlebarCloseText.text( "" + value );
5625                                 break;
5626                         case "dialogClass":
5627                                 uiDialog
5628                                         .removeClass( this.options.dialogClass )
5629                                         .addClass( uiDialogClasses + value );
5630                                 break;
5631                         case "disabled":
5632                                 if ( value ) {
5633                                         uiDialog.addClass( "ui-dialog-disabled" );
5634                                 } else {
5635                                         uiDialog.removeClass( "ui-dialog-disabled" );
5636                                 }
5637                                 break;
5638                         case "draggable":
5639                                 isDraggable = uiDialog.is( ":data(draggable)" );
5640                                 if ( isDraggable && !value ) {
5641                                         uiDialog.draggable( "destroy" );
5642                                 }
5643
5644                                 if ( !isDraggable && value ) {
5645                                         this._makeDraggable();
5646                                 }
5647                                 break;
5648                         case "position":
5649                                 this._position( value );
5650                                 break;
5651                         case "resizable":
5652                                 // currently resizable, becoming non-resizable
5653                                 isResizable = uiDialog.is( ":data(resizable)" );
5654                                 if ( isResizable && !value ) {
5655                                         uiDialog.resizable( "destroy" );
5656                                 }
5657
5658                                 // currently resizable, changing handles
5659                                 if ( isResizable && typeof value === "string" ) {
5660                                         uiDialog.resizable( "option", "handles", value );
5661                                 }
5662
5663                                 // currently non-resizable, becoming resizable
5664                                 if ( !isResizable && value !== false ) {
5665                                         this._makeResizable( value );
5666                                 }
5667                                 break;
5668                         case "title":
5669                                 // convert whatever was passed in o a string, for html() to not throw up
5670                                 $( ".ui-dialog-title", this.uiDialogTitlebar )
5671                                         .html( "" + ( value || "&#160;" ) );
5672                                 break;
5673                 }
5674
5675                 this._super( key, value );
5676         },
5677
5678         _size: function() {
5679                 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
5680                  * divs will both have width and height set, so we need to reset them
5681                  */
5682                 var nonContentHeight, minContentHeight, autoHeight,
5683                         options = this.options,
5684                         isVisible = this.uiDialog.is( ":visible" );
5685
5686                 // reset content sizing
5687                 this.element.show().css({
5688                         width: "auto",
5689                         minHeight: 0,
5690                         height: 0
5691                 });
5692
5693                 if ( options.minWidth > options.width ) {
5694                         options.width = options.minWidth;
5695                 }
5696
5697                 // reset wrapper sizing
5698                 // determine the height of all the non-content elements
5699                 nonContentHeight = this.uiDialog.css({
5700                                 height: "auto",
5701                                 width: options.width
5702                         })
5703                         .outerHeight();
5704                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
5705
5706                 if ( options.height === "auto" ) {
5707                         // only needed for IE6 support
5708                         if ( $.support.minHeight ) {
5709                                 this.element.css({
5710                                         minHeight: minContentHeight,
5711                                         height: "auto"
5712                                 });
5713                         } else {
5714                                 this.uiDialog.show();
5715                                 autoHeight = this.element.css( "height", "auto" ).height();
5716                                 if ( !isVisible ) {
5717                                         this.uiDialog.hide();
5718                                 }
5719                                 this.element.height( Math.max( autoHeight, minContentHeight ) );
5720                         }
5721                 } else {
5722                         this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
5723                 }
5724
5725                 if (this.uiDialog.is( ":data(resizable)" ) ) {
5726                         this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
5727                 }
5728         }
5729 });
5730
5731 $.extend($.ui.dialog, {
5732         uuid: 0,
5733         maxZ: 0,
5734
5735         getTitleId: function($el) {
5736                 var id = $el.attr( "id" );
5737                 if ( !id ) {
5738                         this.uuid += 1;
5739                         id = this.uuid;
5740                 }
5741                 return "ui-dialog-title-" + id;
5742         },
5743
5744         overlay: function( dialog ) {
5745                 this.$el = $.ui.dialog.overlay.create( dialog );
5746         }
5747 });
5748
5749 $.extend( $.ui.dialog.overlay, {
5750         instances: [],
5751         // reuse old instances due to IE memory leak with alpha transparency (see #5185)
5752         oldInstances: [],
5753         maxZ: 0,
5754         events: $.map(
5755                 "focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
5756                 function( event ) {
5757                         return event + ".dialog-overlay";
5758                 }
5759         ).join( " " ),
5760         create: function( dialog ) {
5761                 if ( this.instances.length === 0 ) {
5762                         // prevent use of anchors and inputs
5763                         // we use a setTimeout in case the overlay is created from an
5764                         // event that we're going to be cancelling (see #2804)
5765                         setTimeout(function() {
5766                                 // handle $(el).dialog().dialog('close') (see #4065)
5767                                 if ( $.ui.dialog.overlay.instances.length ) {
5768                                         $( document ).bind( $.ui.dialog.overlay.events, function( event ) {
5769                                                 // stop events if the z-index of the target is < the z-index of the overlay
5770                                                 // we cannot return true when we don't want to cancel the event (#3523)
5771                                                 if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
5772                                                         return false;
5773                                                 }
5774                                         });
5775                                 }
5776                         }, 1 );
5777
5778                         // handle window resize
5779                         $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
5780                 }
5781
5782                 var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
5783
5784                 // allow closing by pressing the escape key
5785                 $( document ).bind( "keydown.dialog-overlay", function( event ) {
5786                         var instances = $.ui.dialog.overlay.instances;
5787                         // only react to the event if we're the top overlay
5788                         if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
5789                                 dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
5790                                 event.keyCode === $.ui.keyCode.ESCAPE ) {
5791
5792                                 dialog.close( event );
5793                                 event.preventDefault();
5794                         }
5795                 });
5796
5797                 $el.appendTo( document.body ).css({
5798                         width: this.width(),
5799                         height: this.height()
5800                 });
5801
5802                 if ( $.fn.bgiframe ) {
5803                         $el.bgiframe();
5804                 }
5805
5806                 this.instances.push( $el );
5807                 return $el;
5808         },
5809
5810         destroy: function( $el ) {
5811                 var indexOf = $.inArray( $el, this.instances ),
5812                         maxZ = 0;
5813
5814                 if ( indexOf !== -1 ) {
5815                         this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
5816                 }
5817
5818                 if ( this.instances.length === 0 ) {
5819                         $( [ document, window ] ).unbind( ".dialog-overlay" );
5820                 }
5821
5822                 $el.height( 0 ).width( 0 ).remove();
5823
5824                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
5825                 $.each( this.instances, function() {
5826                         maxZ = Math.max( maxZ, this.css( "z-index" ) );
5827                 });
5828                 this.maxZ = maxZ;
5829         },
5830
5831         height: function() {
5832                 var scrollHeight,
5833                         offsetHeight;
5834                 // handle IE
5835                 if ( $.ui.ie ) {
5836                         scrollHeight = Math.max(
5837                                 document.documentElement.scrollHeight,
5838                                 document.body.scrollHeight
5839                         );
5840                         offsetHeight = Math.max(
5841                                 document.documentElement.offsetHeight,
5842                                 document.body.offsetHeight
5843                         );
5844
5845                         if ( scrollHeight < offsetHeight ) {
5846                                 return $( window ).height() + "px";
5847                         } else {
5848                                 return scrollHeight + "px";
5849                         }
5850                 // handle "good" browsers
5851                 } else {
5852                         return $( document ).height() + "px";
5853                 }
5854         },
5855
5856         width: function() {
5857                 var scrollWidth,
5858                         offsetWidth;
5859                 // handle IE
5860                 if ( $.ui.ie ) {
5861                         scrollWidth = Math.max(
5862                                 document.documentElement.scrollWidth,
5863                                 document.body.scrollWidth
5864                         );
5865                         offsetWidth = Math.max(
5866                                 document.documentElement.offsetWidth,
5867                                 document.body.offsetWidth
5868                         );
5869
5870                         if ( scrollWidth < offsetWidth ) {
5871                                 return $( window ).width() + "px";
5872                         } else {
5873                                 return scrollWidth + "px";
5874                         }
5875                 // handle "good" browsers
5876                 } else {
5877                         return $( document ).width() + "px";
5878                 }
5879         },
5880
5881         resize: function() {
5882                 /* If the dialog is draggable and the user drags it past the
5883                  * right edge of the window, the document becomes wider so we
5884                  * need to stretch the overlay. If the user then drags the
5885                  * dialog back to the left, the document will become narrower,
5886                  * so we need to shrink the overlay to the appropriate size.
5887                  * This is handled by shrinking the overlay before setting it
5888                  * to the full document size.
5889                  */
5890                 var $overlays = $( [] );
5891                 $.each( $.ui.dialog.overlay.instances, function() {
5892                         $overlays = $overlays.add( this );
5893                 });
5894
5895                 $overlays.css({
5896                         width: 0,
5897                         height: 0
5898                 }).css({
5899                         width: $.ui.dialog.overlay.width(),
5900                         height: $.ui.dialog.overlay.height()
5901                 });
5902         }
5903 });
5904
5905 $.extend( $.ui.dialog.overlay.prototype, {
5906         destroy: function() {
5907                 $.ui.dialog.overlay.destroy( this.$el );
5908         }
5909 });
5910
5911 }( jQuery ) );
5912 (function( $, undefined ) {
5913
5914 $.widget("ui.draggable", $.ui.mouse, {
5915         version: "1.9.2",
5916         widgetEventPrefix: "drag",
5917         options: {
5918                 addClasses: true,
5919                 appendTo: "parent",
5920                 axis: false,
5921                 connectToSortable: false,
5922                 containment: false,
5923                 cursor: "auto",
5924                 cursorAt: false,
5925                 grid: false,
5926                 handle: false,
5927                 helper: "original",
5928                 iframeFix: false,
5929                 opacity: false,
5930                 refreshPositions: false,
5931                 revert: false,
5932                 revertDuration: 500,
5933                 scope: "default",
5934                 scroll: true,
5935                 scrollSensitivity: 20,
5936                 scrollSpeed: 20,
5937                 snap: false,
5938                 snapMode: "both",
5939                 snapTolerance: 20,
5940                 stack: false,
5941                 zIndex: false
5942         },
5943         _create: function() {
5944
5945                 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
5946                         this.element[0].style.position = 'relative';
5947
5948                 (this.options.addClasses && this.element.addClass("ui-draggable"));
5949                 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
5950
5951                 this._mouseInit();
5952
5953         },
5954
5955         _destroy: function() {
5956                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
5957                 this._mouseDestroy();
5958         },
5959
5960         _mouseCapture: function(event) {
5961
5962                 var o = this.options;
5963
5964                 // among others, prevent a drag on a resizable-handle
5965                 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
5966                         return false;
5967
5968                 //Quit if we're not on a valid handle
5969                 this.handle = this._getHandle(event);
5970                 if (!this.handle)
5971                         return false;
5972
5973                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
5974                         $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
5975                         .css({
5976                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
5977                                 position: "absolute", opacity: "0.001", zIndex: 1000
5978                         })
5979                         .css($(this).offset())
5980                         .appendTo("body");
5981                 });
5982
5983                 return true;
5984
5985         },
5986
5987         _mouseStart: function(event) {
5988
5989                 var o = this.options;
5990
5991                 //Create and append the visible helper
5992                 this.helper = this._createHelper(event);
5993
5994                 this.helper.addClass("ui-draggable-dragging");
5995
5996                 //Cache the helper size
5997                 this._cacheHelperProportions();
5998
5999                 //If ddmanager is used for droppables, set the global draggable
6000                 if($.ui.ddmanager)
6001                         $.ui.ddmanager.current = this;
6002
6003                 /*
6004                  * - Position generation -
6005                  * This block generates everything position related - it's the core of draggables.
6006                  */
6007
6008                 //Cache the margins of the original element
6009                 this._cacheMargins();
6010
6011                 //Store the helper's css position
6012                 this.cssPosition = this.helper.css("position");
6013                 this.scrollParent = this.helper.scrollParent();
6014
6015                 //The element's absolute position on the page minus margins
6016                 this.offset = this.positionAbs = this.element.offset();
6017                 this.offset = {
6018                         top: this.offset.top - this.margins.top,
6019                         left: this.offset.left - this.margins.left
6020                 };
6021
6022                 $.extend(this.offset, {
6023                         click: { //Where the click happened, relative to the element
6024                                 left: event.pageX - this.offset.left,
6025                                 top: event.pageY - this.offset.top
6026                         },
6027                         parent: this._getParentOffset(),
6028                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
6029                 });
6030
6031                 //Generate the original position
6032                 this.originalPosition = this.position = this._generatePosition(event);
6033                 this.originalPageX = event.pageX;
6034                 this.originalPageY = event.pageY;
6035
6036                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
6037                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
6038
6039                 //Set a containment if given in the options
6040                 if(o.containment)
6041                         this._setContainment();
6042
6043                 //Trigger event + callbacks
6044                 if(this._trigger("start", event) === false) {
6045                         this._clear();
6046                         return false;
6047                 }
6048
6049                 //Recache the helper size
6050                 this._cacheHelperProportions();
6051
6052                 //Prepare the droppable offsets
6053                 if ($.ui.ddmanager && !o.dropBehaviour)
6054                         $.ui.ddmanager.prepareOffsets(this, event);
6055
6056
6057                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
6058
6059                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
6060                 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
6061
6062                 return true;
6063         },
6064
6065         _mouseDrag: function(event, noPropagation) {
6066
6067                 //Compute the helpers position
6068                 this.position = this._generatePosition(event);
6069                 this.positionAbs = this._convertPositionTo("absolute");
6070
6071                 //Call plugins and callbacks and use the resulting position if something is returned
6072                 if (!noPropagation) {
6073                         var ui = this._uiHash();
6074                         if(this._trigger('drag', event, ui) === false) {
6075                                 this._mouseUp({});
6076                                 return false;
6077                         }
6078                         this.position = ui.position;
6079                 }
6080
6081                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
6082                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
6083                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
6084
6085                 return false;
6086         },
6087
6088         _mouseStop: function(event) {
6089
6090                 //If we are using droppables, inform the manager about the drop
6091                 var dropped = false;
6092                 if ($.ui.ddmanager && !this.options.dropBehaviour)
6093                         dropped = $.ui.ddmanager.drop(this, event);
6094
6095                 //if a drop comes from outside (a sortable)
6096                 if(this.dropped) {
6097                         dropped = this.dropped;
6098                         this.dropped = false;
6099                 }
6100
6101                 //if the original element is no longer in the DOM don't bother to continue (see #8269)
6102                 var element = this.element[0], elementInDom = false;
6103                 while ( element && (element = element.parentNode) ) {
6104                         if (element == document ) {
6105                                 elementInDom = true;
6106                         }
6107                 }
6108                 if ( !elementInDom && this.options.helper === "original" )
6109                         return false;
6110
6111                 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))) {
6112                         var that = this;
6113                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
6114                                 if(that._trigger("stop", event) !== false) {
6115                                         that._clear();
6116                                 }
6117                         });
6118                 } else {
6119                         if(this._trigger("stop", event) !== false) {
6120                                 this._clear();
6121                         }
6122                 }
6123
6124                 return false;
6125         },
6126
6127         _mouseUp: function(event) {
6128                 //Remove frame helpers
6129                 $("div.ui-draggable-iframeFix").each(function() {
6130                         this.parentNode.removeChild(this);
6131                 });
6132
6133                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
6134                 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
6135
6136                 return $.ui.mouse.prototype._mouseUp.call(this, event);
6137         },
6138
6139         cancel: function() {
6140
6141                 if(this.helper.is(".ui-draggable-dragging")) {
6142                         this._mouseUp({});
6143                 } else {
6144                         this._clear();
6145                 }
6146
6147                 return this;
6148
6149         },
6150
6151         _getHandle: function(event) {
6152
6153                 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
6154                 $(this.options.handle, this.element)
6155                         .find("*")
6156                         .andSelf()
6157                         .each(function() {
6158                                 if(this == event.target) handle = true;
6159                         });
6160
6161                 return handle;
6162
6163         },
6164
6165         _createHelper: function(event) {
6166
6167                 var o = this.options;
6168                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
6169
6170                 if(!helper.parents('body').length)
6171                         helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
6172
6173                 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
6174                         helper.css("position", "absolute");
6175
6176                 return helper;
6177
6178         },
6179
6180         _adjustOffsetFromHelper: function(obj) {
6181                 if (typeof obj == 'string') {
6182                         obj = obj.split(' ');
6183                 }
6184                 if ($.isArray(obj)) {
6185                         obj = {left: +obj[0], top: +obj[1] || 0};
6186                 }
6187                 if ('left' in obj) {
6188                         this.offset.click.left = obj.left + this.margins.left;
6189                 }
6190                 if ('right' in obj) {
6191                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6192                 }
6193                 if ('top' in obj) {
6194                         this.offset.click.top = obj.top + this.margins.top;
6195                 }
6196                 if ('bottom' in obj) {
6197                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6198                 }
6199         },
6200
6201         _getParentOffset: function() {
6202
6203                 //Get the offsetParent and cache its position
6204                 this.offsetParent = this.helper.offsetParent();
6205                 var po = this.offsetParent.offset();
6206
6207                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
6208                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6209                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6210                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6211                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6212                         po.left += this.scrollParent.scrollLeft();
6213                         po.top += this.scrollParent.scrollTop();
6214                 }
6215
6216                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
6217                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
6218                         po = { top: 0, left: 0 };
6219
6220                 return {
6221                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
6222                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
6223                 };
6224
6225         },
6226
6227         _getRelativeOffset: function() {
6228
6229                 if(this.cssPosition == "relative") {
6230                         var p = this.element.position();
6231                         return {
6232                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
6233                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
6234                         };
6235                 } else {
6236                         return { top: 0, left: 0 };
6237                 }
6238
6239         },
6240
6241         _cacheMargins: function() {
6242                 this.margins = {
6243                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
6244                         top: (parseInt(this.element.css("marginTop"),10) || 0),
6245                         right: (parseInt(this.element.css("marginRight"),10) || 0),
6246                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
6247                 };
6248         },
6249
6250         _cacheHelperProportions: function() {
6251                 this.helperProportions = {
6252                         width: this.helper.outerWidth(),
6253                         height: this.helper.outerHeight()
6254                 };
6255         },
6256
6257         _setContainment: function() {
6258
6259                 var o = this.options;
6260                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
6261                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
6262                         o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
6263                         o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
6264                         (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
6265                         (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
6266                 ];
6267
6268                 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
6269                         var c = $(o.containment);
6270                         var ce = c[0]; if(!ce) return;
6271                         var co = c.offset();
6272                         var over = ($(ce).css("overflow") != 'hidden');
6273
6274                         this.containment = [
6275                                 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
6276                                 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
6277                                 (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 - this.margins.right,
6278                                 (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  - this.margins.bottom
6279                         ];
6280                         this.relative_container = c;
6281
6282                 } else if(o.containment.constructor == Array) {
6283                         this.containment = o.containment;
6284                 }
6285
6286         },
6287
6288         _convertPositionTo: function(d, pos) {
6289
6290                 if(!pos) pos = this.position;
6291                 var mod = d == "absolute" ? 1 : -1;
6292                 var o = this.options, 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);
6293
6294                 return {
6295                         top: (
6296                                 pos.top                                                                                                                                 // The absolute mouse position
6297                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6298                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
6299                                 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
6300                         ),
6301                         left: (
6302                                 pos.left                                                                                                                                // The absolute mouse position
6303                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
6304                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
6305                                 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
6306                         )
6307                 };
6308
6309         },
6310
6311         _generatePosition: function(event) {
6312
6313                 var o = this.options, 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);
6314                 var pageX = event.pageX;
6315                 var pageY = event.pageY;
6316
6317                 /*
6318                  * - Position constraining -
6319                  * Constrain the position to a mix of grid, containment.
6320                  */
6321
6322                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
6323                         var containment;
6324                         if(this.containment) {
6325                         if (this.relative_container){
6326                                 var co = this.relative_container.offset();
6327                                 containment = [ this.containment[0] + co.left,
6328                                         this.containment[1] + co.top,
6329                                         this.containment[2] + co.left,
6330                                         this.containment[3] + co.top ];
6331                         }
6332                         else {
6333                                 containment = this.containment;
6334                         }
6335
6336                                 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
6337                                 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
6338                                 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
6339                                 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
6340                         }
6341
6342                         if(o.grid) {
6343                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
6344                                 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
6345                                 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;
6346
6347                                 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
6348                                 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;
6349                         }
6350
6351                 }
6352
6353                 return {
6354                         top: (
6355                                 pageY                                                                                                                           // The absolute mouse position
6356                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
6357                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
6358                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
6359                                 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
6360                         ),
6361                         left: (
6362                                 pageX                                                                                                                           // The absolute mouse position
6363                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
6364                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
6365                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
6366                                 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
6367                         )
6368                 };
6369
6370         },
6371
6372         _clear: function() {
6373                 this.helper.removeClass("ui-draggable-dragging");
6374                 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
6375                 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
6376                 this.helper = null;
6377                 this.cancelHelperRemoval = false;
6378         },
6379
6380         // From now on bulk stuff - mainly helpers
6381
6382         _trigger: function(type, event, ui) {
6383                 ui = ui || this._uiHash();
6384                 $.ui.plugin.call(this, type, [event, ui]);
6385                 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
6386                 return $.Widget.prototype._trigger.call(this, type, event, ui);
6387         },
6388
6389         plugins: {},
6390
6391         _uiHash: function(event) {
6392                 return {
6393                         helper: this.helper,
6394                         position: this.position,
6395                         originalPosition: this.originalPosition,
6396                         offset: this.positionAbs
6397                 };
6398         }
6399
6400 });
6401
6402 $.ui.plugin.add("draggable", "connectToSortable", {
6403         start: function(event, ui) {
6404
6405                 var inst = $(this).data("draggable"), o = inst.options,
6406                         uiSortable = $.extend({}, ui, { item: inst.element });
6407                 inst.sortables = [];
6408                 $(o.connectToSortable).each(function() {
6409                         var sortable = $.data(this, 'sortable');
6410                         if (sortable && !sortable.options.disabled) {
6411                                 inst.sortables.push({
6412                                         instance: sortable,
6413                                         shouldRevert: sortable.options.revert
6414                                 });
6415                                 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).
6416                                 sortable._trigger("activate", event, uiSortable);
6417                         }
6418                 });
6419
6420         },
6421         stop: function(event, ui) {
6422
6423                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
6424                 var inst = $(this).data("draggable"),
6425                         uiSortable = $.extend({}, ui, { item: inst.element });
6426
6427                 $.each(inst.sortables, function() {
6428                         if(this.instance.isOver) {
6429
6430                                 this.instance.isOver = 0;
6431
6432                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
6433                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
6434
6435                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
6436                                 if(this.shouldRevert) this.instance.options.revert = true;
6437
6438                                 //Trigger the stop of the sortable
6439                                 this.instance._mouseStop(event);
6440
6441                                 this.instance.options.helper = this.instance.options._helper;
6442
6443                                 //If the helper has been the original item, restore properties in the sortable
6444                                 if(inst.options.helper == 'original')
6445                                         this.instance.currentItem.css({ top: 'auto', left: 'auto' });
6446
6447                         } else {
6448                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
6449                                 this.instance._trigger("deactivate", event, uiSortable);
6450                         }
6451
6452                 });
6453
6454         },
6455         drag: function(event, ui) {
6456
6457                 var inst = $(this).data("draggable"), that = this;
6458
6459                 var checkPos = function(o) {
6460                         var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
6461                         var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
6462                         var itemHeight = o.height, itemWidth = o.width;
6463                         var itemTop = o.top, itemLeft = o.left;
6464
6465                         return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
6466                 };
6467
6468                 $.each(inst.sortables, function(i) {
6469
6470                         var innermostIntersecting = false;
6471                         var thisSortable = this;
6472                         //Copy over some variables to allow calling the sortable's native _intersectsWith
6473                         this.instance.positionAbs = inst.positionAbs;
6474                         this.instance.helperProportions = inst.helperProportions;
6475                         this.instance.offset.click = inst.offset.click;
6476
6477                         if(this.instance._intersectsWith(this.instance.containerCache)) {
6478                                 innermostIntersecting = true;
6479                                 $.each(inst.sortables, function () {
6480                                         this.instance.positionAbs = inst.positionAbs;
6481                                         this.instance.helperProportions = inst.helperProportions;
6482                                         this.instance.offset.click = inst.offset.click;
6483                                         if  (this != thisSortable
6484                                                 && this.instance._intersectsWith(this.instance.containerCache)
6485                                                 && $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
6486                                                 innermostIntersecting = false;
6487                                                 return innermostIntersecting;
6488                                 });
6489                         }
6490
6491
6492                         if(innermostIntersecting) {
6493                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
6494                                 if(!this.instance.isOver) {
6495
6496                                         this.instance.isOver = 1;
6497                                         //Now we fake the start of dragging for the sortable instance,
6498                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
6499                                         //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)
6500                                         this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
6501                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
6502                                         this.instance.options.helper = function() { return ui.helper[0]; };
6503
6504                                         event.target = this.instance.currentItem[0];
6505                                         this.instance._mouseCapture(event, true);
6506                                         this.instance._mouseStart(event, true, true);
6507
6508                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
6509                                         this.instance.offset.click.top = inst.offset.click.top;
6510                                         this.instance.offset.click.left = inst.offset.click.left;
6511                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
6512                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
6513
6514                                         inst._trigger("toSortable", event);
6515                                         inst.dropped = this.instance.element; //draggable revert needs that
6516                                         //hack so receive/update callbacks work (mostly)
6517                                         inst.currentItem = inst.element;
6518                                         this.instance.fromOutside = inst;
6519
6520                                 }
6521
6522                                 //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
6523                                 if(this.instance.currentItem) this.instance._mouseDrag(event);
6524
6525                         } else {
6526
6527                                 //If it doesn't intersect with the sortable, and it intersected before,
6528                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
6529                                 if(this.instance.isOver) {
6530
6531                                         this.instance.isOver = 0;
6532                                         this.instance.cancelHelperRemoval = true;
6533
6534                                         //Prevent reverting on this forced stop
6535                                         this.instance.options.revert = false;
6536
6537                                         // The out event needs to be triggered independently
6538                                         this.instance._trigger('out', event, this.instance._uiHash(this.instance));
6539
6540                                         this.instance._mouseStop(event, true);
6541                                         this.instance.options.helper = this.instance.options._helper;
6542
6543                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
6544                                         this.instance.currentItem.remove();
6545                                         if(this.instance.placeholder) this.instance.placeholder.remove();
6546
6547                                         inst._trigger("fromSortable", event);
6548                                         inst.dropped = false; //draggable revert needs that
6549                                 }
6550
6551                         };
6552
6553                 });
6554
6555         }
6556 });
6557
6558 $.ui.plugin.add("draggable", "cursor", {
6559         start: function(event, ui) {
6560                 var t = $('body'), o = $(this).data('draggable').options;
6561                 if (t.css("cursor")) o._cursor = t.css("cursor");
6562                 t.css("cursor", o.cursor);
6563         },
6564         stop: function(event, ui) {
6565                 var o = $(this).data('draggable').options;
6566                 if (o._cursor) $('body').css("cursor", o._cursor);
6567         }
6568 });
6569
6570 $.ui.plugin.add("draggable", "opacity", {
6571         start: function(event, ui) {
6572                 var t = $(ui.helper), o = $(this).data('draggable').options;
6573                 if(t.css("opacity")) o._opacity = t.css("opacity");
6574                 t.css('opacity', o.opacity);
6575         },
6576         stop: function(event, ui) {
6577                 var o = $(this).data('draggable').options;
6578                 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
6579         }
6580 });
6581
6582 $.ui.plugin.add("draggable", "scroll", {
6583         start: function(event, ui) {
6584                 var i = $(this).data("draggable");
6585                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
6586         },
6587         drag: function(event, ui) {
6588
6589                 var i = $(this).data("draggable"), o = i.options, scrolled = false;
6590
6591                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
6592
6593                         if(!o.axis || o.axis != 'x') {
6594                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
6595                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
6596                                 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
6597                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
6598                         }
6599
6600                         if(!o.axis || o.axis != 'y') {
6601                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
6602                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
6603                                 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
6604                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
6605                         }
6606
6607                 } else {
6608
6609                         if(!o.axis || o.axis != 'x') {
6610                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
6611                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6612                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
6613                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6614                         }
6615
6616                         if(!o.axis || o.axis != 'y') {
6617                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
6618                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6619                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
6620                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6621                         }
6622
6623                 }
6624
6625                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
6626                         $.ui.ddmanager.prepareOffsets(i, event);
6627
6628         }
6629 });
6630
6631 $.ui.plugin.add("draggable", "snap", {
6632         start: function(event, ui) {
6633
6634                 var i = $(this).data("draggable"), o = i.options;
6635                 i.snapElements = [];
6636
6637                 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
6638                         var $t = $(this); var $o = $t.offset();
6639                         if(this != i.element[0]) i.snapElements.push({
6640                                 item: this,
6641                                 width: $t.outerWidth(), height: $t.outerHeight(),
6642                                 top: $o.top, left: $o.left
6643                         });
6644                 });
6645
6646         },
6647         drag: function(event, ui) {
6648
6649                 var inst = $(this).data("draggable"), o = inst.options;
6650                 var d = o.snapTolerance;
6651
6652                 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
6653                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
6654
6655                 for (var i = inst.snapElements.length - 1; i >= 0; i--){
6656
6657                         var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
6658                                 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
6659
6660                         //Yes, I know, this is insane ;)
6661                         if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
6662                                 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6663                                 inst.snapElements[i].snapping = false;
6664                                 continue;
6665                         }
6666
6667                         if(o.snapMode != 'inner') {
6668                                 var ts = Math.abs(t - y2) <= d;
6669                                 var bs = Math.abs(b - y1) <= d;
6670                                 var ls = Math.abs(l - x2) <= d;
6671                                 var rs = Math.abs(r - x1) <= d;
6672                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
6673                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
6674                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
6675                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
6676                         }
6677
6678                         var first = (ts || bs || ls || rs);
6679
6680                         if(o.snapMode != 'outer') {
6681                                 var ts = Math.abs(t - y1) <= d;
6682                                 var bs = Math.abs(b - y2) <= d;
6683                                 var ls = Math.abs(l - x1) <= d;
6684                                 var rs = Math.abs(r - x2) <= d;
6685                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
6686                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
6687                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
6688                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
6689                         }
6690
6691                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
6692                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6693                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
6694
6695                 };
6696
6697         }
6698 });
6699
6700 $.ui.plugin.add("draggable", "stack", {
6701         start: function(event, ui) {
6702
6703                 var o = $(this).data("draggable").options;
6704
6705                 var group = $.makeArray($(o.stack)).sort(function(a,b) {
6706                         return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
6707                 });
6708                 if (!group.length) { return; }
6709
6710                 var min = parseInt(group[0].style.zIndex) || 0;
6711                 $(group).each(function(i) {
6712                         this.style.zIndex = min + i;
6713                 });
6714
6715                 this[0].style.zIndex = min + group.length;
6716
6717         }
6718 });
6719
6720 $.ui.plugin.add("draggable", "zIndex", {
6721         start: function(event, ui) {
6722                 var t = $(ui.helper), o = $(this).data("draggable").options;
6723                 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
6724                 t.css('zIndex', o.zIndex);
6725         },
6726         stop: function(event, ui) {
6727                 var o = $(this).data("draggable").options;
6728                 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
6729         }
6730 });
6731
6732 })(jQuery);
6733 (function( $, undefined ) {
6734
6735 $.widget("ui.droppable", {
6736         version: "1.9.2",
6737         widgetEventPrefix: "drop",
6738         options: {
6739                 accept: '*',
6740                 activeClass: false,
6741                 addClasses: true,
6742                 greedy: false,
6743                 hoverClass: false,
6744                 scope: 'default',
6745                 tolerance: 'intersect'
6746         },
6747         _create: function() {
6748
6749                 var o = this.options, accept = o.accept;
6750                 this.isover = 0; this.isout = 1;
6751
6752                 this.accept = $.isFunction(accept) ? accept : function(d) {
6753                         return d.is(accept);
6754                 };
6755
6756                 //Store the droppable's proportions
6757                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
6758
6759                 // Add the reference and positions to the manager
6760                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
6761                 $.ui.ddmanager.droppables[o.scope].push(this);
6762
6763                 (o.addClasses && this.element.addClass("ui-droppable"));
6764
6765         },
6766
6767         _destroy: function() {
6768                 var drop = $.ui.ddmanager.droppables[this.options.scope];
6769                 for ( var i = 0; i < drop.length; i++ )
6770                         if ( drop[i] == this )
6771                                 drop.splice(i, 1);
6772
6773                 this.element.removeClass("ui-droppable ui-droppable-disabled");
6774         },
6775
6776         _setOption: function(key, value) {
6777
6778                 if(key == 'accept') {
6779                         this.accept = $.isFunction(value) ? value : function(d) {
6780                                 return d.is(value);
6781                         };
6782                 }
6783                 $.Widget.prototype._setOption.apply(this, arguments);
6784         },
6785
6786         _activate: function(event) {
6787                 var draggable = $.ui.ddmanager.current;
6788                 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
6789                 (draggable && this._trigger('activate', event, this.ui(draggable)));
6790         },
6791
6792         _deactivate: function(event) {
6793                 var draggable = $.ui.ddmanager.current;
6794                 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
6795                 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
6796         },
6797
6798         _over: function(event) {
6799
6800                 var draggable = $.ui.ddmanager.current;
6801                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
6802
6803                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
6804                         if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
6805                         this._trigger('over', event, this.ui(draggable));
6806                 }
6807
6808         },
6809
6810         _out: function(event) {
6811
6812                 var draggable = $.ui.ddmanager.current;
6813                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
6814
6815                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
6816                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
6817                         this._trigger('out', event, this.ui(draggable));
6818                 }
6819
6820         },
6821
6822         _drop: function(event,custom) {
6823
6824                 var draggable = custom || $.ui.ddmanager.current;
6825                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
6826
6827                 var childrenIntersection = false;
6828                 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
6829                         var inst = $.data(this, 'droppable');
6830                         if(
6831                                 inst.options.greedy
6832                                 && !inst.options.disabled
6833                                 && inst.options.scope == draggable.options.scope
6834                                 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
6835                                 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
6836                         ) { childrenIntersection = true; return false; }
6837                 });
6838                 if(childrenIntersection) return false;
6839
6840                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
6841                         if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
6842                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
6843                         this._trigger('drop', event, this.ui(draggable));
6844                         return this.element;
6845                 }
6846
6847                 return false;
6848
6849         },
6850
6851         ui: function(c) {
6852                 return {
6853                         draggable: (c.currentItem || c.element),
6854                         helper: c.helper,
6855                         position: c.position,
6856                         offset: c.positionAbs
6857                 };
6858         }
6859
6860 });
6861
6862 $.ui.intersect = function(draggable, droppable, toleranceMode) {
6863
6864         if (!droppable.offset) return false;
6865
6866         var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
6867                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
6868         var l = droppable.offset.left, r = l + droppable.proportions.width,
6869                 t = droppable.offset.top, b = t + droppable.proportions.height;
6870
6871         switch (toleranceMode) {
6872                 case 'fit':
6873                         return (l <= x1 && x2 <= r
6874                                 && t <= y1 && y2 <= b);
6875                         break;
6876                 case 'intersect':
6877                         return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
6878                                 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
6879                                 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
6880                                 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
6881                         break;
6882                 case 'pointer':
6883                         var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
6884                                 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
6885                                 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
6886                         return isOver;
6887                         break;
6888                 case 'touch':
6889                         return (
6890                                         (y1 >= t && y1 <= b) || // Top edge touching
6891                                         (y2 >= t && y2 <= b) || // Bottom edge touching
6892                                         (y1 < t && y2 > b)              // Surrounded vertically
6893                                 ) && (
6894                                         (x1 >= l && x1 <= r) || // Left edge touching
6895                                         (x2 >= l && x2 <= r) || // Right edge touching
6896                                         (x1 < l && x2 > r)              // Surrounded horizontally
6897                                 );
6898                         break;
6899                 default:
6900                         return false;
6901                         break;
6902                 }
6903
6904 };
6905
6906 /*
6907         This manager tracks offsets of draggables and droppables
6908 */
6909 $.ui.ddmanager = {
6910         current: null,
6911         droppables: { 'default': [] },
6912         prepareOffsets: function(t, event) {
6913
6914                 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
6915                 var type = event ? event.type : null; // workaround for #2317
6916                 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
6917
6918                 droppablesLoop: for (var i = 0; i < m.length; i++) {
6919
6920                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;   //No disabled and non-accepted
6921                         for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
6922                         m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                       //If the element is not visible, continue
6923
6924                         if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
6925
6926                         m[i].offset = m[i].element.offset();
6927                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
6928
6929                 }
6930
6931         },
6932         drop: function(draggable, event) {
6933
6934                 var dropped = false;
6935                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
6936
6937                         if(!this.options) return;
6938                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
6939                                 dropped = this._drop.call(this, event) || dropped;
6940
6941                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
6942                                 this.isout = 1; this.isover = 0;
6943                                 this._deactivate.call(this, event);
6944                         }
6945
6946                 });
6947                 return dropped;
6948
6949         },
6950         dragStart: function( draggable, event ) {
6951                 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
6952                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
6953                         if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
6954                 });
6955         },
6956         drag: function(draggable, event) {
6957
6958                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
6959                 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
6960
6961                 //Run through all droppables and check their positions based on specific tolerance options
6962                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
6963
6964                         if(this.options.disabled || this.greedyChild || !this.visible) return;
6965                         var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
6966
6967                         var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
6968                         if(!c) return;
6969
6970                         var parentInstance;
6971                         if (this.options.greedy) {
6972                                 // find droppable parents with same scope
6973                                 var scope = this.options.scope;
6974                                 var parent = this.element.parents(':data(droppable)').filter(function () {
6975                                         return $.data(this, 'droppable').options.scope === scope;
6976                                 });
6977
6978                                 if (parent.length) {
6979                                         parentInstance = $.data(parent[0], 'droppable');
6980                                         parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
6981                                 }
6982                         }
6983
6984                         // we just moved into a greedy child
6985                         if (parentInstance && c == 'isover') {
6986                                 parentInstance['isover'] = 0;
6987                                 parentInstance['isout'] = 1;
6988                                 parentInstance._out.call(parentInstance, event);
6989                         }
6990
6991                         this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
6992                         this[c == "isover" ? "_over" : "_out"].call(this, event);
6993
6994                         // we just moved out of a greedy child
6995                         if (parentInstance && c == 'isout') {
6996                                 parentInstance['isout'] = 0;
6997                                 parentInstance['isover'] = 1;
6998                                 parentInstance._over.call(parentInstance, event);
6999                         }
7000                 });
7001
7002         },
7003         dragStop: function( draggable, event ) {
7004                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
7005                 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
7006                 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
7007         }
7008 };
7009
7010 })(jQuery);
7011 ;(jQuery.effects || (function($, undefined) {
7012
7013 var backCompat = $.uiBackCompat !== false,
7014         // prefix used for storing data on .data()
7015         dataSpace = "ui-effects-";
7016
7017 $.effects = {
7018         effect: {}
7019 };
7020
7021 /*!
7022  * jQuery Color Animations v2.0.0
7023  * http://jquery.com/
7024  *
7025  * Copyright 2012 jQuery Foundation and other contributors
7026  * Released under the MIT license.
7027  * http://jquery.org/license
7028  *
7029  * Date: Mon Aug 13 13:41:02 2012 -0500
7030  */
7031 (function( jQuery, undefined ) {
7032
7033         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
7034
7035         // plusequals test for += 100 -= 100
7036         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
7037         // a set of RE's that can match strings and generate color tuples.
7038         stringParsers = [{
7039                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
7040                         parse: function( execResult ) {
7041                                 return [
7042                                         execResult[ 1 ],
7043                                         execResult[ 2 ],
7044                                         execResult[ 3 ],
7045                                         execResult[ 4 ]
7046                                 ];
7047                         }
7048                 }, {
7049                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
7050                         parse: function( execResult ) {
7051                                 return [
7052                                         execResult[ 1 ] * 2.55,
7053                                         execResult[ 2 ] * 2.55,
7054                                         execResult[ 3 ] * 2.55,
7055                                         execResult[ 4 ]
7056                                 ];
7057                         }
7058                 }, {
7059                         // this regex ignores A-F because it's compared against an already lowercased string
7060                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
7061                         parse: function( execResult ) {
7062                                 return [
7063                                         parseInt( execResult[ 1 ], 16 ),
7064                                         parseInt( execResult[ 2 ], 16 ),
7065                                         parseInt( execResult[ 3 ], 16 )
7066                                 ];
7067                         }
7068                 }, {
7069                         // this regex ignores A-F because it's compared against an already lowercased string
7070                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
7071                         parse: function( execResult ) {
7072                                 return [
7073                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
7074                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
7075                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
7076                                 ];
7077                         }
7078                 }, {
7079                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
7080                         space: "hsla",
7081                         parse: function( execResult ) {
7082                                 return [
7083                                         execResult[ 1 ],
7084                                         execResult[ 2 ] / 100,
7085                                         execResult[ 3 ] / 100,
7086                                         execResult[ 4 ]
7087                                 ];
7088                         }
7089                 }],
7090
7091         // jQuery.Color( )
7092         color = jQuery.Color = function( color, green, blue, alpha ) {
7093                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
7094         },
7095         spaces = {
7096                 rgba: {
7097                         props: {
7098                                 red: {
7099                                         idx: 0,
7100                                         type: "byte"
7101                                 },
7102                                 green: {
7103                                         idx: 1,
7104                                         type: "byte"
7105                                 },
7106                                 blue: {
7107                                         idx: 2,
7108                                         type: "byte"
7109                                 }
7110                         }
7111                 },
7112
7113                 hsla: {
7114                         props: {
7115                                 hue: {
7116                                         idx: 0,
7117                                         type: "degrees"
7118                                 },
7119                                 saturation: {
7120                                         idx: 1,
7121                                         type: "percent"
7122                                 },
7123                                 lightness: {
7124                                         idx: 2,
7125                                         type: "percent"
7126                                 }
7127                         }
7128                 }
7129         },
7130         propTypes = {
7131                 "byte": {
7132                         floor: true,
7133                         max: 255
7134                 },
7135                 "percent": {
7136                         max: 1
7137                 },
7138                 "degrees": {
7139                         mod: 360,
7140                         floor: true
7141                 }
7142         },
7143         support = color.support = {},
7144
7145         // element for support tests
7146         supportElem = jQuery( "<p>" )[ 0 ],
7147
7148         // colors = jQuery.Color.names
7149         colors,
7150
7151         // local aliases of functions called often
7152         each = jQuery.each;
7153
7154 // determine rgba support immediately
7155 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
7156 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
7157
7158 // define cache name and alpha properties
7159 // for rgba and hsla spaces
7160 each( spaces, function( spaceName, space ) {
7161         space.cache = "_" + spaceName;
7162         space.props.alpha = {
7163                 idx: 3,
7164                 type: "percent",
7165                 def: 1
7166         };
7167 });
7168
7169 function clamp( value, prop, allowEmpty ) {
7170         var type = propTypes[ prop.type ] || {};
7171
7172         if ( value == null ) {
7173                 return (allowEmpty || !prop.def) ? null : prop.def;
7174         }
7175
7176         // ~~ is an short way of doing floor for positive numbers
7177         value = type.floor ? ~~value : parseFloat( value );
7178
7179         // IE will pass in empty strings as value for alpha,
7180         // which will hit this case
7181         if ( isNaN( value ) ) {
7182                 return prop.def;
7183         }
7184
7185         if ( type.mod ) {
7186                 // we add mod before modding to make sure that negatives values
7187                 // get converted properly: -10 -> 350
7188                 return (value + type.mod) % type.mod;
7189         }
7190
7191         // for now all property types without mod have min and max
7192         return 0 > value ? 0 : type.max < value ? type.max : value;
7193 }
7194
7195 function stringParse( string ) {
7196         var inst = color(),
7197                 rgba = inst._rgba = [];
7198
7199         string = string.toLowerCase();
7200
7201         each( stringParsers, function( i, parser ) {
7202                 var parsed,
7203                         match = parser.re.exec( string ),
7204                         values = match && parser.parse( match ),
7205                         spaceName = parser.space || "rgba";
7206
7207                 if ( values ) {
7208                         parsed = inst[ spaceName ]( values );
7209
7210                         // if this was an rgba parse the assignment might happen twice
7211                         // oh well....
7212                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
7213                         rgba = inst._rgba = parsed._rgba;
7214
7215                         // exit each( stringParsers ) here because we matched
7216                         return false;
7217                 }
7218         });
7219
7220         // Found a stringParser that handled it
7221         if ( rgba.length ) {
7222
7223                 // if this came from a parsed string, force "transparent" when alpha is 0
7224                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
7225                 if ( rgba.join() === "0,0,0,0" ) {
7226                         jQuery.extend( rgba, colors.transparent );
7227                 }
7228                 return inst;
7229         }
7230
7231         // named colors
7232         return colors[ string ];
7233 }
7234
7235 color.fn = jQuery.extend( color.prototype, {
7236         parse: function( red, green, blue, alpha ) {
7237                 if ( red === undefined ) {
7238                         this._rgba = [ null, null, null, null ];
7239                         return this;
7240                 }
7241                 if ( red.jquery || red.nodeType ) {
7242                         red = jQuery( red ).css( green );
7243                         green = undefined;
7244                 }
7245
7246                 var inst = this,
7247                         type = jQuery.type( red ),
7248                         rgba = this._rgba = [];
7249
7250                 // more than 1 argument specified - assume ( red, green, blue, alpha )
7251                 if ( green !== undefined ) {
7252                         red = [ red, green, blue, alpha ];
7253                         type = "array";
7254                 }
7255
7256                 if ( type === "string" ) {
7257                         return this.parse( stringParse( red ) || colors._default );
7258                 }
7259
7260                 if ( type === "array" ) {
7261                         each( spaces.rgba.props, function( key, prop ) {
7262                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
7263                         });
7264                         return this;
7265                 }
7266
7267                 if ( type === "object" ) {
7268                         if ( red instanceof color ) {
7269                                 each( spaces, function( spaceName, space ) {
7270                                         if ( red[ space.cache ] ) {
7271                                                 inst[ space.cache ] = red[ space.cache ].slice();
7272                                         }
7273                                 });
7274                         } else {
7275                                 each( spaces, function( spaceName, space ) {
7276                                         var cache = space.cache;
7277                                         each( space.props, function( key, prop ) {
7278
7279                                                 // if the cache doesn't exist, and we know how to convert
7280                                                 if ( !inst[ cache ] && space.to ) {
7281
7282                                                         // if the value was null, we don't need to copy it
7283                                                         // if the key was alpha, we don't need to copy it either
7284                                                         if ( key === "alpha" || red[ key ] == null ) {
7285                                                                 return;
7286                                                         }
7287                                                         inst[ cache ] = space.to( inst._rgba );
7288                                                 }
7289
7290                                                 // this is the only case where we allow nulls for ALL properties.
7291                                                 // call clamp with alwaysAllowEmpty
7292                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
7293                                         });
7294
7295                                         // everything defined but alpha?
7296                                         if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
7297                                                 // use the default of 1
7298                                                 inst[ cache ][ 3 ] = 1;
7299                                                 if ( space.from ) {
7300                                                         inst._rgba = space.from( inst[ cache ] );
7301                                                 }
7302                                         }
7303                                 });
7304                         }
7305                         return this;
7306                 }
7307         },
7308         is: function( compare ) {
7309                 var is = color( compare ),
7310                         same = true,
7311                         inst = this;
7312
7313                 each( spaces, function( _, space ) {
7314                         var localCache,
7315                                 isCache = is[ space.cache ];
7316                         if (isCache) {
7317                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
7318                                 each( space.props, function( _, prop ) {
7319                                         if ( isCache[ prop.idx ] != null ) {
7320                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
7321                                                 return same;
7322                                         }
7323                                 });
7324                         }
7325                         return same;
7326                 });
7327                 return same;
7328         },
7329         _space: function() {
7330                 var used = [],
7331                         inst = this;
7332                 each( spaces, function( spaceName, space ) {
7333                         if ( inst[ space.cache ] ) {
7334                                 used.push( spaceName );
7335                         }
7336                 });
7337                 return used.pop();
7338         },
7339         transition: function( other, distance ) {
7340                 var end = color( other ),
7341                         spaceName = end._space(),
7342                         space = spaces[ spaceName ],
7343                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
7344                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
7345                         result = start.slice();
7346
7347                 end = end[ space.cache ];
7348                 each( space.props, function( key, prop ) {
7349                         var index = prop.idx,
7350                                 startValue = start[ index ],
7351                                 endValue = end[ index ],
7352                                 type = propTypes[ prop.type ] || {};
7353
7354                         // if null, don't override start value
7355                         if ( endValue === null ) {
7356                                 return;
7357                         }
7358                         // if null - use end
7359                         if ( startValue === null ) {
7360                                 result[ index ] = endValue;
7361                         } else {
7362                                 if ( type.mod ) {
7363                                         if ( endValue - startValue > type.mod / 2 ) {
7364                                                 startValue += type.mod;
7365                                         } else if ( startValue - endValue > type.mod / 2 ) {
7366                                                 startValue -= type.mod;
7367                                         }
7368                                 }
7369                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
7370                         }
7371                 });
7372                 return this[ spaceName ]( result );
7373         },
7374         blend: function( opaque ) {
7375                 // if we are already opaque - return ourself
7376                 if ( this._rgba[ 3 ] === 1 ) {
7377                         return this;
7378                 }
7379
7380                 var rgb = this._rgba.slice(),
7381                         a = rgb.pop(),
7382                         blend = color( opaque )._rgba;
7383
7384                 return color( jQuery.map( rgb, function( v, i ) {
7385                         return ( 1 - a ) * blend[ i ] + a * v;
7386                 }));
7387         },
7388         toRgbaString: function() {
7389                 var prefix = "rgba(",
7390                         rgba = jQuery.map( this._rgba, function( v, i ) {
7391                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
7392                         });
7393
7394                 if ( rgba[ 3 ] === 1 ) {
7395                         rgba.pop();
7396                         prefix = "rgb(";
7397                 }
7398
7399                 return prefix + rgba.join() + ")";
7400         },
7401         toHslaString: function() {
7402                 var prefix = "hsla(",
7403                         hsla = jQuery.map( this.hsla(), function( v, i ) {
7404                                 if ( v == null ) {
7405                                         v = i > 2 ? 1 : 0;
7406                                 }
7407
7408                                 // catch 1 and 2
7409                                 if ( i && i < 3 ) {
7410                                         v = Math.round( v * 100 ) + "%";
7411                                 }
7412                                 return v;
7413                         });
7414
7415                 if ( hsla[ 3 ] === 1 ) {
7416                         hsla.pop();
7417                         prefix = "hsl(";
7418                 }
7419                 return prefix + hsla.join() + ")";
7420         },
7421         toHexString: function( includeAlpha ) {
7422                 var rgba = this._rgba.slice(),
7423                         alpha = rgba.pop();
7424
7425                 if ( includeAlpha ) {
7426                         rgba.push( ~~( alpha * 255 ) );
7427                 }
7428
7429                 return "#" + jQuery.map( rgba, function( v ) {
7430
7431                         // default to 0 when nulls exist
7432                         v = ( v || 0 ).toString( 16 );
7433                         return v.length === 1 ? "0" + v : v;
7434                 }).join("");
7435         },
7436         toString: function() {
7437                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
7438         }
7439 });
7440 color.fn.parse.prototype = color.fn;
7441
7442 // hsla conversions adapted from:
7443 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
7444
7445 function hue2rgb( p, q, h ) {
7446         h = ( h + 1 ) % 1;
7447         if ( h * 6 < 1 ) {
7448                 return p + (q - p) * h * 6;
7449         }
7450         if ( h * 2 < 1) {
7451                 return q;
7452         }
7453         if ( h * 3 < 2 ) {
7454                 return p + (q - p) * ((2/3) - h) * 6;
7455         }
7456         return p;
7457 }
7458
7459 spaces.hsla.to = function ( rgba ) {
7460         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
7461                 return [ null, null, null, rgba[ 3 ] ];
7462         }
7463         var r = rgba[ 0 ] / 255,
7464                 g = rgba[ 1 ] / 255,
7465                 b = rgba[ 2 ] / 255,
7466                 a = rgba[ 3 ],
7467                 max = Math.max( r, g, b ),
7468                 min = Math.min( r, g, b ),
7469                 diff = max - min,
7470                 add = max + min,
7471                 l = add * 0.5,
7472                 h, s;
7473
7474         if ( min === max ) {
7475                 h = 0;
7476         } else if ( r === max ) {
7477                 h = ( 60 * ( g - b ) / diff ) + 360;
7478         } else if ( g === max ) {
7479                 h = ( 60 * ( b - r ) / diff ) + 120;
7480         } else {
7481                 h = ( 60 * ( r - g ) / diff ) + 240;
7482         }
7483
7484         if ( l === 0 || l === 1 ) {
7485                 s = l;
7486         } else if ( l <= 0.5 ) {
7487                 s = diff / add;
7488         } else {
7489                 s = diff / ( 2 - add );
7490         }
7491         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
7492 };
7493
7494 spaces.hsla.from = function ( hsla ) {
7495         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
7496                 return [ null, null, null, hsla[ 3 ] ];
7497         }
7498         var h = hsla[ 0 ] / 360,
7499                 s = hsla[ 1 ],
7500                 l = hsla[ 2 ],
7501                 a = hsla[ 3 ],
7502                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
7503                 p = 2 * l - q;
7504
7505         return [
7506                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
7507                 Math.round( hue2rgb( p, q, h ) * 255 ),
7508                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
7509                 a
7510         ];
7511 };
7512
7513
7514 each( spaces, function( spaceName, space ) {
7515         var props = space.props,
7516                 cache = space.cache,
7517                 to = space.to,
7518                 from = space.from;
7519
7520         // makes rgba() and hsla()
7521         color.fn[ spaceName ] = function( value ) {
7522
7523                 // generate a cache for this space if it doesn't exist
7524                 if ( to && !this[ cache ] ) {
7525                         this[ cache ] = to( this._rgba );
7526                 }
7527                 if ( value === undefined ) {
7528                         return this[ cache ].slice();
7529                 }
7530
7531                 var ret,
7532                         type = jQuery.type( value ),
7533                         arr = ( type === "array" || type === "object" ) ? value : arguments,
7534                         local = this[ cache ].slice();
7535
7536                 each( props, function( key, prop ) {
7537                         var val = arr[ type === "object" ? key : prop.idx ];
7538                         if ( val == null ) {
7539                                 val = local[ prop.idx ];
7540                         }
7541                         local[ prop.idx ] = clamp( val, prop );
7542                 });
7543
7544                 if ( from ) {
7545                         ret = color( from( local ) );
7546                         ret[ cache ] = local;
7547                         return ret;
7548                 } else {
7549                         return color( local );
7550                 }
7551         };
7552
7553         // makes red() green() blue() alpha() hue() saturation() lightness()
7554         each( props, function( key, prop ) {
7555                 // alpha is included in more than one space
7556                 if ( color.fn[ key ] ) {
7557                         return;
7558                 }
7559                 color.fn[ key ] = function( value ) {
7560                         var vtype = jQuery.type( value ),
7561                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
7562                                 local = this[ fn ](),
7563                                 cur = local[ prop.idx ],
7564                                 match;
7565
7566                         if ( vtype === "undefined" ) {
7567                                 return cur;
7568                         }
7569
7570                         if ( vtype === "function" ) {
7571                                 value = value.call( this, cur );
7572                                 vtype = jQuery.type( value );
7573                         }
7574                         if ( value == null && prop.empty ) {
7575                                 return this;
7576                         }
7577                         if ( vtype === "string" ) {
7578                                 match = rplusequals.exec( value );
7579                                 if ( match ) {
7580                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
7581                                 }
7582                         }
7583                         local[ prop.idx ] = value;
7584                         return this[ fn ]( local );
7585                 };
7586         });
7587 });
7588
7589 // add .fx.step functions
7590 each( stepHooks, function( i, hook ) {
7591         jQuery.cssHooks[ hook ] = {
7592                 set: function( elem, value ) {
7593                         var parsed, curElem,
7594                                 backgroundColor = "";
7595
7596                         if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
7597                                 value = color( parsed || value );
7598                                 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
7599                                         curElem = hook === "backgroundColor" ? elem.parentNode : elem;
7600                                         while (
7601                                                 (backgroundColor === "" || backgroundColor === "transparent") &&
7602                                                 curElem && curElem.style
7603                                         ) {
7604                                                 try {
7605                                                         backgroundColor = jQuery.css( curElem, "backgroundColor" );
7606                                                         curElem = curElem.parentNode;
7607                                                 } catch ( e ) {
7608                                                 }
7609                                         }
7610
7611                                         value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
7612                                                 backgroundColor :
7613                                                 "_default" );
7614                                 }
7615
7616                                 value = value.toRgbaString();
7617                         }
7618                         try {
7619                                 elem.style[ hook ] = value;
7620                         } catch( error ) {
7621                                 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
7622                         }
7623                 }
7624         };
7625         jQuery.fx.step[ hook ] = function( fx ) {
7626                 if ( !fx.colorInit ) {
7627                         fx.start = color( fx.elem, hook );
7628                         fx.end = color( fx.end );
7629                         fx.colorInit = true;
7630                 }
7631                 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
7632         };
7633 });
7634
7635 jQuery.cssHooks.borderColor = {
7636         expand: function( value ) {
7637                 var expanded = {};
7638
7639                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
7640                         expanded[ "border" + part + "Color" ] = value;
7641                 });
7642                 return expanded;
7643         }
7644 };
7645
7646 // Basic color names only.
7647 // Usage of any of the other color names requires adding yourself or including
7648 // jquery.color.svg-names.js.
7649 colors = jQuery.Color.names = {
7650         // 4.1. Basic color keywords
7651         aqua: "#00ffff",
7652         black: "#000000",
7653         blue: "#0000ff",
7654         fuchsia: "#ff00ff",
7655         gray: "#808080",
7656         green: "#008000",
7657         lime: "#00ff00",
7658         maroon: "#800000",
7659         navy: "#000080",
7660         olive: "#808000",
7661         purple: "#800080",
7662         red: "#ff0000",
7663         silver: "#c0c0c0",
7664         teal: "#008080",
7665         white: "#ffffff",
7666         yellow: "#ffff00",
7667
7668         // 4.2.3. "transparent" color keyword
7669         transparent: [ null, null, null, 0 ],
7670
7671         _default: "#ffffff"
7672 };
7673
7674 })( jQuery );
7675
7676
7677
7678 /******************************************************************************/
7679 /****************************** CLASS ANIMATIONS ******************************/
7680 /******************************************************************************/
7681 (function() {
7682
7683 var classAnimationActions = [ "add", "remove", "toggle" ],
7684         shorthandStyles = {
7685                 border: 1,
7686                 borderBottom: 1,
7687                 borderColor: 1,
7688                 borderLeft: 1,
7689                 borderRight: 1,
7690                 borderTop: 1,
7691                 borderWidth: 1,
7692                 margin: 1,
7693                 padding: 1
7694         };
7695
7696 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
7697         $.fx.step[ prop ] = function( fx ) {
7698                 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
7699                         jQuery.style( fx.elem, prop, fx.end );
7700                         fx.setAttr = true;
7701                 }
7702         };
7703 });
7704
7705 function getElementStyles() {
7706         var style = this.ownerDocument.defaultView ?
7707                         this.ownerDocument.defaultView.getComputedStyle( this, null ) :
7708                         this.currentStyle,
7709                 newStyle = {},
7710                 key,
7711                 len;
7712
7713         // webkit enumerates style porperties
7714         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
7715                 len = style.length;
7716                 while ( len-- ) {
7717                         key = style[ len ];
7718                         if ( typeof style[ key ] === "string" ) {
7719                                 newStyle[ $.camelCase( key ) ] = style[ key ];
7720                         }
7721                 }
7722         } else {
7723                 for ( key in style ) {
7724                         if ( typeof style[ key ] === "string" ) {
7725                                 newStyle[ key ] = style[ key ];
7726                         }
7727                 }
7728         }
7729
7730         return newStyle;
7731 }
7732
7733
7734 function styleDifference( oldStyle, newStyle ) {
7735         var diff = {},
7736                 name, value;
7737
7738         for ( name in newStyle ) {
7739                 value = newStyle[ name ];
7740                 if ( oldStyle[ name ] !== value ) {
7741                         if ( !shorthandStyles[ name ] ) {
7742                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
7743                                         diff[ name ] = value;
7744                                 }
7745                         }
7746                 }
7747         }
7748
7749         return diff;
7750 }
7751
7752 $.effects.animateClass = function( value, duration, easing, callback ) {
7753         var o = $.speed( duration, easing, callback );
7754
7755         return this.queue( function() {
7756                 var animated = $( this ),
7757                         baseClass = animated.attr( "class" ) || "",
7758                         applyClassChange,
7759                         allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
7760
7761                 // map the animated objects to store the original styles.
7762                 allAnimations = allAnimations.map(function() {
7763                         var el = $( this );
7764                         return {
7765                                 el: el,
7766                                 start: getElementStyles.call( this )
7767                         };
7768                 });
7769
7770                 // apply class change
7771                 applyClassChange = function() {
7772                         $.each( classAnimationActions, function(i, action) {
7773                                 if ( value[ action ] ) {
7774                                         animated[ action + "Class" ]( value[ action ] );
7775                                 }
7776                         });
7777                 };
7778                 applyClassChange();
7779
7780                 // map all animated objects again - calculate new styles and diff
7781                 allAnimations = allAnimations.map(function() {
7782                         this.end = getElementStyles.call( this.el[ 0 ] );
7783                         this.diff = styleDifference( this.start, this.end );
7784                         return this;
7785                 });
7786
7787                 // apply original class
7788                 animated.attr( "class", baseClass );
7789
7790                 // map all animated objects again - this time collecting a promise
7791                 allAnimations = allAnimations.map(function() {
7792                         var styleInfo = this,
7793                                 dfd = $.Deferred(),
7794                                 opts = jQuery.extend({}, o, {
7795                                         queue: false,
7796                                         complete: function() {
7797                                                 dfd.resolve( styleInfo );
7798                                         }
7799                                 });
7800
7801                         this.el.animate( this.diff, opts );
7802                         return dfd.promise();
7803                 });
7804
7805                 // once all animations have completed:
7806                 $.when.apply( $, allAnimations.get() ).done(function() {
7807
7808                         // set the final class
7809                         applyClassChange();
7810
7811                         // for each animated element,
7812                         // clear all css properties that were animated
7813                         $.each( arguments, function() {
7814                                 var el = this.el;
7815                                 $.each( this.diff, function(key) {
7816                                         el.css( key, '' );
7817                                 });
7818                         });
7819
7820                         // this is guarnteed to be there if you use jQuery.speed()
7821                         // it also handles dequeuing the next anim...
7822                         o.complete.call( animated[ 0 ] );
7823                 });
7824         });
7825 };
7826
7827 $.fn.extend({
7828         _addClass: $.fn.addClass,
7829         addClass: function( classNames, speed, easing, callback ) {
7830                 return speed ?
7831                         $.effects.animateClass.call( this,
7832                                 { add: classNames }, speed, easing, callback ) :
7833                         this._addClass( classNames );
7834         },
7835
7836         _removeClass: $.fn.removeClass,
7837         removeClass: function( classNames, speed, easing, callback ) {
7838                 return speed ?
7839                         $.effects.animateClass.call( this,
7840                                 { remove: classNames }, speed, easing, callback ) :
7841                         this._removeClass( classNames );
7842         },
7843
7844         _toggleClass: $.fn.toggleClass,
7845         toggleClass: function( classNames, force, speed, easing, callback ) {
7846                 if ( typeof force === "boolean" || force === undefined ) {
7847                         if ( !speed ) {
7848                                 // without speed parameter
7849                                 return this._toggleClass( classNames, force );
7850                         } else {
7851                                 return $.effects.animateClass.call( this,
7852                                         (force ? { add: classNames } : { remove: classNames }),
7853                                         speed, easing, callback );
7854                         }
7855                 } else {
7856                         // without force parameter
7857                         return $.effects.animateClass.call( this,
7858                                 { toggle: classNames }, force, speed, easing );
7859                 }
7860         },
7861
7862         switchClass: function( remove, add, speed, easing, callback) {
7863                 return $.effects.animateClass.call( this, {
7864                         add: add,
7865                         remove: remove
7866                 }, speed, easing, callback );
7867         }
7868 });
7869
7870 })();
7871
7872 /******************************************************************************/
7873 /*********************************** EFFECTS **********************************/
7874 /******************************************************************************/
7875
7876 (function() {
7877
7878 $.extend( $.effects, {
7879         version: "1.9.2",
7880
7881         // Saves a set of properties in a data storage
7882         save: function( element, set ) {
7883                 for( var i=0; i < set.length; i++ ) {
7884                         if ( set[ i ] !== null ) {
7885                                 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
7886                         }
7887                 }
7888         },
7889
7890         // Restores a set of previously saved properties from a data storage
7891         restore: function( element, set ) {
7892                 var val, i;
7893                 for( i=0; i < set.length; i++ ) {
7894                         if ( set[ i ] !== null ) {
7895                                 val = element.data( dataSpace + set[ i ] );
7896                                 // support: jQuery 1.6.2
7897                                 // http://bugs.jquery.com/ticket/9917
7898                                 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
7899                                 // We can't differentiate between "" and 0 here, so we just assume
7900                                 // empty string since it's likely to be a more common value...
7901                                 if ( val === undefined ) {
7902                                         val = "";
7903                                 }
7904                                 element.css( set[ i ], val );
7905                         }
7906                 }
7907         },
7908
7909         setMode: function( el, mode ) {
7910                 if (mode === "toggle") {
7911                         mode = el.is( ":hidden" ) ? "show" : "hide";
7912                 }
7913                 return mode;
7914         },
7915
7916         // Translates a [top,left] array into a baseline value
7917         // this should be a little more flexible in the future to handle a string & hash
7918         getBaseline: function( origin, original ) {
7919                 var y, x;
7920                 switch ( origin[ 0 ] ) {
7921                         case "top": y = 0; break;
7922                         case "middle": y = 0.5; break;
7923                         case "bottom": y = 1; break;
7924                         default: y = origin[ 0 ] / original.height;
7925                 }
7926                 switch ( origin[ 1 ] ) {
7927                         case "left": x = 0; break;
7928                         case "center": x = 0.5; break;
7929                         case "right": x = 1; break;
7930                         default: x = origin[ 1 ] / original.width;
7931                 }
7932                 return {
7933                         x: x,
7934                         y: y
7935                 };
7936         },
7937
7938         // Wraps the element around a wrapper that copies position properties
7939         createWrapper: function( element ) {
7940
7941                 // if the element is already wrapped, return it
7942                 if ( element.parent().is( ".ui-effects-wrapper" )) {
7943                         return element.parent();
7944                 }
7945
7946                 // wrap the element
7947                 var props = {
7948                                 width: element.outerWidth(true),
7949                                 height: element.outerHeight(true),
7950                                 "float": element.css( "float" )
7951                         },
7952                         wrapper = $( "<div></div>" )
7953                                 .addClass( "ui-effects-wrapper" )
7954                                 .css({
7955                                         fontSize: "100%",
7956                                         background: "transparent",
7957                                         border: "none",
7958                                         margin: 0,
7959                                         padding: 0
7960                                 }),
7961                         // Store the size in case width/height are defined in % - Fixes #5245
7962                         size = {
7963                                 width: element.width(),
7964                                 height: element.height()
7965                         },
7966                         active = document.activeElement;
7967
7968                 // support: Firefox
7969                 // Firefox incorrectly exposes anonymous content
7970                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
7971                 try {
7972                         active.id;
7973                 } catch( e ) {
7974                         active = document.body;
7975                 }
7976
7977                 element.wrap( wrapper );
7978
7979                 // Fixes #7595 - Elements lose focus when wrapped.
7980                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
7981                         $( active ).focus();
7982                 }
7983
7984                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
7985
7986                 // transfer positioning properties to the wrapper
7987                 if ( element.css( "position" ) === "static" ) {
7988                         wrapper.css({ position: "relative" });
7989                         element.css({ position: "relative" });
7990                 } else {
7991                         $.extend( props, {
7992                                 position: element.css( "position" ),
7993                                 zIndex: element.css( "z-index" )
7994                         });
7995                         $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
7996                                 props[ pos ] = element.css( pos );
7997                                 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
7998                                         props[ pos ] = "auto";
7999                                 }
8000                         });
8001                         element.css({
8002                                 position: "relative",
8003                                 top: 0,
8004                                 left: 0,
8005                                 right: "auto",
8006                                 bottom: "auto"
8007                         });
8008                 }
8009                 element.css(size);
8010
8011                 return wrapper.css( props ).show();
8012         },
8013
8014         removeWrapper: function( element ) {
8015                 var active = document.activeElement;
8016
8017                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
8018                         element.parent().replaceWith( element );
8019
8020                         // Fixes #7595 - Elements lose focus when wrapped.
8021                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
8022                                 $( active ).focus();
8023                         }
8024                 }
8025
8026
8027                 return element;
8028         },
8029
8030         setTransition: function( element, list, factor, value ) {
8031                 value = value || {};
8032                 $.each( list, function( i, x ) {
8033                         var unit = element.cssUnit( x );
8034                         if ( unit[ 0 ] > 0 ) {
8035                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
8036                         }
8037                 });
8038                 return value;
8039         }
8040 });
8041
8042 // return an effect options object for the given parameters:
8043 function _normalizeArguments( effect, options, speed, callback ) {
8044
8045         // allow passing all options as the first parameter
8046         if ( $.isPlainObject( effect ) ) {
8047                 options = effect;
8048                 effect = effect.effect;
8049         }
8050
8051         // convert to an object
8052         effect = { effect: effect };
8053
8054         // catch (effect, null, ...)
8055         if ( options == null ) {
8056                 options = {};
8057         }
8058
8059         // catch (effect, callback)
8060         if ( $.isFunction( options ) ) {
8061                 callback = options;
8062                 speed = null;
8063                 options = {};
8064         }
8065
8066         // catch (effect, speed, ?)
8067         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
8068                 callback = speed;
8069                 speed = options;
8070                 options = {};
8071         }
8072
8073         // catch (effect, options, callback)
8074         if ( $.isFunction( speed ) ) {
8075                 callback = speed;
8076                 speed = null;
8077         }
8078
8079         // add options to effect
8080         if ( options ) {
8081                 $.extend( effect, options );
8082         }
8083
8084         speed = speed || options.duration;
8085         effect.duration = $.fx.off ? 0 :
8086                 typeof speed === "number" ? speed :
8087                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
8088                 $.fx.speeds._default;
8089
8090         effect.complete = callback || options.complete;
8091
8092         return effect;
8093 }
8094
8095 function standardSpeed( speed ) {
8096         // valid standard speeds
8097         if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
8098                 return true;
8099         }
8100
8101         // invalid strings - treat as "normal" speed
8102         if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
8103                 // TODO: remove in 2.0 (#7115)
8104                 if ( backCompat && $.effects[ speed ] ) {
8105                         return false;
8106                 }
8107                 return true;
8108         }
8109
8110         return false;
8111 }
8112
8113 $.fn.extend({
8114         effect: function( /* effect, options, speed, callback */ ) {
8115                 var args = _normalizeArguments.apply( this, arguments ),
8116                         mode = args.mode,
8117                         queue = args.queue,
8118                         effectMethod = $.effects.effect[ args.effect ],
8119
8120                         // DEPRECATED: remove in 2.0 (#7115)
8121                         oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
8122
8123                 if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
8124                         // delegate to the original method (e.g., .show()) if possible
8125                         if ( mode ) {
8126                                 return this[ mode ]( args.duration, args.complete );
8127                         } else {
8128                                 return this.each( function() {
8129                                         if ( args.complete ) {
8130                                                 args.complete.call( this );
8131                                         }
8132                                 });
8133                         }
8134                 }
8135
8136                 function run( next ) {
8137                         var elem = $( this ),
8138                                 complete = args.complete,
8139                                 mode = args.mode;
8140
8141                         function done() {
8142                                 if ( $.isFunction( complete ) ) {
8143                                         complete.call( elem[0] );
8144                                 }
8145                                 if ( $.isFunction( next ) ) {
8146                                         next();
8147                                 }
8148                         }
8149
8150                         // if the element is hiddden and mode is hide,
8151                         // or element is visible and mode is show
8152                         if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
8153                                 done();
8154                         } else {
8155                                 effectMethod.call( elem[0], args, done );
8156                         }
8157                 }
8158
8159                 // TODO: remove this check in 2.0, effectMethod will always be true
8160                 if ( effectMethod ) {
8161                         return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
8162                 } else {
8163                         // DEPRECATED: remove in 2.0 (#7115)
8164                         return oldEffectMethod.call(this, {
8165                                 options: args,
8166                                 duration: args.duration,
8167                                 callback: args.complete,
8168                                 mode: args.mode
8169                         });
8170                 }
8171         },
8172
8173         _show: $.fn.show,
8174         show: function( speed ) {
8175                 if ( standardSpeed( speed ) ) {
8176                         return this._show.apply( this, arguments );
8177                 } else {
8178                         var args = _normalizeArguments.apply( this, arguments );
8179                         args.mode = "show";
8180                         return this.effect.call( this, args );
8181                 }
8182         },
8183
8184         _hide: $.fn.hide,
8185         hide: function( speed ) {
8186                 if ( standardSpeed( speed ) ) {
8187                         return this._hide.apply( this, arguments );
8188                 } else {
8189                         var args = _normalizeArguments.apply( this, arguments );
8190                         args.mode = "hide";
8191                         return this.effect.call( this, args );
8192                 }
8193         },
8194
8195         // jQuery core overloads toggle and creates _toggle
8196         __toggle: $.fn.toggle,
8197         toggle: function( speed ) {
8198                 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
8199                         return this.__toggle.apply( this, arguments );
8200                 } else {
8201                         var args = _normalizeArguments.apply( this, arguments );
8202                         args.mode = "toggle";
8203                         return this.effect.call( this, args );
8204                 }
8205         },
8206
8207         // helper functions
8208         cssUnit: function(key) {
8209                 var style = this.css( key ),
8210                         val = [];
8211
8212                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
8213                         if ( style.indexOf( unit ) > 0 ) {
8214                                 val = [ parseFloat( style ), unit ];
8215                         }
8216                 });
8217                 return val;
8218         }
8219 });
8220
8221 })();
8222
8223 /******************************************************************************/
8224 /*********************************** EASING ***********************************/
8225 /******************************************************************************/
8226
8227 (function() {
8228
8229 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
8230
8231 var baseEasings = {};
8232
8233 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
8234         baseEasings[ name ] = function( p ) {
8235                 return Math.pow( p, i + 2 );
8236         };
8237 });
8238
8239 $.extend( baseEasings, {
8240         Sine: function ( p ) {
8241                 return 1 - Math.cos( p * Math.PI / 2 );
8242         },
8243         Circ: function ( p ) {
8244                 return 1 - Math.sqrt( 1 - p * p );
8245         },
8246         Elastic: function( p ) {
8247                 return p === 0 || p === 1 ? p :
8248                         -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
8249         },
8250         Back: function( p ) {
8251                 return p * p * ( 3 * p - 2 );
8252         },
8253         Bounce: function ( p ) {
8254                 var pow2,
8255                         bounce = 4;
8256
8257                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
8258                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
8259         }
8260 });
8261
8262 $.each( baseEasings, function( name, easeIn ) {
8263         $.easing[ "easeIn" + name ] = easeIn;
8264         $.easing[ "easeOut" + name ] = function( p ) {
8265                 return 1 - easeIn( 1 - p );
8266         };
8267         $.easing[ "easeInOut" + name ] = function( p ) {
8268                 return p < 0.5 ?
8269                         easeIn( p * 2 ) / 2 :
8270                         1 - easeIn( p * -2 + 2 ) / 2;
8271         };
8272 });
8273
8274 })();
8275
8276 })(jQuery));
8277 (function( $, undefined ) {
8278
8279 var rvertical = /up|down|vertical/,
8280         rpositivemotion = /up|left|vertical|horizontal/;
8281
8282 $.effects.effect.blind = function( o, done ) {
8283         // Create element
8284         var el = $( this ),
8285                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
8286                 mode = $.effects.setMode( el, o.mode || "hide" ),
8287                 direction = o.direction || "up",
8288                 vertical = rvertical.test( direction ),
8289                 ref = vertical ? "height" : "width",
8290                 ref2 = vertical ? "top" : "left",
8291                 motion = rpositivemotion.test( direction ),
8292                 animation = {},
8293                 show = mode === "show",
8294                 wrapper, distance, margin;
8295
8296         // if already wrapped, the wrapper's properties are my property. #6245
8297         if ( el.parent().is( ".ui-effects-wrapper" ) ) {
8298                 $.effects.save( el.parent(), props );
8299         } else {
8300                 $.effects.save( el, props );
8301         }
8302         el.show();
8303         wrapper = $.effects.createWrapper( el ).css({
8304                 overflow: "hidden"
8305         });
8306
8307         distance = wrapper[ ref ]();
8308         margin = parseFloat( wrapper.css( ref2 ) ) || 0;
8309
8310         animation[ ref ] = show ? distance : 0;
8311         if ( !motion ) {
8312                 el
8313                         .css( vertical ? "bottom" : "right", 0 )
8314                         .css( vertical ? "top" : "left", "auto" )
8315                         .css({ position: "absolute" });
8316
8317                 animation[ ref2 ] = show ? margin : distance + margin;
8318         }
8319
8320         // start at 0 if we are showing
8321         if ( show ) {
8322                 wrapper.css( ref, 0 );
8323                 if ( ! motion ) {
8324                         wrapper.css( ref2, margin + distance );
8325                 }
8326         }
8327
8328         // Animate
8329         wrapper.animate( animation, {
8330                 duration: o.duration,
8331                 easing: o.easing,
8332                 queue: false,
8333                 complete: function() {
8334                         if ( mode === "hide" ) {
8335                                 el.hide();
8336                         }
8337                         $.effects.restore( el, props );
8338                         $.effects.removeWrapper( el );
8339                         done();
8340                 }
8341         });
8342
8343 };
8344
8345 })(jQuery);
8346 (function( $, undefined ) {
8347
8348 $.effects.effect.bounce = function( o, done ) {
8349         var el = $( this ),
8350                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
8351
8352                 // defaults:
8353                 mode = $.effects.setMode( el, o.mode || "effect" ),
8354                 hide = mode === "hide",
8355                 show = mode === "show",
8356                 direction = o.direction || "up",
8357                 distance = o.distance,
8358                 times = o.times || 5,
8359
8360                 // number of internal animations
8361                 anims = times * 2 + ( show || hide ? 1 : 0 ),
8362                 speed = o.duration / anims,
8363                 easing = o.easing,
8364
8365                 // utility:
8366                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
8367                 motion = ( direction === "up" || direction === "left" ),
8368                 i,
8369                 upAnim,
8370                 downAnim,
8371
8372                 // we will need to re-assemble the queue to stack our animations in place
8373                 queue = el.queue(),
8374                 queuelen = queue.length;
8375
8376         // Avoid touching opacity to prevent clearType and PNG issues in IE
8377         if ( show || hide ) {
8378                 props.push( "opacity" );
8379         }
8380
8381         $.effects.save( el, props );
8382         el.show();
8383         $.effects.createWrapper( el ); // Create Wrapper
8384
8385         // default distance for the BIGGEST bounce is the outer Distance / 3
8386         if ( !distance ) {
8387                 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
8388         }
8389
8390         if ( show ) {
8391                 downAnim = { opacity: 1 };
8392                 downAnim[ ref ] = 0;
8393
8394                 // if we are showing, force opacity 0 and set the initial position
8395                 // then do the "first" animation
8396                 el.css( "opacity", 0 )
8397                         .css( ref, motion ? -distance * 2 : distance * 2 )
8398                         .animate( downAnim, speed, easing );
8399         }
8400
8401         // start at the smallest distance if we are hiding
8402         if ( hide ) {
8403                 distance = distance / Math.pow( 2, times - 1 );
8404         }
8405
8406         downAnim = {};
8407         downAnim[ ref ] = 0;
8408         // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
8409         for ( i = 0; i < times; i++ ) {
8410                 upAnim = {};
8411                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
8412
8413                 el.animate( upAnim, speed, easing )
8414                         .animate( downAnim, speed, easing );
8415
8416                 distance = hide ? distance * 2 : distance / 2;
8417         }
8418
8419         // Last Bounce when Hiding
8420         if ( hide ) {
8421                 upAnim = { opacity: 0 };
8422                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
8423
8424                 el.animate( upAnim, speed, easing );
8425         }
8426
8427         el.queue(function() {
8428                 if ( hide ) {
8429                         el.hide();
8430                 }
8431                 $.effects.restore( el, props );
8432                 $.effects.removeWrapper( el );
8433                 done();
8434         });
8435
8436         // inject all the animations we just queued to be first in line (after "inprogress")
8437         if ( queuelen > 1) {
8438                 queue.splice.apply( queue,
8439                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
8440         }
8441         el.dequeue();
8442
8443 };
8444
8445 })(jQuery);
8446 (function( $, undefined ) {
8447
8448 $.effects.effect.clip = function( o, done ) {
8449         // Create element
8450         var el = $( this ),
8451                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
8452                 mode = $.effects.setMode( el, o.mode || "hide" ),
8453                 show = mode === "show",
8454                 direction = o.direction || "vertical",
8455                 vert = direction === "vertical",
8456                 size = vert ? "height" : "width",
8457                 position = vert ? "top" : "left",
8458                 animation = {},
8459                 wrapper, animate, distance;
8460
8461         // Save & Show
8462         $.effects.save( el, props );
8463         el.show();
8464
8465         // Create Wrapper
8466         wrapper = $.effects.createWrapper( el ).css({
8467                 overflow: "hidden"
8468         });
8469         animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
8470         distance = animate[ size ]();
8471
8472         // Shift
8473         if ( show ) {
8474                 animate.css( size, 0 );
8475                 animate.css( position, distance / 2 );
8476         }
8477
8478         // Create Animation Object:
8479         animation[ size ] = show ? distance : 0;
8480         animation[ position ] = show ? 0 : distance / 2;
8481
8482         // Animate
8483         animate.animate( animation, {
8484                 queue: false,
8485                 duration: o.duration,
8486                 easing: o.easing,
8487                 complete: function() {
8488                         if ( !show ) {
8489                                 el.hide();
8490                         }
8491                         $.effects.restore( el, props );
8492                         $.effects.removeWrapper( el );
8493                         done();
8494                 }
8495         });
8496
8497 };
8498
8499 })(jQuery);
8500 (function( $, undefined ) {
8501
8502 $.effects.effect.drop = function( o, done ) {
8503
8504         var el = $( this ),
8505                 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
8506                 mode = $.effects.setMode( el, o.mode || "hide" ),
8507                 show = mode === "show",
8508                 direction = o.direction || "left",
8509                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
8510                 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
8511                 animation = {
8512                         opacity: show ? 1 : 0
8513                 },
8514                 distance;
8515
8516         // Adjust
8517         $.effects.save( el, props );
8518         el.show();
8519         $.effects.createWrapper( el );
8520
8521         distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
8522
8523         if ( show ) {
8524                 el
8525                         .css( "opacity", 0 )
8526                         .css( ref, motion === "pos" ? -distance : distance );
8527         }
8528
8529         // Animation
8530         animation[ ref ] = ( show ?
8531                 ( motion === "pos" ? "+=" : "-=" ) :
8532                 ( motion === "pos" ? "-=" : "+=" ) ) +
8533                 distance;
8534
8535         // Animate
8536         el.animate( animation, {
8537                 queue: false,
8538                 duration: o.duration,
8539                 easing: o.easing,
8540                 complete: function() {
8541                         if ( mode === "hide" ) {
8542                                 el.hide();
8543                         }
8544                         $.effects.restore( el, props );
8545                         $.effects.removeWrapper( el );
8546                         done();
8547                 }
8548         });
8549 };
8550
8551 })(jQuery);
8552 (function( $, undefined ) {
8553
8554 $.effects.effect.explode = function( o, done ) {
8555
8556         var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
8557                 cells = rows,
8558                 el = $( this ),
8559                 mode = $.effects.setMode( el, o.mode || "hide" ),
8560                 show = mode === "show",
8561
8562                 // show and then visibility:hidden the element before calculating offset
8563                 offset = el.show().css( "visibility", "hidden" ).offset(),
8564
8565                 // width and height of a piece
8566                 width = Math.ceil( el.outerWidth() / cells ),
8567                 height = Math.ceil( el.outerHeight() / rows ),
8568                 pieces = [],
8569
8570                 // loop
8571                 i, j, left, top, mx, my;
8572
8573         // children animate complete:
8574         function childComplete() {
8575                 pieces.push( this );
8576                 if ( pieces.length === rows * cells ) {
8577                         animComplete();
8578                 }
8579         }
8580
8581         // clone the element for each row and cell.
8582         for( i = 0; i < rows ; i++ ) { // ===>
8583                 top = offset.top + i * height;
8584                 my = i - ( rows - 1 ) / 2 ;
8585
8586                 for( j = 0; j < cells ; j++ ) { // |||
8587                         left = offset.left + j * width;
8588                         mx = j - ( cells - 1 ) / 2 ;
8589
8590                         // Create a clone of the now hidden main element that will be absolute positioned
8591                         // within a wrapper div off the -left and -top equal to size of our pieces
8592                         el
8593                                 .clone()
8594                                 .appendTo( "body" )
8595                                 .wrap( "<div></div>" )
8596                                 .css({
8597                                         position: "absolute",
8598                                         visibility: "visible",
8599                                         left: -j * width,
8600                                         top: -i * height
8601                                 })
8602
8603                         // select the wrapper - make it overflow: hidden and absolute positioned based on
8604                         // where the original was located +left and +top equal to the size of pieces
8605                                 .parent()
8606                                 .addClass( "ui-effects-explode" )
8607                                 .css({
8608                                         position: "absolute",
8609                                         overflow: "hidden",
8610                                         width: width,
8611                                         height: height,
8612                                         left: left + ( show ? mx * width : 0 ),
8613                                         top: top + ( show ? my * height : 0 ),
8614                                         opacity: show ? 0 : 1
8615                                 }).animate({
8616                                         left: left + ( show ? 0 : mx * width ),
8617                                         top: top + ( show ? 0 : my * height ),
8618                                         opacity: show ? 1 : 0
8619                                 }, o.duration || 500, o.easing, childComplete );
8620                 }
8621         }
8622
8623         function animComplete() {
8624                 el.css({
8625                         visibility: "visible"
8626                 });
8627                 $( pieces ).remove();
8628                 if ( !show ) {
8629                         el.hide();
8630                 }
8631                 done();
8632         }
8633 };
8634
8635 })(jQuery);
8636 (function( $, undefined ) {
8637
8638 $.effects.effect.fade = function( o, done ) {
8639         var el = $( this ),
8640                 mode = $.effects.setMode( el, o.mode || "toggle" );
8641
8642         el.animate({
8643                 opacity: mode
8644         }, {
8645                 queue: false,
8646                 duration: o.duration,
8647                 easing: o.easing,
8648                 complete: done
8649         });
8650 };
8651
8652 })( jQuery );
8653 (function( $, undefined ) {
8654
8655 $.effects.effect.fold = function( o, done ) {
8656
8657         // Create element
8658         var el = $( this ),
8659                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
8660                 mode = $.effects.setMode( el, o.mode || "hide" ),
8661                 show = mode === "show",
8662                 hide = mode === "hide",
8663                 size = o.size || 15,
8664                 percent = /([0-9]+)%/.exec( size ),
8665                 horizFirst = !!o.horizFirst,
8666                 widthFirst = show !== horizFirst,
8667                 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
8668                 duration = o.duration / 2,
8669                 wrapper, distance,
8670                 animation1 = {},
8671                 animation2 = {};
8672
8673         $.effects.save( el, props );
8674         el.show();
8675
8676         // Create Wrapper
8677         wrapper = $.effects.createWrapper( el ).css({
8678                 overflow: "hidden"
8679         });
8680         distance = widthFirst ?
8681                 [ wrapper.width(), wrapper.height() ] :
8682                 [ wrapper.height(), wrapper.width() ];
8683
8684         if ( percent ) {
8685                 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
8686         }
8687         if ( show ) {
8688                 wrapper.css( horizFirst ? {
8689                         height: 0,
8690                         width: size
8691                 } : {
8692                         height: size,
8693                         width: 0
8694                 });
8695         }
8696
8697         // Animation
8698         animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
8699         animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
8700
8701         // Animate
8702         wrapper
8703                 .animate( animation1, duration, o.easing )
8704                 .animate( animation2, duration, o.easing, function() {
8705                         if ( hide ) {
8706                                 el.hide();
8707                         }
8708                         $.effects.restore( el, props );
8709                         $.effects.removeWrapper( el );
8710                         done();
8711                 });
8712
8713 };
8714
8715 })(jQuery);
8716 (function( $, undefined ) {
8717
8718 $.effects.effect.highlight = function( o, done ) {
8719         var elem = $( this ),
8720                 props = [ "backgroundImage", "backgroundColor", "opacity" ],
8721                 mode = $.effects.setMode( elem, o.mode || "show" ),
8722                 animation = {
8723                         backgroundColor: elem.css( "backgroundColor" )
8724                 };
8725
8726         if (mode === "hide") {
8727                 animation.opacity = 0;
8728         }
8729
8730         $.effects.save( elem, props );
8731
8732         elem
8733                 .show()
8734                 .css({
8735                         backgroundImage: "none",
8736                         backgroundColor: o.color || "#ffff99"
8737                 })
8738                 .animate( animation, {
8739                         queue: false,
8740                         duration: o.duration,
8741                         easing: o.easing,
8742                         complete: function() {
8743                                 if ( mode === "hide" ) {
8744                                         elem.hide();
8745                                 }
8746                                 $.effects.restore( elem, props );
8747                                 done();
8748                         }
8749                 });
8750 };
8751
8752 })(jQuery);
8753 (function( $, undefined ) {
8754
8755 $.effects.effect.pulsate = function( o, done ) {
8756         var elem = $( this ),
8757                 mode = $.effects.setMode( elem, o.mode || "show" ),
8758                 show = mode === "show",
8759                 hide = mode === "hide",
8760                 showhide = ( show || mode === "hide" ),
8761
8762                 // showing or hiding leaves of the "last" animation
8763                 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
8764                 duration = o.duration / anims,
8765                 animateTo = 0,
8766                 queue = elem.queue(),
8767                 queuelen = queue.length,
8768                 i;
8769
8770         if ( show || !elem.is(":visible")) {
8771                 elem.css( "opacity", 0 ).show();
8772                 animateTo = 1;
8773         }
8774
8775         // anims - 1 opacity "toggles"
8776         for ( i = 1; i < anims; i++ ) {
8777                 elem.animate({
8778                         opacity: animateTo
8779                 }, duration, o.easing );
8780                 animateTo = 1 - animateTo;
8781         }
8782
8783         elem.animate({
8784                 opacity: animateTo
8785         }, duration, o.easing);
8786
8787         elem.queue(function() {
8788                 if ( hide ) {
8789                         elem.hide();
8790                 }
8791                 done();
8792         });
8793
8794         // We just queued up "anims" animations, we need to put them next in the queue
8795         if ( queuelen > 1 ) {
8796                 queue.splice.apply( queue,
8797                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
8798         }
8799         elem.dequeue();
8800 };
8801
8802 })(jQuery);
8803 (function( $, undefined ) {
8804
8805 $.effects.effect.puff = function( o, done ) {
8806         var elem = $( this ),
8807                 mode = $.effects.setMode( elem, o.mode || "hide" ),
8808                 hide = mode === "hide",
8809                 percent = parseInt( o.percent, 10 ) || 150,
8810                 factor = percent / 100,
8811                 original = {
8812                         height: elem.height(),
8813                         width: elem.width(),
8814                         outerHeight: elem.outerHeight(),
8815                         outerWidth: elem.outerWidth()
8816                 };
8817
8818         $.extend( o, {
8819                 effect: "scale",
8820                 queue: false,
8821                 fade: true,
8822                 mode: mode,
8823                 complete: done,
8824                 percent: hide ? percent : 100,
8825                 from: hide ?
8826                         original :
8827                         {
8828                                 height: original.height * factor,
8829                                 width: original.width * factor,
8830                                 outerHeight: original.outerHeight * factor,
8831                                 outerWidth: original.outerWidth * factor
8832                         }
8833         });
8834
8835         elem.effect( o );
8836 };
8837
8838 $.effects.effect.scale = function( o, done ) {
8839
8840         // Create element
8841         var el = $( this ),
8842                 options = $.extend( true, {}, o ),
8843                 mode = $.effects.setMode( el, o.mode || "effect" ),
8844                 percent = parseInt( o.percent, 10 ) ||
8845                         ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
8846                 direction = o.direction || "both",
8847                 origin = o.origin,
8848                 original = {
8849                         height: el.height(),
8850                         width: el.width(),
8851                         outerHeight: el.outerHeight(),
8852                         outerWidth: el.outerWidth()
8853                 },
8854                 factor = {
8855                         y: direction !== "horizontal" ? (percent / 100) : 1,
8856                         x: direction !== "vertical" ? (percent / 100) : 1
8857                 };
8858
8859         // We are going to pass this effect to the size effect:
8860         options.effect = "size";
8861         options.queue = false;
8862         options.complete = done;
8863
8864         // Set default origin and restore for show/hide
8865         if ( mode !== "effect" ) {
8866                 options.origin = origin || ["middle","center"];
8867                 options.restore = true;
8868         }
8869
8870         options.from = o.from || ( mode === "show" ? {
8871                 height: 0,
8872                 width: 0,
8873                 outerHeight: 0,
8874                 outerWidth: 0
8875         } : original );
8876         options.to = {
8877                 height: original.height * factor.y,
8878                 width: original.width * factor.x,
8879                 outerHeight: original.outerHeight * factor.y,
8880                 outerWidth: original.outerWidth * factor.x
8881         };
8882
8883         // Fade option to support puff
8884         if ( options.fade ) {
8885                 if ( mode === "show" ) {
8886                         options.from.opacity = 0;
8887                         options.to.opacity = 1;
8888                 }
8889                 if ( mode === "hide" ) {
8890                         options.from.opacity = 1;
8891                         options.to.opacity = 0;
8892                 }
8893         }
8894
8895         // Animate
8896         el.effect( options );
8897
8898 };
8899
8900 $.effects.effect.size = function( o, done ) {
8901
8902         // Create element
8903         var original, baseline, factor,
8904                 el = $( this ),
8905                 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
8906
8907                 // Always restore
8908                 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
8909
8910                 // Copy for children
8911                 props2 = [ "width", "height", "overflow" ],
8912                 cProps = [ "fontSize" ],
8913                 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
8914                 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
8915
8916                 // Set options
8917                 mode = $.effects.setMode( el, o.mode || "effect" ),
8918                 restore = o.restore || mode !== "effect",
8919                 scale = o.scale || "both",
8920                 origin = o.origin || [ "middle", "center" ],
8921                 position = el.css( "position" ),
8922                 props = restore ? props0 : props1,
8923                 zero = {
8924                         height: 0,
8925                         width: 0,
8926                         outerHeight: 0,
8927                         outerWidth: 0
8928                 };
8929
8930         if ( mode === "show" ) {
8931                 el.show();
8932         }
8933         original = {
8934                 height: el.height(),
8935                 width: el.width(),
8936                 outerHeight: el.outerHeight(),
8937                 outerWidth: el.outerWidth()
8938         };
8939
8940         if ( o.mode === "toggle" && mode === "show" ) {
8941                 el.from = o.to || zero;
8942                 el.to = o.from || original;
8943         } else {
8944                 el.from = o.from || ( mode === "show" ? zero : original );
8945                 el.to = o.to || ( mode === "hide" ? zero : original );
8946         }
8947
8948         // Set scaling factor
8949         factor = {
8950                 from: {
8951                         y: el.from.height / original.height,
8952                         x: el.from.width / original.width
8953                 },
8954                 to: {
8955                         y: el.to.height / original.height,
8956                         x: el.to.width / original.width
8957                 }
8958         };
8959
8960         // Scale the css box
8961         if ( scale === "box" || scale === "both" ) {
8962
8963                 // Vertical props scaling
8964                 if ( factor.from.y !== factor.to.y ) {
8965                         props = props.concat( vProps );
8966                         el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
8967                         el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
8968                 }
8969
8970                 // Horizontal props scaling
8971                 if ( factor.from.x !== factor.to.x ) {
8972                         props = props.concat( hProps );
8973                         el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
8974                         el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
8975                 }
8976         }
8977
8978         // Scale the content
8979         if ( scale === "content" || scale === "both" ) {
8980
8981                 // Vertical props scaling
8982                 if ( factor.from.y !== factor.to.y ) {
8983                         props = props.concat( cProps ).concat( props2 );
8984                         el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
8985                         el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
8986                 }
8987         }
8988
8989         $.effects.save( el, props );
8990         el.show();
8991         $.effects.createWrapper( el );
8992         el.css( "overflow", "hidden" ).css( el.from );
8993
8994         // Adjust
8995         if (origin) { // Calculate baseline shifts
8996                 baseline = $.effects.getBaseline( origin, original );
8997                 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
8998                 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
8999                 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
9000                 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
9001         }
9002         el.css( el.from ); // set top & left
9003
9004         // Animate
9005         if ( scale === "content" || scale === "both" ) { // Scale the children
9006
9007                 // Add margins/font-size
9008                 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
9009                 hProps = hProps.concat([ "marginLeft", "marginRight" ]);
9010                 props2 = props0.concat(vProps).concat(hProps);
9011
9012                 el.find( "*[width]" ).each( function(){
9013                         var child = $( this ),
9014                                 c_original = {
9015                                         height: child.height(),
9016                                         width: child.width(),
9017                                         outerHeight: child.outerHeight(),
9018                                         outerWidth: child.outerWidth()
9019                                 };
9020                         if (restore) {
9021                                 $.effects.save(child, props2);
9022                         }
9023
9024                         child.from = {
9025                                 height: c_original.height * factor.from.y,
9026                                 width: c_original.width * factor.from.x,
9027                                 outerHeight: c_original.outerHeight * factor.from.y,
9028                                 outerWidth: c_original.outerWidth * factor.from.x
9029                         };
9030                         child.to = {
9031                                 height: c_original.height * factor.to.y,
9032                                 width: c_original.width * factor.to.x,
9033                                 outerHeight: c_original.height * factor.to.y,
9034                                 outerWidth: c_original.width * factor.to.x
9035                         };
9036
9037                         // Vertical props scaling
9038                         if ( factor.from.y !== factor.to.y ) {
9039                                 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
9040                                 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
9041                         }
9042
9043                         // Horizontal props scaling
9044                         if ( factor.from.x !== factor.to.x ) {
9045                                 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
9046                                 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
9047                         }
9048
9049                         // Animate children
9050                         child.css( child.from );
9051                         child.animate( child.to, o.duration, o.easing, function() {
9052
9053                                 // Restore children
9054                                 if ( restore ) {
9055                                         $.effects.restore( child, props2 );
9056                                 }
9057                         });
9058                 });
9059         }
9060
9061         // Animate
9062         el.animate( el.to, {
9063                 queue: false,
9064                 duration: o.duration,
9065                 easing: o.easing,
9066                 complete: function() {
9067                         if ( el.to.opacity === 0 ) {
9068                                 el.css( "opacity", el.from.opacity );
9069                         }
9070                         if( mode === "hide" ) {
9071                                 el.hide();
9072                         }
9073                         $.effects.restore( el, props );
9074                         if ( !restore ) {
9075
9076                                 // we need to calculate our new positioning based on the scaling
9077                                 if ( position === "static" ) {
9078                                         el.css({
9079                                                 position: "relative",
9080                                                 top: el.to.top,
9081                                                 left: el.to.left
9082                                         });
9083                                 } else {
9084                                         $.each([ "top", "left" ], function( idx, pos ) {
9085                                                 el.css( pos, function( _, str ) {
9086                                                         var val = parseInt( str, 10 ),
9087                                                                 toRef = idx ? el.to.left : el.to.top;
9088
9089                                                         // if original was "auto", recalculate the new value from wrapper
9090                                                         if ( str === "auto" ) {
9091                                                                 return toRef + "px";
9092                                                         }
9093
9094                                                         return val + toRef + "px";
9095                                                 });
9096                                         });
9097                                 }
9098                         }
9099
9100                         $.effects.removeWrapper( el );
9101                         done();
9102                 }
9103         });
9104
9105 };
9106
9107 })(jQuery);
9108 (function( $, undefined ) {
9109
9110 $.effects.effect.shake = function( o, done ) {
9111
9112         var el = $( this ),
9113                 props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9114                 mode = $.effects.setMode( el, o.mode || "effect" ),
9115                 direction = o.direction || "left",
9116                 distance = o.distance || 20,
9117                 times = o.times || 3,
9118                 anims = times * 2 + 1,
9119                 speed = Math.round(o.duration/anims),
9120                 ref = (direction === "up" || direction === "down") ? "top" : "left",
9121                 positiveMotion = (direction === "up" || direction === "left"),
9122                 animation = {},
9123                 animation1 = {},
9124                 animation2 = {},
9125                 i,
9126
9127                 // we will need to re-assemble the queue to stack our animations in place
9128                 queue = el.queue(),
9129                 queuelen = queue.length;
9130
9131         $.effects.save( el, props );
9132         el.show();
9133         $.effects.createWrapper( el );
9134
9135         // Animation
9136         animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
9137         animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
9138         animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
9139
9140         // Animate
9141         el.animate( animation, speed, o.easing );
9142
9143         // Shakes
9144         for ( i = 1; i < times; i++ ) {
9145                 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
9146         }
9147         el
9148                 .animate( animation1, speed, o.easing )
9149                 .animate( animation, speed / 2, o.easing )
9150                 .queue(function() {
9151                         if ( mode === "hide" ) {
9152                                 el.hide();
9153                         }
9154                         $.effects.restore( el, props );
9155                         $.effects.removeWrapper( el );
9156                         done();
9157                 });
9158
9159         // inject all the animations we just queued to be first in line (after "inprogress")
9160         if ( queuelen > 1) {
9161                 queue.splice.apply( queue,
9162                         [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
9163         }
9164         el.dequeue();
9165
9166 };
9167
9168 })(jQuery);
9169 (function( $, undefined ) {
9170
9171 $.effects.effect.slide = function( o, done ) {
9172
9173         // Create element
9174         var el = $( this ),
9175                 props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
9176                 mode = $.effects.setMode( el, o.mode || "show" ),
9177                 show = mode === "show",
9178                 direction = o.direction || "left",
9179                 ref = (direction === "up" || direction === "down") ? "top" : "left",
9180                 positiveMotion = (direction === "up" || direction === "left"),
9181                 distance,
9182                 animation = {};
9183
9184         // Adjust
9185         $.effects.save( el, props );
9186         el.show();
9187         distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
9188
9189         $.effects.createWrapper( el ).css({
9190                 overflow: "hidden"
9191         });
9192
9193         if ( show ) {
9194                 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
9195         }
9196
9197         // Animation
9198         animation[ ref ] = ( show ?
9199                 ( positiveMotion ? "+=" : "-=") :
9200                 ( positiveMotion ? "-=" : "+=")) +
9201                 distance;
9202
9203         // Animate
9204         el.animate( animation, {
9205                 queue: false,
9206                 duration: o.duration,
9207                 easing: o.easing,
9208                 complete: function() {
9209                         if ( mode === "hide" ) {
9210                                 el.hide();
9211                         }
9212                         $.effects.restore( el, props );
9213                         $.effects.removeWrapper( el );
9214                         done();
9215                 }
9216         });
9217 };
9218
9219 })(jQuery);
9220 (function( $, undefined ) {
9221
9222 $.effects.effect.transfer = function( o, done ) {
9223         var elem = $( this ),
9224                 target = $( o.to ),
9225                 targetFixed = target.css( "position" ) === "fixed",
9226                 body = $("body"),
9227                 fixTop = targetFixed ? body.scrollTop() : 0,
9228                 fixLeft = targetFixed ? body.scrollLeft() : 0,
9229                 endPosition = target.offset(),
9230                 animation = {
9231                         top: endPosition.top - fixTop ,
9232                         left: endPosition.left - fixLeft ,
9233                         height: target.innerHeight(),
9234                         width: target.innerWidth()
9235                 },
9236                 startPosition = elem.offset(),
9237                 transfer = $( '<div class="ui-effects-transfer"></div>' )
9238                         .appendTo( document.body )
9239                         .addClass( o.className )
9240                         .css({
9241                                 top: startPosition.top - fixTop ,
9242                                 left: startPosition.left - fixLeft ,
9243                                 height: elem.innerHeight(),
9244                                 width: elem.innerWidth(),
9245                                 position: targetFixed ? "fixed" : "absolute"
9246                         })
9247                         .animate( animation, o.duration, o.easing, function() {
9248                                 transfer.remove();
9249                                 done();
9250                         });
9251 };
9252
9253 })(jQuery);
9254 (function( $, undefined ) {
9255
9256 var mouseHandled = false;
9257
9258 $.widget( "ui.menu", {
9259         version: "1.9.2",
9260         defaultElement: "<ul>",
9261         delay: 300,
9262         options: {
9263                 icons: {
9264                         submenu: "ui-icon-carat-1-e"
9265                 },
9266                 menus: "ul",
9267                 position: {
9268                         my: "left top",
9269                         at: "right top"
9270                 },
9271                 role: "menu",
9272
9273                 // callbacks
9274                 blur: null,
9275                 focus: null,
9276                 select: null
9277         },
9278
9279         _create: function() {
9280                 this.activeMenu = this.element;
9281                 this.element
9282                         .uniqueId()
9283                         .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9284                         .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
9285                         .attr({
9286                                 role: this.options.role,
9287                                 tabIndex: 0
9288                         })
9289                         // need to catch all clicks on disabled menu
9290                         // not possible through _on
9291                         .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
9292                                 if ( this.options.disabled ) {
9293                                         event.preventDefault();
9294                                 }
9295                         }, this ));
9296
9297                 if ( this.options.disabled ) {
9298                         this.element
9299                                 .addClass( "ui-state-disabled" )
9300                                 .attr( "aria-disabled", "true" );
9301                 }
9302
9303                 this._on({
9304                         // Prevent focus from sticking to links inside menu after clicking
9305                         // them (focus should always stay on UL during navigation).
9306                         "mousedown .ui-menu-item > a": function( event ) {
9307                                 event.preventDefault();
9308                         },
9309                         "click .ui-state-disabled > a": function( event ) {
9310                                 event.preventDefault();
9311                         },
9312                         "click .ui-menu-item:has(a)": function( event ) {
9313                                 var target = $( event.target ).closest( ".ui-menu-item" );
9314                                 if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
9315                                         mouseHandled = true;
9316
9317                                         this.select( event );
9318                                         // Open submenu on click
9319                                         if ( target.has( ".ui-menu" ).length ) {
9320                                                 this.expand( event );
9321                                         } else if ( !this.element.is( ":focus" ) ) {
9322                                                 // Redirect focus to the menu
9323                                                 this.element.trigger( "focus", [ true ] );
9324
9325                                                 // If the active item is on the top level, let it stay active.
9326                                                 // Otherwise, blur the active item since it is no longer visible.
9327                                                 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
9328                                                         clearTimeout( this.timer );
9329                                                 }
9330                                         }
9331                                 }
9332                         },
9333                         "mouseenter .ui-menu-item": function( event ) {
9334                                 var target = $( event.currentTarget );
9335                                 // Remove ui-state-active class from siblings of the newly focused menu item
9336                                 // to avoid a jump caused by adjacent elements both having a class with a border
9337                                 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
9338                                 this.focus( event, target );
9339                         },
9340                         mouseleave: "collapseAll",
9341                         "mouseleave .ui-menu": "collapseAll",
9342                         focus: function( event, keepActiveItem ) {
9343                                 // If there's already an active item, keep it active
9344                                 // If not, activate the first item
9345                                 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
9346
9347                                 if ( !keepActiveItem ) {
9348                                         this.focus( event, item );
9349                                 }
9350                         },
9351                         blur: function( event ) {
9352                                 this._delay(function() {
9353                                         if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
9354                                                 this.collapseAll( event );
9355                                         }
9356                                 });
9357                         },
9358                         keydown: "_keydown"
9359                 });
9360
9361                 this.refresh();
9362
9363                 // Clicks outside of a menu collapse any open menus
9364                 this._on( this.document, {
9365                         click: function( event ) {
9366                                 if ( !$( event.target ).closest( ".ui-menu" ).length ) {
9367                                         this.collapseAll( event );
9368                                 }
9369
9370                                 // Reset the mouseHandled flag
9371                                 mouseHandled = false;
9372                         }
9373                 });
9374         },
9375
9376         _destroy: function() {
9377                 // Destroy (sub)menus
9378                 this.element
9379                         .removeAttr( "aria-activedescendant" )
9380                         .find( ".ui-menu" ).andSelf()
9381                                 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
9382                                 .removeAttr( "role" )
9383                                 .removeAttr( "tabIndex" )
9384                                 .removeAttr( "aria-labelledby" )
9385                                 .removeAttr( "aria-expanded" )
9386                                 .removeAttr( "aria-hidden" )
9387                                 .removeAttr( "aria-disabled" )
9388                                 .removeUniqueId()
9389                                 .show();
9390
9391                 // Destroy menu items
9392                 this.element.find( ".ui-menu-item" )
9393                         .removeClass( "ui-menu-item" )
9394                         .removeAttr( "role" )
9395                         .removeAttr( "aria-disabled" )
9396                         .children( "a" )
9397                                 .removeUniqueId()
9398                                 .removeClass( "ui-corner-all ui-state-hover" )
9399                                 .removeAttr( "tabIndex" )
9400                                 .removeAttr( "role" )
9401                                 .removeAttr( "aria-haspopup" )
9402                                 .children().each( function() {
9403                                         var elem = $( this );
9404                                         if ( elem.data( "ui-menu-submenu-carat" ) ) {
9405                                                 elem.remove();
9406                                         }
9407                                 });
9408
9409                 // Destroy menu dividers
9410                 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
9411         },
9412
9413         _keydown: function( event ) {
9414                 var match, prev, character, skip, regex,
9415                         preventDefault = true;
9416
9417                 function escape( value ) {
9418                         return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
9419                 }
9420
9421                 switch ( event.keyCode ) {
9422                 case $.ui.keyCode.PAGE_UP:
9423                         this.previousPage( event );
9424                         break;
9425                 case $.ui.keyCode.PAGE_DOWN:
9426                         this.nextPage( event );
9427                         break;
9428                 case $.ui.keyCode.HOME:
9429                         this._move( "first", "first", event );
9430                         break;
9431                 case $.ui.keyCode.END:
9432                         this._move( "last", "last", event );
9433                         break;
9434                 case $.ui.keyCode.UP:
9435                         this.previous( event );
9436                         break;
9437                 case $.ui.keyCode.DOWN:
9438                         this.next( event );
9439                         break;
9440                 case $.ui.keyCode.LEFT:
9441                         this.collapse( event );
9442                         break;
9443                 case $.ui.keyCode.RIGHT:
9444                         if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
9445                                 this.expand( event );
9446                         }
9447                         break;
9448                 case $.ui.keyCode.ENTER:
9449                 case $.ui.keyCode.SPACE:
9450                         this._activate( event );
9451                         break;
9452                 case $.ui.keyCode.ESCAPE:
9453                         this.collapse( event );
9454                         break;
9455                 default:
9456                         preventDefault = false;
9457                         prev = this.previousFilter || "";
9458                         character = String.fromCharCode( event.keyCode );
9459                         skip = false;
9460
9461                         clearTimeout( this.filterTimer );
9462
9463                         if ( character === prev ) {
9464                                 skip = true;
9465                         } else {
9466                                 character = prev + character;
9467                         }
9468
9469                         regex = new RegExp( "^" + escape( character ), "i" );
9470                         match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9471                                 return regex.test( $( this ).children( "a" ).text() );
9472                         });
9473                         match = skip && match.index( this.active.next() ) !== -1 ?
9474                                 this.active.nextAll( ".ui-menu-item" ) :
9475                                 match;
9476
9477                         // If no matches on the current filter, reset to the last character pressed
9478                         // to move down the menu to the first item that starts with that character
9479                         if ( !match.length ) {
9480                                 character = String.fromCharCode( event.keyCode );
9481                                 regex = new RegExp( "^" + escape( character ), "i" );
9482                                 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9483                                         return regex.test( $( this ).children( "a" ).text() );
9484                                 });
9485                         }
9486
9487                         if ( match.length ) {
9488                                 this.focus( event, match );
9489                                 if ( match.length > 1 ) {
9490                                         this.previousFilter = character;
9491                                         this.filterTimer = this._delay(function() {
9492                                                 delete this.previousFilter;
9493                                         }, 1000 );
9494                                 } else {
9495                                         delete this.previousFilter;
9496                                 }
9497                         } else {
9498                                 delete this.previousFilter;
9499                         }
9500                 }
9501
9502                 if ( preventDefault ) {
9503                         event.preventDefault();
9504                 }
9505         },
9506
9507         _activate: function( event ) {
9508                 if ( !this.active.is( ".ui-state-disabled" ) ) {
9509                         if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
9510                                 this.expand( event );
9511                         } else {
9512                                 this.select( event );
9513                         }
9514                 }
9515         },
9516
9517         refresh: function() {
9518                 var menus,
9519                         icon = this.options.icons.submenu,
9520                         submenus = this.element.find( this.options.menus );
9521
9522                 // Initialize nested menus
9523                 submenus.filter( ":not(.ui-menu)" )
9524                         .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9525                         .hide()
9526                         .attr({
9527                                 role: this.options.role,
9528                                 "aria-hidden": "true",
9529                                 "aria-expanded": "false"
9530                         })
9531                         .each(function() {
9532                                 var menu = $( this ),
9533                                         item = menu.prev( "a" ),
9534                                         submenuCarat = $( "<span>" )
9535                                                 .addClass( "ui-menu-icon ui-icon " + icon )
9536                                                 .data( "ui-menu-submenu-carat", true );
9537
9538                                 item
9539                                         .attr( "aria-haspopup", "true" )
9540                                         .prepend( submenuCarat );
9541                                 menu.attr( "aria-labelledby", item.attr( "id" ) );
9542                         });
9543
9544                 menus = submenus.add( this.element );
9545
9546                 // Don't refresh list items that are already adapted
9547                 menus.children( ":not(.ui-menu-item):has(a)" )
9548                         .addClass( "ui-menu-item" )
9549                         .attr( "role", "presentation" )
9550                         .children( "a" )
9551                                 .uniqueId()
9552                                 .addClass( "ui-corner-all" )
9553                                 .attr({
9554                                         tabIndex: -1,
9555                                         role: this._itemRole()
9556                                 });
9557
9558                 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
9559                 menus.children( ":not(.ui-menu-item)" ).each(function() {
9560                         var item = $( this );
9561                         // hyphen, em dash, en dash
9562                         if ( !/[^\-—–\s]/.test( item.text() ) ) {
9563                                 item.addClass( "ui-widget-content ui-menu-divider" );
9564                         }
9565                 });
9566
9567                 // Add aria-disabled attribute to any disabled menu item
9568                 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
9569
9570                 // If the active item has been removed, blur the menu
9571                 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
9572                         this.blur();
9573                 }
9574         },
9575
9576         _itemRole: function() {
9577                 return {
9578                         menu: "menuitem",
9579                         listbox: "option"
9580                 }[ this.options.role ];
9581         },
9582
9583         focus: function( event, item ) {
9584                 var nested, focused;
9585                 this.blur( event, event && event.type === "focus" );
9586
9587                 this._scrollIntoView( item );
9588
9589                 this.active = item.first();
9590                 focused = this.active.children( "a" ).addClass( "ui-state-focus" );
9591                 // Only update aria-activedescendant if there's a role
9592                 // otherwise we assume focus is managed elsewhere
9593                 if ( this.options.role ) {
9594                         this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
9595                 }
9596
9597                 // Highlight active parent menu item, if any
9598                 this.active
9599                         .parent()
9600                         .closest( ".ui-menu-item" )
9601                         .children( "a:first" )
9602                         .addClass( "ui-state-active" );
9603
9604                 if ( event && event.type === "keydown" ) {
9605                         this._close();
9606                 } else {
9607                         this.timer = this._delay(function() {
9608                                 this._close();
9609                         }, this.delay );
9610                 }
9611
9612                 nested = item.children( ".ui-menu" );
9613                 if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
9614                         this._startOpening(nested);
9615                 }
9616                 this.activeMenu = item.parent();
9617
9618                 this._trigger( "focus", event, { item: item } );
9619         },
9620
9621         _scrollIntoView: function( item ) {
9622                 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
9623                 if ( this._hasScroll() ) {
9624                         borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
9625                         paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
9626                         offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
9627                         scroll = this.activeMenu.scrollTop();
9628                         elementHeight = this.activeMenu.height();
9629                         itemHeight = item.height();
9630
9631                         if ( offset < 0 ) {
9632                                 this.activeMenu.scrollTop( scroll + offset );
9633                         } else if ( offset + itemHeight > elementHeight ) {
9634                                 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
9635                         }
9636                 }
9637         },
9638
9639         blur: function( event, fromFocus ) {
9640                 if ( !fromFocus ) {
9641                         clearTimeout( this.timer );
9642                 }
9643
9644                 if ( !this.active ) {
9645                         return;
9646                 }
9647
9648                 this.active.children( "a" ).removeClass( "ui-state-focus" );
9649                 this.active = null;
9650
9651                 this._trigger( "blur", event, { item: this.active } );
9652         },
9653
9654         _startOpening: function( submenu ) {
9655                 clearTimeout( this.timer );
9656
9657                 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
9658                 // shift in the submenu position when mousing over the carat icon
9659                 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
9660                         return;
9661                 }
9662
9663                 this.timer = this._delay(function() {
9664                         this._close();
9665                         this._open( submenu );
9666                 }, this.delay );
9667         },
9668
9669         _open: function( submenu ) {
9670                 var position = $.extend({
9671                         of: this.active
9672                 }, this.options.position );
9673
9674                 clearTimeout( this.timer );
9675                 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
9676                         .hide()
9677                         .attr( "aria-hidden", "true" );
9678
9679                 submenu
9680                         .show()
9681                         .removeAttr( "aria-hidden" )
9682                         .attr( "aria-expanded", "true" )
9683                         .position( position );
9684         },
9685
9686         collapseAll: function( event, all ) {
9687                 clearTimeout( this.timer );
9688                 this.timer = this._delay(function() {
9689                         // If we were passed an event, look for the submenu that contains the event
9690                         var currentMenu = all ? this.element :
9691                                 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
9692
9693                         // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
9694                         if ( !currentMenu.length ) {
9695                                 currentMenu = this.element;
9696                         }
9697
9698                         this._close( currentMenu );
9699
9700                         this.blur( event );
9701                         this.activeMenu = currentMenu;
9702                 }, this.delay );
9703         },
9704
9705         // With no arguments, closes the currently active menu - if nothing is active
9706         // it closes all menus.  If passed an argument, it will search for menus BELOW
9707         _close: function( startMenu ) {
9708                 if ( !startMenu ) {
9709                         startMenu = this.active ? this.active.parent() : this.element;
9710                 }
9711
9712                 startMenu
9713                         .find( ".ui-menu" )
9714                                 .hide()
9715                                 .attr( "aria-hidden", "true" )
9716                                 .attr( "aria-expanded", "false" )
9717                         .end()
9718                         .find( "a.ui-state-active" )
9719                                 .removeClass( "ui-state-active" );
9720         },
9721
9722         collapse: function( event ) {
9723                 var newItem = this.active &&
9724                         this.active.parent().closest( ".ui-menu-item", this.element );
9725                 if ( newItem && newItem.length ) {
9726                         this._close();
9727                         this.focus( event, newItem );
9728                 }
9729         },
9730
9731         expand: function( event ) {
9732                 var newItem = this.active &&
9733                         this.active
9734                                 .children( ".ui-menu " )
9735                                 .children( ".ui-menu-item" )
9736                                 .first();
9737
9738                 if ( newItem && newItem.length ) {
9739                         this._open( newItem.parent() );
9740
9741                         // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
9742                         this._delay(function() {
9743                                 this.focus( event, newItem );
9744                         });
9745                 }
9746         },
9747
9748         next: function( event ) {
9749                 this._move( "next", "first", event );
9750         },
9751
9752         previous: function( event ) {
9753                 this._move( "prev", "last", event );
9754         },
9755
9756         isFirstItem: function() {
9757                 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
9758         },
9759
9760         isLastItem: function() {
9761                 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
9762         },
9763
9764         _move: function( direction, filter, event ) {
9765                 var next;
9766                 if ( this.active ) {
9767                         if ( direction === "first" || direction === "last" ) {
9768                                 next = this.active
9769                                         [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
9770                                         .eq( -1 );
9771                         } else {
9772                                 next = this.active
9773                                         [ direction + "All" ]( ".ui-menu-item" )
9774                                         .eq( 0 );
9775                         }
9776                 }
9777                 if ( !next || !next.length || !this.active ) {
9778                         next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
9779                 }
9780
9781                 this.focus( event, next );
9782         },
9783
9784         nextPage: function( event ) {
9785                 var item, base, height;
9786
9787                 if ( !this.active ) {
9788                         this.next( event );
9789                         return;
9790                 }
9791                 if ( this.isLastItem() ) {
9792                         return;
9793                 }
9794                 if ( this._hasScroll() ) {
9795                         base = this.active.offset().top;
9796                         height = this.element.height();
9797                         this.active.nextAll( ".ui-menu-item" ).each(function() {
9798                                 item = $( this );
9799                                 return item.offset().top - base - height < 0;
9800                         });
9801
9802                         this.focus( event, item );
9803                 } else {
9804                         this.focus( event, this.activeMenu.children( ".ui-menu-item" )
9805                                 [ !this.active ? "first" : "last" ]() );
9806                 }
9807         },
9808
9809         previousPage: function( event ) {
9810                 var item, base, height;
9811                 if ( !this.active ) {
9812                         this.next( event );
9813                         return;
9814                 }
9815                 if ( this.isFirstItem() ) {
9816                         return;
9817                 }
9818                 if ( this._hasScroll() ) {
9819                         base = this.active.offset().top;
9820                         height = this.element.height();
9821                         this.active.prevAll( ".ui-menu-item" ).each(function() {
9822                                 item = $( this );
9823                                 return item.offset().top - base + height > 0;
9824                         });
9825
9826                         this.focus( event, item );
9827                 } else {
9828                         this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
9829                 }
9830         },
9831
9832         _hasScroll: function() {
9833                 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
9834         },
9835
9836         select: function( event ) {
9837                 // TODO: It should never be possible to not have an active item at this
9838                 // point, but the tests don't trigger mouseenter before click.
9839                 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
9840                 var ui = { item: this.active };
9841                 if ( !this.active.has( ".ui-menu" ).length ) {
9842                         this.collapseAll( event, true );
9843                 }
9844                 this._trigger( "select", event, ui );
9845         }
9846 });
9847
9848 }( jQuery ));
9849 (function( $, undefined ) {
9850
9851 $.widget( "ui.progressbar", {
9852         version: "1.9.2",
9853         options: {
9854                 value: 0,
9855                 max: 100
9856         },
9857
9858         min: 0,
9859
9860         _create: function() {
9861                 this.element
9862                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9863                         .attr({
9864                                 role: "progressbar",
9865                                 "aria-valuemin": this.min,
9866                                 "aria-valuemax": this.options.max,
9867                                 "aria-valuenow": this._value()
9868                         });
9869
9870                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
9871                         .appendTo( this.element );
9872
9873                 this.oldValue = this._value();
9874                 this._refreshValue();
9875         },
9876
9877         _destroy: function() {
9878                 this.element
9879                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9880                         .removeAttr( "role" )
9881                         .removeAttr( "aria-valuemin" )
9882                         .removeAttr( "aria-valuemax" )
9883                         .removeAttr( "aria-valuenow" );
9884
9885                 this.valueDiv.remove();
9886         },
9887
9888         value: function( newValue ) {
9889                 if ( newValue === undefined ) {
9890                         return this._value();
9891                 }
9892
9893                 this._setOption( "value", newValue );
9894                 return this;
9895         },
9896
9897         _setOption: function( key, value ) {
9898                 if ( key === "value" ) {
9899                         this.options.value = value;
9900                         this._refreshValue();
9901                         if ( this._value() === this.options.max ) {
9902                                 this._trigger( "complete" );
9903                         }
9904                 }
9905
9906                 this._super( key, value );
9907         },
9908
9909         _value: function() {
9910                 var val = this.options.value;
9911                 // normalize invalid value
9912                 if ( typeof val !== "number" ) {
9913                         val = 0;
9914                 }
9915                 return Math.min( this.options.max, Math.max( this.min, val ) );
9916         },
9917
9918         _percentage: function() {
9919                 return 100 * this._value() / this.options.max;
9920         },
9921
9922         _refreshValue: function() {
9923                 var value = this.value(),
9924                         percentage = this._percentage();
9925
9926                 if ( this.oldValue !== value ) {
9927                         this.oldValue = value;
9928                         this._trigger( "change" );
9929                 }
9930
9931                 this.valueDiv
9932                         .toggle( value > this.min )
9933                         .toggleClass( "ui-corner-right", value === this.options.max )
9934                         .width( percentage.toFixed(0) + "%" );
9935                 this.element.attr( "aria-valuenow", value );
9936         }
9937 });
9938
9939 })( jQuery );
9940 (function( $, undefined ) {
9941
9942 $.widget("ui.resizable", $.ui.mouse, {
9943         version: "1.9.2",
9944         widgetEventPrefix: "resize",
9945         options: {
9946                 alsoResize: false,
9947                 animate: false,
9948                 animateDuration: "slow",
9949                 animateEasing: "swing",
9950                 aspectRatio: false,
9951                 autoHide: false,
9952                 containment: false,
9953                 ghost: false,
9954                 grid: false,
9955                 handles: "e,s,se",
9956                 helper: false,
9957                 maxHeight: null,
9958                 maxWidth: null,
9959                 minHeight: 10,
9960                 minWidth: 10,
9961                 zIndex: 1000
9962         },
9963         _create: function() {
9964
9965                 var that = this, o = this.options;
9966                 this.element.addClass("ui-resizable");
9967
9968                 $.extend(this, {
9969                         _aspectRatio: !!(o.aspectRatio),
9970                         aspectRatio: o.aspectRatio,
9971                         originalElement: this.element,
9972                         _proportionallyResizeElements: [],
9973                         _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
9974                 });
9975
9976                 //Wrap the element if it cannot hold child nodes
9977                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
9978
9979                         //Create a wrapper element and set the wrapper to the new current internal element
9980                         this.element.wrap(
9981                                 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
9982                                         position: this.element.css('position'),
9983                                         width: this.element.outerWidth(),
9984                                         height: this.element.outerHeight(),
9985                                         top: this.element.css('top'),
9986                                         left: this.element.css('left')
9987                                 })
9988                         );
9989
9990                         //Overwrite the original this.element
9991                         this.element = this.element.parent().data(
9992                                 "resizable", this.element.data('resizable')
9993                         );
9994
9995                         this.elementIsWrapper = true;
9996
9997                         //Move margins to the wrapper
9998                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
9999                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
10000
10001                         //Prevent Safari textarea resize
10002                         this.originalResizeStyle = this.originalElement.css('resize');
10003                         this.originalElement.css('resize', 'none');
10004
10005                         //Push the actual element to our proportionallyResize internal array
10006                         this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
10007
10008                         // avoid IE jump (hard set the margin)
10009                         this.originalElement.css({ margin: this.originalElement.css('margin') });
10010
10011                         // fix handlers offset
10012                         this._proportionallyResize();
10013
10014                 }
10015
10016                 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' });
10017                 if(this.handles.constructor == String) {
10018
10019                         if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
10020                         var n = this.handles.split(","); this.handles = {};
10021
10022                         for(var i = 0; i < n.length; i++) {
10023
10024                                 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
10025                                 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
10026
10027                                 // Apply zIndex to all handles - see #7960
10028                                 axis.css({ zIndex: o.zIndex });
10029
10030                                 //TODO : What's going on here?
10031                                 if ('se' == handle) {
10032                                         axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
10033                                 };
10034
10035                                 //Insert into internal handles object and append to element
10036                                 this.handles[handle] = '.ui-resizable-'+handle;
10037                                 this.element.append(axis);
10038                         }
10039
10040                 }
10041
10042                 this._renderAxis = function(target) {
10043
10044                         target = target || this.element;
10045
10046                         for(var i in this.handles) {
10047
10048                                 if(this.handles[i].constructor == String)
10049                                         this.handles[i] = $(this.handles[i], this.element).show();
10050
10051                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
10052                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
10053
10054                                         var axis = $(this.handles[i], this.element), padWrapper = 0;
10055
10056                                         //Checking the correct pad and border
10057                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
10058
10059                                         //The padding type i have to apply...
10060                                         var padPos = [ 'padding',
10061                                                 /ne|nw|n/.test(i) ? 'Top' :
10062                                                 /se|sw|s/.test(i) ? 'Bottom' :
10063                                                 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
10064
10065                                         target.css(padPos, padWrapper);
10066
10067                                         this._proportionallyResize();
10068
10069                                 }
10070
10071                                 //TODO: What's that good for? There's not anything to be executed left
10072                                 if(!$(this.handles[i]).length)
10073                                         continue;
10074
10075                         }
10076                 };
10077
10078                 //TODO: make renderAxis a prototype function
10079                 this._renderAxis(this.element);
10080
10081                 this._handles = $('.ui-resizable-handle', this.element)
10082                         .disableSelection();
10083
10084                 //Matching axis name
10085                 this._handles.mouseover(function() {
10086                         if (!that.resizing) {
10087                                 if (this.className)
10088                                         var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
10089                                 //Axis, default = se
10090                                 that.axis = axis && axis[1] ? axis[1] : 'se';
10091                         }
10092                 });
10093
10094                 //If we want to auto hide the elements
10095                 if (o.autoHide) {
10096                         this._handles.hide();
10097                         $(this.element)
10098                                 .addClass("ui-resizable-autohide")
10099                                 .mouseenter(function() {
10100                                         if (o.disabled) return;
10101                                         $(this).removeClass("ui-resizable-autohide");
10102                                         that._handles.show();
10103                                 })
10104                                 .mouseleave(function(){
10105                                         if (o.disabled) return;
10106                                         if (!that.resizing) {
10107                                                 $(this).addClass("ui-resizable-autohide");
10108                                                 that._handles.hide();
10109                                         }
10110                                 });
10111                 }
10112
10113                 //Initialize the mouse interaction
10114                 this._mouseInit();
10115
10116         },
10117
10118         _destroy: function() {
10119
10120                 this._mouseDestroy();
10121
10122                 var _destroy = function(exp) {
10123                         $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
10124                                 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
10125                 };
10126
10127                 //TODO: Unwrap at same DOM position
10128                 if (this.elementIsWrapper) {
10129                         _destroy(this.element);
10130                         var wrapper = this.element;
10131                         this.originalElement.css({
10132                                 position: wrapper.css('position'),
10133                                 width: wrapper.outerWidth(),
10134                                 height: wrapper.outerHeight(),
10135                                 top: wrapper.css('top'),
10136                                 left: wrapper.css('left')
10137                         }).insertAfter( wrapper );
10138                         wrapper.remove();
10139                 }
10140
10141                 this.originalElement.css('resize', this.originalResizeStyle);
10142                 _destroy(this.originalElement);
10143
10144                 return this;
10145         },
10146
10147         _mouseCapture: function(event) {
10148                 var handle = false;
10149                 for (var i in this.handles) {
10150                         if ($(this.handles[i])[0] == event.target) {
10151                                 handle = true;
10152                         }
10153                 }
10154
10155                 return !this.options.disabled && handle;
10156         },
10157
10158         _mouseStart: function(event) {
10159
10160                 var o = this.options, iniPos = this.element.position(), el = this.element;
10161
10162                 this.resizing = true;
10163                 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
10164
10165                 // bugfix for http://dev.jquery.com/ticket/1749
10166                 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
10167                         el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
10168                 }
10169
10170                 this._renderProxy();
10171
10172                 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
10173
10174                 if (o.containment) {
10175                         curleft += $(o.containment).scrollLeft() || 0;
10176                         curtop += $(o.containment).scrollTop() || 0;
10177                 }
10178
10179                 //Store needed variables
10180                 this.offset = this.helper.offset();
10181                 this.position = { left: curleft, top: curtop };
10182                 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
10183                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
10184                 this.originalPosition = { left: curleft, top: curtop };
10185                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
10186                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
10187
10188                 //Aspect Ratio
10189                 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
10190
10191                 var cursor = $('.ui-resizable-' + this.axis).css('cursor');
10192                 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
10193
10194                 el.addClass("ui-resizable-resizing");
10195                 this._propagate("start", event);
10196                 return true;
10197         },
10198
10199         _mouseDrag: function(event) {
10200
10201                 //Increase performance, avoid regex
10202                 var el = this.helper, o = this.options, props = {},
10203                         that = this, smp = this.originalMousePosition, a = this.axis;
10204
10205                 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
10206                 var trigger = this._change[a];
10207                 if (!trigger) return false;
10208
10209                 // Calculate the attrs that will be change
10210                 var data = trigger.apply(this, [event, dx, dy]);
10211
10212                 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
10213                 this._updateVirtualBoundaries(event.shiftKey);
10214                 if (this._aspectRatio || event.shiftKey)
10215                         data = this._updateRatio(data, event);
10216
10217                 data = this._respectSize(data, event);
10218
10219                 // plugins callbacks need to be called first
10220                 this._propagate("resize", event);
10221
10222                 el.css({
10223                         top: this.position.top + "px", left: this.position.left + "px",
10224                         width: this.size.width + "px", height: this.size.height + "px"
10225                 });
10226
10227                 if (!this._helper && this._proportionallyResizeElements.length)
10228                         this._proportionallyResize();
10229
10230                 this._updateCache(data);
10231
10232                 // calling the user callback at the end
10233                 this._trigger('resize', event, this.ui());
10234
10235                 return false;
10236         },
10237
10238         _mouseStop: function(event) {
10239
10240                 this.resizing = false;
10241                 var o = this.options, that = this;
10242
10243                 if(this._helper) {
10244                         var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
10245                                 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
10246                                 soffsetw = ista ? 0 : that.sizeDiff.width;
10247
10248                         var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
10249                                 left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
10250                                 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
10251
10252                         if (!o.animate)
10253                                 this.element.css($.extend(s, { top: top, left: left }));
10254
10255                         that.helper.height(that.size.height);
10256                         that.helper.width(that.size.width);
10257
10258                         if (this._helper && !o.animate) this._proportionallyResize();
10259                 }
10260
10261                 $('body').css('cursor', 'auto');
10262
10263                 this.element.removeClass("ui-resizable-resizing");
10264
10265                 this._propagate("stop", event);
10266
10267                 if (this._helper) this.helper.remove();
10268                 return false;
10269
10270         },
10271
10272         _updateVirtualBoundaries: function(forceAspectRatio) {
10273                 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
10274
10275                 b = {
10276                         minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
10277                         maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
10278                         minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
10279                         maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
10280                 };
10281
10282                 if(this._aspectRatio || forceAspectRatio) {
10283                         // We want to create an enclosing box whose aspect ration is the requested one
10284                         // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
10285                         pMinWidth = b.minHeight * this.aspectRatio;
10286                         pMinHeight = b.minWidth / this.aspectRatio;
10287                         pMaxWidth = b.maxHeight * this.aspectRatio;
10288                         pMaxHeight = b.maxWidth / this.aspectRatio;
10289
10290                         if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
10291                         if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
10292                         if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
10293                         if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
10294                 }
10295                 this._vBoundaries = b;
10296         },
10297
10298         _updateCache: function(data) {
10299                 var o = this.options;
10300                 this.offset = this.helper.offset();
10301                 if (isNumber(data.left)) this.position.left = data.left;
10302                 if (isNumber(data.top)) this.position.top = data.top;
10303                 if (isNumber(data.height)) this.size.height = data.height;
10304                 if (isNumber(data.width)) this.size.width = data.width;
10305         },
10306
10307         _updateRatio: function(data, event) {
10308
10309                 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
10310
10311                 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
10312                 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
10313
10314                 if (a == 'sw') {
10315                         data.left = cpos.left + (csize.width - data.width);
10316                         data.top = null;
10317                 }
10318                 if (a == 'nw') {
10319                         data.top = cpos.top + (csize.height - data.height);
10320                         data.left = cpos.left + (csize.width - data.width);
10321                 }
10322
10323                 return data;
10324         },
10325
10326         _respectSize: function(data, event) {
10327
10328                 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
10329                                 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
10330                                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
10331
10332                 if (isminw) data.width = o.minWidth;
10333                 if (isminh) data.height = o.minHeight;
10334                 if (ismaxw) data.width = o.maxWidth;
10335                 if (ismaxh) data.height = o.maxHeight;
10336
10337                 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
10338                 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
10339
10340                 if (isminw && cw) data.left = dw - o.minWidth;
10341                 if (ismaxw && cw) data.left = dw - o.maxWidth;
10342                 if (isminh && ch)       data.top = dh - o.minHeight;
10343                 if (ismaxh && ch)       data.top = dh - o.maxHeight;
10344
10345                 // fixing jump error on top/left - bug #2330
10346                 var isNotwh = !data.width && !data.height;
10347                 if (isNotwh && !data.left && data.top) data.top = null;
10348                 else if (isNotwh && !data.top && data.left) data.left = null;
10349
10350                 return data;
10351         },
10352
10353         _proportionallyResize: function() {
10354
10355                 var o = this.options;
10356                 if (!this._proportionallyResizeElements.length) return;
10357                 var element = this.helper || this.element;
10358
10359                 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
10360
10361                         var prel = this._proportionallyResizeElements[i];
10362
10363                         if (!this.borderDif) {
10364                                 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
10365                                         p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
10366
10367                                 this.borderDif = $.map(b, function(v, i) {
10368                                         var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
10369                                         return border + padding;
10370                                 });
10371                         }
10372
10373                         prel.css({
10374                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
10375                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
10376                         });
10377
10378                 };
10379
10380         },
10381
10382         _renderProxy: function() {
10383
10384                 var el = this.element, o = this.options;
10385                 this.elementOffset = el.offset();
10386
10387                 if(this._helper) {
10388
10389                         this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
10390
10391                         // fix ie6 offset TODO: This seems broken
10392                         var ie6offset = ($.ui.ie6 ? 1 : 0),
10393                         pxyoffset = ( $.ui.ie6 ? 2 : -1 );
10394
10395                         this.helper.addClass(this._helper).css({
10396                                 width: this.element.outerWidth() + pxyoffset,
10397                                 height: this.element.outerHeight() + pxyoffset,
10398                                 position: 'absolute',
10399                                 left: this.elementOffset.left - ie6offset +'px',
10400                                 top: this.elementOffset.top - ie6offset +'px',
10401                                 zIndex: ++o.zIndex //TODO: Don't modify option
10402                         });
10403
10404                         this.helper
10405                                 .appendTo("body")
10406                                 .disableSelection();
10407
10408                 } else {
10409                         this.helper = this.element;
10410                 }
10411
10412         },
10413
10414         _change: {
10415                 e: function(event, dx, dy) {
10416                         return { width: this.originalSize.width + dx };
10417                 },
10418                 w: function(event, dx, dy) {
10419                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
10420                         return { left: sp.left + dx, width: cs.width - dx };
10421                 },
10422                 n: function(event, dx, dy) {
10423                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
10424                         return { top: sp.top + dy, height: cs.height - dy };
10425                 },
10426                 s: function(event, dx, dy) {
10427                         return { height: this.originalSize.height + dy };
10428                 },
10429                 se: function(event, dx, dy) {
10430                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
10431                 },
10432                 sw: function(event, dx, dy) {
10433                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
10434                 },
10435                 ne: function(event, dx, dy) {
10436                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
10437                 },
10438                 nw: function(event, dx, dy) {
10439                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
10440                 }
10441         },
10442
10443         _propagate: function(n, event) {
10444                 $.ui.plugin.call(this, n, [event, this.ui()]);
10445                 (n != "resize" && this._trigger(n, event, this.ui()));
10446         },
10447
10448         plugins: {},
10449
10450         ui: function() {
10451                 return {
10452                         originalElement: this.originalElement,
10453                         element: this.element,
10454                         helper: this.helper,
10455                         position: this.position,
10456                         size: this.size,
10457                         originalSize: this.originalSize,
10458                         originalPosition: this.originalPosition
10459                 };
10460         }
10461
10462 });
10463
10464 /*
10465  * Resizable Extensions
10466  */
10467
10468 $.ui.plugin.add("resizable", "alsoResize", {
10469
10470         start: function (event, ui) {
10471                 var that = $(this).data("resizable"), o = that.options;
10472
10473                 var _store = function (exp) {
10474                         $(exp).each(function() {
10475                                 var el = $(this);
10476                                 el.data("resizable-alsoresize", {
10477                                         width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
10478                                         left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
10479                                 });
10480                         });
10481                 };
10482
10483                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
10484                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
10485                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
10486                 }else{
10487                         _store(o.alsoResize);
10488                 }
10489         },
10490
10491         resize: function (event, ui) {
10492                 var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
10493
10494                 var delta = {
10495                         height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
10496                         top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
10497                 },
10498
10499                 _alsoResize = function (exp, c) {
10500                         $(exp).each(function() {
10501                                 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
10502                                         css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
10503
10504                                 $.each(css, function (i, prop) {
10505                                         var sum = (start[prop]||0) + (delta[prop]||0);
10506                                         if (sum && sum >= 0)
10507                                                 style[prop] = sum || null;
10508                                 });
10509
10510                                 el.css(style);
10511                         });
10512                 };
10513
10514                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
10515                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
10516                 }else{
10517                         _alsoResize(o.alsoResize);
10518                 }
10519         },
10520
10521         stop: function (event, ui) {
10522                 $(this).removeData("resizable-alsoresize");
10523         }
10524 });
10525
10526 $.ui.plugin.add("resizable", "animate", {
10527
10528         stop: function(event, ui) {
10529                 var that = $(this).data("resizable"), o = that.options;
10530
10531                 var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
10532                                         soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
10533                                                 soffsetw = ista ? 0 : that.sizeDiff.width;
10534
10535                 var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
10536                                         left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
10537                                                 top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
10538
10539                 that.element.animate(
10540                         $.extend(style, top && left ? { top: top, left: left } : {}), {
10541                                 duration: o.animateDuration,
10542                                 easing: o.animateEasing,
10543                                 step: function() {
10544
10545                                         var data = {
10546                                                 width: parseInt(that.element.css('width'), 10),
10547                                                 height: parseInt(that.element.css('height'), 10),
10548                                                 top: parseInt(that.element.css('top'), 10),
10549                                                 left: parseInt(that.element.css('left'), 10)
10550                                         };
10551
10552                                         if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
10553
10554                                         // propagating resize, and updating values for each animation step
10555                                         that._updateCache(data);
10556                                         that._propagate("resize", event);
10557
10558                                 }
10559                         }
10560                 );
10561         }
10562
10563 });
10564
10565 $.ui.plugin.add("resizable", "containment", {
10566
10567         start: function(event, ui) {
10568                 var that = $(this).data("resizable"), o = that.options, el = that.element;
10569                 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
10570                 if (!ce) return;
10571
10572                 that.containerElement = $(ce);
10573
10574                 if (/document/.test(oc) || oc == document) {
10575                         that.containerOffset = { left: 0, top: 0 };
10576                         that.containerPosition = { left: 0, top: 0 };
10577
10578                         that.parentData = {
10579                                 element: $(document), left: 0, top: 0,
10580                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
10581                         };
10582                 }
10583
10584                 // i'm a node, so compute top, left, right, bottom
10585                 else {
10586                         var element = $(ce), p = [];
10587                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
10588
10589                         that.containerOffset = element.offset();
10590                         that.containerPosition = element.position();
10591                         that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
10592
10593                         var co = that.containerOffset, ch = that.containerSize.height,  cw = that.containerSize.width,
10594                                                 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
10595
10596                         that.parentData = {
10597                                 element: ce, left: co.left, top: co.top, width: width, height: height
10598                         };
10599                 }
10600         },
10601
10602         resize: function(event, ui) {
10603                 var that = $(this).data("resizable"), o = that.options,
10604                                 ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
10605                                 pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
10606
10607                 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
10608
10609                 if (cp.left < (that._helper ? co.left : 0)) {
10610                         that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
10611                         if (pRatio) that.size.height = that.size.width / that.aspectRatio;
10612                         that.position.left = o.helper ? co.left : 0;
10613                 }
10614
10615                 if (cp.top < (that._helper ? co.top : 0)) {
10616                         that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
10617                         if (pRatio) that.size.width = that.size.height * that.aspectRatio;
10618                         that.position.top = that._helper ? co.top : 0;
10619                 }
10620
10621                 that.offset.left = that.parentData.left+that.position.left;
10622                 that.offset.top = that.parentData.top+that.position.top;
10623
10624                 var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
10625                                         hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
10626
10627                 var isParent = that.containerElement.get(0) == that.element.parent().get(0),
10628                         isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
10629
10630                 if(isParent && isOffsetRelative) woset -= that.parentData.left;
10631
10632                 if (woset + that.size.width >= that.parentData.width) {
10633                         that.size.width = that.parentData.width - woset;
10634                         if (pRatio) that.size.height = that.size.width / that.aspectRatio;
10635                 }
10636
10637                 if (hoset + that.size.height >= that.parentData.height) {
10638                         that.size.height = that.parentData.height - hoset;
10639                         if (pRatio) that.size.width = that.size.height * that.aspectRatio;
10640                 }
10641         },
10642
10643         stop: function(event, ui){
10644                 var that = $(this).data("resizable"), o = that.options, cp = that.position,
10645                                 co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
10646
10647                 var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
10648
10649                 if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
10650                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
10651
10652                 if (that._helper && !o.animate && (/static/).test(ce.css('position')))
10653                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
10654
10655         }
10656 });
10657
10658 $.ui.plugin.add("resizable", "ghost", {
10659
10660         start: function(event, ui) {
10661
10662                 var that = $(this).data("resizable"), o = that.options, cs = that.size;
10663
10664                 that.ghost = that.originalElement.clone();
10665                 that.ghost
10666                         .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
10667                         .addClass('ui-resizable-ghost')
10668                         .addClass(typeof o.ghost == 'string' ? o.ghost : '');
10669
10670                 that.ghost.appendTo(that.helper);
10671
10672         },
10673
10674         resize: function(event, ui){
10675                 var that = $(this).data("resizable"), o = that.options;
10676                 if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
10677         },
10678
10679         stop: function(event, ui){
10680                 var that = $(this).data("resizable"), o = that.options;
10681                 if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
10682         }
10683
10684 });
10685
10686 $.ui.plugin.add("resizable", "grid", {
10687
10688         resize: function(event, ui) {
10689                 var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
10690                 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
10691                 var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
10692
10693                 if (/^(se|s|e)$/.test(a)) {
10694                         that.size.width = os.width + ox;
10695                         that.size.height = os.height + oy;
10696                 }
10697                 else if (/^(ne)$/.test(a)) {
10698                         that.size.width = os.width + ox;
10699                         that.size.height = os.height + oy;
10700                         that.position.top = op.top - oy;
10701                 }
10702                 else if (/^(sw)$/.test(a)) {
10703                         that.size.width = os.width + ox;
10704                         that.size.height = os.height + oy;
10705                         that.position.left = op.left - ox;
10706                 }
10707                 else {
10708                         that.size.width = os.width + ox;
10709                         that.size.height = os.height + oy;
10710                         that.position.top = op.top - oy;
10711                         that.position.left = op.left - ox;
10712                 }
10713         }
10714
10715 });
10716
10717 var num = function(v) {
10718         return parseInt(v, 10) || 0;
10719 };
10720
10721 var isNumber = function(value) {
10722         return !isNaN(parseInt(value, 10));
10723 };
10724
10725 })(jQuery);
10726 (function( $, undefined ) {
10727
10728 $.widget("ui.selectable", $.ui.mouse, {
10729         version: "1.9.2",
10730         options: {
10731                 appendTo: 'body',
10732                 autoRefresh: true,
10733                 distance: 0,
10734                 filter: '*',
10735                 tolerance: 'touch'
10736         },
10737         _create: function() {
10738                 var that = this;
10739
10740                 this.element.addClass("ui-selectable");
10741
10742                 this.dragged = false;
10743
10744                 // cache selectee children based on filter
10745                 var selectees;
10746                 this.refresh = function() {
10747                         selectees = $(that.options.filter, that.element[0]);
10748                         selectees.addClass("ui-selectee");
10749                         selectees.each(function() {
10750                                 var $this = $(this);
10751                                 var pos = $this.offset();
10752                                 $.data(this, "selectable-item", {
10753                                         element: this,
10754                                         $element: $this,
10755                                         left: pos.left,
10756                                         top: pos.top,
10757                                         right: pos.left + $this.outerWidth(),
10758                                         bottom: pos.top + $this.outerHeight(),
10759                                         startselected: false,
10760                                         selected: $this.hasClass('ui-selected'),
10761                                         selecting: $this.hasClass('ui-selecting'),
10762                                         unselecting: $this.hasClass('ui-unselecting')
10763                                 });
10764                         });
10765                 };
10766                 this.refresh();
10767
10768                 this.selectees = selectees.addClass("ui-selectee");
10769
10770                 this._mouseInit();
10771
10772                 this.helper = $("<div class='ui-selectable-helper'></div>");
10773         },
10774
10775         _destroy: function() {
10776                 this.selectees
10777                         .removeClass("ui-selectee")
10778                         .removeData("selectable-item");
10779                 this.element
10780                         .removeClass("ui-selectable ui-selectable-disabled");
10781                 this._mouseDestroy();
10782         },
10783
10784         _mouseStart: function(event) {
10785                 var that = this;
10786
10787                 this.opos = [event.pageX, event.pageY];
10788
10789                 if (this.options.disabled)
10790                         return;
10791
10792                 var options = this.options;
10793
10794                 this.selectees = $(options.filter, this.element[0]);
10795
10796                 this._trigger("start", event);
10797
10798                 $(options.appendTo).append(this.helper);
10799                 // position helper (lasso)
10800                 this.helper.css({
10801                         "left": event.clientX,
10802                         "top": event.clientY,
10803                         "width": 0,
10804                         "height": 0
10805                 });
10806
10807                 if (options.autoRefresh) {
10808                         this.refresh();
10809                 }
10810
10811                 this.selectees.filter('.ui-selected').each(function() {
10812                         var selectee = $.data(this, "selectable-item");
10813                         selectee.startselected = true;
10814                         if (!event.metaKey && !event.ctrlKey) {
10815                                 selectee.$element.removeClass('ui-selected');
10816                                 selectee.selected = false;
10817                                 selectee.$element.addClass('ui-unselecting');
10818                                 selectee.unselecting = true;
10819                                 // selectable UNSELECTING callback
10820                                 that._trigger("unselecting", event, {
10821                                         unselecting: selectee.element
10822                                 });
10823                         }
10824                 });
10825
10826                 $(event.target).parents().andSelf().each(function() {
10827                         var selectee = $.data(this, "selectable-item");
10828                         if (selectee) {
10829                                 var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
10830                                 selectee.$element
10831                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
10832                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
10833                                 selectee.unselecting = !doSelect;
10834                                 selectee.selecting = doSelect;
10835                                 selectee.selected = doSelect;
10836                                 // selectable (UN)SELECTING callback
10837                                 if (doSelect) {
10838                                         that._trigger("selecting", event, {
10839                                                 selecting: selectee.element
10840                                         });
10841                                 } else {
10842                                         that._trigger("unselecting", event, {
10843                                                 unselecting: selectee.element
10844                                         });
10845                                 }
10846                                 return false;
10847                         }
10848                 });
10849
10850         },
10851
10852         _mouseDrag: function(event) {
10853                 var that = this;
10854                 this.dragged = true;
10855
10856                 if (this.options.disabled)
10857                         return;
10858
10859                 var options = this.options;
10860
10861                 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
10862                 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
10863                 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
10864                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
10865
10866                 this.selectees.each(function() {
10867                         var selectee = $.data(this, "selectable-item");
10868                         //prevent helper from being selected if appendTo: selectable
10869                         if (!selectee || selectee.element == that.element[0])
10870                                 return;
10871                         var hit = false;
10872                         if (options.tolerance == 'touch') {
10873                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
10874                         } else if (options.tolerance == 'fit') {
10875                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
10876                         }
10877
10878                         if (hit) {
10879                                 // SELECT
10880                                 if (selectee.selected) {
10881                                         selectee.$element.removeClass('ui-selected');
10882                                         selectee.selected = false;
10883                                 }
10884                                 if (selectee.unselecting) {
10885                                         selectee.$element.removeClass('ui-unselecting');
10886                                         selectee.unselecting = false;
10887                                 }
10888                                 if (!selectee.selecting) {
10889                                         selectee.$element.addClass('ui-selecting');
10890                                         selectee.selecting = true;
10891                                         // selectable SELECTING callback
10892                                         that._trigger("selecting", event, {
10893                                                 selecting: selectee.element
10894                                         });
10895                                 }
10896                         } else {
10897                                 // UNSELECT
10898                                 if (selectee.selecting) {
10899                                         if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
10900                                                 selectee.$element.removeClass('ui-selecting');
10901                                                 selectee.selecting = false;
10902                                                 selectee.$element.addClass('ui-selected');
10903                                                 selectee.selected = true;
10904                                         } else {
10905                                                 selectee.$element.removeClass('ui-selecting');
10906                                                 selectee.selecting = false;
10907                                                 if (selectee.startselected) {
10908                                                         selectee.$element.addClass('ui-unselecting');
10909                                                         selectee.unselecting = true;
10910                                                 }
10911                                                 // selectable UNSELECTING callback
10912                                                 that._trigger("unselecting", event, {
10913                                                         unselecting: selectee.element
10914                                                 });
10915                                         }
10916                                 }
10917                                 if (selectee.selected) {
10918                                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
10919                                                 selectee.$element.removeClass('ui-selected');
10920                                                 selectee.selected = false;
10921
10922                                                 selectee.$element.addClass('ui-unselecting');
10923                                                 selectee.unselecting = true;
10924                                                 // selectable UNSELECTING callback
10925                                                 that._trigger("unselecting", event, {
10926                                                         unselecting: selectee.element
10927                                                 });
10928                                         }
10929                                 }
10930                         }
10931                 });
10932
10933                 return false;
10934         },
10935
10936         _mouseStop: function(event) {
10937                 var that = this;
10938
10939                 this.dragged = false;
10940
10941                 var options = this.options;
10942
10943                 $('.ui-unselecting', this.element[0]).each(function() {
10944                         var selectee = $.data(this, "selectable-item");
10945                         selectee.$element.removeClass('ui-unselecting');
10946                         selectee.unselecting = false;
10947                         selectee.startselected = false;
10948                         that._trigger("unselected", event, {
10949                                 unselected: selectee.element
10950                         });
10951                 });
10952                 $('.ui-selecting', this.element[0]).each(function() {
10953                         var selectee = $.data(this, "selectable-item");
10954                         selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
10955                         selectee.selecting = false;
10956                         selectee.selected = true;
10957                         selectee.startselected = true;
10958                         that._trigger("selected", event, {
10959                                 selected: selectee.element
10960                         });
10961                 });
10962                 this._trigger("stop", event);
10963
10964                 this.helper.remove();
10965
10966                 return false;
10967         }
10968
10969 });
10970
10971 })(jQuery);
10972 (function( $, undefined ) {
10973
10974 // number of pages in a slider
10975 // (how many times can you page up/down to go through the whole range)
10976 var numPages = 5;
10977
10978 $.widget( "ui.slider", $.ui.mouse, {
10979         version: "1.9.2",
10980         widgetEventPrefix: "slide",
10981
10982         options: {
10983                 animate: false,
10984                 distance: 0,
10985                 max: 100,
10986                 min: 0,
10987                 orientation: "horizontal",
10988                 range: false,
10989                 step: 1,
10990                 value: 0,
10991                 values: null
10992         },
10993
10994         _create: function() {
10995                 var i, handleCount,
10996                         o = this.options,
10997                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
10998                         handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
10999                         handles = [];
11000
11001                 this._keySliding = false;
11002                 this._mouseSliding = false;
11003                 this._animateOff = true;
11004                 this._handleIndex = null;
11005                 this._detectOrientation();
11006                 this._mouseInit();
11007
11008                 this.element
11009                         .addClass( "ui-slider" +
11010                                 " ui-slider-" + this.orientation +
11011                                 " ui-widget" +
11012                                 " ui-widget-content" +
11013                                 " ui-corner-all" +
11014                                 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
11015
11016                 this.range = $([]);
11017
11018                 if ( o.range ) {
11019                         if ( o.range === true ) {
11020                                 if ( !o.values ) {
11021                                         o.values = [ this._valueMin(), this._valueMin() ];
11022                                 }
11023                                 if ( o.values.length && o.values.length !== 2 ) {
11024                                         o.values = [ o.values[0], o.values[0] ];
11025                                 }
11026                         }
11027
11028                         this.range = $( "<div></div>" )
11029                                 .appendTo( this.element )
11030                                 .addClass( "ui-slider-range" +
11031                                 // note: this isn't the most fittingly semantic framework class for this element,
11032                                 // but worked best visually with a variety of themes
11033                                 " ui-widget-header" +
11034                                 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
11035                 }
11036
11037                 handleCount = ( o.values && o.values.length ) || 1;
11038
11039                 for ( i = existingHandles.length; i < handleCount; i++ ) {
11040                         handles.push( handle );
11041                 }
11042
11043                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
11044
11045                 this.handle = this.handles.eq( 0 );
11046
11047                 this.handles.add( this.range ).filter( "a" )
11048                         .click(function( event ) {
11049                                 event.preventDefault();
11050                         })
11051                         .mouseenter(function() {
11052                                 if ( !o.disabled ) {
11053                                         $( this ).addClass( "ui-state-hover" );
11054                                 }
11055                         })
11056                         .mouseleave(function() {
11057                                 $( this ).removeClass( "ui-state-hover" );
11058                         })
11059                         .focus(function() {
11060                                 if ( !o.disabled ) {
11061                                         $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
11062                                         $( this ).addClass( "ui-state-focus" );
11063                                 } else {
11064                                         $( this ).blur();
11065                                 }
11066                         })
11067                         .blur(function() {
11068                                 $( this ).removeClass( "ui-state-focus" );
11069                         });
11070
11071                 this.handles.each(function( i ) {
11072                         $( this ).data( "ui-slider-handle-index", i );
11073                 });
11074
11075                 this._on( this.handles, {
11076                         keydown: function( event ) {
11077                                 var allowed, curVal, newVal, step,
11078                                         index = $( event.target ).data( "ui-slider-handle-index" );
11079
11080                                 switch ( event.keyCode ) {
11081                                         case $.ui.keyCode.HOME:
11082                                         case $.ui.keyCode.END:
11083                                         case $.ui.keyCode.PAGE_UP:
11084                                         case $.ui.keyCode.PAGE_DOWN:
11085                                         case $.ui.keyCode.UP:
11086                                         case $.ui.keyCode.RIGHT:
11087                                         case $.ui.keyCode.DOWN:
11088                                         case $.ui.keyCode.LEFT:
11089                                                 event.preventDefault();
11090                                                 if ( !this._keySliding ) {
11091                                                         this._keySliding = true;
11092                                                         $( event.target ).addClass( "ui-state-active" );
11093                                                         allowed = this._start( event, index );
11094                                                         if ( allowed === false ) {
11095                                                                 return;
11096                                                         }
11097                                                 }
11098                                                 break;
11099                                 }
11100
11101                                 step = this.options.step;
11102                                 if ( this.options.values && this.options.values.length ) {
11103                                         curVal = newVal = this.values( index );
11104                                 } else {
11105                                         curVal = newVal = this.value();
11106                                 }
11107
11108                                 switch ( event.keyCode ) {
11109                                         case $.ui.keyCode.HOME:
11110                                                 newVal = this._valueMin();
11111                                                 break;
11112                                         case $.ui.keyCode.END:
11113                                                 newVal = this._valueMax();
11114                                                 break;
11115                                         case $.ui.keyCode.PAGE_UP:
11116                                                 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
11117                                                 break;
11118                                         case $.ui.keyCode.PAGE_DOWN:
11119                                                 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
11120                                                 break;
11121                                         case $.ui.keyCode.UP:
11122                                         case $.ui.keyCode.RIGHT:
11123                                                 if ( curVal === this._valueMax() ) {
11124                                                         return;
11125                                                 }
11126                                                 newVal = this._trimAlignValue( curVal + step );
11127                                                 break;
11128                                         case $.ui.keyCode.DOWN:
11129                                         case $.ui.keyCode.LEFT:
11130                                                 if ( curVal === this._valueMin() ) {
11131                                                         return;
11132                                                 }
11133                                                 newVal = this._trimAlignValue( curVal - step );
11134                                                 break;
11135                                 }
11136
11137                                 this._slide( event, index, newVal );
11138                         },
11139                         keyup: function( event ) {
11140                                 var index = $( event.target ).data( "ui-slider-handle-index" );
11141
11142                                 if ( this._keySliding ) {
11143                                         this._keySliding = false;
11144                                         this._stop( event, index );
11145                                         this._change( event, index );
11146                                         $( event.target ).removeClass( "ui-state-active" );
11147                                 }
11148                         }
11149                 });
11150
11151                 this._refreshValue();
11152
11153                 this._animateOff = false;
11154         },
11155
11156         _destroy: function() {
11157                 this.handles.remove();
11158                 this.range.remove();
11159
11160                 this.element
11161                         .removeClass( "ui-slider" +
11162                                 " ui-slider-horizontal" +
11163                                 " ui-slider-vertical" +
11164                                 " ui-slider-disabled" +
11165                                 " ui-widget" +
11166                                 " ui-widget-content" +
11167                                 " ui-corner-all" );
11168
11169                 this._mouseDestroy();
11170         },
11171
11172         _mouseCapture: function( event ) {
11173                 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
11174                         that = this,
11175                         o = this.options;
11176
11177                 if ( o.disabled ) {
11178                         return false;
11179                 }
11180
11181                 this.elementSize = {
11182                         width: this.element.outerWidth(),
11183                         height: this.element.outerHeight()
11184                 };
11185                 this.elementOffset = this.element.offset();
11186
11187                 position = { x: event.pageX, y: event.pageY };
11188                 normValue = this._normValueFromMouse( position );
11189                 distance = this._valueMax() - this._valueMin() + 1;
11190                 this.handles.each(function( i ) {
11191                         var thisDistance = Math.abs( normValue - that.values(i) );
11192                         if ( distance > thisDistance ) {
11193                                 distance = thisDistance;
11194                                 closestHandle = $( this );
11195                                 index = i;
11196                         }
11197                 });
11198
11199                 // workaround for bug #3736 (if both handles of a range are at 0,
11200                 // the first is always used as the one with least distance,
11201                 // and moving it is obviously prevented by preventing negative ranges)
11202                 if( o.range === true && this.values(1) === o.min ) {
11203                         index += 1;
11204                         closestHandle = $( this.handles[index] );
11205                 }
11206
11207                 allowed = this._start( event, index );
11208                 if ( allowed === false ) {
11209                         return false;
11210                 }
11211                 this._mouseSliding = true;
11212
11213                 this._handleIndex = index;
11214
11215                 closestHandle
11216                         .addClass( "ui-state-active" )
11217                         .focus();
11218
11219                 offset = closestHandle.offset();
11220                 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
11221                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
11222                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
11223                         top: event.pageY - offset.top -
11224                                 ( closestHandle.height() / 2 ) -
11225                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
11226                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
11227                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
11228                 };
11229
11230                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
11231                         this._slide( event, index, normValue );
11232                 }
11233                 this._animateOff = true;
11234                 return true;
11235         },
11236
11237         _mouseStart: function() {
11238                 return true;
11239         },
11240
11241         _mouseDrag: function( event ) {
11242                 var position = { x: event.pageX, y: event.pageY },
11243                         normValue = this._normValueFromMouse( position );
11244
11245                 this._slide( event, this._handleIndex, normValue );
11246
11247                 return false;
11248         },
11249
11250         _mouseStop: function( event ) {
11251                 this.handles.removeClass( "ui-state-active" );
11252                 this._mouseSliding = false;
11253
11254                 this._stop( event, this._handleIndex );
11255                 this._change( event, this._handleIndex );
11256
11257                 this._handleIndex = null;
11258                 this._clickOffset = null;
11259                 this._animateOff = false;
11260
11261                 return false;
11262         },
11263
11264         _detectOrientation: function() {
11265                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
11266         },
11267
11268         _normValueFromMouse: function( position ) {
11269                 var pixelTotal,
11270                         pixelMouse,
11271                         percentMouse,
11272                         valueTotal,
11273                         valueMouse;
11274
11275                 if ( this.orientation === "horizontal" ) {
11276                         pixelTotal = this.elementSize.width;
11277                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
11278                 } else {
11279                         pixelTotal = this.elementSize.height;
11280                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
11281                 }
11282
11283                 percentMouse = ( pixelMouse / pixelTotal );
11284                 if ( percentMouse > 1 ) {
11285                         percentMouse = 1;
11286                 }
11287                 if ( percentMouse < 0 ) {
11288                         percentMouse = 0;
11289                 }
11290                 if ( this.orientation === "vertical" ) {
11291                         percentMouse = 1 - percentMouse;
11292                 }
11293
11294                 valueTotal = this._valueMax() - this._valueMin();
11295                 valueMouse = this._valueMin() + percentMouse * valueTotal;
11296
11297                 return this._trimAlignValue( valueMouse );
11298         },
11299
11300         _start: function( event, index ) {
11301                 var uiHash = {
11302                         handle: this.handles[ index ],
11303                         value: this.value()
11304                 };
11305                 if ( this.options.values && this.options.values.length ) {
11306                         uiHash.value = this.values( index );
11307                         uiHash.values = this.values();
11308                 }
11309                 return this._trigger( "start", event, uiHash );
11310         },
11311
11312         _slide: function( event, index, newVal ) {
11313                 var otherVal,
11314                         newValues,
11315                         allowed;
11316
11317                 if ( this.options.values && this.options.values.length ) {
11318                         otherVal = this.values( index ? 0 : 1 );
11319
11320                         if ( ( this.options.values.length === 2 && this.options.range === true ) &&
11321                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
11322                                 ) {
11323                                 newVal = otherVal;
11324                         }
11325
11326                         if ( newVal !== this.values( index ) ) {
11327                                 newValues = this.values();
11328                                 newValues[ index ] = newVal;
11329                                 // A slide can be canceled by returning false from the slide callback
11330                                 allowed = this._trigger( "slide", event, {
11331                                         handle: this.handles[ index ],
11332                                         value: newVal,
11333                                         values: newValues
11334                                 } );
11335                                 otherVal = this.values( index ? 0 : 1 );
11336                                 if ( allowed !== false ) {
11337                                         this.values( index, newVal, true );
11338                                 }
11339                         }
11340                 } else {
11341                         if ( newVal !== this.value() ) {
11342                                 // A slide can be canceled by returning false from the slide callback
11343                                 allowed = this._trigger( "slide", event, {
11344                                         handle: this.handles[ index ],
11345                                         value: newVal
11346                                 } );
11347                                 if ( allowed !== false ) {
11348                                         this.value( newVal );
11349                                 }
11350                         }
11351                 }
11352         },
11353
11354         _stop: function( event, index ) {
11355                 var uiHash = {
11356                         handle: this.handles[ index ],
11357                         value: this.value()
11358                 };
11359                 if ( this.options.values && this.options.values.length ) {
11360                         uiHash.value = this.values( index );
11361                         uiHash.values = this.values();
11362                 }
11363
11364                 this._trigger( "stop", event, uiHash );
11365         },
11366
11367         _change: function( event, index ) {
11368                 if ( !this._keySliding && !this._mouseSliding ) {
11369                         var uiHash = {
11370                                 handle: this.handles[ index ],
11371                                 value: this.value()
11372                         };
11373                         if ( this.options.values && this.options.values.length ) {
11374                                 uiHash.value = this.values( index );
11375                                 uiHash.values = this.values();
11376                         }
11377
11378                         this._trigger( "change", event, uiHash );
11379                 }
11380         },
11381
11382         value: function( newValue ) {
11383                 if ( arguments.length ) {
11384                         this.options.value = this._trimAlignValue( newValue );
11385                         this._refreshValue();
11386                         this._change( null, 0 );
11387                         return;
11388                 }
11389
11390                 return this._value();
11391         },
11392
11393         values: function( index, newValue ) {
11394                 var vals,
11395                         newValues,
11396                         i;
11397
11398                 if ( arguments.length > 1 ) {
11399                         this.options.values[ index ] = this._trimAlignValue( newValue );
11400                         this._refreshValue();
11401                         this._change( null, index );
11402                         return;
11403                 }
11404
11405                 if ( arguments.length ) {
11406                         if ( $.isArray( arguments[ 0 ] ) ) {
11407                                 vals = this.options.values;
11408                                 newValues = arguments[ 0 ];
11409                                 for ( i = 0; i < vals.length; i += 1 ) {
11410                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
11411                                         this._change( null, i );
11412                                 }
11413                                 this._refreshValue();
11414                         } else {
11415                                 if ( this.options.values && this.options.values.length ) {
11416                                         return this._values( index );
11417                                 } else {
11418                                         return this.value();
11419                                 }
11420                         }
11421                 } else {
11422                         return this._values();
11423                 }
11424         },
11425
11426         _setOption: function( key, value ) {
11427                 var i,
11428                         valsLength = 0;
11429
11430                 if ( $.isArray( this.options.values ) ) {
11431                         valsLength = this.options.values.length;
11432                 }
11433
11434                 $.Widget.prototype._setOption.apply( this, arguments );
11435
11436                 switch ( key ) {
11437                         case "disabled":
11438                                 if ( value ) {
11439                                         this.handles.filter( ".ui-state-focus" ).blur();
11440                                         this.handles.removeClass( "ui-state-hover" );
11441                                         this.handles.prop( "disabled", true );
11442                                         this.element.addClass( "ui-disabled" );
11443                                 } else {
11444                                         this.handles.prop( "disabled", false );
11445                                         this.element.removeClass( "ui-disabled" );
11446                                 }
11447                                 break;
11448                         case "orientation":
11449                                 this._detectOrientation();
11450                                 this.element
11451                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
11452                                         .addClass( "ui-slider-" + this.orientation );
11453                                 this._refreshValue();
11454                                 break;
11455                         case "value":
11456                                 this._animateOff = true;
11457                                 this._refreshValue();
11458                                 this._change( null, 0 );
11459                                 this._animateOff = false;
11460                                 break;
11461                         case "values":
11462                                 this._animateOff = true;
11463                                 this._refreshValue();
11464                                 for ( i = 0; i < valsLength; i += 1 ) {
11465                                         this._change( null, i );
11466                                 }
11467                                 this._animateOff = false;
11468                                 break;
11469                         case "min":
11470                         case "max":
11471                                 this._animateOff = true;
11472                                 this._refreshValue();
11473                                 this._animateOff = false;
11474                                 break;
11475                 }
11476         },
11477
11478         //internal value getter
11479         // _value() returns value trimmed by min and max, aligned by step
11480         _value: function() {
11481                 var val = this.options.value;
11482                 val = this._trimAlignValue( val );
11483
11484                 return val;
11485         },
11486
11487         //internal values getter
11488         // _values() returns array of values trimmed by min and max, aligned by step
11489         // _values( index ) returns single value trimmed by min and max, aligned by step
11490         _values: function( index ) {
11491                 var val,
11492                         vals,
11493                         i;
11494
11495                 if ( arguments.length ) {
11496                         val = this.options.values[ index ];
11497                         val = this._trimAlignValue( val );
11498
11499                         return val;
11500                 } else {
11501                         // .slice() creates a copy of the array
11502                         // this copy gets trimmed by min and max and then returned
11503                         vals = this.options.values.slice();
11504                         for ( i = 0; i < vals.length; i+= 1) {
11505                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
11506                         }
11507
11508                         return vals;
11509                 }
11510         },
11511
11512         // returns the step-aligned value that val is closest to, between (inclusive) min and max
11513         _trimAlignValue: function( val ) {
11514                 if ( val <= this._valueMin() ) {
11515                         return this._valueMin();
11516                 }
11517                 if ( val >= this._valueMax() ) {
11518                         return this._valueMax();
11519                 }
11520                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
11521                         valModStep = (val - this._valueMin()) % step,
11522                         alignValue = val - valModStep;
11523
11524                 if ( Math.abs(valModStep) * 2 >= step ) {
11525                         alignValue += ( valModStep > 0 ) ? step : ( -step );
11526                 }
11527
11528                 // Since JavaScript has problems with large floats, round
11529                 // the final value to 5 digits after the decimal point (see #4124)
11530                 return parseFloat( alignValue.toFixed(5) );
11531         },
11532
11533         _valueMin: function() {
11534                 return this.options.min;
11535         },
11536
11537         _valueMax: function() {
11538                 return this.options.max;
11539         },
11540
11541         _refreshValue: function() {
11542                 var lastValPercent, valPercent, value, valueMin, valueMax,
11543                         oRange = this.options.range,
11544                         o = this.options,
11545                         that = this,
11546                         animate = ( !this._animateOff ) ? o.animate : false,
11547                         _set = {};
11548
11549                 if ( this.options.values && this.options.values.length ) {
11550                         this.handles.each(function( i ) {
11551                                 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
11552                                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
11553                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
11554                                 if ( that.options.range === true ) {
11555                                         if ( that.orientation === "horizontal" ) {
11556                                                 if ( i === 0 ) {
11557                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
11558                                                 }
11559                                                 if ( i === 1 ) {
11560                                                         that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
11561                                                 }
11562                                         } else {
11563                                                 if ( i === 0 ) {
11564                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
11565                                                 }
11566                                                 if ( i === 1 ) {
11567                                                         that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
11568                                                 }
11569                                         }
11570                                 }
11571                                 lastValPercent = valPercent;
11572                         });
11573                 } else {
11574                         value = this.value();
11575                         valueMin = this._valueMin();
11576                         valueMax = this._valueMax();
11577                         valPercent = ( valueMax !== valueMin ) ?
11578                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
11579                                         0;
11580                         _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
11581                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
11582
11583                         if ( oRange === "min" && this.orientation === "horizontal" ) {
11584                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
11585                         }
11586                         if ( oRange === "max" && this.orientation === "horizontal" ) {
11587                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
11588                         }
11589                         if ( oRange === "min" && this.orientation === "vertical" ) {
11590                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
11591                         }
11592                         if ( oRange === "max" && this.orientation === "vertical" ) {
11593                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
11594                         }
11595                 }
11596         }
11597
11598 });
11599
11600 }(jQuery));
11601 (function( $, undefined ) {
11602
11603 $.widget("ui.sortable", $.ui.mouse, {
11604         version: "1.9.2",
11605         widgetEventPrefix: "sort",
11606         ready: false,
11607         options: {
11608                 appendTo: "parent",
11609                 axis: false,
11610                 connectWith: false,
11611                 containment: false,
11612                 cursor: 'auto',
11613                 cursorAt: false,
11614                 dropOnEmpty: true,
11615                 forcePlaceholderSize: false,
11616                 forceHelperSize: false,
11617                 grid: false,
11618                 handle: false,
11619                 helper: "original",
11620                 items: '> *',
11621                 opacity: false,
11622                 placeholder: false,
11623                 revert: false,
11624                 scroll: true,
11625                 scrollSensitivity: 20,
11626                 scrollSpeed: 20,
11627                 scope: "default",
11628                 tolerance: "intersect",
11629                 zIndex: 1000
11630         },
11631         _create: function() {
11632
11633                 var o = this.options;
11634                 this.containerCache = {};
11635                 this.element.addClass("ui-sortable");
11636
11637                 //Get the items
11638                 this.refresh();
11639
11640                 //Let's determine if the items are being displayed horizontally
11641                 this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
11642
11643                 //Let's determine the parent's offset
11644                 this.offset = this.element.offset();
11645
11646                 //Initialize mouse events for interaction
11647                 this._mouseInit();
11648
11649                 //We're ready to go
11650                 this.ready = true
11651
11652         },
11653
11654         _destroy: function() {
11655                 this.element
11656                         .removeClass("ui-sortable ui-sortable-disabled");
11657                 this._mouseDestroy();
11658
11659                 for ( var i = this.items.length - 1; i >= 0; i-- )
11660                         this.items[i].item.removeData(this.widgetName + "-item");
11661
11662                 return this;
11663         },
11664
11665         _setOption: function(key, value){
11666                 if ( key === "disabled" ) {
11667                         this.options[ key ] = value;
11668
11669                         this.widget().toggleClass( "ui-sortable-disabled", !!value );
11670                 } else {
11671                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
11672                         $.Widget.prototype._setOption.apply(this, arguments);
11673                 }
11674         },
11675
11676         _mouseCapture: function(event, overrideHandle) {
11677                 var that = this;
11678
11679                 if (this.reverting) {
11680                         return false;
11681                 }
11682
11683                 if(this.options.disabled || this.options.type == 'static') return false;
11684
11685                 //We have to refresh the items data once first
11686                 this._refreshItems(event);
11687
11688                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
11689                 var currentItem = null, nodes = $(event.target).parents().each(function() {
11690                         if($.data(this, that.widgetName + '-item') == that) {
11691                                 currentItem = $(this);
11692                                 return false;
11693                         }
11694                 });
11695                 if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
11696
11697                 if(!currentItem) return false;
11698                 if(this.options.handle && !overrideHandle) {
11699                         var validHandle = false;
11700
11701                         $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
11702                         if(!validHandle) return false;
11703                 }
11704
11705                 this.currentItem = currentItem;
11706                 this._removeCurrentsFromItems();
11707                 return true;
11708
11709         },
11710
11711         _mouseStart: function(event, overrideHandle, noActivation) {
11712
11713                 var o = this.options;
11714                 this.currentContainer = this;
11715
11716                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
11717                 this.refreshPositions();
11718
11719                 //Create and append the visible helper
11720                 this.helper = this._createHelper(event);
11721
11722                 //Cache the helper size
11723                 this._cacheHelperProportions();
11724
11725                 /*
11726                  * - Position generation -
11727                  * This block generates everything position related - it's the core of draggables.
11728                  */
11729
11730                 //Cache the margins of the original element
11731                 this._cacheMargins();
11732
11733                 //Get the next scrolling parent
11734                 this.scrollParent = this.helper.scrollParent();
11735
11736                 //The element's absolute position on the page minus margins
11737                 this.offset = this.currentItem.offset();
11738                 this.offset = {
11739                         top: this.offset.top - this.margins.top,
11740                         left: this.offset.left - this.margins.left
11741                 };
11742
11743                 $.extend(this.offset, {
11744                         click: { //Where the click happened, relative to the element
11745                                 left: event.pageX - this.offset.left,
11746                                 top: event.pageY - this.offset.top
11747                         },
11748                         parent: this._getParentOffset(),
11749                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
11750                 });
11751
11752                 // Only after we got the offset, we can change the helper's position to absolute
11753                 // TODO: Still need to figure out a way to make relative sorting possible
11754                 this.helper.css("position", "absolute");
11755                 this.cssPosition = this.helper.css("position");
11756
11757                 //Generate the original position
11758                 this.originalPosition = this._generatePosition(event);
11759                 this.originalPageX = event.pageX;
11760                 this.originalPageY = event.pageY;
11761
11762                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
11763                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
11764
11765                 //Cache the former DOM position
11766                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
11767
11768                 //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
11769                 if(this.helper[0] != this.currentItem[0]) {
11770                         this.currentItem.hide();
11771                 }
11772
11773                 //Create the placeholder
11774                 this._createPlaceholder();
11775
11776                 //Set a containment if given in the options
11777                 if(o.containment)
11778                         this._setContainment();
11779
11780                 if(o.cursor) { // cursor option
11781                         if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
11782                         $('body').css("cursor", o.cursor);
11783                 }
11784
11785                 if(o.opacity) { // opacity option
11786                         if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
11787                         this.helper.css("opacity", o.opacity);
11788                 }
11789
11790                 if(o.zIndex) { // zIndex option
11791                         if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
11792                         this.helper.css("zIndex", o.zIndex);
11793                 }
11794
11795                 //Prepare scrolling
11796                 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
11797                         this.overflowOffset = this.scrollParent.offset();
11798
11799                 //Call callbacks
11800                 this._trigger("start", event, this._uiHash());
11801
11802                 //Recache the helper size
11803                 if(!this._preserveHelperProportions)
11804                         this._cacheHelperProportions();
11805
11806
11807                 //Post 'activate' events to possible containers
11808                 if(!noActivation) {
11809                          for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
11810                 }
11811
11812                 //Prepare possible droppables
11813                 if($.ui.ddmanager)
11814                         $.ui.ddmanager.current = this;
11815
11816                 if ($.ui.ddmanager && !o.dropBehaviour)
11817                         $.ui.ddmanager.prepareOffsets(this, event);
11818
11819                 this.dragging = true;
11820
11821                 this.helper.addClass("ui-sortable-helper");
11822                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
11823                 return true;
11824
11825         },
11826
11827         _mouseDrag: function(event) {
11828
11829                 //Compute the helpers position
11830                 this.position = this._generatePosition(event);
11831                 this.positionAbs = this._convertPositionTo("absolute");
11832
11833                 if (!this.lastPositionAbs) {
11834                         this.lastPositionAbs = this.positionAbs;
11835                 }
11836
11837                 //Do scrolling
11838                 if(this.options.scroll) {
11839                         var o = this.options, scrolled = false;
11840                         if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
11841
11842                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
11843                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
11844                                 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
11845                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
11846
11847                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
11848                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
11849                                 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
11850                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
11851
11852                         } else {
11853
11854                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
11855                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
11856                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
11857                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
11858
11859                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
11860                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
11861                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
11862                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
11863
11864                         }
11865
11866                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
11867                                 $.ui.ddmanager.prepareOffsets(this, event);
11868                 }
11869
11870                 //Regenerate the absolute position used for position checks
11871                 this.positionAbs = this._convertPositionTo("absolute");
11872
11873                 //Set the helper position
11874                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
11875                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
11876
11877                 //Rearrange
11878                 for (var i = this.items.length - 1; i >= 0; i--) {
11879
11880                         //Cache variables and intersection, continue if no intersection
11881                         var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
11882                         if (!intersection) continue;
11883
11884                         // Only put the placeholder inside the current Container, skip all
11885                         // items form other containers. This works because when moving
11886                         // an item from one container to another the
11887                         // currentContainer is switched before the placeholder is moved.
11888                         //
11889                         // Without this moving items in "sub-sortables" can cause the placeholder to jitter
11890                         // beetween the outer and inner container.
11891                         if (item.instance !== this.currentContainer) continue;
11892
11893                         if (itemElement != this.currentItem[0] //cannot intersect with itself
11894                                 &&      this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
11895                                 &&      !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
11896                                 && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
11897                                 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
11898                         ) {
11899
11900                                 this.direction = intersection == 1 ? "down" : "up";
11901
11902                                 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
11903                                         this._rearrange(event, item);
11904                                 } else {
11905                                         break;
11906                                 }
11907
11908                                 this._trigger("change", event, this._uiHash());
11909                                 break;
11910                         }
11911                 }
11912
11913                 //Post events to containers
11914                 this._contactContainers(event);
11915
11916                 //Interconnect with droppables
11917                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
11918
11919                 //Call callbacks
11920                 this._trigger('sort', event, this._uiHash());
11921
11922                 this.lastPositionAbs = this.positionAbs;
11923                 return false;
11924
11925         },
11926
11927         _mouseStop: function(event, noPropagation) {
11928
11929                 if(!event) return;
11930
11931                 //If we are using droppables, inform the manager about the drop
11932                 if ($.ui.ddmanager && !this.options.dropBehaviour)
11933                         $.ui.ddmanager.drop(this, event);
11934
11935                 if(this.options.revert) {
11936                         var that = this;
11937                         var cur = this.placeholder.offset();
11938
11939                         this.reverting = true;
11940
11941                         $(this.helper).animate({
11942                                 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
11943                                 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
11944                         }, parseInt(this.options.revert, 10) || 500, function() {
11945                                 that._clear(event);
11946                         });
11947                 } else {
11948                         this._clear(event, noPropagation);
11949                 }
11950
11951                 return false;
11952
11953         },
11954
11955         cancel: function() {
11956
11957                 if(this.dragging) {
11958
11959                         this._mouseUp({ target: null });
11960
11961                         if(this.options.helper == "original")
11962                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
11963                         else
11964                                 this.currentItem.show();
11965
11966                         //Post deactivating events to containers
11967                         for (var i = this.containers.length - 1; i >= 0; i--){
11968                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
11969                                 if(this.containers[i].containerCache.over) {
11970                                         this.containers[i]._trigger("out", null, this._uiHash(this));
11971                                         this.containers[i].containerCache.over = 0;
11972                                 }
11973                         }
11974
11975                 }
11976
11977                 if (this.placeholder) {
11978                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
11979                         if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
11980                         if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
11981
11982                         $.extend(this, {
11983                                 helper: null,
11984                                 dragging: false,
11985                                 reverting: false,
11986                                 _noFinalSort: null
11987                         });
11988
11989                         if(this.domPosition.prev) {
11990                                 $(this.domPosition.prev).after(this.currentItem);
11991                         } else {
11992                                 $(this.domPosition.parent).prepend(this.currentItem);
11993                         }
11994                 }
11995
11996                 return this;
11997
11998         },
11999
12000         serialize: function(o) {
12001
12002                 var items = this._getItemsAsjQuery(o && o.connected);
12003                 var str = []; o = o || {};
12004
12005                 $(items).each(function() {
12006                         var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
12007                         if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
12008                 });
12009
12010                 if(!str.length && o.key) {
12011                         str.push(o.key + '=');
12012                 }
12013
12014                 return str.join('&');
12015
12016         },
12017
12018         toArray: function(o) {
12019
12020                 var items = this._getItemsAsjQuery(o && o.connected);
12021                 var ret = []; o = o || {};
12022
12023                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
12024                 return ret;
12025
12026         },
12027
12028         /* Be careful with the following core functions */
12029         _intersectsWith: function(item) {
12030
12031                 var x1 = this.positionAbs.left,
12032                         x2 = x1 + this.helperProportions.width,
12033                         y1 = this.positionAbs.top,
12034                         y2 = y1 + this.helperProportions.height;
12035
12036                 var l = item.left,
12037                         r = l + item.width,
12038                         t = item.top,
12039                         b = t + item.height;
12040
12041                 var dyClick = this.offset.click.top,
12042                         dxClick = this.offset.click.left;
12043
12044                 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
12045
12046                 if(        this.options.tolerance == "pointer"
12047                         || this.options.forcePointerForContainers
12048                         || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
12049                 ) {
12050                         return isOverElement;
12051                 } else {
12052
12053                         return (l < x1 + (this.helperProportions.width / 2) // Right Half
12054                                 && x2 - (this.helperProportions.width / 2) < r // Left Half
12055                                 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
12056                                 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
12057
12058                 }
12059         },
12060
12061         _intersectsWithPointer: function(item) {
12062
12063                 var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
12064                         isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
12065                         isOverElement = isOverElementHeight && isOverElementWidth,
12066                         verticalDirection = this._getDragVerticalDirection(),
12067                         horizontalDirection = this._getDragHorizontalDirection();
12068
12069                 if (!isOverElement)
12070                         return false;
12071
12072                 return this.floating ?
12073                         ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
12074                         : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
12075
12076         },
12077
12078         _intersectsWithSides: function(item) {
12079
12080                 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
12081                         isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
12082                         verticalDirection = this._getDragVerticalDirection(),
12083                         horizontalDirection = this._getDragHorizontalDirection();
12084
12085                 if (this.floating && horizontalDirection) {
12086                         return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
12087                 } else {
12088                         return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
12089                 }
12090
12091         },
12092
12093         _getDragVerticalDirection: function() {
12094                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
12095                 return delta != 0 && (delta > 0 ? "down" : "up");
12096         },
12097
12098         _getDragHorizontalDirection: function() {
12099                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
12100                 return delta != 0 && (delta > 0 ? "right" : "left");
12101         },
12102
12103         refresh: function(event) {
12104                 this._refreshItems(event);
12105                 this.refreshPositions();
12106                 return this;
12107         },
12108
12109         _connectWith: function() {
12110                 var options = this.options;
12111                 return options.connectWith.constructor == String
12112                         ? [options.connectWith]
12113                         : options.connectWith;
12114         },
12115
12116         _getItemsAsjQuery: function(connected) {
12117
12118                 var items = [];
12119                 var queries = [];
12120                 var connectWith = this._connectWith();
12121
12122                 if(connectWith && connected) {
12123                         for (var i = connectWith.length - 1; i >= 0; i--){
12124                                 var cur = $(connectWith[i]);
12125                                 for (var j = cur.length - 1; j >= 0; j--){
12126                                         var inst = $.data(cur[j], this.widgetName);
12127                                         if(inst && inst != this && !inst.options.disabled) {
12128                                                 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]);
12129                                         }
12130                                 };
12131                         };
12132                 }
12133
12134                 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]);
12135
12136                 for (var i = queries.length - 1; i >= 0; i--){
12137                         queries[i][0].each(function() {
12138                                 items.push(this);
12139                         });
12140                 };
12141
12142                 return $(items);
12143
12144         },
12145
12146         _removeCurrentsFromItems: function() {
12147
12148                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
12149
12150                 this.items = $.grep(this.items, function (item) {
12151                         for (var j=0; j < list.length; j++) {
12152                                 if(list[j] == item.item[0])
12153                                         return false;
12154                         };
12155                         return true;
12156                 });
12157
12158         },
12159
12160         _refreshItems: function(event) {
12161
12162                 this.items = [];
12163                 this.containers = [this];
12164                 var items = this.items;
12165                 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
12166                 var connectWith = this._connectWith();
12167
12168                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
12169                         for (var i = connectWith.length - 1; i >= 0; i--){
12170                                 var cur = $(connectWith[i]);
12171                                 for (var j = cur.length - 1; j >= 0; j--){
12172                                         var inst = $.data(cur[j], this.widgetName);
12173                                         if(inst && inst != this && !inst.options.disabled) {
12174                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
12175                                                 this.containers.push(inst);
12176                                         }
12177                                 };
12178                         };
12179                 }
12180
12181                 for (var i = queries.length - 1; i >= 0; i--) {
12182                         var targetData = queries[i][1];
12183                         var _queries = queries[i][0];
12184
12185                         for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
12186                                 var item = $(_queries[j]);
12187
12188                                 item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
12189
12190                                 items.push({
12191                                         item: item,
12192                                         instance: targetData,
12193                                         width: 0, height: 0,
12194                                         left: 0, top: 0
12195                                 });
12196                         };
12197                 };
12198
12199         },
12200
12201         refreshPositions: function(fast) {
12202
12203                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
12204                 if(this.offsetParent && this.helper) {
12205                         this.offset.parent = this._getParentOffset();
12206                 }
12207
12208                 for (var i = this.items.length - 1; i >= 0; i--){
12209                         var item = this.items[i];
12210
12211                         //We ignore calculating positions of all connected containers when we're not over them
12212                         if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
12213                                 continue;
12214
12215                         var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
12216
12217                         if (!fast) {
12218                                 item.width = t.outerWidth();
12219                                 item.height = t.outerHeight();
12220                         }
12221
12222                         var p = t.offset();
12223                         item.left = p.left;
12224                         item.top = p.top;
12225                 };
12226
12227                 if(this.options.custom && this.options.custom.refreshContainers) {
12228                         this.options.custom.refreshContainers.call(this);
12229                 } else {
12230                         for (var i = this.containers.length - 1; i >= 0; i--){
12231                                 var p = this.containers[i].element.offset();
12232                                 this.containers[i].containerCache.left = p.left;
12233                                 this.containers[i].containerCache.top = p.top;
12234                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
12235                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
12236                         };
12237                 }
12238
12239                 return this;
12240         },
12241
12242         _createPlaceholder: function(that) {
12243                 that = that || this;
12244                 var o = that.options;
12245
12246                 if(!o.placeholder || o.placeholder.constructor == String) {
12247                         var className = o.placeholder;
12248                         o.placeholder = {
12249                                 element: function() {
12250
12251                                         var el = $(document.createElement(that.currentItem[0].nodeName))
12252                                                 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
12253                                                 .removeClass("ui-sortable-helper")[0];
12254
12255                                         if(!className)
12256                                                 el.style.visibility = "hidden";
12257
12258                                         return el;
12259                                 },
12260                                 update: function(container, p) {
12261
12262                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
12263                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
12264                                         if(className && !o.forcePlaceholderSize) return;
12265
12266                                         //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
12267                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
12268                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
12269                                 }
12270                         };
12271                 }
12272
12273                 //Create the placeholder
12274                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
12275
12276                 //Append it after the actual current item
12277                 that.currentItem.after(that.placeholder);
12278
12279                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
12280                 o.placeholder.update(that, that.placeholder);
12281
12282         },
12283
12284         _contactContainers: function(event) {
12285
12286                 // get innermost container that intersects with item
12287                 var innermostContainer = null, innermostIndex = null;
12288
12289
12290                 for (var i = this.containers.length - 1; i >= 0; i--){
12291
12292                         // never consider a container that's located within the item itself
12293                         if($.contains(this.currentItem[0], this.containers[i].element[0]))
12294                                 continue;
12295
12296                         if(this._intersectsWith(this.containers[i].containerCache)) {
12297
12298                                 // if we've already found a container and it's more "inner" than this, then continue
12299                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
12300                                         continue;
12301
12302                                 innermostContainer = this.containers[i];
12303                                 innermostIndex = i;
12304
12305                         } else {
12306                                 // container doesn't intersect. trigger "out" event if necessary
12307                                 if(this.containers[i].containerCache.over) {
12308                                         this.containers[i]._trigger("out", event, this._uiHash(this));
12309                                         this.containers[i].containerCache.over = 0;
12310                                 }
12311                         }
12312
12313                 }
12314
12315                 // if no intersecting containers found, return
12316                 if(!innermostContainer) return;
12317
12318                 // move the item into the container if it's not there already
12319                 if(this.containers.length === 1) {
12320                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
12321                         this.containers[innermostIndex].containerCache.over = 1;
12322                 } else {
12323
12324                         //When entering a new container, we will find the item with the least distance and append our item near it
12325                         var dist = 10000; var itemWithLeastDistance = null;
12326                         var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
12327                         var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
12328                         var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
12329                         for (var j = this.items.length - 1; j >= 0; j--) {
12330                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
12331                                 if(this.items[j].item[0] == this.currentItem[0]) continue;
12332                                 var cur = this.items[j].item.offset()[posProperty];
12333                                 var nearBottom = false;
12334                                 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
12335                                         nearBottom = true;
12336                                         cur += this.items[j][sizeProperty];
12337                                 }
12338
12339                                 if(Math.abs(cur - base) < dist) {
12340                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
12341                                         this.direction = nearBottom ? "up": "down";
12342                                 }
12343                         }
12344
12345                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
12346                                 return;
12347
12348                         this.currentContainer = this.containers[innermostIndex];
12349                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
12350                         this._trigger("change", event, this._uiHash());
12351                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
12352
12353                         //Update the placeholder
12354                         this.options.placeholder.update(this.currentContainer, this.placeholder);
12355
12356                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
12357                         this.containers[innermostIndex].containerCache.over = 1;
12358                 }
12359
12360
12361         },
12362
12363         _createHelper: function(event) {
12364
12365                 var o = this.options;
12366                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
12367
12368                 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
12369                         $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
12370
12371                 if(helper[0] == this.currentItem[0])
12372                         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") };
12373
12374                 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
12375                 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
12376
12377                 return helper;
12378
12379         },
12380
12381         _adjustOffsetFromHelper: function(obj) {
12382                 if (typeof obj == 'string') {
12383                         obj = obj.split(' ');
12384                 }
12385                 if ($.isArray(obj)) {
12386                         obj = {left: +obj[0], top: +obj[1] || 0};
12387                 }
12388                 if ('left' in obj) {
12389                         this.offset.click.left = obj.left + this.margins.left;
12390                 }
12391                 if ('right' in obj) {
12392                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
12393                 }
12394                 if ('top' in obj) {
12395                         this.offset.click.top = obj.top + this.margins.top;
12396                 }
12397                 if ('bottom' in obj) {
12398                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
12399                 }
12400         },
12401
12402         _getParentOffset: function() {
12403
12404
12405                 //Get the offsetParent and cache its position
12406                 this.offsetParent = this.helper.offsetParent();
12407                 var po = this.offsetParent.offset();
12408
12409                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
12410                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
12411                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
12412                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
12413                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
12414                         po.left += this.scrollParent.scrollLeft();
12415                         po.top += this.scrollParent.scrollTop();
12416                 }
12417
12418                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
12419                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
12420                         po = { top: 0, left: 0 };
12421
12422                 return {
12423                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
12424                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
12425                 };
12426
12427         },
12428
12429         _getRelativeOffset: function() {
12430
12431                 if(this.cssPosition == "relative") {
12432                         var p = this.currentItem.position();
12433                         return {
12434                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
12435                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
12436                         };
12437                 } else {
12438                         return { top: 0, left: 0 };
12439                 }
12440
12441         },
12442
12443         _cacheMargins: function() {
12444                 this.margins = {
12445                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
12446                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
12447                 };
12448         },
12449
12450         _cacheHelperProportions: function() {
12451                 this.helperProportions = {
12452                         width: this.helper.outerWidth(),
12453                         height: this.helper.outerHeight()
12454                 };
12455         },
12456
12457         _setContainment: function() {
12458
12459                 var o = this.options;
12460                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
12461                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
12462                         0 - this.offset.relative.left - this.offset.parent.left,
12463                         0 - this.offset.relative.top - this.offset.parent.top,
12464                         $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
12465                         ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
12466                 ];
12467
12468                 if(!(/^(document|window|parent)$/).test(o.containment)) {
12469                         var ce = $(o.containment)[0];
12470                         var co = $(o.containment).offset();
12471                         var over = ($(ce).css("overflow") != 'hidden');
12472
12473                         this.containment = [
12474                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
12475                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
12476                                 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,
12477                                 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
12478                         ];
12479                 }
12480
12481         },
12482
12483         _convertPositionTo: function(d, pos) {
12484
12485                 if(!pos) pos = this.position;
12486                 var mod = d == "absolute" ? 1 : -1;
12487                 var o = this.options, 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);
12488
12489                 return {
12490                         top: (
12491                                 pos.top                                                                                                                                 // The absolute mouse position
12492                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
12493                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
12494                                 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
12495                         ),
12496                         left: (
12497                                 pos.left                                                                                                                                // The absolute mouse position
12498                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
12499                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
12500                                 - ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
12501                         )
12502                 };
12503
12504         },
12505
12506         _generatePosition: function(event) {
12507
12508                 var o = this.options, 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);
12509
12510                 // This is another very weird special case that only happens for relative elements:
12511                 // 1. If the css position is relative
12512                 // 2. and the scroll parent is the document or similar to the offset parent
12513                 // we have to refresh the relative offset during the scroll so there are no jumps
12514                 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
12515                         this.offset.relative = this._getRelativeOffset();
12516                 }
12517
12518                 var pageX = event.pageX;
12519                 var pageY = event.pageY;
12520
12521                 /*
12522                  * - Position constraining -
12523                  * Constrain the position to a mix of grid, containment.
12524                  */
12525
12526                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
12527
12528                         if(this.containment) {
12529                                 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
12530                                 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
12531                                 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
12532                                 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
12533                         }
12534
12535                         if(o.grid) {
12536                                 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
12537                                 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;
12538
12539                                 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
12540                                 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;
12541                         }
12542
12543                 }
12544
12545                 return {
12546                         top: (
12547                                 pageY                                                                                                                           // The absolute mouse position
12548                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
12549                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
12550                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
12551                                 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
12552                         ),
12553                         left: (
12554                                 pageX                                                                                                                           // The absolute mouse position
12555                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
12556                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
12557                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
12558                                 + ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
12559                         )
12560                 };
12561
12562         },
12563
12564         _rearrange: function(event, i, a, hardRefresh) {
12565
12566                 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));
12567
12568                 //Various things done here to improve the performance:
12569                 // 1. we create a setTimeout, that calls refreshPositions
12570                 // 2. on the instance, we have a counter variable, that get's higher after every append
12571                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
12572                 // 4. this lets only the last addition to the timeout stack through
12573                 this.counter = this.counter ? ++this.counter : 1;
12574                 var counter = this.counter;
12575
12576                 this._delay(function() {
12577                         if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
12578                 });
12579
12580         },
12581
12582         _clear: function(event, noPropagation) {
12583
12584                 this.reverting = false;
12585                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
12586                 // everything else normalized again
12587                 var delayedTriggers = [];
12588
12589                 // We first have to update the dom position of the actual currentItem
12590                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
12591                 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
12592                 this._noFinalSort = null;
12593
12594                 if(this.helper[0] == this.currentItem[0]) {
12595                         for(var i in this._storedCSS) {
12596                                 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
12597                         }
12598                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
12599                 } else {
12600                         this.currentItem.show();
12601                 }
12602
12603                 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
12604                 if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
12605
12606                 // Check if the items Container has Changed and trigger appropriate
12607                 // events.
12608                 if (this !== this.currentContainer) {
12609                         if(!noPropagation) {
12610                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
12611                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
12612                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
12613                         }
12614                 }
12615
12616
12617                 //Post events to containers
12618                 for (var i = this.containers.length - 1; i >= 0; i--){
12619                         if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
12620                         if(this.containers[i].containerCache.over) {
12621                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
12622                                 this.containers[i].containerCache.over = 0;
12623                         }
12624                 }
12625
12626                 //Do what was originally in plugins
12627                 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
12628                 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
12629                 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
12630
12631                 this.dragging = false;
12632                 if(this.cancelHelperRemoval) {
12633                         if(!noPropagation) {
12634                                 this._trigger("beforeStop", event, this._uiHash());
12635                                 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
12636                                 this._trigger("stop", event, this._uiHash());
12637                         }
12638
12639                         this.fromOutside = false;
12640                         return false;
12641                 }
12642
12643                 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
12644
12645                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
12646                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
12647
12648                 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
12649
12650                 if(!noPropagation) {
12651                         for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
12652                         this._trigger("stop", event, this._uiHash());
12653                 }
12654
12655                 this.fromOutside = false;
12656                 return true;
12657
12658         },
12659
12660         _trigger: function() {
12661                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
12662                         this.cancel();
12663                 }
12664         },
12665
12666         _uiHash: function(_inst) {
12667                 var inst = _inst || this;
12668                 return {
12669                         helper: inst.helper,
12670                         placeholder: inst.placeholder || $([]),
12671                         position: inst.position,
12672                         originalPosition: inst.originalPosition,
12673                         offset: inst.positionAbs,
12674                         item: inst.currentItem,
12675                         sender: _inst ? _inst.element : null
12676                 };
12677         }
12678
12679 });
12680
12681 })(jQuery);
12682 (function( $ ) {
12683
12684 function modifier( fn ) {
12685         return function() {
12686                 var previous = this.element.val();
12687                 fn.apply( this, arguments );
12688                 this._refresh();
12689                 if ( previous !== this.element.val() ) {
12690                         this._trigger( "change" );
12691                 }
12692         };
12693 }
12694
12695 $.widget( "ui.spinner", {
12696         version: "1.9.2",
12697         defaultElement: "<input>",
12698         widgetEventPrefix: "spin",
12699         options: {
12700                 culture: null,
12701                 icons: {
12702                         down: "ui-icon-triangle-1-s",
12703                         up: "ui-icon-triangle-1-n"
12704                 },
12705                 incremental: true,
12706                 max: null,
12707                 min: null,
12708                 numberFormat: null,
12709                 page: 10,
12710                 step: 1,
12711
12712                 change: null,
12713                 spin: null,
12714                 start: null,
12715                 stop: null
12716         },
12717
12718         _create: function() {
12719                 // handle string values that need to be parsed
12720                 this._setOption( "max", this.options.max );
12721                 this._setOption( "min", this.options.min );
12722                 this._setOption( "step", this.options.step );
12723
12724                 // format the value, but don't constrain
12725                 this._value( this.element.val(), true );
12726
12727                 this._draw();
12728                 this._on( this._events );
12729                 this._refresh();
12730
12731                 // turning off autocomplete prevents the browser from remembering the
12732                 // value when navigating through history, so we re-enable autocomplete
12733                 // if the page is unloaded before the widget is destroyed. #7790
12734                 this._on( this.window, {
12735                         beforeunload: function() {
12736                                 this.element.removeAttr( "autocomplete" );
12737                         }
12738                 });
12739         },
12740
12741         _getCreateOptions: function() {
12742                 var options = {},
12743                         element = this.element;
12744
12745                 $.each( [ "min", "max", "step" ], function( i, option ) {
12746                         var value = element.attr( option );
12747                         if ( value !== undefined && value.length ) {
12748                                 options[ option ] = value;
12749                         }
12750                 });
12751
12752                 return options;
12753         },
12754
12755         _events: {
12756                 keydown: function( event ) {
12757                         if ( this._start( event ) && this._keydown( event ) ) {
12758                                 event.preventDefault();
12759                         }
12760                 },
12761                 keyup: "_stop",
12762                 focus: function() {
12763                         this.previous = this.element.val();
12764                 },
12765                 blur: function( event ) {
12766                         if ( this.cancelBlur ) {
12767                                 delete this.cancelBlur;
12768                                 return;
12769                         }
12770
12771                         this._refresh();
12772                         if ( this.previous !== this.element.val() ) {
12773                                 this._trigger( "change", event );
12774                         }
12775                 },
12776                 mousewheel: function( event, delta ) {
12777                         if ( !delta ) {
12778                                 return;
12779                         }
12780                         if ( !this.spinning && !this._start( event ) ) {
12781                                 return false;
12782                         }
12783
12784                         this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
12785                         clearTimeout( this.mousewheelTimer );
12786                         this.mousewheelTimer = this._delay(function() {
12787                                 if ( this.spinning ) {
12788                                         this._stop( event );
12789                                 }
12790                         }, 100 );
12791                         event.preventDefault();
12792                 },
12793                 "mousedown .ui-spinner-button": function( event ) {
12794                         var previous;
12795
12796                         // We never want the buttons to have focus; whenever the user is
12797                         // interacting with the spinner, the focus should be on the input.
12798                         // If the input is focused then this.previous is properly set from
12799                         // when the input first received focus. If the input is not focused
12800                         // then we need to set this.previous based on the value before spinning.
12801                         previous = this.element[0] === this.document[0].activeElement ?
12802                                 this.previous : this.element.val();
12803                         function checkFocus() {
12804                                 var isActive = this.element[0] === this.document[0].activeElement;
12805                                 if ( !isActive ) {
12806                                         this.element.focus();
12807                                         this.previous = previous;
12808                                         // support: IE
12809                                         // IE sets focus asynchronously, so we need to check if focus
12810                                         // moved off of the input because the user clicked on the button.
12811                                         this._delay(function() {
12812                                                 this.previous = previous;
12813                                         });
12814                                 }
12815                         }
12816
12817                         // ensure focus is on (or stays on) the text field
12818                         event.preventDefault();
12819                         checkFocus.call( this );
12820
12821                         // support: IE
12822                         // IE doesn't prevent moving focus even with event.preventDefault()
12823                         // so we set a flag to know when we should ignore the blur event
12824                         // and check (again) if focus moved off of the input.
12825                         this.cancelBlur = true;
12826                         this._delay(function() {
12827                                 delete this.cancelBlur;
12828                                 checkFocus.call( this );
12829                         });
12830
12831                         if ( this._start( event ) === false ) {
12832                                 return;
12833                         }
12834
12835                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12836                 },
12837                 "mouseup .ui-spinner-button": "_stop",
12838                 "mouseenter .ui-spinner-button": function( event ) {
12839                         // button will add ui-state-active if mouse was down while mouseleave and kept down
12840                         if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
12841                                 return;
12842                         }
12843
12844                         if ( this._start( event ) === false ) {
12845                                 return false;
12846                         }
12847                         this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12848                 },
12849                 // TODO: do we really want to consider this a stop?
12850                 // shouldn't we just stop the repeater and wait until mouseup before
12851                 // we trigger the stop event?
12852                 "mouseleave .ui-spinner-button": "_stop"
12853         },
12854
12855         _draw: function() {
12856                 var uiSpinner = this.uiSpinner = this.element
12857                         .addClass( "ui-spinner-input" )
12858                         .attr( "autocomplete", "off" )
12859                         .wrap( this._uiSpinnerHtml() )
12860                         .parent()
12861                                 // add buttons
12862                                 .append( this._buttonHtml() );
12863
12864                 this.element.attr( "role", "spinbutton" );
12865
12866                 // button bindings
12867                 this.buttons = uiSpinner.find( ".ui-spinner-button" )
12868                         .attr( "tabIndex", -1 )
12869                         .button()
12870                         .removeClass( "ui-corner-all" );
12871
12872                 // IE 6 doesn't understand height: 50% for the buttons
12873                 // unless the wrapper has an explicit height
12874                 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
12875                                 uiSpinner.height() > 0 ) {
12876                         uiSpinner.height( uiSpinner.height() );
12877                 }
12878
12879                 // disable spinner if element was already disabled
12880                 if ( this.options.disabled ) {
12881                         this.disable();
12882                 }
12883         },
12884
12885         _keydown: function( event ) {
12886                 var options = this.options,
12887                         keyCode = $.ui.keyCode;
12888
12889                 switch ( event.keyCode ) {
12890                 case keyCode.UP:
12891                         this._repeat( null, 1, event );
12892                         return true;
12893                 case keyCode.DOWN:
12894                         this._repeat( null, -1, event );
12895                         return true;
12896                 case keyCode.PAGE_UP:
12897                         this._repeat( null, options.page, event );
12898                         return true;
12899                 case keyCode.PAGE_DOWN:
12900                         this._repeat( null, -options.page, event );
12901                         return true;
12902                 }
12903
12904                 return false;
12905         },
12906
12907         _uiSpinnerHtml: function() {
12908                 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
12909         },
12910
12911         _buttonHtml: function() {
12912                 return "" +
12913                         "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
12914                                 "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
12915                         "</a>" +
12916                         "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
12917                                 "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
12918                         "</a>";
12919         },
12920
12921         _start: function( event ) {
12922                 if ( !this.spinning && this._trigger( "start", event ) === false ) {
12923                         return false;
12924                 }
12925
12926                 if ( !this.counter ) {
12927                         this.counter = 1;
12928                 }
12929                 this.spinning = true;
12930                 return true;
12931         },
12932
12933         _repeat: function( i, steps, event ) {
12934                 i = i || 500;
12935
12936                 clearTimeout( this.timer );
12937                 this.timer = this._delay(function() {
12938                         this._repeat( 40, steps, event );
12939                 }, i );
12940
12941                 this._spin( steps * this.options.step, event );
12942         },
12943
12944         _spin: function( step, event ) {
12945                 var value = this.value() || 0;
12946
12947                 if ( !this.counter ) {
12948                         this.counter = 1;
12949                 }
12950
12951                 value = this._adjustValue( value + step * this._increment( this.counter ) );
12952
12953                 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
12954                         this._value( value );
12955                         this.counter++;
12956                 }
12957         },
12958
12959         _increment: function( i ) {
12960                 var incremental = this.options.incremental;
12961
12962                 if ( incremental ) {
12963                         return $.isFunction( incremental ) ?
12964                                 incremental( i ) :
12965                                 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
12966                 }
12967
12968                 return 1;
12969         },
12970
12971         _precision: function() {
12972                 var precision = this._precisionOf( this.options.step );
12973                 if ( this.options.min !== null ) {
12974                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
12975                 }
12976                 return precision;
12977         },
12978
12979         _precisionOf: function( num ) {
12980                 var str = num.toString(),
12981                         decimal = str.indexOf( "." );
12982                 return decimal === -1 ? 0 : str.length - decimal - 1;
12983         },
12984
12985         _adjustValue: function( value ) {
12986                 var base, aboveMin,
12987                         options = this.options;
12988
12989                 // make sure we're at a valid step
12990                 // - find out where we are relative to the base (min or 0)
12991                 base = options.min !== null ? options.min : 0;
12992                 aboveMin = value - base;
12993                 // - round to the nearest step
12994                 aboveMin = Math.round(aboveMin / options.step) * options.step;
12995                 // - rounding is based on 0, so adjust back to our base
12996                 value = base + aboveMin;
12997
12998                 // fix precision from bad JS floating point math
12999                 value = parseFloat( value.toFixed( this._precision() ) );
13000
13001                 // clamp the value
13002                 if ( options.max !== null && value > options.max) {
13003                         return options.max;
13004                 }
13005                 if ( options.min !== null && value < options.min ) {
13006                         return options.min;
13007                 }
13008
13009                 return value;
13010         },
13011
13012         _stop: function( event ) {
13013                 if ( !this.spinning ) {
13014                         return;
13015                 }
13016
13017                 clearTimeout( this.timer );
13018                 clearTimeout( this.mousewheelTimer );
13019                 this.counter = 0;
13020                 this.spinning = false;
13021                 this._trigger( "stop", event );
13022         },
13023
13024         _setOption: function( key, value ) {
13025                 if ( key === "culture" || key === "numberFormat" ) {
13026                         var prevValue = this._parse( this.element.val() );
13027                         this.options[ key ] = value;
13028                         this.element.val( this._format( prevValue ) );
13029                         return;
13030                 }
13031
13032                 if ( key === "max" || key === "min" || key === "step" ) {
13033                         if ( typeof value === "string" ) {
13034                                 value = this._parse( value );
13035                         }
13036                 }
13037
13038                 this._super( key, value );
13039
13040                 if ( key === "disabled" ) {
13041                         if ( value ) {
13042                                 this.element.prop( "disabled", true );
13043                                 this.buttons.button( "disable" );
13044                         } else {
13045                                 this.element.prop( "disabled", false );
13046                                 this.buttons.button( "enable" );
13047                         }
13048                 }
13049         },
13050
13051         _setOptions: modifier(function( options ) {
13052                 this._super( options );
13053                 this._value( this.element.val() );
13054         }),
13055
13056         _parse: function( val ) {
13057                 if ( typeof val === "string" && val !== "" ) {
13058                         val = window.Globalize && this.options.numberFormat ?
13059                                 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13060                 }
13061                 return val === "" || isNaN( val ) ? null : val;
13062         },
13063
13064         _format: function( value ) {
13065                 if ( value === "" ) {
13066                         return "";
13067                 }
13068                 return window.Globalize && this.options.numberFormat ?
13069                         Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13070                         value;
13071         },
13072
13073         _refresh: function() {
13074                 this.element.attr({
13075                         "aria-valuemin": this.options.min,
13076                         "aria-valuemax": this.options.max,
13077                         // TODO: what should we do with values that can't be parsed?
13078                         "aria-valuenow": this._parse( this.element.val() )
13079                 });
13080         },
13081
13082         // update the value without triggering change
13083         _value: function( value, allowAny ) {
13084                 var parsed;
13085                 if ( value !== "" ) {
13086                         parsed = this._parse( value );
13087                         if ( parsed !== null ) {
13088                                 if ( !allowAny ) {
13089                                         parsed = this._adjustValue( parsed );
13090                                 }
13091                                 value = this._format( parsed );
13092                         }
13093                 }
13094                 this.element.val( value );
13095                 this._refresh();
13096         },
13097
13098         _destroy: function() {
13099                 this.element
13100                         .removeClass( "ui-spinner-input" )
13101                         .prop( "disabled", false )
13102                         .removeAttr( "autocomplete" )
13103                         .removeAttr( "role" )
13104                         .removeAttr( "aria-valuemin" )
13105                         .removeAttr( "aria-valuemax" )
13106                         .removeAttr( "aria-valuenow" );
13107                 this.uiSpinner.replaceWith( this.element );
13108         },
13109
13110         stepUp: modifier(function( steps ) {
13111                 this._stepUp( steps );
13112         }),
13113         _stepUp: function( steps ) {
13114                 this._spin( (steps || 1) * this.options.step );
13115         },
13116
13117         stepDown: modifier(function( steps ) {
13118                 this._stepDown( steps );
13119         }),
13120         _stepDown: function( steps ) {
13121                 this._spin( (steps || 1) * -this.options.step );
13122         },
13123
13124         pageUp: modifier(function( pages ) {
13125                 this._stepUp( (pages || 1) * this.options.page );
13126         }),
13127
13128         pageDown: modifier(function( pages ) {
13129                 this._stepDown( (pages || 1) * this.options.page );
13130         }),
13131
13132         value: function( newVal ) {
13133                 if ( !arguments.length ) {
13134                         return this._parse( this.element.val() );
13135                 }
13136                 modifier( this._value ).call( this, newVal );
13137         },
13138
13139         widget: function() {
13140                 return this.uiSpinner;
13141         }
13142 });
13143
13144 }( jQuery ) );
13145 (function( $, undefined ) {
13146
13147 var tabId = 0,
13148         rhash = /#.*$/;
13149
13150 function getNextTabId() {
13151         return ++tabId;
13152 }
13153
13154 function isLocal( anchor ) {
13155         return anchor.hash.length > 1 &&
13156                 anchor.href.replace( rhash, "" ) ===
13157                         location.href.replace( rhash, "" )
13158                                 // support: Safari 5.1
13159                                 // Safari 5.1 doesn't encode spaces in window.location
13160                                 // but it does encode spaces from anchors (#8777)
13161                                 .replace( /\s/g, "%20" );
13162 }
13163
13164 $.widget( "ui.tabs", {
13165         version: "1.9.2",
13166         delay: 300,
13167         options: {
13168                 active: null,
13169                 collapsible: false,
13170                 event: "click",
13171                 heightStyle: "content",
13172                 hide: null,
13173                 show: null,
13174
13175                 // callbacks
13176                 activate: null,
13177                 beforeActivate: null,
13178                 beforeLoad: null,
13179                 load: null
13180         },
13181
13182         _create: function() {
13183                 var that = this,
13184                         options = this.options,
13185                         active = options.active,
13186                         locationHash = location.hash.substring( 1 );
13187
13188                 this.running = false;
13189
13190                 this.element
13191                         .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13192                         .toggleClass( "ui-tabs-collapsible", options.collapsible )
13193                         // Prevent users from focusing disabled tabs via click
13194                         .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13195                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
13196                                         event.preventDefault();
13197                                 }
13198                         })
13199                         // support: IE <9
13200                         // Preventing the default action in mousedown doesn't prevent IE
13201                         // from focusing the element, so if the anchor gets focused, blur.
13202                         // We don't have to worry about focusing the previously focused
13203                         // element since clicking on a non-focusable element should focus
13204                         // the body anyway.
13205                         .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13206                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13207                                         this.blur();
13208                                 }
13209                         });
13210
13211                 this._processTabs();
13212
13213                 if ( active === null ) {
13214                         // check the fragment identifier in the URL
13215                         if ( locationHash ) {
13216                                 this.tabs.each(function( i, tab ) {
13217                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13218                                                 active = i;
13219                                                 return false;
13220                                         }
13221                                 });
13222                         }
13223
13224                         // check for a tab marked active via a class
13225                         if ( active === null ) {
13226                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13227                         }
13228
13229                         // no active tab, set to false
13230                         if ( active === null || active === -1 ) {
13231                                 active = this.tabs.length ? 0 : false;
13232                         }
13233                 }
13234
13235                 // handle numbers: negative, out of range
13236                 if ( active !== false ) {
13237                         active = this.tabs.index( this.tabs.eq( active ) );
13238                         if ( active === -1 ) {
13239                                 active = options.collapsible ? false : 0;
13240                         }
13241                 }
13242                 options.active = active;
13243
13244                 // don't allow collapsible: false and active: false
13245                 if ( !options.collapsible && options.active === false && this.anchors.length ) {
13246                         options.active = 0;
13247                 }
13248
13249                 // Take disabling tabs via class attribute from HTML
13250                 // into account and update option properly.
13251                 if ( $.isArray( options.disabled ) ) {
13252                         options.disabled = $.unique( options.disabled.concat(
13253                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13254                                         return that.tabs.index( li );
13255                                 })
13256                         ) ).sort();
13257                 }
13258
13259                 // check for length avoids error when initializing empty list
13260                 if ( this.options.active !== false && this.anchors.length ) {
13261                         this.active = this._findActive( this.options.active );
13262                 } else {
13263                         this.active = $();
13264                 }
13265
13266                 this._refresh();
13267
13268                 if ( this.active.length ) {
13269                         this.load( options.active );
13270                 }
13271         },
13272
13273         _getCreateEventData: function() {
13274                 return {
13275                         tab: this.active,
13276                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13277                 };
13278         },
13279
13280         _tabKeydown: function( event ) {
13281                 var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13282                         selectedIndex = this.tabs.index( focusedTab ),
13283                         goingForward = true;
13284
13285                 if ( this._handlePageNav( event ) ) {
13286                         return;
13287                 }
13288
13289                 switch ( event.keyCode ) {
13290                         case $.ui.keyCode.RIGHT:
13291                         case $.ui.keyCode.DOWN:
13292                                 selectedIndex++;
13293                                 break;
13294                         case $.ui.keyCode.UP:
13295                         case $.ui.keyCode.LEFT:
13296                                 goingForward = false;
13297                                 selectedIndex--;
13298                                 break;
13299                         case $.ui.keyCode.END:
13300                                 selectedIndex = this.anchors.length - 1;
13301                                 break;
13302                         case $.ui.keyCode.HOME:
13303                                 selectedIndex = 0;
13304                                 break;
13305                         case $.ui.keyCode.SPACE:
13306                                 // Activate only, no collapsing
13307                                 event.preventDefault();
13308                                 clearTimeout( this.activating );
13309                                 this._activate( selectedIndex );
13310                                 return;
13311                         case $.ui.keyCode.ENTER:
13312                                 // Toggle (cancel delayed activation, allow collapsing)
13313                                 event.preventDefault();
13314                                 clearTimeout( this.activating );
13315                                 // Determine if we should collapse or activate
13316                                 this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13317                                 return;
13318                         default:
13319                                 return;
13320                 }
13321
13322                 // Focus the appropriate tab, based on which key was pressed
13323                 event.preventDefault();
13324                 clearTimeout( this.activating );
13325                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13326
13327                 // Navigating with control key will prevent automatic activation
13328                 if ( !event.ctrlKey ) {
13329                         // Update aria-selected immediately so that AT think the tab is already selected.
13330                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
13331                         // but the tab will already be activated by the time the announcement finishes.
13332                         focusedTab.attr( "aria-selected", "false" );
13333                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13334
13335                         this.activating = this._delay(function() {
13336                                 this.option( "active", selectedIndex );
13337                         }, this.delay );
13338                 }
13339         },
13340
13341         _panelKeydown: function( event ) {
13342                 if ( this._handlePageNav( event ) ) {
13343                         return;
13344                 }
13345
13346                 // Ctrl+up moves focus to the current tab
13347                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13348                         event.preventDefault();
13349                         this.active.focus();
13350                 }
13351         },
13352
13353         // Alt+page up/down moves focus to the previous/next tab (and activates)
13354         _handlePageNav: function( event ) {
13355                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13356                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
13357                         return true;
13358                 }
13359                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13360                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
13361                         return true;
13362                 }
13363         },
13364
13365         _findNextTab: function( index, goingForward ) {
13366                 var lastTabIndex = this.tabs.length - 1;
13367
13368                 function constrain() {
13369                         if ( index > lastTabIndex ) {
13370                                 index = 0;
13371                         }
13372                         if ( index < 0 ) {
13373                                 index = lastTabIndex;
13374                         }
13375                         return index;
13376                 }
13377
13378                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
13379                         index = goingForward ? index + 1 : index - 1;
13380                 }
13381
13382                 return index;
13383         },
13384
13385         _focusNextTab: function( index, goingForward ) {
13386                 index = this._findNextTab( index, goingForward );
13387                 this.tabs.eq( index ).focus();
13388                 return index;
13389         },
13390
13391         _setOption: function( key, value ) {
13392                 if ( key === "active" ) {
13393                         // _activate() will handle invalid values and update this.options
13394                         this._activate( value );
13395                         return;
13396                 }
13397
13398                 if ( key === "disabled" ) {
13399                         // don't use the widget factory's disabled handling
13400                         this._setupDisabled( value );
13401                         return;
13402                 }
13403
13404                 this._super( key, value);
13405
13406                 if ( key === "collapsible" ) {
13407                         this.element.toggleClass( "ui-tabs-collapsible", value );
13408                         // Setting collapsible: false while collapsed; open first panel
13409                         if ( !value && this.options.active === false ) {
13410                                 this._activate( 0 );
13411                         }
13412                 }
13413
13414                 if ( key === "event" ) {
13415                         this._setupEvents( value );
13416                 }
13417
13418                 if ( key === "heightStyle" ) {
13419                         this._setupHeightStyle( value );
13420                 }
13421         },
13422
13423         _tabId: function( tab ) {
13424                 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
13425         },
13426
13427         _sanitizeSelector: function( hash ) {
13428                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
13429         },
13430
13431         refresh: function() {
13432                 var options = this.options,
13433                         lis = this.tablist.children( ":has(a[href])" );
13434
13435                 // get disabled tabs from class attribute from HTML
13436                 // this will get converted to a boolean if needed in _refresh()
13437                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
13438                         return lis.index( tab );
13439                 });
13440
13441                 this._processTabs();
13442
13443                 // was collapsed or no tabs
13444                 if ( options.active === false || !this.anchors.length ) {
13445                         options.active = false;
13446                         this.active = $();
13447                 // was active, but active tab is gone
13448                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
13449                         // all remaining tabs are disabled
13450                         if ( this.tabs.length === options.disabled.length ) {
13451                                 options.active = false;
13452                                 this.active = $();
13453                         // activate previous tab
13454                         } else {
13455                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
13456                         }
13457                 // was active, active tab still exists
13458                 } else {
13459                         // make sure active index is correct
13460                         options.active = this.tabs.index( this.active );
13461                 }
13462
13463                 this._refresh();
13464         },
13465
13466         _refresh: function() {
13467                 this._setupDisabled( this.options.disabled );
13468                 this._setupEvents( this.options.event );
13469                 this._setupHeightStyle( this.options.heightStyle );
13470
13471                 this.tabs.not( this.active ).attr({
13472                         "aria-selected": "false",
13473                         tabIndex: -1
13474                 });
13475                 this.panels.not( this._getPanelForTab( this.active ) )
13476                         .hide()
13477                         .attr({
13478                                 "aria-expanded": "false",
13479                                 "aria-hidden": "true"
13480                         });
13481
13482                 // Make sure one tab is in the tab order
13483                 if ( !this.active.length ) {
13484                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
13485                 } else {
13486                         this.active
13487                                 .addClass( "ui-tabs-active ui-state-active" )
13488                                 .attr({
13489                                         "aria-selected": "true",
13490                                         tabIndex: 0
13491                                 });
13492                         this._getPanelForTab( this.active )
13493                                 .show()
13494                                 .attr({
13495                                         "aria-expanded": "true",
13496                                         "aria-hidden": "false"
13497                                 });
13498                 }
13499         },
13500
13501         _processTabs: function() {
13502                 var that = this;
13503
13504                 this.tablist = this._getList()
13505                         .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13506                         .attr( "role", "tablist" );
13507
13508                 this.tabs = this.tablist.find( "> li:has(a[href])" )
13509                         .addClass( "ui-state-default ui-corner-top" )
13510                         .attr({
13511                                 role: "tab",
13512                                 tabIndex: -1
13513                         });
13514
13515                 this.anchors = this.tabs.map(function() {
13516                                 return $( "a", this )[ 0 ];
13517                         })
13518                         .addClass( "ui-tabs-anchor" )
13519                         .attr({
13520                                 role: "presentation",
13521                                 tabIndex: -1
13522                         });
13523
13524                 this.panels = $();
13525
13526                 this.anchors.each(function( i, anchor ) {
13527                         var selector, panel, panelId,
13528                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
13529                                 tab = $( anchor ).closest( "li" ),
13530                                 originalAriaControls = tab.attr( "aria-controls" );
13531
13532                         // inline tab
13533                         if ( isLocal( anchor ) ) {
13534                                 selector = anchor.hash;
13535                                 panel = that.element.find( that._sanitizeSelector( selector ) );
13536                         // remote tab
13537                         } else {
13538                                 panelId = that._tabId( tab );
13539                                 selector = "#" + panelId;
13540                                 panel = that.element.find( selector );
13541                                 if ( !panel.length ) {
13542                                         panel = that._createPanel( panelId );
13543                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
13544                                 }
13545                                 panel.attr( "aria-live", "polite" );
13546                         }
13547
13548                         if ( panel.length) {
13549                                 that.panels = that.panels.add( panel );
13550                         }
13551                         if ( originalAriaControls ) {
13552                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
13553                         }
13554                         tab.attr({
13555                                 "aria-controls": selector.substring( 1 ),
13556                                 "aria-labelledby": anchorId
13557                         });
13558                         panel.attr( "aria-labelledby", anchorId );
13559                 });
13560
13561                 this.panels
13562                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13563                         .attr( "role", "tabpanel" );
13564         },
13565
13566         // allow overriding how to find the list for rare usage scenarios (#7715)
13567         _getList: function() {
13568                 return this.element.find( "ol,ul" ).eq( 0 );
13569         },
13570
13571         _createPanel: function( id ) {
13572                 return $( "<div>" )
13573                         .attr( "id", id )
13574                         .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13575                         .data( "ui-tabs-destroy", true );
13576         },
13577
13578         _setupDisabled: function( disabled ) {
13579                 if ( $.isArray( disabled ) ) {
13580                         if ( !disabled.length ) {
13581                                 disabled = false;
13582                         } else if ( disabled.length === this.anchors.length ) {
13583                                 disabled = true;
13584                         }
13585                 }
13586
13587                 // disable tabs
13588                 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
13589                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
13590                                 $( li )
13591                                         .addClass( "ui-state-disabled" )
13592                                         .attr( "aria-disabled", "true" );
13593                         } else {
13594                                 $( li )
13595                                         .removeClass( "ui-state-disabled" )
13596                                         .removeAttr( "aria-disabled" );
13597                         }
13598                 }
13599
13600                 this.options.disabled = disabled;
13601         },
13602
13603         _setupEvents: function( event ) {
13604                 var events = {
13605                         click: function( event ) {
13606                                 event.preventDefault();
13607                         }
13608                 };
13609                 if ( event ) {
13610                         $.each( event.split(" "), function( index, eventName ) {
13611                                 events[ eventName ] = "_eventHandler";
13612                         });
13613                 }
13614
13615                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
13616                 this._on( this.anchors, events );
13617                 this._on( this.tabs, { keydown: "_tabKeydown" } );
13618                 this._on( this.panels, { keydown: "_panelKeydown" } );
13619
13620                 this._focusable( this.tabs );
13621                 this._hoverable( this.tabs );
13622         },
13623
13624         _setupHeightStyle: function( heightStyle ) {
13625                 var maxHeight, overflow,
13626                         parent = this.element.parent();
13627
13628                 if ( heightStyle === "fill" ) {
13629                         // IE 6 treats height like minHeight, so we need to turn off overflow
13630                         // in order to get a reliable height
13631                         // we use the minHeight support test because we assume that only
13632                         // browsers that don't support minHeight will treat height as minHeight
13633                         if ( !$.support.minHeight ) {
13634                                 overflow = parent.css( "overflow" );
13635                                 parent.css( "overflow", "hidden");
13636                         }
13637                         maxHeight = parent.height();
13638                         this.element.siblings( ":visible" ).each(function() {
13639                                 var elem = $( this ),
13640                                         position = elem.css( "position" );
13641
13642                                 if ( position === "absolute" || position === "fixed" ) {
13643                                         return;
13644                                 }
13645                                 maxHeight -= elem.outerHeight( true );
13646                         });
13647                         if ( overflow ) {
13648                                 parent.css( "overflow", overflow );
13649                         }
13650
13651                         this.element.children().not( this.panels ).each(function() {
13652                                 maxHeight -= $( this ).outerHeight( true );
13653                         });
13654
13655                         this.panels.each(function() {
13656                                 $( this ).height( Math.max( 0, maxHeight -
13657                                         $( this ).innerHeight() + $( this ).height() ) );
13658                         })
13659                         .css( "overflow", "auto" );
13660                 } else if ( heightStyle === "auto" ) {
13661                         maxHeight = 0;
13662                         this.panels.each(function() {
13663                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
13664                         }).height( maxHeight );
13665                 }
13666         },
13667
13668         _eventHandler: function( event ) {
13669                 var options = this.options,
13670                         active = this.active,
13671                         anchor = $( event.currentTarget ),
13672                         tab = anchor.closest( "li" ),
13673                         clickedIsActive = tab[ 0 ] === active[ 0 ],
13674                         collapsing = clickedIsActive && options.collapsible,
13675                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
13676                         toHide = !active.length ? $() : this._getPanelForTab( active ),
13677                         eventData = {
13678                                 oldTab: active,
13679                                 oldPanel: toHide,
13680                                 newTab: collapsing ? $() : tab,
13681                                 newPanel: toShow
13682                         };
13683
13684                 event.preventDefault();
13685
13686                 if ( tab.hasClass( "ui-state-disabled" ) ||
13687                                 // tab is already loading
13688                                 tab.hasClass( "ui-tabs-loading" ) ||
13689                                 // can't switch durning an animation
13690                                 this.running ||
13691                                 // click on active header, but not collapsible
13692                                 ( clickedIsActive && !options.collapsible ) ||
13693                                 // allow canceling activation
13694                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
13695                         return;
13696                 }
13697
13698                 options.active = collapsing ? false : this.tabs.index( tab );
13699
13700                 this.active = clickedIsActive ? $() : tab;
13701                 if ( this.xhr ) {
13702                         this.xhr.abort();
13703                 }
13704
13705                 if ( !toHide.length && !toShow.length ) {
13706                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
13707                 }
13708
13709                 if ( toShow.length ) {
13710                         this.load( this.tabs.index( tab ), event );
13711                 }
13712                 this._toggle( event, eventData );
13713         },
13714
13715         // handles show/hide for selecting tabs
13716         _toggle: function( event, eventData ) {
13717                 var that = this,
13718                         toShow = eventData.newPanel,
13719                         toHide = eventData.oldPanel;
13720
13721                 this.running = true;
13722
13723                 function complete() {
13724                         that.running = false;
13725                         that._trigger( "activate", event, eventData );
13726                 }
13727
13728                 function show() {
13729                         eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
13730
13731                         if ( toShow.length && that.options.show ) {
13732                                 that._show( toShow, that.options.show, complete );
13733                         } else {
13734                                 toShow.show();
13735                                 complete();
13736                         }
13737                 }
13738
13739                 // start out by hiding, then showing, then completing
13740                 if ( toHide.length && this.options.hide ) {
13741                         this._hide( toHide, this.options.hide, function() {
13742                                 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13743                                 show();
13744                         });
13745                 } else {
13746                         eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13747                         toHide.hide();
13748                         show();
13749                 }
13750
13751                 toHide.attr({
13752                         "aria-expanded": "false",
13753                         "aria-hidden": "true"
13754                 });
13755                 eventData.oldTab.attr( "aria-selected", "false" );
13756                 // If we're switching tabs, remove the old tab from the tab order.
13757                 // If we're opening from collapsed state, remove the previous tab from the tab order.
13758                 // If we're collapsing, then keep the collapsing tab in the tab order.
13759                 if ( toShow.length && toHide.length ) {
13760                         eventData.oldTab.attr( "tabIndex", -1 );
13761                 } else if ( toShow.length ) {
13762                         this.tabs.filter(function() {
13763                                 return $( this ).attr( "tabIndex" ) === 0;
13764                         })
13765                         .attr( "tabIndex", -1 );
13766                 }
13767
13768                 toShow.attr({
13769                         "aria-expanded": "true",
13770                         "aria-hidden": "false"
13771                 });
13772                 eventData.newTab.attr({
13773                         "aria-selected": "true",
13774                         tabIndex: 0
13775                 });
13776         },
13777
13778         _activate: function( index ) {
13779                 var anchor,
13780                         active = this._findActive( index );
13781
13782                 // trying to activate the already active panel
13783                 if ( active[ 0 ] === this.active[ 0 ] ) {
13784                         return;
13785                 }
13786
13787                 // trying to collapse, simulate a click on the current active header
13788                 if ( !active.length ) {
13789                         active = this.active;
13790                 }
13791
13792                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
13793                 this._eventHandler({
13794                         target: anchor,
13795                         currentTarget: anchor,
13796                         preventDefault: $.noop
13797                 });
13798         },
13799
13800         _findActive: function( index ) {
13801                 return index === false ? $() : this.tabs.eq( index );
13802         },
13803
13804         _getIndex: function( index ) {
13805                 // meta-function to give users option to provide a href string instead of a numerical index.
13806                 if ( typeof index === "string" ) {
13807                         index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
13808                 }
13809
13810                 return index;
13811         },
13812
13813         _destroy: function() {
13814                 if ( this.xhr ) {
13815                         this.xhr.abort();
13816                 }
13817
13818                 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
13819
13820                 this.tablist
13821                         .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13822                         .removeAttr( "role" );
13823
13824                 this.anchors
13825                         .removeClass( "ui-tabs-anchor" )
13826                         .removeAttr( "role" )
13827                         .removeAttr( "tabIndex" )
13828                         .removeData( "href.tabs" )
13829                         .removeData( "load.tabs" )
13830                         .removeUniqueId();
13831
13832                 this.tabs.add( this.panels ).each(function() {
13833                         if ( $.data( this, "ui-tabs-destroy" ) ) {
13834                                 $( this ).remove();
13835                         } else {
13836                                 $( this )
13837                                         .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
13838                                                 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
13839                                         .removeAttr( "tabIndex" )
13840                                         .removeAttr( "aria-live" )
13841                                         .removeAttr( "aria-busy" )
13842                                         .removeAttr( "aria-selected" )
13843                                         .removeAttr( "aria-labelledby" )
13844                                         .removeAttr( "aria-hidden" )
13845                                         .removeAttr( "aria-expanded" )
13846                                         .removeAttr( "role" );
13847                         }
13848                 });
13849
13850                 this.tabs.each(function() {
13851                         var li = $( this ),
13852                                 prev = li.data( "ui-tabs-aria-controls" );
13853                         if ( prev ) {
13854                                 li.attr( "aria-controls", prev );
13855                         } else {
13856                                 li.removeAttr( "aria-controls" );
13857                         }
13858                 });
13859
13860                 this.panels.show();
13861
13862                 if ( this.options.heightStyle !== "content" ) {
13863                         this.panels.css( "height", "" );
13864                 }
13865         },
13866
13867         enable: function( index ) {
13868                 var disabled = this.options.disabled;
13869                 if ( disabled === false ) {
13870                         return;
13871                 }
13872
13873                 if ( index === undefined ) {
13874                         disabled = false;
13875                 } else {
13876                         index = this._getIndex( index );
13877                         if ( $.isArray( disabled ) ) {
13878                                 disabled = $.map( disabled, function( num ) {
13879                                         return num !== index ? num : null;
13880                                 });
13881                         } else {
13882                                 disabled = $.map( this.tabs, function( li, num ) {
13883                                         return num !== index ? num : null;
13884                                 });
13885                         }
13886                 }
13887                 this._setupDisabled( disabled );
13888         },
13889
13890         disable: function( index ) {
13891                 var disabled = this.options.disabled;
13892                 if ( disabled === true ) {
13893                         return;
13894                 }
13895
13896                 if ( index === undefined ) {
13897                         disabled = true;
13898                 } else {
13899                         index = this._getIndex( index );
13900                         if ( $.inArray( index, disabled ) !== -1 ) {
13901                                 return;
13902                         }
13903                         if ( $.isArray( disabled ) ) {
13904                                 disabled = $.merge( [ index ], disabled ).sort();
13905                         } else {
13906                                 disabled = [ index ];
13907                         }
13908                 }
13909                 this._setupDisabled( disabled );
13910         },
13911
13912         load: function( index, event ) {
13913                 index = this._getIndex( index );
13914                 var that = this,
13915                         tab = this.tabs.eq( index ),
13916                         anchor = tab.find( ".ui-tabs-anchor" ),
13917                         panel = this._getPanelForTab( tab ),
13918                         eventData = {
13919                                 tab: tab,
13920                                 panel: panel
13921                         };
13922
13923                 // not remote
13924                 if ( isLocal( anchor[ 0 ] ) ) {
13925                         return;
13926                 }
13927
13928                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
13929
13930                 // support: jQuery <1.8
13931                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
13932                 // but as of 1.8, $.ajax() always returns a jqXHR object.
13933                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
13934                         tab.addClass( "ui-tabs-loading" );
13935                         panel.attr( "aria-busy", "true" );
13936
13937                         this.xhr
13938                                 .success(function( response ) {
13939                                         // support: jQuery <1.8
13940                                         // http://bugs.jquery.com/ticket/11778
13941                                         setTimeout(function() {
13942                                                 panel.html( response );
13943                                                 that._trigger( "load", event, eventData );
13944                                         }, 1 );
13945                                 })
13946                                 .complete(function( jqXHR, status ) {
13947                                         // support: jQuery <1.8
13948                                         // http://bugs.jquery.com/ticket/11778
13949                                         setTimeout(function() {
13950                                                 if ( status === "abort" ) {
13951                                                         that.panels.stop( false, true );
13952                                                 }
13953
13954                                                 tab.removeClass( "ui-tabs-loading" );
13955                                                 panel.removeAttr( "aria-busy" );
13956
13957                                                 if ( jqXHR === that.xhr ) {
13958                                                         delete that.xhr;
13959                                                 }
13960                                         }, 1 );
13961                                 });
13962                 }
13963         },
13964
13965         // TODO: Remove this function in 1.10 when ajaxOptions is removed
13966         _ajaxSettings: function( anchor, event, eventData ) {
13967                 var that = this;
13968                 return {
13969                         url: anchor.attr( "href" ),
13970                         beforeSend: function( jqXHR, settings ) {
13971                                 return that._trigger( "beforeLoad", event,
13972                                         $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
13973                         }
13974                 };
13975         },
13976
13977         _getPanelForTab: function( tab ) {
13978                 var id = $( tab ).attr( "aria-controls" );
13979                 return this.element.find( this._sanitizeSelector( "#" + id ) );
13980         }
13981 });
13982
13983 // DEPRECATED
13984 if ( $.uiBackCompat !== false ) {
13985
13986         // helper method for a lot of the back compat extensions
13987         $.ui.tabs.prototype._ui = function( tab, panel ) {
13988                 return {
13989                         tab: tab,
13990                         panel: panel,
13991                         index: this.anchors.index( tab )
13992                 };
13993         };
13994
13995         // url method
13996         $.widget( "ui.tabs", $.ui.tabs, {
13997                 url: function( index, url ) {
13998                         this.anchors.eq( index ).attr( "href", url );
13999                 }
14000         });
14001
14002         // TODO: Remove _ajaxSettings() method when removing this extension
14003         // ajaxOptions and cache options
14004         $.widget( "ui.tabs", $.ui.tabs, {
14005                 options: {
14006                         ajaxOptions: null,
14007                         cache: false
14008                 },
14009
14010                 _create: function() {
14011                         this._super();
14012
14013                         var that = this;
14014
14015                         this._on({ tabsbeforeload: function( event, ui ) {
14016                                 // tab is already cached
14017                                 if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
14018                                         event.preventDefault();
14019                                         return;
14020                                 }
14021
14022                                 ui.jqXHR.success(function() {
14023                                         if ( that.options.cache ) {
14024                                                 $.data( ui.tab[ 0 ], "cache.tabs", true );
14025                                         }
14026                                 });
14027                         }});
14028                 },
14029
14030                 _ajaxSettings: function( anchor, event, ui ) {
14031                         var ajaxOptions = this.options.ajaxOptions;
14032                         return $.extend( {}, ajaxOptions, {
14033                                 error: function( xhr, status ) {
14034                                         try {
14035                                                 // Passing index avoid a race condition when this method is
14036                                                 // called after the user has selected another tab.
14037                                                 // Pass the anchor that initiated this request allows
14038                                                 // loadError to manipulate the tab content panel via $(a.hash)
14039                                                 ajaxOptions.error(
14040                                                         xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
14041                                         }
14042                                         catch ( error ) {}
14043                                 }
14044                         }, this._superApply( arguments ) );
14045                 },
14046
14047                 _setOption: function( key, value ) {
14048                         // reset cache if switching from cached to not cached
14049                         if ( key === "cache" && value === false ) {
14050                                 this.anchors.removeData( "cache.tabs" );
14051                         }
14052                         this._super( key, value );
14053                 },
14054
14055                 _destroy: function() {
14056                         this.anchors.removeData( "cache.tabs" );
14057                         this._super();
14058                 },
14059
14060                 url: function( index ){
14061                         this.anchors.eq( index ).removeData( "cache.tabs" );
14062                         this._superApply( arguments );
14063                 }
14064         });
14065
14066         // abort method
14067         $.widget( "ui.tabs", $.ui.tabs, {
14068                 abort: function() {
14069                         if ( this.xhr ) {
14070                                 this.xhr.abort();
14071                         }
14072                 }
14073         });
14074
14075         // spinner
14076         $.widget( "ui.tabs", $.ui.tabs, {
14077                 options: {
14078                         spinner: "<em>Loading&#8230;</em>"
14079                 },
14080                 _create: function() {
14081                         this._super();
14082                         this._on({
14083                                 tabsbeforeload: function( event, ui ) {
14084                                         // Don't react to nested tabs or tabs that don't use a spinner
14085                                         if ( event.target !== this.element[ 0 ] ||
14086                                                         !this.options.spinner ) {
14087                                                 return;
14088                                         }
14089
14090                                         var span = ui.tab.find( "span" ),
14091                                                 html = span.html();
14092                                         span.html( this.options.spinner );
14093                                         ui.jqXHR.complete(function() {
14094                                                 span.html( html );
14095                                         });
14096                                 }
14097                         });
14098                 }
14099         });
14100
14101         // enable/disable events
14102         $.widget( "ui.tabs", $.ui.tabs, {
14103                 options: {
14104                         enable: null,
14105                         disable: null
14106                 },
14107
14108                 enable: function( index ) {
14109                         var options = this.options,
14110                                 trigger;
14111
14112                         if ( index && options.disabled === true ||
14113                                         ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
14114                                 trigger = true;
14115                         }
14116
14117                         this._superApply( arguments );
14118
14119                         if ( trigger ) {
14120                                 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14121                         }
14122                 },
14123
14124                 disable: function( index ) {
14125                         var options = this.options,
14126                                 trigger;
14127
14128                         if ( index && options.disabled === false ||
14129                                         ( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
14130                                 trigger = true;
14131                         }
14132
14133                         this._superApply( arguments );
14134
14135                         if ( trigger ) {
14136                                 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14137                         }
14138                 }
14139         });
14140
14141         // add/remove methods and events
14142         $.widget( "ui.tabs", $.ui.tabs, {
14143                 options: {
14144                         add: null,
14145                         remove: null,
14146                         tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
14147                 },
14148
14149                 add: function( url, label, index ) {
14150                         if ( index === undefined ) {
14151                                 index = this.anchors.length;
14152                         }
14153
14154                         var doInsertAfter, panel,
14155                                 options = this.options,
14156                                 li = $( options.tabTemplate
14157                                         .replace( /#\{href\}/g, url )
14158                                         .replace( /#\{label\}/g, label ) ),
14159                                 id = !url.indexOf( "#" ) ?
14160                                         url.replace( "#", "" ) :
14161                                         this._tabId( li );
14162
14163                         li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
14164                         li.attr( "aria-controls", id );
14165
14166                         doInsertAfter = index >= this.tabs.length;
14167
14168                         // try to find an existing element before creating a new one
14169                         panel = this.element.find( "#" + id );
14170                         if ( !panel.length ) {
14171                                 panel = this._createPanel( id );
14172                                 if ( doInsertAfter ) {
14173                                         if ( index > 0 ) {
14174                                                 panel.insertAfter( this.panels.eq( -1 ) );
14175                                         } else {
14176                                                 panel.appendTo( this.element );
14177                                         }
14178                                 } else {
14179                                         panel.insertBefore( this.panels[ index ] );
14180                                 }
14181                         }
14182                         panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
14183
14184                         if ( doInsertAfter ) {
14185                                 li.appendTo( this.tablist );
14186                         } else {
14187                                 li.insertBefore( this.tabs[ index ] );
14188                         }
14189
14190                         options.disabled = $.map( options.disabled, function( n ) {
14191                                 return n >= index ? ++n : n;
14192                         });
14193
14194                         this.refresh();
14195                         if ( this.tabs.length === 1 && options.active === false ) {
14196                                 this.option( "active", 0 );
14197                         }
14198
14199                         this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14200                         return this;
14201                 },
14202
14203                 remove: function( index ) {
14204                         index = this._getIndex( index );
14205                         var options = this.options,
14206                                 tab = this.tabs.eq( index ).remove(),
14207                                 panel = this._getPanelForTab( tab ).remove();
14208
14209                         // If selected tab was removed focus tab to the right or
14210                         // in case the last tab was removed the tab to the left.
14211                         // We check for more than 2 tabs, because if there are only 2,
14212                         // then when we remove this tab, there will only be one tab left
14213                         // so we don't need to detect which tab to activate.
14214                         if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
14215                                 this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
14216                         }
14217
14218                         options.disabled = $.map(
14219                                 $.grep( options.disabled, function( n ) {
14220                                         return n !== index;
14221                                 }),
14222                                 function( n ) {
14223                                         return n >= index ? --n : n;
14224                                 });
14225
14226                         this.refresh();
14227
14228                         this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
14229                         return this;
14230                 }
14231         });
14232
14233         // length method
14234         $.widget( "ui.tabs", $.ui.tabs, {
14235                 length: function() {
14236                         return this.anchors.length;
14237                 }
14238         });
14239
14240         // panel ids (idPrefix option + title attribute)
14241         $.widget( "ui.tabs", $.ui.tabs, {
14242                 options: {
14243                         idPrefix: "ui-tabs-"
14244                 },
14245
14246                 _tabId: function( tab ) {
14247                         var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
14248                         a = a[0];
14249                         return $( a ).closest( "li" ).attr( "aria-controls" ) ||
14250                                 a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
14251                                 this.options.idPrefix + getNextTabId();
14252                 }
14253         });
14254
14255         // _createPanel method
14256         $.widget( "ui.tabs", $.ui.tabs, {
14257                 options: {
14258                         panelTemplate: "<div></div>"
14259                 },
14260
14261                 _createPanel: function( id ) {
14262                         return $( this.options.panelTemplate )
14263                                 .attr( "id", id )
14264                                 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14265                                 .data( "ui-tabs-destroy", true );
14266                 }
14267         });
14268
14269         // selected option
14270         $.widget( "ui.tabs", $.ui.tabs, {
14271                 _create: function() {
14272                         var options = this.options;
14273                         if ( options.active === null && options.selected !== undefined ) {
14274                                 options.active = options.selected === -1 ? false : options.selected;
14275                         }
14276                         this._super();
14277                         options.selected = options.active;
14278                         if ( options.selected === false ) {
14279                                 options.selected = -1;
14280                         }
14281                 },
14282
14283                 _setOption: function( key, value ) {
14284                         if ( key !== "selected" ) {
14285                                 return this._super( key, value );
14286                         }
14287
14288                         var options = this.options;
14289                         this._super( "active", value === -1 ? false : value );
14290                         options.selected = options.active;
14291                         if ( options.selected === false ) {
14292                                 options.selected = -1;
14293                         }
14294                 },
14295
14296                 _eventHandler: function() {
14297                         this._superApply( arguments );
14298                         this.options.selected = this.options.active;
14299                         if ( this.options.selected === false ) {
14300                                 this.options.selected = -1;
14301                         }
14302                 }
14303         });
14304
14305         // show and select event
14306         $.widget( "ui.tabs", $.ui.tabs, {
14307                 options: {
14308                         show: null,
14309                         select: null
14310                 },
14311                 _create: function() {
14312                         this._super();
14313                         if ( this.options.active !== false ) {
14314                                 this._trigger( "show", null, this._ui(
14315                                         this.active.find( ".ui-tabs-anchor" )[ 0 ],
14316                                         this._getPanelForTab( this.active )[ 0 ] ) );
14317                         }
14318                 },
14319                 _trigger: function( type, event, data ) {
14320                         var tab, panel,
14321                                 ret = this._superApply( arguments );
14322
14323                         if ( !ret ) {
14324                                 return false;
14325                         }
14326
14327                         if ( type === "beforeActivate" ) {
14328                                 tab = data.newTab.length ? data.newTab : data.oldTab;
14329                                 panel = data.newPanel.length ? data.newPanel : data.oldPanel;
14330                                 ret = this._super( "select", event, {
14331                                         tab: tab.find( ".ui-tabs-anchor" )[ 0],
14332                                         panel: panel[ 0 ],
14333                                         index: tab.closest( "li" ).index()
14334                                 });
14335                         } else if ( type === "activate" && data.newTab.length ) {
14336                                 ret = this._super( "show", event, {
14337                                         tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
14338                                         panel: data.newPanel[ 0 ],
14339                                         index: data.newTab.closest( "li" ).index()
14340                                 });
14341                         }
14342                         return ret;
14343                 }
14344         });
14345
14346         // select method
14347         $.widget( "ui.tabs", $.ui.tabs, {
14348                 select: function( index ) {
14349                         index = this._getIndex( index );
14350                         if ( index === -1 ) {
14351                                 if ( this.options.collapsible && this.options.selected !== -1 ) {
14352                                         index = this.options.selected;
14353                                 } else {
14354                                         return;
14355                                 }
14356                         }
14357                         this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
14358                 }
14359         });
14360
14361         // cookie option
14362         (function() {
14363
14364         var listId = 0;
14365
14366         $.widget( "ui.tabs", $.ui.tabs, {
14367                 options: {
14368                         cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
14369                 },
14370                 _create: function() {
14371                         var options = this.options,
14372                                 active;
14373                         if ( options.active == null && options.cookie ) {
14374                                 active = parseInt( this._cookie(), 10 );
14375                                 if ( active === -1 ) {
14376                                         active = false;
14377                                 }
14378                                 options.active = active;
14379                         }
14380                         this._super();
14381                 },
14382                 _cookie: function( active ) {
14383                         var cookie = [ this.cookie ||
14384                                 ( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
14385                         if ( arguments.length ) {
14386                                 cookie.push( active === false ? -1 : active );
14387                                 cookie.push( this.options.cookie );
14388                         }
14389                         return $.cookie.apply( null, cookie );
14390                 },
14391                 _refresh: function() {
14392                         this._super();
14393                         if ( this.options.cookie ) {
14394                                 this._cookie( this.options.active, this.options.cookie );
14395                         }
14396                 },
14397                 _eventHandler: function() {
14398                         this._superApply( arguments );
14399                         if ( this.options.cookie ) {
14400                                 this._cookie( this.options.active, this.options.cookie );
14401                         }
14402                 },
14403                 _destroy: function() {
14404                         this._super();
14405                         if ( this.options.cookie ) {
14406                                 this._cookie( null, this.options.cookie );
14407                         }
14408                 }
14409         });
14410
14411         })();
14412
14413         // load event
14414         $.widget( "ui.tabs", $.ui.tabs, {
14415                 _trigger: function( type, event, data ) {
14416                         var _data = $.extend( {}, data );
14417                         if ( type === "load" ) {
14418                                 _data.panel = _data.panel[ 0 ];
14419                                 _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
14420                         }
14421                         return this._super( type, event, _data );
14422                 }
14423         });
14424
14425         // fx option
14426         // The new animation options (show, hide) conflict with the old show callback.
14427         // The old fx option wins over show/hide anyway (always favor back-compat).
14428         // If a user wants to use the new animation API, they must give up the old API.
14429         $.widget( "ui.tabs", $.ui.tabs, {
14430                 options: {
14431                         fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
14432                 },
14433
14434                 _getFx: function() {
14435                         var hide, show,
14436                                 fx = this.options.fx;
14437
14438                         if ( fx ) {
14439                                 if ( $.isArray( fx ) ) {
14440                                         hide = fx[ 0 ];
14441                                         show = fx[ 1 ];
14442                                 } else {
14443                                         hide = show = fx;
14444                                 }
14445                         }
14446
14447                         return fx ? { show: show, hide: hide } : null;
14448                 },
14449
14450                 _toggle: function( event, eventData ) {
14451                         var that = this,
14452                                 toShow = eventData.newPanel,
14453                                 toHide = eventData.oldPanel,
14454                                 fx = this._getFx();
14455
14456                         if ( !fx ) {
14457                                 return this._super( event, eventData );
14458                         }
14459
14460                         that.running = true;
14461
14462                         function complete() {
14463                                 that.running = false;
14464                                 that._trigger( "activate", event, eventData );
14465                         }
14466
14467                         function show() {
14468                                 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14469
14470                                 if ( toShow.length && fx.show ) {
14471                                         toShow
14472                                                 .animate( fx.show, fx.show.duration, function() {
14473                                                         complete();
14474                                                 });
14475                                 } else {
14476                                         toShow.show();
14477                                         complete();
14478                                 }
14479                         }
14480
14481                         // start out by hiding, then showing, then completing
14482                         if ( toHide.length && fx.hide ) {
14483                                 toHide.animate( fx.hide, fx.hide.duration, function() {
14484                                         eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14485                                         show();
14486                                 });
14487                         } else {
14488                                 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14489                                 toHide.hide();
14490                                 show();
14491                         }
14492                 }
14493         });
14494 }
14495
14496 })( jQuery );
14497 (function( $ ) {
14498
14499 var increments = 0;
14500
14501 function addDescribedBy( elem, id ) {
14502         var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14503         describedby.push( id );
14504         elem
14505                 .data( "ui-tooltip-id", id )
14506                 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14507 }
14508
14509 function removeDescribedBy( elem ) {
14510         var id = elem.data( "ui-tooltip-id" ),
14511                 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14512                 index = $.inArray( id, describedby );
14513         if ( index !== -1 ) {
14514                 describedby.splice( index, 1 );
14515         }
14516
14517         elem.removeData( "ui-tooltip-id" );
14518         describedby = $.trim( describedby.join( " " ) );
14519         if ( describedby ) {
14520                 elem.attr( "aria-describedby", describedby );
14521         } else {
14522                 elem.removeAttr( "aria-describedby" );
14523         }
14524 }
14525
14526 $.widget( "ui.tooltip", {
14527         version: "1.9.2",
14528         options: {
14529                 content: function() {
14530                         return $( this ).attr( "title" );
14531                 },
14532                 hide: true,
14533                 // Disabled elements have inconsistent behavior across browsers (#8661)
14534                 items: "[title]:not([disabled])",
14535                 position: {
14536                         my: "left top+15",
14537                         at: "left bottom",
14538                         collision: "flipfit flip"
14539                 },
14540                 show: true,
14541                 tooltipClass: null,
14542                 track: false,
14543
14544                 // callbacks
14545                 close: null,
14546                 open: null
14547         },
14548
14549         _create: function() {
14550                 this._on({
14551                         mouseover: "open",
14552                         focusin: "open"
14553                 });
14554
14555                 // IDs of generated tooltips, needed for destroy
14556                 this.tooltips = {};
14557                 // IDs of parent tooltips where we removed the title attribute
14558                 this.parents = {};
14559
14560                 if ( this.options.disabled ) {
14561                         this._disable();
14562                 }
14563         },
14564
14565         _setOption: function( key, value ) {
14566                 var that = this;
14567
14568                 if ( key === "disabled" ) {
14569                         this[ value ? "_disable" : "_enable" ]();
14570                         this.options[ key ] = value;
14571                         // disable element style changes
14572                         return;
14573                 }
14574
14575                 this._super( key, value );
14576
14577                 if ( key === "content" ) {
14578                         $.each( this.tooltips, function( id, element ) {
14579                                 that._updateContent( element );
14580                         });
14581                 }
14582         },
14583
14584         _disable: function() {
14585                 var that = this;
14586
14587                 // close open tooltips
14588                 $.each( this.tooltips, function( id, element ) {
14589                         var event = $.Event( "blur" );
14590                         event.target = event.currentTarget = element[0];
14591                         that.close( event, true );
14592                 });
14593
14594                 // remove title attributes to prevent native tooltips
14595                 this.element.find( this.options.items ).andSelf().each(function() {
14596                         var element = $( this );
14597                         if ( element.is( "[title]" ) ) {
14598                                 element
14599                                         .data( "ui-tooltip-title", element.attr( "title" ) )
14600                                         .attr( "title", "" );
14601                         }
14602                 });
14603         },
14604
14605         _enable: function() {
14606                 // restore title attributes
14607                 this.element.find( this.options.items ).andSelf().each(function() {
14608                         var element = $( this );
14609                         if ( element.data( "ui-tooltip-title" ) ) {
14610                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
14611                         }
14612                 });
14613         },
14614
14615         open: function( event ) {
14616                 var that = this,
14617                         target = $( event ? event.target : this.element )
14618                                 // we need closest here due to mouseover bubbling,
14619                                 // but always pointing at the same event target
14620                                 .closest( this.options.items );
14621
14622                 // No element to show a tooltip for or the tooltip is already open
14623                 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14624                         return;
14625                 }
14626
14627                 if ( target.attr( "title" ) ) {
14628                         target.data( "ui-tooltip-title", target.attr( "title" ) );
14629                 }
14630
14631                 target.data( "ui-tooltip-open", true );
14632
14633                 // kill parent tooltips, custom or native, for hover
14634                 if ( event && event.type === "mouseover" ) {
14635                         target.parents().each(function() {
14636                                 var parent = $( this ),
14637                                         blurEvent;
14638                                 if ( parent.data( "ui-tooltip-open" ) ) {
14639                                         blurEvent = $.Event( "blur" );
14640                                         blurEvent.target = blurEvent.currentTarget = this;
14641                                         that.close( blurEvent, true );
14642                                 }
14643                                 if ( parent.attr( "title" ) ) {
14644                                         parent.uniqueId();
14645                                         that.parents[ this.id ] = {
14646                                                 element: this,
14647                                                 title: parent.attr( "title" )
14648                                         };
14649                                         parent.attr( "title", "" );
14650                                 }
14651                         });
14652                 }
14653
14654                 this._updateContent( target, event );
14655         },
14656
14657         _updateContent: function( target, event ) {
14658                 var content,
14659                         contentOption = this.options.content,
14660                         that = this,
14661                         eventType = event ? event.type : null;
14662
14663                 if ( typeof contentOption === "string" ) {
14664                         return this._open( event, target, contentOption );
14665                 }
14666
14667                 content = contentOption.call( target[0], function( response ) {
14668                         // ignore async response if tooltip was closed already
14669                         if ( !target.data( "ui-tooltip-open" ) ) {
14670                                 return;
14671                         }
14672                         // IE may instantly serve a cached response for ajax requests
14673                         // delay this call to _open so the other call to _open runs first
14674                         that._delay(function() {
14675                                 // jQuery creates a special event for focusin when it doesn't
14676                                 // exist natively. To improve performance, the native event
14677                                 // object is reused and the type is changed. Therefore, we can't
14678                                 // rely on the type being correct after the event finished
14679                                 // bubbling, so we set it back to the previous value. (#8740)
14680                                 if ( event ) {
14681                                         event.type = eventType;
14682                                 }
14683                                 this._open( event, target, response );
14684                         });
14685                 });
14686                 if ( content ) {
14687                         this._open( event, target, content );
14688                 }
14689         },
14690
14691         _open: function( event, target, content ) {
14692                 var tooltip, events, delayedShow,
14693                         positionOption = $.extend( {}, this.options.position );
14694
14695                 if ( !content ) {
14696                         return;
14697                 }
14698
14699                 // Content can be updated multiple times. If the tooltip already
14700                 // exists, then just update the content and bail.
14701                 tooltip = this._find( target );
14702                 if ( tooltip.length ) {
14703                         tooltip.find( ".ui-tooltip-content" ).html( content );
14704                         return;
14705                 }
14706
14707                 // if we have a title, clear it to prevent the native tooltip
14708                 // we have to check first to avoid defining a title if none exists
14709                 // (we don't want to cause an element to start matching [title])
14710                 //
14711                 // We use removeAttr only for key events, to allow IE to export the correct
14712                 // accessible attributes. For mouse events, set to empty string to avoid
14713                 // native tooltip showing up (happens only when removing inside mouseover).
14714                 if ( target.is( "[title]" ) ) {
14715                         if ( event && event.type === "mouseover" ) {
14716                                 target.attr( "title", "" );
14717                         } else {
14718                                 target.removeAttr( "title" );
14719                         }
14720                 }
14721
14722                 tooltip = this._tooltip( target );
14723                 addDescribedBy( target, tooltip.attr( "id" ) );
14724                 tooltip.find( ".ui-tooltip-content" ).html( content );
14725
14726                 function position( event ) {
14727                         positionOption.of = event;
14728                         if ( tooltip.is( ":hidden" ) ) {
14729                                 return;
14730                         }
14731                         tooltip.position( positionOption );
14732                 }
14733                 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14734                         this._on( this.document, {
14735                                 mousemove: position
14736                         });
14737                         // trigger once to override element-relative positioning
14738                         position( event );
14739                 } else {
14740                         tooltip.position( $.extend({
14741                                 of: target
14742                         }, this.options.position ) );
14743                 }
14744
14745                 tooltip.hide();
14746
14747                 this._show( tooltip, this.options.show );
14748                 // Handle tracking tooltips that are shown with a delay (#8644). As soon
14749                 // as the tooltip is visible, position the tooltip using the most recent
14750                 // event.
14751                 if ( this.options.show && this.options.show.delay ) {
14752                         delayedShow = setInterval(function() {
14753                                 if ( tooltip.is( ":visible" ) ) {
14754                                         position( positionOption.of );
14755                                         clearInterval( delayedShow );
14756                                 }
14757                         }, $.fx.interval );
14758                 }
14759
14760                 this._trigger( "open", event, { tooltip: tooltip } );
14761
14762                 events = {
14763                         keyup: function( event ) {
14764                                 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14765                                         var fakeEvent = $.Event(event);
14766                                         fakeEvent.currentTarget = target[0];
14767                                         this.close( fakeEvent, true );
14768                                 }
14769                         },
14770                         remove: function() {
14771                                 this._removeTooltip( tooltip );
14772                         }
14773                 };
14774                 if ( !event || event.type === "mouseover" ) {
14775                         events.mouseleave = "close";
14776                 }
14777                 if ( !event || event.type === "focusin" ) {
14778                         events.focusout = "close";
14779                 }
14780                 this._on( true, target, events );
14781         },
14782
14783         close: function( event ) {
14784                 var that = this,
14785                         target = $( event ? event.currentTarget : this.element ),
14786                         tooltip = this._find( target );
14787
14788                 // disabling closes the tooltip, so we need to track when we're closing
14789                 // to avoid an infinite loop in case the tooltip becomes disabled on close
14790                 if ( this.closing ) {
14791                         return;
14792                 }
14793
14794                 // only set title if we had one before (see comment in _open())
14795                 if ( target.data( "ui-tooltip-title" ) ) {
14796                         target.attr( "title", target.data( "ui-tooltip-title" ) );
14797                 }
14798
14799                 removeDescribedBy( target );
14800
14801                 tooltip.stop( true );
14802                 this._hide( tooltip, this.options.hide, function() {
14803                         that._removeTooltip( $( this ) );
14804                 });
14805
14806                 target.removeData( "ui-tooltip-open" );
14807                 this._off( target, "mouseleave focusout keyup" );
14808                 // Remove 'remove' binding only on delegated targets
14809                 if ( target[0] !== this.element[0] ) {
14810                         this._off( target, "remove" );
14811                 }
14812                 this._off( this.document, "mousemove" );
14813
14814                 if ( event && event.type === "mouseleave" ) {
14815                         $.each( this.parents, function( id, parent ) {
14816                                 $( parent.element ).attr( "title", parent.title );
14817                                 delete that.parents[ id ];
14818                         });
14819                 }
14820
14821                 this.closing = true;
14822                 this._trigger( "close", event, { tooltip: tooltip } );
14823                 this.closing = false;
14824         },
14825
14826         _tooltip: function( element ) {
14827                 var id = "ui-tooltip-" + increments++,
14828                         tooltip = $( "<div>" )
14829                                 .attr({
14830                                         id: id,
14831                                         role: "tooltip"
14832                                 })
14833                                 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14834                                         ( this.options.tooltipClass || "" ) );
14835                 $( "<div>" )
14836                         .addClass( "ui-tooltip-content" )
14837                         .appendTo( tooltip );
14838                 tooltip.appendTo( this.document[0].body );
14839                 if ( $.fn.bgiframe ) {
14840                         tooltip.bgiframe();
14841                 }
14842                 this.tooltips[ id ] = element;
14843                 return tooltip;
14844         },
14845
14846         _find: function( target ) {
14847                 var id = target.data( "ui-tooltip-id" );
14848                 return id ? $( "#" + id ) : $();
14849         },
14850
14851         _removeTooltip: function( tooltip ) {
14852                 tooltip.remove();
14853                 delete this.tooltips[ tooltip.attr( "id" ) ];
14854         },
14855
14856         _destroy: function() {
14857                 var that = this;
14858
14859                 // close open tooltips
14860                 $.each( this.tooltips, function( id, element ) {
14861                         // Delegate to close method to handle common cleanup
14862                         var event = $.Event( "blur" );
14863                         event.target = event.currentTarget = element[0];
14864                         that.close( event, true );
14865
14866                         // Remove immediately; destroying an open tooltip doesn't use the
14867                         // hide animation
14868                         $( "#" + id ).remove();
14869
14870                         // Restore the title
14871                         if ( element.data( "ui-tooltip-title" ) ) {
14872                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
14873                                 element.removeData( "ui-tooltip-title" );
14874                         }
14875                 });
14876         }
14877 });
14878
14879 }( jQuery ) );