first commit
[wnstats.git] / public / javascripts / jqplot / examples / jquery-ui / js / jquery-ui.js
blobcd515f36129cfe56142ea40bedb65a3cf422be00
1 /*!
2  * jQuery UI 1.8.16
3  *
4  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5  * Dual licensed under the MIT or GPL Version 2 licenses.
6  * http://jquery.org/license
7  *
8  * http://docs.jquery.com/UI
9  */
10 (function( $, undefined ) {
12 // prevent duplicate loading
13 // this is only a problem because we proxy existing functions
14 // and we don't want to double proxy them
15 $.ui = $.ui || {};
16 if ( $.ui.version ) {
17         return;
20 $.extend( $.ui, {
21         version: "1.8.16",
23         keyCode: {
24                 ALT: 18,
25                 BACKSPACE: 8,
26                 CAPS_LOCK: 20,
27                 COMMA: 188,
28                 COMMAND: 91,
29                 COMMAND_LEFT: 91, // COMMAND
30                 COMMAND_RIGHT: 93,
31                 CONTROL: 17,
32                 DELETE: 46,
33                 DOWN: 40,
34                 END: 35,
35                 ENTER: 13,
36                 ESCAPE: 27,
37                 HOME: 36,
38                 INSERT: 45,
39                 LEFT: 37,
40                 MENU: 93, // COMMAND_RIGHT
41                 NUMPAD_ADD: 107,
42                 NUMPAD_DECIMAL: 110,
43                 NUMPAD_DIVIDE: 111,
44                 NUMPAD_ENTER: 108,
45                 NUMPAD_MULTIPLY: 106,
46                 NUMPAD_SUBTRACT: 109,
47                 PAGE_DOWN: 34,
48                 PAGE_UP: 33,
49                 PERIOD: 190,
50                 RIGHT: 39,
51                 SHIFT: 16,
52                 SPACE: 32,
53                 TAB: 9,
54                 UP: 38,
55                 WINDOWS: 91 // COMMAND
56         }
57 });
59 // plugins
60 $.fn.extend({
61         propAttr: $.fn.prop || $.fn.attr,
63         _focus: $.fn.focus,
64         focus: function( delay, fn ) {
65                 return typeof delay === "number" ?
66                         this.each(function() {
67                                 var elem = this;
68                                 setTimeout(function() {
69                                         $( elem ).focus();
70                                         if ( fn ) {
71                                                 fn.call( elem );
72                                         }
73                                 }, delay );
74                         }) :
75                         this._focus.apply( this, arguments );
76         },
78         scrollParent: function() {
79                 var scrollParent;
80                 if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
81                         scrollParent = this.parents().filter(function() {
82                                 return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
83                         }).eq(0);
84                 } else {
85                         scrollParent = this.parents().filter(function() {
86                                 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
87                         }).eq(0);
88                 }
90                 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
91         },
93         zIndex: function( zIndex ) {
94                 if ( zIndex !== undefined ) {
95                         return this.css( "zIndex", zIndex );
96                 }
98                 if ( this.length ) {
99                         var elem = $( this[ 0 ] ), position, value;
100                         while ( elem.length && elem[ 0 ] !== document ) {
101                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
102                                 // This makes behavior of this function consistent across browsers
103                                 // WebKit always returns auto if the element is positioned
104                                 position = elem.css( "position" );
105                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
106                                         // IE returns 0 when zIndex is not specified
107                                         // other browsers return a string
108                                         // we ignore the case of nested elements with an explicit value of 0
109                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
110                                         value = parseInt( elem.css( "zIndex" ), 10 );
111                                         if ( !isNaN( value ) && value !== 0 ) {
112                                                 return value;
113                                         }
114                                 }
115                                 elem = elem.parent();
116                         }
117                 }
119                 return 0;
120         },
122         disableSelection: function() {
123                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
124                         ".ui-disableSelection", function( event ) {
125                                 event.preventDefault();
126                         });
127         },
129         enableSelection: function() {
130                 return this.unbind( ".ui-disableSelection" );
131         }
134 $.each( [ "Width", "Height" ], function( i, name ) {
135         var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
136                 type = name.toLowerCase(),
137                 orig = {
138                         innerWidth: $.fn.innerWidth,
139                         innerHeight: $.fn.innerHeight,
140                         outerWidth: $.fn.outerWidth,
141                         outerHeight: $.fn.outerHeight
142                 };
144         function reduce( elem, size, border, margin ) {
145                 $.each( side, function() {
146                         size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
147                         if ( border ) {
148                                 size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
149                         }
150                         if ( margin ) {
151                                 size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
152                         }
153                 });
154                 return size;
155         }
157         $.fn[ "inner" + name ] = function( size ) {
158                 if ( size === undefined ) {
159                         return orig[ "inner" + name ].call( this );
160                 }
162                 return this.each(function() {
163                         $( this ).css( type, reduce( this, size ) + "px" );
164                 });
165         };
167         $.fn[ "outer" + name] = function( size, margin ) {
168                 if ( typeof size !== "number" ) {
169                         return orig[ "outer" + name ].call( this, size );
170                 }
172                 return this.each(function() {
173                         $( this).css( type, reduce( this, size, true, margin ) + "px" );
174                 });
175         };
178 // selectors
179 function focusable( element, isTabIndexNotNaN ) {
180         var nodeName = element.nodeName.toLowerCase();
181         if ( "area" === nodeName ) {
182                 var map = element.parentNode,
183                         mapName = map.name,
184                         img;
185                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
186                         return false;
187                 }
188                 img = $( "img[usemap=#" + mapName + "]" )[0];
189                 return !!img && visible( img );
190         }
191         return ( /input|select|textarea|button|object/.test( nodeName )
192                 ? !element.disabled
193                 : "a" == nodeName
194                         ? element.href || isTabIndexNotNaN
195                         : isTabIndexNotNaN)
196                 // the element and all of its ancestors must be visible
197                 && visible( element );
200 function visible( element ) {
201         return !$( element ).parents().andSelf().filter(function() {
202                 return $.curCSS( this, "visibility" ) === "hidden" ||
203                         $.expr.filters.hidden( this );
204         }).length;
207 $.extend( $.expr[ ":" ], {
208         data: function( elem, i, match ) {
209                 return !!$.data( elem, match[ 3 ] );
210         },
212         focusable: function( element ) {
213                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
214         },
216         tabbable: function( element ) {
217                 var tabIndex = $.attr( element, "tabindex" ),
218                         isTabIndexNaN = isNaN( tabIndex );
219                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
220         }
223 // support
224 $(function() {
225         var body = document.body,
226                 div = body.appendChild( div = document.createElement( "div" ) );
228         $.extend( div.style, {
229                 minHeight: "100px",
230                 height: "auto",
231                 padding: 0,
232                 borderWidth: 0
233         });
235         $.support.minHeight = div.offsetHeight === 100;
236         $.support.selectstart = "onselectstart" in div;
238         // set display to none to avoid a layout bug in IE
239         // http://dev.jquery.com/ticket/4014
240         body.removeChild( div ).style.display = "none";
247 // deprecated
248 $.extend( $.ui, {
249         // $.ui.plugin is deprecated.  Use the proxy pattern instead.
250         plugin: {
251                 add: function( module, option, set ) {
252                         var proto = $.ui[ module ].prototype;
253                         for ( var i in set ) {
254                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
255                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
256                         }
257                 },
258                 call: function( instance, name, args ) {
259                         var set = instance.plugins[ name ];
260                         if ( !set || !instance.element[ 0 ].parentNode ) {
261                                 return;
262                         }
263         
264                         for ( var i = 0; i < set.length; i++ ) {
265                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
266                                         set[ i ][ 1 ].apply( instance.element, args );
267                                 }
268                         }
269                 }
270         },
271         
272         // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
273         contains: function( a, b ) {
274                 return document.compareDocumentPosition ?
275                         a.compareDocumentPosition( b ) & 16 :
276                         a !== b && a.contains( b );
277         },
278         
279         // only used by resizable
280         hasScroll: function( el, a ) {
281         
282                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
283                 if ( $( el ).css( "overflow" ) === "hidden") {
284                         return false;
285                 }
286         
287                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
288                         has = false;
289         
290                 if ( el[ scroll ] > 0 ) {
291                         return true;
292                 }
293         
294                 // TODO: determine which cases actually cause this to happen
295                 // if the element doesn't have the scroll set, see if it's possible to
296                 // set the scroll
297                 el[ scroll ] = 1;
298                 has = ( el[ scroll ] > 0 );
299                 el[ scroll ] = 0;
300                 return has;
301         },
302         
303         // these are odd functions, fix the API or move into individual plugins
304         isOverAxis: function( x, reference, size ) {
305                 //Determines when x coordinate is over "b" element axis
306                 return ( x > reference ) && ( x < ( reference + size ) );
307         },
308         isOver: function( y, x, top, left, height, width ) {
309                 //Determines when x, y coordinates is over "b" element
310                 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
311         }
314 })( jQuery );
316  * jQuery UI Widget 1.8.16
318  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
319  * Dual licensed under the MIT or GPL Version 2 licenses.
320  * http://jquery.org/license
322  * http://docs.jquery.com/UI/Widget
323  */
324 (function( $, undefined ) {
326 // jQuery 1.4+
327 if ( $.cleanData ) {
328         var _cleanData = $.cleanData;
329         $.cleanData = function( elems ) {
330                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
331                         try {
332                                 $( elem ).triggerHandler( "remove" );
333                         // http://bugs.jquery.com/ticket/8235
334                         } catch( e ) {}
335                 }
336                 _cleanData( elems );
337         };
338 } else {
339         var _remove = $.fn.remove;
340         $.fn.remove = function( selector, keepData ) {
341                 return this.each(function() {
342                         if ( !keepData ) {
343                                 if ( !selector || $.filter( selector, [ this ] ).length ) {
344                                         $( "*", this ).add( [ this ] ).each(function() {
345                                                 try {
346                                                         $( this ).triggerHandler( "remove" );
347                                                 // http://bugs.jquery.com/ticket/8235
348                                                 } catch( e ) {}
349                                         });
350                                 }
351                         }
352                         return _remove.call( $(this), selector, keepData );
353                 });
354         };
357 $.widget = function( name, base, prototype ) {
358         var namespace = name.split( "." )[ 0 ],
359                 fullName;
360         name = name.split( "." )[ 1 ];
361         fullName = namespace + "-" + name;
363         if ( !prototype ) {
364                 prototype = base;
365                 base = $.Widget;
366         }
368         // create selector for plugin
369         $.expr[ ":" ][ fullName ] = function( elem ) {
370                 return !!$.data( elem, name );
371         };
373         $[ namespace ] = $[ namespace ] || {};
374         $[ namespace ][ name ] = function( options, element ) {
375                 // allow instantiation without initializing for simple inheritance
376                 if ( arguments.length ) {
377                         this._createWidget( options, element );
378                 }
379         };
381         var basePrototype = new base();
382         // we need to make the options hash a property directly on the new instance
383         // otherwise we'll modify the options hash on the prototype that we're
384         // inheriting from
385 //      $.each( basePrototype, function( key, val ) {
386 //              if ( $.isPlainObject(val) ) {
387 //                      basePrototype[ key ] = $.extend( {}, val );
388 //              }
389 //      });
390         basePrototype.options = $.extend( true, {}, basePrototype.options );
391         $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
392                 namespace: namespace,
393                 widgetName: name,
394                 widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
395                 widgetBaseClass: fullName
396         }, prototype );
398         $.widget.bridge( name, $[ namespace ][ name ] );
401 $.widget.bridge = function( name, object ) {
402         $.fn[ name ] = function( options ) {
403                 var isMethodCall = typeof options === "string",
404                         args = Array.prototype.slice.call( arguments, 1 ),
405                         returnValue = this;
407                 // allow multiple hashes to be passed on init
408                 options = !isMethodCall && args.length ?
409                         $.extend.apply( null, [ true, options ].concat(args) ) :
410                         options;
412                 // prevent calls to internal methods
413                 if ( isMethodCall && options.charAt( 0 ) === "_" ) {
414                         return returnValue;
415                 }
417                 if ( isMethodCall ) {
418                         this.each(function() {
419                                 var instance = $.data( this, name ),
420                                         methodValue = instance && $.isFunction( instance[options] ) ?
421                                                 instance[ options ].apply( instance, args ) :
422                                                 instance;
423                                 // TODO: add this back in 1.9 and use $.error() (see #5972)
424 //                              if ( !instance ) {
425 //                                      throw "cannot call methods on " + name + " prior to initialization; " +
426 //                                              "attempted to call method '" + options + "'";
427 //                              }
428 //                              if ( !$.isFunction( instance[options] ) ) {
429 //                                      throw "no such method '" + options + "' for " + name + " widget instance";
430 //                              }
431 //                              var methodValue = instance[ options ].apply( instance, args );
432                                 if ( methodValue !== instance && methodValue !== undefined ) {
433                                         returnValue = methodValue;
434                                         return false;
435                                 }
436                         });
437                 } else {
438                         this.each(function() {
439                                 var instance = $.data( this, name );
440                                 if ( instance ) {
441                                         instance.option( options || {} )._init();
442                                 } else {
443                                         $.data( this, name, new object( options, this ) );
444                                 }
445                         });
446                 }
448                 return returnValue;
449         };
452 $.Widget = function( options, element ) {
453         // allow instantiation without initializing for simple inheritance
454         if ( arguments.length ) {
455                 this._createWidget( options, element );
456         }
459 $.Widget.prototype = {
460         widgetName: "widget",
461         widgetEventPrefix: "",
462         options: {
463                 disabled: false
464         },
465         _createWidget: function( options, element ) {
466                 // $.widget.bridge stores the plugin instance, but we do it anyway
467                 // so that it's stored even before the _create function runs
468                 $.data( element, this.widgetName, this );
469                 this.element = $( element );
470                 this.options = $.extend( true, {},
471                         this.options,
472                         this._getCreateOptions(),
473                         options );
475                 var self = this;
476                 this.element.bind( "remove." + this.widgetName, function() {
477                         self.destroy();
478                 });
480                 this._create();
481                 this._trigger( "create" );
482                 this._init();
483         },
484         _getCreateOptions: function() {
485                 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
486         },
487         _create: function() {},
488         _init: function() {},
490         destroy: function() {
491                 this.element
492                         .unbind( "." + this.widgetName )
493                         .removeData( this.widgetName );
494                 this.widget()
495                         .unbind( "." + this.widgetName )
496                         .removeAttr( "aria-disabled" )
497                         .removeClass(
498                                 this.widgetBaseClass + "-disabled " +
499                                 "ui-state-disabled" );
500         },
502         widget: function() {
503                 return this.element;
504         },
506         option: function( key, value ) {
507                 var options = key;
509                 if ( arguments.length === 0 ) {
510                         // don't return a reference to the internal hash
511                         return $.extend( {}, this.options );
512                 }
514                 if  (typeof key === "string" ) {
515                         if ( value === undefined ) {
516                                 return this.options[ key ];
517                         }
518                         options = {};
519                         options[ key ] = value;
520                 }
522                 this._setOptions( options );
524                 return this;
525         },
526         _setOptions: function( options ) {
527                 var self = this;
528                 $.each( options, function( key, value ) {
529                         self._setOption( key, value );
530                 });
532                 return this;
533         },
534         _setOption: function( key, value ) {
535                 this.options[ key ] = value;
537                 if ( key === "disabled" ) {
538                         this.widget()
539                                 [ value ? "addClass" : "removeClass"](
540                                         this.widgetBaseClass + "-disabled" + " " +
541                                         "ui-state-disabled" )
542                                 .attr( "aria-disabled", value );
543                 }
545                 return this;
546         },
548         enable: function() {
549                 return this._setOption( "disabled", false );
550         },
551         disable: function() {
552                 return this._setOption( "disabled", true );
553         },
555         _trigger: function( type, event, data ) {
556                 var callback = this.options[ type ];
558                 event = $.Event( event );
559                 event.type = ( type === this.widgetEventPrefix ?
560                         type :
561                         this.widgetEventPrefix + type ).toLowerCase();
562                 data = data || {};
564                 // copy original event properties over to the new event
565                 // this would happen if we could call $.event.fix instead of $.Event
566                 // but we don't have a way to force an event to be fixed multiple times
567                 if ( event.originalEvent ) {
568                         for ( var i = $.event.props.length, prop; i; ) {
569                                 prop = $.event.props[ --i ];
570                                 event[ prop ] = event.originalEvent[ prop ];
571                         }
572                 }
574                 this.element.trigger( event, data );
576                 return !( $.isFunction(callback) &&
577                         callback.call( this.element[0], event, data ) === false ||
578                         event.isDefaultPrevented() );
579         }
582 })( jQuery );
584  * jQuery UI Mouse 1.8.16
586  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
587  * Dual licensed under the MIT or GPL Version 2 licenses.
588  * http://jquery.org/license
590  * http://docs.jquery.com/UI/Mouse
592  * Depends:
593  *      jquery.ui.widget.js
594  */
595 (function( $, undefined ) {
597 var mouseHandled = false;
598 $( document ).mouseup( function( e ) {
599         mouseHandled = false;
602 $.widget("ui.mouse", {
603         options: {
604                 cancel: ':input,option',
605                 distance: 1,
606                 delay: 0
607         },
608         _mouseInit: function() {
609                 var self = this;
611                 this.element
612                         .bind('mousedown.'+this.widgetName, function(event) {
613                                 return self._mouseDown(event);
614                         })
615                         .bind('click.'+this.widgetName, function(event) {
616                                 if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
617                                     $.removeData(event.target, self.widgetName + '.preventClickEvent');
618                                         event.stopImmediatePropagation();
619                                         return false;
620                                 }
621                         });
623                 this.started = false;
624         },
626         // TODO: make sure destroying one instance of mouse doesn't mess with
627         // other instances of mouse
628         _mouseDestroy: function() {
629                 this.element.unbind('.'+this.widgetName);
630         },
632         _mouseDown: function(event) {
633                 // don't let more than one widget handle mouseStart
634                 if( mouseHandled ) { return };
636                 // we may have missed mouseup (out of window)
637                 (this._mouseStarted && this._mouseUp(event));
639                 this._mouseDownEvent = event;
641                 var self = this,
642                         btnIsLeft = (event.which == 1),
643                         // event.target.nodeName works around a bug in IE 8 with
644                         // disabled inputs (#7620)
645                         elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
646                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
647                         return true;
648                 }
650                 this.mouseDelayMet = !this.options.delay;
651                 if (!this.mouseDelayMet) {
652                         this._mouseDelayTimer = setTimeout(function() {
653                                 self.mouseDelayMet = true;
654                         }, this.options.delay);
655                 }
657                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
658                         this._mouseStarted = (this._mouseStart(event) !== false);
659                         if (!this._mouseStarted) {
660                                 event.preventDefault();
661                                 return true;
662                         }
663                 }
665                 // Click event may never have fired (Gecko & Opera)
666                 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
667                         $.removeData(event.target, this.widgetName + '.preventClickEvent');
668                 }
670                 // these delegates are required to keep context
671                 this._mouseMoveDelegate = function(event) {
672                         return self._mouseMove(event);
673                 };
674                 this._mouseUpDelegate = function(event) {
675                         return self._mouseUp(event);
676                 };
677                 $(document)
678                         .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
679                         .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
681                 event.preventDefault();
682                 
683                 mouseHandled = true;
684                 return true;
685         },
687         _mouseMove: function(event) {
688                 // IE mouseup check - mouseup happened when mouse was out of window
689                 if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
690                         return this._mouseUp(event);
691                 }
693                 if (this._mouseStarted) {
694                         this._mouseDrag(event);
695                         return event.preventDefault();
696                 }
698                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
699                         this._mouseStarted =
700                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
701                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
702                 }
704                 return !this._mouseStarted;
705         },
707         _mouseUp: function(event) {
708                 $(document)
709                         .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
710                         .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
712                 if (this._mouseStarted) {
713                         this._mouseStarted = false;
715                         if (event.target == this._mouseDownEvent.target) {
716                             $.data(event.target, this.widgetName + '.preventClickEvent', true);
717                         }
719                         this._mouseStop(event);
720                 }
722                 return false;
723         },
725         _mouseDistanceMet: function(event) {
726                 return (Math.max(
727                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
728                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
729                         ) >= this.options.distance
730                 );
731         },
733         _mouseDelayMet: function(event) {
734                 return this.mouseDelayMet;
735         },
737         // These are placeholder methods, to be overriden by extending plugin
738         _mouseStart: function(event) {},
739         _mouseDrag: function(event) {},
740         _mouseStop: function(event) {},
741         _mouseCapture: function(event) { return true; }
744 })(jQuery);
746  * jQuery UI Draggable 1.8.16
748  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
749  * Dual licensed under the MIT or GPL Version 2 licenses.
750  * http://jquery.org/license
752  * http://docs.jquery.com/UI/Draggables
754  * Depends:
755  *      jquery.ui.core.js
756  *      jquery.ui.mouse.js
757  *      jquery.ui.widget.js
758  */
759 (function( $, undefined ) {
761 $.widget("ui.draggable", $.ui.mouse, {
762         widgetEventPrefix: "drag",
763         options: {
764                 addClasses: true,
765                 appendTo: "parent",
766                 axis: false,
767                 connectToSortable: false,
768                 containment: false,
769                 cursor: "auto",
770                 cursorAt: false,
771                 grid: false,
772                 handle: false,
773                 helper: "original",
774                 iframeFix: false,
775                 opacity: false,
776                 refreshPositions: false,
777                 revert: false,
778                 revertDuration: 500,
779                 scope: "default",
780                 scroll: true,
781                 scrollSensitivity: 20,
782                 scrollSpeed: 20,
783                 snap: false,
784                 snapMode: "both",
785                 snapTolerance: 20,
786                 stack: false,
787                 zIndex: false
788         },
789         _create: function() {
791                 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
792                         this.element[0].style.position = 'relative';
794                 (this.options.addClasses && this.element.addClass("ui-draggable"));
795                 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
797                 this._mouseInit();
799         },
801         destroy: function() {
802                 if(!this.element.data('draggable')) return;
803                 this.element
804                         .removeData("draggable")
805                         .unbind(".draggable")
806                         .removeClass("ui-draggable"
807                                 + " ui-draggable-dragging"
808                                 + " ui-draggable-disabled");
809                 this._mouseDestroy();
811                 return this;
812         },
814         _mouseCapture: function(event) {
816                 var o = this.options;
818                 // among others, prevent a drag on a resizable-handle
819                 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
820                         return false;
822                 //Quit if we're not on a valid handle
823                 this.handle = this._getHandle(event);
824                 if (!this.handle)
825                         return false;
826                 
827                 if ( o.iframeFix ) {
828                         $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
829                                 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
830                                 .css({
831                                         width: this.offsetWidth+"px", height: this.offsetHeight+"px",
832                                         position: "absolute", opacity: "0.001", zIndex: 1000
833                                 })
834                                 .css($(this).offset())
835                                 .appendTo("body");
836                         });
837                 }
839                 return true;
841         },
843         _mouseStart: function(event) {
845                 var o = this.options;
847                 //Create and append the visible helper
848                 this.helper = this._createHelper(event);
850                 //Cache the helper size
851                 this._cacheHelperProportions();
853                 //If ddmanager is used for droppables, set the global draggable
854                 if($.ui.ddmanager)
855                         $.ui.ddmanager.current = this;
857                 /*
858                  * - Position generation -
859                  * This block generates everything position related - it's the core of draggables.
860                  */
862                 //Cache the margins of the original element
863                 this._cacheMargins();
865                 //Store the helper's css position
866                 this.cssPosition = this.helper.css("position");
867                 this.scrollParent = this.helper.scrollParent();
869                 //The element's absolute position on the page minus margins
870                 this.offset = this.positionAbs = this.element.offset();
871                 this.offset = {
872                         top: this.offset.top - this.margins.top,
873                         left: this.offset.left - this.margins.left
874                 };
876                 $.extend(this.offset, {
877                         click: { //Where the click happened, relative to the element
878                                 left: event.pageX - this.offset.left,
879                                 top: event.pageY - this.offset.top
880                         },
881                         parent: this._getParentOffset(),
882                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
883                 });
885                 //Generate the original position
886                 this.originalPosition = this.position = this._generatePosition(event);
887                 this.originalPageX = event.pageX;
888                 this.originalPageY = event.pageY;
890                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
891                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
893                 //Set a containment if given in the options
894                 if(o.containment)
895                         this._setContainment();
897                 //Trigger event + callbacks
898                 if(this._trigger("start", event) === false) {
899                         this._clear();
900                         return false;
901                 }
903                 //Recache the helper size
904                 this._cacheHelperProportions();
906                 //Prepare the droppable offsets
907                 if ($.ui.ddmanager && !o.dropBehaviour)
908                         $.ui.ddmanager.prepareOffsets(this, event);
910                 this.helper.addClass("ui-draggable-dragging");
911                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
912                 
913                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
914                 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
915                 
916                 return true;
917         },
919         _mouseDrag: function(event, noPropagation) {
921                 //Compute the helpers position
922                 this.position = this._generatePosition(event);
923                 this.positionAbs = this._convertPositionTo("absolute");
925                 //Call plugins and callbacks and use the resulting position if something is returned
926                 if (!noPropagation) {
927                         var ui = this._uiHash();
928                         if(this._trigger('drag', event, ui) === false) {
929                                 this._mouseUp({});
930                                 return false;
931                         }
932                         this.position = ui.position;
933                 }
935                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
936                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
937                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
939                 return false;
940         },
942         _mouseStop: function(event) {
944                 //If we are using droppables, inform the manager about the drop
945                 var dropped = false;
946                 if ($.ui.ddmanager && !this.options.dropBehaviour)
947                         dropped = $.ui.ddmanager.drop(this, event);
949                 //if a drop comes from outside (a sortable)
950                 if(this.dropped) {
951                         dropped = this.dropped;
952                         this.dropped = false;
953                 }
954                 
955                 //if the original element is removed, don't bother to continue if helper is set to "original"
956                 if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
957                         return false;
959                 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))) {
960                         var self = this;
961                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
962                                 if(self._trigger("stop", event) !== false) {
963                                         self._clear();
964                                 }
965                         });
966                 } else {
967                         if(this._trigger("stop", event) !== false) {
968                                 this._clear();
969                         }
970                 }
972                 return false;
973         },
974         
975         _mouseUp: function(event) {
976                 if (this.options.iframeFix === true) {
977                         $("div.ui-draggable-iframeFix").each(function() { 
978                                 this.parentNode.removeChild(this); 
979                         }); //Remove frame helpers
980                 }
981                 
982                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
983                 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
984                 
985                 return $.ui.mouse.prototype._mouseUp.call(this, event);
986         },
987         
988         cancel: function() {
989                 
990                 if(this.helper.is(".ui-draggable-dragging")) {
991                         this._mouseUp({});
992                 } else {
993                         this._clear();
994                 }
995                 
996                 return this;
997                 
998         },
1000         _getHandle: function(event) {
1002                 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1003                 $(this.options.handle, this.element)
1004                         .find("*")
1005                         .andSelf()
1006                         .each(function() {
1007                                 if(this == event.target) handle = true;
1008                         });
1010                 return handle;
1012         },
1014         _createHelper: function(event) {
1016                 var o = this.options;
1017                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1019                 if(!helper.parents('body').length)
1020                         helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1022                 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1023                         helper.css("position", "absolute");
1025                 return helper;
1027         },
1029         _adjustOffsetFromHelper: function(obj) {
1030                 if (typeof obj == 'string') {
1031                         obj = obj.split(' ');
1032                 }
1033                 if ($.isArray(obj)) {
1034                         obj = {left: +obj[0], top: +obj[1] || 0};
1035                 }
1036                 if ('left' in obj) {
1037                         this.offset.click.left = obj.left + this.margins.left;
1038                 }
1039                 if ('right' in obj) {
1040                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1041                 }
1042                 if ('top' in obj) {
1043                         this.offset.click.top = obj.top + this.margins.top;
1044                 }
1045                 if ('bottom' in obj) {
1046                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1047                 }
1048         },
1050         _getParentOffset: function() {
1052                 //Get the offsetParent and cache its position
1053                 this.offsetParent = this.helper.offsetParent();
1054                 var po = this.offsetParent.offset();
1056                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1057                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1058                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1059                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1060                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1061                         po.left += this.scrollParent.scrollLeft();
1062                         po.top += this.scrollParent.scrollTop();
1063                 }
1065                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1066                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1067                         po = { top: 0, left: 0 };
1069                 return {
1070                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1071                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1072                 };
1074         },
1076         _getRelativeOffset: function() {
1078                 if(this.cssPosition == "relative") {
1079                         var p = this.element.position();
1080                         return {
1081                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1082                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1083                         };
1084                 } else {
1085                         return { top: 0, left: 0 };
1086                 }
1088         },
1090         _cacheMargins: function() {
1091                 this.margins = {
1092                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
1093                         top: (parseInt(this.element.css("marginTop"),10) || 0),
1094                         right: (parseInt(this.element.css("marginRight"),10) || 0),
1095                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1096                 };
1097         },
1099         _cacheHelperProportions: function() {
1100                 this.helperProportions = {
1101                         width: this.helper.outerWidth(),
1102                         height: this.helper.outerHeight()
1103                 };
1104         },
1106         _setContainment: function() {
1108                 var o = this.options;
1109                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1110                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
1111                         o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1112                         o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1113                         (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1114                         (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1115                 ];
1117                 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1118                         var c = $(o.containment);
1119                         var ce = c[0]; if(!ce) return;
1120                         var co = c.offset();
1121                         var over = ($(ce).css("overflow") != 'hidden');
1123                         this.containment = [
1124                                 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1125                                 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1126                                 (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,
1127                                 (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
1128                         ];
1129                         this.relative_container = c;
1131                 } else if(o.containment.constructor == Array) {
1132                         this.containment = o.containment;
1133                 }
1135         },
1137         _convertPositionTo: function(d, pos) {
1139                 if(!pos) pos = this.position;
1140                 var mod = d == "absolute" ? 1 : -1;
1141                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1143                 return {
1144                         top: (
1145                                 pos.top                                                                                                                                 // The absolute mouse position
1146                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1147                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
1148                                 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1149                         ),
1150                         left: (
1151                                 pos.left                                                                                                                                // The absolute mouse position
1152                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
1153                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
1154                                 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1155                         )
1156                 };
1158         },
1160         _generatePosition: function(event) {
1162                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1163                 var pageX = event.pageX;
1164                 var pageY = event.pageY;
1166                 /*
1167                  * - Position constraining -
1168                  * Constrain the position to a mix of grid, containment.
1169                  */
1171                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1172                          var containment;
1173                          if(this.containment) {
1174                                  if (this.relative_container){
1175                                      var co = this.relative_container.offset();
1176                                      containment = [ this.containment[0] + co.left,
1177                                                      this.containment[1] + co.top,
1178                                                      this.containment[2] + co.left,
1179                                                      this.containment[3] + co.top ];
1180                                  }
1181                                  else {
1182                                      containment = this.containment;
1183                                  }
1185                                 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1186                                 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1187                                 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1188                                 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1189                         }
1191                         if(o.grid) {
1192                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1193                                 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1194                                 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;
1196                                 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1197                                 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;
1198                         }
1200                 }
1202                 return {
1203                         top: (
1204                                 pageY                                                                                                                           // The absolute mouse position
1205                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
1206                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
1207                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
1208                                 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1209                         ),
1210                         left: (
1211                                 pageX                                                                                                                           // The absolute mouse position
1212                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
1213                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
1214                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
1215                                 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1216                         )
1217                 };
1219         },
1221         _clear: function() {
1222                 this.helper.removeClass("ui-draggable-dragging");
1223                 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1224                 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1225                 this.helper = null;
1226                 this.cancelHelperRemoval = false;
1227         },
1229         // From now on bulk stuff - mainly helpers
1231         _trigger: function(type, event, ui) {
1232                 ui = ui || this._uiHash();
1233                 $.ui.plugin.call(this, type, [event, ui]);
1234                 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1235                 return $.Widget.prototype._trigger.call(this, type, event, ui);
1236         },
1238         plugins: {},
1240         _uiHash: function(event) {
1241                 return {
1242                         helper: this.helper,
1243                         position: this.position,
1244                         originalPosition: this.originalPosition,
1245                         offset: this.positionAbs
1246                 };
1247         }
1251 $.extend($.ui.draggable, {
1252         version: "1.8.16"
1255 $.ui.plugin.add("draggable", "connectToSortable", {
1256         start: function(event, ui) {
1258                 var inst = $(this).data("draggable"), o = inst.options,
1259                         uiSortable = $.extend({}, ui, { item: inst.element });
1260                 inst.sortables = [];
1261                 $(o.connectToSortable).each(function() {
1262                         var sortable = $.data(this, 'sortable');
1263                         if (sortable && !sortable.options.disabled) {
1264                                 inst.sortables.push({
1265                                         instance: sortable,
1266                                         shouldRevert: sortable.options.revert
1267                                 });
1268                                 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).
1269                                 sortable._trigger("activate", event, uiSortable);
1270                         }
1271                 });
1273         },
1274         stop: function(event, ui) {
1276                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1277                 var inst = $(this).data("draggable"),
1278                         uiSortable = $.extend({}, ui, { item: inst.element });
1280                 $.each(inst.sortables, function() {
1281                         if(this.instance.isOver) {
1283                                 this.instance.isOver = 0;
1285                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1286                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1288                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1289                                 if(this.shouldRevert) this.instance.options.revert = true;
1291                                 //Trigger the stop of the sortable
1292                                 this.instance._mouseStop(event);
1294                                 this.instance.options.helper = this.instance.options._helper;
1296                                 //If the helper has been the original item, restore properties in the sortable
1297                                 if(inst.options.helper == 'original')
1298                                         this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1300                         } else {
1301                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1302                                 this.instance._trigger("deactivate", event, uiSortable);
1303                         }
1305                 });
1307         },
1308         drag: function(event, ui) {
1310                 var inst = $(this).data("draggable"), self = this;
1312                 var checkPos = function(o) {
1313                         var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1314                         var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1315                         var itemHeight = o.height, itemWidth = o.width;
1316                         var itemTop = o.top, itemLeft = o.left;
1318                         return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1319                 };
1321                 $.each(inst.sortables, function(i) {
1322                         
1323                         //Copy over some variables to allow calling the sortable's native _intersectsWith
1324                         this.instance.positionAbs = inst.positionAbs;
1325                         this.instance.helperProportions = inst.helperProportions;
1326                         this.instance.offset.click = inst.offset.click;
1327                         
1328                         if(this.instance._intersectsWith(this.instance.containerCache)) {
1330                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1331                                 if(!this.instance.isOver) {
1333                                         this.instance.isOver = 1;
1334                                         //Now we fake the start of dragging for the sortable instance,
1335                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1336                                         //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)
1337                                         this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1338                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1339                                         this.instance.options.helper = function() { return ui.helper[0]; };
1341                                         event.target = this.instance.currentItem[0];
1342                                         this.instance._mouseCapture(event, true);
1343                                         this.instance._mouseStart(event, true, true);
1345                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1346                                         this.instance.offset.click.top = inst.offset.click.top;
1347                                         this.instance.offset.click.left = inst.offset.click.left;
1348                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1349                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1351                                         inst._trigger("toSortable", event);
1352                                         inst.dropped = this.instance.element; //draggable revert needs that
1353                                         //hack so receive/update callbacks work (mostly)
1354                                         inst.currentItem = inst.element;
1355                                         this.instance.fromOutside = inst;
1357                                 }
1359                                 //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
1360                                 if(this.instance.currentItem) this.instance._mouseDrag(event);
1362                         } else {
1364                                 //If it doesn't intersect with the sortable, and it intersected before,
1365                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1366                                 if(this.instance.isOver) {
1368                                         this.instance.isOver = 0;
1369                                         this.instance.cancelHelperRemoval = true;
1370                                         
1371                                         //Prevent reverting on this forced stop
1372                                         this.instance.options.revert = false;
1373                                         
1374                                         // The out event needs to be triggered independently
1375                                         this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1376                                         
1377                                         this.instance._mouseStop(event, true);
1378                                         this.instance.options.helper = this.instance.options._helper;
1380                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1381                                         this.instance.currentItem.remove();
1382                                         if(this.instance.placeholder) this.instance.placeholder.remove();
1384                                         inst._trigger("fromSortable", event);
1385                                         inst.dropped = false; //draggable revert needs that
1386                                 }
1388                         };
1390                 });
1392         }
1395 $.ui.plugin.add("draggable", "cursor", {
1396         start: function(event, ui) {
1397                 var t = $('body'), o = $(this).data('draggable').options;
1398                 if (t.css("cursor")) o._cursor = t.css("cursor");
1399                 t.css("cursor", o.cursor);
1400         },
1401         stop: function(event, ui) {
1402                 var o = $(this).data('draggable').options;
1403                 if (o._cursor) $('body').css("cursor", o._cursor);
1404         }
1407 $.ui.plugin.add("draggable", "opacity", {
1408         start: function(event, ui) {
1409                 var t = $(ui.helper), o = $(this).data('draggable').options;
1410                 if(t.css("opacity")) o._opacity = t.css("opacity");
1411                 t.css('opacity', o.opacity);
1412         },
1413         stop: function(event, ui) {
1414                 var o = $(this).data('draggable').options;
1415                 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1416         }
1419 $.ui.plugin.add("draggable", "scroll", {
1420         start: function(event, ui) {
1421                 var i = $(this).data("draggable");
1422                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1423         },
1424         drag: function(event, ui) {
1426                 var i = $(this).data("draggable"), o = i.options, scrolled = false;
1428                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1430                         if(!o.axis || o.axis != 'x') {
1431                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1432                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1433                                 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1434                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1435                         }
1437                         if(!o.axis || o.axis != 'y') {
1438                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1439                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1440                                 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1441                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1442                         }
1444                 } else {
1446                         if(!o.axis || o.axis != 'x') {
1447                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1448                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1449                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1450                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1451                         }
1453                         if(!o.axis || o.axis != 'y') {
1454                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1455                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1456                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1457                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1458                         }
1460                 }
1462                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1463                         $.ui.ddmanager.prepareOffsets(i, event);
1465         }
1468 $.ui.plugin.add("draggable", "snap", {
1469         start: function(event, ui) {
1471                 var i = $(this).data("draggable"), o = i.options;
1472                 i.snapElements = [];
1474                 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1475                         var $t = $(this); var $o = $t.offset();
1476                         if(this != i.element[0]) i.snapElements.push({
1477                                 item: this,
1478                                 width: $t.outerWidth(), height: $t.outerHeight(),
1479                                 top: $o.top, left: $o.left
1480                         });
1481                 });
1483         },
1484         drag: function(event, ui) {
1486                 var inst = $(this).data("draggable"), o = inst.options;
1487                 var d = o.snapTolerance;
1489                 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1490                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1492                 for (var i = inst.snapElements.length - 1; i >= 0; i--){
1494                         var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1495                                 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1497                         //Yes, I know, this is insane ;)
1498                         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))) {
1499                                 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 })));
1500                                 inst.snapElements[i].snapping = false;
1501                                 continue;
1502                         }
1504                         if(o.snapMode != 'inner') {
1505                                 var ts = Math.abs(t - y2) <= d;
1506                                 var bs = Math.abs(b - y1) <= d;
1507                                 var ls = Math.abs(l - x2) <= d;
1508                                 var rs = Math.abs(r - x1) <= d;
1509                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1510                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1511                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1512                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1513                         }
1515                         var first = (ts || bs || ls || rs);
1517                         if(o.snapMode != 'outer') {
1518                                 var ts = Math.abs(t - y1) <= d;
1519                                 var bs = Math.abs(b - y2) <= d;
1520                                 var ls = Math.abs(l - x1) <= d;
1521                                 var rs = Math.abs(r - x2) <= d;
1522                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1523                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1524                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1525                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1526                         }
1528                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1529                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1530                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1532                 };
1534         }
1537 $.ui.plugin.add("draggable", "stack", {
1538         start: function(event, ui) {
1540                 var o = $(this).data("draggable").options;
1542                 var group = $.makeArray($(o.stack)).sort(function(a,b) {
1543                         return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1544                 });
1545                 if (!group.length) { return; }
1546                 
1547                 var min = parseInt(group[0].style.zIndex) || 0;
1548                 $(group).each(function(i) {
1549                         this.style.zIndex = min + i;
1550                 });
1552                 this[0].style.zIndex = min + group.length;
1554         }
1557 $.ui.plugin.add("draggable", "zIndex", {
1558         start: function(event, ui) {
1559                 var t = $(ui.helper), o = $(this).data("draggable").options;
1560                 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1561                 t.css('zIndex', o.zIndex);
1562         },
1563         stop: function(event, ui) {
1564                 var o = $(this).data("draggable").options;
1565                 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1566         }
1569 })(jQuery);
1571  * jQuery UI Droppable 1.8.16
1573  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1574  * Dual licensed under the MIT or GPL Version 2 licenses.
1575  * http://jquery.org/license
1577  * http://docs.jquery.com/UI/Droppables
1579  * Depends:
1580  *      jquery.ui.core.js
1581  *      jquery.ui.widget.js
1582  *      jquery.ui.mouse.js
1583  *      jquery.ui.draggable.js
1584  */
1585 (function( $, undefined ) {
1587 $.widget("ui.droppable", {
1588         widgetEventPrefix: "drop",
1589         options: {
1590                 accept: '*',
1591                 activeClass: false,
1592                 addClasses: true,
1593                 greedy: false,
1594                 hoverClass: false,
1595                 scope: 'default',
1596                 tolerance: 'intersect'
1597         },
1598         _create: function() {
1600                 var o = this.options, accept = o.accept;
1601                 this.isover = 0; this.isout = 1;
1603                 this.accept = $.isFunction(accept) ? accept : function(d) {
1604                         return d.is(accept);
1605                 };
1607                 //Store the droppable's proportions
1608                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1610                 // Add the reference and positions to the manager
1611                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1612                 $.ui.ddmanager.droppables[o.scope].push(this);
1614                 (o.addClasses && this.element.addClass("ui-droppable"));
1616         },
1618         destroy: function() {
1619                 var drop = $.ui.ddmanager.droppables[this.options.scope];
1620                 for ( var i = 0; i < drop.length; i++ )
1621                         if ( drop[i] == this )
1622                                 drop.splice(i, 1);
1624                 this.element
1625                         .removeClass("ui-droppable ui-droppable-disabled")
1626                         .removeData("droppable")
1627                         .unbind(".droppable");
1629                 return this;
1630         },
1632         _setOption: function(key, value) {
1634                 if(key == 'accept') {
1635                         this.accept = $.isFunction(value) ? value : function(d) {
1636                                 return d.is(value);
1637                         };
1638                 }
1639                 $.Widget.prototype._setOption.apply(this, arguments);
1640         },
1642         _activate: function(event) {
1643                 var draggable = $.ui.ddmanager.current;
1644                 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1645                 (draggable && this._trigger('activate', event, this.ui(draggable)));
1646         },
1648         _deactivate: function(event) {
1649                 var draggable = $.ui.ddmanager.current;
1650                 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1651                 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
1652         },
1654         _over: function(event) {
1656                 var draggable = $.ui.ddmanager.current;
1657                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1659                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1660                         if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1661                         this._trigger('over', event, this.ui(draggable));
1662                 }
1664         },
1666         _out: function(event) {
1668                 var draggable = $.ui.ddmanager.current;
1669                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1671                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1672                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1673                         this._trigger('out', event, this.ui(draggable));
1674                 }
1676         },
1678         _drop: function(event,custom) {
1680                 var draggable = custom || $.ui.ddmanager.current;
1681                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1683                 var childrenIntersection = false;
1684                 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1685                         var inst = $.data(this, 'droppable');
1686                         if(
1687                                 inst.options.greedy
1688                                 && !inst.options.disabled
1689                                 && inst.options.scope == draggable.options.scope
1690                                 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1691                                 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1692                         ) { childrenIntersection = true; return false; }
1693                 });
1694                 if(childrenIntersection) return false;
1696                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1697                         if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1698                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1699                         this._trigger('drop', event, this.ui(draggable));
1700                         return this.element;
1701                 }
1703                 return false;
1705         },
1707         ui: function(c) {
1708                 return {
1709                         draggable: (c.currentItem || c.element),
1710                         helper: c.helper,
1711                         position: c.position,
1712                         offset: c.positionAbs
1713                 };
1714         }
1718 $.extend($.ui.droppable, {
1719         version: "1.8.16"
1722 $.ui.intersect = function(draggable, droppable, toleranceMode) {
1724         if (!droppable.offset) return false;
1726         var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1727                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1728         var l = droppable.offset.left, r = l + droppable.proportions.width,
1729                 t = droppable.offset.top, b = t + droppable.proportions.height;
1731         switch (toleranceMode) {
1732                 case 'fit':
1733                         return (l <= x1 && x2 <= r
1734                                 && t <= y1 && y2 <= b);
1735                         break;
1736                 case 'intersect':
1737                         return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1738                                 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
1739                                 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1740                                 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1741                         break;
1742                 case 'pointer':
1743                         var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1744                                 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1745                                 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1746                         return isOver;
1747                         break;
1748                 case 'touch':
1749                         return (
1750                                         (y1 >= t && y1 <= b) || // Top edge touching
1751                                         (y2 >= t && y2 <= b) || // Bottom edge touching
1752                                         (y1 < t && y2 > b)              // Surrounded vertically
1753                                 ) && (
1754                                         (x1 >= l && x1 <= r) || // Left edge touching
1755                                         (x2 >= l && x2 <= r) || // Right edge touching
1756                                         (x1 < l && x2 > r)              // Surrounded horizontally
1757                                 );
1758                         break;
1759                 default:
1760                         return false;
1761                         break;
1762                 }
1767         This manager tracks offsets of draggables and droppables
1769 $.ui.ddmanager = {
1770         current: null,
1771         droppables: { 'default': [] },
1772         prepareOffsets: function(t, event) {
1774                 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
1775                 var type = event ? event.type : null; // workaround for #2317
1776                 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
1778                 droppablesLoop: for (var i = 0; i < m.length; i++) {
1780                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;   //No disabled and non-accepted
1781                         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
1782                         m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                       //If the element is not visible, continue
1784                         if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
1786                         m[i].offset = m[i].element.offset();
1787                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
1789                 }
1791         },
1792         drop: function(draggable, event) {
1794                 var dropped = false;
1795                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
1797                         if(!this.options) return;
1798                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
1799                                 dropped = dropped || this._drop.call(this, event);
1801                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1802                                 this.isout = 1; this.isover = 0;
1803                                 this._deactivate.call(this, event);
1804                         }
1806                 });
1807                 return dropped;
1809         },
1810         dragStart: function( draggable, event ) {
1811                 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
1812                 draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
1813                         if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
1814                 });
1815         },
1816         drag: function(draggable, event) {
1818                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
1819                 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
1821                 //Run through all droppables and check their positions based on specific tolerance options
1822                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
1824                         if(this.options.disabled || this.greedyChild || !this.visible) return;
1825                         var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
1827                         var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
1828                         if(!c) return;
1830                         var parentInstance;
1831                         if (this.options.greedy) {
1832                                 var parent = this.element.parents(':data(droppable):eq(0)');
1833                                 if (parent.length) {
1834                                         parentInstance = $.data(parent[0], 'droppable');
1835                                         parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
1836                                 }
1837                         }
1839                         // we just moved into a greedy child
1840                         if (parentInstance && c == 'isover') {
1841                                 parentInstance['isover'] = 0;
1842                                 parentInstance['isout'] = 1;
1843                                 parentInstance._out.call(parentInstance, event);
1844                         }
1846                         this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
1847                         this[c == "isover" ? "_over" : "_out"].call(this, event);
1849                         // we just moved out of a greedy child
1850                         if (parentInstance && c == 'isout') {
1851                                 parentInstance['isout'] = 0;
1852                                 parentInstance['isover'] = 1;
1853                                 parentInstance._over.call(parentInstance, event);
1854                         }
1855                 });
1857         },
1858         dragStop: function( draggable, event ) {
1859                 draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
1860                 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
1861                 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
1862         }
1865 })(jQuery);
1867  * jQuery UI Resizable 1.8.16
1869  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1870  * Dual licensed under the MIT or GPL Version 2 licenses.
1871  * http://jquery.org/license
1873  * http://docs.jquery.com/UI/Resizables
1875  * Depends:
1876  *      jquery.ui.core.js
1877  *      jquery.ui.mouse.js
1878  *      jquery.ui.widget.js
1879  */
1880 (function( $, undefined ) {
1882 $.widget("ui.resizable", $.ui.mouse, {
1883         widgetEventPrefix: "resize",
1884         options: {
1885                 alsoResize: false,
1886                 animate: false,
1887                 animateDuration: "slow",
1888                 animateEasing: "swing",
1889                 aspectRatio: false,
1890                 autoHide: false,
1891                 containment: false,
1892                 ghost: false,
1893                 grid: false,
1894                 handles: "e,s,se",
1895                 helper: false,
1896                 maxHeight: null,
1897                 maxWidth: null,
1898                 minHeight: 10,
1899                 minWidth: 10,
1900                 zIndex: 1000
1901         },
1902         _create: function() {
1904                 var self = this, o = this.options;
1905                 this.element.addClass("ui-resizable");
1907                 $.extend(this, {
1908                         _aspectRatio: !!(o.aspectRatio),
1909                         aspectRatio: o.aspectRatio,
1910                         originalElement: this.element,
1911                         _proportionallyResizeElements: [],
1912                         _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
1913                 });
1915                 //Wrap the element if it cannot hold child nodes
1916                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
1918                         //Opera fix for relative positioning
1919                         if (/relative/.test(this.element.css('position')) && $.browser.opera)
1920                                 this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
1922                         //Create a wrapper element and set the wrapper to the new current internal element
1923                         this.element.wrap(
1924                                 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
1925                                         position: this.element.css('position'),
1926                                         width: this.element.outerWidth(),
1927                                         height: this.element.outerHeight(),
1928                                         top: this.element.css('top'),
1929                                         left: this.element.css('left')
1930                                 })
1931                         );
1933                         //Overwrite the original this.element
1934                         this.element = this.element.parent().data(
1935                                 "resizable", this.element.data('resizable')
1936                         );
1938                         this.elementIsWrapper = true;
1940                         //Move margins to the wrapper
1941                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
1942                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
1944                         //Prevent Safari textarea resize
1945                         this.originalResizeStyle = this.originalElement.css('resize');
1946                         this.originalElement.css('resize', 'none');
1948                         //Push the actual element to our proportionallyResize internal array
1949                         this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
1951                         // avoid IE jump (hard set the margin)
1952                         this.originalElement.css({ margin: this.originalElement.css('margin') });
1954                         // fix handlers offset
1955                         this._proportionallyResize();
1957                 }
1959                 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' });
1960                 if(this.handles.constructor == String) {
1962                         if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
1963                         var n = this.handles.split(","); this.handles = {};
1965                         for(var i = 0; i < n.length; i++) {
1967                                 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
1968                                 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
1970                                 // increase zIndex of sw, se, ne, nw axis
1971                                 //TODO : this modifies original option
1972                                 if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
1974                                 //TODO : What's going on here?
1975                                 if ('se' == handle) {
1976                                         axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
1977                                 };
1979                                 //Insert into internal handles object and append to element
1980                                 this.handles[handle] = '.ui-resizable-'+handle;
1981                                 this.element.append(axis);
1982                         }
1984                 }
1986                 this._renderAxis = function(target) {
1988                         target = target || this.element;
1990                         for(var i in this.handles) {
1992                                 if(this.handles[i].constructor == String)
1993                                         this.handles[i] = $(this.handles[i], this.element).show();
1995                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
1996                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
1998                                         var axis = $(this.handles[i], this.element), padWrapper = 0;
2000                                         //Checking the correct pad and border
2001                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2003                                         //The padding type i have to apply...
2004                                         var padPos = [ 'padding',
2005                                                 /ne|nw|n/.test(i) ? 'Top' :
2006                                                 /se|sw|s/.test(i) ? 'Bottom' :
2007                                                 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
2009                                         target.css(padPos, padWrapper);
2011                                         this._proportionallyResize();
2013                                 }
2015                                 //TODO: What's that good for? There's not anything to be executed left
2016                                 if(!$(this.handles[i]).length)
2017                                         continue;
2019                         }
2020                 };
2022                 //TODO: make renderAxis a prototype function
2023                 this._renderAxis(this.element);
2025                 this._handles = $('.ui-resizable-handle', this.element)
2026                         .disableSelection();
2028                 //Matching axis name
2029                 this._handles.mouseover(function() {
2030                         if (!self.resizing) {
2031                                 if (this.className)
2032                                         var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2033                                 //Axis, default = se
2034                                 self.axis = axis && axis[1] ? axis[1] : 'se';
2035                         }
2036                 });
2038                 //If we want to auto hide the elements
2039                 if (o.autoHide) {
2040                         this._handles.hide();
2041                         $(this.element)
2042                                 .addClass("ui-resizable-autohide")
2043                                 .hover(function() {
2044                                         if (o.disabled) return;
2045                                         $(this).removeClass("ui-resizable-autohide");
2046                                         self._handles.show();
2047                                 },
2048                                 function(){
2049                                         if (o.disabled) return;
2050                                         if (!self.resizing) {
2051                                                 $(this).addClass("ui-resizable-autohide");
2052                                                 self._handles.hide();
2053                                         }
2054                                 });
2055                 }
2057                 //Initialize the mouse interaction
2058                 this._mouseInit();
2060         },
2062         destroy: function() {
2064                 this._mouseDestroy();
2066                 var _destroy = function(exp) {
2067                         $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2068                                 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2069                 };
2071                 //TODO: Unwrap at same DOM position
2072                 if (this.elementIsWrapper) {
2073                         _destroy(this.element);
2074                         var wrapper = this.element;
2075                         wrapper.after(
2076                                 this.originalElement.css({
2077                                         position: wrapper.css('position'),
2078                                         width: wrapper.outerWidth(),
2079                                         height: wrapper.outerHeight(),
2080                                         top: wrapper.css('top'),
2081                                         left: wrapper.css('left')
2082                                 })
2083                         ).remove();
2084                 }
2086                 this.originalElement.css('resize', this.originalResizeStyle);
2087                 _destroy(this.originalElement);
2089                 return this;
2090         },
2092         _mouseCapture: function(event) {
2093                 var handle = false;
2094                 for (var i in this.handles) {
2095                         if ($(this.handles[i])[0] == event.target) {
2096                                 handle = true;
2097                         }
2098                 }
2100                 return !this.options.disabled && handle;
2101         },
2103         _mouseStart: function(event) {
2105                 var o = this.options, iniPos = this.element.position(), el = this.element;
2107                 this.resizing = true;
2108                 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2110                 // bugfix for http://dev.jquery.com/ticket/1749
2111                 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2112                         el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2113                 }
2115                 //Opera fixing relative position
2116                 if ($.browser.opera && (/relative/).test(el.css('position')))
2117                         el.css({ position: 'relative', top: 'auto', left: 'auto' });
2119                 this._renderProxy();
2121                 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2123                 if (o.containment) {
2124                         curleft += $(o.containment).scrollLeft() || 0;
2125                         curtop += $(o.containment).scrollTop() || 0;
2126                 }
2128                 //Store needed variables
2129                 this.offset = this.helper.offset();
2130                 this.position = { left: curleft, top: curtop };
2131                 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2132                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2133                 this.originalPosition = { left: curleft, top: curtop };
2134                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2135                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2137                 //Aspect Ratio
2138                 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2140             var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2141             $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2143                 el.addClass("ui-resizable-resizing");
2144                 this._propagate("start", event);
2145                 return true;
2146         },
2148         _mouseDrag: function(event) {
2150                 //Increase performance, avoid regex
2151                 var el = this.helper, o = this.options, props = {},
2152                         self = this, smp = this.originalMousePosition, a = this.axis;
2154                 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2155                 var trigger = this._change[a];
2156                 if (!trigger) return false;
2158                 // Calculate the attrs that will be change
2159                 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2161                 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2162                 this._updateVirtualBoundaries(event.shiftKey);
2163                 if (this._aspectRatio || event.shiftKey)
2164                         data = this._updateRatio(data, event);
2166                 data = this._respectSize(data, event);
2168                 // plugins callbacks need to be called first
2169                 this._propagate("resize", event);
2171                 el.css({
2172                         top: this.position.top + "px", left: this.position.left + "px",
2173                         width: this.size.width + "px", height: this.size.height + "px"
2174                 });
2176                 if (!this._helper && this._proportionallyResizeElements.length)
2177                         this._proportionallyResize();
2179                 this._updateCache(data);
2181                 // calling the user callback at the end
2182                 this._trigger('resize', event, this.ui());
2184                 return false;
2185         },
2187         _mouseStop: function(event) {
2189                 this.resizing = false;
2190                 var o = this.options, self = this;
2192                 if(this._helper) {
2193                         var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2194                                 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2195                                 soffsetw = ista ? 0 : self.sizeDiff.width;
2197                         var s = { width: (self.helper.width()  - soffsetw), height: (self.helper.height() - soffseth) },
2198                                 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2199                                 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2201                         if (!o.animate)
2202                                 this.element.css($.extend(s, { top: top, left: left }));
2204                         self.helper.height(self.size.height);
2205                         self.helper.width(self.size.width);
2207                         if (this._helper && !o.animate) this._proportionallyResize();
2208                 }
2210                 $('body').css('cursor', 'auto');
2212                 this.element.removeClass("ui-resizable-resizing");
2214                 this._propagate("stop", event);
2216                 if (this._helper) this.helper.remove();
2217                 return false;
2219         },
2221     _updateVirtualBoundaries: function(forceAspectRatio) {
2222         var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2224         b = {
2225             minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2226             maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2227             minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2228             maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2229         };
2231         if(this._aspectRatio || forceAspectRatio) {
2232             // We want to create an enclosing box whose aspect ration is the requested one
2233             // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2234             pMinWidth = b.minHeight * this.aspectRatio;
2235             pMinHeight = b.minWidth / this.aspectRatio;
2236             pMaxWidth = b.maxHeight * this.aspectRatio;
2237             pMaxHeight = b.maxWidth / this.aspectRatio;
2239             if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2240             if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2241             if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2242             if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2243         }
2244         this._vBoundaries = b;
2245     },
2247         _updateCache: function(data) {
2248                 var o = this.options;
2249                 this.offset = this.helper.offset();
2250                 if (isNumber(data.left)) this.position.left = data.left;
2251                 if (isNumber(data.top)) this.position.top = data.top;
2252                 if (isNumber(data.height)) this.size.height = data.height;
2253                 if (isNumber(data.width)) this.size.width = data.width;
2254         },
2256         _updateRatio: function(data, event) {
2258                 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2260                 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2261                 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2263                 if (a == 'sw') {
2264                         data.left = cpos.left + (csize.width - data.width);
2265                         data.top = null;
2266                 }
2267                 if (a == 'nw') {
2268                         data.top = cpos.top + (csize.height - data.height);
2269                         data.left = cpos.left + (csize.width - data.width);
2270                 }
2272                 return data;
2273         },
2275         _respectSize: function(data, event) {
2277                 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2278                                 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2279                                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2281                 if (isminw) data.width = o.minWidth;
2282                 if (isminh) data.height = o.minHeight;
2283                 if (ismaxw) data.width = o.maxWidth;
2284                 if (ismaxh) data.height = o.maxHeight;
2286                 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2287                 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2289                 if (isminw && cw) data.left = dw - o.minWidth;
2290                 if (ismaxw && cw) data.left = dw - o.maxWidth;
2291                 if (isminh && ch)       data.top = dh - o.minHeight;
2292                 if (ismaxh && ch)       data.top = dh - o.maxHeight;
2294                 // fixing jump error on top/left - bug #2330
2295                 var isNotwh = !data.width && !data.height;
2296                 if (isNotwh && !data.left && data.top) data.top = null;
2297                 else if (isNotwh && !data.top && data.left) data.left = null;
2299                 return data;
2300         },
2302         _proportionallyResize: function() {
2304                 var o = this.options;
2305                 if (!this._proportionallyResizeElements.length) return;
2306                 var element = this.helper || this.element;
2308                 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2310                         var prel = this._proportionallyResizeElements[i];
2312                         if (!this.borderDif) {
2313                                 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2314                                         p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2316                                 this.borderDif = $.map(b, function(v, i) {
2317                                         var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2318                                         return border + padding;
2319                                 });
2320                         }
2322                         if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2323                                 continue;
2325                         prel.css({
2326                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2327                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2328                         });
2330                 };
2332         },
2334         _renderProxy: function() {
2336                 var el = this.element, o = this.options;
2337                 this.elementOffset = el.offset();
2339                 if(this._helper) {
2341                         this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2343                         // fix ie6 offset TODO: This seems broken
2344                         var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2345                         pxyoffset = ( ie6 ? 2 : -1 );
2347                         this.helper.addClass(this._helper).css({
2348                                 width: this.element.outerWidth() + pxyoffset,
2349                                 height: this.element.outerHeight() + pxyoffset,
2350                                 position: 'absolute',
2351                                 left: this.elementOffset.left - ie6offset +'px',
2352                                 top: this.elementOffset.top - ie6offset +'px',
2353                                 zIndex: ++o.zIndex //TODO: Don't modify option
2354                         });
2356                         this.helper
2357                                 .appendTo("body")
2358                                 .disableSelection();
2360                 } else {
2361                         this.helper = this.element;
2362                 }
2364         },
2366         _change: {
2367                 e: function(event, dx, dy) {
2368                         return { width: this.originalSize.width + dx };
2369                 },
2370                 w: function(event, dx, dy) {
2371                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2372                         return { left: sp.left + dx, width: cs.width - dx };
2373                 },
2374                 n: function(event, dx, dy) {
2375                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2376                         return { top: sp.top + dy, height: cs.height - dy };
2377                 },
2378                 s: function(event, dx, dy) {
2379                         return { height: this.originalSize.height + dy };
2380                 },
2381                 se: function(event, dx, dy) {
2382                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2383                 },
2384                 sw: function(event, dx, dy) {
2385                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2386                 },
2387                 ne: function(event, dx, dy) {
2388                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2389                 },
2390                 nw: function(event, dx, dy) {
2391                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2392                 }
2393         },
2395         _propagate: function(n, event) {
2396                 $.ui.plugin.call(this, n, [event, this.ui()]);
2397                 (n != "resize" && this._trigger(n, event, this.ui()));
2398         },
2400         plugins: {},
2402         ui: function() {
2403                 return {
2404                         originalElement: this.originalElement,
2405                         element: this.element,
2406                         helper: this.helper,
2407                         position: this.position,
2408                         size: this.size,
2409                         originalSize: this.originalSize,
2410                         originalPosition: this.originalPosition
2411                 };
2412         }
2416 $.extend($.ui.resizable, {
2417         version: "1.8.16"
2421  * Resizable Extensions
2422  */
2424 $.ui.plugin.add("resizable", "alsoResize", {
2426         start: function (event, ui) {
2427                 var self = $(this).data("resizable"), o = self.options;
2429                 var _store = function (exp) {
2430                         $(exp).each(function() {
2431                                 var el = $(this);
2432                                 el.data("resizable-alsoresize", {
2433                                         width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2434                                         left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
2435                                         position: el.css('position') // to reset Opera on stop()
2436                                 });
2437                         });
2438                 };
2440                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2441                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2442                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2443                 }else{
2444                         _store(o.alsoResize);
2445                 }
2446         },
2448         resize: function (event, ui) {
2449                 var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2451                 var delta = {
2452                         height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2453                         top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2454                 },
2456                 _alsoResize = function (exp, c) {
2457                         $(exp).each(function() {
2458                                 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 
2459                                         css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2461                                 $.each(css, function (i, prop) {
2462                                         var sum = (start[prop]||0) + (delta[prop]||0);
2463                                         if (sum && sum >= 0)
2464                                                 style[prop] = sum || null;
2465                                 });
2467                                 // Opera fixing relative position
2468                                 if ($.browser.opera && /relative/.test(el.css('position'))) {
2469                                         self._revertToRelativePosition = true;
2470                                         el.css({ position: 'absolute', top: 'auto', left: 'auto' });
2471                                 }
2473                                 el.css(style);
2474                         });
2475                 };
2477                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2478                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2479                 }else{
2480                         _alsoResize(o.alsoResize);
2481                 }
2482         },
2484         stop: function (event, ui) {
2485                 var self = $(this).data("resizable"), o = self.options;
2487                 var _reset = function (exp) {
2488                         $(exp).each(function() {
2489                                 var el = $(this);
2490                                 // reset position for Opera - no need to verify it was changed
2491                                 el.css({ position: el.data("resizable-alsoresize").position });
2492                         });
2493                 };
2495                 if (self._revertToRelativePosition) {
2496                         self._revertToRelativePosition = false;
2497                         if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2498                                 $.each(o.alsoResize, function (exp) { _reset(exp); });
2499                         }else{
2500                                 _reset(o.alsoResize);
2501                         }
2502                 }
2504                 $(this).removeData("resizable-alsoresize");
2505         }
2508 $.ui.plugin.add("resizable", "animate", {
2510         stop: function(event, ui) {
2511                 var self = $(this).data("resizable"), o = self.options;
2513                 var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2514                                         soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2515                                                 soffsetw = ista ? 0 : self.sizeDiff.width;
2517                 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2518                                         left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2519                                                 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2521                 self.element.animate(
2522                         $.extend(style, top && left ? { top: top, left: left } : {}), {
2523                                 duration: o.animateDuration,
2524                                 easing: o.animateEasing,
2525                                 step: function() {
2527                                         var data = {
2528                                                 width: parseInt(self.element.css('width'), 10),
2529                                                 height: parseInt(self.element.css('height'), 10),
2530                                                 top: parseInt(self.element.css('top'), 10),
2531                                                 left: parseInt(self.element.css('left'), 10)
2532                                         };
2534                                         if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2536                                         // propagating resize, and updating values for each animation step
2537                                         self._updateCache(data);
2538                                         self._propagate("resize", event);
2540                                 }
2541                         }
2542                 );
2543         }
2547 $.ui.plugin.add("resizable", "containment", {
2549         start: function(event, ui) {
2550                 var self = $(this).data("resizable"), o = self.options, el = self.element;
2551                 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2552                 if (!ce) return;
2554                 self.containerElement = $(ce);
2556                 if (/document/.test(oc) || oc == document) {
2557                         self.containerOffset = { left: 0, top: 0 };
2558                         self.containerPosition = { left: 0, top: 0 };
2560                         self.parentData = {
2561                                 element: $(document), left: 0, top: 0,
2562                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2563                         };
2564                 }
2566                 // i'm a node, so compute top, left, right, bottom
2567                 else {
2568                         var element = $(ce), p = [];
2569                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2571                         self.containerOffset = element.offset();
2572                         self.containerPosition = element.position();
2573                         self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2575                         var co = self.containerOffset, ch = self.containerSize.height,  cw = self.containerSize.width,
2576                                                 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2578                         self.parentData = {
2579                                 element: ce, left: co.left, top: co.top, width: width, height: height
2580                         };
2581                 }
2582         },
2584         resize: function(event, ui) {
2585                 var self = $(this).data("resizable"), o = self.options,
2586                                 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2587                                 pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2589                 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2591                 if (cp.left < (self._helper ? co.left : 0)) {
2592                         self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2593                         if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2594                         self.position.left = o.helper ? co.left : 0;
2595                 }
2597                 if (cp.top < (self._helper ? co.top : 0)) {
2598                         self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2599                         if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2600                         self.position.top = self._helper ? co.top : 0;
2601                 }
2603                 self.offset.left = self.parentData.left+self.position.left;
2604                 self.offset.top = self.parentData.top+self.position.top;
2606                 var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2607                                         hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2609                 var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2610                     isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2612                 if(isParent && isOffsetRelative) woset -= self.parentData.left;
2614                 if (woset + self.size.width >= self.parentData.width) {
2615                         self.size.width = self.parentData.width - woset;
2616                         if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2617                 }
2619                 if (hoset + self.size.height >= self.parentData.height) {
2620                         self.size.height = self.parentData.height - hoset;
2621                         if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2622                 }
2623         },
2625         stop: function(event, ui){
2626                 var self = $(this).data("resizable"), o = self.options, cp = self.position,
2627                                 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2629                 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2631                 if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2632                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2634                 if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2635                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2637         }
2640 $.ui.plugin.add("resizable", "ghost", {
2642         start: function(event, ui) {
2644                 var self = $(this).data("resizable"), o = self.options, cs = self.size;
2646                 self.ghost = self.originalElement.clone();
2647                 self.ghost
2648                         .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2649                         .addClass('ui-resizable-ghost')
2650                         .addClass(typeof o.ghost == 'string' ? o.ghost : '');
2652                 self.ghost.appendTo(self.helper);
2654         },
2656         resize: function(event, ui){
2657                 var self = $(this).data("resizable"), o = self.options;
2658                 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2659         },
2661         stop: function(event, ui){
2662                 var self = $(this).data("resizable"), o = self.options;
2663                 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2664         }
2668 $.ui.plugin.add("resizable", "grid", {
2670         resize: function(event, ui) {
2671                 var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
2672                 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2673                 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);
2675                 if (/^(se|s|e)$/.test(a)) {
2676                         self.size.width = os.width + ox;
2677                         self.size.height = os.height + oy;
2678                 }
2679                 else if (/^(ne)$/.test(a)) {
2680                         self.size.width = os.width + ox;
2681                         self.size.height = os.height + oy;
2682                         self.position.top = op.top - oy;
2683                 }
2684                 else if (/^(sw)$/.test(a)) {
2685                         self.size.width = os.width + ox;
2686                         self.size.height = os.height + oy;
2687                         self.position.left = op.left - ox;
2688                 }
2689                 else {
2690                         self.size.width = os.width + ox;
2691                         self.size.height = os.height + oy;
2692                         self.position.top = op.top - oy;
2693                         self.position.left = op.left - ox;
2694                 }
2695         }
2699 var num = function(v) {
2700         return parseInt(v, 10) || 0;
2703 var isNumber = function(value) {
2704         return !isNaN(parseInt(value, 10));
2707 })(jQuery);
2709  * jQuery UI Selectable 1.8.16
2711  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2712  * Dual licensed under the MIT or GPL Version 2 licenses.
2713  * http://jquery.org/license
2715  * http://docs.jquery.com/UI/Selectables
2717  * Depends:
2718  *      jquery.ui.core.js
2719  *      jquery.ui.mouse.js
2720  *      jquery.ui.widget.js
2721  */
2722 (function( $, undefined ) {
2724 $.widget("ui.selectable", $.ui.mouse, {
2725         options: {
2726                 appendTo: 'body',
2727                 autoRefresh: true,
2728                 distance: 0,
2729                 filter: '*',
2730                 tolerance: 'touch'
2731         },
2732         _create: function() {
2733                 var self = this;
2735                 this.element.addClass("ui-selectable");
2737                 this.dragged = false;
2739                 // cache selectee children based on filter
2740                 var selectees;
2741                 this.refresh = function() {
2742                         selectees = $(self.options.filter, self.element[0]);
2743                         selectees.each(function() {
2744                                 var $this = $(this);
2745                                 var pos = $this.offset();
2746                                 $.data(this, "selectable-item", {
2747                                         element: this,
2748                                         $element: $this,
2749                                         left: pos.left,
2750                                         top: pos.top,
2751                                         right: pos.left + $this.outerWidth(),
2752                                         bottom: pos.top + $this.outerHeight(),
2753                                         startselected: false,
2754                                         selected: $this.hasClass('ui-selected'),
2755                                         selecting: $this.hasClass('ui-selecting'),
2756                                         unselecting: $this.hasClass('ui-unselecting')
2757                                 });
2758                         });
2759                 };
2760                 this.refresh();
2762                 this.selectees = selectees.addClass("ui-selectee");
2764                 this._mouseInit();
2766                 this.helper = $("<div class='ui-selectable-helper'></div>");
2767         },
2769         destroy: function() {
2770                 this.selectees
2771                         .removeClass("ui-selectee")
2772                         .removeData("selectable-item");
2773                 this.element
2774                         .removeClass("ui-selectable ui-selectable-disabled")
2775                         .removeData("selectable")
2776                         .unbind(".selectable");
2777                 this._mouseDestroy();
2779                 return this;
2780         },
2782         _mouseStart: function(event) {
2783                 var self = this;
2785                 this.opos = [event.pageX, event.pageY];
2787                 if (this.options.disabled)
2788                         return;
2790                 var options = this.options;
2792                 this.selectees = $(options.filter, this.element[0]);
2794                 this._trigger("start", event);
2796                 $(options.appendTo).append(this.helper);
2797                 // position helper (lasso)
2798                 this.helper.css({
2799                         "left": event.clientX,
2800                         "top": event.clientY,
2801                         "width": 0,
2802                         "height": 0
2803                 });
2805                 if (options.autoRefresh) {
2806                         this.refresh();
2807                 }
2809                 this.selectees.filter('.ui-selected').each(function() {
2810                         var selectee = $.data(this, "selectable-item");
2811                         selectee.startselected = true;
2812                         if (!event.metaKey) {
2813                                 selectee.$element.removeClass('ui-selected');
2814                                 selectee.selected = false;
2815                                 selectee.$element.addClass('ui-unselecting');
2816                                 selectee.unselecting = true;
2817                                 // selectable UNSELECTING callback
2818                                 self._trigger("unselecting", event, {
2819                                         unselecting: selectee.element
2820                                 });
2821                         }
2822                 });
2824                 $(event.target).parents().andSelf().each(function() {
2825                         var selectee = $.data(this, "selectable-item");
2826                         if (selectee) {
2827                                 var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
2828                                 selectee.$element
2829                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
2830                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
2831                                 selectee.unselecting = !doSelect;
2832                                 selectee.selecting = doSelect;
2833                                 selectee.selected = doSelect;
2834                                 // selectable (UN)SELECTING callback
2835                                 if (doSelect) {
2836                                         self._trigger("selecting", event, {
2837                                                 selecting: selectee.element
2838                                         });
2839                                 } else {
2840                                         self._trigger("unselecting", event, {
2841                                                 unselecting: selectee.element
2842                                         });
2843                                 }
2844                                 return false;
2845                         }
2846                 });
2848         },
2850         _mouseDrag: function(event) {
2851                 var self = this;
2852                 this.dragged = true;
2854                 if (this.options.disabled)
2855                         return;
2857                 var options = this.options;
2859                 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
2860                 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
2861                 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
2862                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
2864                 this.selectees.each(function() {
2865                         var selectee = $.data(this, "selectable-item");
2866                         //prevent helper from being selected if appendTo: selectable
2867                         if (!selectee || selectee.element == self.element[0])
2868                                 return;
2869                         var hit = false;
2870                         if (options.tolerance == 'touch') {
2871                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
2872                         } else if (options.tolerance == 'fit') {
2873                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
2874                         }
2876                         if (hit) {
2877                                 // SELECT
2878                                 if (selectee.selected) {
2879                                         selectee.$element.removeClass('ui-selected');
2880                                         selectee.selected = false;
2881                                 }
2882                                 if (selectee.unselecting) {
2883                                         selectee.$element.removeClass('ui-unselecting');
2884                                         selectee.unselecting = false;
2885                                 }
2886                                 if (!selectee.selecting) {
2887                                         selectee.$element.addClass('ui-selecting');
2888                                         selectee.selecting = true;
2889                                         // selectable SELECTING callback
2890                                         self._trigger("selecting", event, {
2891                                                 selecting: selectee.element
2892                                         });
2893                                 }
2894                         } else {
2895                                 // UNSELECT
2896                                 if (selectee.selecting) {
2897                                         if (event.metaKey && selectee.startselected) {
2898                                                 selectee.$element.removeClass('ui-selecting');
2899                                                 selectee.selecting = false;
2900                                                 selectee.$element.addClass('ui-selected');
2901                                                 selectee.selected = true;
2902                                         } else {
2903                                                 selectee.$element.removeClass('ui-selecting');
2904                                                 selectee.selecting = false;
2905                                                 if (selectee.startselected) {
2906                                                         selectee.$element.addClass('ui-unselecting');
2907                                                         selectee.unselecting = true;
2908                                                 }
2909                                                 // selectable UNSELECTING callback
2910                                                 self._trigger("unselecting", event, {
2911                                                         unselecting: selectee.element
2912                                                 });
2913                                         }
2914                                 }
2915                                 if (selectee.selected) {
2916                                         if (!event.metaKey && !selectee.startselected) {
2917                                                 selectee.$element.removeClass('ui-selected');
2918                                                 selectee.selected = false;
2920                                                 selectee.$element.addClass('ui-unselecting');
2921                                                 selectee.unselecting = true;
2922                                                 // selectable UNSELECTING callback
2923                                                 self._trigger("unselecting", event, {
2924                                                         unselecting: selectee.element
2925                                                 });
2926                                         }
2927                                 }
2928                         }
2929                 });
2931                 return false;
2932         },
2934         _mouseStop: function(event) {
2935                 var self = this;
2937                 this.dragged = false;
2939                 var options = this.options;
2941                 $('.ui-unselecting', this.element[0]).each(function() {
2942                         var selectee = $.data(this, "selectable-item");
2943                         selectee.$element.removeClass('ui-unselecting');
2944                         selectee.unselecting = false;
2945                         selectee.startselected = false;
2946                         self._trigger("unselected", event, {
2947                                 unselected: selectee.element
2948                         });
2949                 });
2950                 $('.ui-selecting', this.element[0]).each(function() {
2951                         var selectee = $.data(this, "selectable-item");
2952                         selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
2953                         selectee.selecting = false;
2954                         selectee.selected = true;
2955                         selectee.startselected = true;
2956                         self._trigger("selected", event, {
2957                                 selected: selectee.element
2958                         });
2959                 });
2960                 this._trigger("stop", event);
2962                 this.helper.remove();
2964                 return false;
2965         }
2969 $.extend($.ui.selectable, {
2970         version: "1.8.16"
2973 })(jQuery);
2975  * jQuery UI Sortable 1.8.16
2977  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2978  * Dual licensed under the MIT or GPL Version 2 licenses.
2979  * http://jquery.org/license
2981  * http://docs.jquery.com/UI/Sortables
2983  * Depends:
2984  *      jquery.ui.core.js
2985  *      jquery.ui.mouse.js
2986  *      jquery.ui.widget.js
2987  */
2988 (function( $, undefined ) {
2990 $.widget("ui.sortable", $.ui.mouse, {
2991         widgetEventPrefix: "sort",
2992         options: {
2993                 appendTo: "parent",
2994                 axis: false,
2995                 connectWith: false,
2996                 containment: false,
2997                 cursor: 'auto',
2998                 cursorAt: false,
2999                 dropOnEmpty: true,
3000                 forcePlaceholderSize: false,
3001                 forceHelperSize: false,
3002                 grid: false,
3003                 handle: false,
3004                 helper: "original",
3005                 items: '> *',
3006                 opacity: false,
3007                 placeholder: false,
3008                 revert: false,
3009                 scroll: true,
3010                 scrollSensitivity: 20,
3011                 scrollSpeed: 20,
3012                 scope: "default",
3013                 tolerance: "intersect",
3014                 zIndex: 1000
3015         },
3016         _create: function() {
3018                 var o = this.options;
3019                 this.containerCache = {};
3020                 this.element.addClass("ui-sortable");
3022                 //Get the items
3023                 this.refresh();
3025                 //Let's determine if the items are being displayed horizontally
3026                 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;
3028                 //Let's determine the parent's offset
3029                 this.offset = this.element.offset();
3031                 //Initialize mouse events for interaction
3032                 this._mouseInit();
3034         },
3036         destroy: function() {
3037                 this.element
3038                         .removeClass("ui-sortable ui-sortable-disabled")
3039                         .removeData("sortable")
3040                         .unbind(".sortable");
3041                 this._mouseDestroy();
3043                 for ( var i = this.items.length - 1; i >= 0; i-- )
3044                         this.items[i].item.removeData("sortable-item");
3046                 return this;
3047         },
3049         _setOption: function(key, value){
3050                 if ( key === "disabled" ) {
3051                         this.options[ key ] = value;
3052         
3053                         this.widget()
3054                                 [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3055                 } else {
3056                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3057                         $.Widget.prototype._setOption.apply(this, arguments);
3058                 }
3059         },
3061         _mouseCapture: function(event, overrideHandle) {
3063                 if (this.reverting) {
3064                         return false;
3065                 }
3067                 if(this.options.disabled || this.options.type == 'static') return false;
3069                 //We have to refresh the items data once first
3070                 this._refreshItems(event);
3072                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3073                 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
3074                         if($.data(this, 'sortable-item') == self) {
3075                                 currentItem = $(this);
3076                                 return false;
3077                         }
3078                 });
3079                 if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
3081                 if(!currentItem) return false;
3082                 if(this.options.handle && !overrideHandle) {
3083                         var validHandle = false;
3085                         $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3086                         if(!validHandle) return false;
3087                 }
3089                 this.currentItem = currentItem;
3090                 this._removeCurrentsFromItems();
3091                 return true;
3093         },
3095         _mouseStart: function(event, overrideHandle, noActivation) {
3097                 var o = this.options, self = this;
3098                 this.currentContainer = this;
3100                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3101                 this.refreshPositions();
3103                 //Create and append the visible helper
3104                 this.helper = this._createHelper(event);
3106                 //Cache the helper size
3107                 this._cacheHelperProportions();
3109                 /*
3110                  * - Position generation -
3111                  * This block generates everything position related - it's the core of draggables.
3112                  */
3114                 //Cache the margins of the original element
3115                 this._cacheMargins();
3117                 //Get the next scrolling parent
3118                 this.scrollParent = this.helper.scrollParent();
3120                 //The element's absolute position on the page minus margins
3121                 this.offset = this.currentItem.offset();
3122                 this.offset = {
3123                         top: this.offset.top - this.margins.top,
3124                         left: this.offset.left - this.margins.left
3125                 };
3127                 // Only after we got the offset, we can change the helper's position to absolute
3128                 // TODO: Still need to figure out a way to make relative sorting possible
3129                 this.helper.css("position", "absolute");
3130                 this.cssPosition = this.helper.css("position");
3132                 $.extend(this.offset, {
3133                         click: { //Where the click happened, relative to the element
3134                                 left: event.pageX - this.offset.left,
3135                                 top: event.pageY - this.offset.top
3136                         },
3137                         parent: this._getParentOffset(),
3138                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3139                 });
3141                 //Generate the original position
3142                 this.originalPosition = this._generatePosition(event);
3143                 this.originalPageX = event.pageX;
3144                 this.originalPageY = event.pageY;
3146                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3147                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3149                 //Cache the former DOM position
3150                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3152                 //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
3153                 if(this.helper[0] != this.currentItem[0]) {
3154                         this.currentItem.hide();
3155                 }
3157                 //Create the placeholder
3158                 this._createPlaceholder();
3160                 //Set a containment if given in the options
3161                 if(o.containment)
3162                         this._setContainment();
3164                 if(o.cursor) { // cursor option
3165                         if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3166                         $('body').css("cursor", o.cursor);
3167                 }
3169                 if(o.opacity) { // opacity option
3170                         if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3171                         this.helper.css("opacity", o.opacity);
3172                 }
3174                 if(o.zIndex) { // zIndex option
3175                         if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3176                         this.helper.css("zIndex", o.zIndex);
3177                 }
3179                 //Prepare scrolling
3180                 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3181                         this.overflowOffset = this.scrollParent.offset();
3183                 //Call callbacks
3184                 this._trigger("start", event, this._uiHash());
3186                 //Recache the helper size
3187                 if(!this._preserveHelperProportions)
3188                         this._cacheHelperProportions();
3191                 //Post 'activate' events to possible containers
3192                 if(!noActivation) {
3193                          for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3194                 }
3196                 //Prepare possible droppables
3197                 if($.ui.ddmanager)
3198                         $.ui.ddmanager.current = this;
3200                 if ($.ui.ddmanager && !o.dropBehaviour)
3201                         $.ui.ddmanager.prepareOffsets(this, event);
3203                 this.dragging = true;
3205                 this.helper.addClass("ui-sortable-helper");
3206                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3207                 return true;
3209         },
3211         _mouseDrag: function(event) {
3213                 //Compute the helpers position
3214                 this.position = this._generatePosition(event);
3215                 this.positionAbs = this._convertPositionTo("absolute");
3217                 if (!this.lastPositionAbs) {
3218                         this.lastPositionAbs = this.positionAbs;
3219                 }
3221                 //Do scrolling
3222                 if(this.options.scroll) {
3223                         var o = this.options, scrolled = false;
3224                         if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3226                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3227                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3228                                 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3229                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3231                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3232                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3233                                 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3234                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3236                         } else {
3238                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3239                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3240                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3241                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3243                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3244                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3245                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3246                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3248                         }
3250                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3251                                 $.ui.ddmanager.prepareOffsets(this, event);
3252                 }
3254                 //Regenerate the absolute position used for position checks
3255                 this.positionAbs = this._convertPositionTo("absolute");
3257                 //Set the helper position
3258                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3259                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3261                 //Rearrange
3262                 for (var i = this.items.length - 1; i >= 0; i--) {
3264                         //Cache variables and intersection, continue if no intersection
3265                         var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3266                         if (!intersection) continue;
3268                         if(itemElement != this.currentItem[0] //cannot intersect with itself
3269                                 &&      this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3270                                 &&      !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3271                                 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3272                                 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3273                         ) {
3275                                 this.direction = intersection == 1 ? "down" : "up";
3277                                 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3278                                         this._rearrange(event, item);
3279                                 } else {
3280                                         break;
3281                                 }
3283                                 this._trigger("change", event, this._uiHash());
3284                                 break;
3285                         }
3286                 }
3288                 //Post events to containers
3289                 this._contactContainers(event);
3291                 //Interconnect with droppables
3292                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3294                 //Call callbacks
3295                 this._trigger('sort', event, this._uiHash());
3297                 this.lastPositionAbs = this.positionAbs;
3298                 return false;
3300         },
3302         _mouseStop: function(event, noPropagation) {
3304                 if(!event) return;
3306                 //If we are using droppables, inform the manager about the drop
3307                 if ($.ui.ddmanager && !this.options.dropBehaviour)
3308                         $.ui.ddmanager.drop(this, event);
3310                 if(this.options.revert) {
3311                         var self = this;
3312                         var cur = self.placeholder.offset();
3314                         self.reverting = true;
3316                         $(this.helper).animate({
3317                                 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3318                                 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3319                         }, parseInt(this.options.revert, 10) || 500, function() {
3320                                 self._clear(event);
3321                         });
3322                 } else {
3323                         this._clear(event, noPropagation);
3324                 }
3326                 return false;
3328         },
3330         cancel: function() {
3332                 var self = this;
3334                 if(this.dragging) {
3336                         this._mouseUp({ target: null });
3338                         if(this.options.helper == "original")
3339                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3340                         else
3341                                 this.currentItem.show();
3343                         //Post deactivating events to containers
3344                         for (var i = this.containers.length - 1; i >= 0; i--){
3345                                 this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3346                                 if(this.containers[i].containerCache.over) {
3347                                         this.containers[i]._trigger("out", null, self._uiHash(this));
3348                                         this.containers[i].containerCache.over = 0;
3349                                 }
3350                         }
3352                 }
3354                 if (this.placeholder) {
3355                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3356                         if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3357                         if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3359                         $.extend(this, {
3360                                 helper: null,
3361                                 dragging: false,
3362                                 reverting: false,
3363                                 _noFinalSort: null
3364                         });
3366                         if(this.domPosition.prev) {
3367                                 $(this.domPosition.prev).after(this.currentItem);
3368                         } else {
3369                                 $(this.domPosition.parent).prepend(this.currentItem);
3370                         }
3371                 }
3373                 return this;
3375         },
3377         serialize: function(o) {
3379                 var items = this._getItemsAsjQuery(o && o.connected);
3380                 var str = []; o = o || {};
3382                 $(items).each(function() {
3383                         var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3384                         if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3385                 });
3387                 if(!str.length && o.key) {
3388                         str.push(o.key + '=');
3389                 }
3391                 return str.join('&');
3393         },
3395         toArray: function(o) {
3397                 var items = this._getItemsAsjQuery(o && o.connected);
3398                 var ret = []; o = o || {};
3400                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3401                 return ret;
3403         },
3405         /* Be careful with the following core functions */
3406         _intersectsWith: function(item) {
3408                 var x1 = this.positionAbs.left,
3409                         x2 = x1 + this.helperProportions.width,
3410                         y1 = this.positionAbs.top,
3411                         y2 = y1 + this.helperProportions.height;
3413                 var l = item.left,
3414                         r = l + item.width,
3415                         t = item.top,
3416                         b = t + item.height;
3418                 var dyClick = this.offset.click.top,
3419                         dxClick = this.offset.click.left;
3421                 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3423                 if(        this.options.tolerance == "pointer"
3424                         || this.options.forcePointerForContainers
3425                         || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3426                 ) {
3427                         return isOverElement;
3428                 } else {
3430                         return (l < x1 + (this.helperProportions.width / 2) // Right Half
3431                                 && x2 - (this.helperProportions.width / 2) < r // Left Half
3432                                 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3433                                 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
3435                 }
3436         },
3438         _intersectsWithPointer: function(item) {
3440                 var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3441                         isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3442                         isOverElement = isOverElementHeight && isOverElementWidth,
3443                         verticalDirection = this._getDragVerticalDirection(),
3444                         horizontalDirection = this._getDragHorizontalDirection();
3446                 if (!isOverElement)
3447                         return false;
3449                 return this.floating ?
3450                         ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3451                         : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3453         },
3455         _intersectsWithSides: function(item) {
3457                 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3458                         isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3459                         verticalDirection = this._getDragVerticalDirection(),
3460                         horizontalDirection = this._getDragHorizontalDirection();
3462                 if (this.floating && horizontalDirection) {
3463                         return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3464                 } else {
3465                         return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3466                 }
3468         },
3470         _getDragVerticalDirection: function() {
3471                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
3472                 return delta != 0 && (delta > 0 ? "down" : "up");
3473         },
3475         _getDragHorizontalDirection: function() {
3476                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
3477                 return delta != 0 && (delta > 0 ? "right" : "left");
3478         },
3480         refresh: function(event) {
3481                 this._refreshItems(event);
3482                 this.refreshPositions();
3483                 return this;
3484         },
3486         _connectWith: function() {
3487                 var options = this.options;
3488                 return options.connectWith.constructor == String
3489                         ? [options.connectWith]
3490                         : options.connectWith;
3491         },
3492         
3493         _getItemsAsjQuery: function(connected) {
3495                 var self = this;
3496                 var items = [];
3497                 var queries = [];
3498                 var connectWith = this._connectWith();
3500                 if(connectWith && connected) {
3501                         for (var i = connectWith.length - 1; i >= 0; i--){
3502                                 var cur = $(connectWith[i]);
3503                                 for (var j = cur.length - 1; j >= 0; j--){
3504                                         var inst = $.data(cur[j], 'sortable');
3505                                         if(inst && inst != this && !inst.options.disabled) {
3506                                                 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]);
3507                                         }
3508                                 };
3509                         };
3510                 }
3512                 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]);
3514                 for (var i = queries.length - 1; i >= 0; i--){
3515                         queries[i][0].each(function() {
3516                                 items.push(this);
3517                         });
3518                 };
3520                 return $(items);
3522         },
3524         _removeCurrentsFromItems: function() {
3526                 var list = this.currentItem.find(":data(sortable-item)");
3528                 for (var i=0; i < this.items.length; i++) {
3530                         for (var j=0; j < list.length; j++) {
3531                                 if(list[j] == this.items[i].item[0])
3532                                         this.items.splice(i,1);
3533                         };
3535                 };
3537         },
3539         _refreshItems: function(event) {
3541                 this.items = [];
3542                 this.containers = [this];
3543                 var items = this.items;
3544                 var self = this;
3545                 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3546                 var connectWith = this._connectWith();
3548                 if(connectWith) {
3549                         for (var i = connectWith.length - 1; i >= 0; i--){
3550                                 var cur = $(connectWith[i]);
3551                                 for (var j = cur.length - 1; j >= 0; j--){
3552                                         var inst = $.data(cur[j], 'sortable');
3553                                         if(inst && inst != this && !inst.options.disabled) {
3554                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3555                                                 this.containers.push(inst);
3556                                         }
3557                                 };
3558                         };
3559                 }
3561                 for (var i = queries.length - 1; i >= 0; i--) {
3562                         var targetData = queries[i][1];
3563                         var _queries = queries[i][0];
3565                         for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3566                                 var item = $(_queries[j]);
3568                                 item.data('sortable-item', targetData); // Data for target checking (mouse manager)
3570                                 items.push({
3571                                         item: item,
3572                                         instance: targetData,
3573                                         width: 0, height: 0,
3574                                         left: 0, top: 0
3575                                 });
3576                         };
3577                 };
3579         },
3581         refreshPositions: function(fast) {
3583                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3584                 if(this.offsetParent && this.helper) {
3585                         this.offset.parent = this._getParentOffset();
3586                 }
3588                 for (var i = this.items.length - 1; i >= 0; i--){
3589                         var item = this.items[i];
3591                         //We ignore calculating positions of all connected containers when we're not over them
3592                         if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3593                                 continue;
3595                         var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3597                         if (!fast) {
3598                                 item.width = t.outerWidth();
3599                                 item.height = t.outerHeight();
3600                         }
3602                         var p = t.offset();
3603                         item.left = p.left;
3604                         item.top = p.top;
3605                 };
3607                 if(this.options.custom && this.options.custom.refreshContainers) {
3608                         this.options.custom.refreshContainers.call(this);
3609                 } else {
3610                         for (var i = this.containers.length - 1; i >= 0; i--){
3611                                 var p = this.containers[i].element.offset();
3612                                 this.containers[i].containerCache.left = p.left;
3613                                 this.containers[i].containerCache.top = p.top;
3614                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3615                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3616                         };
3617                 }
3619                 return this;
3620         },
3622         _createPlaceholder: function(that) {
3624                 var self = that || this, o = self.options;
3626                 if(!o.placeholder || o.placeholder.constructor == String) {
3627                         var className = o.placeholder;
3628                         o.placeholder = {
3629                                 element: function() {
3631                                         var el = $(document.createElement(self.currentItem[0].nodeName))
3632                                                 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3633                                                 .removeClass("ui-sortable-helper")[0];
3635                                         if(!className)
3636                                                 el.style.visibility = "hidden";
3638                                         return el;
3639                                 },
3640                                 update: function(container, p) {
3642                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3643                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3644                                         if(className && !o.forcePlaceholderSize) return;
3646                                         //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
3647                                         if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3648                                         if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3649                                 }
3650                         };
3651                 }
3653                 //Create the placeholder
3654                 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3656                 //Append it after the actual current item
3657                 self.currentItem.after(self.placeholder);
3659                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3660                 o.placeholder.update(self, self.placeholder);
3662         },
3664         _contactContainers: function(event) {
3665                 
3666                 // get innermost container that intersects with item 
3667                 var innermostContainer = null, innermostIndex = null;           
3668                 
3669                 
3670                 for (var i = this.containers.length - 1; i >= 0; i--){
3672                         // never consider a container that's located within the item itself 
3673                         if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3674                                 continue;
3676                         if(this._intersectsWith(this.containers[i].containerCache)) {
3678                                 // if we've already found a container and it's more "inner" than this, then continue 
3679                                 if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3680                                         continue;
3682                                 innermostContainer = this.containers[i]; 
3683                                 innermostIndex = i;
3684                                         
3685                         } else {
3686                                 // container doesn't intersect. trigger "out" event if necessary 
3687                                 if(this.containers[i].containerCache.over) {
3688                                         this.containers[i]._trigger("out", event, this._uiHash(this));
3689                                         this.containers[i].containerCache.over = 0;
3690                                 }
3691                         }
3693                 }
3694                 
3695                 // if no intersecting containers found, return 
3696                 if(!innermostContainer) return; 
3698                 // move the item into the container if it's not there already
3699                 if(this.containers.length === 1) {
3700                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3701                         this.containers[innermostIndex].containerCache.over = 1;
3702                 } else if(this.currentContainer != this.containers[innermostIndex]) { 
3704                         //When entering a new container, we will find the item with the least distance and append our item near it 
3705                         var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; 
3706                         for (var j = this.items.length - 1; j >= 0; j--) { 
3707                                 if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 
3708                                 var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; 
3709                                 if(Math.abs(cur - base) < dist) { 
3710                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 
3711                                 } 
3712                         } 
3714                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 
3715                                 return; 
3717                         this.currentContainer = this.containers[innermostIndex]; 
3718                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 
3719                         this._trigger("change", event, this._uiHash()); 
3720                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 
3722                         //Update the placeholder 
3723                         this.options.placeholder.update(this.currentContainer, this.placeholder); 
3724                 
3725                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 
3726                         this.containers[innermostIndex].containerCache.over = 1;
3727                 } 
3728         
3729                 
3730         },
3732         _createHelper: function(event) {
3734                 var o = this.options;
3735                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3737                 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3738                         $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3740                 if(helper[0] == this.currentItem[0])
3741                         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") };
3743                 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3744                 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3746                 return helper;
3748         },
3750         _adjustOffsetFromHelper: function(obj) {
3751                 if (typeof obj == 'string') {
3752                         obj = obj.split(' ');
3753                 }
3754                 if ($.isArray(obj)) {
3755                         obj = {left: +obj[0], top: +obj[1] || 0};
3756                 }
3757                 if ('left' in obj) {
3758                         this.offset.click.left = obj.left + this.margins.left;
3759                 }
3760                 if ('right' in obj) {
3761                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3762                 }
3763                 if ('top' in obj) {
3764                         this.offset.click.top = obj.top + this.margins.top;
3765                 }
3766                 if ('bottom' in obj) {
3767                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3768                 }
3769         },
3771         _getParentOffset: function() {
3774                 //Get the offsetParent and cache its position
3775                 this.offsetParent = this.helper.offsetParent();
3776                 var po = this.offsetParent.offset();
3778                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
3779                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
3780                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
3781                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
3782                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
3783                         po.left += this.scrollParent.scrollLeft();
3784                         po.top += this.scrollParent.scrollTop();
3785                 }
3787                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
3788                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
3789                         po = { top: 0, left: 0 };
3791                 return {
3792                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3793                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3794                 };
3796         },
3798         _getRelativeOffset: function() {
3800                 if(this.cssPosition == "relative") {
3801                         var p = this.currentItem.position();
3802                         return {
3803                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
3804                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
3805                         };
3806                 } else {
3807                         return { top: 0, left: 0 };
3808                 }
3810         },
3812         _cacheMargins: function() {
3813                 this.margins = {
3814                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
3815                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
3816                 };
3817         },
3819         _cacheHelperProportions: function() {
3820                 this.helperProportions = {
3821                         width: this.helper.outerWidth(),
3822                         height: this.helper.outerHeight()
3823                 };
3824         },
3826         _setContainment: function() {
3828                 var o = this.options;
3829                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
3830                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
3831                         0 - this.offset.relative.left - this.offset.parent.left,
3832                         0 - this.offset.relative.top - this.offset.parent.top,
3833                         $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
3834                         ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
3835                 ];
3837                 if(!(/^(document|window|parent)$/).test(o.containment)) {
3838                         var ce = $(o.containment)[0];
3839                         var co = $(o.containment).offset();
3840                         var over = ($(ce).css("overflow") != 'hidden');
3842                         this.containment = [
3843                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
3844                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
3845                                 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,
3846                                 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
3847                         ];
3848                 }
3850         },
3852         _convertPositionTo: function(d, pos) {
3854                 if(!pos) pos = this.position;
3855                 var mod = d == "absolute" ? 1 : -1;
3856                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3858                 return {
3859                         top: (
3860                                 pos.top                                                                                                                                 // The absolute mouse position
3861                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
3862                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
3863                                 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
3864                         ),
3865                         left: (
3866                                 pos.left                                                                                                                                // The absolute mouse position
3867                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
3868                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
3869                                 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
3870                         )
3871                 };
3873         },
3875         _generatePosition: function(event) {
3877                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3879                 // This is another very weird special case that only happens for relative elements:
3880                 // 1. If the css position is relative
3881                 // 2. and the scroll parent is the document or similar to the offset parent
3882                 // we have to refresh the relative offset during the scroll so there are no jumps
3883                 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
3884                         this.offset.relative = this._getRelativeOffset();
3885                 }
3887                 var pageX = event.pageX;
3888                 var pageY = event.pageY;
3890                 /*
3891                  * - Position constraining -
3892                  * Constrain the position to a mix of grid, containment.
3893                  */
3895                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
3897                         if(this.containment) {
3898                                 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
3899                                 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
3900                                 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
3901                                 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
3902                         }
3904                         if(o.grid) {
3905                                 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
3906                                 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;
3908                                 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
3909                                 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;
3910                         }
3912                 }
3914                 return {
3915                         top: (
3916                                 pageY                                                                                                                           // The absolute mouse position
3917                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
3918                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
3919                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
3920                                 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
3921                         ),
3922                         left: (
3923                                 pageX                                                                                                                           // The absolute mouse position
3924                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
3925                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
3926                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
3927                                 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
3928                         )
3929                 };
3931         },
3933         _rearrange: function(event, i, a, hardRefresh) {
3935                 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));
3937                 //Various things done here to improve the performance:
3938                 // 1. we create a setTimeout, that calls refreshPositions
3939                 // 2. on the instance, we have a counter variable, that get's higher after every append
3940                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
3941                 // 4. this lets only the last addition to the timeout stack through
3942                 this.counter = this.counter ? ++this.counter : 1;
3943                 var self = this, counter = this.counter;
3945                 window.setTimeout(function() {
3946                         if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
3947                 },0);
3949         },
3951         _clear: function(event, noPropagation) {
3953                 this.reverting = false;
3954                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
3955                 // everything else normalized again
3956                 var delayedTriggers = [], self = this;
3958                 // We first have to update the dom position of the actual currentItem
3959                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
3960                 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
3961                 this._noFinalSort = null;
3963                 if(this.helper[0] == this.currentItem[0]) {
3964                         for(var i in this._storedCSS) {
3965                                 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
3966                         }
3967                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3968                 } else {
3969                         this.currentItem.show();
3970                 }
3972                 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
3973                 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
3974                 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
3975                         if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
3976                         for (var i = this.containers.length - 1; i >= 0; i--){
3977                                 if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
3978                                         delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
3979                                         delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
3980                                 }
3981                         };
3982                 };
3984                 //Post events to containers
3985                 for (var i = this.containers.length - 1; i >= 0; i--){
3986                         if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
3987                         if(this.containers[i].containerCache.over) {
3988                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
3989                                 this.containers[i].containerCache.over = 0;
3990                         }
3991                 }
3993                 //Do what was originally in plugins
3994                 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
3995                 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
3996                 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
3998                 this.dragging = false;
3999                 if(this.cancelHelperRemoval) {
4000                         if(!noPropagation) {
4001                                 this._trigger("beforeStop", event, this._uiHash());
4002                                 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4003                                 this._trigger("stop", event, this._uiHash());
4004                         }
4005                         return false;
4006                 }
4008                 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4010                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4011                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4013                 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4015                 if(!noPropagation) {
4016                         for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4017                         this._trigger("stop", event, this._uiHash());
4018                 }
4020                 this.fromOutside = false;
4021                 return true;
4023         },
4025         _trigger: function() {
4026                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4027                         this.cancel();
4028                 }
4029         },
4031         _uiHash: function(inst) {
4032                 var self = inst || this;
4033                 return {
4034                         helper: self.helper,
4035                         placeholder: self.placeholder || $([]),
4036                         position: self.position,
4037                         originalPosition: self.originalPosition,
4038                         offset: self.positionAbs,
4039                         item: self.currentItem,
4040                         sender: inst ? inst.element : null
4041                 };
4042         }
4046 $.extend($.ui.sortable, {
4047         version: "1.8.16"
4050 })(jQuery);
4052  * jQuery UI Effects 1.8.16
4054  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4055  * Dual licensed under the MIT or GPL Version 2 licenses.
4056  * http://jquery.org/license
4058  * http://docs.jquery.com/UI/Effects/
4059  */
4060 ;jQuery.effects || (function($, undefined) {
4062 $.effects = {};
4066 /******************************************************************************/
4067 /****************************** COLOR ANIMATIONS ******************************/
4068 /******************************************************************************/
4070 // override the animation for color styles
4071 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
4072         'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
4073 function(i, attr) {
4074         $.fx.step[attr] = function(fx) {
4075                 if (!fx.colorInit) {
4076                         fx.start = getColor(fx.elem, attr);
4077                         fx.end = getRGB(fx.end);
4078                         fx.colorInit = true;
4079                 }
4081                 fx.elem.style[attr] = 'rgb(' +
4082                         Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
4083                         Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
4084                         Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
4085         };
4088 // Color Conversion functions from highlightFade
4089 // By Blair Mitchelmore
4090 // http://jquery.offput.ca/highlightFade/
4092 // Parse strings looking for color tuples [255,255,255]
4093 function getRGB(color) {
4094                 var result;
4096                 // Check if we're already dealing with an array of colors
4097                 if ( color && color.constructor == Array && color.length == 3 )
4098                                 return color;
4100                 // Look for rgb(num,num,num)
4101                 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
4102                                 return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
4104                 // Look for rgb(num%,num%,num%)
4105                 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
4106                                 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
4108                 // Look for #a0b1c2
4109                 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
4110                                 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
4112                 // Look for #fff
4113                 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
4114                                 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
4116                 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
4117                 if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
4118                                 return colors['transparent'];
4120                 // Otherwise, we're most likely dealing with a named color
4121                 return colors[$.trim(color).toLowerCase()];
4124 function getColor(elem, attr) {
4125                 var color;
4127                 do {
4128                                 color = $.curCSS(elem, attr);
4130                                 // Keep going until we find an element that has color, or we hit the body
4131                                 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
4132                                                 break;
4134                                 attr = "backgroundColor";
4135                 } while ( elem = elem.parentNode );
4137                 return getRGB(color);
4140 // Some named colors to work with
4141 // From Interface by Stefan Petre
4142 // http://interface.eyecon.ro/
4144 var colors = {
4145         aqua:[0,255,255],
4146         azure:[240,255,255],
4147         beige:[245,245,220],
4148         black:[0,0,0],
4149         blue:[0,0,255],
4150         brown:[165,42,42],
4151         cyan:[0,255,255],
4152         darkblue:[0,0,139],
4153         darkcyan:[0,139,139],
4154         darkgrey:[169,169,169],
4155         darkgreen:[0,100,0],
4156         darkkhaki:[189,183,107],
4157         darkmagenta:[139,0,139],
4158         darkolivegreen:[85,107,47],
4159         darkorange:[255,140,0],
4160         darkorchid:[153,50,204],
4161         darkred:[139,0,0],
4162         darksalmon:[233,150,122],
4163         darkviolet:[148,0,211],
4164         fuchsia:[255,0,255],
4165         gold:[255,215,0],
4166         green:[0,128,0],
4167         indigo:[75,0,130],
4168         khaki:[240,230,140],
4169         lightblue:[173,216,230],
4170         lightcyan:[224,255,255],
4171         lightgreen:[144,238,144],
4172         lightgrey:[211,211,211],
4173         lightpink:[255,182,193],
4174         lightyellow:[255,255,224],
4175         lime:[0,255,0],
4176         magenta:[255,0,255],
4177         maroon:[128,0,0],
4178         navy:[0,0,128],
4179         olive:[128,128,0],
4180         orange:[255,165,0],
4181         pink:[255,192,203],
4182         purple:[128,0,128],
4183         violet:[128,0,128],
4184         red:[255,0,0],
4185         silver:[192,192,192],
4186         white:[255,255,255],
4187         yellow:[255,255,0],
4188         transparent: [255,255,255]
4193 /******************************************************************************/
4194 /****************************** CLASS ANIMATIONS ******************************/
4195 /******************************************************************************/
4197 var classAnimationActions = ['add', 'remove', 'toggle'],
4198         shorthandStyles = {
4199                 border: 1,
4200                 borderBottom: 1,
4201                 borderColor: 1,
4202                 borderLeft: 1,
4203                 borderRight: 1,
4204                 borderTop: 1,
4205                 borderWidth: 1,
4206                 margin: 1,
4207                 padding: 1
4208         };
4210 function getElementStyles() {
4211         var style = document.defaultView
4212                         ? document.defaultView.getComputedStyle(this, null)
4213                         : this.currentStyle,
4214                 newStyle = {},
4215                 key,
4216                 camelCase;
4218         // webkit enumerates style porperties
4219         if (style && style.length && style[0] && style[style[0]]) {
4220                 var len = style.length;
4221                 while (len--) {
4222                         key = style[len];
4223                         if (typeof style[key] == 'string') {
4224                                 camelCase = key.replace(/\-(\w)/g, function(all, letter){
4225                                         return letter.toUpperCase();
4226                                 });
4227                                 newStyle[camelCase] = style[key];
4228                         }
4229                 }
4230         } else {
4231                 for (key in style) {
4232                         if (typeof style[key] === 'string') {
4233                                 newStyle[key] = style[key];
4234                         }
4235                 }
4236         }
4237         
4238         return newStyle;
4241 function filterStyles(styles) {
4242         var name, value;
4243         for (name in styles) {
4244                 value = styles[name];
4245                 if (
4246                         // ignore null and undefined values
4247                         value == null ||
4248                         // ignore functions (when does this occur?)
4249                         $.isFunction(value) ||
4250                         // shorthand styles that need to be expanded
4251                         name in shorthandStyles ||
4252                         // ignore scrollbars (break in IE)
4253                         (/scrollbar/).test(name) ||
4255                         // only colors or values that can be converted to numbers
4256                         (!(/color/i).test(name) && isNaN(parseFloat(value)))
4257                 ) {
4258                         delete styles[name];
4259                 }
4260         }
4261         
4262         return styles;
4265 function styleDifference(oldStyle, newStyle) {
4266         var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
4267                 name;
4269         for (name in newStyle) {
4270                 if (oldStyle[name] != newStyle[name]) {
4271                         diff[name] = newStyle[name];
4272                 }
4273         }
4275         return diff;
4278 $.effects.animateClass = function(value, duration, easing, callback) {
4279         if ($.isFunction(easing)) {
4280                 callback = easing;
4281                 easing = null;
4282         }
4284         return this.queue(function() {
4285                 var that = $(this),
4286                         originalStyleAttr = that.attr('style') || ' ',
4287                         originalStyle = filterStyles(getElementStyles.call(this)),
4288                         newStyle,
4289                         className = that.attr('class');
4291                 $.each(classAnimationActions, function(i, action) {
4292                         if (value[action]) {
4293                                 that[action + 'Class'](value[action]);
4294                         }
4295                 });
4296                 newStyle = filterStyles(getElementStyles.call(this));
4297                 that.attr('class', className);
4299                 that.animate(styleDifference(originalStyle, newStyle), {
4300                         queue: false,
4301                         duration: duration,
4302                         easing: easing,
4303                         complete: function() {
4304                                 $.each(classAnimationActions, function(i, action) {
4305                                         if (value[action]) { that[action + 'Class'](value[action]); }
4306                                 });
4307                                 // work around bug in IE by clearing the cssText before setting it
4308                                 if (typeof that.attr('style') == 'object') {
4309                                         that.attr('style').cssText = '';
4310                                         that.attr('style').cssText = originalStyleAttr;
4311                                 } else {
4312                                         that.attr('style', originalStyleAttr);
4313                                 }
4314                                 if (callback) { callback.apply(this, arguments); }
4315                                 $.dequeue( this );
4316                         }
4317                 });
4318         });
4321 $.fn.extend({
4322         _addClass: $.fn.addClass,
4323         addClass: function(classNames, speed, easing, callback) {
4324                 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
4325         },
4327         _removeClass: $.fn.removeClass,
4328         removeClass: function(classNames,speed,easing,callback) {
4329                 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
4330         },
4332         _toggleClass: $.fn.toggleClass,
4333         toggleClass: function(classNames, force, speed, easing, callback) {
4334                 if ( typeof force == "boolean" || force === undefined ) {
4335                         if ( !speed ) {
4336                                 // without speed parameter;
4337                                 return this._toggleClass(classNames, force);
4338                         } else {
4339                                 return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
4340                         }
4341                 } else {
4342                         // without switch parameter;
4343                         return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
4344                 }
4345         },
4347         switchClass: function(remove,add,speed,easing,callback) {
4348                 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
4349         }
4354 /******************************************************************************/
4355 /*********************************** EFFECTS **********************************/
4356 /******************************************************************************/
4358 $.extend($.effects, {
4359         version: "1.8.16",
4361         // Saves a set of properties in a data storage
4362         save: function(element, set) {
4363                 for(var i=0; i < set.length; i++) {
4364                         if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
4365                 }
4366         },
4368         // Restores a set of previously saved properties from a data storage
4369         restore: function(element, set) {
4370                 for(var i=0; i < set.length; i++) {
4371                         if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
4372                 }
4373         },
4375         setMode: function(el, mode) {
4376                 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
4377                 return mode;
4378         },
4380         getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
4381                 // this should be a little more flexible in the future to handle a string & hash
4382                 var y, x;
4383                 switch (origin[0]) {
4384                         case 'top': y = 0; break;
4385                         case 'middle': y = 0.5; break;
4386                         case 'bottom': y = 1; break;
4387                         default: y = origin[0] / original.height;
4388                 };
4389                 switch (origin[1]) {
4390                         case 'left': x = 0; break;
4391                         case 'center': x = 0.5; break;
4392                         case 'right': x = 1; break;
4393                         default: x = origin[1] / original.width;
4394                 };
4395                 return {x: x, y: y};
4396         },
4398         // Wraps the element around a wrapper that copies position properties
4399         createWrapper: function(element) {
4401                 // if the element is already wrapped, return it
4402                 if (element.parent().is('.ui-effects-wrapper')) {
4403                         return element.parent();
4404                 }
4406                 // wrap the element
4407                 var props = {
4408                                 width: element.outerWidth(true),
4409                                 height: element.outerHeight(true),
4410                                 'float': element.css('float')
4411                         },
4412                         wrapper = $('<div></div>')
4413                                 .addClass('ui-effects-wrapper')
4414                                 .css({
4415                                         fontSize: '100%',
4416                                         background: 'transparent',
4417                                         border: 'none',
4418                                         margin: 0,
4419                                         padding: 0
4420                                 }),
4421                         active = document.activeElement;
4423                 element.wrap(wrapper);
4425                 // Fixes #7595 - Elements lose focus when wrapped.
4426                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4427                         $( active ).focus();
4428                 }
4429                 
4430                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
4432                 // transfer positioning properties to the wrapper
4433                 if (element.css('position') == 'static') {
4434                         wrapper.css({ position: 'relative' });
4435                         element.css({ position: 'relative' });
4436                 } else {
4437                         $.extend(props, {
4438                                 position: element.css('position'),
4439                                 zIndex: element.css('z-index')
4440                         });
4441                         $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
4442                                 props[pos] = element.css(pos);
4443                                 if (isNaN(parseInt(props[pos], 10))) {
4444                                         props[pos] = 'auto';
4445                                 }
4446                         });
4447                         element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
4448                 }
4450                 return wrapper.css(props).show();
4451         },
4453         removeWrapper: function(element) {
4454                 var parent,
4455                         active = document.activeElement;
4456                 
4457                 if (element.parent().is('.ui-effects-wrapper')) {
4458                         parent = element.parent().replaceWith(element);
4459                         // Fixes #7595 - Elements lose focus when wrapped.
4460                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4461                                 $( active ).focus();
4462                         }
4463                         return parent;
4464                 }
4465                         
4466                 return element;
4467         },
4469         setTransition: function(element, list, factor, value) {
4470                 value = value || {};
4471                 $.each(list, function(i, x){
4472                         unit = element.cssUnit(x);
4473                         if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
4474                 });
4475                 return value;
4476         }
4480 function _normalizeArguments(effect, options, speed, callback) {
4481         // shift params for method overloading
4482         if (typeof effect == 'object') {
4483                 callback = options;
4484                 speed = null;
4485                 options = effect;
4486                 effect = options.effect;
4487         }
4488         if ($.isFunction(options)) {
4489                 callback = options;
4490                 speed = null;
4491                 options = {};
4492         }
4493         if (typeof options == 'number' || $.fx.speeds[options]) {
4494                 callback = speed;
4495                 speed = options;
4496                 options = {};
4497         }
4498         if ($.isFunction(speed)) {
4499                 callback = speed;
4500                 speed = null;
4501         }
4503         options = options || {};
4505         speed = speed || options.duration;
4506         speed = $.fx.off ? 0 : typeof speed == 'number'
4507                 ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
4509         callback = callback || options.complete;
4511         return [effect, options, speed, callback];
4514 function standardSpeed( speed ) {
4515         // valid standard speeds
4516         if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
4517                 return true;
4518         }
4519         
4520         // invalid strings - treat as "normal" speed
4521         if ( typeof speed === "string" && !$.effects[ speed ] ) {
4522                 return true;
4523         }
4524         
4525         return false;
4528 $.fn.extend({
4529         effect: function(effect, options, speed, callback) {
4530                 var args = _normalizeArguments.apply(this, arguments),
4531                         // TODO: make effects take actual parameters instead of a hash
4532                         args2 = {
4533                                 options: args[1],
4534                                 duration: args[2],
4535                                 callback: args[3]
4536                         },
4537                         mode = args2.options.mode,
4538                         effectMethod = $.effects[effect];
4539                 
4540                 if ( $.fx.off || !effectMethod ) {
4541                         // delegate to the original method (e.g., .show()) if possible
4542                         if ( mode ) {
4543                                 return this[ mode ]( args2.duration, args2.callback );
4544                         } else {
4545                                 return this.each(function() {
4546                                         if ( args2.callback ) {
4547                                                 args2.callback.call( this );
4548                                         }
4549                                 });
4550                         }
4551                 }
4552                 
4553                 return effectMethod.call(this, args2);
4554         },
4556         _show: $.fn.show,
4557         show: function(speed) {
4558                 if ( standardSpeed( speed ) ) {
4559                         return this._show.apply(this, arguments);
4560                 } else {
4561                         var args = _normalizeArguments.apply(this, arguments);
4562                         args[1].mode = 'show';
4563                         return this.effect.apply(this, args);
4564                 }
4565         },
4567         _hide: $.fn.hide,
4568         hide: function(speed) {
4569                 if ( standardSpeed( speed ) ) {
4570                         return this._hide.apply(this, arguments);
4571                 } else {
4572                         var args = _normalizeArguments.apply(this, arguments);
4573                         args[1].mode = 'hide';
4574                         return this.effect.apply(this, args);
4575                 }
4576         },
4578         // jQuery core overloads toggle and creates _toggle
4579         __toggle: $.fn.toggle,
4580         toggle: function(speed) {
4581                 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
4582                         return this.__toggle.apply(this, arguments);
4583                 } else {
4584                         var args = _normalizeArguments.apply(this, arguments);
4585                         args[1].mode = 'toggle';
4586                         return this.effect.apply(this, args);
4587                 }
4588         },
4590         // helper functions
4591         cssUnit: function(key) {
4592                 var style = this.css(key), val = [];
4593                 $.each( ['em','px','%','pt'], function(i, unit){
4594                         if(style.indexOf(unit) > 0)
4595                                 val = [parseFloat(style), unit];
4596                 });
4597                 return val;
4598         }
4603 /******************************************************************************/
4604 /*********************************** EASING ***********************************/
4605 /******************************************************************************/
4608  * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
4610  * Uses the built in easing capabilities added In jQuery 1.1
4611  * to offer multiple easing options
4613  * TERMS OF USE - jQuery Easing
4615  * Open source under the BSD License.
4617  * Copyright 2008 George McGinley Smith
4618  * All rights reserved.
4620  * Redistribution and use in source and binary forms, with or without modification,
4621  * are permitted provided that the following conditions are met:
4623  * Redistributions of source code must retain the above copyright notice, this list of
4624  * conditions and the following disclaimer.
4625  * Redistributions in binary form must reproduce the above copyright notice, this list
4626  * of conditions and the following disclaimer in the documentation and/or other materials
4627  * provided with the distribution.
4629  * Neither the name of the author nor the names of contributors may be used to endorse
4630  * or promote products derived from this software without specific prior written permission.
4632  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
4633  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4634  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
4635  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
4636  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4637  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
4638  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4639  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4640  * OF THE POSSIBILITY OF SUCH DAMAGE.
4644 // t: current time, b: begInnIng value, c: change In value, d: duration
4645 $.easing.jswing = $.easing.swing;
4647 $.extend($.easing,
4649         def: 'easeOutQuad',
4650         swing: function (x, t, b, c, d) {
4651                 //alert($.easing.default);
4652                 return $.easing[$.easing.def](x, t, b, c, d);
4653         },
4654         easeInQuad: function (x, t, b, c, d) {
4655                 return c*(t/=d)*t + b;
4656         },
4657         easeOutQuad: function (x, t, b, c, d) {
4658                 return -c *(t/=d)*(t-2) + b;
4659         },
4660         easeInOutQuad: function (x, t, b, c, d) {
4661                 if ((t/=d/2) < 1) return c/2*t*t + b;
4662                 return -c/2 * ((--t)*(t-2) - 1) + b;
4663         },
4664         easeInCubic: function (x, t, b, c, d) {
4665                 return c*(t/=d)*t*t + b;
4666         },
4667         easeOutCubic: function (x, t, b, c, d) {
4668                 return c*((t=t/d-1)*t*t + 1) + b;
4669         },
4670         easeInOutCubic: function (x, t, b, c, d) {
4671                 if ((t/=d/2) < 1) return c/2*t*t*t + b;
4672                 return c/2*((t-=2)*t*t + 2) + b;
4673         },
4674         easeInQuart: function (x, t, b, c, d) {
4675                 return c*(t/=d)*t*t*t + b;
4676         },
4677         easeOutQuart: function (x, t, b, c, d) {
4678                 return -c * ((t=t/d-1)*t*t*t - 1) + b;
4679         },
4680         easeInOutQuart: function (x, t, b, c, d) {
4681                 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
4682                 return -c/2 * ((t-=2)*t*t*t - 2) + b;
4683         },
4684         easeInQuint: function (x, t, b, c, d) {
4685                 return c*(t/=d)*t*t*t*t + b;
4686         },
4687         easeOutQuint: function (x, t, b, c, d) {
4688                 return c*((t=t/d-1)*t*t*t*t + 1) + b;
4689         },
4690         easeInOutQuint: function (x, t, b, c, d) {
4691                 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
4692                 return c/2*((t-=2)*t*t*t*t + 2) + b;
4693         },
4694         easeInSine: function (x, t, b, c, d) {
4695                 return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
4696         },
4697         easeOutSine: function (x, t, b, c, d) {
4698                 return c * Math.sin(t/d * (Math.PI/2)) + b;
4699         },
4700         easeInOutSine: function (x, t, b, c, d) {
4701                 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
4702         },
4703         easeInExpo: function (x, t, b, c, d) {
4704                 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
4705         },
4706         easeOutExpo: function (x, t, b, c, d) {
4707                 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
4708         },
4709         easeInOutExpo: function (x, t, b, c, d) {
4710                 if (t==0) return b;
4711                 if (t==d) return b+c;
4712                 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
4713                 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
4714         },
4715         easeInCirc: function (x, t, b, c, d) {
4716                 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
4717         },
4718         easeOutCirc: function (x, t, b, c, d) {
4719                 return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
4720         },
4721         easeInOutCirc: function (x, t, b, c, d) {
4722                 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
4723                 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
4724         },
4725         easeInElastic: function (x, t, b, c, d) {
4726                 var s=1.70158;var p=0;var a=c;
4727                 if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
4728                 if (a < Math.abs(c)) { a=c; var s=p/4; }
4729                 else var s = p/(2*Math.PI) * Math.asin (c/a);
4730                 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4731         },
4732         easeOutElastic: function (x, t, b, c, d) {
4733                 var s=1.70158;var p=0;var a=c;
4734                 if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
4735                 if (a < Math.abs(c)) { a=c; var s=p/4; }
4736                 else var s = p/(2*Math.PI) * Math.asin (c/a);
4737                 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
4738         },
4739         easeInOutElastic: function (x, t, b, c, d) {
4740                 var s=1.70158;var p=0;var a=c;
4741                 if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
4742                 if (a < Math.abs(c)) { a=c; var s=p/4; }
4743                 else var s = p/(2*Math.PI) * Math.asin (c/a);
4744                 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4745                 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
4746         },
4747         easeInBack: function (x, t, b, c, d, s) {
4748                 if (s == undefined) s = 1.70158;
4749                 return c*(t/=d)*t*((s+1)*t - s) + b;
4750         },
4751         easeOutBack: function (x, t, b, c, d, s) {
4752                 if (s == undefined) s = 1.70158;
4753                 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
4754         },
4755         easeInOutBack: function (x, t, b, c, d, s) {
4756                 if (s == undefined) s = 1.70158;
4757                 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
4758                 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
4759         },
4760         easeInBounce: function (x, t, b, c, d) {
4761                 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
4762         },
4763         easeOutBounce: function (x, t, b, c, d) {
4764                 if ((t/=d) < (1/2.75)) {
4765                         return c*(7.5625*t*t) + b;
4766                 } else if (t < (2/2.75)) {
4767                         return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
4768                 } else if (t < (2.5/2.75)) {
4769                         return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
4770                 } else {
4771                         return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
4772                 }
4773         },
4774         easeInOutBounce: function (x, t, b, c, d) {
4775                 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
4776                 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
4777         }
4782  * TERMS OF USE - EASING EQUATIONS
4784  * Open source under the BSD License.
4786  * Copyright 2001 Robert Penner
4787  * All rights reserved.
4789  * Redistribution and use in source and binary forms, with or without modification,
4790  * are permitted provided that the following conditions are met:
4792  * Redistributions of source code must retain the above copyright notice, this list of
4793  * conditions and the following disclaimer.
4794  * Redistributions in binary form must reproduce the above copyright notice, this list
4795  * of conditions and the following disclaimer in the documentation and/or other materials
4796  * provided with the distribution.
4798  * Neither the name of the author nor the names of contributors may be used to endorse
4799  * or promote products derived from this software without specific prior written permission.
4801  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
4802  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4803  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
4804  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
4805  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4806  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
4807  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4808  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4809  * OF THE POSSIBILITY OF SUCH DAMAGE.
4811  */
4813 })(jQuery);
4815  * jQuery UI Effects Blind 1.8.16
4817  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4818  * Dual licensed under the MIT or GPL Version 2 licenses.
4819  * http://jquery.org/license
4821  * http://docs.jquery.com/UI/Effects/Blind
4823  * Depends:
4824  *      jquery.effects.core.js
4825  */
4826 (function( $, undefined ) {
4828 $.effects.blind = function(o) {
4830         return this.queue(function() {
4832                 // Create element
4833                 var el = $(this), props = ['position','top','bottom','left','right'];
4835                 // Set options
4836                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4837                 var direction = o.options.direction || 'vertical'; // Default direction
4839                 // Adjust
4840                 $.effects.save(el, props); el.show(); // Save & Show
4841                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4842                 var ref = (direction == 'vertical') ? 'height' : 'width';
4843                 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
4844                 if(mode == 'show') wrapper.css(ref, 0); // Shift
4846                 // Animation
4847                 var animation = {};
4848                 animation[ref] = mode == 'show' ? distance : 0;
4850                 // Animate
4851                 wrapper.animate(animation, o.duration, o.options.easing, function() {
4852                         if(mode == 'hide') el.hide(); // Hide
4853                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4854                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
4855                         el.dequeue();
4856                 });
4858         });
4862 })(jQuery);
4864  * jQuery UI Effects Bounce 1.8.16
4866  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4867  * Dual licensed under the MIT or GPL Version 2 licenses.
4868  * http://jquery.org/license
4870  * http://docs.jquery.com/UI/Effects/Bounce
4872  * Depends:
4873  *      jquery.effects.core.js
4874  */
4875 (function( $, undefined ) {
4877 $.effects.bounce = function(o) {
4879         return this.queue(function() {
4881                 // Create element
4882                 var el = $(this), props = ['position','top','bottom','left','right'];
4884                 // Set options
4885                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
4886                 var direction = o.options.direction || 'up'; // Default direction
4887                 var distance = o.options.distance || 20; // Default distance
4888                 var times = o.options.times || 5; // Default # of times
4889                 var speed = o.duration || 250; // Default speed per bounce
4890                 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
4892                 // Adjust
4893                 $.effects.save(el, props); el.show(); // Save & Show
4894                 $.effects.createWrapper(el); // Create Wrapper
4895                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4896                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4897                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
4898                 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
4899                 if (mode == 'hide') distance = distance / (times * 2);
4900                 if (mode != 'hide') times--;
4902                 // Animate
4903                 if (mode == 'show') { // Show Bounce
4904                         var animation = {opacity: 1};
4905                         animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4906                         el.animate(animation, speed / 2, o.options.easing);
4907                         distance = distance / 2;
4908                         times--;
4909                 };
4910                 for (var i = 0; i < times; i++) { // Bounces
4911                         var animation1 = {}, animation2 = {};
4912                         animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4913                         animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4914                         el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
4915                         distance = (mode == 'hide') ? distance * 2 : distance / 2;
4916                 };
4917                 if (mode == 'hide') { // Last Bounce
4918                         var animation = {opacity: 0};
4919                         animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
4920                         el.animate(animation, speed / 2, o.options.easing, function(){
4921                                 el.hide(); // Hide
4922                                 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4923                                 if(o.callback) o.callback.apply(this, arguments); // Callback
4924                         });
4925                 } else {
4926                         var animation1 = {}, animation2 = {};
4927                         animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4928                         animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4929                         el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
4930                                 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4931                                 if(o.callback) o.callback.apply(this, arguments); // Callback
4932                         });
4933                 };
4934                 el.queue('fx', function() { el.dequeue(); });
4935                 el.dequeue();
4936         });
4940 })(jQuery);
4942  * jQuery UI Effects Clip 1.8.16
4944  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4945  * Dual licensed under the MIT or GPL Version 2 licenses.
4946  * http://jquery.org/license
4948  * http://docs.jquery.com/UI/Effects/Clip
4950  * Depends:
4951  *      jquery.effects.core.js
4952  */
4953 (function( $, undefined ) {
4955 $.effects.clip = function(o) {
4957         return this.queue(function() {
4959                 // Create element
4960                 var el = $(this), props = ['position','top','bottom','left','right','height','width'];
4962                 // Set options
4963                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4964                 var direction = o.options.direction || 'vertical'; // Default direction
4966                 // Adjust
4967                 $.effects.save(el, props); el.show(); // Save & Show
4968                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4969                 var animate = el[0].tagName == 'IMG' ? wrapper : el;
4970                 var ref = {
4971                         size: (direction == 'vertical') ? 'height' : 'width',
4972                         position: (direction == 'vertical') ? 'top' : 'left'
4973                 };
4974                 var distance = (direction == 'vertical') ? animate.height() : animate.width();
4975                 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
4977                 // Animation
4978                 var animation = {};
4979                 animation[ref.size] = mode == 'show' ? distance : 0;
4980                 animation[ref.position] = mode == 'show' ? 0 : distance / 2;
4982                 // Animate
4983                 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4984                         if(mode == 'hide') el.hide(); // Hide
4985                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4986                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
4987                         el.dequeue();
4988                 }});
4990         });
4994 })(jQuery);
4996  * jQuery UI Effects Drop 1.8.16
4998  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4999  * Dual licensed under the MIT or GPL Version 2 licenses.
5000  * http://jquery.org/license
5002  * http://docs.jquery.com/UI/Effects/Drop
5004  * Depends:
5005  *      jquery.effects.core.js
5006  */
5007 (function( $, undefined ) {
5009 $.effects.drop = function(o) {
5011         return this.queue(function() {
5013                 // Create element
5014                 var el = $(this), props = ['position','top','bottom','left','right','opacity'];
5016                 // Set options
5017                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
5018                 var direction = o.options.direction || 'left'; // Default Direction
5020                 // Adjust
5021                 $.effects.save(el, props); el.show(); // Save & Show
5022                 $.effects.createWrapper(el); // Create Wrapper
5023                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5024                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5025                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
5026                 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
5028                 // Animation
5029                 var animation = {opacity: mode == 'show' ? 1 : 0};
5030                 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
5032                 // Animate
5033                 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5034                         if(mode == 'hide') el.hide(); // Hide
5035                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5036                         if(o.callback) o.callback.apply(this, arguments); // Callback
5037                         el.dequeue();
5038                 }});
5040         });
5044 })(jQuery);
5046  * jQuery UI Effects Explode 1.8.16
5048  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5049  * Dual licensed under the MIT or GPL Version 2 licenses.
5050  * http://jquery.org/license
5052  * http://docs.jquery.com/UI/Effects/Explode
5054  * Depends:
5055  *      jquery.effects.core.js
5056  */
5057 (function( $, undefined ) {
5059 $.effects.explode = function(o) {
5061         return this.queue(function() {
5063         var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
5064         var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
5066         o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
5067         var el = $(this).show().css('visibility', 'hidden');
5068         var offset = el.offset();
5070         //Substract the margins - not fixing the problem yet.
5071         offset.top -= parseInt(el.css("marginTop"),10) || 0;
5072         offset.left -= parseInt(el.css("marginLeft"),10) || 0;
5074         var width = el.outerWidth(true);
5075         var height = el.outerHeight(true);
5077         for(var i=0;i<rows;i++) { // =
5078                 for(var j=0;j<cells;j++) { // ||
5079                         el
5080                                 .clone()
5081                                 .appendTo('body')
5082                                 .wrap('<div></div>')
5083                                 .css({
5084                                         position: 'absolute',
5085                                         visibility: 'visible',
5086                                         left: -j*(width/cells),
5087                                         top: -i*(height/rows)
5088                                 })
5089                                 .parent()
5090                                 .addClass('ui-effects-explode')
5091                                 .css({
5092                                         position: 'absolute',
5093                                         overflow: 'hidden',
5094                                         width: width/cells,
5095                                         height: height/rows,
5096                                         left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
5097                                         top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
5098                                         opacity: o.options.mode == 'show' ? 0 : 1
5099                                 }).animate({
5100                                         left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
5101                                         top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
5102                                         opacity: o.options.mode == 'show' ? 1 : 0
5103                                 }, o.duration || 500);
5104                 }
5105         }
5107         // Set a timeout, to call the callback approx. when the other animations have finished
5108         setTimeout(function() {
5110                 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
5111                                 if(o.callback) o.callback.apply(el[0]); // Callback
5112                                 el.dequeue();
5114                                 $('div.ui-effects-explode').remove();
5116         }, o.duration || 500);
5119         });
5123 })(jQuery);
5125  * jQuery UI Effects Fade 1.8.16
5127  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5128  * Dual licensed under the MIT or GPL Version 2 licenses.
5129  * http://jquery.org/license
5131  * http://docs.jquery.com/UI/Effects/Fade
5133  * Depends:
5134  *      jquery.effects.core.js
5135  */
5136 (function( $, undefined ) {
5138 $.effects.fade = function(o) {
5139         return this.queue(function() {
5140                 var elem = $(this),
5141                         mode = $.effects.setMode(elem, o.options.mode || 'hide');
5143                 elem.animate({ opacity: mode }, {
5144                         queue: false,
5145                         duration: o.duration,
5146                         easing: o.options.easing,
5147                         complete: function() {
5148                                 (o.callback && o.callback.apply(this, arguments));
5149                                 elem.dequeue();
5150                         }
5151                 });
5152         });
5155 })(jQuery);
5157  * jQuery UI Effects Fold 1.8.16
5159  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5160  * Dual licensed under the MIT or GPL Version 2 licenses.
5161  * http://jquery.org/license
5163  * http://docs.jquery.com/UI/Effects/Fold
5165  * Depends:
5166  *      jquery.effects.core.js
5167  */
5168 (function( $, undefined ) {
5170 $.effects.fold = function(o) {
5172         return this.queue(function() {
5174                 // Create element
5175                 var el = $(this), props = ['position','top','bottom','left','right'];
5177                 // Set options
5178                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
5179                 var size = o.options.size || 15; // Default fold size
5180                 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
5181                 var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
5183                 // Adjust
5184                 $.effects.save(el, props); el.show(); // Save & Show
5185                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
5186                 var widthFirst = ((mode == 'show') != horizFirst);
5187                 var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
5188                 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
5189                 var percent = /([0-9]+)%/.exec(size);
5190                 if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
5191                 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
5193                 // Animation
5194                 var animation1 = {}, animation2 = {};
5195                 animation1[ref[0]] = mode == 'show' ? distance[0] : size;
5196                 animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
5198                 // Animate
5199                 wrapper.animate(animation1, duration, o.options.easing)
5200                 .animate(animation2, duration, o.options.easing, function() {
5201                         if(mode == 'hide') el.hide(); // Hide
5202                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5203                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
5204                         el.dequeue();
5205                 });
5207         });
5211 })(jQuery);
5213  * jQuery UI Effects Highlight 1.8.16
5215  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5216  * Dual licensed under the MIT or GPL Version 2 licenses.
5217  * http://jquery.org/license
5219  * http://docs.jquery.com/UI/Effects/Highlight
5221  * Depends:
5222  *      jquery.effects.core.js
5223  */
5224 (function( $, undefined ) {
5226 $.effects.highlight = function(o) {
5227         return this.queue(function() {
5228                 var elem = $(this),
5229                         props = ['backgroundImage', 'backgroundColor', 'opacity'],
5230                         mode = $.effects.setMode(elem, o.options.mode || 'show'),
5231                         animation = {
5232                                 backgroundColor: elem.css('backgroundColor')
5233                         };
5235                 if (mode == 'hide') {
5236                         animation.opacity = 0;
5237                 }
5239                 $.effects.save(elem, props);
5240                 elem
5241                         .show()
5242                         .css({
5243                                 backgroundImage: 'none',
5244                                 backgroundColor: o.options.color || '#ffff99'
5245                         })
5246                         .animate(animation, {
5247                                 queue: false,
5248                                 duration: o.duration,
5249                                 easing: o.options.easing,
5250                                 complete: function() {
5251                                         (mode == 'hide' && elem.hide());
5252                                         $.effects.restore(elem, props);
5253                                         (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
5254                                         (o.callback && o.callback.apply(this, arguments));
5255                                         elem.dequeue();
5256                                 }
5257                         });
5258         });
5261 })(jQuery);
5263  * jQuery UI Effects Pulsate 1.8.16
5265  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5266  * Dual licensed under the MIT or GPL Version 2 licenses.
5267  * http://jquery.org/license
5269  * http://docs.jquery.com/UI/Effects/Pulsate
5271  * Depends:
5272  *      jquery.effects.core.js
5273  */
5274 (function( $, undefined ) {
5276 $.effects.pulsate = function(o) {
5277         return this.queue(function() {
5278                 var elem = $(this),
5279                         mode = $.effects.setMode(elem, o.options.mode || 'show');
5280                         times = ((o.options.times || 5) * 2) - 1;
5281                         duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
5282                         isVisible = elem.is(':visible'),
5283                         animateTo = 0;
5285                 if (!isVisible) {
5286                         elem.css('opacity', 0).show();
5287                         animateTo = 1;
5288                 }
5290                 if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
5291                         times--;
5292                 }
5294                 for (var i = 0; i < times; i++) {
5295                         elem.animate({ opacity: animateTo }, duration, o.options.easing);
5296                         animateTo = (animateTo + 1) % 2;
5297                 }
5299                 elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
5300                         if (animateTo == 0) {
5301                                 elem.hide();
5302                         }
5303                         (o.callback && o.callback.apply(this, arguments));
5304                 });
5306                 elem
5307                         .queue('fx', function() { elem.dequeue(); })
5308                         .dequeue();
5309         });
5312 })(jQuery);
5314  * jQuery UI Effects Scale 1.8.16
5316  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5317  * Dual licensed under the MIT or GPL Version 2 licenses.
5318  * http://jquery.org/license
5320  * http://docs.jquery.com/UI/Effects/Scale
5322  * Depends:
5323  *      jquery.effects.core.js
5324  */
5325 (function( $, undefined ) {
5327 $.effects.puff = function(o) {
5328         return this.queue(function() {
5329                 var elem = $(this),
5330                         mode = $.effects.setMode(elem, o.options.mode || 'hide'),
5331                         percent = parseInt(o.options.percent, 10) || 150,
5332                         factor = percent / 100,
5333                         original = { height: elem.height(), width: elem.width() };
5335                 $.extend(o.options, {
5336                         fade: true,
5337                         mode: mode,
5338                         percent: mode == 'hide' ? percent : 100,
5339                         from: mode == 'hide'
5340                                 ? original
5341                                 : {
5342                                         height: original.height * factor,
5343                                         width: original.width * factor
5344                                 }
5345                 });
5347                 elem.effect('scale', o.options, o.duration, o.callback);
5348                 elem.dequeue();
5349         });
5352 $.effects.scale = function(o) {
5354         return this.queue(function() {
5356                 // Create element
5357                 var el = $(this);
5359                 // Set options
5360                 var options = $.extend(true, {}, o.options);
5361                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5362                 var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
5363                 var direction = o.options.direction || 'both'; // Set default axis
5364                 var origin = o.options.origin; // The origin of the scaling
5365                 if (mode != 'effect') { // Set default origin and restore for show/hide
5366                         options.origin = origin || ['middle','center'];
5367                         options.restore = true;
5368                 }
5369                 var original = {height: el.height(), width: el.width()}; // Save original
5370                 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
5372                 // Adjust
5373                 var factor = { // Set scaling factor
5374                         y: direction != 'horizontal' ? (percent / 100) : 1,
5375                         x: direction != 'vertical' ? (percent / 100) : 1
5376                 };
5377                 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
5379                 if (o.options.fade) { // Fade option to support puff
5380                         if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
5381                         if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
5382                 };
5384                 // Animation
5385                 options.from = el.from; options.to = el.to; options.mode = mode;
5387                 // Animate
5388                 el.effect('size', options, o.duration, o.callback);
5389                 el.dequeue();
5390         });
5394 $.effects.size = function(o) {
5396         return this.queue(function() {
5398                 // Create element
5399                 var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
5400                 var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
5401                 var props2 = ['width','height','overflow']; // Copy for children
5402                 var cProps = ['fontSize'];
5403                 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
5404                 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
5406                 // Set options
5407                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5408                 var restore = o.options.restore || false; // Default restore
5409                 var scale = o.options.scale || 'both'; // Default scale mode
5410                 var origin = o.options.origin; // The origin of the sizing
5411                 var original = {height: el.height(), width: el.width()}; // Save original
5412                 el.from = o.options.from || original; // Default from state
5413                 el.to = o.options.to || original; // Default to state
5414                 // Adjust
5415                 if (origin) { // Calculate baseline shifts
5416                         var baseline = $.effects.getBaseline(origin, original);
5417                         el.from.top = (original.height - el.from.height) * baseline.y;
5418                         el.from.left = (original.width - el.from.width) * baseline.x;
5419                         el.to.top = (original.height - el.to.height) * baseline.y;
5420                         el.to.left = (original.width - el.to.width) * baseline.x;
5421                 };
5422                 var factor = { // Set scaling factor
5423                         from: {y: el.from.height / original.height, x: el.from.width / original.width},
5424                         to: {y: el.to.height / original.height, x: el.to.width / original.width}
5425                 };
5426                 if (scale == 'box' || scale == 'both') { // Scale the css box
5427                         if (factor.from.y != factor.to.y) { // Vertical props scaling
5428                                 props = props.concat(vProps);
5429                                 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
5430                                 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
5431                         };
5432                         if (factor.from.x != factor.to.x) { // Horizontal props scaling
5433                                 props = props.concat(hProps);
5434                                 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
5435                                 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
5436                         };
5437                 };
5438                 if (scale == 'content' || scale == 'both') { // Scale the content
5439                         if (factor.from.y != factor.to.y) { // Vertical props scaling
5440                                 props = props.concat(cProps);
5441                                 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
5442                                 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
5443                         };
5444                 };
5445                 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
5446                 $.effects.createWrapper(el); // Create Wrapper
5447                 el.css('overflow','hidden').css(el.from); // Shift
5449                 // Animate
5450                 if (scale == 'content' || scale == 'both') { // Scale the children
5451                         vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
5452                         hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
5453                         props2 = props.concat(vProps).concat(hProps); // Concat
5454                         el.find("*[width]").each(function(){
5455                                 child = $(this);
5456                                 if (restore) $.effects.save(child, props2);
5457                                 var c_original = {height: child.height(), width: child.width()}; // Save original
5458                                 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
5459                                 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
5460                                 if (factor.from.y != factor.to.y) { // Vertical props scaling
5461                                         child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
5462                                         child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
5463                                 };
5464                                 if (factor.from.x != factor.to.x) { // Horizontal props scaling
5465                                         child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
5466                                         child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
5467                                 };
5468                                 child.css(child.from); // Shift children
5469                                 child.animate(child.to, o.duration, o.options.easing, function(){
5470                                         if (restore) $.effects.restore(child, props2); // Restore children
5471                                 }); // Animate children
5472                         });
5473                 };
5475                 // Animate
5476                 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5477                         if (el.to.opacity === 0) {
5478                                 el.css('opacity', el.from.opacity);
5479                         }
5480                         if(mode == 'hide') el.hide(); // Hide
5481                         $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
5482                         if(o.callback) o.callback.apply(this, arguments); // Callback
5483                         el.dequeue();
5484                 }});
5486         });
5490 })(jQuery);
5492  * jQuery UI Effects Shake 1.8.16
5494  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5495  * Dual licensed under the MIT or GPL Version 2 licenses.
5496  * http://jquery.org/license
5498  * http://docs.jquery.com/UI/Effects/Shake
5500  * Depends:
5501  *      jquery.effects.core.js
5502  */
5503 (function( $, undefined ) {
5505 $.effects.shake = function(o) {
5507         return this.queue(function() {
5509                 // Create element
5510                 var el = $(this), props = ['position','top','bottom','left','right'];
5512                 // Set options
5513                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5514                 var direction = o.options.direction || 'left'; // Default direction
5515                 var distance = o.options.distance || 20; // Default distance
5516                 var times = o.options.times || 3; // Default # of times
5517                 var speed = o.duration || o.options.duration || 140; // Default speed per shake
5519                 // Adjust
5520                 $.effects.save(el, props); el.show(); // Save & Show
5521                 $.effects.createWrapper(el); // Create Wrapper
5522                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5523                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5525                 // Animation
5526                 var animation = {}, animation1 = {}, animation2 = {};
5527                 animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
5528                 animation1[ref] = (motion == 'pos' ? '+=' : '-=')  + distance * 2;
5529                 animation2[ref] = (motion == 'pos' ? '-=' : '+=')  + distance * 2;
5531                 // Animate
5532                 el.animate(animation, speed, o.options.easing);
5533                 for (var i = 1; i < times; i++) { // Shakes
5534                         el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
5535                 };
5536                 el.animate(animation1, speed, o.options.easing).
5537                 animate(animation, speed / 2, o.options.easing, function(){ // Last shake
5538                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5539                         if(o.callback) o.callback.apply(this, arguments); // Callback
5540                 });
5541                 el.queue('fx', function() { el.dequeue(); });
5542                 el.dequeue();
5543         });
5547 })(jQuery);
5549  * jQuery UI Effects Slide 1.8.16
5551  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5552  * Dual licensed under the MIT or GPL Version 2 licenses.
5553  * http://jquery.org/license
5555  * http://docs.jquery.com/UI/Effects/Slide
5557  * Depends:
5558  *      jquery.effects.core.js
5559  */
5560 (function( $, undefined ) {
5562 $.effects.slide = function(o) {
5564         return this.queue(function() {
5566                 // Create element
5567                 var el = $(this), props = ['position','top','bottom','left','right'];
5569                 // Set options
5570                 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
5571                 var direction = o.options.direction || 'left'; // Default Direction
5573                 // Adjust
5574                 $.effects.save(el, props); el.show(); // Save & Show
5575                 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
5576                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5577                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5578                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
5579                 if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
5581                 // Animation
5582                 var animation = {};
5583                 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
5585                 // Animate
5586                 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5587                         if(mode == 'hide') el.hide(); // Hide
5588                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5589                         if(o.callback) o.callback.apply(this, arguments); // Callback
5590                         el.dequeue();
5591                 }});
5593         });
5597 })(jQuery);
5599  * jQuery UI Effects Transfer 1.8.16
5601  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5602  * Dual licensed under the MIT or GPL Version 2 licenses.
5603  * http://jquery.org/license
5605  * http://docs.jquery.com/UI/Effects/Transfer
5607  * Depends:
5608  *      jquery.effects.core.js
5609  */
5610 (function( $, undefined ) {
5612 $.effects.transfer = function(o) {
5613         return this.queue(function() {
5614                 var elem = $(this),
5615                         target = $(o.options.to),
5616                         endPosition = target.offset(),
5617                         animation = {
5618                                 top: endPosition.top,
5619                                 left: endPosition.left,
5620                                 height: target.innerHeight(),
5621                                 width: target.innerWidth()
5622                         },
5623                         startPosition = elem.offset(),
5624                         transfer = $('<div class="ui-effects-transfer"></div>')
5625                                 .appendTo(document.body)
5626                                 .addClass(o.options.className)
5627                                 .css({
5628                                         top: startPosition.top,
5629                                         left: startPosition.left,
5630                                         height: elem.innerHeight(),
5631                                         width: elem.innerWidth(),
5632                                         position: 'absolute'
5633                                 })
5634                                 .animate(animation, o.duration, o.options.easing, function() {
5635                                         transfer.remove();
5636                                         (o.callback && o.callback.apply(elem[0], arguments));
5637                                         elem.dequeue();
5638                                 });
5639         });
5642 })(jQuery);
5644  * jQuery UI Accordion 1.8.16
5646  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5647  * Dual licensed under the MIT or GPL Version 2 licenses.
5648  * http://jquery.org/license
5650  * http://docs.jquery.com/UI/Accordion
5652  * Depends:
5653  *      jquery.ui.core.js
5654  *      jquery.ui.widget.js
5655  */
5656 (function( $, undefined ) {
5658 $.widget( "ui.accordion", {
5659         options: {
5660                 active: 0,
5661                 animated: "slide",
5662                 autoHeight: true,
5663                 clearStyle: false,
5664                 collapsible: false,
5665                 event: "click",
5666                 fillSpace: false,
5667                 header: "> li > :first-child,> :not(li):even",
5668                 icons: {
5669                         header: "ui-icon-triangle-1-e",
5670                         headerSelected: "ui-icon-triangle-1-s"
5671                 },
5672                 navigation: false,
5673                 navigationFilter: function() {
5674                         return this.href.toLowerCase() === location.href.toLowerCase();
5675                 }
5676         },
5678         _create: function() {
5679                 var self = this,
5680                         options = self.options;
5682                 self.running = 0;
5684                 self.element
5685                         .addClass( "ui-accordion ui-widget ui-helper-reset" )
5686                         // in lack of child-selectors in CSS
5687                         // we need to mark top-LIs in a UL-accordion for some IE-fix
5688                         .children( "li" )
5689                                 .addClass( "ui-accordion-li-fix" );
5691                 self.headers = self.element.find( options.header )
5692                         .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
5693                         .bind( "mouseenter.accordion", function() {
5694                                 if ( options.disabled ) {
5695                                         return;
5696                                 }
5697                                 $( this ).addClass( "ui-state-hover" );
5698                         })
5699                         .bind( "mouseleave.accordion", function() {
5700                                 if ( options.disabled ) {
5701                                         return;
5702                                 }
5703                                 $( this ).removeClass( "ui-state-hover" );
5704                         })
5705                         .bind( "focus.accordion", function() {
5706                                 if ( options.disabled ) {
5707                                         return;
5708                                 }
5709                                 $( this ).addClass( "ui-state-focus" );
5710                         })
5711                         .bind( "blur.accordion", function() {
5712                                 if ( options.disabled ) {
5713                                         return;
5714                                 }
5715                                 $( this ).removeClass( "ui-state-focus" );
5716                         });
5718                 self.headers.next()
5719                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
5721                 if ( options.navigation ) {
5722                         var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
5723                         if ( current.length ) {
5724                                 var header = current.closest( ".ui-accordion-header" );
5725                                 if ( header.length ) {
5726                                         // anchor within header
5727                                         self.active = header;
5728                                 } else {
5729                                         // anchor within content
5730                                         self.active = current.closest( ".ui-accordion-content" ).prev();
5731                                 }
5732                         }
5733                 }
5735                 self.active = self._findActive( self.active || options.active )
5736                         .addClass( "ui-state-default ui-state-active" )
5737                         .toggleClass( "ui-corner-all" )
5738                         .toggleClass( "ui-corner-top" );
5739                 self.active.next().addClass( "ui-accordion-content-active" );
5741                 self._createIcons();
5742                 self.resize();
5743                 
5744                 // ARIA
5745                 self.element.attr( "role", "tablist" );
5747                 self.headers
5748                         .attr( "role", "tab" )
5749                         .bind( "keydown.accordion", function( event ) {
5750                                 return self._keydown( event );
5751                         })
5752                         .next()
5753                                 .attr( "role", "tabpanel" );
5755                 self.headers
5756                         .not( self.active || "" )
5757                         .attr({
5758                                 "aria-expanded": "false",
5759                                 "aria-selected": "false",
5760                                 tabIndex: -1
5761                         })
5762                         .next()
5763                                 .hide();
5765                 // make sure at least one header is in the tab order
5766                 if ( !self.active.length ) {
5767                         self.headers.eq( 0 ).attr( "tabIndex", 0 );
5768                 } else {
5769                         self.active
5770                                 .attr({
5771                                         "aria-expanded": "true",
5772                                         "aria-selected": "true",
5773                                         tabIndex: 0
5774                                 });
5775                 }
5777                 // only need links in tab order for Safari
5778                 if ( !$.browser.safari ) {
5779                         self.headers.find( "a" ).attr( "tabIndex", -1 );
5780                 }
5782                 if ( options.event ) {
5783                         self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
5784                                 self._clickHandler.call( self, event, this );
5785                                 event.preventDefault();
5786                         });
5787                 }
5788         },
5790         _createIcons: function() {
5791                 var options = this.options;
5792                 if ( options.icons ) {
5793                         $( "<span></span>" )
5794                                 .addClass( "ui-icon " + options.icons.header )
5795                                 .prependTo( this.headers );
5796                         this.active.children( ".ui-icon" )
5797                                 .toggleClass(options.icons.header)
5798                                 .toggleClass(options.icons.headerSelected);
5799                         this.element.addClass( "ui-accordion-icons" );
5800                 }
5801         },
5803         _destroyIcons: function() {
5804                 this.headers.children( ".ui-icon" ).remove();
5805                 this.element.removeClass( "ui-accordion-icons" );
5806         },
5808         destroy: function() {
5809                 var options = this.options;
5811                 this.element
5812                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5813                         .removeAttr( "role" );
5815                 this.headers
5816                         .unbind( ".accordion" )
5817                         .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5818                         .removeAttr( "role" )
5819                         .removeAttr( "aria-expanded" )
5820                         .removeAttr( "aria-selected" )
5821                         .removeAttr( "tabIndex" );
5823                 this.headers.find( "a" ).removeAttr( "tabIndex" );
5824                 this._destroyIcons();
5825                 var contents = this.headers.next()
5826                         .css( "display", "" )
5827                         .removeAttr( "role" )
5828                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
5829                 if ( options.autoHeight || options.fillHeight ) {
5830                         contents.css( "height", "" );
5831                 }
5833                 return $.Widget.prototype.destroy.call( this );
5834         },
5836         _setOption: function( key, value ) {
5837                 $.Widget.prototype._setOption.apply( this, arguments );
5838                         
5839                 if ( key == "active" ) {
5840                         this.activate( value );
5841                 }
5842                 if ( key == "icons" ) {
5843                         this._destroyIcons();
5844                         if ( value ) {
5845                                 this._createIcons();
5846                         }
5847                 }
5848                 // #5332 - opacity doesn't cascade to positioned elements in IE
5849                 // so we need to add the disabled class to the headers and panels
5850                 if ( key == "disabled" ) {
5851                         this.headers.add(this.headers.next())
5852                                 [ value ? "addClass" : "removeClass" ](
5853                                         "ui-accordion-disabled ui-state-disabled" );
5854                 }
5855         },
5857         _keydown: function( event ) {
5858                 if ( this.options.disabled || event.altKey || event.ctrlKey ) {
5859                         return;
5860                 }
5862                 var keyCode = $.ui.keyCode,
5863                         length = this.headers.length,
5864                         currentIndex = this.headers.index( event.target ),
5865                         toFocus = false;
5867                 switch ( event.keyCode ) {
5868                         case keyCode.RIGHT:
5869                         case keyCode.DOWN:
5870                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5871                                 break;
5872                         case keyCode.LEFT:
5873                         case keyCode.UP:
5874                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5875                                 break;
5876                         case keyCode.SPACE:
5877                         case keyCode.ENTER:
5878                                 this._clickHandler( { target: event.target }, event.target );
5879                                 event.preventDefault();
5880                 }
5882                 if ( toFocus ) {
5883                         $( event.target ).attr( "tabIndex", -1 );
5884                         $( toFocus ).attr( "tabIndex", 0 );
5885                         toFocus.focus();
5886                         return false;
5887                 }
5889                 return true;
5890         },
5892         resize: function() {
5893                 var options = this.options,
5894                         maxHeight;
5896                 if ( options.fillSpace ) {
5897                         if ( $.browser.msie ) {
5898                                 var defOverflow = this.element.parent().css( "overflow" );
5899                                 this.element.parent().css( "overflow", "hidden");
5900                         }
5901                         maxHeight = this.element.parent().height();
5902                         if ($.browser.msie) {
5903                                 this.element.parent().css( "overflow", defOverflow );
5904                         }
5906                         this.headers.each(function() {
5907                                 maxHeight -= $( this ).outerHeight( true );
5908                         });
5910                         this.headers.next()
5911                                 .each(function() {
5912                                         $( this ).height( Math.max( 0, maxHeight -
5913                                                 $( this ).innerHeight() + $( this ).height() ) );
5914                                 })
5915                                 .css( "overflow", "auto" );
5916                 } else if ( options.autoHeight ) {
5917                         maxHeight = 0;
5918                         this.headers.next()
5919                                 .each(function() {
5920                                         maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
5921                                 })
5922                                 .height( maxHeight );
5923                 }
5925                 return this;
5926         },
5928         activate: function( index ) {
5929                 // TODO this gets called on init, changing the option without an explicit call for that
5930                 this.options.active = index;
5931                 // call clickHandler with custom event
5932                 var active = this._findActive( index )[ 0 ];
5933                 this._clickHandler( { target: active }, active );
5935                 return this;
5936         },
5938         _findActive: function( selector ) {
5939                 return selector
5940                         ? typeof selector === "number"
5941                                 ? this.headers.filter( ":eq(" + selector + ")" )
5942                                 : this.headers.not( this.headers.not( selector ) )
5943                         : selector === false
5944                                 ? $( [] )
5945                                 : this.headers.filter( ":eq(0)" );
5946         },
5948         // TODO isn't event.target enough? why the separate target argument?
5949         _clickHandler: function( event, target ) {
5950                 var options = this.options;
5951                 if ( options.disabled ) {
5952                         return;
5953                 }
5955                 // called only when using activate(false) to close all parts programmatically
5956                 if ( !event.target ) {
5957                         if ( !options.collapsible ) {
5958                                 return;
5959                         }
5960                         this.active
5961                                 .removeClass( "ui-state-active ui-corner-top" )
5962                                 .addClass( "ui-state-default ui-corner-all" )
5963                                 .children( ".ui-icon" )
5964                                         .removeClass( options.icons.headerSelected )
5965                                         .addClass( options.icons.header );
5966                         this.active.next().addClass( "ui-accordion-content-active" );
5967                         var toHide = this.active.next(),
5968                                 data = {
5969                                         options: options,
5970                                         newHeader: $( [] ),
5971                                         oldHeader: options.active,
5972                                         newContent: $( [] ),
5973                                         oldContent: toHide
5974                                 },
5975                                 toShow = ( this.active = $( [] ) );
5976                         this._toggle( toShow, toHide, data );
5977                         return;
5978                 }
5980                 // get the click target
5981                 var clicked = $( event.currentTarget || target ),
5982                         clickedIsActive = clicked[0] === this.active[0];
5984                 // TODO the option is changed, is that correct?
5985                 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
5986                 options.active = options.collapsible && clickedIsActive ?
5987                         false :
5988                         this.headers.index( clicked );
5990                 // if animations are still active, or the active header is the target, ignore click
5991                 if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
5992                         return;
5993                 }
5995                 // find elements to show and hide
5996                 var active = this.active,
5997                         toShow = clicked.next(),
5998                         toHide = this.active.next(),
5999                         data = {
6000                                 options: options,
6001                                 newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
6002                                 oldHeader: this.active,
6003                                 newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
6004                                 oldContent: toHide
6005                         },
6006                         down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
6008                 // when the call to ._toggle() comes after the class changes
6009                 // it causes a very odd bug in IE 8 (see #6720)
6010                 this.active = clickedIsActive ? $([]) : clicked;
6011                 this._toggle( toShow, toHide, data, clickedIsActive, down );
6013                 // switch classes
6014                 active
6015                         .removeClass( "ui-state-active ui-corner-top" )
6016                         .addClass( "ui-state-default ui-corner-all" )
6017                         .children( ".ui-icon" )
6018                                 .removeClass( options.icons.headerSelected )
6019                                 .addClass( options.icons.header );
6020                 if ( !clickedIsActive ) {
6021                         clicked
6022                                 .removeClass( "ui-state-default ui-corner-all" )
6023                                 .addClass( "ui-state-active ui-corner-top" )
6024                                 .children( ".ui-icon" )
6025                                         .removeClass( options.icons.header )
6026                                         .addClass( options.icons.headerSelected );
6027                         clicked
6028                                 .next()
6029                                 .addClass( "ui-accordion-content-active" );
6030                 }
6032                 return;
6033         },
6035         _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
6036                 var self = this,
6037                         options = self.options;
6039                 self.toShow = toShow;
6040                 self.toHide = toHide;
6041                 self.data = data;
6043                 var complete = function() {
6044                         if ( !self ) {
6045                                 return;
6046                         }
6047                         return self._completed.apply( self, arguments );
6048                 };
6050                 // trigger changestart event
6051                 self._trigger( "changestart", null, self.data );
6053                 // count elements to animate
6054                 self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
6056                 if ( options.animated ) {
6057                         var animOptions = {};
6059                         if ( options.collapsible && clickedIsActive ) {
6060                                 animOptions = {
6061                                         toShow: $( [] ),
6062                                         toHide: toHide,
6063                                         complete: complete,
6064                                         down: down,
6065                                         autoHeight: options.autoHeight || options.fillSpace
6066                                 };
6067                         } else {
6068                                 animOptions = {
6069                                         toShow: toShow,
6070                                         toHide: toHide,
6071                                         complete: complete,
6072                                         down: down,
6073                                         autoHeight: options.autoHeight || options.fillSpace
6074                                 };
6075                         }
6077                         if ( !options.proxied ) {
6078                                 options.proxied = options.animated;
6079                         }
6081                         if ( !options.proxiedDuration ) {
6082                                 options.proxiedDuration = options.duration;
6083                         }
6085                         options.animated = $.isFunction( options.proxied ) ?
6086                                 options.proxied( animOptions ) :
6087                                 options.proxied;
6089                         options.duration = $.isFunction( options.proxiedDuration ) ?
6090                                 options.proxiedDuration( animOptions ) :
6091                                 options.proxiedDuration;
6093                         var animations = $.ui.accordion.animations,
6094                                 duration = options.duration,
6095                                 easing = options.animated;
6097                         if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
6098                                 easing = "slide";
6099                         }
6100                         if ( !animations[ easing ] ) {
6101                                 animations[ easing ] = function( options ) {
6102                                         this.slide( options, {
6103                                                 easing: easing,
6104                                                 duration: duration || 700
6105                                         });
6106                                 };
6107                         }
6109                         animations[ easing ]( animOptions );
6110                 } else {
6111                         if ( options.collapsible && clickedIsActive ) {
6112                                 toShow.toggle();
6113                         } else {
6114                                 toHide.hide();
6115                                 toShow.show();
6116                         }
6118                         complete( true );
6119                 }
6121                 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
6122                 toHide.prev()
6123                         .attr({
6124                                 "aria-expanded": "false",
6125                                 "aria-selected": "false",
6126                                 tabIndex: -1
6127                         })
6128                         .blur();
6129                 toShow.prev()
6130                         .attr({
6131                                 "aria-expanded": "true",
6132                                 "aria-selected": "true",
6133                                 tabIndex: 0
6134                         })
6135                         .focus();
6136         },
6138         _completed: function( cancel ) {
6139                 this.running = cancel ? 0 : --this.running;
6140                 if ( this.running ) {
6141                         return;
6142                 }
6144                 if ( this.options.clearStyle ) {
6145                         this.toShow.add( this.toHide ).css({
6146                                 height: "",
6147                                 overflow: ""
6148                         });
6149                 }
6151                 // other classes are removed before the animation; this one needs to stay until completed
6152                 this.toHide.removeClass( "ui-accordion-content-active" );
6153                 // Work around for rendering bug in IE (#5421)
6154                 if ( this.toHide.length ) {
6155                         this.toHide.parent()[0].className = this.toHide.parent()[0].className;
6156                 }
6158                 this._trigger( "change", null, this.data );
6159         }
6162 $.extend( $.ui.accordion, {
6163         version: "1.8.16",
6164         animations: {
6165                 slide: function( options, additions ) {
6166                         options = $.extend({
6167                                 easing: "swing",
6168                                 duration: 300
6169                         }, options, additions );
6170                         if ( !options.toHide.size() ) {
6171                                 options.toShow.animate({
6172                                         height: "show",
6173                                         paddingTop: "show",
6174                                         paddingBottom: "show"
6175                                 }, options );
6176                                 return;
6177                         }
6178                         if ( !options.toShow.size() ) {
6179                                 options.toHide.animate({
6180                                         height: "hide",
6181                                         paddingTop: "hide",
6182                                         paddingBottom: "hide"
6183                                 }, options );
6184                                 return;
6185                         }
6186                         var overflow = options.toShow.css( "overflow" ),
6187                                 percentDone = 0,
6188                                 showProps = {},
6189                                 hideProps = {},
6190                                 fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
6191                                 originalWidth;
6192                         // fix width before calculating height of hidden element
6193                         var s = options.toShow;
6194                         originalWidth = s[0].style.width;
6195                         s.width( parseInt( s.parent().width(), 10 )
6196                                 - parseInt( s.css( "paddingLeft" ), 10 )
6197                                 - parseInt( s.css( "paddingRight" ), 10 )
6198                                 - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
6199                                 - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
6201                         $.each( fxAttrs, function( i, prop ) {
6202                                 hideProps[ prop ] = "hide";
6204                                 var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
6205                                 showProps[ prop ] = {
6206                                         value: parts[ 1 ],
6207                                         unit: parts[ 2 ] || "px"
6208                                 };
6209                         });
6210                         options.toShow.css({ height: 0, overflow: "hidden" }).show();
6211                         options.toHide
6212                                 .filter( ":hidden" )
6213                                         .each( options.complete )
6214                                 .end()
6215                                 .filter( ":visible" )
6216                                 .animate( hideProps, {
6217                                 step: function( now, settings ) {
6218                                         // only calculate the percent when animating height
6219                                         // IE gets very inconsistent results when animating elements
6220                                         // with small values, which is common for padding
6221                                         if ( settings.prop == "height" ) {
6222                                                 percentDone = ( settings.end - settings.start === 0 ) ? 0 :
6223                                                         ( settings.now - settings.start ) / ( settings.end - settings.start );
6224                                         }
6226                                         options.toShow[ 0 ].style[ settings.prop ] =
6227                                                 ( percentDone * showProps[ settings.prop ].value )
6228                                                 + showProps[ settings.prop ].unit;
6229                                 },
6230                                 duration: options.duration,
6231                                 easing: options.easing,
6232                                 complete: function() {
6233                                         if ( !options.autoHeight ) {
6234                                                 options.toShow.css( "height", "" );
6235                                         }
6236                                         options.toShow.css({
6237                                                 width: originalWidth,
6238                                                 overflow: overflow
6239                                         });
6240                                         options.complete();
6241                                 }
6242                         });
6243                 },
6244                 bounceslide: function( options ) {
6245                         this.slide( options, {
6246                                 easing: options.down ? "easeOutBounce" : "swing",
6247                                 duration: options.down ? 1000 : 200
6248                         });
6249                 }
6250         }
6253 })( jQuery );
6255  * jQuery UI Autocomplete 1.8.16
6257  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6258  * Dual licensed under the MIT or GPL Version 2 licenses.
6259  * http://jquery.org/license
6261  * http://docs.jquery.com/UI/Autocomplete
6263  * Depends:
6264  *      jquery.ui.core.js
6265  *      jquery.ui.widget.js
6266  *      jquery.ui.position.js
6267  */
6268 (function( $, undefined ) {
6270 // used to prevent race conditions with remote data sources
6271 var requestIndex = 0;
6273 $.widget( "ui.autocomplete", {
6274         options: {
6275                 appendTo: "body",
6276                 autoFocus: false,
6277                 delay: 300,
6278                 minLength: 1,
6279                 position: {
6280                         my: "left top",
6281                         at: "left bottom",
6282                         collision: "none"
6283                 },
6284                 source: null
6285         },
6287         pending: 0,
6289         _create: function() {
6290                 var self = this,
6291                         doc = this.element[ 0 ].ownerDocument,
6292                         suppressKeyPress;
6294                 this.element
6295                         .addClass( "ui-autocomplete-input" )
6296                         .attr( "autocomplete", "off" )
6297                         // TODO verify these actually work as intended
6298                         .attr({
6299                                 role: "textbox",
6300                                 "aria-autocomplete": "list",
6301                                 "aria-haspopup": "true"
6302                         })
6303                         .bind( "keydown.autocomplete", function( event ) {
6304                                 if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
6305                                         return;
6306                                 }
6308                                 suppressKeyPress = false;
6309                                 var keyCode = $.ui.keyCode;
6310                                 switch( event.keyCode ) {
6311                                 case keyCode.PAGE_UP:
6312                                         self._move( "previousPage", event );
6313                                         break;
6314                                 case keyCode.PAGE_DOWN:
6315                                         self._move( "nextPage", event );
6316                                         break;
6317                                 case keyCode.UP:
6318                                         self._move( "previous", event );
6319                                         // prevent moving cursor to beginning of text field in some browsers
6320                                         event.preventDefault();
6321                                         break;
6322                                 case keyCode.DOWN:
6323                                         self._move( "next", event );
6324                                         // prevent moving cursor to end of text field in some browsers
6325                                         event.preventDefault();
6326                                         break;
6327                                 case keyCode.ENTER:
6328                                 case keyCode.NUMPAD_ENTER:
6329                                         // when menu is open and has focus
6330                                         if ( self.menu.active ) {
6331                                                 // #6055 - Opera still allows the keypress to occur
6332                                                 // which causes forms to submit
6333                                                 suppressKeyPress = true;
6334                                                 event.preventDefault();
6335                                         }
6336                                         //passthrough - ENTER and TAB both select the current element
6337                                 case keyCode.TAB:
6338                                         if ( !self.menu.active ) {
6339                                                 return;
6340                                         }
6341                                         self.menu.select( event );
6342                                         break;
6343                                 case keyCode.ESCAPE:
6344                                         self.element.val( self.term );
6345                                         self.close( event );
6346                                         break;
6347                                 default:
6348                                         // keypress is triggered before the input value is changed
6349                                         clearTimeout( self.searching );
6350                                         self.searching = setTimeout(function() {
6351                                                 // only search if the value has changed
6352                                                 if ( self.term != self.element.val() ) {
6353                                                         self.selectedItem = null;
6354                                                         self.search( null, event );
6355                                                 }
6356                                         }, self.options.delay );
6357                                         break;
6358                                 }
6359                         })
6360                         .bind( "keypress.autocomplete", function( event ) {
6361                                 if ( suppressKeyPress ) {
6362                                         suppressKeyPress = false;
6363                                         event.preventDefault();
6364                                 }
6365                         })
6366                         .bind( "focus.autocomplete", function() {
6367                                 if ( self.options.disabled ) {
6368                                         return;
6369                                 }
6371                                 self.selectedItem = null;
6372                                 self.previous = self.element.val();
6373                         })
6374                         .bind( "blur.autocomplete", function( event ) {
6375                                 if ( self.options.disabled ) {
6376                                         return;
6377                                 }
6379                                 clearTimeout( self.searching );
6380                                 // clicks on the menu (or a button to trigger a search) will cause a blur event
6381                                 self.closing = setTimeout(function() {
6382                                         self.close( event );
6383                                         self._change( event );
6384                                 }, 150 );
6385                         });
6386                 this._initSource();
6387                 this.response = function() {
6388                         return self._response.apply( self, arguments );
6389                 };
6390                 this.menu = $( "<ul></ul>" )
6391                         .addClass( "ui-autocomplete" )
6392                         .appendTo( $( this.options.appendTo || "body", doc )[0] )
6393                         // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
6394                         .mousedown(function( event ) {
6395                                 // clicking on the scrollbar causes focus to shift to the body
6396                                 // but we can't detect a mouseup or a click immediately afterward
6397                                 // so we have to track the next mousedown and close the menu if
6398                                 // the user clicks somewhere outside of the autocomplete
6399                                 var menuElement = self.menu.element[ 0 ];
6400                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6401                                         setTimeout(function() {
6402                                                 $( document ).one( 'mousedown', function( event ) {
6403                                                         if ( event.target !== self.element[ 0 ] &&
6404                                                                 event.target !== menuElement &&
6405                                                                 !$.ui.contains( menuElement, event.target ) ) {
6406                                                                 self.close();
6407                                                         }
6408                                                 });
6409                                         }, 1 );
6410                                 }
6412                                 // use another timeout to make sure the blur-event-handler on the input was already triggered
6413                                 setTimeout(function() {
6414                                         clearTimeout( self.closing );
6415                                 }, 13);
6416                         })
6417                         .menu({
6418                                 focus: function( event, ui ) {
6419                                         var item = ui.item.data( "item.autocomplete" );
6420                                         if ( false !== self._trigger( "focus", event, { item: item } ) ) {
6421                                                 // use value to match what will end up in the input, if it was a key event
6422                                                 if ( /^key/.test(event.originalEvent.type) ) {
6423                                                         self.element.val( item.value );
6424                                                 }
6425                                         }
6426                                 },
6427                                 selected: function( event, ui ) {
6428                                         var item = ui.item.data( "item.autocomplete" ),
6429                                                 previous = self.previous;
6431                                         // only trigger when focus was lost (click on menu)
6432                                         if ( self.element[0] !== doc.activeElement ) {
6433                                                 self.element.focus();
6434                                                 self.previous = previous;
6435                                                 // #6109 - IE triggers two focus events and the second
6436                                                 // is asynchronous, so we need to reset the previous
6437                                                 // term synchronously and asynchronously :-(
6438                                                 setTimeout(function() {
6439                                                         self.previous = previous;
6440                                                         self.selectedItem = item;
6441                                                 }, 1);
6442                                         }
6444                                         if ( false !== self._trigger( "select", event, { item: item } ) ) {
6445                                                 self.element.val( item.value );
6446                                         }
6447                                         // reset the term after the select event
6448                                         // this allows custom select handling to work properly
6449                                         self.term = self.element.val();
6451                                         self.close( event );
6452                                         self.selectedItem = item;
6453                                 },
6454                                 blur: function( event, ui ) {
6455                                         // don't set the value of the text field if it's already correct
6456                                         // this prevents moving the cursor unnecessarily
6457                                         if ( self.menu.element.is(":visible") &&
6458                                                 ( self.element.val() !== self.term ) ) {
6459                                                 self.element.val( self.term );
6460                                         }
6461                                 }
6462                         })
6463                         .zIndex( this.element.zIndex() + 1 )
6464                         // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6465                         .css({ top: 0, left: 0 })
6466                         .hide()
6467                         .data( "menu" );
6468                 if ( $.fn.bgiframe ) {
6469                          this.menu.element.bgiframe();
6470                 }
6471         },
6473         destroy: function() {
6474                 this.element
6475                         .removeClass( "ui-autocomplete-input" )
6476                         .removeAttr( "autocomplete" )
6477                         .removeAttr( "role" )
6478                         .removeAttr( "aria-autocomplete" )
6479                         .removeAttr( "aria-haspopup" );
6480                 this.menu.element.remove();
6481                 $.Widget.prototype.destroy.call( this );
6482         },
6484         _setOption: function( key, value ) {
6485                 $.Widget.prototype._setOption.apply( this, arguments );
6486                 if ( key === "source" ) {
6487                         this._initSource();
6488                 }
6489                 if ( key === "appendTo" ) {
6490                         this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
6491                 }
6492                 if ( key === "disabled" && value && this.xhr ) {
6493                         this.xhr.abort();
6494                 }
6495         },
6497         _initSource: function() {
6498                 var self = this,
6499                         array,
6500                         url;
6501                 if ( $.isArray(this.options.source) ) {
6502                         array = this.options.source;
6503                         this.source = function( request, response ) {
6504                                 response( $.ui.autocomplete.filter(array, request.term) );
6505                         };
6506                 } else if ( typeof this.options.source === "string" ) {
6507                         url = this.options.source;
6508                         this.source = function( request, response ) {
6509                                 if ( self.xhr ) {
6510                                         self.xhr.abort();
6511                                 }
6512                                 self.xhr = $.ajax({
6513                                         url: url,
6514                                         data: request,
6515                                         dataType: "json",
6516                                         autocompleteRequest: ++requestIndex,
6517                                         success: function( data, status ) {
6518                                                 if ( this.autocompleteRequest === requestIndex ) {
6519                                                         response( data );
6520                                                 }
6521                                         },
6522                                         error: function() {
6523                                                 if ( this.autocompleteRequest === requestIndex ) {
6524                                                         response( [] );
6525                                                 }
6526                                         }
6527                                 });
6528                         };
6529                 } else {
6530                         this.source = this.options.source;
6531                 }
6532         },
6534         search: function( value, event ) {
6535                 value = value != null ? value : this.element.val();
6537                 // always save the actual value, not the one passed as an argument
6538                 this.term = this.element.val();
6540                 if ( value.length < this.options.minLength ) {
6541                         return this.close( event );
6542                 }
6544                 clearTimeout( this.closing );
6545                 if ( this._trigger( "search", event ) === false ) {
6546                         return;
6547                 }
6549                 return this._search( value );
6550         },
6552         _search: function( value ) {
6553                 this.pending++;
6554                 this.element.addClass( "ui-autocomplete-loading" );
6556                 this.source( { term: value }, this.response );
6557         },
6559         _response: function( content ) {
6560                 if ( !this.options.disabled && content && content.length ) {
6561                         content = this._normalize( content );
6562                         this._suggest( content );
6563                         this._trigger( "open" );
6564                 } else {
6565                         this.close();
6566                 }
6567                 this.pending--;
6568                 if ( !this.pending ) {
6569                         this.element.removeClass( "ui-autocomplete-loading" );
6570                 }
6571         },
6573         close: function( event ) {
6574                 clearTimeout( this.closing );
6575                 if ( this.menu.element.is(":visible") ) {
6576                         this.menu.element.hide();
6577                         this.menu.deactivate();
6578                         this._trigger( "close", event );
6579                 }
6580         },
6581         
6582         _change: function( event ) {
6583                 if ( this.previous !== this.element.val() ) {
6584                         this._trigger( "change", event, { item: this.selectedItem } );
6585                 }
6586         },
6588         _normalize: function( items ) {
6589                 // assume all items have the right format when the first item is complete
6590                 if ( items.length && items[0].label && items[0].value ) {
6591                         return items;
6592                 }
6593                 return $.map( items, function(item) {
6594                         if ( typeof item === "string" ) {
6595                                 return {
6596                                         label: item,
6597                                         value: item
6598                                 };
6599                         }
6600                         return $.extend({
6601                                 label: item.label || item.value,
6602                                 value: item.value || item.label
6603                         }, item );
6604                 });
6605         },
6607         _suggest: function( items ) {
6608                 var ul = this.menu.element
6609                         .empty()
6610                         .zIndex( this.element.zIndex() + 1 );
6611                 this._renderMenu( ul, items );
6612                 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
6613                 this.menu.deactivate();
6614                 this.menu.refresh();
6616                 // size and position menu
6617                 ul.show();
6618                 this._resizeMenu();
6619                 ul.position( $.extend({
6620                         of: this.element
6621                 }, this.options.position ));
6623                 if ( this.options.autoFocus ) {
6624                         this.menu.next( new $.Event("mouseover") );
6625                 }
6626         },
6628         _resizeMenu: function() {
6629                 var ul = this.menu.element;
6630                 ul.outerWidth( Math.max(
6631                         ul.width( "" ).outerWidth(),
6632                         this.element.outerWidth()
6633                 ) );
6634         },
6636         _renderMenu: function( ul, items ) {
6637                 var self = this;
6638                 $.each( items, function( index, item ) {
6639                         self._renderItem( ul, item );
6640                 });
6641         },
6643         _renderItem: function( ul, item) {
6644                 return $( "<li></li>" )
6645                         .data( "item.autocomplete", item )
6646                         .append( $( "<a></a>" ).text( item.label ) )
6647                         .appendTo( ul );
6648         },
6650         _move: function( direction, event ) {
6651                 if ( !this.menu.element.is(":visible") ) {
6652                         this.search( null, event );
6653                         return;
6654                 }
6655                 if ( this.menu.first() && /^previous/.test(direction) ||
6656                                 this.menu.last() && /^next/.test(direction) ) {
6657                         this.element.val( this.term );
6658                         this.menu.deactivate();
6659                         return;
6660                 }
6661                 this.menu[ direction ]( event );
6662         },
6664         widget: function() {
6665                 return this.menu.element;
6666         }
6669 $.extend( $.ui.autocomplete, {
6670         escapeRegex: function( value ) {
6671                 return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
6672         },
6673         filter: function(array, term) {
6674                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6675                 return $.grep( array, function(value) {
6676                         return matcher.test( value.label || value.value || value );
6677                 });
6678         }
6681 }( jQuery ));
6684  * jQuery UI Menu (not officially released)
6685  * 
6686  * This widget isn't yet finished and the API is subject to change. We plan to finish
6687  * it for the next release. You're welcome to give it a try anyway and give us feedback,
6688  * as long as you're okay with migrating your code later on. We can help with that, too.
6690  * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
6691  * Dual licensed under the MIT or GPL Version 2 licenses.
6692  * http://jquery.org/license
6694  * http://docs.jquery.com/UI/Menu
6696  * Depends:
6697  *      jquery.ui.core.js
6698  *  jquery.ui.widget.js
6699  */
6700 (function($) {
6702 $.widget("ui.menu", {
6703         _create: function() {
6704                 var self = this;
6705                 this.element
6706                         .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
6707                         .attr({
6708                                 role: "listbox",
6709                                 "aria-activedescendant": "ui-active-menuitem"
6710                         })
6711                         .click(function( event ) {
6712                                 if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
6713                                         return;
6714                                 }
6715                                 // temporary
6716                                 event.preventDefault();
6717                                 self.select( event );
6718                         });
6719                 this.refresh();
6720         },
6721         
6722         refresh: function() {
6723                 var self = this;
6725                 // don't refresh list items that are already adapted
6726                 var items = this.element.children("li:not(.ui-menu-item):has(a)")
6727                         .addClass("ui-menu-item")
6728                         .attr("role", "menuitem");
6729                 
6730                 items.children("a")
6731                         .addClass("ui-corner-all")
6732                         .attr("tabindex", -1)
6733                         // mouseenter doesn't work with event delegation
6734                         .mouseenter(function( event ) {
6735                                 self.activate( event, $(this).parent() );
6736                         })
6737                         .mouseleave(function() {
6738                                 self.deactivate();
6739                         });
6740         },
6742         activate: function( event, item ) {
6743                 this.deactivate();
6744                 if (this.hasScroll()) {
6745                         var offset = item.offset().top - this.element.offset().top,
6746                                 scroll = this.element.scrollTop(),
6747                                 elementHeight = this.element.height();
6748                         if (offset < 0) {
6749                                 this.element.scrollTop( scroll + offset);
6750                         } else if (offset >= elementHeight) {
6751                                 this.element.scrollTop( scroll + offset - elementHeight + item.height());
6752                         }
6753                 }
6754                 this.active = item.eq(0)
6755                         .children("a")
6756                                 .addClass("ui-state-hover")
6757                                 .attr("id", "ui-active-menuitem")
6758                         .end();
6759                 this._trigger("focus", event, { item: item });
6760         },
6762         deactivate: function() {
6763                 if (!this.active) { return; }
6765                 this.active.children("a")
6766                         .removeClass("ui-state-hover")
6767                         .removeAttr("id");
6768                 this._trigger("blur");
6769                 this.active = null;
6770         },
6772         next: function(event) {
6773                 this.move("next", ".ui-menu-item:first", event);
6774         },
6776         previous: function(event) {
6777                 this.move("prev", ".ui-menu-item:last", event);
6778         },
6780         first: function() {
6781                 return this.active && !this.active.prevAll(".ui-menu-item").length;
6782         },
6784         last: function() {
6785                 return this.active && !this.active.nextAll(".ui-menu-item").length;
6786         },
6788         move: function(direction, edge, event) {
6789                 if (!this.active) {
6790                         this.activate(event, this.element.children(edge));
6791                         return;
6792                 }
6793                 var next = this.active[direction + "All"](".ui-menu-item").eq(0);
6794                 if (next.length) {
6795                         this.activate(event, next);
6796                 } else {
6797                         this.activate(event, this.element.children(edge));
6798                 }
6799         },
6801         // TODO merge with previousPage
6802         nextPage: function(event) {
6803                 if (this.hasScroll()) {
6804                         // TODO merge with no-scroll-else
6805                         if (!this.active || this.last()) {
6806                                 this.activate(event, this.element.children(".ui-menu-item:first"));
6807                                 return;
6808                         }
6809                         var base = this.active.offset().top,
6810                                 height = this.element.height(),
6811                                 result = this.element.children(".ui-menu-item").filter(function() {
6812                                         var close = $(this).offset().top - base - height + $(this).height();
6813                                         // TODO improve approximation
6814                                         return close < 10 && close > -10;
6815                                 });
6817                         // TODO try to catch this earlier when scrollTop indicates the last page anyway
6818                         if (!result.length) {
6819                                 result = this.element.children(".ui-menu-item:last");
6820                         }
6821                         this.activate(event, result);
6822                 } else {
6823                         this.activate(event, this.element.children(".ui-menu-item")
6824                                 .filter(!this.active || this.last() ? ":first" : ":last"));
6825                 }
6826         },
6828         // TODO merge with nextPage
6829         previousPage: function(event) {
6830                 if (this.hasScroll()) {
6831                         // TODO merge with no-scroll-else
6832                         if (!this.active || this.first()) {
6833                                 this.activate(event, this.element.children(".ui-menu-item:last"));
6834                                 return;
6835                         }
6837                         var base = this.active.offset().top,
6838                                 height = this.element.height();
6839                                 result = this.element.children(".ui-menu-item").filter(function() {
6840                                         var close = $(this).offset().top - base + height - $(this).height();
6841                                         // TODO improve approximation
6842                                         return close < 10 && close > -10;
6843                                 });
6845                         // TODO try to catch this earlier when scrollTop indicates the last page anyway
6846                         if (!result.length) {
6847                                 result = this.element.children(".ui-menu-item:first");
6848                         }
6849                         this.activate(event, result);
6850                 } else {
6851                         this.activate(event, this.element.children(".ui-menu-item")
6852                                 .filter(!this.active || this.first() ? ":last" : ":first"));
6853                 }
6854         },
6856         hasScroll: function() {
6857                 return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
6858         },
6860         select: function( event ) {
6861                 this._trigger("selected", event, { item: this.active });
6862         }
6865 }(jQuery));
6867  * jQuery UI Button 1.8.16
6869  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6870  * Dual licensed under the MIT or GPL Version 2 licenses.
6871  * http://jquery.org/license
6873  * http://docs.jquery.com/UI/Button
6875  * Depends:
6876  *      jquery.ui.core.js
6877  *      jquery.ui.widget.js
6878  */
6879 (function( $, undefined ) {
6881 var lastActive, startXPos, startYPos, clickDragged,
6882         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6883         stateClasses = "ui-state-hover ui-state-active ",
6884         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",
6885         formResetHandler = function() {
6886                 var buttons = $( this ).find( ":ui-button" );
6887                 setTimeout(function() {
6888                         buttons.button( "refresh" );
6889                 }, 1 );
6890         },
6891         radioGroup = function( radio ) {
6892                 var name = radio.name,
6893                         form = radio.form,
6894                         radios = $( [] );
6895                 if ( name ) {
6896                         if ( form ) {
6897                                 radios = $( form ).find( "[name='" + name + "']" );
6898                         } else {
6899                                 radios = $( "[name='" + name + "']", radio.ownerDocument )
6900                                         .filter(function() {
6901                                                 return !this.form;
6902                                         });
6903                         }
6904                 }
6905                 return radios;
6906         };
6908 $.widget( "ui.button", {
6909         options: {
6910                 disabled: null,
6911                 text: true,
6912                 label: null,
6913                 icons: {
6914                         primary: null,
6915                         secondary: null
6916                 }
6917         },
6918         _create: function() {
6919                 this.element.closest( "form" )
6920                         .unbind( "reset.button" )
6921                         .bind( "reset.button", formResetHandler );
6923                 if ( typeof this.options.disabled !== "boolean" ) {
6924                         this.options.disabled = this.element.propAttr( "disabled" );
6925                 }
6927                 this._determineButtonType();
6928                 this.hasTitle = !!this.buttonElement.attr( "title" );
6930                 var self = this,
6931                         options = this.options,
6932                         toggleButton = this.type === "checkbox" || this.type === "radio",
6933                         hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
6934                         focusClass = "ui-state-focus";
6936                 if ( options.label === null ) {
6937                         options.label = this.buttonElement.html();
6938                 }
6940                 if ( this.element.is( ":disabled" ) ) {
6941                         options.disabled = true;
6942                 }
6944                 this.buttonElement
6945                         .addClass( baseClasses )
6946                         .attr( "role", "button" )
6947                         .bind( "mouseenter.button", function() {
6948                                 if ( options.disabled ) {
6949                                         return;
6950                                 }
6951                                 $( this ).addClass( "ui-state-hover" );
6952                                 if ( this === lastActive ) {
6953                                         $( this ).addClass( "ui-state-active" );
6954                                 }
6955                         })
6956                         .bind( "mouseleave.button", function() {
6957                                 if ( options.disabled ) {
6958                                         return;
6959                                 }
6960                                 $( this ).removeClass( hoverClass );
6961                         })
6962                         .bind( "click.button", function( event ) {
6963                                 if ( options.disabled ) {
6964                                         event.preventDefault();
6965                                         event.stopImmediatePropagation();
6966                                 }
6967                         });
6969                 this.element
6970                         .bind( "focus.button", function() {
6971                                 // no need to check disabled, focus won't be triggered anyway
6972                                 self.buttonElement.addClass( focusClass );
6973                         })
6974                         .bind( "blur.button", function() {
6975                                 self.buttonElement.removeClass( focusClass );
6976                         });
6978                 if ( toggleButton ) {
6979                         this.element.bind( "change.button", function() {
6980                                 if ( clickDragged ) {
6981                                         return;
6982                                 }
6983                                 self.refresh();
6984                         });
6985                         // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6986                         // prevents issue where button state changes but checkbox/radio checked state
6987                         // does not in Firefox (see ticket #6970)
6988                         this.buttonElement
6989                                 .bind( "mousedown.button", function( event ) {
6990                                         if ( options.disabled ) {
6991                                                 return;
6992                                         }
6993                                         clickDragged = false;
6994                                         startXPos = event.pageX;
6995                                         startYPos = event.pageY;
6996                                 })
6997                                 .bind( "mouseup.button", function( event ) {
6998                                         if ( options.disabled ) {
6999                                                 return;
7000                                         }
7001                                         if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
7002                                                 clickDragged = true;
7003                                         }
7004                         });
7005                 }
7007                 if ( this.type === "checkbox" ) {
7008                         this.buttonElement.bind( "click.button", function() {
7009                                 if ( options.disabled || clickDragged ) {
7010                                         return false;
7011                                 }
7012                                 $( this ).toggleClass( "ui-state-active" );
7013                                 self.buttonElement.attr( "aria-pressed", self.element[0].checked );
7014                         });
7015                 } else if ( this.type === "radio" ) {
7016                         this.buttonElement.bind( "click.button", function() {
7017                                 if ( options.disabled || clickDragged ) {
7018                                         return false;
7019                                 }
7020                                 $( this ).addClass( "ui-state-active" );
7021                                 self.buttonElement.attr( "aria-pressed", "true" );
7023                                 var radio = self.element[ 0 ];
7024                                 radioGroup( radio )
7025                                         .not( radio )
7026                                         .map(function() {
7027                                                 return $( this ).button( "widget" )[ 0 ];
7028                                         })
7029                                         .removeClass( "ui-state-active" )
7030                                         .attr( "aria-pressed", "false" );
7031                         });
7032                 } else {
7033                         this.buttonElement
7034                                 .bind( "mousedown.button", function() {
7035                                         if ( options.disabled ) {
7036                                                 return false;
7037                                         }
7038                                         $( this ).addClass( "ui-state-active" );
7039                                         lastActive = this;
7040                                         $( document ).one( "mouseup", function() {
7041                                                 lastActive = null;
7042                                         });
7043                                 })
7044                                 .bind( "mouseup.button", function() {
7045                                         if ( options.disabled ) {
7046                                                 return false;
7047                                         }
7048                                         $( this ).removeClass( "ui-state-active" );
7049                                 })
7050                                 .bind( "keydown.button", function(event) {
7051                                         if ( options.disabled ) {
7052                                                 return false;
7053                                         }
7054                                         if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
7055                                                 $( this ).addClass( "ui-state-active" );
7056                                         }
7057                                 })
7058                                 .bind( "keyup.button", function() {
7059                                         $( this ).removeClass( "ui-state-active" );
7060                                 });
7062                         if ( this.buttonElement.is("a") ) {
7063                                 this.buttonElement.keyup(function(event) {
7064                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
7065                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
7066                                                 $( this ).click();
7067                                         }
7068                                 });
7069                         }
7070                 }
7072                 // TODO: pull out $.Widget's handling for the disabled option into
7073                 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7074                 // be overridden by individual plugins
7075                 this._setOption( "disabled", options.disabled );
7076                 this._resetButton();
7077         },
7079         _determineButtonType: function() {
7081                 if ( this.element.is(":checkbox") ) {
7082                         this.type = "checkbox";
7083                 } else if ( this.element.is(":radio") ) {
7084                         this.type = "radio";
7085                 } else if ( this.element.is("input") ) {
7086                         this.type = "input";
7087                 } else {
7088                         this.type = "button";
7089                 }
7091                 if ( this.type === "checkbox" || this.type === "radio" ) {
7092                         // we don't search against the document in case the element
7093                         // is disconnected from the DOM
7094                         var ancestor = this.element.parents().filter(":last"),
7095                                 labelSelector = "label[for='" + this.element.attr("id") + "']";
7096                         this.buttonElement = ancestor.find( labelSelector );
7097                         if ( !this.buttonElement.length ) {
7098                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7099                                 this.buttonElement = ancestor.filter( labelSelector );
7100                                 if ( !this.buttonElement.length ) {
7101                                         this.buttonElement = ancestor.find( labelSelector );
7102                                 }
7103                         }
7104                         this.element.addClass( "ui-helper-hidden-accessible" );
7106                         var checked = this.element.is( ":checked" );
7107                         if ( checked ) {
7108                                 this.buttonElement.addClass( "ui-state-active" );
7109                         }
7110                         this.buttonElement.attr( "aria-pressed", checked );
7111                 } else {
7112                         this.buttonElement = this.element;
7113                 }
7114         },
7116         widget: function() {
7117                 return this.buttonElement;
7118         },
7120         destroy: function() {
7121                 this.element
7122                         .removeClass( "ui-helper-hidden-accessible" );
7123                 this.buttonElement
7124                         .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7125                         .removeAttr( "role" )
7126                         .removeAttr( "aria-pressed" )
7127                         .html( this.buttonElement.find(".ui-button-text").html() );
7129                 if ( !this.hasTitle ) {
7130                         this.buttonElement.removeAttr( "title" );
7131                 }
7133                 $.Widget.prototype.destroy.call( this );
7134         },
7136         _setOption: function( key, value ) {
7137                 $.Widget.prototype._setOption.apply( this, arguments );
7138                 if ( key === "disabled" ) {
7139                         if ( value ) {
7140                                 this.element.propAttr( "disabled", true );
7141                         } else {
7142                                 this.element.propAttr( "disabled", false );
7143                         }
7144                         return;
7145                 }
7146                 this._resetButton();
7147         },
7149         refresh: function() {
7150                 var isDisabled = this.element.is( ":disabled" );
7151                 if ( isDisabled !== this.options.disabled ) {
7152                         this._setOption( "disabled", isDisabled );
7153                 }
7154                 if ( this.type === "radio" ) {
7155                         radioGroup( this.element[0] ).each(function() {
7156                                 if ( $( this ).is( ":checked" ) ) {
7157                                         $( this ).button( "widget" )
7158                                                 .addClass( "ui-state-active" )
7159                                                 .attr( "aria-pressed", "true" );
7160                                 } else {
7161                                         $( this ).button( "widget" )
7162                                                 .removeClass( "ui-state-active" )
7163                                                 .attr( "aria-pressed", "false" );
7164                                 }
7165                         });
7166                 } else if ( this.type === "checkbox" ) {
7167                         if ( this.element.is( ":checked" ) ) {
7168                                 this.buttonElement
7169                                         .addClass( "ui-state-active" )
7170                                         .attr( "aria-pressed", "true" );
7171                         } else {
7172                                 this.buttonElement
7173                                         .removeClass( "ui-state-active" )
7174                                         .attr( "aria-pressed", "false" );
7175                         }
7176                 }
7177         },
7179         _resetButton: function() {
7180                 if ( this.type === "input" ) {
7181                         if ( this.options.label ) {
7182                                 this.element.val( this.options.label );
7183                         }
7184                         return;
7185                 }
7186                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
7187                         buttonText = $( "<span></span>" )
7188                                 .addClass( "ui-button-text" )
7189                                 .html( this.options.label )
7190                                 .appendTo( buttonElement.empty() )
7191                                 .text(),
7192                         icons = this.options.icons,
7193                         multipleIcons = icons.primary && icons.secondary,
7194                         buttonClasses = [];  
7196                 if ( icons.primary || icons.secondary ) {
7197                         if ( this.options.text ) {
7198                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7199                         }
7201                         if ( icons.primary ) {
7202                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7203                         }
7205                         if ( icons.secondary ) {
7206                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7207                         }
7209                         if ( !this.options.text ) {
7210                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7212                                 if ( !this.hasTitle ) {
7213                                         buttonElement.attr( "title", buttonText );
7214                                 }
7215                         }
7216                 } else {
7217                         buttonClasses.push( "ui-button-text-only" );
7218                 }
7219                 buttonElement.addClass( buttonClasses.join( " " ) );
7220         }
7223 $.widget( "ui.buttonset", {
7224         options: {
7225                 items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
7226         },
7228         _create: function() {
7229                 this.element.addClass( "ui-buttonset" );
7230         },
7231         
7232         _init: function() {
7233                 this.refresh();
7234         },
7236         _setOption: function( key, value ) {
7237                 if ( key === "disabled" ) {
7238                         this.buttons.button( "option", key, value );
7239                 }
7241                 $.Widget.prototype._setOption.apply( this, arguments );
7242         },
7243         
7244         refresh: function() {
7245                 var ltr = this.element.css( "direction" ) === "ltr";
7246                 
7247                 this.buttons = this.element.find( this.options.items )
7248                         .filter( ":ui-button" )
7249                                 .button( "refresh" )
7250                         .end()
7251                         .not( ":ui-button" )
7252                                 .button()
7253                         .end()
7254                         .map(function() {
7255                                 return $( this ).button( "widget" )[ 0 ];
7256                         })
7257                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7258                                 .filter( ":first" )
7259                                         .addClass( ltr ? "ui-corner-left" : "ui-corner-right" )
7260                                 .end()
7261                                 .filter( ":last" )
7262                                         .addClass( ltr ? "ui-corner-right" : "ui-corner-left" )
7263                                 .end()
7264                         .end();
7265         },
7267         destroy: function() {
7268                 this.element.removeClass( "ui-buttonset" );
7269                 this.buttons
7270                         .map(function() {
7271                                 return $( this ).button( "widget" )[ 0 ];
7272                         })
7273                                 .removeClass( "ui-corner-left ui-corner-right" )
7274                         .end()
7275                         .button( "destroy" );
7277                 $.Widget.prototype.destroy.call( this );
7278         }
7281 }( jQuery ) );
7283  * jQuery UI Datepicker 1.8.16
7285  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
7286  * Dual licensed under the MIT or GPL Version 2 licenses.
7287  * http://jquery.org/license
7289  * http://docs.jquery.com/UI/Datepicker
7291  * Depends:
7292  *      jquery.ui.core.js
7293  */
7294 (function( $, undefined ) {
7296 $.extend($.ui, { datepicker: { version: "1.8.16" } });
7298 var PROP_NAME = 'datepicker';
7299 var dpuuid = new Date().getTime();
7300 var instActive;
7302 /* Date picker manager.
7303    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7304    Settings for (groups of) date pickers are maintained in an instance object,
7305    allowing multiple different settings on the same page. */
7307 function Datepicker() {
7308         this.debug = false; // Change this to true to start debugging
7309         this._curInst = null; // The current instance in use
7310         this._keyEvent = false; // If the last event was a key event
7311         this._disabledInputs = []; // List of date picker inputs that have been disabled
7312         this._datepickerShowing = false; // True if the popup picker is showing , false if not
7313         this._inDialog = false; // True if showing within a "dialog", false if not
7314         this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
7315         this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
7316         this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
7317         this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
7318         this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
7319         this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
7320         this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
7321         this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
7322         this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
7323         this.regional = []; // Available regional settings, indexed by language code
7324         this.regional[''] = { // Default regional settings
7325                 closeText: 'Done', // Display text for close link
7326                 prevText: 'Prev', // Display text for previous month link
7327                 nextText: 'Next', // Display text for next month link
7328                 currentText: 'Today', // Display text for current month link
7329                 monthNames: ['January','February','March','April','May','June',
7330                         'July','August','September','October','November','December'], // Names of months for drop-down and formatting
7331                 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
7332                 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
7333                 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
7334                 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
7335                 weekHeader: 'Wk', // Column header for week of the year
7336                 dateFormat: 'mm/dd/yy', // See format options on parseDate
7337                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7338                 isRTL: false, // True if right-to-left language, false if left-to-right
7339                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7340                 yearSuffix: '' // Additional text to append to the year in the month headers
7341         };
7342         this._defaults = { // Global defaults for all the date picker instances
7343                 showOn: 'focus', // 'focus' for popup on focus,
7344                         // 'button' for trigger button, or 'both' for either
7345                 showAnim: 'fadeIn', // Name of jQuery animation for popup
7346                 showOptions: {}, // Options for enhanced animations
7347                 defaultDate: null, // Used when field is blank: actual date,
7348                         // +/-number for offset from today, null for today
7349                 appendText: '', // Display text following the input box, e.g. showing the format
7350                 buttonText: '...', // Text for trigger button
7351                 buttonImage: '', // URL for trigger button image
7352                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7353                 hideIfNoPrevNext: false, // True to hide next/previous month links
7354                         // if not applicable, false to just disable them
7355                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7356                 gotoCurrent: false, // True if today link goes back to current selection instead
7357                 changeMonth: false, // True if month can be selected directly, false if only prev/next
7358                 changeYear: false, // True if year can be selected directly, false if only prev/next
7359                 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
7360                         // either relative to today's year (-nn:+nn), relative to currently displayed year
7361                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7362                 showOtherMonths: false, // True to show dates in other months, false to leave blank
7363                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7364                 showWeek: false, // True to show week of the year, false to not show it
7365                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7366                         // takes a Date and returns the number of the week for it
7367                 shortYearCutoff: '+10', // Short year values < this are in the current century,
7368                         // > this are in the previous century,
7369                         // string value starting with '+' for current year + value
7370                 minDate: null, // The earliest selectable date, or null for no limit
7371                 maxDate: null, // The latest selectable date, or null for no limit
7372                 duration: 'fast', // Duration of display/closure
7373                 beforeShowDay: null, // Function that takes a date and returns an array with
7374                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
7375                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7376                 beforeShow: null, // Function that takes an input field and
7377                         // returns a set of custom settings for the date picker
7378                 onSelect: null, // Define a callback function when a date is selected
7379                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
7380                 onClose: null, // Define a callback function when the datepicker is closed
7381                 numberOfMonths: 1, // Number of months to show at a time
7382                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7383                 stepMonths: 1, // Number of months to step back/forward
7384                 stepBigMonths: 12, // Number of months to step back/forward for the big links
7385                 altField: '', // Selector for an alternate field to store selected dates into
7386                 altFormat: '', // The date format to use for the alternate field
7387                 constrainInput: true, // The input is constrained by the current date format
7388                 showButtonPanel: false, // True to show button panel, false to not show it
7389                 autoSize: false, // True to size the input for the date format, false to leave as is
7390                 disabled: false // The initial disabled state
7391         };
7392         $.extend(this._defaults, this.regional['']);
7393         this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
7396 $.extend(Datepicker.prototype, {
7397         /* Class name added to elements to indicate already configured with a date picker. */
7398         markerClassName: 'hasDatepicker',
7399         
7400         //Keep track of the maximum number of rows displayed (see #7043)
7401         maxRows: 4,
7403         /* Debug logging (if enabled). */
7404         log: function () {
7405                 if (this.debug)
7406                         console.log.apply('', arguments);
7407         },
7408         
7409         // TODO rename to "widget" when switching to widget factory
7410         _widgetDatepicker: function() {
7411                 return this.dpDiv;
7412         },
7414         /* Override the default settings for all instances of the date picker.
7415            @param  settings  object - the new settings to use as defaults (anonymous object)
7416            @return the manager object */
7417         setDefaults: function(settings) {
7418                 extendRemove(this._defaults, settings || {});
7419                 return this;
7420         },
7422         /* Attach the date picker to a jQuery selection.
7423            @param  target    element - the target input field or division or span
7424            @param  settings  object - the new settings to use for this date picker instance (anonymous) */
7425         _attachDatepicker: function(target, settings) {
7426                 // check for settings on the control itself - in namespace 'date:'
7427                 var inlineSettings = null;
7428                 for (var attrName in this._defaults) {
7429                         var attrValue = target.getAttribute('date:' + attrName);
7430                         if (attrValue) {
7431                                 inlineSettings = inlineSettings || {};
7432                                 try {
7433                                         inlineSettings[attrName] = eval(attrValue);
7434                                 } catch (err) {
7435                                         inlineSettings[attrName] = attrValue;
7436                                 }
7437                         }
7438                 }
7439                 var nodeName = target.nodeName.toLowerCase();
7440                 var inline = (nodeName == 'div' || nodeName == 'span');
7441                 if (!target.id) {
7442                         this.uuid += 1;
7443                         target.id = 'dp' + this.uuid;
7444                 }
7445                 var inst = this._newInst($(target), inline);
7446                 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
7447                 if (nodeName == 'input') {
7448                         this._connectDatepicker(target, inst);
7449                 } else if (inline) {
7450                         this._inlineDatepicker(target, inst);
7451                 }
7452         },
7454         /* Create a new instance object. */
7455         _newInst: function(target, inline) {
7456                 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
7457                 return {id: id, input: target, // associated target
7458                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7459                         drawMonth: 0, drawYear: 0, // month being drawn
7460                         inline: inline, // is datepicker inline or not
7461                         dpDiv: (!inline ? this.dpDiv : // presentation div
7462                         bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
7463         },
7465         /* Attach the date picker to an input field. */
7466         _connectDatepicker: function(target, inst) {
7467                 var input = $(target);
7468                 inst.append = $([]);
7469                 inst.trigger = $([]);
7470                 if (input.hasClass(this.markerClassName))
7471                         return;
7472                 this._attachments(input, inst);
7473                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
7474                         keypress(this._doKeyPress).keyup(this._doKeyUp).
7475                         bind("setData.datepicker", function(event, key, value) {
7476                                 inst.settings[key] = value;
7477                         }).bind("getData.datepicker", function(event, key) {
7478                                 return this._get(inst, key);
7479                         });
7480                 this._autoSize(inst);
7481                 $.data(target, PROP_NAME, inst);
7482                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7483                 if( inst.settings.disabled ) {
7484                         this._disableDatepicker( target );
7485                 }
7486         },
7488         /* Make attachments based on settings. */
7489         _attachments: function(input, inst) {
7490                 var appendText = this._get(inst, 'appendText');
7491                 var isRTL = this._get(inst, 'isRTL');
7492                 if (inst.append)
7493                         inst.append.remove();
7494                 if (appendText) {
7495                         inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
7496                         input[isRTL ? 'before' : 'after'](inst.append);
7497                 }
7498                 input.unbind('focus', this._showDatepicker);
7499                 if (inst.trigger)
7500                         inst.trigger.remove();
7501                 var showOn = this._get(inst, 'showOn');
7502                 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
7503                         input.focus(this._showDatepicker);
7504                 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
7505                         var buttonText = this._get(inst, 'buttonText');
7506                         var buttonImage = this._get(inst, 'buttonImage');
7507                         inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
7508                                 $('<img/>').addClass(this._triggerClass).
7509                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7510                                 $('<button type="button"></button>').addClass(this._triggerClass).
7511                                         html(buttonImage == '' ? buttonText : $('<img/>').attr(
7512                                         { src:buttonImage, alt:buttonText, title:buttonText })));
7513                         input[isRTL ? 'before' : 'after'](inst.trigger);
7514                         inst.trigger.click(function() {
7515                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
7516                                         $.datepicker._hideDatepicker();
7517                                 else
7518                                         $.datepicker._showDatepicker(input[0]);
7519                                 return false;
7520                         });
7521                 }
7522         },
7524         /* Apply the maximum length for the date format. */
7525         _autoSize: function(inst) {
7526                 if (this._get(inst, 'autoSize') && !inst.inline) {
7527                         var date = new Date(2009, 12 - 1, 20); // Ensure double digits
7528                         var dateFormat = this._get(inst, 'dateFormat');
7529                         if (dateFormat.match(/[DM]/)) {
7530                                 var findMax = function(names) {
7531                                         var max = 0;
7532                                         var maxI = 0;
7533                                         for (var i = 0; i < names.length; i++) {
7534                                                 if (names[i].length > max) {
7535                                                         max = names[i].length;
7536                                                         maxI = i;
7537                                                 }
7538                                         }
7539                                         return maxI;
7540                                 };
7541                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7542                                         'monthNames' : 'monthNamesShort'))));
7543                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7544                                         'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
7545                         }
7546                         inst.input.attr('size', this._formatDate(inst, date).length);
7547                 }
7548         },
7550         /* Attach an inline date picker to a div. */
7551         _inlineDatepicker: function(target, inst) {
7552                 var divSpan = $(target);
7553                 if (divSpan.hasClass(this.markerClassName))
7554                         return;
7555                 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
7556                         bind("setData.datepicker", function(event, key, value){
7557                                 inst.settings[key] = value;
7558                         }).bind("getData.datepicker", function(event, key){
7559                                 return this._get(inst, key);
7560                         });
7561                 $.data(target, PROP_NAME, inst);
7562                 this._setDate(inst, this._getDefaultDate(inst), true);
7563                 this._updateDatepicker(inst);
7564                 this._updateAlternate(inst);
7565                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7566                 if( inst.settings.disabled ) {
7567                         this._disableDatepicker( target );
7568                 }
7569                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7570                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7571                 inst.dpDiv.css( "display", "block" );
7572         },
7574         /* Pop-up the date picker in a "dialog" box.
7575            @param  input     element - ignored
7576            @param  date      string or Date - the initial date to display
7577            @param  onSelect  function - the function to call when a date is selected
7578            @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7579            @param  pos       int[2] - coordinates for the dialog's position within the screen or
7580                              event - with x/y coordinates or
7581                              leave empty for default (screen centre)
7582            @return the manager object */
7583         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7584                 var inst = this._dialogInst; // internal instance
7585                 if (!inst) {
7586                         this.uuid += 1;
7587                         var id = 'dp' + this.uuid;
7588                         this._dialogInput = $('<input type="text" id="' + id +
7589                                 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
7590                         this._dialogInput.keydown(this._doKeyDown);
7591                         $('body').append(this._dialogInput);
7592                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
7593                         inst.settings = {};
7594                         $.data(this._dialogInput[0], PROP_NAME, inst);
7595                 }
7596                 extendRemove(inst.settings, settings || {});
7597                 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
7598                 this._dialogInput.val(date);
7600                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7601                 if (!this._pos) {
7602                         var browserWidth = document.documentElement.clientWidth;
7603                         var browserHeight = document.documentElement.clientHeight;
7604                         var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7605                         var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7606                         this._pos = // should use actual width/height below
7607                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7608                 }
7610                 // move input on screen for focus, but hidden behind dialog
7611                 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
7612                 inst.settings.onSelect = onSelect;
7613                 this._inDialog = true;
7614                 this.dpDiv.addClass(this._dialogClass);
7615                 this._showDatepicker(this._dialogInput[0]);
7616                 if ($.blockUI)
7617                         $.blockUI(this.dpDiv);
7618                 $.data(this._dialogInput[0], PROP_NAME, inst);
7619                 return this;
7620         },
7622         /* Detach a datepicker from its control.
7623            @param  target    element - the target input field or division or span */
7624         _destroyDatepicker: function(target) {
7625                 var $target = $(target);
7626                 var inst = $.data(target, PROP_NAME);
7627                 if (!$target.hasClass(this.markerClassName)) {
7628                         return;
7629                 }
7630                 var nodeName = target.nodeName.toLowerCase();
7631                 $.removeData(target, PROP_NAME);
7632                 if (nodeName == 'input') {
7633                         inst.append.remove();
7634                         inst.trigger.remove();
7635                         $target.removeClass(this.markerClassName).
7636                                 unbind('focus', this._showDatepicker).
7637                                 unbind('keydown', this._doKeyDown).
7638                                 unbind('keypress', this._doKeyPress).
7639                                 unbind('keyup', this._doKeyUp);
7640                 } else if (nodeName == 'div' || nodeName == 'span')
7641                         $target.removeClass(this.markerClassName).empty();
7642         },
7644         /* Enable the date picker to a jQuery selection.
7645            @param  target    element - the target input field or division or span */
7646         _enableDatepicker: function(target) {
7647                 var $target = $(target);
7648                 var inst = $.data(target, PROP_NAME);
7649                 if (!$target.hasClass(this.markerClassName)) {
7650                         return;
7651                 }
7652                 var nodeName = target.nodeName.toLowerCase();
7653                 if (nodeName == 'input') {
7654                         target.disabled = false;
7655                         inst.trigger.filter('button').
7656                                 each(function() { this.disabled = false; }).end().
7657                                 filter('img').css({opacity: '1.0', cursor: ''});
7658                 }
7659                 else if (nodeName == 'div' || nodeName == 'span') {
7660                         var inline = $target.children('.' + this._inlineClass);
7661                         inline.children().removeClass('ui-state-disabled');
7662                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7663                                 removeAttr("disabled");
7664                 }
7665                 this._disabledInputs = $.map(this._disabledInputs,
7666                         function(value) { return (value == target ? null : value); }); // delete entry
7667         },
7669         /* Disable the date picker to a jQuery selection.
7670            @param  target    element - the target input field or division or span */
7671         _disableDatepicker: function(target) {
7672                 var $target = $(target);
7673                 var inst = $.data(target, PROP_NAME);
7674                 if (!$target.hasClass(this.markerClassName)) {
7675                         return;
7676                 }
7677                 var nodeName = target.nodeName.toLowerCase();
7678                 if (nodeName == 'input') {
7679                         target.disabled = true;
7680                         inst.trigger.filter('button').
7681                                 each(function() { this.disabled = true; }).end().
7682                                 filter('img').css({opacity: '0.5', cursor: 'default'});
7683                 }
7684                 else if (nodeName == 'div' || nodeName == 'span') {
7685                         var inline = $target.children('.' + this._inlineClass);
7686                         inline.children().addClass('ui-state-disabled');
7687                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7688                                 attr("disabled", "disabled");
7689                 }
7690                 this._disabledInputs = $.map(this._disabledInputs,
7691                         function(value) { return (value == target ? null : value); }); // delete entry
7692                 this._disabledInputs[this._disabledInputs.length] = target;
7693         },
7695         /* Is the first field in a jQuery collection disabled as a datepicker?
7696            @param  target    element - the target input field or division or span
7697            @return boolean - true if disabled, false if enabled */
7698         _isDisabledDatepicker: function(target) {
7699                 if (!target) {
7700                         return false;
7701                 }
7702                 for (var i = 0; i < this._disabledInputs.length; i++) {
7703                         if (this._disabledInputs[i] == target)
7704                                 return true;
7705                 }
7706                 return false;
7707         },
7709         /* Retrieve the instance data for the target control.
7710            @param  target  element - the target input field or division or span
7711            @return  object - the associated instance data
7712            @throws  error if a jQuery problem getting data */
7713         _getInst: function(target) {
7714                 try {
7715                         return $.data(target, PROP_NAME);
7716                 }
7717                 catch (err) {
7718                         throw 'Missing instance data for this datepicker';
7719                 }
7720         },
7722         /* Update or retrieve the settings for a date picker attached to an input field or division.
7723            @param  target  element - the target input field or division or span
7724            @param  name    object - the new settings to update or
7725                            string - the name of the setting to change or retrieve,
7726                            when retrieving also 'all' for all instance settings or
7727                            'defaults' for all global defaults
7728            @param  value   any - the new value for the setting
7729                            (omit if above is an object or to retrieve a value) */
7730         _optionDatepicker: function(target, name, value) {
7731                 var inst = this._getInst(target);
7732                 if (arguments.length == 2 && typeof name == 'string') {
7733                         return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
7734                                 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
7735                                 this._get(inst, name)) : null));
7736                 }
7737                 var settings = name || {};
7738                 if (typeof name == 'string') {
7739                         settings = {};
7740                         settings[name] = value;
7741                 }
7742                 if (inst) {
7743                         if (this._curInst == inst) {
7744                                 this._hideDatepicker();
7745                         }
7746                         var date = this._getDateDatepicker(target, true);
7747                         var minDate = this._getMinMaxDate(inst, 'min');
7748                         var maxDate = this._getMinMaxDate(inst, 'max');
7749                         extendRemove(inst.settings, settings);
7750                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7751                         if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
7752                                 inst.settings.minDate = this._formatDate(inst, minDate);
7753                         if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
7754                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
7755                         this._attachments($(target), inst);
7756                         this._autoSize(inst);
7757                         this._setDate(inst, date);
7758                         this._updateAlternate(inst);
7759                         this._updateDatepicker(inst);
7760                 }
7761         },
7763         // change method deprecated
7764         _changeDatepicker: function(target, name, value) {
7765                 this._optionDatepicker(target, name, value);
7766         },
7768         /* Redraw the date picker attached to an input field or division.
7769            @param  target  element - the target input field or division or span */
7770         _refreshDatepicker: function(target) {
7771                 var inst = this._getInst(target);
7772                 if (inst) {
7773                         this._updateDatepicker(inst);
7774                 }
7775         },
7777         /* Set the dates for a jQuery selection.
7778            @param  target   element - the target input field or division or span
7779            @param  date     Date - the new date */
7780         _setDateDatepicker: function(target, date) {
7781                 var inst = this._getInst(target);
7782                 if (inst) {
7783                         this._setDate(inst, date);
7784                         this._updateDatepicker(inst);
7785                         this._updateAlternate(inst);
7786                 }
7787         },
7789         /* Get the date(s) for the first entry in a jQuery selection.
7790            @param  target     element - the target input field or division or span
7791            @param  noDefault  boolean - true if no default date is to be used
7792            @return Date - the current date */
7793         _getDateDatepicker: function(target, noDefault) {
7794                 var inst = this._getInst(target);
7795                 if (inst && !inst.inline)
7796                         this._setDateFromField(inst, noDefault);
7797                 return (inst ? this._getDate(inst) : null);
7798         },
7800         /* Handle keystrokes. */
7801         _doKeyDown: function(event) {
7802                 var inst = $.datepicker._getInst(event.target);
7803                 var handled = true;
7804                 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
7805                 inst._keyEvent = true;
7806                 if ($.datepicker._datepickerShowing)
7807                         switch (event.keyCode) {
7808                                 case 9: $.datepicker._hideDatepicker();
7809                                                 handled = false;
7810                                                 break; // hide on tab out
7811                                 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 
7812                                                                         $.datepicker._currentClass + ')', inst.dpDiv);
7813                                                 if (sel[0])
7814                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7815                                                         var onSelect = $.datepicker._get(inst, 'onSelect');
7816                                                         if (onSelect) {
7817                                                                 var dateStr = $.datepicker._formatDate(inst);
7819                                                                 // trigger custom callback
7820                                                                 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7821                                                         }
7822                                                 else
7823                                                         $.datepicker._hideDatepicker();
7824                                                 return false; // don't submit the form
7825                                                 break; // select the value on enter
7826                                 case 27: $.datepicker._hideDatepicker();
7827                                                 break; // hide on escape
7828                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7829                                                         -$.datepicker._get(inst, 'stepBigMonths') :
7830                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
7831                                                 break; // previous month/year on page up/+ ctrl
7832                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7833                                                         +$.datepicker._get(inst, 'stepBigMonths') :
7834                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
7835                                                 break; // next month/year on page down/+ ctrl
7836                                 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
7837                                                 handled = event.ctrlKey || event.metaKey;
7838                                                 break; // clear on ctrl or command +end
7839                                 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7840                                                 handled = event.ctrlKey || event.metaKey;
7841                                                 break; // current on ctrl or command +home
7842                                 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7843                                                 handled = event.ctrlKey || event.metaKey;
7844                                                 // -1 day on ctrl or command +left
7845                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7846                                                                         -$.datepicker._get(inst, 'stepBigMonths') :
7847                                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
7848                                                 // next month/year on alt +left on Mac
7849                                                 break;
7850                                 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7851                                                 handled = event.ctrlKey || event.metaKey;
7852                                                 break; // -1 week on ctrl or command +up
7853                                 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7854                                                 handled = event.ctrlKey || event.metaKey;
7855                                                 // +1 day on ctrl or command +right
7856                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7857                                                                         +$.datepicker._get(inst, 'stepBigMonths') :
7858                                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
7859                                                 // next month/year on alt +right
7860                                                 break;
7861                                 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7862                                                 handled = event.ctrlKey || event.metaKey;
7863                                                 break; // +1 week on ctrl or command +down
7864                                 default: handled = false;
7865                         }
7866                 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7867                         $.datepicker._showDatepicker(this);
7868                 else {
7869                         handled = false;
7870                 }
7871                 if (handled) {
7872                         event.preventDefault();
7873                         event.stopPropagation();
7874                 }
7875         },
7877         /* Filter entered characters - based on date format. */
7878         _doKeyPress: function(event) {
7879                 var inst = $.datepicker._getInst(event.target);
7880                 if ($.datepicker._get(inst, 'constrainInput')) {
7881                         var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7882                         var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7883                         return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7884                 }
7885         },
7887         /* Synchronise manual entry and field/alternate field. */
7888         _doKeyUp: function(event) {
7889                 var inst = $.datepicker._getInst(event.target);
7890                 if (inst.input.val() != inst.lastVal) {
7891                         try {
7892                                 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7893                                         (inst.input ? inst.input.val() : null),
7894                                         $.datepicker._getFormatConfig(inst));
7895                                 if (date) { // only if valid
7896                                         $.datepicker._setDateFromField(inst);
7897                                         $.datepicker._updateAlternate(inst);
7898                                         $.datepicker._updateDatepicker(inst);
7899                                 }
7900                         }
7901                         catch (event) {
7902                                 $.datepicker.log(event);
7903                         }
7904                 }
7905                 return true;
7906         },
7908         /* Pop-up the date picker for a given input field.
7909        If false returned from beforeShow event handler do not show. 
7910            @param  input  element - the input field attached to the date picker or
7911                           event - if triggered by focus */
7912         _showDatepicker: function(input) {
7913                 input = input.target || input;
7914                 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7915                         input = $('input', input.parentNode)[0];
7916                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7917                         return;
7918                 var inst = $.datepicker._getInst(input);
7919                 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7920                         if ( $.datepicker._datepickerShowing ) {
7921                                 $.datepicker._triggerOnClose($.datepicker._curInst);
7922                         }
7923                         $.datepicker._curInst.dpDiv.stop(true, true);
7924                 }
7925                 var beforeShow = $.datepicker._get(inst, 'beforeShow');
7926                 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7927                 if(beforeShowSettings === false){
7928             //false
7929                         return;
7930                 }
7931                 extendRemove(inst.settings, beforeShowSettings);
7932                 inst.lastVal = null;
7933                 $.datepicker._lastInput = input;
7934                 $.datepicker._setDateFromField(inst);
7935                 if ($.datepicker._inDialog) // hide cursor
7936                         input.value = '';
7937                 if (!$.datepicker._pos) { // position below input
7938                         $.datepicker._pos = $.datepicker._findPos(input);
7939                         $.datepicker._pos[1] += input.offsetHeight; // add the height
7940                 }
7941                 var isFixed = false;
7942                 $(input).parents().each(function() {
7943                         isFixed |= $(this).css('position') == 'fixed';
7944                         return !isFixed;
7945                 });
7946                 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
7947                         $.datepicker._pos[0] -= document.documentElement.scrollLeft;
7948                         $.datepicker._pos[1] -= document.documentElement.scrollTop;
7949                 }
7950                 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7951                 $.datepicker._pos = null;
7952                 //to avoid flashes on Firefox
7953                 inst.dpDiv.empty();
7954                 // determine sizing offscreen
7955                 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7956                 $.datepicker._updateDatepicker(inst);
7957                 // fix width for dynamic number of date pickers
7958                 // and adjust position before showing
7959                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
7960                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7961                         'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7962                         left: offset.left + 'px', top: offset.top + 'px'});
7963                 if (!inst.inline) {
7964                         var showAnim = $.datepicker._get(inst, 'showAnim');
7965                         var duration = $.datepicker._get(inst, 'duration');
7966                         var postProcess = function() {
7967                                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7968                                 if( !! cover.length ){
7969                                         var borders = $.datepicker._getBorders(inst.dpDiv);
7970                                         cover.css({left: -borders[0], top: -borders[1],
7971                                                 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7972                                 }
7973                         };
7974                         inst.dpDiv.zIndex($(input).zIndex()+1);
7975                         $.datepicker._datepickerShowing = true;
7976                         if ($.effects && $.effects[showAnim])
7977                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7978                         else
7979                                 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7980                         if (!showAnim || !duration)
7981                                 postProcess();
7982                         if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7983                                 inst.input.focus();
7984                         $.datepicker._curInst = inst;
7985                 }
7986         },
7988         /* Generate the date picker content. */
7989         _updateDatepicker: function(inst) {
7990                 var self = this;
7991                 self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7992                 var borders = $.datepicker._getBorders(inst.dpDiv);
7993                 instActive = inst; // for delegate hover events
7994                 inst.dpDiv.empty().append(this._generateHTML(inst));
7995                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7996                 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7997                         cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7998                 }
7999                 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
8000                 var numMonths = this._getNumberOfMonths(inst);
8001                 var cols = numMonths[1];
8002                 var width = 17;
8003                 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
8004                 if (cols > 1)
8005                         inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
8006                 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
8007                         'Class']('ui-datepicker-multi');
8008                 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
8009                         'Class']('ui-datepicker-rtl');
8010                 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
8011                                 // #6694 - don't focus the input if it's already focused
8012                                 // this breaks the change event in IE
8013                                 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
8014                         inst.input.focus();
8015                 // deffered render of the years select (to avoid flashes on Firefox) 
8016                 if( inst.yearshtml ){
8017                         var origyearshtml = inst.yearshtml;
8018                         setTimeout(function(){
8019                                 //assure that inst.yearshtml didn't change.
8020                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8021                                         inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
8022                                 }
8023                                 origyearshtml = inst.yearshtml = null;
8024                         }, 0);
8025                 }
8026         },
8028         /* Retrieve the size of left and top borders for an element.
8029            @param  elem  (jQuery object) the element of interest
8030            @return  (number[2]) the left and top borders */
8031         _getBorders: function(elem) {
8032                 var convert = function(value) {
8033                         return {thin: 1, medium: 2, thick: 3}[value] || value;
8034                 };
8035                 return [parseFloat(convert(elem.css('border-left-width'))),
8036                         parseFloat(convert(elem.css('border-top-width')))];
8037         },
8039         /* Check positioning to remain on screen. */
8040         _checkOffset: function(inst, offset, isFixed) {
8041                 var dpWidth = inst.dpDiv.outerWidth();
8042                 var dpHeight = inst.dpDiv.outerHeight();
8043                 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
8044                 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
8045                 var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
8046                 var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
8048                 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
8049                 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
8050                 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8052                 // now check if datepicker is showing outside window viewport - move to a better place if so.
8053                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8054                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
8055                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8056                         Math.abs(dpHeight + inputHeight) : 0);
8058                 return offset;
8059         },
8061         /* Find an object's position on the screen. */
8062         _findPos: function(obj) {
8063                 var inst = this._getInst(obj);
8064                 var isRTL = this._get(inst, 'isRTL');
8065         while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
8066             obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
8067         }
8068         var position = $(obj).offset();
8069             return [position.left, position.top];
8070         },
8072         /* Trigger custom callback of onClose. */
8073         _triggerOnClose: function(inst) {
8074                 var onClose = this._get(inst, 'onClose');
8075                 if (onClose)
8076                         onClose.apply((inst.input ? inst.input[0] : null),
8077                                                   [(inst.input ? inst.input.val() : ''), inst]);
8078         },
8080         /* Hide the date picker from view.
8081            @param  input  element - the input field attached to the date picker */
8082         _hideDatepicker: function(input) {
8083                 var inst = this._curInst;
8084                 if (!inst || (input && inst != $.data(input, PROP_NAME)))
8085                         return;
8086                 if (this._datepickerShowing) {
8087                         var showAnim = this._get(inst, 'showAnim');
8088                         var duration = this._get(inst, 'duration');
8089                         var postProcess = function() {
8090                                 $.datepicker._tidyDialog(inst);
8091                                 this._curInst = null;
8092                         };
8093                         if ($.effects && $.effects[showAnim])
8094                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8095                         else
8096                                 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
8097                                         (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
8098                         if (!showAnim)
8099                                 postProcess();
8100                         $.datepicker._triggerOnClose(inst);
8101                         this._datepickerShowing = false;
8102                         this._lastInput = null;
8103                         if (this._inDialog) {
8104                                 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
8105                                 if ($.blockUI) {
8106                                         $.unblockUI();
8107                                         $('body').append(this.dpDiv);
8108                                 }
8109                         }
8110                         this._inDialog = false;
8111                 }
8112         },
8114         /* Tidy up after a dialog display. */
8115         _tidyDialog: function(inst) {
8116                 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
8117         },
8119         /* Close date picker if clicked elsewhere. */
8120         _checkExternalClick: function(event) {
8121                 if (!$.datepicker._curInst)
8122                         return;
8123                 var $target = $(event.target);
8124                 if ($target[0].id != $.datepicker._mainDivId &&
8125                                 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
8126                                 !$target.hasClass($.datepicker.markerClassName) &&
8127                                 !$target.hasClass($.datepicker._triggerClass) &&
8128                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
8129                         $.datepicker._hideDatepicker();
8130         },
8132         /* Adjust one of the date sub-fields. */
8133         _adjustDate: function(id, offset, period) {
8134                 var target = $(id);
8135                 var inst = this._getInst(target[0]);
8136                 if (this._isDisabledDatepicker(target[0])) {
8137                         return;
8138                 }
8139                 this._adjustInstDate(inst, offset +
8140                         (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
8141                         period);
8142                 this._updateDatepicker(inst);
8143         },
8145         /* Action for current link. */
8146         _gotoToday: function(id) {
8147                 var target = $(id);
8148                 var inst = this._getInst(target[0]);
8149                 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
8150                         inst.selectedDay = inst.currentDay;
8151                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8152                         inst.drawYear = inst.selectedYear = inst.currentYear;
8153                 }
8154                 else {
8155                         var date = new Date();
8156                         inst.selectedDay = date.getDate();
8157                         inst.drawMonth = inst.selectedMonth = date.getMonth();
8158                         inst.drawYear = inst.selectedYear = date.getFullYear();
8159                 }
8160                 this._notifyChange(inst);
8161                 this._adjustDate(target);
8162         },
8164         /* Action for selecting a new month/year. */
8165         _selectMonthYear: function(id, select, period) {
8166                 var target = $(id);
8167                 var inst = this._getInst(target[0]);
8168                 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
8169                 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
8170                         parseInt(select.options[select.selectedIndex].value,10);
8171                 this._notifyChange(inst);
8172                 this._adjustDate(target);
8173         },
8175         /* Action for selecting a day. */
8176         _selectDay: function(id, month, year, td) {
8177                 var target = $(id);
8178                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8179                         return;
8180                 }
8181                 var inst = this._getInst(target[0]);
8182                 inst.selectedDay = inst.currentDay = $('a', td).html();
8183                 inst.selectedMonth = inst.currentMonth = month;
8184                 inst.selectedYear = inst.currentYear = year;
8185                 this._selectDate(id, this._formatDate(inst,
8186                         inst.currentDay, inst.currentMonth, inst.currentYear));
8187         },
8189         /* Erase the input field and hide the date picker. */
8190         _clearDate: function(id) {
8191                 var target = $(id);
8192                 var inst = this._getInst(target[0]);
8193                 this._selectDate(target, '');
8194         },
8196         /* Update the input field with the selected date. */
8197         _selectDate: function(id, dateStr) {
8198                 var target = $(id);
8199                 var inst = this._getInst(target[0]);
8200                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8201                 if (inst.input)
8202                         inst.input.val(dateStr);
8203                 this._updateAlternate(inst);
8204                 var onSelect = this._get(inst, 'onSelect');
8205                 if (onSelect)
8206                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8207                 else if (inst.input)
8208                         inst.input.trigger('change'); // fire the change event
8209                 if (inst.inline)
8210                         this._updateDatepicker(inst);
8211                 else {
8212                         this._hideDatepicker();
8213                         this._lastInput = inst.input[0];
8214                         if (typeof(inst.input[0]) != 'object')
8215                                 inst.input.focus(); // restore focus
8216                         this._lastInput = null;
8217                 }
8218         },
8220         /* Update any alternate field to synchronise with the main field. */
8221         _updateAlternate: function(inst) {
8222                 var altField = this._get(inst, 'altField');
8223                 if (altField) { // update alternate field too
8224                         var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
8225                         var date = this._getDate(inst);
8226                         var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8227                         $(altField).each(function() { $(this).val(dateStr); });
8228                 }
8229         },
8231         /* Set as beforeShowDay function to prevent selection of weekends.
8232            @param  date  Date - the date to customise
8233            @return [boolean, string] - is this date selectable?, what is its CSS class? */
8234         noWeekends: function(date) {
8235                 var day = date.getDay();
8236                 return [(day > 0 && day < 6), ''];
8237         },
8239         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8240            @param  date  Date - the date to get the week for
8241            @return  number - the number of the week within the year that contains this date */
8242         iso8601Week: function(date) {
8243                 var checkDate = new Date(date.getTime());
8244                 // Find Thursday of this week starting on Monday
8245                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8246                 var time = checkDate.getTime();
8247                 checkDate.setMonth(0); // Compare with Jan 1
8248                 checkDate.setDate(1);
8249                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8250         },
8252         /* Parse a string value into a date object.
8253            See formatDate below for the possible formats.
8255            @param  format    string - the expected format of the date
8256            @param  value     string - the date in the above format
8257            @param  settings  Object - attributes include:
8258                              shortYearCutoff  number - the cutoff year for determining the century (optional)
8259                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
8260                              dayNames         string[7] - names of the days from Sunday (optional)
8261                              monthNamesShort  string[12] - abbreviated names of the months (optional)
8262                              monthNames       string[12] - names of the months (optional)
8263            @return  Date - the extracted date value or null if value is blank */
8264         parseDate: function (format, value, settings) {
8265                 if (format == null || value == null)
8266                         throw 'Invalid arguments';
8267                 value = (typeof value == 'object' ? value.toString() : value + '');
8268                 if (value == '')
8269                         return null;
8270                 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
8271                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8272                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8273                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8274                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8275                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8276                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8277                 var year = -1;
8278                 var month = -1;
8279                 var day = -1;
8280                 var doy = -1;
8281                 var literal = false;
8282                 // Check whether a format character is doubled
8283                 var lookAhead = function(match) {
8284                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8285                         if (matches)
8286                                 iFormat++;
8287                         return matches;
8288                 };
8289                 // Extract a number from the string value
8290                 var getNumber = function(match) {
8291                         var isDoubled = lookAhead(match);
8292                         var size = (match == '@' ? 14 : (match == '!' ? 20 :
8293                                 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
8294                         var digits = new RegExp('^\\d{1,' + size + '}');
8295                         var num = value.substring(iValue).match(digits);
8296                         if (!num)
8297                                 throw 'Missing number at position ' + iValue;
8298                         iValue += num[0].length;
8299                         return parseInt(num[0], 10);
8300                 };
8301                 // Extract a name from the string value and convert to an index
8302                 var getName = function(match, shortNames, longNames) {
8303                         var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8304                                 return [ [k, v] ];
8305                         }).sort(function (a, b) {
8306                                 return -(a[1].length - b[1].length);
8307                         });
8308                         var index = -1;
8309                         $.each(names, function (i, pair) {
8310                                 var name = pair[1];
8311                                 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
8312                                         index = pair[0];
8313                                         iValue += name.length;
8314                                         return false;
8315                                 }
8316                         });
8317                         if (index != -1)
8318                                 return index + 1;
8319                         else
8320                                 throw 'Unknown name at position ' + iValue;
8321                 };
8322                 // Confirm that a literal character matches the string value
8323                 var checkLiteral = function() {
8324                         if (value.charAt(iValue) != format.charAt(iFormat))
8325                                 throw 'Unexpected literal at position ' + iValue;
8326                         iValue++;
8327                 };
8328                 var iValue = 0;
8329                 for (var iFormat = 0; iFormat < format.length; iFormat++) {
8330                         if (literal)
8331                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8332                                         literal = false;
8333                                 else
8334                                         checkLiteral();
8335                         else
8336                                 switch (format.charAt(iFormat)) {
8337                                         case 'd':
8338                                                 day = getNumber('d');
8339                                                 break;
8340                                         case 'D':
8341                                                 getName('D', dayNamesShort, dayNames);
8342                                                 break;
8343                                         case 'o':
8344                                                 doy = getNumber('o');
8345                                                 break;
8346                                         case 'm':
8347                                                 month = getNumber('m');
8348                                                 break;
8349                                         case 'M':
8350                                                 month = getName('M', monthNamesShort, monthNames);
8351                                                 break;
8352                                         case 'y':
8353                                                 year = getNumber('y');
8354                                                 break;
8355                                         case '@':
8356                                                 var date = new Date(getNumber('@'));
8357                                                 year = date.getFullYear();
8358                                                 month = date.getMonth() + 1;
8359                                                 day = date.getDate();
8360                                                 break;
8361                                         case '!':
8362                                                 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
8363                                                 year = date.getFullYear();
8364                                                 month = date.getMonth() + 1;
8365                                                 day = date.getDate();
8366                                                 break;
8367                                         case "'":
8368                                                 if (lookAhead("'"))
8369                                                         checkLiteral();
8370                                                 else
8371                                                         literal = true;
8372                                                 break;
8373                                         default:
8374                                                 checkLiteral();
8375                                 }
8376                 }
8377                 if (iValue < value.length){
8378                         throw "Extra/unparsed characters found in date: " + value.substring(iValue);
8379                 }
8380                 if (year == -1)
8381                         year = new Date().getFullYear();
8382                 else if (year < 100)
8383                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8384                                 (year <= shortYearCutoff ? 0 : -100);
8385                 if (doy > -1) {
8386                         month = 1;
8387                         day = doy;
8388                         do {
8389                                 var dim = this._getDaysInMonth(year, month - 1);
8390                                 if (day <= dim)
8391                                         break;
8392                                 month++;
8393                                 day -= dim;
8394                         } while (true);
8395                 }
8396                 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8397                 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
8398                         throw 'Invalid date'; // E.g. 31/02/00
8399                 return date;
8400         },
8402         /* Standard date formats. */
8403         ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
8404         COOKIE: 'D, dd M yy',
8405         ISO_8601: 'yy-mm-dd',
8406         RFC_822: 'D, d M y',
8407         RFC_850: 'DD, dd-M-y',
8408         RFC_1036: 'D, d M y',
8409         RFC_1123: 'D, d M yy',
8410         RFC_2822: 'D, d M yy',
8411         RSS: 'D, d M y', // RFC 822
8412         TICKS: '!',
8413         TIMESTAMP: '@',
8414         W3C: 'yy-mm-dd', // ISO 8601
8416         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8417                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8419         /* Format a date object into a string value.
8420            The format can be combinations of the following:
8421            d  - day of month (no leading zero)
8422            dd - day of month (two digit)
8423            o  - day of year (no leading zeros)
8424            oo - day of year (three digit)
8425            D  - day name short
8426            DD - day name long
8427            m  - month of year (no leading zero)
8428            mm - month of year (two digit)
8429            M  - month name short
8430            MM - month name long
8431            y  - year (two digit)
8432            yy - year (four digit)
8433            @ - Unix timestamp (ms since 01/01/1970)
8434            ! - Windows ticks (100ns since 01/01/0001)
8435            '...' - literal text
8436            '' - single quote
8438            @param  format    string - the desired format of the date
8439            @param  date      Date - the date value to format
8440            @param  settings  Object - attributes include:
8441                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
8442                              dayNames         string[7] - names of the days from Sunday (optional)
8443                              monthNamesShort  string[12] - abbreviated names of the months (optional)
8444                              monthNames       string[12] - names of the months (optional)
8445            @return  string - the date in the above format */
8446         formatDate: function (format, date, settings) {
8447                 if (!date)
8448                         return '';
8449                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8450                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8451                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8452                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8453                 // Check whether a format character is doubled
8454                 var lookAhead = function(match) {
8455                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8456                         if (matches)
8457                                 iFormat++;
8458                         return matches;
8459                 };
8460                 // Format a number, with leading zero if necessary
8461                 var formatNumber = function(match, value, len) {
8462                         var num = '' + value;
8463                         if (lookAhead(match))
8464                                 while (num.length < len)
8465                                         num = '0' + num;
8466                         return num;
8467                 };
8468                 // Format a name, short or long as requested
8469                 var formatName = function(match, value, shortNames, longNames) {
8470                         return (lookAhead(match) ? longNames[value] : shortNames[value]);
8471                 };
8472                 var output = '';
8473                 var literal = false;
8474                 if (date)
8475                         for (var iFormat = 0; iFormat < format.length; iFormat++) {
8476                                 if (literal)
8477                                         if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8478                                                 literal = false;
8479                                         else
8480                                                 output += format.charAt(iFormat);
8481                                 else
8482                                         switch (format.charAt(iFormat)) {
8483                                                 case 'd':
8484                                                         output += formatNumber('d', date.getDate(), 2);
8485                                                         break;
8486                                                 case 'D':
8487                                                         output += formatName('D', date.getDay(), dayNamesShort, dayNames);
8488                                                         break;
8489                                                 case 'o':
8490                                                         output += formatNumber('o',
8491                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8492                                                         break;
8493                                                 case 'm':
8494                                                         output += formatNumber('m', date.getMonth() + 1, 2);
8495                                                         break;
8496                                                 case 'M':
8497                                                         output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
8498                                                         break;
8499                                                 case 'y':
8500                                                         output += (lookAhead('y') ? date.getFullYear() :
8501                                                                 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
8502                                                         break;
8503                                                 case '@':
8504                                                         output += date.getTime();
8505                                                         break;
8506                                                 case '!':
8507                                                         output += date.getTime() * 10000 + this._ticksTo1970;
8508                                                         break;
8509                                                 case "'":
8510                                                         if (lookAhead("'"))
8511                                                                 output += "'";
8512                                                         else
8513                                                                 literal = true;
8514                                                         break;
8515                                                 default:
8516                                                         output += format.charAt(iFormat);
8517                                         }
8518                         }
8519                 return output;
8520         },
8522         /* Extract all possible characters from the date format. */
8523         _possibleChars: function (format) {
8524                 var chars = '';
8525                 var literal = false;
8526                 // Check whether a format character is doubled
8527                 var lookAhead = function(match) {
8528                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8529                         if (matches)
8530                                 iFormat++;
8531                         return matches;
8532                 };
8533                 for (var iFormat = 0; iFormat < format.length; iFormat++)
8534                         if (literal)
8535                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8536                                         literal = false;
8537                                 else
8538                                         chars += format.charAt(iFormat);
8539                         else
8540                                 switch (format.charAt(iFormat)) {
8541                                         case 'd': case 'm': case 'y': case '@':
8542                                                 chars += '0123456789';
8543                                                 break;
8544                                         case 'D': case 'M':
8545                                                 return null; // Accept anything
8546                                         case "'":
8547                                                 if (lookAhead("'"))
8548                                                         chars += "'";
8549                                                 else
8550                                                         literal = true;
8551                                                 break;
8552                                         default:
8553                                                 chars += format.charAt(iFormat);
8554                                 }
8555                 return chars;
8556         },
8558         /* Get a setting value, defaulting if necessary. */
8559         _get: function(inst, name) {
8560                 return inst.settings[name] !== undefined ?
8561                         inst.settings[name] : this._defaults[name];
8562         },
8564         /* Parse existing date and initialise date picker. */
8565         _setDateFromField: function(inst, noDefault) {
8566                 if (inst.input.val() == inst.lastVal) {
8567                         return;
8568                 }
8569                 var dateFormat = this._get(inst, 'dateFormat');
8570                 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
8571                 var date, defaultDate;
8572                 date = defaultDate = this._getDefaultDate(inst);
8573                 var settings = this._getFormatConfig(inst);
8574                 try {
8575                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8576                 } catch (event) {
8577                         this.log(event);
8578                         dates = (noDefault ? '' : dates);
8579                 }
8580                 inst.selectedDay = date.getDate();
8581                 inst.drawMonth = inst.selectedMonth = date.getMonth();
8582                 inst.drawYear = inst.selectedYear = date.getFullYear();
8583                 inst.currentDay = (dates ? date.getDate() : 0);
8584                 inst.currentMonth = (dates ? date.getMonth() : 0);
8585                 inst.currentYear = (dates ? date.getFullYear() : 0);
8586                 this._adjustInstDate(inst);
8587         },
8589         /* Retrieve the default date shown on opening. */
8590         _getDefaultDate: function(inst) {
8591                 return this._restrictMinMax(inst,
8592                         this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
8593         },
8595         /* A date may be specified as an exact value or a relative one. */
8596         _determineDate: function(inst, date, defaultDate) {
8597                 var offsetNumeric = function(offset) {
8598                         var date = new Date();
8599                         date.setDate(date.getDate() + offset);
8600                         return date;
8601                 };
8602                 var offsetString = function(offset) {
8603                         try {
8604                                 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8605                                         offset, $.datepicker._getFormatConfig(inst));
8606                         }
8607                         catch (e) {
8608                                 // Ignore
8609                         }
8610                         var date = (offset.toLowerCase().match(/^c/) ?
8611                                 $.datepicker._getDate(inst) : null) || new Date();
8612                         var year = date.getFullYear();
8613                         var month = date.getMonth();
8614                         var day = date.getDate();
8615                         var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
8616                         var matches = pattern.exec(offset);
8617                         while (matches) {
8618                                 switch (matches[2] || 'd') {
8619                                         case 'd' : case 'D' :
8620                                                 day += parseInt(matches[1],10); break;
8621                                         case 'w' : case 'W' :
8622                                                 day += parseInt(matches[1],10) * 7; break;
8623                                         case 'm' : case 'M' :
8624                                                 month += parseInt(matches[1],10);
8625                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8626                                                 break;
8627                                         case 'y': case 'Y' :
8628                                                 year += parseInt(matches[1],10);
8629                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8630                                                 break;
8631                                 }
8632                                 matches = pattern.exec(offset);
8633                         }
8634                         return new Date(year, month, day);
8635                 };
8636                 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
8637                         (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8638                 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
8639                 if (newDate) {
8640                         newDate.setHours(0);
8641                         newDate.setMinutes(0);
8642                         newDate.setSeconds(0);
8643                         newDate.setMilliseconds(0);
8644                 }
8645                 return this._daylightSavingAdjust(newDate);
8646         },
8648         /* Handle switch to/from daylight saving.
8649            Hours may be non-zero on daylight saving cut-over:
8650            > 12 when midnight changeover, but then cannot generate
8651            midnight datetime, so jump to 1AM, otherwise reset.
8652            @param  date  (Date) the date to check
8653            @return  (Date) the corrected date */
8654         _daylightSavingAdjust: function(date) {
8655                 if (!date) return null;
8656                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8657                 return date;
8658         },
8660         /* Set the date(s) directly. */
8661         _setDate: function(inst, date, noChange) {
8662                 var clear = !date;
8663                 var origMonth = inst.selectedMonth;
8664                 var origYear = inst.selectedYear;
8665                 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8666                 inst.selectedDay = inst.currentDay = newDate.getDate();
8667                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8668                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8669                 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
8670                         this._notifyChange(inst);
8671                 this._adjustInstDate(inst);
8672                 if (inst.input) {
8673                         inst.input.val(clear ? '' : this._formatDate(inst));
8674                 }
8675         },
8677         /* Retrieve the date(s) directly. */
8678         _getDate: function(inst) {
8679                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
8680                         this._daylightSavingAdjust(new Date(
8681                         inst.currentYear, inst.currentMonth, inst.currentDay)));
8682                         return startDate;
8683         },
8685         /* Generate the HTML for the current state of the date picker. */
8686         _generateHTML: function(inst) {
8687                 var today = new Date();
8688                 today = this._daylightSavingAdjust(
8689                         new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
8690                 var isRTL = this._get(inst, 'isRTL');
8691                 var showButtonPanel = this._get(inst, 'showButtonPanel');
8692                 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
8693                 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
8694                 var numMonths = this._getNumberOfMonths(inst);
8695                 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
8696                 var stepMonths = this._get(inst, 'stepMonths');
8697                 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
8698                 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8699                         new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8700                 var minDate = this._getMinMaxDate(inst, 'min');
8701                 var maxDate = this._getMinMaxDate(inst, 'max');
8702                 var drawMonth = inst.drawMonth - showCurrentAtPos;
8703                 var drawYear = inst.drawYear;
8704                 if (drawMonth < 0) {
8705                         drawMonth += 12;
8706                         drawYear--;
8707                 }
8708                 if (maxDate) {
8709                         var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8710                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8711                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8712                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8713                                 drawMonth--;
8714                                 if (drawMonth < 0) {
8715                                         drawMonth = 11;
8716                                         drawYear--;
8717                                 }
8718                         }
8719                 }
8720                 inst.drawMonth = drawMonth;
8721                 inst.drawYear = drawYear;
8722                 var prevText = this._get(inst, 'prevText');
8723                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8724                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8725                         this._getFormatConfig(inst)));
8726                 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8727                         '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8728                         '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
8729                         ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
8730                         (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>'));
8731                 var nextText = this._get(inst, 'nextText');
8732                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8733                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8734                         this._getFormatConfig(inst)));
8735                 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8736                         '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8737                         '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
8738                         ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
8739                         (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>'));
8740                 var currentText = this._get(inst, 'currentText');
8741                 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
8742                 currentText = (!navigationAsDateFormat ? currentText :
8743                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8744                 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8745                         '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
8746                 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
8747                         (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8748                         '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
8749                         '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
8750                 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
8751                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
8752                 var showWeek = this._get(inst, 'showWeek');
8753                 var dayNames = this._get(inst, 'dayNames');
8754                 var dayNamesShort = this._get(inst, 'dayNamesShort');
8755                 var dayNamesMin = this._get(inst, 'dayNamesMin');
8756                 var monthNames = this._get(inst, 'monthNames');
8757                 var monthNamesShort = this._get(inst, 'monthNamesShort');
8758                 var beforeShowDay = this._get(inst, 'beforeShowDay');
8759                 var showOtherMonths = this._get(inst, 'showOtherMonths');
8760                 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
8761                 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
8762                 var defaultDate = this._getDefaultDate(inst);
8763                 var html = '';
8764                 for (var row = 0; row < numMonths[0]; row++) {
8765                         var group = '';
8766                         this.maxRows = 4;
8767                         for (var col = 0; col < numMonths[1]; col++) {
8768                                 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8769                                 var cornerClass = ' ui-corner-all';
8770                                 var calender = '';
8771                                 if (isMultiMonth) {
8772                                         calender += '<div class="ui-datepicker-group';
8773                                         if (numMonths[1] > 1)
8774                                                 switch (col) {
8775                                                         case 0: calender += ' ui-datepicker-group-first';
8776                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
8777                                                         case numMonths[1]-1: calender += ' ui-datepicker-group-last';
8778                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
8779                                                         default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
8780                                                 }
8781                                         calender += '">';
8782                                 }
8783                                 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
8784                                         (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
8785                                         (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
8786                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8787                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8788                                         '</div><table class="ui-datepicker-calendar"><thead>' +
8789                                         '<tr>';
8790                                 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
8791                                 for (var dow = 0; dow < 7; dow++) { // days of the week
8792                                         var day = (dow + firstDay) % 7;
8793                                         thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
8794                                                 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
8795                                 }
8796                                 calender += thead + '</tr></thead><tbody>';
8797                                 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8798                                 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
8799                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8800                                 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8801                                 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8802                                 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8803                                 this.maxRows = numRows;
8804                                 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8805                                 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8806                                         calender += '<tr>';
8807                                         var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8808                                                 this._get(inst, 'calculateWeek')(printDate) + '</td>');
8809                                         for (var dow = 0; dow < 7; dow++) { // create date picker days
8810                                                 var daySettings = (beforeShowDay ?
8811                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8812                                                 var otherMonth = (printDate.getMonth() != drawMonth);
8813                                                 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8814                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8815                                                 tbody += '<td class="' +
8816                                                         ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8817                                                         (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8818                                                         ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8819                                                         (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8820                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
8821                                                         ' ' + this._dayOverClass : '') + // highlight selected day
8822                                                         (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
8823                                                         (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8824                                                         (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8825                                                         (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8826                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8827                                                         (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
8828                                                         inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
8829                                                         (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
8830                                                         (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8831                                                         (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8832                                                         (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8833                                                         (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8834                                                         '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8835                                                 printDate.setDate(printDate.getDate() + 1);
8836                                                 printDate = this._daylightSavingAdjust(printDate);
8837                                         }
8838                                         calender += tbody + '</tr>';
8839                                 }
8840                                 drawMonth++;
8841                                 if (drawMonth > 11) {
8842                                         drawMonth = 0;
8843                                         drawYear++;
8844                                 }
8845                                 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 
8846                                                         ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8847                                 group += calender;
8848                         }
8849                         html += group;
8850                 }
8851                 html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
8852                         '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8853                 inst._keyEvent = false;
8854                 return html;
8855         },
8857         /* Generate the month and year header. */
8858         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8859                         secondary, monthNames, monthNamesShort) {
8860                 var changeMonth = this._get(inst, 'changeMonth');
8861                 var changeYear = this._get(inst, 'changeYear');
8862                 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8863                 var html = '<div class="ui-datepicker-title">';
8864                 var monthHtml = '';
8865                 // month selection
8866                 if (secondary || !changeMonth)
8867                         monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8868                 else {
8869                         var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8870                         var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8871                         monthHtml += '<select class="ui-datepicker-month" ' +
8872                                 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
8873                                 '>';
8874                         for (var month = 0; month < 12; month++) {
8875                                 if ((!inMinYear || month >= minDate.getMonth()) &&
8876                                                 (!inMaxYear || month <= maxDate.getMonth()))
8877                                         monthHtml += '<option value="' + month + '"' +
8878                                                 (month == drawMonth ? ' selected="selected"' : '') +
8879                                                 '>' + monthNamesShort[month] + '</option>';
8880                         }
8881                         monthHtml += '</select>';
8882                 }
8883                 if (!showMonthAfterYear)
8884                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
8885                 // year selection
8886                 if ( !inst.yearshtml ) {
8887                         inst.yearshtml = '';
8888                         if (secondary || !changeYear)
8889                                 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
8890                         else {
8891                                 // determine range of years to display
8892                                 var years = this._get(inst, 'yearRange').split(':');
8893                                 var thisYear = new Date().getFullYear();
8894                                 var determineYear = function(value) {
8895                                         var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8896                                                 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8897                                                 parseInt(value, 10)));
8898                                         return (isNaN(year) ? thisYear : year);
8899                                 };
8900                                 var year = determineYear(years[0]);
8901                                 var endYear = Math.max(year, determineYear(years[1] || ''));
8902                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8903                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8904                                 inst.yearshtml += '<select class="ui-datepicker-year" ' +
8905                                         'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
8906                                         '>';
8907                                 for (; year <= endYear; year++) {
8908                                         inst.yearshtml += '<option value="' + year + '"' +
8909                                                 (year == drawYear ? ' selected="selected"' : '') +
8910                                                 '>' + year + '</option>';
8911                                 }
8912                                 inst.yearshtml += '</select>';
8913                                 
8914                                 html += inst.yearshtml;
8915                                 inst.yearshtml = null;
8916                         }
8917                 }
8918                 html += this._get(inst, 'yearSuffix');
8919                 if (showMonthAfterYear)
8920                         html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
8921                 html += '</div>'; // Close datepicker_header
8922                 return html;
8923         },
8925         /* Adjust one of the date sub-fields. */
8926         _adjustInstDate: function(inst, offset, period) {
8927                 var year = inst.drawYear + (period == 'Y' ? offset : 0);
8928                 var month = inst.drawMonth + (period == 'M' ? offset : 0);
8929                 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8930                         (period == 'D' ? offset : 0);
8931                 var date = this._restrictMinMax(inst,
8932                         this._daylightSavingAdjust(new Date(year, month, day)));
8933                 inst.selectedDay = date.getDate();
8934                 inst.drawMonth = inst.selectedMonth = date.getMonth();
8935                 inst.drawYear = inst.selectedYear = date.getFullYear();
8936                 if (period == 'M' || period == 'Y')
8937                         this._notifyChange(inst);
8938         },
8940         /* Ensure a date is within any min/max bounds. */
8941         _restrictMinMax: function(inst, date) {
8942                 var minDate = this._getMinMaxDate(inst, 'min');
8943                 var maxDate = this._getMinMaxDate(inst, 'max');
8944                 var newDate = (minDate && date < minDate ? minDate : date);
8945                 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8946                 return newDate;
8947         },
8949         /* Notify change of month/year. */
8950         _notifyChange: function(inst) {
8951                 var onChange = this._get(inst, 'onChangeMonthYear');
8952                 if (onChange)
8953                         onChange.apply((inst.input ? inst.input[0] : null),
8954                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
8955         },
8957         /* Determine the number of months to show. */
8958         _getNumberOfMonths: function(inst) {
8959                 var numMonths = this._get(inst, 'numberOfMonths');
8960                 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8961         },
8963         /* Determine the current maximum date - ensure no time components are set. */
8964         _getMinMaxDate: function(inst, minMax) {
8965                 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8966         },
8968         /* Find the number of days in a given month. */
8969         _getDaysInMonth: function(year, month) {
8970                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8971         },
8973         /* Find the day of the week of the first of a month. */
8974         _getFirstDayOfMonth: function(year, month) {
8975                 return new Date(year, month, 1).getDay();
8976         },
8978         /* Determines if we should allow a "next/prev" month display change. */
8979         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
8980                 var numMonths = this._getNumberOfMonths(inst);
8981                 var date = this._daylightSavingAdjust(new Date(curYear,
8982                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8983                 if (offset < 0)
8984                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8985                 return this._isInRange(inst, date);
8986         },
8988         /* Is the given date in the accepted range? */
8989         _isInRange: function(inst, date) {
8990                 var minDate = this._getMinMaxDate(inst, 'min');
8991                 var maxDate = this._getMinMaxDate(inst, 'max');
8992                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
8993                         (!maxDate || date.getTime() <= maxDate.getTime()));
8994         },
8996         /* Provide the configuration settings for formatting/parsing. */
8997         _getFormatConfig: function(inst) {
8998                 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8999                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9000                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9001                 return {shortYearCutoff: shortYearCutoff,
9002                         dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
9003                         monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
9004         },
9006         /* Format the given date for display. */
9007         _formatDate: function(inst, day, month, year) {
9008                 if (!day) {
9009                         inst.currentDay = inst.selectedDay;
9010                         inst.currentMonth = inst.selectedMonth;
9011                         inst.currentYear = inst.selectedYear;
9012                 }
9013                 var date = (day ? (typeof day == 'object' ? day :
9014                         this._daylightSavingAdjust(new Date(year, month, day))) :
9015                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9016                 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
9017         }
9021  * Bind hover events for datepicker elements.
9022  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9023  * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9024  */ 
9025 function bindHover(dpDiv) {
9026         var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
9027         return dpDiv.bind('mouseout', function(event) {
9028                         var elem = $( event.target ).closest( selector );
9029                         if ( !elem.length ) {
9030                                 return;
9031                         }
9032                         elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
9033                 })
9034                 .bind('mouseover', function(event) {
9035                         var elem = $( event.target ).closest( selector );
9036                         if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
9037                                         !elem.length ) {
9038                                 return;
9039                         }
9040                         elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
9041                         elem.addClass('ui-state-hover');
9042                         if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
9043                         if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
9044                 });
9047 /* jQuery extend now ignores nulls! */
9048 function extendRemove(target, props) {
9049         $.extend(target, props);
9050         for (var name in props)
9051                 if (props[name] == null || props[name] == undefined)
9052                         target[name] = props[name];
9053         return target;
9056 /* Determine whether an object is an array. */
9057 function isArray(a) {
9058         return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
9059                 (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
9062 /* Invoke the datepicker functionality.
9063    @param  options  string - a command, optionally followed by additional parameters or
9064                     Object - settings for attaching new datepicker functionality
9065    @return  jQuery object */
9066 $.fn.datepicker = function(options){
9067         
9068         /* Verify an empty collection wasn't passed - Fixes #6976 */
9069         if ( !this.length ) {
9070                 return this;
9071         }
9072         
9073         /* Initialise the date picker. */
9074         if (!$.datepicker.initialized) {
9075                 $(document).mousedown($.datepicker._checkExternalClick).
9076                         find('body').append($.datepicker.dpDiv);
9077                 $.datepicker.initialized = true;
9078         }
9080         var otherArgs = Array.prototype.slice.call(arguments, 1);
9081         if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
9082                 return $.datepicker['_' + options + 'Datepicker'].
9083                         apply($.datepicker, [this[0]].concat(otherArgs));
9084         if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
9085                 return $.datepicker['_' + options + 'Datepicker'].
9086                         apply($.datepicker, [this[0]].concat(otherArgs));
9087         return this.each(function() {
9088                 typeof options == 'string' ?
9089                         $.datepicker['_' + options + 'Datepicker'].
9090                                 apply($.datepicker, [this].concat(otherArgs)) :
9091                         $.datepicker._attachDatepicker(this, options);
9092         });
9095 $.datepicker = new Datepicker(); // singleton instance
9096 $.datepicker.initialized = false;
9097 $.datepicker.uuid = new Date().getTime();
9098 $.datepicker.version = "1.8.16";
9100 // Workaround for #4055
9101 // Add another global to avoid noConflict issues with inline event handlers
9102 window['DP_jQuery_' + dpuuid] = $;
9104 })(jQuery);
9106  * jQuery UI Dialog 1.8.16
9108  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
9109  * Dual licensed under the MIT or GPL Version 2 licenses.
9110  * http://jquery.org/license
9112  * http://docs.jquery.com/UI/Dialog
9114  * Depends:
9115  *      jquery.ui.core.js
9116  *      jquery.ui.widget.js
9117  *  jquery.ui.button.js
9118  *      jquery.ui.draggable.js
9119  *      jquery.ui.mouse.js
9120  *      jquery.ui.position.js
9121  *      jquery.ui.resizable.js
9122  */
9123 (function( $, undefined ) {
9125 var uiDialogClasses =
9126                 'ui-dialog ' +
9127                 'ui-widget ' +
9128                 'ui-widget-content ' +
9129                 'ui-corner-all ',
9130         sizeRelatedOptions = {
9131                 buttons: true,
9132                 height: true,
9133                 maxHeight: true,
9134                 maxWidth: true,
9135                 minHeight: true,
9136                 minWidth: true,
9137                 width: true
9138         },
9139         resizableRelatedOptions = {
9140                 maxHeight: true,
9141                 maxWidth: true,
9142                 minHeight: true,
9143                 minWidth: true
9144         },
9145         // support for jQuery 1.3.2 - handle common attrFn methods for dialog
9146         attrFn = $.attrFn || {
9147                 val: true,
9148                 css: true,
9149                 html: true,
9150                 text: true,
9151                 data: true,
9152                 width: true,
9153                 height: true,
9154                 offset: true,
9155                 click: true
9156         };
9158 $.widget("ui.dialog", {
9159         options: {
9160                 autoOpen: true,
9161                 buttons: {},
9162                 closeOnEscape: true,
9163                 closeText: 'close',
9164                 dialogClass: '',
9165                 draggable: true,
9166                 hide: null,
9167                 height: 'auto',
9168                 maxHeight: false,
9169                 maxWidth: false,
9170                 minHeight: 150,
9171                 minWidth: 150,
9172                 modal: false,
9173                 position: {
9174                         my: 'center',
9175                         at: 'center',
9176                         collision: 'fit',
9177                         // ensure that the titlebar is never outside the document
9178                         using: function(pos) {
9179                                 var topOffset = $(this).css(pos).offset().top;
9180                                 if (topOffset < 0) {
9181                                         $(this).css('top', pos.top - topOffset);
9182                                 }
9183                         }
9184                 },
9185                 resizable: true,
9186                 show: null,
9187                 stack: true,
9188                 title: '',
9189                 width: 300,
9190                 zIndex: 1000
9191         },
9193         _create: function() {
9194                 this.originalTitle = this.element.attr('title');
9195                 // #5742 - .attr() might return a DOMElement
9196                 if ( typeof this.originalTitle !== "string" ) {
9197                         this.originalTitle = "";
9198                 }
9200                 this.options.title = this.options.title || this.originalTitle;
9201                 var self = this,
9202                         options = self.options,
9204                         title = options.title || '&#160;',
9205                         titleId = $.ui.dialog.getTitleId(self.element),
9207                         uiDialog = (self.uiDialog = $('<div></div>'))
9208                                 .appendTo(document.body)
9209                                 .hide()
9210                                 .addClass(uiDialogClasses + options.dialogClass)
9211                                 .css({
9212                                         zIndex: options.zIndex
9213                                 })
9214                                 // setting tabIndex makes the div focusable
9215                                 // setting outline to 0 prevents a border on focus in Mozilla
9216                                 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
9217                                         if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9218                                                 event.keyCode === $.ui.keyCode.ESCAPE) {
9219                                                 
9220                                                 self.close(event);
9221                                                 event.preventDefault();
9222                                         }
9223                                 })
9224                                 .attr({
9225                                         role: 'dialog',
9226                                         'aria-labelledby': titleId
9227                                 })
9228                                 .mousedown(function(event) {
9229                                         self.moveToTop(false, event);
9230                                 }),
9232                         uiDialogContent = self.element
9233                                 .show()
9234                                 .removeAttr('title')
9235                                 .addClass(
9236                                         'ui-dialog-content ' +
9237                                         'ui-widget-content')
9238                                 .appendTo(uiDialog),
9240                         uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
9241                                 .addClass(
9242                                         'ui-dialog-titlebar ' +
9243                                         'ui-widget-header ' +
9244                                         'ui-corner-all ' +
9245                                         'ui-helper-clearfix'
9246                                 )
9247                                 .prependTo(uiDialog),
9249                         uiDialogTitlebarClose = $('<a href="#"></a>')
9250                                 .addClass(
9251                                         'ui-dialog-titlebar-close ' +
9252                                         'ui-corner-all'
9253                                 )
9254                                 .attr('role', 'button')
9255                                 .hover(
9256                                         function() {
9257                                                 uiDialogTitlebarClose.addClass('ui-state-hover');
9258                                         },
9259                                         function() {
9260                                                 uiDialogTitlebarClose.removeClass('ui-state-hover');
9261                                         }
9262                                 )
9263                                 .focus(function() {
9264                                         uiDialogTitlebarClose.addClass('ui-state-focus');
9265                                 })
9266                                 .blur(function() {
9267                                         uiDialogTitlebarClose.removeClass('ui-state-focus');
9268                                 })
9269                                 .click(function(event) {
9270                                         self.close(event);
9271                                         return false;
9272                                 })
9273                                 .appendTo(uiDialogTitlebar),
9275                         uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
9276                                 .addClass(
9277                                         'ui-icon ' +
9278                                         'ui-icon-closethick'
9279                                 )
9280                                 .text(options.closeText)
9281                                 .appendTo(uiDialogTitlebarClose),
9283                         uiDialogTitle = $('<span></span>')
9284                                 .addClass('ui-dialog-title')
9285                                 .attr('id', titleId)
9286                                 .html(title)
9287                                 .prependTo(uiDialogTitlebar);
9289                 //handling of deprecated beforeclose (vs beforeClose) option
9290                 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
9291                 //TODO: remove in 1.9pre
9292                 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
9293                         options.beforeClose = options.beforeclose;
9294                 }
9296                 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
9298                 if (options.draggable && $.fn.draggable) {
9299                         self._makeDraggable();
9300                 }
9301                 if (options.resizable && $.fn.resizable) {
9302                         self._makeResizable();
9303                 }
9305                 self._createButtons(options.buttons);
9306                 self._isOpen = false;
9308                 if ($.fn.bgiframe) {
9309                         uiDialog.bgiframe();
9310                 }
9311         },
9313         _init: function() {
9314                 if ( this.options.autoOpen ) {
9315                         this.open();
9316                 }
9317         },
9319         destroy: function() {
9320                 var self = this;
9321                 
9322                 if (self.overlay) {
9323                         self.overlay.destroy();
9324                 }
9325                 self.uiDialog.hide();
9326                 self.element
9327                         .unbind('.dialog')
9328                         .removeData('dialog')
9329                         .removeClass('ui-dialog-content ui-widget-content')
9330                         .hide().appendTo('body');
9331                 self.uiDialog.remove();
9333                 if (self.originalTitle) {
9334                         self.element.attr('title', self.originalTitle);
9335                 }
9337                 return self;
9338         },
9340         widget: function() {
9341                 return this.uiDialog;
9342         },
9344         close: function(event) {
9345                 var self = this,
9346                         maxZ, thisZ;
9347                 
9348                 if (false === self._trigger('beforeClose', event)) {
9349                         return;
9350                 }
9352                 if (self.overlay) {
9353                         self.overlay.destroy();
9354                 }
9355                 self.uiDialog.unbind('keypress.ui-dialog');
9357                 self._isOpen = false;
9359                 if (self.options.hide) {
9360                         self.uiDialog.hide(self.options.hide, function() {
9361                                 self._trigger('close', event);
9362                         });
9363                 } else {
9364                         self.uiDialog.hide();
9365                         self._trigger('close', event);
9366                 }
9368                 $.ui.dialog.overlay.resize();
9370                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9371                 if (self.options.modal) {
9372                         maxZ = 0;
9373                         $('.ui-dialog').each(function() {
9374                                 if (this !== self.uiDialog[0]) {
9375                                         thisZ = $(this).css('z-index');
9376                                         if(!isNaN(thisZ)) {
9377                                                 maxZ = Math.max(maxZ, thisZ);
9378                                         }
9379                                 }
9380                         });
9381                         $.ui.dialog.maxZ = maxZ;
9382                 }
9384                 return self;
9385         },
9387         isOpen: function() {
9388                 return this._isOpen;
9389         },
9391         // the force parameter allows us to move modal dialogs to their correct
9392         // position on open
9393         moveToTop: function(force, event) {
9394                 var self = this,
9395                         options = self.options,
9396                         saveScroll;
9398                 if ((options.modal && !force) ||
9399                         (!options.stack && !options.modal)) {
9400                         return self._trigger('focus', event);
9401                 }
9403                 if (options.zIndex > $.ui.dialog.maxZ) {
9404                         $.ui.dialog.maxZ = options.zIndex;
9405                 }
9406                 if (self.overlay) {
9407                         $.ui.dialog.maxZ += 1;
9408                         self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
9409                 }
9411                 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
9412                 //  http://ui.jquery.com/bugs/ticket/3193
9413                 saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
9414                 $.ui.dialog.maxZ += 1;
9415                 self.uiDialog.css('z-index', $.ui.dialog.maxZ);
9416                 self.element.attr(saveScroll);
9417                 self._trigger('focus', event);
9419                 return self;
9420         },
9422         open: function() {
9423                 if (this._isOpen) { return; }
9425                 var self = this,
9426                         options = self.options,
9427                         uiDialog = self.uiDialog;
9429                 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
9430                 self._size();
9431                 self._position(options.position);
9432                 uiDialog.show(options.show);
9433                 self.moveToTop(true);
9435                 // prevent tabbing out of modal dialogs
9436                 if (options.modal) {
9437                         uiDialog.bind('keypress.ui-dialog', function(event) {
9438                                 if (event.keyCode !== $.ui.keyCode.TAB) {
9439                                         return;
9440                                 }
9442                                 var tabbables = $(':tabbable', this),
9443                                         first = tabbables.filter(':first'),
9444                                         last  = tabbables.filter(':last');
9446                                 if (event.target === last[0] && !event.shiftKey) {
9447                                         first.focus(1);
9448                                         return false;
9449                                 } else if (event.target === first[0] && event.shiftKey) {
9450                                         last.focus(1);
9451                                         return false;
9452                                 }
9453                         });
9454                 }
9456                 // set focus to the first tabbable element in the content area or the first button
9457                 // if there are no tabbable elements, set focus on the dialog itself
9458                 $(self.element.find(':tabbable').get().concat(
9459                         uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
9460                                 uiDialog.get()))).eq(0).focus();
9462                 self._isOpen = true;
9463                 self._trigger('open');
9465                 return self;
9466         },
9468         _createButtons: function(buttons) {
9469                 var self = this,
9470                         hasButtons = false,
9471                         uiDialogButtonPane = $('<div></div>')
9472                                 .addClass(
9473                                         'ui-dialog-buttonpane ' +
9474                                         'ui-widget-content ' +
9475                                         'ui-helper-clearfix'
9476                                 ),
9477                         uiButtonSet = $( "<div></div>" )
9478                                 .addClass( "ui-dialog-buttonset" )
9479                                 .appendTo( uiDialogButtonPane );
9481                 // if we already have a button pane, remove it
9482                 self.uiDialog.find('.ui-dialog-buttonpane').remove();
9484                 if (typeof buttons === 'object' && buttons !== null) {
9485                         $.each(buttons, function() {
9486                                 return !(hasButtons = true);
9487                         });
9488                 }
9489                 if (hasButtons) {
9490                         $.each(buttons, function(name, props) {
9491                                 props = $.isFunction( props ) ?
9492                                         { click: props, text: name } :
9493                                         props;
9494                                 var button = $('<button type="button"></button>')
9495                                         .click(function() {
9496                                                 props.click.apply(self.element[0], arguments);
9497                                         })
9498                                         .appendTo(uiButtonSet);
9499                                 // can't use .attr( props, true ) with jQuery 1.3.2.
9500                                 $.each( props, function( key, value ) {
9501                                         if ( key === "click" ) {
9502                                                 return;
9503                                         }
9504                                         if ( key in attrFn ) {
9505                                                 button[ key ]( value );
9506                                         } else {
9507                                                 button.attr( key, value );
9508                                         }
9509                                 });
9510                                 if ($.fn.button) {
9511                                         button.button();
9512                                 }
9513                         });
9514                         uiDialogButtonPane.appendTo(self.uiDialog);
9515                 }
9516         },
9518         _makeDraggable: function() {
9519                 var self = this,
9520                         options = self.options,
9521                         doc = $(document),
9522                         heightBeforeDrag;
9524                 function filteredUi(ui) {
9525                         return {
9526                                 position: ui.position,
9527                                 offset: ui.offset
9528                         };
9529                 }
9531                 self.uiDialog.draggable({
9532                         cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
9533                         handle: '.ui-dialog-titlebar',
9534                         containment: 'document',
9535                         start: function(event, ui) {
9536                                 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
9537                                 $(this).height($(this).height()).addClass("ui-dialog-dragging");
9538                                 self._trigger('dragStart', event, filteredUi(ui));
9539                         },
9540                         drag: function(event, ui) {
9541                                 self._trigger('drag', event, filteredUi(ui));
9542                         },
9543                         stop: function(event, ui) {
9544                                 options.position = [ui.position.left - doc.scrollLeft(),
9545                                         ui.position.top - doc.scrollTop()];
9546                                 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
9547                                 self._trigger('dragStop', event, filteredUi(ui));
9548                                 $.ui.dialog.overlay.resize();
9549                         }
9550                 });
9551         },
9553         _makeResizable: function(handles) {
9554                 handles = (handles === undefined ? this.options.resizable : handles);
9555                 var self = this,
9556                         options = self.options,
9557                         // .ui-resizable has position: relative defined in the stylesheet
9558                         // but dialogs have to use absolute or fixed positioning
9559                         position = self.uiDialog.css('position'),
9560                         resizeHandles = (typeof handles === 'string' ?
9561                                 handles :
9562                                 'n,e,s,w,se,sw,ne,nw'
9563                         );
9565                 function filteredUi(ui) {
9566                         return {
9567                                 originalPosition: ui.originalPosition,
9568                                 originalSize: ui.originalSize,
9569                                 position: ui.position,
9570                                 size: ui.size
9571                         };
9572                 }
9574                 self.uiDialog.resizable({
9575                         cancel: '.ui-dialog-content',
9576                         containment: 'document',
9577                         alsoResize: self.element,
9578                         maxWidth: options.maxWidth,
9579                         maxHeight: options.maxHeight,
9580                         minWidth: options.minWidth,
9581                         minHeight: self._minHeight(),
9582                         handles: resizeHandles,
9583                         start: function(event, ui) {
9584                                 $(this).addClass("ui-dialog-resizing");
9585                                 self._trigger('resizeStart', event, filteredUi(ui));
9586                         },
9587                         resize: function(event, ui) {
9588                                 self._trigger('resize', event, filteredUi(ui));
9589                         },
9590                         stop: function(event, ui) {
9591                                 $(this).removeClass("ui-dialog-resizing");
9592                                 options.height = $(this).height();
9593                                 options.width = $(this).width();
9594                                 self._trigger('resizeStop', event, filteredUi(ui));
9595                                 $.ui.dialog.overlay.resize();
9596                         }
9597                 })
9598                 .css('position', position)
9599                 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
9600         },
9602         _minHeight: function() {
9603                 var options = this.options;
9605                 if (options.height === 'auto') {
9606                         return options.minHeight;
9607                 } else {
9608                         return Math.min(options.minHeight, options.height);
9609                 }
9610         },
9612         _position: function(position) {
9613                 var myAt = [],
9614                         offset = [0, 0],
9615                         isVisible;
9617                 if (position) {
9618                         // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
9619         //              if (typeof position == 'string' || $.isArray(position)) {
9620         //                      myAt = $.isArray(position) ? position : position.split(' ');
9622                         if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
9623                                 myAt = position.split ? position.split(' ') : [position[0], position[1]];
9624                                 if (myAt.length === 1) {
9625                                         myAt[1] = myAt[0];
9626                                 }
9628                                 $.each(['left', 'top'], function(i, offsetPosition) {
9629                                         if (+myAt[i] === myAt[i]) {
9630                                                 offset[i] = myAt[i];
9631                                                 myAt[i] = offsetPosition;
9632                                         }
9633                                 });
9635                                 position = {
9636                                         my: myAt.join(" "),
9637                                         at: myAt.join(" "),
9638                                         offset: offset.join(" ")
9639                                 };
9640                         } 
9642                         position = $.extend({}, $.ui.dialog.prototype.options.position, position);
9643                 } else {
9644                         position = $.ui.dialog.prototype.options.position;
9645                 }
9647                 // need to show the dialog to get the actual offset in the position plugin
9648                 isVisible = this.uiDialog.is(':visible');
9649                 if (!isVisible) {
9650                         this.uiDialog.show();
9651                 }
9652                 this.uiDialog
9653                         // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
9654                         .css({ top: 0, left: 0 })
9655                         .position($.extend({ of: window }, position));
9656                 if (!isVisible) {
9657                         this.uiDialog.hide();
9658                 }
9659         },
9661         _setOptions: function( options ) {
9662                 var self = this,
9663                         resizableOptions = {},
9664                         resize = false;
9666                 $.each( options, function( key, value ) {
9667                         self._setOption( key, value );
9668                         
9669                         if ( key in sizeRelatedOptions ) {
9670                                 resize = true;
9671                         }
9672                         if ( key in resizableRelatedOptions ) {
9673                                 resizableOptions[ key ] = value;
9674                         }
9675                 });
9677                 if ( resize ) {
9678                         this._size();
9679                 }
9680                 if ( this.uiDialog.is( ":data(resizable)" ) ) {
9681                         this.uiDialog.resizable( "option", resizableOptions );
9682                 }
9683         },
9685         _setOption: function(key, value){
9686                 var self = this,
9687                         uiDialog = self.uiDialog;
9689                 switch (key) {
9690                         //handling of deprecated beforeclose (vs beforeClose) option
9691                         //Ticket #4669 http://dev.jqueryui.com/ticket/4669
9692                         //TODO: remove in 1.9pre
9693                         case "beforeclose":
9694                                 key = "beforeClose";
9695                                 break;
9696                         case "buttons":
9697                                 self._createButtons(value);
9698                                 break;
9699                         case "closeText":
9700                                 // ensure that we always pass a string
9701                                 self.uiDialogTitlebarCloseText.text("" + value);
9702                                 break;
9703                         case "dialogClass":
9704                                 uiDialog
9705                                         .removeClass(self.options.dialogClass)
9706                                         .addClass(uiDialogClasses + value);
9707                                 break;
9708                         case "disabled":
9709                                 if (value) {
9710                                         uiDialog.addClass('ui-dialog-disabled');
9711                                 } else {
9712                                         uiDialog.removeClass('ui-dialog-disabled');
9713                                 }
9714                                 break;
9715                         case "draggable":
9716                                 var isDraggable = uiDialog.is( ":data(draggable)" );
9717                                 if ( isDraggable && !value ) {
9718                                         uiDialog.draggable( "destroy" );
9719                                 }
9720                                 
9721                                 if ( !isDraggable && value ) {
9722                                         self._makeDraggable();
9723                                 }
9724                                 break;
9725                         case "position":
9726                                 self._position(value);
9727                                 break;
9728                         case "resizable":
9729                                 // currently resizable, becoming non-resizable
9730                                 var isResizable = uiDialog.is( ":data(resizable)" );
9731                                 if (isResizable && !value) {
9732                                         uiDialog.resizable('destroy');
9733                                 }
9735                                 // currently resizable, changing handles
9736                                 if (isResizable && typeof value === 'string') {
9737                                         uiDialog.resizable('option', 'handles', value);
9738                                 }
9740                                 // currently non-resizable, becoming resizable
9741                                 if (!isResizable && value !== false) {
9742                                         self._makeResizable(value);
9743                                 }
9744                                 break;
9745                         case "title":
9746                                 // convert whatever was passed in o a string, for html() to not throw up
9747                                 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
9748                                 break;
9749                 }
9751                 $.Widget.prototype._setOption.apply(self, arguments);
9752         },
9754         _size: function() {
9755                 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9756                  * divs will both have width and height set, so we need to reset them
9757                  */
9758                 var options = this.options,
9759                         nonContentHeight,
9760                         minContentHeight,
9761                         isVisible = this.uiDialog.is( ":visible" );
9763                 // reset content sizing
9764                 this.element.show().css({
9765                         width: 'auto',
9766                         minHeight: 0,
9767                         height: 0
9768                 });
9770                 if (options.minWidth > options.width) {
9771                         options.width = options.minWidth;
9772                 }
9774                 // reset wrapper sizing
9775                 // determine the height of all the non-content elements
9776                 nonContentHeight = this.uiDialog.css({
9777                                 height: 'auto',
9778                                 width: options.width
9779                         })
9780                         .height();
9781                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9782                 
9783                 if ( options.height === "auto" ) {
9784                         // only needed for IE6 support
9785                         if ( $.support.minHeight ) {
9786                                 this.element.css({
9787                                         minHeight: minContentHeight,
9788                                         height: "auto"
9789                                 });
9790                         } else {
9791                                 this.uiDialog.show();
9792                                 var autoHeight = this.element.css( "height", "auto" ).height();
9793                                 if ( !isVisible ) {
9794                                         this.uiDialog.hide();
9795                                 }
9796                                 this.element.height( Math.max( autoHeight, minContentHeight ) );
9797                         }
9798                 } else {
9799                         this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
9800                 }
9802                 if (this.uiDialog.is(':data(resizable)')) {
9803                         this.uiDialog.resizable('option', 'minHeight', this._minHeight());
9804                 }
9805         }
9808 $.extend($.ui.dialog, {
9809         version: "1.8.16",
9811         uuid: 0,
9812         maxZ: 0,
9814         getTitleId: function($el) {
9815                 var id = $el.attr('id');
9816                 if (!id) {
9817                         this.uuid += 1;
9818                         id = this.uuid;
9819                 }
9820                 return 'ui-dialog-title-' + id;
9821         },
9823         overlay: function(dialog) {
9824                 this.$el = $.ui.dialog.overlay.create(dialog);
9825         }
9828 $.extend($.ui.dialog.overlay, {
9829         instances: [],
9830         // reuse old instances due to IE memory leak with alpha transparency (see #5185)
9831         oldInstances: [],
9832         maxZ: 0,
9833         events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
9834                 function(event) { return event + '.dialog-overlay'; }).join(' '),
9835         create: function(dialog) {
9836                 if (this.instances.length === 0) {
9837                         // prevent use of anchors and inputs
9838                         // we use a setTimeout in case the overlay is created from an
9839                         // event that we're going to be cancelling (see #2804)
9840                         setTimeout(function() {
9841                                 // handle $(el).dialog().dialog('close') (see #4065)
9842                                 if ($.ui.dialog.overlay.instances.length) {
9843                                         $(document).bind($.ui.dialog.overlay.events, function(event) {
9844                                                 // stop events if the z-index of the target is < the z-index of the overlay
9845                                                 // we cannot return true when we don't want to cancel the event (#3523)
9846                                                 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
9847                                                         return false;
9848                                                 }
9849                                         });
9850                                 }
9851                         }, 1);
9853                         // allow closing by pressing the escape key
9854                         $(document).bind('keydown.dialog-overlay', function(event) {
9855                                 if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9856                                         event.keyCode === $.ui.keyCode.ESCAPE) {
9857                                         
9858                                         dialog.close(event);
9859                                         event.preventDefault();
9860                                 }
9861                         });
9863                         // handle window resize
9864                         $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
9865                 }
9867                 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
9868                         .appendTo(document.body)
9869                         .css({
9870                                 width: this.width(),
9871                                 height: this.height()
9872                         });
9874                 if ($.fn.bgiframe) {
9875                         $el.bgiframe();
9876                 }
9878                 this.instances.push($el);
9879                 return $el;
9880         },
9882         destroy: function($el) {
9883                 var indexOf = $.inArray($el, this.instances);
9884                 if (indexOf != -1){
9885                         this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
9886                 }
9888                 if (this.instances.length === 0) {
9889                         $([document, window]).unbind('.dialog-overlay');
9890                 }
9892                 $el.remove();
9893                 
9894                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9895                 var maxZ = 0;
9896                 $.each(this.instances, function() {
9897                         maxZ = Math.max(maxZ, this.css('z-index'));
9898                 });
9899                 this.maxZ = maxZ;
9900         },
9902         height: function() {
9903                 var scrollHeight,
9904                         offsetHeight;
9905                 // handle IE 6
9906                 if ($.browser.msie && $.browser.version < 7) {
9907                         scrollHeight = Math.max(
9908                                 document.documentElement.scrollHeight,
9909                                 document.body.scrollHeight
9910                         );
9911                         offsetHeight = Math.max(
9912                                 document.documentElement.offsetHeight,
9913                                 document.body.offsetHeight
9914                         );
9916                         if (scrollHeight < offsetHeight) {
9917                                 return $(window).height() + 'px';
9918                         } else {
9919                                 return scrollHeight + 'px';
9920                         }
9921                 // handle "good" browsers
9922                 } else {
9923                         return $(document).height() + 'px';
9924                 }
9925         },
9927         width: function() {
9928                 var scrollWidth,
9929                         offsetWidth;
9930                 // handle IE
9931                 if ( $.browser.msie ) {
9932                         scrollWidth = Math.max(
9933                                 document.documentElement.scrollWidth,
9934                                 document.body.scrollWidth
9935                         );
9936                         offsetWidth = Math.max(
9937                                 document.documentElement.offsetWidth,
9938                                 document.body.offsetWidth
9939                         );
9941                         if (scrollWidth < offsetWidth) {
9942                                 return $(window).width() + 'px';
9943                         } else {
9944                                 return scrollWidth + 'px';
9945                         }
9946                 // handle "good" browsers
9947                 } else {
9948                         return $(document).width() + 'px';
9949                 }
9950         },
9952         resize: function() {
9953                 /* If the dialog is draggable and the user drags it past the
9954                  * right edge of the window, the document becomes wider so we
9955                  * need to stretch the overlay. If the user then drags the
9956                  * dialog back to the left, the document will become narrower,
9957                  * so we need to shrink the overlay to the appropriate size.
9958                  * This is handled by shrinking the overlay before setting it
9959                  * to the full document size.
9960                  */
9961                 var $overlays = $([]);
9962                 $.each($.ui.dialog.overlay.instances, function() {
9963                         $overlays = $overlays.add(this);
9964                 });
9966                 $overlays.css({
9967                         width: 0,
9968                         height: 0
9969                 }).css({
9970                         width: $.ui.dialog.overlay.width(),
9971                         height: $.ui.dialog.overlay.height()
9972                 });
9973         }
9976 $.extend($.ui.dialog.overlay.prototype, {
9977         destroy: function() {
9978                 $.ui.dialog.overlay.destroy(this.$el);
9979         }
9982 }(jQuery));
9984  * jQuery UI Position 1.8.16
9986  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
9987  * Dual licensed under the MIT or GPL Version 2 licenses.
9988  * http://jquery.org/license
9990  * http://docs.jquery.com/UI/Position
9991  */
9992 (function( $, undefined ) {
9994 $.ui = $.ui || {};
9996 var horizontalPositions = /left|center|right/,
9997         verticalPositions = /top|center|bottom/,
9998         center = "center",
9999         _position = $.fn.position,
10000         _offset = $.fn.offset;
10002 $.fn.position = function( options ) {
10003         if ( !options || !options.of ) {
10004                 return _position.apply( this, arguments );
10005         }
10007         // make a copy, we don't want to modify arguments
10008         options = $.extend( {}, options );
10010         var target = $( options.of ),
10011                 targetElem = target[0],
10012                 collision = ( options.collision || "flip" ).split( " " ),
10013                 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
10014                 targetWidth,
10015                 targetHeight,
10016                 basePosition;
10018         if ( targetElem.nodeType === 9 ) {
10019                 targetWidth = target.width();
10020                 targetHeight = target.height();
10021                 basePosition = { top: 0, left: 0 };
10022         // TODO: use $.isWindow() in 1.9
10023         } else if ( targetElem.setTimeout ) {
10024                 targetWidth = target.width();
10025                 targetHeight = target.height();
10026                 basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
10027         } else if ( targetElem.preventDefault ) {
10028                 // force left top to allow flipping
10029                 options.at = "left top";
10030                 targetWidth = targetHeight = 0;
10031                 basePosition = { top: options.of.pageY, left: options.of.pageX };
10032         } else {
10033                 targetWidth = target.outerWidth();
10034                 targetHeight = target.outerHeight();
10035                 basePosition = target.offset();
10036         }
10038         // force my and at to have valid horizontal and veritcal positions
10039         // if a value is missing or invalid, it will be converted to center 
10040         $.each( [ "my", "at" ], function() {
10041                 var pos = ( options[this] || "" ).split( " " );
10042                 if ( pos.length === 1) {
10043                         pos = horizontalPositions.test( pos[0] ) ?
10044                                 pos.concat( [center] ) :
10045                                 verticalPositions.test( pos[0] ) ?
10046                                         [ center ].concat( pos ) :
10047                                         [ center, center ];
10048                 }
10049                 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
10050                 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
10051                 options[ this ] = pos;
10052         });
10054         // normalize collision option
10055         if ( collision.length === 1 ) {
10056                 collision[ 1 ] = collision[ 0 ];
10057         }
10059         // normalize offset option
10060         offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
10061         if ( offset.length === 1 ) {
10062                 offset[ 1 ] = offset[ 0 ];
10063         }
10064         offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
10066         if ( options.at[0] === "right" ) {
10067                 basePosition.left += targetWidth;
10068         } else if ( options.at[0] === center ) {
10069                 basePosition.left += targetWidth / 2;
10070         }
10072         if ( options.at[1] === "bottom" ) {
10073                 basePosition.top += targetHeight;
10074         } else if ( options.at[1] === center ) {
10075                 basePosition.top += targetHeight / 2;
10076         }
10078         basePosition.left += offset[ 0 ];
10079         basePosition.top += offset[ 1 ];
10081         return this.each(function() {
10082                 var elem = $( this ),
10083                         elemWidth = elem.outerWidth(),
10084                         elemHeight = elem.outerHeight(),
10085                         marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
10086                         marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
10087                         collisionWidth = elemWidth + marginLeft +
10088                                 ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
10089                         collisionHeight = elemHeight + marginTop +
10090                                 ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
10091                         position = $.extend( {}, basePosition ),
10092                         collisionPosition;
10094                 if ( options.my[0] === "right" ) {
10095                         position.left -= elemWidth;
10096                 } else if ( options.my[0] === center ) {
10097                         position.left -= elemWidth / 2;
10098                 }
10100                 if ( options.my[1] === "bottom" ) {
10101                         position.top -= elemHeight;
10102                 } else if ( options.my[1] === center ) {
10103                         position.top -= elemHeight / 2;
10104                 }
10106                 // prevent fractions (see #5280)
10107                 position.left = Math.round( position.left );
10108                 position.top = Math.round( position.top );
10110                 collisionPosition = {
10111                         left: position.left - marginLeft,
10112                         top: position.top - marginTop
10113                 };
10115                 $.each( [ "left", "top" ], function( i, dir ) {
10116                         if ( $.ui.position[ collision[i] ] ) {
10117                                 $.ui.position[ collision[i] ][ dir ]( position, {
10118                                         targetWidth: targetWidth,
10119                                         targetHeight: targetHeight,
10120                                         elemWidth: elemWidth,
10121                                         elemHeight: elemHeight,
10122                                         collisionPosition: collisionPosition,
10123                                         collisionWidth: collisionWidth,
10124                                         collisionHeight: collisionHeight,
10125                                         offset: offset,
10126                                         my: options.my,
10127                                         at: options.at
10128                                 });
10129                         }
10130                 });
10132                 if ( $.fn.bgiframe ) {
10133                         elem.bgiframe();
10134                 }
10135                 elem.offset( $.extend( position, { using: options.using } ) );
10136         });
10139 $.ui.position = {
10140         fit: {
10141                 left: function( position, data ) {
10142                         var win = $( window ),
10143                                 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
10144                         position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
10145                 },
10146                 top: function( position, data ) {
10147                         var win = $( window ),
10148                                 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
10149                         position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
10150                 }
10151         },
10153         flip: {
10154                 left: function( position, data ) {
10155                         if ( data.at[0] === center ) {
10156                                 return;
10157                         }
10158                         var win = $( window ),
10159                                 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
10160                                 myOffset = data.my[ 0 ] === "left" ?
10161                                         -data.elemWidth :
10162                                         data.my[ 0 ] === "right" ?
10163                                                 data.elemWidth :
10164                                                 0,
10165                                 atOffset = data.at[ 0 ] === "left" ?
10166                                         data.targetWidth :
10167                                         -data.targetWidth,
10168                                 offset = -2 * data.offset[ 0 ];
10169                         position.left += data.collisionPosition.left < 0 ?
10170                                 myOffset + atOffset + offset :
10171                                 over > 0 ?
10172                                         myOffset + atOffset + offset :
10173                                         0;
10174                 },
10175                 top: function( position, data ) {
10176                         if ( data.at[1] === center ) {
10177                                 return;
10178                         }
10179                         var win = $( window ),
10180                                 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
10181                                 myOffset = data.my[ 1 ] === "top" ?
10182                                         -data.elemHeight :
10183                                         data.my[ 1 ] === "bottom" ?
10184                                                 data.elemHeight :
10185                                                 0,
10186                                 atOffset = data.at[ 1 ] === "top" ?
10187                                         data.targetHeight :
10188                                         -data.targetHeight,
10189                                 offset = -2 * data.offset[ 1 ];
10190                         position.top += data.collisionPosition.top < 0 ?
10191                                 myOffset + atOffset + offset :
10192                                 over > 0 ?
10193                                         myOffset + atOffset + offset :
10194                                         0;
10195                 }
10196         }
10199 // offset setter from jQuery 1.4
10200 if ( !$.offset.setOffset ) {
10201         $.offset.setOffset = function( elem, options ) {
10202                 // set position first, in-case top/left are set even on static elem
10203                 if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
10204                         elem.style.position = "relative";
10205                 }
10206                 var curElem   = $( elem ),
10207                         curOffset = curElem.offset(),
10208                         curTop    = parseInt( $.curCSS( elem, "top",  true ), 10 ) || 0,
10209                         curLeft   = parseInt( $.curCSS( elem, "left", true ), 10)  || 0,
10210                         props     = {
10211                                 top:  (options.top  - curOffset.top)  + curTop,
10212                                 left: (options.left - curOffset.left) + curLeft
10213                         };
10214                 
10215                 if ( 'using' in options ) {
10216                         options.using.call( elem, props );
10217                 } else {
10218                         curElem.css( props );
10219                 }
10220         };
10222         $.fn.offset = function( options ) {
10223                 var elem = this[ 0 ];
10224                 if ( !elem || !elem.ownerDocument ) { return null; }
10225                 if ( options ) { 
10226                         return this.each(function() {
10227                                 $.offset.setOffset( this, options );
10228                         });
10229                 }
10230                 return _offset.call( this );
10231         };
10234 }( jQuery ));
10236  * jQuery UI Progressbar 1.8.16
10238  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10239  * Dual licensed under the MIT or GPL Version 2 licenses.
10240  * http://jquery.org/license
10242  * http://docs.jquery.com/UI/Progressbar
10244  * Depends:
10245  *   jquery.ui.core.js
10246  *   jquery.ui.widget.js
10247  */
10248 (function( $, undefined ) {
10250 $.widget( "ui.progressbar", {
10251         options: {
10252                 value: 0,
10253                 max: 100
10254         },
10256         min: 0,
10258         _create: function() {
10259                 this.element
10260                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10261                         .attr({
10262                                 role: "progressbar",
10263                                 "aria-valuemin": this.min,
10264                                 "aria-valuemax": this.options.max,
10265                                 "aria-valuenow": this._value()
10266                         });
10268                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10269                         .appendTo( this.element );
10271                 this.oldValue = this._value();
10272                 this._refreshValue();
10273         },
10275         destroy: function() {
10276                 this.element
10277                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10278                         .removeAttr( "role" )
10279                         .removeAttr( "aria-valuemin" )
10280                         .removeAttr( "aria-valuemax" )
10281                         .removeAttr( "aria-valuenow" );
10283                 this.valueDiv.remove();
10285                 $.Widget.prototype.destroy.apply( this, arguments );
10286         },
10288         value: function( newValue ) {
10289                 if ( newValue === undefined ) {
10290                         return this._value();
10291                 }
10293                 this._setOption( "value", newValue );
10294                 return this;
10295         },
10297         _setOption: function( key, value ) {
10298                 if ( key === "value" ) {
10299                         this.options.value = value;
10300                         this._refreshValue();
10301                         if ( this._value() === this.options.max ) {
10302                                 this._trigger( "complete" );
10303                         }
10304                 }
10306                 $.Widget.prototype._setOption.apply( this, arguments );
10307         },
10309         _value: function() {
10310                 var val = this.options.value;
10311                 // normalize invalid value
10312                 if ( typeof val !== "number" ) {
10313                         val = 0;
10314                 }
10315                 return Math.min( this.options.max, Math.max( this.min, val ) );
10316         },
10318         _percentage: function() {
10319                 return 100 * this._value() / this.options.max;
10320         },
10322         _refreshValue: function() {
10323                 var value = this.value();
10324                 var percentage = this._percentage();
10326                 if ( this.oldValue !== value ) {
10327                         this.oldValue = value;
10328                         this._trigger( "change" );
10329                 }
10331                 this.valueDiv
10332                         .toggle( value > this.min )
10333                         .toggleClass( "ui-corner-right", value === this.options.max )
10334                         .width( percentage.toFixed(0) + "%" );
10335                 this.element.attr( "aria-valuenow", value );
10336         }
10339 $.extend( $.ui.progressbar, {
10340         version: "1.8.16"
10343 })( jQuery );
10345  * jQuery UI Slider 1.8.16
10347  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10348  * Dual licensed under the MIT or GPL Version 2 licenses.
10349  * http://jquery.org/license
10351  * http://docs.jquery.com/UI/Slider
10353  * Depends:
10354  *      jquery.ui.core.js
10355  *      jquery.ui.mouse.js
10356  *      jquery.ui.widget.js
10357  */
10358 (function( $, undefined ) {
10360 // number of pages in a slider
10361 // (how many times can you page up/down to go through the whole range)
10362 var numPages = 5;
10364 $.widget( "ui.slider", $.ui.mouse, {
10366         widgetEventPrefix: "slide",
10368         options: {
10369                 animate: false,
10370                 distance: 0,
10371                 max: 100,
10372                 min: 0,
10373                 orientation: "horizontal",
10374                 range: false,
10375                 step: 1,
10376                 value: 0,
10377                 values: null
10378         },
10380         _create: function() {
10381                 var self = this,
10382                         o = this.options,
10383                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
10384                         handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
10385                         handleCount = ( o.values && o.values.length ) || 1,
10386                         handles = [];
10388                 this._keySliding = false;
10389                 this._mouseSliding = false;
10390                 this._animateOff = true;
10391                 this._handleIndex = null;
10392                 this._detectOrientation();
10393                 this._mouseInit();
10395                 this.element
10396                         .addClass( "ui-slider" +
10397                                 " ui-slider-" + this.orientation +
10398                                 " ui-widget" +
10399                                 " ui-widget-content" +
10400                                 " ui-corner-all" +
10401                                 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
10403                 this.range = $([]);
10405                 if ( o.range ) {
10406                         if ( o.range === true ) {
10407                                 if ( !o.values ) {
10408                                         o.values = [ this._valueMin(), this._valueMin() ];
10409                                 }
10410                                 if ( o.values.length && o.values.length !== 2 ) {
10411                                         o.values = [ o.values[0], o.values[0] ];
10412                                 }
10413                         }
10415                         this.range = $( "<div></div>" )
10416                                 .appendTo( this.element )
10417                                 .addClass( "ui-slider-range" +
10418                                 // note: this isn't the most fittingly semantic framework class for this element,
10419                                 // but worked best visually with a variety of themes
10420                                 " ui-widget-header" + 
10421                                 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
10422                 }
10424                 for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
10425                         handles.push( handle );
10426                 }
10428                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
10430                 this.handle = this.handles.eq( 0 );
10432                 this.handles.add( this.range ).filter( "a" )
10433                         .click(function( event ) {
10434                                 event.preventDefault();
10435                         })
10436                         .hover(function() {
10437                                 if ( !o.disabled ) {
10438                                         $( this ).addClass( "ui-state-hover" );
10439                                 }
10440                         }, function() {
10441                                 $( this ).removeClass( "ui-state-hover" );
10442                         })
10443                         .focus(function() {
10444                                 if ( !o.disabled ) {
10445                                         $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
10446                                         $( this ).addClass( "ui-state-focus" );
10447                                 } else {
10448                                         $( this ).blur();
10449                                 }
10450                         })
10451                         .blur(function() {
10452                                 $( this ).removeClass( "ui-state-focus" );
10453                         });
10455                 this.handles.each(function( i ) {
10456                         $( this ).data( "index.ui-slider-handle", i );
10457                 });
10459                 this.handles
10460                         .keydown(function( event ) {
10461                                 var ret = true,
10462                                         index = $( this ).data( "index.ui-slider-handle" ),
10463                                         allowed,
10464                                         curVal,
10465                                         newVal,
10466                                         step;
10467         
10468                                 if ( self.options.disabled ) {
10469                                         return;
10470                                 }
10471         
10472                                 switch ( event.keyCode ) {
10473                                         case $.ui.keyCode.HOME:
10474                                         case $.ui.keyCode.END:
10475                                         case $.ui.keyCode.PAGE_UP:
10476                                         case $.ui.keyCode.PAGE_DOWN:
10477                                         case $.ui.keyCode.UP:
10478                                         case $.ui.keyCode.RIGHT:
10479                                         case $.ui.keyCode.DOWN:
10480                                         case $.ui.keyCode.LEFT:
10481                                                 ret = false;
10482                                                 if ( !self._keySliding ) {
10483                                                         self._keySliding = true;
10484                                                         $( this ).addClass( "ui-state-active" );
10485                                                         allowed = self._start( event, index );
10486                                                         if ( allowed === false ) {
10487                                                                 return;
10488                                                         }
10489                                                 }
10490                                                 break;
10491                                 }
10492         
10493                                 step = self.options.step;
10494                                 if ( self.options.values && self.options.values.length ) {
10495                                         curVal = newVal = self.values( index );
10496                                 } else {
10497                                         curVal = newVal = self.value();
10498                                 }
10499         
10500                                 switch ( event.keyCode ) {
10501                                         case $.ui.keyCode.HOME:
10502                                                 newVal = self._valueMin();
10503                                                 break;
10504                                         case $.ui.keyCode.END:
10505                                                 newVal = self._valueMax();
10506                                                 break;
10507                                         case $.ui.keyCode.PAGE_UP:
10508                                                 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
10509                                                 break;
10510                                         case $.ui.keyCode.PAGE_DOWN:
10511                                                 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
10512                                                 break;
10513                                         case $.ui.keyCode.UP:
10514                                         case $.ui.keyCode.RIGHT:
10515                                                 if ( curVal === self._valueMax() ) {
10516                                                         return;
10517                                                 }
10518                                                 newVal = self._trimAlignValue( curVal + step );
10519                                                 break;
10520                                         case $.ui.keyCode.DOWN:
10521                                         case $.ui.keyCode.LEFT:
10522                                                 if ( curVal === self._valueMin() ) {
10523                                                         return;
10524                                                 }
10525                                                 newVal = self._trimAlignValue( curVal - step );
10526                                                 break;
10527                                 }
10528         
10529                                 self._slide( event, index, newVal );
10530         
10531                                 return ret;
10532         
10533                         })
10534                         .keyup(function( event ) {
10535                                 var index = $( this ).data( "index.ui-slider-handle" );
10536         
10537                                 if ( self._keySliding ) {
10538                                         self._keySliding = false;
10539                                         self._stop( event, index );
10540                                         self._change( event, index );
10541                                         $( this ).removeClass( "ui-state-active" );
10542                                 }
10543         
10544                         });
10546                 this._refreshValue();
10548                 this._animateOff = false;
10549         },
10551         destroy: function() {
10552                 this.handles.remove();
10553                 this.range.remove();
10555                 this.element
10556                         .removeClass( "ui-slider" +
10557                                 " ui-slider-horizontal" +
10558                                 " ui-slider-vertical" +
10559                                 " ui-slider-disabled" +
10560                                 " ui-widget" +
10561                                 " ui-widget-content" +
10562                                 " ui-corner-all" )
10563                         .removeData( "slider" )
10564                         .unbind( ".slider" );
10566                 this._mouseDestroy();
10568                 return this;
10569         },
10571         _mouseCapture: function( event ) {
10572                 var o = this.options,
10573                         position,
10574                         normValue,
10575                         distance,
10576                         closestHandle,
10577                         self,
10578                         index,
10579                         allowed,
10580                         offset,
10581                         mouseOverHandle;
10583                 if ( o.disabled ) {
10584                         return false;
10585                 }
10587                 this.elementSize = {
10588                         width: this.element.outerWidth(),
10589                         height: this.element.outerHeight()
10590                 };
10591                 this.elementOffset = this.element.offset();
10593                 position = { x: event.pageX, y: event.pageY };
10594                 normValue = this._normValueFromMouse( position );
10595                 distance = this._valueMax() - this._valueMin() + 1;
10596                 self = this;
10597                 this.handles.each(function( i ) {
10598                         var thisDistance = Math.abs( normValue - self.values(i) );
10599                         if ( distance > thisDistance ) {
10600                                 distance = thisDistance;
10601                                 closestHandle = $( this );
10602                                 index = i;
10603                         }
10604                 });
10606                 // workaround for bug #3736 (if both handles of a range are at 0,
10607                 // the first is always used as the one with least distance,
10608                 // and moving it is obviously prevented by preventing negative ranges)
10609                 if( o.range === true && this.values(1) === o.min ) {
10610                         index += 1;
10611                         closestHandle = $( this.handles[index] );
10612                 }
10614                 allowed = this._start( event, index );
10615                 if ( allowed === false ) {
10616                         return false;
10617                 }
10618                 this._mouseSliding = true;
10620                 self._handleIndex = index;
10622                 closestHandle
10623                         .addClass( "ui-state-active" )
10624                         .focus();
10625                 
10626                 offset = closestHandle.offset();
10627                 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
10628                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10629                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10630                         top: event.pageY - offset.top -
10631                                 ( closestHandle.height() / 2 ) -
10632                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10633                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10634                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10635                 };
10637                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10638                         this._slide( event, index, normValue );
10639                 }
10640                 this._animateOff = true;
10641                 return true;
10642         },
10644         _mouseStart: function( event ) {
10645                 return true;
10646         },
10648         _mouseDrag: function( event ) {
10649                 var position = { x: event.pageX, y: event.pageY },
10650                         normValue = this._normValueFromMouse( position );
10651                 
10652                 this._slide( event, this._handleIndex, normValue );
10654                 return false;
10655         },
10657         _mouseStop: function( event ) {
10658                 this.handles.removeClass( "ui-state-active" );
10659                 this._mouseSliding = false;
10661                 this._stop( event, this._handleIndex );
10662                 this._change( event, this._handleIndex );
10664                 this._handleIndex = null;
10665                 this._clickOffset = null;
10666                 this._animateOff = false;
10668                 return false;
10669         },
10670         
10671         _detectOrientation: function() {
10672                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10673         },
10675         _normValueFromMouse: function( position ) {
10676                 var pixelTotal,
10677                         pixelMouse,
10678                         percentMouse,
10679                         valueTotal,
10680                         valueMouse;
10682                 if ( this.orientation === "horizontal" ) {
10683                         pixelTotal = this.elementSize.width;
10684                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10685                 } else {
10686                         pixelTotal = this.elementSize.height;
10687                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10688                 }
10690                 percentMouse = ( pixelMouse / pixelTotal );
10691                 if ( percentMouse > 1 ) {
10692                         percentMouse = 1;
10693                 }
10694                 if ( percentMouse < 0 ) {
10695                         percentMouse = 0;
10696                 }
10697                 if ( this.orientation === "vertical" ) {
10698                         percentMouse = 1 - percentMouse;
10699                 }
10701                 valueTotal = this._valueMax() - this._valueMin();
10702                 valueMouse = this._valueMin() + percentMouse * valueTotal;
10704                 return this._trimAlignValue( valueMouse );
10705         },
10707         _start: function( event, index ) {
10708                 var uiHash = {
10709                         handle: this.handles[ index ],
10710                         value: this.value()
10711                 };
10712                 if ( this.options.values && this.options.values.length ) {
10713                         uiHash.value = this.values( index );
10714                         uiHash.values = this.values();
10715                 }
10716                 return this._trigger( "start", event, uiHash );
10717         },
10719         _slide: function( event, index, newVal ) {
10720                 var otherVal,
10721                         newValues,
10722                         allowed;
10724                 if ( this.options.values && this.options.values.length ) {
10725                         otherVal = this.values( index ? 0 : 1 );
10727                         if ( ( this.options.values.length === 2 && this.options.range === true ) && 
10728                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10729                                 ) {
10730                                 newVal = otherVal;
10731                         }
10733                         if ( newVal !== this.values( index ) ) {
10734                                 newValues = this.values();
10735                                 newValues[ index ] = newVal;
10736                                 // A slide can be canceled by returning false from the slide callback
10737                                 allowed = this._trigger( "slide", event, {
10738                                         handle: this.handles[ index ],
10739                                         value: newVal,
10740                                         values: newValues
10741                                 } );
10742                                 otherVal = this.values( index ? 0 : 1 );
10743                                 if ( allowed !== false ) {
10744                                         this.values( index, newVal, true );
10745                                 }
10746                         }
10747                 } else {
10748                         if ( newVal !== this.value() ) {
10749                                 // A slide can be canceled by returning false from the slide callback
10750                                 allowed = this._trigger( "slide", event, {
10751                                         handle: this.handles[ index ],
10752                                         value: newVal
10753                                 } );
10754                                 if ( allowed !== false ) {
10755                                         this.value( newVal );
10756                                 }
10757                         }
10758                 }
10759         },
10761         _stop: function( event, index ) {
10762                 var uiHash = {
10763                         handle: this.handles[ index ],
10764                         value: this.value()
10765                 };
10766                 if ( this.options.values && this.options.values.length ) {
10767                         uiHash.value = this.values( index );
10768                         uiHash.values = this.values();
10769                 }
10771                 this._trigger( "stop", event, uiHash );
10772         },
10774         _change: function( event, index ) {
10775                 if ( !this._keySliding && !this._mouseSliding ) {
10776                         var uiHash = {
10777                                 handle: this.handles[ index ],
10778                                 value: this.value()
10779                         };
10780                         if ( this.options.values && this.options.values.length ) {
10781                                 uiHash.value = this.values( index );
10782                                 uiHash.values = this.values();
10783                         }
10785                         this._trigger( "change", event, uiHash );
10786                 }
10787         },
10789         value: function( newValue ) {
10790                 if ( arguments.length ) {
10791                         this.options.value = this._trimAlignValue( newValue );
10792                         this._refreshValue();
10793                         this._change( null, 0 );
10794                         return;
10795                 }
10797                 return this._value();
10798         },
10800         values: function( index, newValue ) {
10801                 var vals,
10802                         newValues,
10803                         i;
10805                 if ( arguments.length > 1 ) {
10806                         this.options.values[ index ] = this._trimAlignValue( newValue );
10807                         this._refreshValue();
10808                         this._change( null, index );
10809                         return;
10810                 }
10812                 if ( arguments.length ) {
10813                         if ( $.isArray( arguments[ 0 ] ) ) {
10814                                 vals = this.options.values;
10815                                 newValues = arguments[ 0 ];
10816                                 for ( i = 0; i < vals.length; i += 1 ) {
10817                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
10818                                         this._change( null, i );
10819                                 }
10820                                 this._refreshValue();
10821                         } else {
10822                                 if ( this.options.values && this.options.values.length ) {
10823                                         return this._values( index );
10824                                 } else {
10825                                         return this.value();
10826                                 }
10827                         }
10828                 } else {
10829                         return this._values();
10830                 }
10831         },
10833         _setOption: function( key, value ) {
10834                 var i,
10835                         valsLength = 0;
10837                 if ( $.isArray( this.options.values ) ) {
10838                         valsLength = this.options.values.length;
10839                 }
10841                 $.Widget.prototype._setOption.apply( this, arguments );
10843                 switch ( key ) {
10844                         case "disabled":
10845                                 if ( value ) {
10846                                         this.handles.filter( ".ui-state-focus" ).blur();
10847                                         this.handles.removeClass( "ui-state-hover" );
10848                                         this.handles.propAttr( "disabled", true );
10849                                         this.element.addClass( "ui-disabled" );
10850                                 } else {
10851                                         this.handles.propAttr( "disabled", false );
10852                                         this.element.removeClass( "ui-disabled" );
10853                                 }
10854                                 break;
10855                         case "orientation":
10856                                 this._detectOrientation();
10857                                 this.element
10858                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
10859                                         .addClass( "ui-slider-" + this.orientation );
10860                                 this._refreshValue();
10861                                 break;
10862                         case "value":
10863                                 this._animateOff = true;
10864                                 this._refreshValue();
10865                                 this._change( null, 0 );
10866                                 this._animateOff = false;
10867                                 break;
10868                         case "values":
10869                                 this._animateOff = true;
10870                                 this._refreshValue();
10871                                 for ( i = 0; i < valsLength; i += 1 ) {
10872                                         this._change( null, i );
10873                                 }
10874                                 this._animateOff = false;
10875                                 break;
10876                 }
10877         },
10879         //internal value getter
10880         // _value() returns value trimmed by min and max, aligned by step
10881         _value: function() {
10882                 var val = this.options.value;
10883                 val = this._trimAlignValue( val );
10885                 return val;
10886         },
10888         //internal values getter
10889         // _values() returns array of values trimmed by min and max, aligned by step
10890         // _values( index ) returns single value trimmed by min and max, aligned by step
10891         _values: function( index ) {
10892                 var val,
10893                         vals,
10894                         i;
10896                 if ( arguments.length ) {
10897                         val = this.options.values[ index ];
10898                         val = this._trimAlignValue( val );
10900                         return val;
10901                 } else {
10902                         // .slice() creates a copy of the array
10903                         // this copy gets trimmed by min and max and then returned
10904                         vals = this.options.values.slice();
10905                         for ( i = 0; i < vals.length; i+= 1) {
10906                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
10907                         }
10909                         return vals;
10910                 }
10911         },
10912         
10913         // returns the step-aligned value that val is closest to, between (inclusive) min and max
10914         _trimAlignValue: function( val ) {
10915                 if ( val <= this._valueMin() ) {
10916                         return this._valueMin();
10917                 }
10918                 if ( val >= this._valueMax() ) {
10919                         return this._valueMax();
10920                 }
10921                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
10922                         valModStep = (val - this._valueMin()) % step,
10923                         alignValue = val - valModStep;
10925                 if ( Math.abs(valModStep) * 2 >= step ) {
10926                         alignValue += ( valModStep > 0 ) ? step : ( -step );
10927                 }
10929                 // Since JavaScript has problems with large floats, round
10930                 // the final value to 5 digits after the decimal point (see #4124)
10931                 return parseFloat( alignValue.toFixed(5) );
10932         },
10934         _valueMin: function() {
10935                 return this.options.min;
10936         },
10938         _valueMax: function() {
10939                 return this.options.max;
10940         },
10941         
10942         _refreshValue: function() {
10943                 var oRange = this.options.range,
10944                         o = this.options,
10945                         self = this,
10946                         animate = ( !this._animateOff ) ? o.animate : false,
10947                         valPercent,
10948                         _set = {},
10949                         lastValPercent,
10950                         value,
10951                         valueMin,
10952                         valueMax;
10954                 if ( this.options.values && this.options.values.length ) {
10955                         this.handles.each(function( i, j ) {
10956                                 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
10957                                 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10958                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10959                                 if ( self.options.range === true ) {
10960                                         if ( self.orientation === "horizontal" ) {
10961                                                 if ( i === 0 ) {
10962                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10963                                                 }
10964                                                 if ( i === 1 ) {
10965                                                         self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10966                                                 }
10967                                         } else {
10968                                                 if ( i === 0 ) {
10969                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10970                                                 }
10971                                                 if ( i === 1 ) {
10972                                                         self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10973                                                 }
10974                                         }
10975                                 }
10976                                 lastValPercent = valPercent;
10977                         });
10978                 } else {
10979                         value = this.value();
10980                         valueMin = this._valueMin();
10981                         valueMax = this._valueMax();
10982                         valPercent = ( valueMax !== valueMin ) ?
10983                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10984                                         0;
10985                         _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10986                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10988                         if ( oRange === "min" && this.orientation === "horizontal" ) {
10989                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10990                         }
10991                         if ( oRange === "max" && this.orientation === "horizontal" ) {
10992                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10993                         }
10994                         if ( oRange === "min" && this.orientation === "vertical" ) {
10995                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10996                         }
10997                         if ( oRange === "max" && this.orientation === "vertical" ) {
10998                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10999                         }
11000                 }
11001         }
11005 $.extend( $.ui.slider, {
11006         version: "1.8.16"
11009 }(jQuery));
11011  * jQuery UI Tabs 1.8.16
11013  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11014  * Dual licensed under the MIT or GPL Version 2 licenses.
11015  * http://jquery.org/license
11017  * http://docs.jquery.com/UI/Tabs
11019  * Depends:
11020  *      jquery.ui.core.js
11021  *      jquery.ui.widget.js
11022  */
11023 (function( $, undefined ) {
11025 var tabId = 0,
11026         listId = 0;
11028 function getNextTabId() {
11029         return ++tabId;
11032 function getNextListId() {
11033         return ++listId;
11036 $.widget( "ui.tabs", {
11037         options: {
11038                 add: null,
11039                 ajaxOptions: null,
11040                 cache: false,
11041                 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
11042                 collapsible: false,
11043                 disable: null,
11044                 disabled: [],
11045                 enable: null,
11046                 event: "click",
11047                 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
11048                 idPrefix: "ui-tabs-",
11049                 load: null,
11050                 panelTemplate: "<div></div>",
11051                 remove: null,
11052                 select: null,
11053                 show: null,
11054                 spinner: "<em>Loading&#8230;</em>",
11055                 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
11056         },
11058         _create: function() {
11059                 this._tabify( true );
11060         },
11062         _setOption: function( key, value ) {
11063                 if ( key == "selected" ) {
11064                         if (this.options.collapsible && value == this.options.selected ) {
11065                                 return;
11066                         }
11067                         this.select( value );
11068                 } else {
11069                         this.options[ key ] = value;
11070                         this._tabify();
11071                 }
11072         },
11074         _tabId: function( a ) {
11075                 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
11076                         this.options.idPrefix + getNextTabId();
11077         },
11079         _sanitizeSelector: function( hash ) {
11080                 // we need this because an id may contain a ":"
11081                 return hash.replace( /:/g, "\\:" );
11082         },
11084         _cookie: function() {
11085                 var cookie = this.cookie ||
11086                         ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
11087                 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
11088         },
11090         _ui: function( tab, panel ) {
11091                 return {
11092                         tab: tab,
11093                         panel: panel,
11094                         index: this.anchors.index( tab )
11095                 };
11096         },
11098         _cleanup: function() {
11099                 // restore all former loading tabs labels
11100                 this.lis.filter( ".ui-state-processing" )
11101                         .removeClass( "ui-state-processing" )
11102                         .find( "span:data(label.tabs)" )
11103                                 .each(function() {
11104                                         var el = $( this );
11105                                         el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
11106                                 });
11107         },
11109         _tabify: function( init ) {
11110                 var self = this,
11111                         o = this.options,
11112                         fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
11114                 this.list = this.element.find( "ol,ul" ).eq( 0 );
11115                 this.lis = $( " > li:has(a[href])", this.list );
11116                 this.anchors = this.lis.map(function() {
11117                         return $( "a", this )[ 0 ];
11118                 });
11119                 this.panels = $( [] );
11121                 this.anchors.each(function( i, a ) {
11122                         var href = $( a ).attr( "href" );
11123                         // For dynamically created HTML that contains a hash as href IE < 8 expands
11124                         // such href to the full page url with hash and then misinterprets tab as ajax.
11125                         // Same consideration applies for an added tab with a fragment identifier
11126                         // since a[href=#fragment-identifier] does unexpectedly not match.
11127                         // Thus normalize href attribute...
11128                         var hrefBase = href.split( "#" )[ 0 ],
11129                                 baseEl;
11130                         if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
11131                                         ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
11132                                 href = a.hash;
11133                                 a.href = href;
11134                         }
11136                         // inline tab
11137                         if ( fragmentId.test( href ) ) {
11138                                 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
11139                         // remote tab
11140                         // prevent loading the page itself if href is just "#"
11141                         } else if ( href && href !== "#" ) {
11142                                 // required for restore on destroy
11143                                 $.data( a, "href.tabs", href );
11145                                 // TODO until #3808 is fixed strip fragment identifier from url
11146                                 // (IE fails to load from such url)
11147                                 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
11149                                 var id = self._tabId( a );
11150                                 a.href = "#" + id;
11151                                 var $panel = self.element.find( "#" + id );
11152                                 if ( !$panel.length ) {
11153                                         $panel = $( o.panelTemplate )
11154                                                 .attr( "id", id )
11155                                                 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11156                                                 .insertAfter( self.panels[ i - 1 ] || self.list );
11157                                         $panel.data( "destroy.tabs", true );
11158                                 }
11159                                 self.panels = self.panels.add( $panel );
11160                         // invalid tab href
11161                         } else {
11162                                 o.disabled.push( i );
11163                         }
11164                 });
11166                 // initialization from scratch
11167                 if ( init ) {
11168                         // attach necessary classes for styling
11169                         this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
11170                         this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
11171                         this.lis.addClass( "ui-state-default ui-corner-top" );
11172                         this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
11174                         // Selected tab
11175                         // use "selected" option or try to retrieve:
11176                         // 1. from fragment identifier in url
11177                         // 2. from cookie
11178                         // 3. from selected class attribute on <li>
11179                         if ( o.selected === undefined ) {
11180                                 if ( location.hash ) {
11181                                         this.anchors.each(function( i, a ) {
11182                                                 if ( a.hash == location.hash ) {
11183                                                         o.selected = i;
11184                                                         return false;
11185                                                 }
11186                                         });
11187                                 }
11188                                 if ( typeof o.selected !== "number" && o.cookie ) {
11189                                         o.selected = parseInt( self._cookie(), 10 );
11190                                 }
11191                                 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
11192                                         o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
11193                                 }
11194                                 o.selected = o.selected || ( this.lis.length ? 0 : -1 );
11195                         } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
11196                                 o.selected = -1;
11197                         }
11199                         // sanity check - default to first tab...
11200                         o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
11201                                 ? o.selected
11202                                 : 0;
11204                         // Take disabling tabs via class attribute from HTML
11205                         // into account and update option properly.
11206                         // A selected tab cannot become disabled.
11207                         o.disabled = $.unique( o.disabled.concat(
11208                                 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
11209                                         return self.lis.index( n );
11210                                 })
11211                         ) ).sort();
11213                         if ( $.inArray( o.selected, o.disabled ) != -1 ) {
11214                                 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
11215                         }
11217                         // highlight selected tab
11218                         this.panels.addClass( "ui-tabs-hide" );
11219                         this.lis.removeClass( "ui-tabs-selected ui-state-active" );
11220                         // check for length avoids error when initializing empty list
11221                         if ( o.selected >= 0 && this.anchors.length ) {
11222                                 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
11223                                 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
11225                                 // seems to be expected behavior that the show callback is fired
11226                                 self.element.queue( "tabs", function() {
11227                                         self._trigger( "show", null,
11228                                                 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
11229                                 });
11231                                 this.load( o.selected );
11232                         }
11234                         // clean up to avoid memory leaks in certain versions of IE 6
11235                         // TODO: namespace this event
11236                         $( window ).bind( "unload", function() {
11237                                 self.lis.add( self.anchors ).unbind( ".tabs" );
11238                                 self.lis = self.anchors = self.panels = null;
11239                         });
11240                 // update selected after add/remove
11241                 } else {
11242                         o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
11243                 }
11245                 // update collapsible
11246                 // TODO: use .toggleClass()
11247                 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
11249                 // set or update cookie after init and add/remove respectively
11250                 if ( o.cookie ) {
11251                         this._cookie( o.selected, o.cookie );
11252                 }
11254                 // disable tabs
11255                 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
11256                         $( li )[ $.inArray( i, o.disabled ) != -1 &&
11257                                 // TODO: use .toggleClass()
11258                                 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
11259                 }
11261                 // reset cache if switching from cached to not cached
11262                 if ( o.cache === false ) {
11263                         this.anchors.removeData( "cache.tabs" );
11264                 }
11266                 // remove all handlers before, tabify may run on existing tabs after add or option change
11267                 this.lis.add( this.anchors ).unbind( ".tabs" );
11269                 if ( o.event !== "mouseover" ) {
11270                         var addState = function( state, el ) {
11271                                 if ( el.is( ":not(.ui-state-disabled)" ) ) {
11272                                         el.addClass( "ui-state-" + state );
11273                                 }
11274                         };
11275                         var removeState = function( state, el ) {
11276                                 el.removeClass( "ui-state-" + state );
11277                         };
11278                         this.lis.bind( "mouseover.tabs" , function() {
11279                                 addState( "hover", $( this ) );
11280                         });
11281                         this.lis.bind( "mouseout.tabs", function() {
11282                                 removeState( "hover", $( this ) );
11283                         });
11284                         this.anchors.bind( "focus.tabs", function() {
11285                                 addState( "focus", $( this ).closest( "li" ) );
11286                         });
11287                         this.anchors.bind( "blur.tabs", function() {
11288                                 removeState( "focus", $( this ).closest( "li" ) );
11289                         });
11290                 }
11292                 // set up animations
11293                 var hideFx, showFx;
11294                 if ( o.fx ) {
11295                         if ( $.isArray( o.fx ) ) {
11296                                 hideFx = o.fx[ 0 ];
11297                                 showFx = o.fx[ 1 ];
11298                         } else {
11299                                 hideFx = showFx = o.fx;
11300                         }
11301                 }
11303                 // Reset certain styles left over from animation
11304                 // and prevent IE's ClearType bug...
11305                 function resetStyle( $el, fx ) {
11306                         $el.css( "display", "" );
11307                         if ( !$.support.opacity && fx.opacity ) {
11308                                 $el[ 0 ].style.removeAttribute( "filter" );
11309                         }
11310                 }
11312                 // Show a tab...
11313                 var showTab = showFx
11314                         ? function( clicked, $show ) {
11315                                 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
11316                                 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
11317                                         .animate( showFx, showFx.duration || "normal", function() {
11318                                                 resetStyle( $show, showFx );
11319                                                 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
11320                                         });
11321                         }
11322                         : function( clicked, $show ) {
11323                                 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
11324                                 $show.removeClass( "ui-tabs-hide" );
11325                                 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
11326                         };
11328                 // Hide a tab, $show is optional...
11329                 var hideTab = hideFx
11330                         ? function( clicked, $hide ) {
11331                                 $hide.animate( hideFx, hideFx.duration || "normal", function() {
11332                                         self.lis.removeClass( "ui-tabs-selected ui-state-active" );
11333                                         $hide.addClass( "ui-tabs-hide" );
11334                                         resetStyle( $hide, hideFx );
11335                                         self.element.dequeue( "tabs" );
11336                                 });
11337                         }
11338                         : function( clicked, $hide, $show ) {
11339                                 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
11340                                 $hide.addClass( "ui-tabs-hide" );
11341                                 self.element.dequeue( "tabs" );
11342                         };
11344                 // attach tab event handler, unbind to avoid duplicates from former tabifying...
11345                 this.anchors.bind( o.event + ".tabs", function() {
11346                         var el = this,
11347                                 $li = $(el).closest( "li" ),
11348                                 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
11349                                 $show = self.element.find( self._sanitizeSelector( el.hash ) );
11351                         // If tab is already selected and not collapsible or tab disabled or
11352                         // or is already loading or click callback returns false stop here.
11353                         // Check if click handler returns false last so that it is not executed
11354                         // for a disabled or loading tab!
11355                         if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
11356                                 $li.hasClass( "ui-state-disabled" ) ||
11357                                 $li.hasClass( "ui-state-processing" ) ||
11358                                 self.panels.filter( ":animated" ).length ||
11359                                 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
11360                                 this.blur();
11361                                 return false;
11362                         }
11364                         o.selected = self.anchors.index( this );
11366                         self.abort();
11368                         // if tab may be closed
11369                         if ( o.collapsible ) {
11370                                 if ( $li.hasClass( "ui-tabs-selected" ) ) {
11371                                         o.selected = -1;
11373                                         if ( o.cookie ) {
11374                                                 self._cookie( o.selected, o.cookie );
11375                                         }
11377                                         self.element.queue( "tabs", function() {
11378                                                 hideTab( el, $hide );
11379                                         }).dequeue( "tabs" );
11381                                         this.blur();
11382                                         return false;
11383                                 } else if ( !$hide.length ) {
11384                                         if ( o.cookie ) {
11385                                                 self._cookie( o.selected, o.cookie );
11386                                         }
11388                                         self.element.queue( "tabs", function() {
11389                                                 showTab( el, $show );
11390                                         });
11392                                         // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
11393                                         self.load( self.anchors.index( this ) );
11395                                         this.blur();
11396                                         return false;
11397                                 }
11398                         }
11400                         if ( o.cookie ) {
11401                                 self._cookie( o.selected, o.cookie );
11402                         }
11404                         // show new tab
11405                         if ( $show.length ) {
11406                                 if ( $hide.length ) {
11407                                         self.element.queue( "tabs", function() {
11408                                                 hideTab( el, $hide );
11409                                         });
11410                                 }
11411                                 self.element.queue( "tabs", function() {
11412                                         showTab( el, $show );
11413                                 });
11415                                 self.load( self.anchors.index( this ) );
11416                         } else {
11417                                 throw "jQuery UI Tabs: Mismatching fragment identifier.";
11418                         }
11420                         // Prevent IE from keeping other link focussed when using the back button
11421                         // and remove dotted border from clicked link. This is controlled via CSS
11422                         // in modern browsers; blur() removes focus from address bar in Firefox
11423                         // which can become a usability and annoying problem with tabs('rotate').
11424                         if ( $.browser.msie ) {
11425                                 this.blur();
11426                         }
11427                 });
11429                 // disable click in any case
11430                 this.anchors.bind( "click.tabs", function(){
11431                         return false;
11432                 });
11433         },
11435     _getIndex: function( index ) {
11436                 // meta-function to give users option to provide a href string instead of a numerical index.
11437                 // also sanitizes numerical indexes to valid values.
11438                 if ( typeof index == "string" ) {
11439                         index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
11440                 }
11442                 return index;
11443         },
11445         destroy: function() {
11446                 var o = this.options;
11448                 this.abort();
11450                 this.element
11451                         .unbind( ".tabs" )
11452                         .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
11453                         .removeData( "tabs" );
11455                 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
11457                 this.anchors.each(function() {
11458                         var href = $.data( this, "href.tabs" );
11459                         if ( href ) {
11460                                 this.href = href;
11461                         }
11462                         var $this = $( this ).unbind( ".tabs" );
11463                         $.each( [ "href", "load", "cache" ], function( i, prefix ) {
11464                                 $this.removeData( prefix + ".tabs" );
11465                         });
11466                 });
11468                 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
11469                         if ( $.data( this, "destroy.tabs" ) ) {
11470                                 $( this ).remove();
11471                         } else {
11472                                 $( this ).removeClass([
11473                                         "ui-state-default",
11474                                         "ui-corner-top",
11475                                         "ui-tabs-selected",
11476                                         "ui-state-active",
11477                                         "ui-state-hover",
11478                                         "ui-state-focus",
11479                                         "ui-state-disabled",
11480                                         "ui-tabs-panel",
11481                                         "ui-widget-content",
11482                                         "ui-corner-bottom",
11483                                         "ui-tabs-hide"
11484                                 ].join( " " ) );
11485                         }
11486                 });
11488                 if ( o.cookie ) {
11489                         this._cookie( null, o.cookie );
11490                 }
11492                 return this;
11493         },
11495         add: function( url, label, index ) {
11496                 if ( index === undefined ) {
11497                         index = this.anchors.length;
11498                 }
11500                 var self = this,
11501                         o = this.options,
11502                         $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
11503                         id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
11505                 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
11507                 // try to find an existing element before creating a new one
11508                 var $panel = self.element.find( "#" + id );
11509                 if ( !$panel.length ) {
11510                         $panel = $( o.panelTemplate )
11511                                 .attr( "id", id )
11512                                 .data( "destroy.tabs", true );
11513                 }
11514                 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
11516                 if ( index >= this.lis.length ) {
11517                         $li.appendTo( this.list );
11518                         $panel.appendTo( this.list[ 0 ].parentNode );
11519                 } else {
11520                         $li.insertBefore( this.lis[ index ] );
11521                         $panel.insertBefore( this.panels[ index ] );
11522                 }
11524                 o.disabled = $.map( o.disabled, function( n, i ) {
11525                         return n >= index ? ++n : n;
11526                 });
11528                 this._tabify();
11530                 if ( this.anchors.length == 1 ) {
11531                         o.selected = 0;
11532                         $li.addClass( "ui-tabs-selected ui-state-active" );
11533                         $panel.removeClass( "ui-tabs-hide" );
11534                         this.element.queue( "tabs", function() {
11535                                 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
11536                         });
11538                         this.load( 0 );
11539                 }
11541                 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11542                 return this;
11543         },
11545         remove: function( index ) {
11546                 index = this._getIndex( index );
11547                 var o = this.options,
11548                         $li = this.lis.eq( index ).remove(),
11549                         $panel = this.panels.eq( index ).remove();
11551                 // If selected tab was removed focus tab to the right or
11552                 // in case the last tab was removed the tab to the left.
11553                 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
11554                         this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
11555                 }
11557                 o.disabled = $.map(
11558                         $.grep( o.disabled, function(n, i) {
11559                                 return n != index;
11560                         }),
11561                         function( n, i ) {
11562                                 return n >= index ? --n : n;
11563                         });
11565                 this._tabify();
11567                 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
11568                 return this;
11569         },
11571         enable: function( index ) {
11572                 index = this._getIndex( index );
11573                 var o = this.options;
11574                 if ( $.inArray( index, o.disabled ) == -1 ) {
11575                         return;
11576                 }
11578                 this.lis.eq( index ).removeClass( "ui-state-disabled" );
11579                 o.disabled = $.grep( o.disabled, function( n, i ) {
11580                         return n != index;
11581                 });
11583                 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11584                 return this;
11585         },
11587         disable: function( index ) {
11588                 index = this._getIndex( index );
11589                 var self = this, o = this.options;
11590                 // cannot disable already selected tab
11591                 if ( index != o.selected ) {
11592                         this.lis.eq( index ).addClass( "ui-state-disabled" );
11594                         o.disabled.push( index );
11595                         o.disabled.sort();
11597                         this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11598                 }
11600                 return this;
11601         },
11603         select: function( index ) {
11604                 index = this._getIndex( index );
11605                 if ( index == -1 ) {
11606                         if ( this.options.collapsible && this.options.selected != -1 ) {
11607                                 index = this.options.selected;
11608                         } else {
11609                                 return this;
11610                         }
11611                 }
11612                 this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
11613                 return this;
11614         },
11616         load: function( index ) {
11617                 index = this._getIndex( index );
11618                 var self = this,
11619                         o = this.options,
11620                         a = this.anchors.eq( index )[ 0 ],
11621                         url = $.data( a, "load.tabs" );
11623                 this.abort();
11625                 // not remote or from cache
11626                 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
11627                         this.element.dequeue( "tabs" );
11628                         return;
11629                 }
11631                 // load remote from here on
11632                 this.lis.eq( index ).addClass( "ui-state-processing" );
11634                 if ( o.spinner ) {
11635                         var span = $( "span", a );
11636                         span.data( "label.tabs", span.html() ).html( o.spinner );
11637                 }
11639                 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
11640                         url: url,
11641                         success: function( r, s ) {
11642                                 self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
11644                                 // take care of tab labels
11645                                 self._cleanup();
11647                                 if ( o.cache ) {
11648                                         $.data( a, "cache.tabs", true );
11649                                 }
11651                                 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
11652                                 try {
11653                                         o.ajaxOptions.success( r, s );
11654                                 }
11655                                 catch ( e ) {}
11656                         },
11657                         error: function( xhr, s, e ) {
11658                                 // take care of tab labels
11659                                 self._cleanup();
11661                                 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
11662                                 try {
11663                                         // Passing index avoid a race condition when this method is
11664                                         // called after the user has selected another tab.
11665                                         // Pass the anchor that initiated this request allows
11666                                         // loadError to manipulate the tab content panel via $(a.hash)
11667                                         o.ajaxOptions.error( xhr, s, index, a );
11668                                 }
11669                                 catch ( e ) {}
11670                         }
11671                 } ) );
11673                 // last, so that load event is fired before show...
11674                 self.element.dequeue( "tabs" );
11676                 return this;
11677         },
11679         abort: function() {
11680                 // stop possibly running animations
11681                 this.element.queue( [] );
11682                 this.panels.stop( false, true );
11684                 // "tabs" queue must not contain more than two elements,
11685                 // which are the callbacks for the latest clicked tab...
11686                 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
11688                 // terminate pending requests from other tabs
11689                 if ( this.xhr ) {
11690                         this.xhr.abort();
11691                         delete this.xhr;
11692                 }
11694                 // take care of tab labels
11695                 this._cleanup();
11696                 return this;
11697         },
11699         url: function( index, url ) {
11700                 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
11701                 return this;
11702         },
11704         length: function() {
11705                 return this.anchors.length;
11706         }
11709 $.extend( $.ui.tabs, {
11710         version: "1.8.16"
11714  * Tabs Extensions
11715  */
11718  * Rotate
11719  */
11720 $.extend( $.ui.tabs.prototype, {
11721         rotation: null,
11722         rotate: function( ms, continuing ) {
11723                 var self = this,
11724                         o = this.options;
11726                 var rotate = self._rotate || ( self._rotate = function( e ) {
11727                         clearTimeout( self.rotation );
11728                         self.rotation = setTimeout(function() {
11729                                 var t = o.selected;
11730                                 self.select( ++t < self.anchors.length ? t : 0 );
11731                         }, ms );
11732                         
11733                         if ( e ) {
11734                                 e.stopPropagation();
11735                         }
11736                 });
11738                 var stop = self._unrotate || ( self._unrotate = !continuing
11739                         ? function(e) {
11740                                 if (e.clientX) { // in case of a true click
11741                                         self.rotate(null);
11742                                 }
11743                         }
11744                         : function( e ) {
11745                                 t = o.selected;
11746                                 rotate();
11747                         });
11749                 // start rotation
11750                 if ( ms ) {
11751                         this.element.bind( "tabsshow", rotate );
11752                         this.anchors.bind( o.event + ".tabs", stop );
11753                         rotate();
11754                 // stop rotation
11755                 } else {
11756                         clearTimeout( self.rotation );
11757                         this.element.unbind( "tabsshow", rotate );
11758                         this.anchors.unbind( o.event + ".tabs", stop );
11759                         delete this._rotate;
11760                         delete this._unrotate;
11761                 }
11763                 return this;
11764         }
11767 })( jQuery );