response
[ikiwiki.git] / underlays / attachment / ikiwiki / jquery-ui.full.js
1 /*!
2  * jQuery UI 1.8.14
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 ) {
11
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;
18 }
19
20 $.extend( $.ui, {
21         version: "1.8.14",
22
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 });
58
59 // plugins
60 $.fn.extend({
61         _focus: $.fn.focus,
62         focus: function( delay, fn ) {
63                 return typeof delay === "number" ?
64                         this.each(function() {
65                                 var elem = this;
66                                 setTimeout(function() {
67                                         $( elem ).focus();
68                                         if ( fn ) {
69                                                 fn.call( elem );
70                                         }
71                                 }, delay );
72                         }) :
73                         this._focus.apply( this, arguments );
74         },
75
76         scrollParent: function() {
77                 var scrollParent;
78                 if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
79                         scrollParent = this.parents().filter(function() {
80                                 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));
81                         }).eq(0);
82                 } else {
83                         scrollParent = this.parents().filter(function() {
84                                 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
85                         }).eq(0);
86                 }
87
88                 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
89         },
90
91         zIndex: function( zIndex ) {
92                 if ( zIndex !== undefined ) {
93                         return this.css( "zIndex", zIndex );
94                 }
95
96                 if ( this.length ) {
97                         var elem = $( this[ 0 ] ), position, value;
98                         while ( elem.length && elem[ 0 ] !== document ) {
99                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
100                                 // This makes behavior of this function consistent across browsers
101                                 // WebKit always returns auto if the element is positioned
102                                 position = elem.css( "position" );
103                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
104                                         // IE returns 0 when zIndex is not specified
105                                         // other browsers return a string
106                                         // we ignore the case of nested elements with an explicit value of 0
107                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
108                                         value = parseInt( elem.css( "zIndex" ), 10 );
109                                         if ( !isNaN( value ) && value !== 0 ) {
110                                                 return value;
111                                         }
112                                 }
113                                 elem = elem.parent();
114                         }
115                 }
116
117                 return 0;
118         },
119
120         disableSelection: function() {
121                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
122                         ".ui-disableSelection", function( event ) {
123                                 event.preventDefault();
124                         });
125         },
126
127         enableSelection: function() {
128                 return this.unbind( ".ui-disableSelection" );
129         }
130 });
131
132 $.each( [ "Width", "Height" ], function( i, name ) {
133         var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
134                 type = name.toLowerCase(),
135                 orig = {
136                         innerWidth: $.fn.innerWidth,
137                         innerHeight: $.fn.innerHeight,
138                         outerWidth: $.fn.outerWidth,
139                         outerHeight: $.fn.outerHeight
140                 };
141
142         function reduce( elem, size, border, margin ) {
143                 $.each( side, function() {
144                         size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
145                         if ( border ) {
146                                 size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
147                         }
148                         if ( margin ) {
149                                 size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
150                         }
151                 });
152                 return size;
153         }
154
155         $.fn[ "inner" + name ] = function( size ) {
156                 if ( size === undefined ) {
157                         return orig[ "inner" + name ].call( this );
158                 }
159
160                 return this.each(function() {
161                         $( this ).css( type, reduce( this, size ) + "px" );
162                 });
163         };
164
165         $.fn[ "outer" + name] = function( size, margin ) {
166                 if ( typeof size !== "number" ) {
167                         return orig[ "outer" + name ].call( this, size );
168                 }
169
170                 return this.each(function() {
171                         $( this).css( type, reduce( this, size, true, margin ) + "px" );
172                 });
173         };
174 });
175
176 // selectors
177 function focusable( element, isTabIndexNotNaN ) {
178         var nodeName = element.nodeName.toLowerCase();
179         if ( "area" === nodeName ) {
180                 var map = element.parentNode,
181                         mapName = map.name,
182                         img;
183                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
184                         return false;
185                 }
186                 img = $( "img[usemap=#" + mapName + "]" )[0];
187                 return !!img && visible( img );
188         }
189         return ( /input|select|textarea|button|object/.test( nodeName )
190                 ? !element.disabled
191                 : "a" == nodeName
192                         ? element.href || isTabIndexNotNaN
193                         : isTabIndexNotNaN)
194                 // the element and all of its ancestors must be visible
195                 && visible( element );
196 }
197
198 function visible( element ) {
199         return !$( element ).parents().andSelf().filter(function() {
200                 return $.curCSS( this, "visibility" ) === "hidden" ||
201                         $.expr.filters.hidden( this );
202         }).length;
203 }
204
205 $.extend( $.expr[ ":" ], {
206         data: function( elem, i, match ) {
207                 return !!$.data( elem, match[ 3 ] );
208         },
209
210         focusable: function( element ) {
211                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
212         },
213
214         tabbable: function( element ) {
215                 var tabIndex = $.attr( element, "tabindex" ),
216                         isTabIndexNaN = isNaN( tabIndex );
217                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
218         }
219 });
220
221 // support
222 $(function() {
223         var body = document.body,
224                 div = body.appendChild( div = document.createElement( "div" ) );
225
226         $.extend( div.style, {
227                 minHeight: "100px",
228                 height: "auto",
229                 padding: 0,
230                 borderWidth: 0
231         });
232
233         $.support.minHeight = div.offsetHeight === 100;
234         $.support.selectstart = "onselectstart" in div;
235
236         // set display to none to avoid a layout bug in IE
237         // http://dev.jquery.com/ticket/4014
238         body.removeChild( div ).style.display = "none";
239 });
240
241
242
243
244
245 // deprecated
246 $.extend( $.ui, {
247         // $.ui.plugin is deprecated.  Use the proxy pattern instead.
248         plugin: {
249                 add: function( module, option, set ) {
250                         var proto = $.ui[ module ].prototype;
251                         for ( var i in set ) {
252                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
253                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
254                         }
255                 },
256                 call: function( instance, name, args ) {
257                         var set = instance.plugins[ name ];
258                         if ( !set || !instance.element[ 0 ].parentNode ) {
259                                 return;
260                         }
261         
262                         for ( var i = 0; i < set.length; i++ ) {
263                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
264                                         set[ i ][ 1 ].apply( instance.element, args );
265                                 }
266                         }
267                 }
268         },
269         
270         // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
271         contains: function( a, b ) {
272                 return document.compareDocumentPosition ?
273                         a.compareDocumentPosition( b ) & 16 :
274                         a !== b && a.contains( b );
275         },
276         
277         // only used by resizable
278         hasScroll: function( el, a ) {
279         
280                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
281                 if ( $( el ).css( "overflow" ) === "hidden") {
282                         return false;
283                 }
284         
285                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
286                         has = false;
287         
288                 if ( el[ scroll ] > 0 ) {
289                         return true;
290                 }
291         
292                 // TODO: determine which cases actually cause this to happen
293                 // if the element doesn't have the scroll set, see if it's possible to
294                 // set the scroll
295                 el[ scroll ] = 1;
296                 has = ( el[ scroll ] > 0 );
297                 el[ scroll ] = 0;
298                 return has;
299         },
300         
301         // these are odd functions, fix the API or move into individual plugins
302         isOverAxis: function( x, reference, size ) {
303                 //Determines when x coordinate is over "b" element axis
304                 return ( x > reference ) && ( x < ( reference + size ) );
305         },
306         isOver: function( y, x, top, left, height, width ) {
307                 //Determines when x, y coordinates is over "b" element
308                 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
309         }
310 });
311
312 })( jQuery );
313 /*!
314  * jQuery UI Widget 1.8.14
315  *
316  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
317  * Dual licensed under the MIT or GPL Version 2 licenses.
318  * http://jquery.org/license
319  *
320  * http://docs.jquery.com/UI/Widget
321  */
322 (function( $, undefined ) {
323
324 // jQuery 1.4+
325 if ( $.cleanData ) {
326         var _cleanData = $.cleanData;
327         $.cleanData = function( elems ) {
328                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
329                         $( elem ).triggerHandler( "remove" );
330                 }
331                 _cleanData( elems );
332         };
333 } else {
334         var _remove = $.fn.remove;
335         $.fn.remove = function( selector, keepData ) {
336                 return this.each(function() {
337                         if ( !keepData ) {
338                                 if ( !selector || $.filter( selector, [ this ] ).length ) {
339                                         $( "*", this ).add( [ this ] ).each(function() {
340                                                 $( this ).triggerHandler( "remove" );
341                                         });
342                                 }
343                         }
344                         return _remove.call( $(this), selector, keepData );
345                 });
346         };
347 }
348
349 $.widget = function( name, base, prototype ) {
350         var namespace = name.split( "." )[ 0 ],
351                 fullName;
352         name = name.split( "." )[ 1 ];
353         fullName = namespace + "-" + name;
354
355         if ( !prototype ) {
356                 prototype = base;
357                 base = $.Widget;
358         }
359
360         // create selector for plugin
361         $.expr[ ":" ][ fullName ] = function( elem ) {
362                 return !!$.data( elem, name );
363         };
364
365         $[ namespace ] = $[ namespace ] || {};
366         $[ namespace ][ name ] = function( options, element ) {
367                 // allow instantiation without initializing for simple inheritance
368                 if ( arguments.length ) {
369                         this._createWidget( options, element );
370                 }
371         };
372
373         var basePrototype = new base();
374         // we need to make the options hash a property directly on the new instance
375         // otherwise we'll modify the options hash on the prototype that we're
376         // inheriting from
377 //      $.each( basePrototype, function( key, val ) {
378 //              if ( $.isPlainObject(val) ) {
379 //                      basePrototype[ key ] = $.extend( {}, val );
380 //              }
381 //      });
382         basePrototype.options = $.extend( true, {}, basePrototype.options );
383         $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
384                 namespace: namespace,
385                 widgetName: name,
386                 widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
387                 widgetBaseClass: fullName
388         }, prototype );
389
390         $.widget.bridge( name, $[ namespace ][ name ] );
391 };
392
393 $.widget.bridge = function( name, object ) {
394         $.fn[ name ] = function( options ) {
395                 var isMethodCall = typeof options === "string",
396                         args = Array.prototype.slice.call( arguments, 1 ),
397                         returnValue = this;
398
399                 // allow multiple hashes to be passed on init
400                 options = !isMethodCall && args.length ?
401                         $.extend.apply( null, [ true, options ].concat(args) ) :
402                         options;
403
404                 // prevent calls to internal methods
405                 if ( isMethodCall && options.charAt( 0 ) === "_" ) {
406                         return returnValue;
407                 }
408
409                 if ( isMethodCall ) {
410                         this.each(function() {
411                                 var instance = $.data( this, name ),
412                                         methodValue = instance && $.isFunction( instance[options] ) ?
413                                                 instance[ options ].apply( instance, args ) :
414                                                 instance;
415                                 // TODO: add this back in 1.9 and use $.error() (see #5972)
416 //                              if ( !instance ) {
417 //                                      throw "cannot call methods on " + name + " prior to initialization; " +
418 //                                              "attempted to call method '" + options + "'";
419 //                              }
420 //                              if ( !$.isFunction( instance[options] ) ) {
421 //                                      throw "no such method '" + options + "' for " + name + " widget instance";
422 //                              }
423 //                              var methodValue = instance[ options ].apply( instance, args );
424                                 if ( methodValue !== instance && methodValue !== undefined ) {
425                                         returnValue = methodValue;
426                                         return false;
427                                 }
428                         });
429                 } else {
430                         this.each(function() {
431                                 var instance = $.data( this, name );
432                                 if ( instance ) {
433                                         instance.option( options || {} )._init();
434                                 } else {
435                                         $.data( this, name, new object( options, this ) );
436                                 }
437                         });
438                 }
439
440                 return returnValue;
441         };
442 };
443
444 $.Widget = function( options, element ) {
445         // allow instantiation without initializing for simple inheritance
446         if ( arguments.length ) {
447                 this._createWidget( options, element );
448         }
449 };
450
451 $.Widget.prototype = {
452         widgetName: "widget",
453         widgetEventPrefix: "",
454         options: {
455                 disabled: false
456         },
457         _createWidget: function( options, element ) {
458                 // $.widget.bridge stores the plugin instance, but we do it anyway
459                 // so that it's stored even before the _create function runs
460                 $.data( element, this.widgetName, this );
461                 this.element = $( element );
462                 this.options = $.extend( true, {},
463                         this.options,
464                         this._getCreateOptions(),
465                         options );
466
467                 var self = this;
468                 this.element.bind( "remove." + this.widgetName, function() {
469                         self.destroy();
470                 });
471
472                 this._create();
473                 this._trigger( "create" );
474                 this._init();
475         },
476         _getCreateOptions: function() {
477                 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
478         },
479         _create: function() {},
480         _init: function() {},
481
482         destroy: function() {
483                 this.element
484                         .unbind( "." + this.widgetName )
485                         .removeData( this.widgetName );
486                 this.widget()
487                         .unbind( "." + this.widgetName )
488                         .removeAttr( "aria-disabled" )
489                         .removeClass(
490                                 this.widgetBaseClass + "-disabled " +
491                                 "ui-state-disabled" );
492         },
493
494         widget: function() {
495                 return this.element;
496         },
497
498         option: function( key, value ) {
499                 var options = key;
500
501                 if ( arguments.length === 0 ) {
502                         // don't return a reference to the internal hash
503                         return $.extend( {}, this.options );
504                 }
505
506                 if  (typeof key === "string" ) {
507                         if ( value === undefined ) {
508                                 return this.options[ key ];
509                         }
510                         options = {};
511                         options[ key ] = value;
512                 }
513
514                 this._setOptions( options );
515
516                 return this;
517         },
518         _setOptions: function( options ) {
519                 var self = this;
520                 $.each( options, function( key, value ) {
521                         self._setOption( key, value );
522                 });
523
524                 return this;
525         },
526         _setOption: function( key, value ) {
527                 this.options[ key ] = value;
528
529                 if ( key === "disabled" ) {
530                         this.widget()
531                                 [ value ? "addClass" : "removeClass"](
532                                         this.widgetBaseClass + "-disabled" + " " +
533                                         "ui-state-disabled" )
534                                 .attr( "aria-disabled", value );
535                 }
536
537                 return this;
538         },
539
540         enable: function() {
541                 return this._setOption( "disabled", false );
542         },
543         disable: function() {
544                 return this._setOption( "disabled", true );
545         },
546
547         _trigger: function( type, event, data ) {
548                 var callback = this.options[ type ];
549
550                 event = $.Event( event );
551                 event.type = ( type === this.widgetEventPrefix ?
552                         type :
553                         this.widgetEventPrefix + type ).toLowerCase();
554                 data = data || {};
555
556                 // copy original event properties over to the new event
557                 // this would happen if we could call $.event.fix instead of $.Event
558                 // but we don't have a way to force an event to be fixed multiple times
559                 if ( event.originalEvent ) {
560                         for ( var i = $.event.props.length, prop; i; ) {
561                                 prop = $.event.props[ --i ];
562                                 event[ prop ] = event.originalEvent[ prop ];
563                         }
564                 }
565
566                 this.element.trigger( event, data );
567
568                 return !( $.isFunction(callback) &&
569                         callback.call( this.element[0], event, data ) === false ||
570                         event.isDefaultPrevented() );
571         }
572 };
573
574 })( jQuery );
575 /*!
576  * jQuery UI Mouse 1.8.14
577  *
578  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
579  * Dual licensed under the MIT or GPL Version 2 licenses.
580  * http://jquery.org/license
581  *
582  * http://docs.jquery.com/UI/Mouse
583  *
584  * Depends:
585  *      jquery.ui.widget.js
586  */
587 (function( $, undefined ) {
588
589 var mouseHandled = false;
590 $(document).mousedown(function(e) {
591         mouseHandled = false;
592 });
593
594 $.widget("ui.mouse", {
595         options: {
596                 cancel: ':input,option',
597                 distance: 1,
598                 delay: 0
599         },
600         _mouseInit: function() {
601                 var self = this;
602
603                 this.element
604                         .bind('mousedown.'+this.widgetName, function(event) {
605                                 return self._mouseDown(event);
606                         })
607                         .bind('click.'+this.widgetName, function(event) {
608                                 if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
609                                     $.removeData(event.target, self.widgetName + '.preventClickEvent');
610                                         event.stopImmediatePropagation();
611                                         return false;
612                                 }
613                         });
614
615                 this.started = false;
616         },
617
618         // TODO: make sure destroying one instance of mouse doesn't mess with
619         // other instances of mouse
620         _mouseDestroy: function() {
621                 this.element.unbind('.'+this.widgetName);
622         },
623
624         _mouseDown: function(event) {
625                 // don't let more than one widget handle mouseStart
626                 if(mouseHandled) {return};
627
628                 // we may have missed mouseup (out of window)
629                 (this._mouseStarted && this._mouseUp(event));
630
631                 this._mouseDownEvent = event;
632
633                 var self = this,
634                         btnIsLeft = (event.which == 1),
635                         elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).closest(this.options.cancel).length : false);
636                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
637                         return true;
638                 }
639
640                 this.mouseDelayMet = !this.options.delay;
641                 if (!this.mouseDelayMet) {
642                         this._mouseDelayTimer = setTimeout(function() {
643                                 self.mouseDelayMet = true;
644                         }, this.options.delay);
645                 }
646
647                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
648                         this._mouseStarted = (this._mouseStart(event) !== false);
649                         if (!this._mouseStarted) {
650                                 event.preventDefault();
651                                 return true;
652                         }
653                 }
654
655                 // Click event may never have fired (Gecko & Opera)
656                 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
657                         $.removeData(event.target, this.widgetName + '.preventClickEvent');
658                 }
659
660                 // these delegates are required to keep context
661                 this._mouseMoveDelegate = function(event) {
662                         return self._mouseMove(event);
663                 };
664                 this._mouseUpDelegate = function(event) {
665                         return self._mouseUp(event);
666                 };
667                 $(document)
668                         .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
669                         .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
670
671                 event.preventDefault();
672                 
673                 mouseHandled = true;
674                 return true;
675         },
676
677         _mouseMove: function(event) {
678                 // IE mouseup check - mouseup happened when mouse was out of window
679                 if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
680                         return this._mouseUp(event);
681                 }
682
683                 if (this._mouseStarted) {
684                         this._mouseDrag(event);
685                         return event.preventDefault();
686                 }
687
688                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
689                         this._mouseStarted =
690                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
691                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
692                 }
693
694                 return !this._mouseStarted;
695         },
696
697         _mouseUp: function(event) {
698                 $(document)
699                         .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
700                         .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
701
702                 if (this._mouseStarted) {
703                         this._mouseStarted = false;
704
705                         if (event.target == this._mouseDownEvent.target) {
706                             $.data(event.target, this.widgetName + '.preventClickEvent', true);
707                         }
708
709                         this._mouseStop(event);
710                 }
711
712                 return false;
713         },
714
715         _mouseDistanceMet: function(event) {
716                 return (Math.max(
717                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
718                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
719                         ) >= this.options.distance
720                 );
721         },
722
723         _mouseDelayMet: function(event) {
724                 return this.mouseDelayMet;
725         },
726
727         // These are placeholder methods, to be overriden by extending plugin
728         _mouseStart: function(event) {},
729         _mouseDrag: function(event) {},
730         _mouseStop: function(event) {},
731         _mouseCapture: function(event) { return true; }
732 });
733
734 })(jQuery);
735 /*
736  * jQuery UI Position 1.8.14
737  *
738  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
739  * Dual licensed under the MIT or GPL Version 2 licenses.
740  * http://jquery.org/license
741  *
742  * http://docs.jquery.com/UI/Position
743  */
744 (function( $, undefined ) {
745
746 $.ui = $.ui || {};
747
748 var horizontalPositions = /left|center|right/,
749         verticalPositions = /top|center|bottom/,
750         center = "center",
751         _position = $.fn.position,
752         _offset = $.fn.offset;
753
754 $.fn.position = function( options ) {
755         if ( !options || !options.of ) {
756                 return _position.apply( this, arguments );
757         }
758
759         // make a copy, we don't want to modify arguments
760         options = $.extend( {}, options );
761
762         var target = $( options.of ),
763                 targetElem = target[0],
764                 collision = ( options.collision || "flip" ).split( " " ),
765                 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
766                 targetWidth,
767                 targetHeight,
768                 basePosition;
769
770         if ( targetElem.nodeType === 9 ) {
771                 targetWidth = target.width();
772                 targetHeight = target.height();
773                 basePosition = { top: 0, left: 0 };
774         // TODO: use $.isWindow() in 1.9
775         } else if ( targetElem.setTimeout ) {
776                 targetWidth = target.width();
777                 targetHeight = target.height();
778                 basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
779         } else if ( targetElem.preventDefault ) {
780                 // force left top to allow flipping
781                 options.at = "left top";
782                 targetWidth = targetHeight = 0;
783                 basePosition = { top: options.of.pageY, left: options.of.pageX };
784         } else {
785                 targetWidth = target.outerWidth();
786                 targetHeight = target.outerHeight();
787                 basePosition = target.offset();
788         }
789
790         // force my and at to have valid horizontal and veritcal positions
791         // if a value is missing or invalid, it will be converted to center 
792         $.each( [ "my", "at" ], function() {
793                 var pos = ( options[this] || "" ).split( " " );
794                 if ( pos.length === 1) {
795                         pos = horizontalPositions.test( pos[0] ) ?
796                                 pos.concat( [center] ) :
797                                 verticalPositions.test( pos[0] ) ?
798                                         [ center ].concat( pos ) :
799                                         [ center, center ];
800                 }
801                 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
802                 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
803                 options[ this ] = pos;
804         });
805
806         // normalize collision option
807         if ( collision.length === 1 ) {
808                 collision[ 1 ] = collision[ 0 ];
809         }
810
811         // normalize offset option
812         offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
813         if ( offset.length === 1 ) {
814                 offset[ 1 ] = offset[ 0 ];
815         }
816         offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
817
818         if ( options.at[0] === "right" ) {
819                 basePosition.left += targetWidth;
820         } else if ( options.at[0] === center ) {
821                 basePosition.left += targetWidth / 2;
822         }
823
824         if ( options.at[1] === "bottom" ) {
825                 basePosition.top += targetHeight;
826         } else if ( options.at[1] === center ) {
827                 basePosition.top += targetHeight / 2;
828         }
829
830         basePosition.left += offset[ 0 ];
831         basePosition.top += offset[ 1 ];
832
833         return this.each(function() {
834                 var elem = $( this ),
835                         elemWidth = elem.outerWidth(),
836                         elemHeight = elem.outerHeight(),
837                         marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
838                         marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
839                         collisionWidth = elemWidth + marginLeft +
840                                 ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
841                         collisionHeight = elemHeight + marginTop +
842                                 ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
843                         position = $.extend( {}, basePosition ),
844                         collisionPosition;
845
846                 if ( options.my[0] === "right" ) {
847                         position.left -= elemWidth;
848                 } else if ( options.my[0] === center ) {
849                         position.left -= elemWidth / 2;
850                 }
851
852                 if ( options.my[1] === "bottom" ) {
853                         position.top -= elemHeight;
854                 } else if ( options.my[1] === center ) {
855                         position.top -= elemHeight / 2;
856                 }
857
858                 // prevent fractions (see #5280)
859                 position.left = Math.round( position.left );
860                 position.top = Math.round( position.top );
861
862                 collisionPosition = {
863                         left: position.left - marginLeft,
864                         top: position.top - marginTop
865                 };
866
867                 $.each( [ "left", "top" ], function( i, dir ) {
868                         if ( $.ui.position[ collision[i] ] ) {
869                                 $.ui.position[ collision[i] ][ dir ]( position, {
870                                         targetWidth: targetWidth,
871                                         targetHeight: targetHeight,
872                                         elemWidth: elemWidth,
873                                         elemHeight: elemHeight,
874                                         collisionPosition: collisionPosition,
875                                         collisionWidth: collisionWidth,
876                                         collisionHeight: collisionHeight,
877                                         offset: offset,
878                                         my: options.my,
879                                         at: options.at
880                                 });
881                         }
882                 });
883
884                 if ( $.fn.bgiframe ) {
885                         elem.bgiframe();
886                 }
887                 elem.offset( $.extend( position, { using: options.using } ) );
888         });
889 };
890
891 $.ui.position = {
892         fit: {
893                 left: function( position, data ) {
894                         var win = $( window ),
895                                 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
896                         position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
897                 },
898                 top: function( position, data ) {
899                         var win = $( window ),
900                                 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
901                         position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
902                 }
903         },
904
905         flip: {
906                 left: function( position, data ) {
907                         if ( data.at[0] === center ) {
908                                 return;
909                         }
910                         var win = $( window ),
911                                 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
912                                 myOffset = data.my[ 0 ] === "left" ?
913                                         -data.elemWidth :
914                                         data.my[ 0 ] === "right" ?
915                                                 data.elemWidth :
916                                                 0,
917                                 atOffset = data.at[ 0 ] === "left" ?
918                                         data.targetWidth :
919                                         -data.targetWidth,
920                                 offset = -2 * data.offset[ 0 ];
921                         position.left += data.collisionPosition.left < 0 ?
922                                 myOffset + atOffset + offset :
923                                 over > 0 ?
924                                         myOffset + atOffset + offset :
925                                         0;
926                 },
927                 top: function( position, data ) {
928                         if ( data.at[1] === center ) {
929                                 return;
930                         }
931                         var win = $( window ),
932                                 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
933                                 myOffset = data.my[ 1 ] === "top" ?
934                                         -data.elemHeight :
935                                         data.my[ 1 ] === "bottom" ?
936                                                 data.elemHeight :
937                                                 0,
938                                 atOffset = data.at[ 1 ] === "top" ?
939                                         data.targetHeight :
940                                         -data.targetHeight,
941                                 offset = -2 * data.offset[ 1 ];
942                         position.top += data.collisionPosition.top < 0 ?
943                                 myOffset + atOffset + offset :
944                                 over > 0 ?
945                                         myOffset + atOffset + offset :
946                                         0;
947                 }
948         }
949 };
950
951 // offset setter from jQuery 1.4
952 if ( !$.offset.setOffset ) {
953         $.offset.setOffset = function( elem, options ) {
954                 // set position first, in-case top/left are set even on static elem
955                 if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
956                         elem.style.position = "relative";
957                 }
958                 var curElem   = $( elem ),
959                         curOffset = curElem.offset(),
960                         curTop    = parseInt( $.curCSS( elem, "top",  true ), 10 ) || 0,
961                         curLeft   = parseInt( $.curCSS( elem, "left", true ), 10)  || 0,
962                         props     = {
963                                 top:  (options.top  - curOffset.top)  + curTop,
964                                 left: (options.left - curOffset.left) + curLeft
965                         };
966                 
967                 if ( 'using' in options ) {
968                         options.using.call( elem, props );
969                 } else {
970                         curElem.css( props );
971                 }
972         };
973
974         $.fn.offset = function( options ) {
975                 var elem = this[ 0 ];
976                 if ( !elem || !elem.ownerDocument ) { return null; }
977                 if ( options ) { 
978                         return this.each(function() {
979                                 $.offset.setOffset( this, options );
980                         });
981                 }
982                 return _offset.call( this );
983         };
984 }
985
986 }( jQuery ));
987 /*
988  * jQuery UI Draggable 1.8.14
989  *
990  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
991  * Dual licensed under the MIT or GPL Version 2 licenses.
992  * http://jquery.org/license
993  *
994  * http://docs.jquery.com/UI/Draggables
995  *
996  * Depends:
997  *      jquery.ui.core.js
998  *      jquery.ui.mouse.js
999  *      jquery.ui.widget.js
1000  */
1001 (function( $, undefined ) {
1002
1003 $.widget("ui.draggable", $.ui.mouse, {
1004         widgetEventPrefix: "drag",
1005         options: {
1006                 addClasses: true,
1007                 appendTo: "parent",
1008                 axis: false,
1009                 connectToSortable: false,
1010                 containment: false,
1011                 cursor: "auto",
1012                 cursorAt: false,
1013                 grid: false,
1014                 handle: false,
1015                 helper: "original",
1016                 iframeFix: false,
1017                 opacity: false,
1018                 refreshPositions: false,
1019                 revert: false,
1020                 revertDuration: 500,
1021                 scope: "default",
1022                 scroll: true,
1023                 scrollSensitivity: 20,
1024                 scrollSpeed: 20,
1025                 snap: false,
1026                 snapMode: "both",
1027                 snapTolerance: 20,
1028                 stack: false,
1029                 zIndex: false
1030         },
1031         _create: function() {
1032
1033                 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1034                         this.element[0].style.position = 'relative';
1035
1036                 (this.options.addClasses && this.element.addClass("ui-draggable"));
1037                 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1038
1039                 this._mouseInit();
1040
1041         },
1042
1043         destroy: function() {
1044                 if(!this.element.data('draggable')) return;
1045                 this.element
1046                         .removeData("draggable")
1047                         .unbind(".draggable")
1048                         .removeClass("ui-draggable"
1049                                 + " ui-draggable-dragging"
1050                                 + " ui-draggable-disabled");
1051                 this._mouseDestroy();
1052
1053                 return this;
1054         },
1055
1056         _mouseCapture: function(event) {
1057
1058                 var o = this.options;
1059
1060                 // among others, prevent a drag on a resizable-handle
1061                 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1062                         return false;
1063
1064                 //Quit if we're not on a valid handle
1065                 this.handle = this._getHandle(event);
1066                 if (!this.handle)
1067                         return false;
1068                 
1069                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1070                         $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1071                         .css({
1072                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1073                                 position: "absolute", opacity: "0.001", zIndex: 1000
1074                         })
1075                         .css($(this).offset())
1076                         .appendTo("body");
1077                 });
1078
1079                 return true;
1080
1081         },
1082
1083         _mouseStart: function(event) {
1084
1085                 var o = this.options;
1086
1087                 //Create and append the visible helper
1088                 this.helper = this._createHelper(event);
1089
1090                 //Cache the helper size
1091                 this._cacheHelperProportions();
1092
1093                 //If ddmanager is used for droppables, set the global draggable
1094                 if($.ui.ddmanager)
1095                         $.ui.ddmanager.current = this;
1096
1097                 /*
1098                  * - Position generation -
1099                  * This block generates everything position related - it's the core of draggables.
1100                  */
1101
1102                 //Cache the margins of the original element
1103                 this._cacheMargins();
1104
1105                 //Store the helper's css position
1106                 this.cssPosition = this.helper.css("position");
1107                 this.scrollParent = this.helper.scrollParent();
1108
1109                 //The element's absolute position on the page minus margins
1110                 this.offset = this.positionAbs = this.element.offset();
1111                 this.offset = {
1112                         top: this.offset.top - this.margins.top,
1113                         left: this.offset.left - this.margins.left
1114                 };
1115
1116                 $.extend(this.offset, {
1117                         click: { //Where the click happened, relative to the element
1118                                 left: event.pageX - this.offset.left,
1119                                 top: event.pageY - this.offset.top
1120                         },
1121                         parent: this._getParentOffset(),
1122                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1123                 });
1124
1125                 //Generate the original position
1126                 this.originalPosition = this.position = this._generatePosition(event);
1127                 this.originalPageX = event.pageX;
1128                 this.originalPageY = event.pageY;
1129
1130                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1131                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1132
1133                 //Set a containment if given in the options
1134                 if(o.containment)
1135                         this._setContainment();
1136
1137                 //Trigger event + callbacks
1138                 if(this._trigger("start", event) === false) {
1139                         this._clear();
1140                         return false;
1141                 }
1142
1143                 //Recache the helper size
1144                 this._cacheHelperProportions();
1145
1146                 //Prepare the droppable offsets
1147                 if ($.ui.ddmanager && !o.dropBehaviour)
1148                         $.ui.ddmanager.prepareOffsets(this, event);
1149
1150                 this.helper.addClass("ui-draggable-dragging");
1151                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1152                 
1153                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1154                 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1155                 
1156                 return true;
1157         },
1158
1159         _mouseDrag: function(event, noPropagation) {
1160
1161                 //Compute the helpers position
1162                 this.position = this._generatePosition(event);
1163                 this.positionAbs = this._convertPositionTo("absolute");
1164
1165                 //Call plugins and callbacks and use the resulting position if something is returned
1166                 if (!noPropagation) {
1167                         var ui = this._uiHash();
1168                         if(this._trigger('drag', event, ui) === false) {
1169                                 this._mouseUp({});
1170                                 return false;
1171                         }
1172                         this.position = ui.position;
1173                 }
1174
1175                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1176                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1177                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1178
1179                 return false;
1180         },
1181
1182         _mouseStop: function(event) {
1183
1184                 //If we are using droppables, inform the manager about the drop
1185                 var dropped = false;
1186                 if ($.ui.ddmanager && !this.options.dropBehaviour)
1187                         dropped = $.ui.ddmanager.drop(this, event);
1188
1189                 //if a drop comes from outside (a sortable)
1190                 if(this.dropped) {
1191                         dropped = this.dropped;
1192                         this.dropped = false;
1193                 }
1194                 
1195                 //if the original element is removed, don't bother to continue if helper is set to "original"
1196                 if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
1197                         return false;
1198
1199                 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))) {
1200                         var self = this;
1201                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1202                                 if(self._trigger("stop", event) !== false) {
1203                                         self._clear();
1204                                 }
1205                         });
1206                 } else {
1207                         if(this._trigger("stop", event) !== false) {
1208                                 this._clear();
1209                         }
1210                 }
1211
1212                 return false;
1213         },
1214         
1215         _mouseUp: function(event) {
1216                 if (this.options.iframeFix === true) {
1217                         $("div.ui-draggable-iframeFix").each(function() { 
1218                                 this.parentNode.removeChild(this); 
1219                         }); //Remove frame helpers
1220                 }
1221                 
1222                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1223                 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1224                 
1225                 return $.ui.mouse.prototype._mouseUp.call(this, event);
1226         },
1227         
1228         cancel: function() {
1229                 
1230                 if(this.helper.is(".ui-draggable-dragging")) {
1231                         this._mouseUp({});
1232                 } else {
1233                         this._clear();
1234                 }
1235                 
1236                 return this;
1237                 
1238         },
1239
1240         _getHandle: function(event) {
1241
1242                 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1243                 $(this.options.handle, this.element)
1244                         .find("*")
1245                         .andSelf()
1246                         .each(function() {
1247                                 if(this == event.target) handle = true;
1248                         });
1249
1250                 return handle;
1251
1252         },
1253
1254         _createHelper: function(event) {
1255
1256                 var o = this.options;
1257                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1258
1259                 if(!helper.parents('body').length)
1260                         helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1261
1262                 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1263                         helper.css("position", "absolute");
1264
1265                 return helper;
1266
1267         },
1268
1269         _adjustOffsetFromHelper: function(obj) {
1270                 if (typeof obj == 'string') {
1271                         obj = obj.split(' ');
1272                 }
1273                 if ($.isArray(obj)) {
1274                         obj = {left: +obj[0], top: +obj[1] || 0};
1275                 }
1276                 if ('left' in obj) {
1277                         this.offset.click.left = obj.left + this.margins.left;
1278                 }
1279                 if ('right' in obj) {
1280                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1281                 }
1282                 if ('top' in obj) {
1283                         this.offset.click.top = obj.top + this.margins.top;
1284                 }
1285                 if ('bottom' in obj) {
1286                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1287                 }
1288         },
1289
1290         _getParentOffset: function() {
1291
1292                 //Get the offsetParent and cache its position
1293                 this.offsetParent = this.helper.offsetParent();
1294                 var po = this.offsetParent.offset();
1295
1296                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1297                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1298                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1299                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1300                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1301                         po.left += this.scrollParent.scrollLeft();
1302                         po.top += this.scrollParent.scrollTop();
1303                 }
1304
1305                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1306                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1307                         po = { top: 0, left: 0 };
1308
1309                 return {
1310                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1311                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1312                 };
1313
1314         },
1315
1316         _getRelativeOffset: function() {
1317
1318                 if(this.cssPosition == "relative") {
1319                         var p = this.element.position();
1320                         return {
1321                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1322                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1323                         };
1324                 } else {
1325                         return { top: 0, left: 0 };
1326                 }
1327
1328         },
1329
1330         _cacheMargins: function() {
1331                 this.margins = {
1332                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
1333                         top: (parseInt(this.element.css("marginTop"),10) || 0),
1334                         right: (parseInt(this.element.css("marginRight"),10) || 0),
1335                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1336                 };
1337         },
1338
1339         _cacheHelperProportions: function() {
1340                 this.helperProportions = {
1341                         width: this.helper.outerWidth(),
1342                         height: this.helper.outerHeight()
1343                 };
1344         },
1345
1346         _setContainment: function() {
1347
1348                 var o = this.options;
1349                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1350                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
1351                         o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1352                         o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1353                         (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1354                         (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1355                 ];
1356
1357                 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1358                         var c = $(o.containment);
1359                         var ce = c[0]; if(!ce) return;
1360                         var co = c.offset();
1361                         var over = ($(ce).css("overflow") != 'hidden');
1362
1363                         this.containment = [
1364                                 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1365                                 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1366                                 (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,
1367                                 (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
1368                         ];
1369                         this.relative_container = c;
1370
1371                 } else if(o.containment.constructor == Array) {
1372                         this.containment = o.containment;
1373                 }
1374
1375         },
1376
1377         _convertPositionTo: function(d, pos) {
1378
1379                 if(!pos) pos = this.position;
1380                 var mod = d == "absolute" ? 1 : -1;
1381                 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);
1382
1383                 return {
1384                         top: (
1385                                 pos.top                                                                                                                                 // The absolute mouse position
1386                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1387                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
1388                                 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1389                         ),
1390                         left: (
1391                                 pos.left                                                                                                                                // The absolute mouse position
1392                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
1393                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
1394                                 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1395                         )
1396                 };
1397
1398         },
1399
1400         _generatePosition: function(event) {
1401
1402                 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);
1403                 var pageX = event.pageX;
1404                 var pageY = event.pageY;
1405
1406                 /*
1407                  * - Position constraining -
1408                  * Constrain the position to a mix of grid, containment.
1409                  */
1410
1411                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1412                          var containment;
1413                          if(this.containment) {
1414                                  if (this.relative_container){
1415                                      var co = this.relative_container.offset();
1416                                      containment = [ this.containment[0] + co.left,
1417                                                      this.containment[1] + co.top,
1418                                                      this.containment[2] + co.left,
1419                                                      this.containment[3] + co.top ];
1420                                  }
1421                                  else {
1422                                      containment = this.containment;
1423                                  }
1424
1425                                 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1426                                 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1427                                 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1428                                 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1429                         }
1430
1431                         if(o.grid) {
1432                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1433                                 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1434                                 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;
1435
1436                                 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1437                                 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;
1438                         }
1439
1440                 }
1441
1442                 return {
1443                         top: (
1444                                 pageY                                                                                                                           // The absolute mouse position
1445                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
1446                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
1447                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
1448                                 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1449                         ),
1450                         left: (
1451                                 pageX                                                                                                                           // The absolute mouse position
1452                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
1453                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
1454                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
1455                                 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1456                         )
1457                 };
1458
1459         },
1460
1461         _clear: function() {
1462                 this.helper.removeClass("ui-draggable-dragging");
1463                 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1464                 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1465                 this.helper = null;
1466                 this.cancelHelperRemoval = false;
1467         },
1468
1469         // From now on bulk stuff - mainly helpers
1470
1471         _trigger: function(type, event, ui) {
1472                 ui = ui || this._uiHash();
1473                 $.ui.plugin.call(this, type, [event, ui]);
1474                 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1475                 return $.Widget.prototype._trigger.call(this, type, event, ui);
1476         },
1477
1478         plugins: {},
1479
1480         _uiHash: function(event) {
1481                 return {
1482                         helper: this.helper,
1483                         position: this.position,
1484                         originalPosition: this.originalPosition,
1485                         offset: this.positionAbs
1486                 };
1487         }
1488
1489 });
1490
1491 $.extend($.ui.draggable, {
1492         version: "1.8.14"
1493 });
1494
1495 $.ui.plugin.add("draggable", "connectToSortable", {
1496         start: function(event, ui) {
1497
1498                 var inst = $(this).data("draggable"), o = inst.options,
1499                         uiSortable = $.extend({}, ui, { item: inst.element });
1500                 inst.sortables = [];
1501                 $(o.connectToSortable).each(function() {
1502                         var sortable = $.data(this, 'sortable');
1503                         if (sortable && !sortable.options.disabled) {
1504                                 inst.sortables.push({
1505                                         instance: sortable,
1506                                         shouldRevert: sortable.options.revert
1507                                 });
1508                                 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).
1509                                 sortable._trigger("activate", event, uiSortable);
1510                         }
1511                 });
1512
1513         },
1514         stop: function(event, ui) {
1515
1516                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1517                 var inst = $(this).data("draggable"),
1518                         uiSortable = $.extend({}, ui, { item: inst.element });
1519
1520                 $.each(inst.sortables, function() {
1521                         if(this.instance.isOver) {
1522
1523                                 this.instance.isOver = 0;
1524
1525                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1526                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1527
1528                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1529                                 if(this.shouldRevert) this.instance.options.revert = true;
1530
1531                                 //Trigger the stop of the sortable
1532                                 this.instance._mouseStop(event);
1533
1534                                 this.instance.options.helper = this.instance.options._helper;
1535
1536                                 //If the helper has been the original item, restore properties in the sortable
1537                                 if(inst.options.helper == 'original')
1538                                         this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1539
1540                         } else {
1541                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1542                                 this.instance._trigger("deactivate", event, uiSortable);
1543                         }
1544
1545                 });
1546
1547         },
1548         drag: function(event, ui) {
1549
1550                 var inst = $(this).data("draggable"), self = this;
1551
1552                 var checkPos = function(o) {
1553                         var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1554                         var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1555                         var itemHeight = o.height, itemWidth = o.width;
1556                         var itemTop = o.top, itemLeft = o.left;
1557
1558                         return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1559                 };
1560
1561                 $.each(inst.sortables, function(i) {
1562                         
1563                         //Copy over some variables to allow calling the sortable's native _intersectsWith
1564                         this.instance.positionAbs = inst.positionAbs;
1565                         this.instance.helperProportions = inst.helperProportions;
1566                         this.instance.offset.click = inst.offset.click;
1567                         
1568                         if(this.instance._intersectsWith(this.instance.containerCache)) {
1569
1570                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1571                                 if(!this.instance.isOver) {
1572
1573                                         this.instance.isOver = 1;
1574                                         //Now we fake the start of dragging for the sortable instance,
1575                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1576                                         //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)
1577                                         this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1578                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1579                                         this.instance.options.helper = function() { return ui.helper[0]; };
1580
1581                                         event.target = this.instance.currentItem[0];
1582                                         this.instance._mouseCapture(event, true);
1583                                         this.instance._mouseStart(event, true, true);
1584
1585                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1586                                         this.instance.offset.click.top = inst.offset.click.top;
1587                                         this.instance.offset.click.left = inst.offset.click.left;
1588                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1589                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1590
1591                                         inst._trigger("toSortable", event);
1592                                         inst.dropped = this.instance.element; //draggable revert needs that
1593                                         //hack so receive/update callbacks work (mostly)
1594                                         inst.currentItem = inst.element;
1595                                         this.instance.fromOutside = inst;
1596
1597                                 }
1598
1599                                 //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
1600                                 if(this.instance.currentItem) this.instance._mouseDrag(event);
1601
1602                         } else {
1603
1604                                 //If it doesn't intersect with the sortable, and it intersected before,
1605                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1606                                 if(this.instance.isOver) {
1607
1608                                         this.instance.isOver = 0;
1609                                         this.instance.cancelHelperRemoval = true;
1610                                         
1611                                         //Prevent reverting on this forced stop
1612                                         this.instance.options.revert = false;
1613                                         
1614                                         // The out event needs to be triggered independently
1615                                         this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1616                                         
1617                                         this.instance._mouseStop(event, true);
1618                                         this.instance.options.helper = this.instance.options._helper;
1619
1620                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1621                                         this.instance.currentItem.remove();
1622                                         if(this.instance.placeholder) this.instance.placeholder.remove();
1623
1624                                         inst._trigger("fromSortable", event);
1625                                         inst.dropped = false; //draggable revert needs that
1626                                 }
1627
1628                         };
1629
1630                 });
1631
1632         }
1633 });
1634
1635 $.ui.plugin.add("draggable", "cursor", {
1636         start: function(event, ui) {
1637                 var t = $('body'), o = $(this).data('draggable').options;
1638                 if (t.css("cursor")) o._cursor = t.css("cursor");
1639                 t.css("cursor", o.cursor);
1640         },
1641         stop: function(event, ui) {
1642                 var o = $(this).data('draggable').options;
1643                 if (o._cursor) $('body').css("cursor", o._cursor);
1644         }
1645 });
1646
1647 $.ui.plugin.add("draggable", "opacity", {
1648         start: function(event, ui) {
1649                 var t = $(ui.helper), o = $(this).data('draggable').options;
1650                 if(t.css("opacity")) o._opacity = t.css("opacity");
1651                 t.css('opacity', o.opacity);
1652         },
1653         stop: function(event, ui) {
1654                 var o = $(this).data('draggable').options;
1655                 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1656         }
1657 });
1658
1659 $.ui.plugin.add("draggable", "scroll", {
1660         start: function(event, ui) {
1661                 var i = $(this).data("draggable");
1662                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1663         },
1664         drag: function(event, ui) {
1665
1666                 var i = $(this).data("draggable"), o = i.options, scrolled = false;
1667
1668                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1669
1670                         if(!o.axis || o.axis != 'x') {
1671                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1672                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1673                                 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1674                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1675                         }
1676
1677                         if(!o.axis || o.axis != 'y') {
1678                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1679                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1680                                 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1681                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1682                         }
1683
1684                 } else {
1685
1686                         if(!o.axis || o.axis != 'x') {
1687                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1688                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1689                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1690                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1691                         }
1692
1693                         if(!o.axis || o.axis != 'y') {
1694                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1695                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1696                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1697                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1698                         }
1699
1700                 }
1701
1702                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1703                         $.ui.ddmanager.prepareOffsets(i, event);
1704
1705         }
1706 });
1707
1708 $.ui.plugin.add("draggable", "snap", {
1709         start: function(event, ui) {
1710
1711                 var i = $(this).data("draggable"), o = i.options;
1712                 i.snapElements = [];
1713
1714                 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1715                         var $t = $(this); var $o = $t.offset();
1716                         if(this != i.element[0]) i.snapElements.push({
1717                                 item: this,
1718                                 width: $t.outerWidth(), height: $t.outerHeight(),
1719                                 top: $o.top, left: $o.left
1720                         });
1721                 });
1722
1723         },
1724         drag: function(event, ui) {
1725
1726                 var inst = $(this).data("draggable"), o = inst.options;
1727                 var d = o.snapTolerance;
1728
1729                 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1730                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1731
1732                 for (var i = inst.snapElements.length - 1; i >= 0; i--){
1733
1734                         var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1735                                 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1736
1737                         //Yes, I know, this is insane ;)
1738                         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))) {
1739                                 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 })));
1740                                 inst.snapElements[i].snapping = false;
1741                                 continue;
1742                         }
1743
1744                         if(o.snapMode != 'inner') {
1745                                 var ts = Math.abs(t - y2) <= d;
1746                                 var bs = Math.abs(b - y1) <= d;
1747                                 var ls = Math.abs(l - x2) <= d;
1748                                 var rs = Math.abs(r - x1) <= d;
1749                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1750                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1751                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1752                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1753                         }
1754
1755                         var first = (ts || bs || ls || rs);
1756
1757                         if(o.snapMode != 'outer') {
1758                                 var ts = Math.abs(t - y1) <= d;
1759                                 var bs = Math.abs(b - y2) <= d;
1760                                 var ls = Math.abs(l - x1) <= d;
1761                                 var rs = Math.abs(r - x2) <= d;
1762                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1763                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1764                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1765                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1766                         }
1767
1768                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1769                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1770                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1771
1772                 };
1773
1774         }
1775 });
1776
1777 $.ui.plugin.add("draggable", "stack", {
1778         start: function(event, ui) {
1779
1780                 var o = $(this).data("draggable").options;
1781
1782                 var group = $.makeArray($(o.stack)).sort(function(a,b) {
1783                         return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1784                 });
1785                 if (!group.length) { return; }
1786                 
1787                 var min = parseInt(group[0].style.zIndex) || 0;
1788                 $(group).each(function(i) {
1789                         this.style.zIndex = min + i;
1790                 });
1791
1792                 this[0].style.zIndex = min + group.length;
1793
1794         }
1795 });
1796
1797 $.ui.plugin.add("draggable", "zIndex", {
1798         start: function(event, ui) {
1799                 var t = $(ui.helper), o = $(this).data("draggable").options;
1800                 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1801                 t.css('zIndex', o.zIndex);
1802         },
1803         stop: function(event, ui) {
1804                 var o = $(this).data("draggable").options;
1805                 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1806         }
1807 });
1808
1809 })(jQuery);
1810 /*
1811  * jQuery UI Droppable 1.8.14
1812  *
1813  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1814  * Dual licensed under the MIT or GPL Version 2 licenses.
1815  * http://jquery.org/license
1816  *
1817  * http://docs.jquery.com/UI/Droppables
1818  *
1819  * Depends:
1820  *      jquery.ui.core.js
1821  *      jquery.ui.widget.js
1822  *      jquery.ui.mouse.js
1823  *      jquery.ui.draggable.js
1824  */
1825 (function( $, undefined ) {
1826
1827 $.widget("ui.droppable", {
1828         widgetEventPrefix: "drop",
1829         options: {
1830                 accept: '*',
1831                 activeClass: false,
1832                 addClasses: true,
1833                 greedy: false,
1834                 hoverClass: false,
1835                 scope: 'default',
1836                 tolerance: 'intersect'
1837         },
1838         _create: function() {
1839
1840                 var o = this.options, accept = o.accept;
1841                 this.isover = 0; this.isout = 1;
1842
1843                 this.accept = $.isFunction(accept) ? accept : function(d) {
1844                         return d.is(accept);
1845                 };
1846
1847                 //Store the droppable's proportions
1848                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1849
1850                 // Add the reference and positions to the manager
1851                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1852                 $.ui.ddmanager.droppables[o.scope].push(this);
1853
1854                 (o.addClasses && this.element.addClass("ui-droppable"));
1855
1856         },
1857
1858         destroy: function() {
1859                 var drop = $.ui.ddmanager.droppables[this.options.scope];
1860                 for ( var i = 0; i < drop.length; i++ )
1861                         if ( drop[i] == this )
1862                                 drop.splice(i, 1);
1863
1864                 this.element
1865                         .removeClass("ui-droppable ui-droppable-disabled")
1866                         .removeData("droppable")
1867                         .unbind(".droppable");
1868
1869                 return this;
1870         },
1871
1872         _setOption: function(key, value) {
1873
1874                 if(key == 'accept') {
1875                         this.accept = $.isFunction(value) ? value : function(d) {
1876                                 return d.is(value);
1877                         };
1878                 }
1879                 $.Widget.prototype._setOption.apply(this, arguments);
1880         },
1881
1882         _activate: function(event) {
1883                 var draggable = $.ui.ddmanager.current;
1884                 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1885                 (draggable && this._trigger('activate', event, this.ui(draggable)));
1886         },
1887
1888         _deactivate: function(event) {
1889                 var draggable = $.ui.ddmanager.current;
1890                 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1891                 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
1892         },
1893
1894         _over: function(event) {
1895
1896                 var draggable = $.ui.ddmanager.current;
1897                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1898
1899                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1900                         if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1901                         this._trigger('over', event, this.ui(draggable));
1902                 }
1903
1904         },
1905
1906         _out: function(event) {
1907
1908                 var draggable = $.ui.ddmanager.current;
1909                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1910
1911                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1912                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1913                         this._trigger('out', event, this.ui(draggable));
1914                 }
1915
1916         },
1917
1918         _drop: function(event,custom) {
1919
1920                 var draggable = custom || $.ui.ddmanager.current;
1921                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1922
1923                 var childrenIntersection = false;
1924                 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1925                         var inst = $.data(this, 'droppable');
1926                         if(
1927                                 inst.options.greedy
1928                                 && !inst.options.disabled
1929                                 && inst.options.scope == draggable.options.scope
1930                                 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1931                                 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1932                         ) { childrenIntersection = true; return false; }
1933                 });
1934                 if(childrenIntersection) return false;
1935
1936                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1937                         if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1938                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1939                         this._trigger('drop', event, this.ui(draggable));
1940                         return this.element;
1941                 }
1942
1943                 return false;
1944
1945         },
1946
1947         ui: function(c) {
1948                 return {
1949                         draggable: (c.currentItem || c.element),
1950                         helper: c.helper,
1951                         position: c.position,
1952                         offset: c.positionAbs
1953                 };
1954         }
1955
1956 });
1957
1958 $.extend($.ui.droppable, {
1959         version: "1.8.14"
1960 });
1961
1962 $.ui.intersect = function(draggable, droppable, toleranceMode) {
1963
1964         if (!droppable.offset) return false;
1965
1966         var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1967                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1968         var l = droppable.offset.left, r = l + droppable.proportions.width,
1969                 t = droppable.offset.top, b = t + droppable.proportions.height;
1970
1971         switch (toleranceMode) {
1972                 case 'fit':
1973                         return (l <= x1 && x2 <= r
1974                                 && t <= y1 && y2 <= b);
1975                         break;
1976                 case 'intersect':
1977                         return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1978                                 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
1979                                 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1980                                 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1981                         break;
1982                 case 'pointer':
1983                         var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1984                                 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1985                                 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1986                         return isOver;
1987                         break;
1988                 case 'touch':
1989                         return (
1990                                         (y1 >= t && y1 <= b) || // Top edge touching
1991                                         (y2 >= t && y2 <= b) || // Bottom edge touching
1992                                         (y1 < t && y2 > b)              // Surrounded vertically
1993                                 ) && (
1994                                         (x1 >= l && x1 <= r) || // Left edge touching
1995                                         (x2 >= l && x2 <= r) || // Right edge touching
1996                                         (x1 < l && x2 > r)              // Surrounded horizontally
1997                                 );
1998                         break;
1999                 default:
2000                         return false;
2001                         break;
2002                 }
2003
2004 };
2005
2006 /*
2007         This manager tracks offsets of draggables and droppables
2008 */
2009 $.ui.ddmanager = {
2010         current: null,
2011         droppables: { 'default': [] },
2012         prepareOffsets: function(t, event) {
2013
2014                 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2015                 var type = event ? event.type : null; // workaround for #2317
2016                 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2017
2018                 droppablesLoop: for (var i = 0; i < m.length; i++) {
2019
2020                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;   //No disabled and non-accepted
2021                         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
2022                         m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                       //If the element is not visible, continue
2023
2024                         if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2025
2026                         m[i].offset = m[i].element.offset();
2027                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2028
2029                 }
2030
2031         },
2032         drop: function(draggable, event) {
2033
2034                 var dropped = false;
2035                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2036
2037                         if(!this.options) return;
2038                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2039                                 dropped = dropped || this._drop.call(this, event);
2040
2041                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2042                                 this.isout = 1; this.isover = 0;
2043                                 this._deactivate.call(this, event);
2044                         }
2045
2046                 });
2047                 return dropped;
2048
2049         },
2050         dragStart: function( draggable, event ) {
2051                 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2052                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2053                         if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2054                 });
2055         },
2056         drag: function(draggable, event) {
2057
2058                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2059                 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2060
2061                 //Run through all droppables and check their positions based on specific tolerance options
2062                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2063
2064                         if(this.options.disabled || this.greedyChild || !this.visible) return;
2065                         var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2066
2067                         var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2068                         if(!c) return;
2069
2070                         var parentInstance;
2071                         if (this.options.greedy) {
2072                                 var parent = this.element.parents(':data(droppable):eq(0)');
2073                                 if (parent.length) {
2074                                         parentInstance = $.data(parent[0], 'droppable');
2075                                         parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2076                                 }
2077                         }
2078
2079                         // we just moved into a greedy child
2080                         if (parentInstance && c == 'isover') {
2081                                 parentInstance['isover'] = 0;
2082                                 parentInstance['isout'] = 1;
2083                                 parentInstance._out.call(parentInstance, event);
2084                         }
2085
2086                         this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2087                         this[c == "isover" ? "_over" : "_out"].call(this, event);
2088
2089                         // we just moved out of a greedy child
2090                         if (parentInstance && c == 'isout') {
2091                                 parentInstance['isout'] = 0;
2092                                 parentInstance['isover'] = 1;
2093                                 parentInstance._over.call(parentInstance, event);
2094                         }
2095                 });
2096
2097         },
2098         dragStop: function( draggable, event ) {
2099                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2100                 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2101                 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2102         }
2103 };
2104
2105 })(jQuery);
2106 /*
2107  * jQuery UI Resizable 1.8.14
2108  *
2109  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2110  * Dual licensed under the MIT or GPL Version 2 licenses.
2111  * http://jquery.org/license
2112  *
2113  * http://docs.jquery.com/UI/Resizables
2114  *
2115  * Depends:
2116  *      jquery.ui.core.js
2117  *      jquery.ui.mouse.js
2118  *      jquery.ui.widget.js
2119  */
2120 (function( $, undefined ) {
2121
2122 $.widget("ui.resizable", $.ui.mouse, {
2123         widgetEventPrefix: "resize",
2124         options: {
2125                 alsoResize: false,
2126                 animate: false,
2127                 animateDuration: "slow",
2128                 animateEasing: "swing",
2129                 aspectRatio: false,
2130                 autoHide: false,
2131                 containment: false,
2132                 ghost: false,
2133                 grid: false,
2134                 handles: "e,s,se",
2135                 helper: false,
2136                 maxHeight: null,
2137                 maxWidth: null,
2138                 minHeight: 10,
2139                 minWidth: 10,
2140                 zIndex: 1000
2141         },
2142         _create: function() {
2143
2144                 var self = this, o = this.options;
2145                 this.element.addClass("ui-resizable");
2146
2147                 $.extend(this, {
2148                         _aspectRatio: !!(o.aspectRatio),
2149                         aspectRatio: o.aspectRatio,
2150                         originalElement: this.element,
2151                         _proportionallyResizeElements: [],
2152                         _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2153                 });
2154
2155                 //Wrap the element if it cannot hold child nodes
2156                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2157
2158                         //Opera fix for relative positioning
2159                         if (/relative/.test(this.element.css('position')) && $.browser.opera)
2160                                 this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
2161
2162                         //Create a wrapper element and set the wrapper to the new current internal element
2163                         this.element.wrap(
2164                                 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2165                                         position: this.element.css('position'),
2166                                         width: this.element.outerWidth(),
2167                                         height: this.element.outerHeight(),
2168                                         top: this.element.css('top'),
2169                                         left: this.element.css('left')
2170                                 })
2171                         );
2172
2173                         //Overwrite the original this.element
2174                         this.element = this.element.parent().data(
2175                                 "resizable", this.element.data('resizable')
2176                         );
2177
2178                         this.elementIsWrapper = true;
2179
2180                         //Move margins to the wrapper
2181                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2182                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2183
2184                         //Prevent Safari textarea resize
2185                         this.originalResizeStyle = this.originalElement.css('resize');
2186                         this.originalElement.css('resize', 'none');
2187
2188                         //Push the actual element to our proportionallyResize internal array
2189                         this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2190
2191                         // avoid IE jump (hard set the margin)
2192                         this.originalElement.css({ margin: this.originalElement.css('margin') });
2193
2194                         // fix handlers offset
2195                         this._proportionallyResize();
2196
2197                 }
2198
2199                 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' });
2200                 if(this.handles.constructor == String) {
2201
2202                         if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2203                         var n = this.handles.split(","); this.handles = {};
2204
2205                         for(var i = 0; i < n.length; i++) {
2206
2207                                 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2208                                 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2209
2210                                 // increase zIndex of sw, se, ne, nw axis
2211                                 //TODO : this modifies original option
2212                                 if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
2213
2214                                 //TODO : What's going on here?
2215                                 if ('se' == handle) {
2216                                         axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2217                                 };
2218
2219                                 //Insert into internal handles object and append to element
2220                                 this.handles[handle] = '.ui-resizable-'+handle;
2221                                 this.element.append(axis);
2222                         }
2223
2224                 }
2225
2226                 this._renderAxis = function(target) {
2227
2228                         target = target || this.element;
2229
2230                         for(var i in this.handles) {
2231
2232                                 if(this.handles[i].constructor == String)
2233                                         this.handles[i] = $(this.handles[i], this.element).show();
2234
2235                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2236                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2237
2238                                         var axis = $(this.handles[i], this.element), padWrapper = 0;
2239
2240                                         //Checking the correct pad and border
2241                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2242
2243                                         //The padding type i have to apply...
2244                                         var padPos = [ 'padding',
2245                                                 /ne|nw|n/.test(i) ? 'Top' :
2246                                                 /se|sw|s/.test(i) ? 'Bottom' :
2247                                                 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
2248
2249                                         target.css(padPos, padWrapper);
2250
2251                                         this._proportionallyResize();
2252
2253                                 }
2254
2255                                 //TODO: What's that good for? There's not anything to be executed left
2256                                 if(!$(this.handles[i]).length)
2257                                         continue;
2258
2259                         }
2260                 };
2261
2262                 //TODO: make renderAxis a prototype function
2263                 this._renderAxis(this.element);
2264
2265                 this._handles = $('.ui-resizable-handle', this.element)
2266                         .disableSelection();
2267
2268                 //Matching axis name
2269                 this._handles.mouseover(function() {
2270                         if (!self.resizing) {
2271                                 if (this.className)
2272                                         var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2273                                 //Axis, default = se
2274                                 self.axis = axis && axis[1] ? axis[1] : 'se';
2275                         }
2276                 });
2277
2278                 //If we want to auto hide the elements
2279                 if (o.autoHide) {
2280                         this._handles.hide();
2281                         $(this.element)
2282                                 .addClass("ui-resizable-autohide")
2283                                 .hover(function() {
2284                                         if (o.disabled) return;
2285                                         $(this).removeClass("ui-resizable-autohide");
2286                                         self._handles.show();
2287                                 },
2288                                 function(){
2289                                         if (o.disabled) return;
2290                                         if (!self.resizing) {
2291                                                 $(this).addClass("ui-resizable-autohide");
2292                                                 self._handles.hide();
2293                                         }
2294                                 });
2295                 }
2296
2297                 //Initialize the mouse interaction
2298                 this._mouseInit();
2299
2300         },
2301
2302         destroy: function() {
2303
2304                 this._mouseDestroy();
2305
2306                 var _destroy = function(exp) {
2307                         $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2308                                 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2309                 };
2310
2311                 //TODO: Unwrap at same DOM position
2312                 if (this.elementIsWrapper) {
2313                         _destroy(this.element);
2314                         var wrapper = this.element;
2315                         wrapper.after(
2316                                 this.originalElement.css({
2317                                         position: wrapper.css('position'),
2318                                         width: wrapper.outerWidth(),
2319                                         height: wrapper.outerHeight(),
2320                                         top: wrapper.css('top'),
2321                                         left: wrapper.css('left')
2322                                 })
2323                         ).remove();
2324                 }
2325
2326                 this.originalElement.css('resize', this.originalResizeStyle);
2327                 _destroy(this.originalElement);
2328
2329                 return this;
2330         },
2331
2332         _mouseCapture: function(event) {
2333                 var handle = false;
2334                 for (var i in this.handles) {
2335                         if ($(this.handles[i])[0] == event.target) {
2336                                 handle = true;
2337                         }
2338                 }
2339
2340                 return !this.options.disabled && handle;
2341         },
2342
2343         _mouseStart: function(event) {
2344
2345                 var o = this.options, iniPos = this.element.position(), el = this.element;
2346
2347                 this.resizing = true;
2348                 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2349
2350                 // bugfix for http://dev.jquery.com/ticket/1749
2351                 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2352                         el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2353                 }
2354
2355                 //Opera fixing relative position
2356                 if ($.browser.opera && (/relative/).test(el.css('position')))
2357                         el.css({ position: 'relative', top: 'auto', left: 'auto' });
2358
2359                 this._renderProxy();
2360
2361                 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2362
2363                 if (o.containment) {
2364                         curleft += $(o.containment).scrollLeft() || 0;
2365                         curtop += $(o.containment).scrollTop() || 0;
2366                 }
2367
2368                 //Store needed variables
2369                 this.offset = this.helper.offset();
2370                 this.position = { left: curleft, top: curtop };
2371                 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2372                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2373                 this.originalPosition = { left: curleft, top: curtop };
2374                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2375                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2376
2377                 //Aspect Ratio
2378                 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2379
2380             var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2381             $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2382
2383                 el.addClass("ui-resizable-resizing");
2384                 this._propagate("start", event);
2385                 return true;
2386         },
2387
2388         _mouseDrag: function(event) {
2389
2390                 //Increase performance, avoid regex
2391                 var el = this.helper, o = this.options, props = {},
2392                         self = this, smp = this.originalMousePosition, a = this.axis;
2393
2394                 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2395                 var trigger = this._change[a];
2396                 if (!trigger) return false;
2397
2398                 // Calculate the attrs that will be change
2399                 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2400
2401                 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2402                 this._updateVirtualBoundaries(event.shiftKey);
2403                 if (this._aspectRatio || event.shiftKey)
2404                         data = this._updateRatio(data, event);
2405
2406                 data = this._respectSize(data, event);
2407
2408                 // plugins callbacks need to be called first
2409                 this._propagate("resize", event);
2410
2411                 el.css({
2412                         top: this.position.top + "px", left: this.position.left + "px",
2413                         width: this.size.width + "px", height: this.size.height + "px"
2414                 });
2415
2416                 if (!this._helper && this._proportionallyResizeElements.length)
2417                         this._proportionallyResize();
2418
2419                 this._updateCache(data);
2420
2421                 // calling the user callback at the end
2422                 this._trigger('resize', event, this.ui());
2423
2424                 return false;
2425         },
2426
2427         _mouseStop: function(event) {
2428
2429                 this.resizing = false;
2430                 var o = this.options, self = this;
2431
2432                 if(this._helper) {
2433                         var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2434                                 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2435                                 soffsetw = ista ? 0 : self.sizeDiff.width;
2436
2437                         var s = { width: (self.helper.width()  - soffsetw), height: (self.helper.height() - soffseth) },
2438                                 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2439                                 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2440
2441                         if (!o.animate)
2442                                 this.element.css($.extend(s, { top: top, left: left }));
2443
2444                         self.helper.height(self.size.height);
2445                         self.helper.width(self.size.width);
2446
2447                         if (this._helper && !o.animate) this._proportionallyResize();
2448                 }
2449
2450                 $('body').css('cursor', 'auto');
2451
2452                 this.element.removeClass("ui-resizable-resizing");
2453
2454                 this._propagate("stop", event);
2455
2456                 if (this._helper) this.helper.remove();
2457                 return false;
2458
2459         },
2460
2461     _updateVirtualBoundaries: function(forceAspectRatio) {
2462         var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2463
2464         b = {
2465             minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2466             maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2467             minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2468             maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2469         };
2470
2471         if(this._aspectRatio || forceAspectRatio) {
2472             // We want to create an enclosing box whose aspect ration is the requested one
2473             // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2474             pMinWidth = b.minHeight * this.aspectRatio;
2475             pMinHeight = b.minWidth / this.aspectRatio;
2476             pMaxWidth = b.maxHeight * this.aspectRatio;
2477             pMaxHeight = b.maxWidth / this.aspectRatio;
2478
2479             if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2480             if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2481             if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2482             if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2483         }
2484         this._vBoundaries = b;
2485     },
2486
2487         _updateCache: function(data) {
2488                 var o = this.options;
2489                 this.offset = this.helper.offset();
2490                 if (isNumber(data.left)) this.position.left = data.left;
2491                 if (isNumber(data.top)) this.position.top = data.top;
2492                 if (isNumber(data.height)) this.size.height = data.height;
2493                 if (isNumber(data.width)) this.size.width = data.width;
2494         },
2495
2496         _updateRatio: function(data, event) {
2497
2498                 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2499
2500                 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2501                 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2502
2503                 if (a == 'sw') {
2504                         data.left = cpos.left + (csize.width - data.width);
2505                         data.top = null;
2506                 }
2507                 if (a == 'nw') {
2508                         data.top = cpos.top + (csize.height - data.height);
2509                         data.left = cpos.left + (csize.width - data.width);
2510                 }
2511
2512                 return data;
2513         },
2514
2515         _respectSize: function(data, event) {
2516
2517                 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2518                                 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2519                                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2520
2521                 if (isminw) data.width = o.minWidth;
2522                 if (isminh) data.height = o.minHeight;
2523                 if (ismaxw) data.width = o.maxWidth;
2524                 if (ismaxh) data.height = o.maxHeight;
2525
2526                 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2527                 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2528
2529                 if (isminw && cw) data.left = dw - o.minWidth;
2530                 if (ismaxw && cw) data.left = dw - o.maxWidth;
2531                 if (isminh && ch)       data.top = dh - o.minHeight;
2532                 if (ismaxh && ch)       data.top = dh - o.maxHeight;
2533
2534                 // fixing jump error on top/left - bug #2330
2535                 var isNotwh = !data.width && !data.height;
2536                 if (isNotwh && !data.left && data.top) data.top = null;
2537                 else if (isNotwh && !data.top && data.left) data.left = null;
2538
2539                 return data;
2540         },
2541
2542         _proportionallyResize: function() {
2543
2544                 var o = this.options;
2545                 if (!this._proportionallyResizeElements.length) return;
2546                 var element = this.helper || this.element;
2547
2548                 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2549
2550                         var prel = this._proportionallyResizeElements[i];
2551
2552                         if (!this.borderDif) {
2553                                 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2554                                         p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2555
2556                                 this.borderDif = $.map(b, function(v, i) {
2557                                         var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2558                                         return border + padding;
2559                                 });
2560                         }
2561
2562                         if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2563                                 continue;
2564
2565                         prel.css({
2566                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2567                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2568                         });
2569
2570                 };
2571
2572         },
2573
2574         _renderProxy: function() {
2575
2576                 var el = this.element, o = this.options;
2577                 this.elementOffset = el.offset();
2578
2579                 if(this._helper) {
2580
2581                         this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2582
2583                         // fix ie6 offset TODO: This seems broken
2584                         var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2585                         pxyoffset = ( ie6 ? 2 : -1 );
2586
2587                         this.helper.addClass(this._helper).css({
2588                                 width: this.element.outerWidth() + pxyoffset,
2589                                 height: this.element.outerHeight() + pxyoffset,
2590                                 position: 'absolute',
2591                                 left: this.elementOffset.left - ie6offset +'px',
2592                                 top: this.elementOffset.top - ie6offset +'px',
2593                                 zIndex: ++o.zIndex //TODO: Don't modify option
2594                         });
2595
2596                         this.helper
2597                                 .appendTo("body")
2598                                 .disableSelection();
2599
2600                 } else {
2601                         this.helper = this.element;
2602                 }
2603
2604         },
2605
2606         _change: {
2607                 e: function(event, dx, dy) {
2608                         return { width: this.originalSize.width + dx };
2609                 },
2610                 w: function(event, dx, dy) {
2611                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2612                         return { left: sp.left + dx, width: cs.width - dx };
2613                 },
2614                 n: function(event, dx, dy) {
2615                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2616                         return { top: sp.top + dy, height: cs.height - dy };
2617                 },
2618                 s: function(event, dx, dy) {
2619                         return { height: this.originalSize.height + dy };
2620                 },
2621                 se: function(event, dx, dy) {
2622                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2623                 },
2624                 sw: function(event, dx, dy) {
2625                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2626                 },
2627                 ne: function(event, dx, dy) {
2628                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2629                 },
2630                 nw: function(event, dx, dy) {
2631                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2632                 }
2633         },
2634
2635         _propagate: function(n, event) {
2636                 $.ui.plugin.call(this, n, [event, this.ui()]);
2637                 (n != "resize" && this._trigger(n, event, this.ui()));
2638         },
2639
2640         plugins: {},
2641
2642         ui: function() {
2643                 return {
2644                         originalElement: this.originalElement,
2645                         element: this.element,
2646                         helper: this.helper,
2647                         position: this.position,
2648                         size: this.size,
2649                         originalSize: this.originalSize,
2650                         originalPosition: this.originalPosition
2651                 };
2652         }
2653
2654 });
2655
2656 $.extend($.ui.resizable, {
2657         version: "1.8.14"
2658 });
2659
2660 /*
2661  * Resizable Extensions
2662  */
2663
2664 $.ui.plugin.add("resizable", "alsoResize", {
2665
2666         start: function (event, ui) {
2667                 var self = $(this).data("resizable"), o = self.options;
2668
2669                 var _store = function (exp) {
2670                         $(exp).each(function() {
2671                                 var el = $(this);
2672                                 el.data("resizable-alsoresize", {
2673                                         width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2674                                         left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
2675                                         position: el.css('position') // to reset Opera on stop()
2676                                 });
2677                         });
2678                 };
2679
2680                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2681                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2682                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2683                 }else{
2684                         _store(o.alsoResize);
2685                 }
2686         },
2687
2688         resize: function (event, ui) {
2689                 var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2690
2691                 var delta = {
2692                         height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2693                         top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2694                 },
2695
2696                 _alsoResize = function (exp, c) {
2697                         $(exp).each(function() {
2698                                 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 
2699                                         css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2700
2701                                 $.each(css, function (i, prop) {
2702                                         var sum = (start[prop]||0) + (delta[prop]||0);
2703                                         if (sum && sum >= 0)
2704                                                 style[prop] = sum || null;
2705                                 });
2706
2707                                 // Opera fixing relative position
2708                                 if ($.browser.opera && /relative/.test(el.css('position'))) {
2709                                         self._revertToRelativePosition = true;
2710                                         el.css({ position: 'absolute', top: 'auto', left: 'auto' });
2711                                 }
2712
2713                                 el.css(style);
2714                         });
2715                 };
2716
2717                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2718                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2719                 }else{
2720                         _alsoResize(o.alsoResize);
2721                 }
2722         },
2723
2724         stop: function (event, ui) {
2725                 var self = $(this).data("resizable"), o = self.options;
2726
2727                 var _reset = function (exp) {
2728                         $(exp).each(function() {
2729                                 var el = $(this);
2730                                 // reset position for Opera - no need to verify it was changed
2731                                 el.css({ position: el.data("resizable-alsoresize").position });
2732                         });
2733                 };
2734
2735                 if (self._revertToRelativePosition) {
2736                         self._revertToRelativePosition = false;
2737                         if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2738                                 $.each(o.alsoResize, function (exp) { _reset(exp); });
2739                         }else{
2740                                 _reset(o.alsoResize);
2741                         }
2742                 }
2743
2744                 $(this).removeData("resizable-alsoresize");
2745         }
2746 });
2747
2748 $.ui.plugin.add("resizable", "animate", {
2749
2750         stop: function(event, ui) {
2751                 var self = $(this).data("resizable"), o = self.options;
2752
2753                 var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2754                                         soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2755                                                 soffsetw = ista ? 0 : self.sizeDiff.width;
2756
2757                 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2758                                         left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2759                                                 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2760
2761                 self.element.animate(
2762                         $.extend(style, top && left ? { top: top, left: left } : {}), {
2763                                 duration: o.animateDuration,
2764                                 easing: o.animateEasing,
2765                                 step: function() {
2766
2767                                         var data = {
2768                                                 width: parseInt(self.element.css('width'), 10),
2769                                                 height: parseInt(self.element.css('height'), 10),
2770                                                 top: parseInt(self.element.css('top'), 10),
2771                                                 left: parseInt(self.element.css('left'), 10)
2772                                         };
2773
2774                                         if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2775
2776                                         // propagating resize, and updating values for each animation step
2777                                         self._updateCache(data);
2778                                         self._propagate("resize", event);
2779
2780                                 }
2781                         }
2782                 );
2783         }
2784
2785 });
2786
2787 $.ui.plugin.add("resizable", "containment", {
2788
2789         start: function(event, ui) {
2790                 var self = $(this).data("resizable"), o = self.options, el = self.element;
2791                 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2792                 if (!ce) return;
2793
2794                 self.containerElement = $(ce);
2795
2796                 if (/document/.test(oc) || oc == document) {
2797                         self.containerOffset = { left: 0, top: 0 };
2798                         self.containerPosition = { left: 0, top: 0 };
2799
2800                         self.parentData = {
2801                                 element: $(document), left: 0, top: 0,
2802                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2803                         };
2804                 }
2805
2806                 // i'm a node, so compute top, left, right, bottom
2807                 else {
2808                         var element = $(ce), p = [];
2809                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2810
2811                         self.containerOffset = element.offset();
2812                         self.containerPosition = element.position();
2813                         self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2814
2815                         var co = self.containerOffset, ch = self.containerSize.height,  cw = self.containerSize.width,
2816                                                 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2817
2818                         self.parentData = {
2819                                 element: ce, left: co.left, top: co.top, width: width, height: height
2820                         };
2821                 }
2822         },
2823
2824         resize: function(event, ui) {
2825                 var self = $(this).data("resizable"), o = self.options,
2826                                 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2827                                 pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2828
2829                 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2830
2831                 if (cp.left < (self._helper ? co.left : 0)) {
2832                         self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2833                         if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2834                         self.position.left = o.helper ? co.left : 0;
2835                 }
2836
2837                 if (cp.top < (self._helper ? co.top : 0)) {
2838                         self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2839                         if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2840                         self.position.top = self._helper ? co.top : 0;
2841                 }
2842
2843                 self.offset.left = self.parentData.left+self.position.left;
2844                 self.offset.top = self.parentData.top+self.position.top;
2845
2846                 var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2847                                         hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2848
2849                 var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2850                     isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2851
2852                 if(isParent && isOffsetRelative) woset -= self.parentData.left;
2853
2854                 if (woset + self.size.width >= self.parentData.width) {
2855                         self.size.width = self.parentData.width - woset;
2856                         if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2857                 }
2858
2859                 if (hoset + self.size.height >= self.parentData.height) {
2860                         self.size.height = self.parentData.height - hoset;
2861                         if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2862                 }
2863         },
2864
2865         stop: function(event, ui){
2866                 var self = $(this).data("resizable"), o = self.options, cp = self.position,
2867                                 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2868
2869                 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2870
2871                 if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2872                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2873
2874                 if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2875                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2876
2877         }
2878 });
2879
2880 $.ui.plugin.add("resizable", "ghost", {
2881
2882         start: function(event, ui) {
2883
2884                 var self = $(this).data("resizable"), o = self.options, cs = self.size;
2885
2886                 self.ghost = self.originalElement.clone();
2887                 self.ghost
2888                         .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2889                         .addClass('ui-resizable-ghost')
2890                         .addClass(typeof o.ghost == 'string' ? o.ghost : '');
2891
2892                 self.ghost.appendTo(self.helper);
2893
2894         },
2895
2896         resize: function(event, ui){
2897                 var self = $(this).data("resizable"), o = self.options;
2898                 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2899         },
2900
2901         stop: function(event, ui){
2902                 var self = $(this).data("resizable"), o = self.options;
2903                 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2904         }
2905
2906 });
2907
2908 $.ui.plugin.add("resizable", "grid", {
2909
2910         resize: function(event, ui) {
2911                 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;
2912                 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2913                 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);
2914
2915                 if (/^(se|s|e)$/.test(a)) {
2916                         self.size.width = os.width + ox;
2917                         self.size.height = os.height + oy;
2918                 }
2919                 else if (/^(ne)$/.test(a)) {
2920                         self.size.width = os.width + ox;
2921                         self.size.height = os.height + oy;
2922                         self.position.top = op.top - oy;
2923                 }
2924                 else if (/^(sw)$/.test(a)) {
2925                         self.size.width = os.width + ox;
2926                         self.size.height = os.height + oy;
2927                         self.position.left = op.left - ox;
2928                 }
2929                 else {
2930                         self.size.width = os.width + ox;
2931                         self.size.height = os.height + oy;
2932                         self.position.top = op.top - oy;
2933                         self.position.left = op.left - ox;
2934                 }
2935         }
2936
2937 });
2938
2939 var num = function(v) {
2940         return parseInt(v, 10) || 0;
2941 };
2942
2943 var isNumber = function(value) {
2944         return !isNaN(parseInt(value, 10));
2945 };
2946
2947 })(jQuery);
2948 /*
2949  * jQuery UI Selectable 1.8.14
2950  *
2951  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2952  * Dual licensed under the MIT or GPL Version 2 licenses.
2953  * http://jquery.org/license
2954  *
2955  * http://docs.jquery.com/UI/Selectables
2956  *
2957  * Depends:
2958  *      jquery.ui.core.js
2959  *      jquery.ui.mouse.js
2960  *      jquery.ui.widget.js
2961  */
2962 (function( $, undefined ) {
2963
2964 $.widget("ui.selectable", $.ui.mouse, {
2965         options: {
2966                 appendTo: 'body',
2967                 autoRefresh: true,
2968                 distance: 0,
2969                 filter: '*',
2970                 tolerance: 'touch'
2971         },
2972         _create: function() {
2973                 var self = this;
2974
2975                 this.element.addClass("ui-selectable");
2976
2977                 this.dragged = false;
2978
2979                 // cache selectee children based on filter
2980                 var selectees;
2981                 this.refresh = function() {
2982                         selectees = $(self.options.filter, self.element[0]);
2983                         selectees.each(function() {
2984                                 var $this = $(this);
2985                                 var pos = $this.offset();
2986                                 $.data(this, "selectable-item", {
2987                                         element: this,
2988                                         $element: $this,
2989                                         left: pos.left,
2990                                         top: pos.top,
2991                                         right: pos.left + $this.outerWidth(),
2992                                         bottom: pos.top + $this.outerHeight(),
2993                                         startselected: false,
2994                                         selected: $this.hasClass('ui-selected'),
2995                                         selecting: $this.hasClass('ui-selecting'),
2996                                         unselecting: $this.hasClass('ui-unselecting')
2997                                 });
2998                         });
2999                 };
3000                 this.refresh();
3001
3002                 this.selectees = selectees.addClass("ui-selectee");
3003
3004                 this._mouseInit();
3005
3006                 this.helper = $("<div class='ui-selectable-helper'></div>");
3007         },
3008
3009         destroy: function() {
3010                 this.selectees
3011                         .removeClass("ui-selectee")
3012                         .removeData("selectable-item");
3013                 this.element
3014                         .removeClass("ui-selectable ui-selectable-disabled")
3015                         .removeData("selectable")
3016                         .unbind(".selectable");
3017                 this._mouseDestroy();
3018
3019                 return this;
3020         },
3021
3022         _mouseStart: function(event) {
3023                 var self = this;
3024
3025                 this.opos = [event.pageX, event.pageY];
3026
3027                 if (this.options.disabled)
3028                         return;
3029
3030                 var options = this.options;
3031
3032                 this.selectees = $(options.filter, this.element[0]);
3033
3034                 this._trigger("start", event);
3035
3036                 $(options.appendTo).append(this.helper);
3037                 // position helper (lasso)
3038                 this.helper.css({
3039                         "left": event.clientX,
3040                         "top": event.clientY,
3041                         "width": 0,
3042                         "height": 0
3043                 });
3044
3045                 if (options.autoRefresh) {
3046                         this.refresh();
3047                 }
3048
3049                 this.selectees.filter('.ui-selected').each(function() {
3050                         var selectee = $.data(this, "selectable-item");
3051                         selectee.startselected = true;
3052                         if (!event.metaKey) {
3053                                 selectee.$element.removeClass('ui-selected');
3054                                 selectee.selected = false;
3055                                 selectee.$element.addClass('ui-unselecting');
3056                                 selectee.unselecting = true;
3057                                 // selectable UNSELECTING callback
3058                                 self._trigger("unselecting", event, {
3059                                         unselecting: selectee.element
3060                                 });
3061                         }
3062                 });
3063
3064                 $(event.target).parents().andSelf().each(function() {
3065                         var selectee = $.data(this, "selectable-item");
3066                         if (selectee) {
3067                                 var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
3068                                 selectee.$element
3069                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3070                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3071                                 selectee.unselecting = !doSelect;
3072                                 selectee.selecting = doSelect;
3073                                 selectee.selected = doSelect;
3074                                 // selectable (UN)SELECTING callback
3075                                 if (doSelect) {
3076                                         self._trigger("selecting", event, {
3077                                                 selecting: selectee.element
3078                                         });
3079                                 } else {
3080                                         self._trigger("unselecting", event, {
3081                                                 unselecting: selectee.element
3082                                         });
3083                                 }
3084                                 return false;
3085                         }
3086                 });
3087
3088         },
3089
3090         _mouseDrag: function(event) {
3091                 var self = this;
3092                 this.dragged = true;
3093
3094                 if (this.options.disabled)
3095                         return;
3096
3097                 var options = this.options;
3098
3099                 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3100                 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3101                 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3102                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3103
3104                 this.selectees.each(function() {
3105                         var selectee = $.data(this, "selectable-item");
3106                         //prevent helper from being selected if appendTo: selectable
3107                         if (!selectee || selectee.element == self.element[0])
3108                                 return;
3109                         var hit = false;
3110                         if (options.tolerance == 'touch') {
3111                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3112                         } else if (options.tolerance == 'fit') {
3113                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3114                         }
3115
3116                         if (hit) {
3117                                 // SELECT
3118                                 if (selectee.selected) {
3119                                         selectee.$element.removeClass('ui-selected');
3120                                         selectee.selected = false;
3121                                 }
3122                                 if (selectee.unselecting) {
3123                                         selectee.$element.removeClass('ui-unselecting');
3124                                         selectee.unselecting = false;
3125                                 }
3126                                 if (!selectee.selecting) {
3127                                         selectee.$element.addClass('ui-selecting');
3128                                         selectee.selecting = true;
3129                                         // selectable SELECTING callback
3130                                         self._trigger("selecting", event, {
3131                                                 selecting: selectee.element
3132                                         });
3133                                 }
3134                         } else {
3135                                 // UNSELECT
3136                                 if (selectee.selecting) {
3137                                         if (event.metaKey && selectee.startselected) {
3138                                                 selectee.$element.removeClass('ui-selecting');
3139                                                 selectee.selecting = false;
3140                                                 selectee.$element.addClass('ui-selected');
3141                                                 selectee.selected = true;
3142                                         } else {
3143                                                 selectee.$element.removeClass('ui-selecting');
3144                                                 selectee.selecting = false;
3145                                                 if (selectee.startselected) {
3146                                                         selectee.$element.addClass('ui-unselecting');
3147                                                         selectee.unselecting = true;
3148                                                 }
3149                                                 // selectable UNSELECTING callback
3150                                                 self._trigger("unselecting", event, {
3151                                                         unselecting: selectee.element
3152                                                 });
3153                                         }
3154                                 }
3155                                 if (selectee.selected) {
3156                                         if (!event.metaKey && !selectee.startselected) {
3157                                                 selectee.$element.removeClass('ui-selected');
3158                                                 selectee.selected = false;
3159
3160                                                 selectee.$element.addClass('ui-unselecting');
3161                                                 selectee.unselecting = true;
3162                                                 // selectable UNSELECTING callback
3163                                                 self._trigger("unselecting", event, {
3164                                                         unselecting: selectee.element
3165                                                 });
3166                                         }
3167                                 }
3168                         }
3169                 });
3170
3171                 return false;
3172         },
3173
3174         _mouseStop: function(event) {
3175                 var self = this;
3176
3177                 this.dragged = false;
3178
3179                 var options = this.options;
3180
3181                 $('.ui-unselecting', this.element[0]).each(function() {
3182                         var selectee = $.data(this, "selectable-item");
3183                         selectee.$element.removeClass('ui-unselecting');
3184                         selectee.unselecting = false;
3185                         selectee.startselected = false;
3186                         self._trigger("unselected", event, {
3187                                 unselected: selectee.element
3188                         });
3189                 });
3190                 $('.ui-selecting', this.element[0]).each(function() {
3191                         var selectee = $.data(this, "selectable-item");
3192                         selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3193                         selectee.selecting = false;
3194                         selectee.selected = true;
3195                         selectee.startselected = true;
3196                         self._trigger("selected", event, {
3197                                 selected: selectee.element
3198                         });
3199                 });
3200                 this._trigger("stop", event);
3201
3202                 this.helper.remove();
3203
3204                 return false;
3205         }
3206
3207 });
3208
3209 $.extend($.ui.selectable, {
3210         version: "1.8.14"
3211 });
3212
3213 })(jQuery);
3214 /*
3215  * jQuery UI Sortable 1.8.14
3216  *
3217  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
3218  * Dual licensed under the MIT or GPL Version 2 licenses.
3219  * http://jquery.org/license
3220  *
3221  * http://docs.jquery.com/UI/Sortables
3222  *
3223  * Depends:
3224  *      jquery.ui.core.js
3225  *      jquery.ui.mouse.js
3226  *      jquery.ui.widget.js
3227  */
3228 (function( $, undefined ) {
3229
3230 $.widget("ui.sortable", $.ui.mouse, {
3231         widgetEventPrefix: "sort",
3232         options: {
3233                 appendTo: "parent",
3234                 axis: false,
3235                 connectWith: false,
3236                 containment: false,
3237                 cursor: 'auto',
3238                 cursorAt: false,
3239                 dropOnEmpty: true,
3240                 forcePlaceholderSize: false,
3241                 forceHelperSize: false,
3242                 grid: false,
3243                 handle: false,
3244                 helper: "original",
3245                 items: '> *',
3246                 opacity: false,
3247                 placeholder: false,
3248                 revert: false,
3249                 scroll: true,
3250                 scrollSensitivity: 20,
3251                 scrollSpeed: 20,
3252                 scope: "default",
3253                 tolerance: "intersect",
3254                 zIndex: 1000
3255         },
3256         _create: function() {
3257
3258                 var o = this.options;
3259                 this.containerCache = {};
3260                 this.element.addClass("ui-sortable");
3261
3262                 //Get the items
3263                 this.refresh();
3264
3265                 //Let's determine if the items are being displayed horizontally
3266                 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;
3267
3268                 //Let's determine the parent's offset
3269                 this.offset = this.element.offset();
3270
3271                 //Initialize mouse events for interaction
3272                 this._mouseInit();
3273
3274         },
3275
3276         destroy: function() {
3277                 this.element
3278                         .removeClass("ui-sortable ui-sortable-disabled")
3279                         .removeData("sortable")
3280                         .unbind(".sortable");
3281                 this._mouseDestroy();
3282
3283                 for ( var i = this.items.length - 1; i >= 0; i-- )
3284                         this.items[i].item.removeData("sortable-item");
3285
3286                 return this;
3287         },
3288
3289         _setOption: function(key, value){
3290                 if ( key === "disabled" ) {
3291                         this.options[ key ] = value;
3292         
3293                         this.widget()
3294                                 [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3295                 } else {
3296                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3297                         $.Widget.prototype._setOption.apply(this, arguments);
3298                 }
3299         },
3300
3301         _mouseCapture: function(event, overrideHandle) {
3302
3303                 if (this.reverting) {
3304                         return false;
3305                 }
3306
3307                 if(this.options.disabled || this.options.type == 'static') return false;
3308
3309                 //We have to refresh the items data once first
3310                 this._refreshItems(event);
3311
3312                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3313                 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
3314                         if($.data(this, 'sortable-item') == self) {
3315                                 currentItem = $(this);
3316                                 return false;
3317                         }
3318                 });
3319                 if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
3320
3321                 if(!currentItem) return false;
3322                 if(this.options.handle && !overrideHandle) {
3323                         var validHandle = false;
3324
3325                         $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3326                         if(!validHandle) return false;
3327                 }
3328
3329                 this.currentItem = currentItem;
3330                 this._removeCurrentsFromItems();
3331                 return true;
3332
3333         },
3334
3335         _mouseStart: function(event, overrideHandle, noActivation) {
3336
3337                 var o = this.options, self = this;
3338                 this.currentContainer = this;
3339
3340                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3341                 this.refreshPositions();
3342
3343                 //Create and append the visible helper
3344                 this.helper = this._createHelper(event);
3345
3346                 //Cache the helper size
3347                 this._cacheHelperProportions();
3348
3349                 /*
3350                  * - Position generation -
3351                  * This block generates everything position related - it's the core of draggables.
3352                  */
3353
3354                 //Cache the margins of the original element
3355                 this._cacheMargins();
3356
3357                 //Get the next scrolling parent
3358                 this.scrollParent = this.helper.scrollParent();
3359
3360                 //The element's absolute position on the page minus margins
3361                 this.offset = this.currentItem.offset();
3362                 this.offset = {
3363                         top: this.offset.top - this.margins.top,
3364                         left: this.offset.left - this.margins.left
3365                 };
3366
3367                 // Only after we got the offset, we can change the helper's position to absolute
3368                 // TODO: Still need to figure out a way to make relative sorting possible
3369                 this.helper.css("position", "absolute");
3370                 this.cssPosition = this.helper.css("position");
3371
3372                 $.extend(this.offset, {
3373                         click: { //Where the click happened, relative to the element
3374                                 left: event.pageX - this.offset.left,
3375                                 top: event.pageY - this.offset.top
3376                         },
3377                         parent: this._getParentOffset(),
3378                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3379                 });
3380
3381                 //Generate the original position
3382                 this.originalPosition = this._generatePosition(event);
3383                 this.originalPageX = event.pageX;
3384                 this.originalPageY = event.pageY;
3385
3386                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3387                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3388
3389                 //Cache the former DOM position
3390                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3391
3392                 //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
3393                 if(this.helper[0] != this.currentItem[0]) {
3394                         this.currentItem.hide();
3395                 }
3396
3397                 //Create the placeholder
3398                 this._createPlaceholder();
3399
3400                 //Set a containment if given in the options
3401                 if(o.containment)
3402                         this._setContainment();
3403
3404                 if(o.cursor) { // cursor option
3405                         if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3406                         $('body').css("cursor", o.cursor);
3407                 }
3408
3409                 if(o.opacity) { // opacity option
3410                         if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3411                         this.helper.css("opacity", o.opacity);
3412                 }
3413
3414                 if(o.zIndex) { // zIndex option
3415                         if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3416                         this.helper.css("zIndex", o.zIndex);
3417                 }
3418
3419                 //Prepare scrolling
3420                 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3421                         this.overflowOffset = this.scrollParent.offset();
3422
3423                 //Call callbacks
3424                 this._trigger("start", event, this._uiHash());
3425
3426                 //Recache the helper size
3427                 if(!this._preserveHelperProportions)
3428                         this._cacheHelperProportions();
3429
3430
3431                 //Post 'activate' events to possible containers
3432                 if(!noActivation) {
3433                          for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3434                 }
3435
3436                 //Prepare possible droppables
3437                 if($.ui.ddmanager)
3438                         $.ui.ddmanager.current = this;
3439
3440                 if ($.ui.ddmanager && !o.dropBehaviour)
3441                         $.ui.ddmanager.prepareOffsets(this, event);
3442
3443                 this.dragging = true;
3444
3445                 this.helper.addClass("ui-sortable-helper");
3446                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3447                 return true;
3448
3449         },
3450
3451         _mouseDrag: function(event) {
3452
3453                 //Compute the helpers position
3454                 this.position = this._generatePosition(event);
3455                 this.positionAbs = this._convertPositionTo("absolute");
3456
3457                 if (!this.lastPositionAbs) {
3458                         this.lastPositionAbs = this.positionAbs;
3459                 }
3460
3461                 //Do scrolling
3462                 if(this.options.scroll) {
3463                         var o = this.options, scrolled = false;
3464                         if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3465
3466                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3467                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3468                                 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3469                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3470
3471                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3472                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3473                                 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3474                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3475
3476                         } else {
3477
3478                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3479                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3480                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3481                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3482
3483                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3484                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3485                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3486                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3487
3488                         }
3489
3490                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3491                                 $.ui.ddmanager.prepareOffsets(this, event);
3492                 }
3493
3494                 //Regenerate the absolute position used for position checks
3495                 this.positionAbs = this._convertPositionTo("absolute");
3496
3497                 //Set the helper position
3498                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3499                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3500
3501                 //Rearrange
3502                 for (var i = this.items.length - 1; i >= 0; i--) {
3503
3504                         //Cache variables and intersection, continue if no intersection
3505                         var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3506                         if (!intersection) continue;
3507
3508                         if(itemElement != this.currentItem[0] //cannot intersect with itself
3509                                 &&      this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3510                                 &&      !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3511                                 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3512                                 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3513                         ) {
3514
3515                                 this.direction = intersection == 1 ? "down" : "up";
3516
3517                                 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3518                                         this._rearrange(event, item);
3519                                 } else {
3520                                         break;
3521                                 }
3522
3523                                 this._trigger("change", event, this._uiHash());
3524                                 break;
3525                         }
3526                 }
3527
3528                 //Post events to containers
3529                 this._contactContainers(event);
3530
3531                 //Interconnect with droppables
3532                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3533
3534                 //Call callbacks
3535                 this._trigger('sort', event, this._uiHash());
3536
3537                 this.lastPositionAbs = this.positionAbs;
3538                 return false;
3539
3540         },
3541
3542         _mouseStop: function(event, noPropagation) {
3543
3544                 if(!event) return;
3545
3546                 //If we are using droppables, inform the manager about the drop
3547                 if ($.ui.ddmanager && !this.options.dropBehaviour)
3548                         $.ui.ddmanager.drop(this, event);
3549
3550                 if(this.options.revert) {
3551                         var self = this;
3552                         var cur = self.placeholder.offset();
3553
3554                         self.reverting = true;
3555
3556                         $(this.helper).animate({
3557                                 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3558                                 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3559                         }, parseInt(this.options.revert, 10) || 500, function() {
3560                                 self._clear(event);
3561                         });
3562                 } else {
3563                         this._clear(event, noPropagation);
3564                 }
3565
3566                 return false;
3567
3568         },
3569
3570         cancel: function() {
3571
3572                 var self = this;
3573
3574                 if(this.dragging) {
3575
3576                         this._mouseUp({ target: null });
3577
3578                         if(this.options.helper == "original")
3579                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3580                         else
3581                                 this.currentItem.show();
3582
3583                         //Post deactivating events to containers
3584                         for (var i = this.containers.length - 1; i >= 0; i--){
3585                                 this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3586                                 if(this.containers[i].containerCache.over) {
3587                                         this.containers[i]._trigger("out", null, self._uiHash(this));
3588                                         this.containers[i].containerCache.over = 0;
3589                                 }
3590                         }
3591
3592                 }
3593
3594                 if (this.placeholder) {
3595                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3596                         if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3597                         if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3598
3599                         $.extend(this, {
3600                                 helper: null,
3601                                 dragging: false,
3602                                 reverting: false,
3603                                 _noFinalSort: null
3604                         });
3605
3606                         if(this.domPosition.prev) {
3607                                 $(this.domPosition.prev).after(this.currentItem);
3608                         } else {
3609                                 $(this.domPosition.parent).prepend(this.currentItem);
3610                         }
3611                 }
3612
3613                 return this;
3614
3615         },
3616
3617         serialize: function(o) {
3618
3619                 var items = this._getItemsAsjQuery(o && o.connected);
3620                 var str = []; o = o || {};
3621
3622                 $(items).each(function() {
3623                         var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3624                         if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3625                 });
3626
3627                 if(!str.length && o.key) {
3628                         str.push(o.key + '=');
3629                 }
3630
3631                 return str.join('&');
3632
3633         },
3634
3635         toArray: function(o) {
3636
3637                 var items = this._getItemsAsjQuery(o && o.connected);
3638                 var ret = []; o = o || {};
3639
3640                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3641                 return ret;
3642
3643         },
3644
3645         /* Be careful with the following core functions */
3646         _intersectsWith: function(item) {
3647
3648                 var x1 = this.positionAbs.left,
3649                         x2 = x1 + this.helperProportions.width,
3650                         y1 = this.positionAbs.top,
3651                         y2 = y1 + this.helperProportions.height;
3652
3653                 var l = item.left,
3654                         r = l + item.width,
3655                         t = item.top,
3656                         b = t + item.height;
3657
3658                 var dyClick = this.offset.click.top,
3659                         dxClick = this.offset.click.left;
3660
3661                 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3662
3663                 if(        this.options.tolerance == "pointer"
3664                         || this.options.forcePointerForContainers
3665                         || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3666                 ) {
3667                         return isOverElement;
3668                 } else {
3669
3670                         return (l < x1 + (this.helperProportions.width / 2) // Right Half
3671                                 && x2 - (this.helperProportions.width / 2) < r // Left Half
3672                                 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3673                                 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
3674
3675                 }
3676         },
3677
3678         _intersectsWithPointer: function(item) {
3679
3680                 var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3681                         isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3682                         isOverElement = isOverElementHeight && isOverElementWidth,
3683                         verticalDirection = this._getDragVerticalDirection(),
3684                         horizontalDirection = this._getDragHorizontalDirection();
3685
3686                 if (!isOverElement)
3687                         return false;
3688
3689                 return this.floating ?
3690                         ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3691                         : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3692
3693         },
3694
3695         _intersectsWithSides: function(item) {
3696
3697                 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3698                         isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3699                         verticalDirection = this._getDragVerticalDirection(),
3700                         horizontalDirection = this._getDragHorizontalDirection();
3701
3702                 if (this.floating && horizontalDirection) {
3703                         return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3704                 } else {
3705                         return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3706                 }
3707
3708         },
3709
3710         _getDragVerticalDirection: function() {
3711                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
3712                 return delta != 0 && (delta > 0 ? "down" : "up");
3713         },
3714
3715         _getDragHorizontalDirection: function() {
3716                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
3717                 return delta != 0 && (delta > 0 ? "right" : "left");
3718         },
3719
3720         refresh: function(event) {
3721                 this._refreshItems(event);
3722                 this.refreshPositions();
3723                 return this;
3724         },
3725
3726         _connectWith: function() {
3727                 var options = this.options;
3728                 return options.connectWith.constructor == String
3729                         ? [options.connectWith]
3730                         : options.connectWith;
3731         },
3732         
3733         _getItemsAsjQuery: function(connected) {
3734
3735                 var self = this;
3736                 var items = [];
3737                 var queries = [];
3738                 var connectWith = this._connectWith();
3739
3740                 if(connectWith && connected) {
3741                         for (var i = connectWith.length - 1; i >= 0; i--){
3742                                 var cur = $(connectWith[i]);
3743                                 for (var j = cur.length - 1; j >= 0; j--){
3744                                         var inst = $.data(cur[j], 'sortable');
3745                                         if(inst && inst != this && !inst.options.disabled) {
3746                                                 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]);
3747                                         }
3748                                 };
3749                         };
3750                 }
3751
3752                 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]);
3753
3754                 for (var i = queries.length - 1; i >= 0; i--){
3755                         queries[i][0].each(function() {
3756                                 items.push(this);
3757                         });
3758                 };
3759
3760                 return $(items);
3761
3762         },
3763
3764         _removeCurrentsFromItems: function() {
3765
3766                 var list = this.currentItem.find(":data(sortable-item)");
3767
3768                 for (var i=0; i < this.items.length; i++) {
3769
3770                         for (var j=0; j < list.length; j++) {
3771                                 if(list[j] == this.items[i].item[0])
3772                                         this.items.splice(i,1);
3773                         };
3774
3775                 };
3776
3777         },
3778
3779         _refreshItems: function(event) {
3780
3781                 this.items = [];
3782                 this.containers = [this];
3783                 var items = this.items;
3784                 var self = this;
3785                 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3786                 var connectWith = this._connectWith();
3787
3788                 if(connectWith) {
3789                         for (var i = connectWith.length - 1; i >= 0; i--){
3790                                 var cur = $(connectWith[i]);
3791                                 for (var j = cur.length - 1; j >= 0; j--){
3792                                         var inst = $.data(cur[j], 'sortable');
3793                                         if(inst && inst != this && !inst.options.disabled) {
3794                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3795                                                 this.containers.push(inst);
3796                                         }
3797                                 };
3798                         };
3799                 }
3800
3801                 for (var i = queries.length - 1; i >= 0; i--) {
3802                         var targetData = queries[i][1];
3803                         var _queries = queries[i][0];
3804
3805                         for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3806                                 var item = $(_queries[j]);
3807
3808                                 item.data('sortable-item', targetData); // Data for target checking (mouse manager)
3809
3810                                 items.push({
3811                                         item: item,
3812                                         instance: targetData,
3813                                         width: 0, height: 0,
3814                                         left: 0, top: 0
3815                                 });
3816                         };
3817                 };
3818
3819         },
3820
3821         refreshPositions: function(fast) {
3822
3823                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3824                 if(this.offsetParent && this.helper) {
3825                         this.offset.parent = this._getParentOffset();
3826                 }
3827
3828                 for (var i = this.items.length - 1; i >= 0; i--){
3829                         var item = this.items[i];
3830
3831                         //We ignore calculating positions of all connected containers when we're not over them
3832                         if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3833                                 continue;
3834
3835                         var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3836
3837                         if (!fast) {
3838                                 item.width = t.outerWidth();
3839                                 item.height = t.outerHeight();
3840                         }
3841
3842                         var p = t.offset();
3843                         item.left = p.left;
3844                         item.top = p.top;
3845                 };
3846
3847                 if(this.options.custom && this.options.custom.refreshContainers) {
3848                         this.options.custom.refreshContainers.call(this);
3849                 } else {
3850                         for (var i = this.containers.length - 1; i >= 0; i--){
3851                                 var p = this.containers[i].element.offset();
3852                                 this.containers[i].containerCache.left = p.left;
3853                                 this.containers[i].containerCache.top = p.top;
3854                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3855                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3856                         };
3857                 }
3858
3859                 return this;
3860         },
3861
3862         _createPlaceholder: function(that) {
3863
3864                 var self = that || this, o = self.options;
3865
3866                 if(!o.placeholder || o.placeholder.constructor == String) {
3867                         var className = o.placeholder;
3868                         o.placeholder = {
3869                                 element: function() {
3870
3871                                         var el = $(document.createElement(self.currentItem[0].nodeName))
3872                                                 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3873                                                 .removeClass("ui-sortable-helper")[0];
3874
3875                                         if(!className)
3876                                                 el.style.visibility = "hidden";
3877
3878                                         return el;
3879                                 },
3880                                 update: function(container, p) {
3881
3882                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3883                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3884                                         if(className && !o.forcePlaceholderSize) return;
3885
3886                                         //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
3887                                         if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3888                                         if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3889                                 }
3890                         };
3891                 }
3892
3893                 //Create the placeholder
3894                 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3895
3896                 //Append it after the actual current item
3897                 self.currentItem.after(self.placeholder);
3898
3899                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3900                 o.placeholder.update(self, self.placeholder);
3901
3902         },
3903
3904         _contactContainers: function(event) {
3905                 
3906                 // get innermost container that intersects with item 
3907                 var innermostContainer = null, innermostIndex = null;           
3908                 
3909                 
3910                 for (var i = this.containers.length - 1; i >= 0; i--){
3911
3912                         // never consider a container that's located within the item itself 
3913                         if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3914                                 continue;
3915
3916                         if(this._intersectsWith(this.containers[i].containerCache)) {
3917
3918                                 // if we've already found a container and it's more "inner" than this, then continue 
3919                                 if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3920                                         continue;
3921
3922                                 innermostContainer = this.containers[i]; 
3923                                 innermostIndex = i;
3924                                         
3925                         } else {
3926                                 // container doesn't intersect. trigger "out" event if necessary 
3927                                 if(this.containers[i].containerCache.over) {
3928                                         this.containers[i]._trigger("out", event, this._uiHash(this));
3929                                         this.containers[i].containerCache.over = 0;
3930                                 }
3931                         }
3932
3933                 }
3934                 
3935                 // if no intersecting containers found, return 
3936                 if(!innermostContainer) return; 
3937
3938                 // move the item into the container if it's not there already
3939                 if(this.containers.length === 1) {
3940                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3941                         this.containers[innermostIndex].containerCache.over = 1;
3942                 } else if(this.currentContainer != this.containers[innermostIndex]) { 
3943
3944                         //When entering a new container, we will find the item with the least distance and append our item near it 
3945                         var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; 
3946                         for (var j = this.items.length - 1; j >= 0; j--) { 
3947                                 if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 
3948                                 var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; 
3949                                 if(Math.abs(cur - base) < dist) { 
3950                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 
3951                                 } 
3952                         } 
3953
3954                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 
3955                                 return; 
3956
3957                         this.currentContainer = this.containers[innermostIndex]; 
3958                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 
3959                         this._trigger("change", event, this._uiHash()); 
3960                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 
3961
3962                         //Update the placeholder 
3963                         this.options.placeholder.update(this.currentContainer, this.placeholder); 
3964                 
3965                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 
3966                         this.containers[innermostIndex].containerCache.over = 1;
3967                 } 
3968         
3969                 
3970         },
3971
3972         _createHelper: function(event) {
3973
3974                 var o = this.options;
3975                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3976
3977                 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3978                         $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3979
3980                 if(helper[0] == this.currentItem[0])
3981                         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") };
3982
3983                 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3984                 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3985
3986                 return helper;
3987
3988         },
3989
3990         _adjustOffsetFromHelper: function(obj) {
3991                 if (typeof obj == 'string') {
3992                         obj = obj.split(' ');
3993                 }
3994                 if ($.isArray(obj)) {
3995                         obj = {left: +obj[0], top: +obj[1] || 0};
3996                 }
3997                 if ('left' in obj) {
3998                         this.offset.click.left = obj.left + this.margins.left;
3999                 }
4000                 if ('right' in obj) {
4001                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4002                 }
4003                 if ('top' in obj) {
4004                         this.offset.click.top = obj.top + this.margins.top;
4005                 }
4006                 if ('bottom' in obj) {
4007                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4008                 }
4009         },
4010
4011         _getParentOffset: function() {
4012
4013
4014                 //Get the offsetParent and cache its position
4015                 this.offsetParent = this.helper.offsetParent();
4016                 var po = this.offsetParent.offset();
4017
4018                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4019                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4020                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4021                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4022                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
4023                         po.left += this.scrollParent.scrollLeft();
4024                         po.top += this.scrollParent.scrollTop();
4025                 }
4026
4027                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4028                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
4029                         po = { top: 0, left: 0 };
4030
4031                 return {
4032                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4033                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4034                 };
4035
4036         },
4037
4038         _getRelativeOffset: function() {
4039
4040                 if(this.cssPosition == "relative") {
4041                         var p = this.currentItem.position();
4042                         return {
4043                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4044                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4045                         };
4046                 } else {
4047                         return { top: 0, left: 0 };
4048                 }
4049
4050         },
4051
4052         _cacheMargins: function() {
4053                 this.margins = {
4054                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4055                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4056                 };
4057         },
4058
4059         _cacheHelperProportions: function() {
4060                 this.helperProportions = {
4061                         width: this.helper.outerWidth(),
4062                         height: this.helper.outerHeight()
4063                 };
4064         },
4065
4066         _setContainment: function() {
4067
4068                 var o = this.options;
4069                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4070                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
4071                         0 - this.offset.relative.left - this.offset.parent.left,
4072                         0 - this.offset.relative.top - this.offset.parent.top,
4073                         $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4074                         ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4075                 ];
4076
4077                 if(!(/^(document|window|parent)$/).test(o.containment)) {
4078                         var ce = $(o.containment)[0];
4079                         var co = $(o.containment).offset();
4080                         var over = ($(ce).css("overflow") != 'hidden');
4081
4082                         this.containment = [
4083                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4084                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4085                                 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,
4086                                 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
4087                         ];
4088                 }
4089
4090         },
4091
4092         _convertPositionTo: function(d, pos) {
4093
4094                 if(!pos) pos = this.position;
4095                 var mod = d == "absolute" ? 1 : -1;
4096                 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);
4097
4098                 return {
4099                         top: (
4100                                 pos.top                                                                                                                                 // The absolute mouse position
4101                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4102                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
4103                                 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4104                         ),
4105                         left: (
4106                                 pos.left                                                                                                                                // The absolute mouse position
4107                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
4108                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
4109                                 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4110                         )
4111                 };
4112
4113         },
4114
4115         _generatePosition: function(event) {
4116
4117                 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);
4118
4119                 // This is another very weird special case that only happens for relative elements:
4120                 // 1. If the css position is relative
4121                 // 2. and the scroll parent is the document or similar to the offset parent
4122                 // we have to refresh the relative offset during the scroll so there are no jumps
4123                 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4124                         this.offset.relative = this._getRelativeOffset();
4125                 }
4126
4127                 var pageX = event.pageX;
4128                 var pageY = event.pageY;
4129
4130                 /*
4131                  * - Position constraining -
4132                  * Constrain the position to a mix of grid, containment.
4133                  */
4134
4135                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4136
4137                         if(this.containment) {
4138                                 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4139                                 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4140                                 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4141                                 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4142                         }
4143
4144                         if(o.grid) {
4145                                 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4146                                 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;
4147
4148                                 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4149                                 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;
4150                         }
4151
4152                 }
4153
4154                 return {
4155                         top: (
4156                                 pageY                                                                                                                           // The absolute mouse position
4157                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
4158                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
4159                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
4160                                 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4161                         ),
4162                         left: (
4163                                 pageX                                                                                                                           // The absolute mouse position
4164                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
4165                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
4166                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
4167                                 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4168                         )
4169                 };
4170
4171         },
4172
4173         _rearrange: function(event, i, a, hardRefresh) {
4174
4175                 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));
4176
4177                 //Various things done here to improve the performance:
4178                 // 1. we create a setTimeout, that calls refreshPositions
4179                 // 2. on the instance, we have a counter variable, that get's higher after every append
4180                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4181                 // 4. this lets only the last addition to the timeout stack through
4182                 this.counter = this.counter ? ++this.counter : 1;
4183                 var self = this, counter = this.counter;
4184
4185                 window.setTimeout(function() {
4186                         if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4187                 },0);
4188
4189         },
4190
4191         _clear: function(event, noPropagation) {
4192
4193                 this.reverting = false;
4194                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4195                 // everything else normalized again
4196                 var delayedTriggers = [], self = this;
4197
4198                 // We first have to update the dom position of the actual currentItem
4199                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4200                 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4201                 this._noFinalSort = null;
4202
4203                 if(this.helper[0] == this.currentItem[0]) {
4204                         for(var i in this._storedCSS) {
4205                                 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4206                         }
4207                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4208                 } else {
4209                         this.currentItem.show();
4210                 }
4211
4212                 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4213                 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
4214                 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
4215                         if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4216                         for (var i = this.containers.length - 1; i >= 0; i--){
4217                                 if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
4218                                         delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4219                                         delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
4220                                 }
4221                         };
4222                 };
4223
4224                 //Post events to containers
4225                 for (var i = this.containers.length - 1; i >= 0; i--){
4226                         if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4227                         if(this.containers[i].containerCache.over) {
4228                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4229                                 this.containers[i].containerCache.over = 0;
4230                         }
4231                 }
4232
4233                 //Do what was originally in plugins
4234                 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4235                 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4236                 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4237
4238                 this.dragging = false;
4239                 if(this.cancelHelperRemoval) {
4240                         if(!noPropagation) {
4241                                 this._trigger("beforeStop", event, this._uiHash());
4242                                 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4243                                 this._trigger("stop", event, this._uiHash());
4244                         }
4245                         return false;
4246                 }
4247
4248                 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4249
4250                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4251                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4252
4253                 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4254
4255                 if(!noPropagation) {
4256                         for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4257                         this._trigger("stop", event, this._uiHash());
4258                 }
4259
4260                 this.fromOutside = false;
4261                 return true;
4262
4263         },
4264
4265         _trigger: function() {
4266                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4267                         this.cancel();
4268                 }
4269         },
4270
4271         _uiHash: function(inst) {
4272                 var self = inst || this;
4273                 return {
4274                         helper: self.helper,
4275                         placeholder: self.placeholder || $([]),
4276                         position: self.position,
4277                         originalPosition: self.originalPosition,
4278                         offset: self.positionAbs,
4279                         item: self.currentItem,
4280                         sender: inst ? inst.element : null
4281                 };
4282         }
4283
4284 });
4285
4286 $.extend($.ui.sortable, {
4287         version: "1.8.14"
4288 });
4289
4290 })(jQuery);
4291 /*
4292  * jQuery UI Accordion 1.8.14
4293  *
4294  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4295  * Dual licensed under the MIT or GPL Version 2 licenses.
4296  * http://jquery.org/license
4297  *
4298  * http://docs.jquery.com/UI/Accordion
4299  *
4300  * Depends:
4301  *      jquery.ui.core.js
4302  *      jquery.ui.widget.js
4303  */
4304 (function( $, undefined ) {
4305
4306 $.widget( "ui.accordion", {
4307         options: {
4308                 active: 0,
4309                 animated: "slide",
4310                 autoHeight: true,
4311                 clearStyle: false,
4312                 collapsible: false,
4313                 event: "click",
4314                 fillSpace: false,
4315                 header: "> li > :first-child,> :not(li):even",
4316                 icons: {
4317                         header: "ui-icon-triangle-1-e",
4318                         headerSelected: "ui-icon-triangle-1-s"
4319                 },
4320                 navigation: false,
4321                 navigationFilter: function() {
4322                         return this.href.toLowerCase() === location.href.toLowerCase();
4323                 }
4324         },
4325
4326         _create: function() {
4327                 var self = this,
4328                         options = self.options;
4329
4330                 self.running = 0;
4331
4332                 self.element
4333                         .addClass( "ui-accordion ui-widget ui-helper-reset" )
4334                         // in lack of child-selectors in CSS
4335                         // we need to mark top-LIs in a UL-accordion for some IE-fix
4336                         .children( "li" )
4337                                 .addClass( "ui-accordion-li-fix" );
4338
4339                 self.headers = self.element.find( options.header )
4340                         .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
4341                         .bind( "mouseenter.accordion", function() {
4342                                 if ( options.disabled ) {
4343                                         return;
4344                                 }
4345                                 $( this ).addClass( "ui-state-hover" );
4346                         })
4347                         .bind( "mouseleave.accordion", function() {
4348                                 if ( options.disabled ) {
4349                                         return;
4350                                 }
4351                                 $( this ).removeClass( "ui-state-hover" );
4352                         })
4353                         .bind( "focus.accordion", function() {
4354                                 if ( options.disabled ) {
4355                                         return;
4356                                 }
4357                                 $( this ).addClass( "ui-state-focus" );
4358                         })
4359                         .bind( "blur.accordion", function() {
4360                                 if ( options.disabled ) {
4361                                         return;
4362                                 }
4363                                 $( this ).removeClass( "ui-state-focus" );
4364                         });
4365
4366                 self.headers.next()
4367                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
4368
4369                 if ( options.navigation ) {
4370                         var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
4371                         if ( current.length ) {
4372                                 var header = current.closest( ".ui-accordion-header" );
4373                                 if ( header.length ) {
4374                                         // anchor within header
4375                                         self.active = header;
4376                                 } else {
4377                                         // anchor within content
4378                                         self.active = current.closest( ".ui-accordion-content" ).prev();
4379                                 }
4380                         }
4381                 }
4382
4383                 self.active = self._findActive( self.active || options.active )
4384                         .addClass( "ui-state-default ui-state-active" )
4385                         .toggleClass( "ui-corner-all" )
4386                         .toggleClass( "ui-corner-top" );
4387                 self.active.next().addClass( "ui-accordion-content-active" );
4388
4389                 self._createIcons();
4390                 self.resize();
4391                 
4392                 // ARIA
4393                 self.element.attr( "role", "tablist" );
4394
4395                 self.headers
4396                         .attr( "role", "tab" )
4397                         .bind( "keydown.accordion", function( event ) {
4398                                 return self._keydown( event );
4399                         })
4400                         .next()
4401                                 .attr( "role", "tabpanel" );
4402
4403                 self.headers
4404                         .not( self.active || "" )
4405                         .attr({
4406                                 "aria-expanded": "false",
4407                                 "aria-selected": "false",
4408                                 tabIndex: -1
4409                         })
4410                         .next()
4411                                 .hide();
4412
4413                 // make sure at least one header is in the tab order
4414                 if ( !self.active.length ) {
4415                         self.headers.eq( 0 ).attr( "tabIndex", 0 );
4416                 } else {
4417                         self.active
4418                                 .attr({
4419                                         "aria-expanded": "true",
4420                                         "aria-selected": "true",
4421                                         tabIndex: 0
4422                                 });
4423                 }
4424
4425                 // only need links in tab order for Safari
4426                 if ( !$.browser.safari ) {
4427                         self.headers.find( "a" ).attr( "tabIndex", -1 );
4428                 }
4429
4430                 if ( options.event ) {
4431                         self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
4432                                 self._clickHandler.call( self, event, this );
4433                                 event.preventDefault();
4434                         });
4435                 }
4436         },
4437
4438         _createIcons: function() {
4439                 var options = this.options;
4440                 if ( options.icons ) {
4441                         $( "<span></span>" )
4442                                 .addClass( "ui-icon " + options.icons.header )
4443                                 .prependTo( this.headers );
4444                         this.active.children( ".ui-icon" )
4445                                 .toggleClass(options.icons.header)
4446                                 .toggleClass(options.icons.headerSelected);
4447                         this.element.addClass( "ui-accordion-icons" );
4448                 }
4449         },
4450
4451         _destroyIcons: function() {
4452                 this.headers.children( ".ui-icon" ).remove();
4453                 this.element.removeClass( "ui-accordion-icons" );
4454         },
4455
4456         destroy: function() {
4457                 var options = this.options;
4458
4459                 this.element
4460                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
4461                         .removeAttr( "role" );
4462
4463                 this.headers
4464                         .unbind( ".accordion" )
4465                         .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" )
4466                         .removeAttr( "role" )
4467                         .removeAttr( "aria-expanded" )
4468                         .removeAttr( "aria-selected" )
4469                         .removeAttr( "tabIndex" );
4470
4471                 this.headers.find( "a" ).removeAttr( "tabIndex" );
4472                 this._destroyIcons();
4473                 var contents = this.headers.next()
4474                         .css( "display", "" )
4475                         .removeAttr( "role" )
4476                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
4477                 if ( options.autoHeight || options.fillHeight ) {
4478                         contents.css( "height", "" );
4479                 }
4480
4481                 return $.Widget.prototype.destroy.call( this );
4482         },
4483
4484         _setOption: function( key, value ) {
4485                 $.Widget.prototype._setOption.apply( this, arguments );
4486                         
4487                 if ( key == "active" ) {
4488                         this.activate( value );
4489                 }
4490                 if ( key == "icons" ) {
4491                         this._destroyIcons();
4492                         if ( value ) {
4493                                 this._createIcons();
4494                         }
4495                 }
4496                 // #5332 - opacity doesn't cascade to positioned elements in IE
4497                 // so we need to add the disabled class to the headers and panels
4498                 if ( key == "disabled" ) {
4499                         this.headers.add(this.headers.next())
4500                                 [ value ? "addClass" : "removeClass" ](
4501                                         "ui-accordion-disabled ui-state-disabled" );
4502                 }
4503         },
4504
4505         _keydown: function( event ) {
4506                 if ( this.options.disabled || event.altKey || event.ctrlKey ) {
4507                         return;
4508                 }
4509
4510                 var keyCode = $.ui.keyCode,
4511                         length = this.headers.length,
4512                         currentIndex = this.headers.index( event.target ),
4513                         toFocus = false;
4514
4515                 switch ( event.keyCode ) {
4516                         case keyCode.RIGHT:
4517                         case keyCode.DOWN:
4518                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4519                                 break;
4520                         case keyCode.LEFT:
4521                         case keyCode.UP:
4522                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4523                                 break;
4524                         case keyCode.SPACE:
4525                         case keyCode.ENTER:
4526                                 this._clickHandler( { target: event.target }, event.target );
4527                                 event.preventDefault();
4528                 }
4529
4530                 if ( toFocus ) {
4531                         $( event.target ).attr( "tabIndex", -1 );
4532                         $( toFocus ).attr( "tabIndex", 0 );
4533                         toFocus.focus();
4534                         return false;
4535                 }
4536
4537                 return true;
4538         },
4539
4540         resize: function() {
4541                 var options = this.options,
4542                         maxHeight;
4543
4544                 if ( options.fillSpace ) {
4545                         if ( $.browser.msie ) {
4546                                 var defOverflow = this.element.parent().css( "overflow" );
4547                                 this.element.parent().css( "overflow", "hidden");
4548                         }
4549                         maxHeight = this.element.parent().height();
4550                         if ($.browser.msie) {
4551                                 this.element.parent().css( "overflow", defOverflow );
4552                         }
4553
4554                         this.headers.each(function() {
4555                                 maxHeight -= $( this ).outerHeight( true );
4556                         });
4557
4558                         this.headers.next()
4559                                 .each(function() {
4560                                         $( this ).height( Math.max( 0, maxHeight -
4561                                                 $( this ).innerHeight() + $( this ).height() ) );
4562                                 })
4563                                 .css( "overflow", "auto" );
4564                 } else if ( options.autoHeight ) {
4565                         maxHeight = 0;
4566                         this.headers.next()
4567                                 .each(function() {
4568                                         maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
4569                                 })
4570                                 .height( maxHeight );
4571                 }
4572
4573                 return this;
4574         },
4575
4576         activate: function( index ) {
4577                 // TODO this gets called on init, changing the option without an explicit call for that
4578                 this.options.active = index;
4579                 // call clickHandler with custom event
4580                 var active = this._findActive( index )[ 0 ];
4581                 this._clickHandler( { target: active }, active );
4582
4583                 return this;
4584         },
4585
4586         _findActive: function( selector ) {
4587                 return selector
4588                         ? typeof selector === "number"
4589                                 ? this.headers.filter( ":eq(" + selector + ")" )
4590                                 : this.headers.not( this.headers.not( selector ) )
4591                         : selector === false
4592                                 ? $( [] )
4593                                 : this.headers.filter( ":eq(0)" );
4594         },
4595
4596         // TODO isn't event.target enough? why the separate target argument?
4597         _clickHandler: function( event, target ) {
4598                 var options = this.options;
4599                 if ( options.disabled ) {
4600                         return;
4601                 }
4602
4603                 // called only when using activate(false) to close all parts programmatically
4604                 if ( !event.target ) {
4605                         if ( !options.collapsible ) {
4606                                 return;
4607                         }
4608                         this.active
4609                                 .removeClass( "ui-state-active ui-corner-top" )
4610                                 .addClass( "ui-state-default ui-corner-all" )
4611                                 .children( ".ui-icon" )
4612                                         .removeClass( options.icons.headerSelected )
4613                                         .addClass( options.icons.header );
4614                         this.active.next().addClass( "ui-accordion-content-active" );
4615                         var toHide = this.active.next(),
4616                                 data = {
4617                                         options: options,
4618                                         newHeader: $( [] ),
4619                                         oldHeader: options.active,
4620                                         newContent: $( [] ),
4621                                         oldContent: toHide
4622                                 },
4623                                 toShow = ( this.active = $( [] ) );
4624                         this._toggle( toShow, toHide, data );
4625                         return;
4626                 }
4627
4628                 // get the click target
4629                 var clicked = $( event.currentTarget || target ),
4630                         clickedIsActive = clicked[0] === this.active[0];
4631
4632                 // TODO the option is changed, is that correct?
4633                 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
4634                 options.active = options.collapsible && clickedIsActive ?
4635                         false :
4636                         this.headers.index( clicked );
4637
4638                 // if animations are still active, or the active header is the target, ignore click
4639                 if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
4640                         return;
4641                 }
4642
4643                 // find elements to show and hide
4644                 var active = this.active,
4645                         toShow = clicked.next(),
4646                         toHide = this.active.next(),
4647                         data = {
4648                                 options: options,
4649                                 newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
4650                                 oldHeader: this.active,
4651                                 newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
4652                                 oldContent: toHide
4653                         },
4654                         down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
4655
4656                 // when the call to ._toggle() comes after the class changes
4657                 // it causes a very odd bug in IE 8 (see #6720)
4658                 this.active = clickedIsActive ? $([]) : clicked;
4659                 this._toggle( toShow, toHide, data, clickedIsActive, down );
4660
4661                 // switch classes
4662                 active
4663                         .removeClass( "ui-state-active ui-corner-top" )
4664                         .addClass( "ui-state-default ui-corner-all" )
4665                         .children( ".ui-icon" )
4666                                 .removeClass( options.icons.headerSelected )
4667                                 .addClass( options.icons.header );
4668                 if ( !clickedIsActive ) {
4669                         clicked
4670                                 .removeClass( "ui-state-default ui-corner-all" )
4671                                 .addClass( "ui-state-active ui-corner-top" )
4672                                 .children( ".ui-icon" )
4673                                         .removeClass( options.icons.header )
4674                                         .addClass( options.icons.headerSelected );
4675                         clicked
4676                                 .next()
4677                                 .addClass( "ui-accordion-content-active" );
4678                 }
4679
4680                 return;
4681         },
4682
4683         _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
4684                 var self = this,
4685                         options = self.options;
4686
4687                 self.toShow = toShow;
4688                 self.toHide = toHide;
4689                 self.data = data;
4690
4691                 var complete = function() {
4692                         if ( !self ) {
4693                                 return;
4694                         }
4695                         return self._completed.apply( self, arguments );
4696                 };
4697
4698                 // trigger changestart event
4699                 self._trigger( "changestart", null, self.data );
4700
4701                 // count elements to animate
4702                 self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
4703
4704                 if ( options.animated ) {
4705                         var animOptions = {};
4706
4707                         if ( options.collapsible && clickedIsActive ) {
4708                                 animOptions = {
4709                                         toShow: $( [] ),
4710                                         toHide: toHide,
4711                                         complete: complete,
4712                                         down: down,
4713                                         autoHeight: options.autoHeight || options.fillSpace
4714                                 };
4715                         } else {
4716                                 animOptions = {
4717                                         toShow: toShow,
4718                                         toHide: toHide,
4719                                         complete: complete,
4720                                         down: down,
4721                                         autoHeight: options.autoHeight || options.fillSpace
4722                                 };
4723                         }
4724
4725                         if ( !options.proxied ) {
4726                                 options.proxied = options.animated;
4727                         }
4728
4729                         if ( !options.proxiedDuration ) {
4730                                 options.proxiedDuration = options.duration;
4731                         }
4732
4733                         options.animated = $.isFunction( options.proxied ) ?
4734                                 options.proxied( animOptions ) :
4735                                 options.proxied;
4736
4737                         options.duration = $.isFunction( options.proxiedDuration ) ?
4738                                 options.proxiedDuration( animOptions ) :
4739                                 options.proxiedDuration;
4740
4741                         var animations = $.ui.accordion.animations,
4742                                 duration = options.duration,
4743                                 easing = options.animated;
4744
4745                         if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
4746                                 easing = "slide";
4747                         }
4748                         if ( !animations[ easing ] ) {
4749                                 animations[ easing ] = function( options ) {
4750                                         this.slide( options, {
4751                                                 easing: easing,
4752                                                 duration: duration || 700
4753                                         });
4754                                 };
4755                         }
4756
4757                         animations[ easing ]( animOptions );
4758                 } else {
4759                         if ( options.collapsible && clickedIsActive ) {
4760                                 toShow.toggle();
4761                         } else {
4762                                 toHide.hide();
4763                                 toShow.show();
4764                         }
4765
4766                         complete( true );
4767                 }
4768
4769                 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
4770                 toHide.prev()
4771                         .attr({
4772                                 "aria-expanded": "false",
4773                                 "aria-selected": "false",
4774                                 tabIndex: -1
4775                         })
4776                         .blur();
4777                 toShow.prev()
4778                         .attr({
4779                                 "aria-expanded": "true",
4780                                 "aria-selected": "true",
4781                                 tabIndex: 0
4782                         })
4783                         .focus();
4784         },
4785
4786         _completed: function( cancel ) {
4787                 this.running = cancel ? 0 : --this.running;
4788                 if ( this.running ) {
4789                         return;
4790                 }
4791
4792                 if ( this.options.clearStyle ) {
4793                         this.toShow.add( this.toHide ).css({
4794                                 height: "",
4795                                 overflow: ""
4796                         });
4797                 }
4798
4799                 // other classes are removed before the animation; this one needs to stay until completed
4800                 this.toHide.removeClass( "ui-accordion-content-active" );
4801                 // Work around for rendering bug in IE (#5421)
4802                 if ( this.toHide.length ) {
4803                         this.toHide.parent()[0].className = this.toHide.parent()[0].className;
4804                 }
4805
4806                 this._trigger( "change", null, this.data );
4807         }
4808 });
4809
4810 $.extend( $.ui.accordion, {
4811         version: "1.8.14",
4812         animations: {
4813                 slide: function( options, additions ) {
4814                         options = $.extend({
4815                                 easing: "swing",
4816                                 duration: 300
4817                         }, options, additions );
4818                         if ( !options.toHide.size() ) {
4819                                 options.toShow.animate({
4820                                         height: "show",
4821                                         paddingTop: "show",
4822                                         paddingBottom: "show"
4823                                 }, options );
4824                                 return;
4825                         }
4826                         if ( !options.toShow.size() ) {
4827                                 options.toHide.animate({
4828                                         height: "hide",
4829                                         paddingTop: "hide",
4830                                         paddingBottom: "hide"
4831                                 }, options );
4832                                 return;
4833                         }
4834                         var overflow = options.toShow.css( "overflow" ),
4835                                 percentDone = 0,
4836                                 showProps = {},
4837                                 hideProps = {},
4838                                 fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
4839                                 originalWidth;
4840                         // fix width before calculating height of hidden element
4841                         var s = options.toShow;
4842                         originalWidth = s[0].style.width;
4843                         s.width( parseInt( s.parent().width(), 10 )
4844                                 - parseInt( s.css( "paddingLeft" ), 10 )
4845                                 - parseInt( s.css( "paddingRight" ), 10 )
4846                                 - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
4847                                 - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
4848
4849                         $.each( fxAttrs, function( i, prop ) {
4850                                 hideProps[ prop ] = "hide";
4851
4852                                 var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
4853                                 showProps[ prop ] = {
4854                                         value: parts[ 1 ],
4855                                         unit: parts[ 2 ] || "px"
4856                                 };
4857                         });
4858                         options.toShow.css({ height: 0, overflow: "hidden" }).show();
4859                         options.toHide
4860                                 .filter( ":hidden" )
4861                                         .each( options.complete )
4862                                 .end()
4863                                 .filter( ":visible" )
4864                                 .animate( hideProps, {
4865                                 step: function( now, settings ) {
4866                                         // only calculate the percent when animating height
4867                                         // IE gets very inconsistent results when animating elements
4868                                         // with small values, which is common for padding
4869                                         if ( settings.prop == "height" ) {
4870                                                 percentDone = ( settings.end - settings.start === 0 ) ? 0 :
4871                                                         ( settings.now - settings.start ) / ( settings.end - settings.start );
4872                                         }
4873
4874                                         options.toShow[ 0 ].style[ settings.prop ] =
4875                                                 ( percentDone * showProps[ settings.prop ].value )
4876                                                 + showProps[ settings.prop ].unit;
4877                                 },
4878                                 duration: options.duration,
4879                                 easing: options.easing,
4880                                 complete: function() {
4881                                         if ( !options.autoHeight ) {
4882                                                 options.toShow.css( "height", "" );
4883                                         }
4884                                         options.toShow.css({
4885                                                 width: originalWidth,
4886                                                 overflow: overflow
4887                                         });
4888                                         options.complete();
4889                                 }
4890                         });
4891                 },
4892                 bounceslide: function( options ) {
4893                         this.slide( options, {
4894                                 easing: options.down ? "easeOutBounce" : "swing",
4895                                 duration: options.down ? 1000 : 200
4896                         });
4897                 }
4898         }
4899 });
4900
4901 })( jQuery );
4902 /*
4903  * jQuery UI Autocomplete 1.8.14
4904  *
4905  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4906  * Dual licensed under the MIT or GPL Version 2 licenses.
4907  * http://jquery.org/license
4908  *
4909  * http://docs.jquery.com/UI/Autocomplete
4910  *
4911  * Depends:
4912  *      jquery.ui.core.js
4913  *      jquery.ui.widget.js
4914  *      jquery.ui.position.js
4915  */
4916 (function( $, undefined ) {
4917
4918 // used to prevent race conditions with remote data sources
4919 var requestIndex = 0;
4920
4921 $.widget( "ui.autocomplete", {
4922         options: {
4923                 appendTo: "body",
4924                 autoFocus: false,
4925                 delay: 300,
4926                 minLength: 1,
4927                 position: {
4928                         my: "left top",
4929                         at: "left bottom",
4930                         collision: "none"
4931                 },
4932                 source: null
4933         },
4934
4935         pending: 0,
4936
4937         _create: function() {
4938                 var self = this,
4939                         doc = this.element[ 0 ].ownerDocument,
4940                         suppressKeyPress;
4941
4942                 this.element
4943                         .addClass( "ui-autocomplete-input" )
4944                         .attr( "autocomplete", "off" )
4945                         // TODO verify these actually work as intended
4946                         .attr({
4947                                 role: "textbox",
4948                                 "aria-autocomplete": "list",
4949                                 "aria-haspopup": "true"
4950                         })
4951                         .bind( "keydown.autocomplete", function( event ) {
4952                                 if ( self.options.disabled || self.element.attr( "readonly" ) ) {
4953                                         return;
4954                                 }
4955
4956                                 suppressKeyPress = false;
4957                                 var keyCode = $.ui.keyCode;
4958                                 switch( event.keyCode ) {
4959                                 case keyCode.PAGE_UP:
4960                                         self._move( "previousPage", event );
4961                                         break;
4962                                 case keyCode.PAGE_DOWN:
4963                                         self._move( "nextPage", event );
4964                                         break;
4965                                 case keyCode.UP:
4966                                         self._move( "previous", event );
4967                                         // prevent moving cursor to beginning of text field in some browsers
4968                                         event.preventDefault();
4969                                         break;
4970                                 case keyCode.DOWN:
4971                                         self._move( "next", event );
4972                                         // prevent moving cursor to end of text field in some browsers
4973                                         event.preventDefault();
4974                                         break;
4975                                 case keyCode.ENTER:
4976                                 case keyCode.NUMPAD_ENTER:
4977                                         // when menu is open and has focus
4978                                         if ( self.menu.active ) {
4979                                                 // #6055 - Opera still allows the keypress to occur
4980                                                 // which causes forms to submit
4981                                                 suppressKeyPress = true;
4982                                                 event.preventDefault();
4983                                         }
4984                                         //passthrough - ENTER and TAB both select the current element
4985                                 case keyCode.TAB:
4986                                         if ( !self.menu.active ) {
4987                                                 return;
4988                                         }
4989                                         self.menu.select( event );
4990                                         break;
4991                                 case keyCode.ESCAPE:
4992                                         self.element.val( self.term );
4993                                         self.close( event );
4994                                         break;
4995                                 default:
4996                                         // keypress is triggered before the input value is changed
4997                                         clearTimeout( self.searching );
4998                                         self.searching = setTimeout(function() {
4999                                                 // only search if the value has changed
5000                                                 if ( self.term != self.element.val() ) {
5001                                                         self.selectedItem = null;
5002                                                         self.search( null, event );
5003                                                 }
5004                                         }, self.options.delay );
5005                                         break;
5006                                 }
5007                         })
5008                         .bind( "keypress.autocomplete", function( event ) {
5009                                 if ( suppressKeyPress ) {
5010                                         suppressKeyPress = false;
5011                                         event.preventDefault();
5012                                 }
5013                         })
5014                         .bind( "focus.autocomplete", function() {
5015                                 if ( self.options.disabled ) {
5016                                         return;
5017                                 }
5018
5019                                 self.selectedItem = null;
5020                                 self.previous = self.element.val();
5021                         })
5022                         .bind( "blur.autocomplete", function( event ) {
5023                                 if ( self.options.disabled ) {
5024                                         return;
5025                                 }
5026
5027                                 clearTimeout( self.searching );
5028                                 // clicks on the menu (or a button to trigger a search) will cause a blur event
5029                                 self.closing = setTimeout(function() {
5030                                         self.close( event );
5031                                         self._change( event );
5032                                 }, 150 );
5033                         });
5034                 this._initSource();
5035                 this.response = function() {
5036                         return self._response.apply( self, arguments );
5037                 };
5038                 this.menu = $( "<ul></ul>" )
5039                         .addClass( "ui-autocomplete" )
5040                         .appendTo( $( this.options.appendTo || "body", doc )[0] )
5041                         // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
5042                         .mousedown(function( event ) {
5043                                 // clicking on the scrollbar causes focus to shift to the body
5044                                 // but we can't detect a mouseup or a click immediately afterward
5045                                 // so we have to track the next mousedown and close the menu if
5046                                 // the user clicks somewhere outside of the autocomplete
5047                                 var menuElement = self.menu.element[ 0 ];
5048                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5049                                         setTimeout(function() {
5050                                                 $( document ).one( 'mousedown', function( event ) {
5051                                                         if ( event.target !== self.element[ 0 ] &&
5052                                                                 event.target !== menuElement &&
5053                                                                 !$.ui.contains( menuElement, event.target ) ) {
5054                                                                 self.close();
5055                                                         }
5056                                                 });
5057                                         }, 1 );
5058                                 }
5059
5060                                 // use another timeout to make sure the blur-event-handler on the input was already triggered
5061                                 setTimeout(function() {
5062                                         clearTimeout( self.closing );
5063                                 }, 13);
5064                         })
5065                         .menu({
5066                                 focus: function( event, ui ) {
5067                                         var item = ui.item.data( "item.autocomplete" );
5068                                         if ( false !== self._trigger( "focus", event, { item: item } ) ) {
5069                                                 // use value to match what will end up in the input, if it was a key event
5070                                                 if ( /^key/.test(event.originalEvent.type) ) {
5071                                                         self.element.val( item.value );
5072                                                 }
5073                                         }
5074                                 },
5075                                 selected: function( event, ui ) {
5076                                         var item = ui.item.data( "item.autocomplete" ),
5077                                                 previous = self.previous;
5078
5079                                         // only trigger when focus was lost (click on menu)
5080                                         if ( self.element[0] !== doc.activeElement ) {
5081                                                 self.element.focus();
5082                                                 self.previous = previous;
5083                                                 // #6109 - IE triggers two focus events and the second
5084                                                 // is asynchronous, so we need to reset the previous
5085                                                 // term synchronously and asynchronously :-(
5086                                                 setTimeout(function() {
5087                                                         self.previous = previous;
5088                                                         self.selectedItem = item;
5089                                                 }, 1);
5090                                         }
5091
5092                                         if ( false !== self._trigger( "select", event, { item: item } ) ) {
5093                                                 self.element.val( item.value );
5094                                         }
5095                                         // reset the term after the select event
5096                                         // this allows custom select handling to work properly
5097                                         self.term = self.element.val();
5098
5099                                         self.close( event );
5100                                         self.selectedItem = item;
5101                                 },
5102                                 blur: function( event, ui ) {
5103                                         // don't set the value of the text field if it's already correct
5104                                         // this prevents moving the cursor unnecessarily
5105                                         if ( self.menu.element.is(":visible") &&
5106                                                 ( self.element.val() !== self.term ) ) {
5107                                                 self.element.val( self.term );
5108                                         }
5109                                 }
5110                         })
5111                         .zIndex( this.element.zIndex() + 1 )
5112                         // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
5113                         .css({ top: 0, left: 0 })
5114                         .hide()
5115                         .data( "menu" );
5116                 if ( $.fn.bgiframe ) {
5117                          this.menu.element.bgiframe();
5118                 }
5119         },
5120
5121         destroy: function() {
5122                 this.element
5123                         .removeClass( "ui-autocomplete-input" )
5124                         .removeAttr( "autocomplete" )
5125                         .removeAttr( "role" )
5126                         .removeAttr( "aria-autocomplete" )
5127                         .removeAttr( "aria-haspopup" );
5128                 this.menu.element.remove();
5129                 $.Widget.prototype.destroy.call( this );
5130         },
5131
5132         _setOption: function( key, value ) {
5133                 $.Widget.prototype._setOption.apply( this, arguments );
5134                 if ( key === "source" ) {
5135                         this._initSource();
5136                 }
5137                 if ( key === "appendTo" ) {
5138                         this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
5139                 }
5140                 if ( key === "disabled" && value && this.xhr ) {
5141                         this.xhr.abort();
5142                 }
5143         },
5144
5145         _initSource: function() {
5146                 var self = this,
5147                         array,
5148                         url;
5149                 if ( $.isArray(this.options.source) ) {
5150                         array = this.options.source;
5151                         this.source = function( request, response ) {
5152                                 response( $.ui.autocomplete.filter(array, request.term) );
5153                         };
5154                 } else if ( typeof this.options.source === "string" ) {
5155                         url = this.options.source;
5156                         this.source = function( request, response ) {
5157                                 if ( self.xhr ) {
5158                                         self.xhr.abort();
5159                                 }
5160                                 self.xhr = $.ajax({
5161                                         url: url,
5162                                         data: request,
5163                                         dataType: "json",
5164                                         autocompleteRequest: ++requestIndex,
5165                                         success: function( data, status ) {
5166                                                 if ( this.autocompleteRequest === requestIndex ) {
5167                                                         response( data );
5168                                                 }
5169                                         },
5170                                         error: function() {
5171                                                 if ( this.autocompleteRequest === requestIndex ) {
5172                                                         response( [] );
5173                                                 }
5174                                         }
5175                                 });
5176                         };
5177                 } else {
5178                         this.source = this.options.source;
5179                 }
5180         },
5181
5182         search: function( value, event ) {
5183                 value = value != null ? value : this.element.val();
5184
5185                 // always save the actual value, not the one passed as an argument
5186                 this.term = this.element.val();
5187
5188                 if ( value.length < this.options.minLength ) {
5189                         return this.close( event );
5190                 }
5191
5192                 clearTimeout( this.closing );
5193                 if ( this._trigger( "search", event ) === false ) {
5194                         return;
5195                 }
5196
5197                 return this._search( value );
5198         },
5199
5200         _search: function( value ) {
5201                 this.pending++;
5202                 this.element.addClass( "ui-autocomplete-loading" );
5203
5204                 this.source( { term: value }, this.response );
5205         },
5206
5207         _response: function( content ) {
5208                 if ( !this.options.disabled && content && content.length ) {
5209                         content = this._normalize( content );
5210                         this._suggest( content );
5211                         this._trigger( "open" );
5212                 } else {
5213                         this.close();
5214                 }
5215                 this.pending--;
5216                 if ( !this.pending ) {
5217                         this.element.removeClass( "ui-autocomplete-loading" );
5218                 }
5219         },
5220
5221         close: function( event ) {
5222                 clearTimeout( this.closing );
5223                 if ( this.menu.element.is(":visible") ) {
5224                         this.menu.element.hide();
5225                         this.menu.deactivate();
5226                         this._trigger( "close", event );
5227                 }
5228         },
5229         
5230         _change: function( event ) {
5231                 if ( this.previous !== this.element.val() ) {
5232                         this._trigger( "change", event, { item: this.selectedItem } );
5233                 }
5234         },
5235
5236         _normalize: function( items ) {
5237                 // assume all items have the right format when the first item is complete
5238                 if ( items.length && items[0].label && items[0].value ) {
5239                         return items;
5240                 }
5241                 return $.map( items, function(item) {
5242                         if ( typeof item === "string" ) {
5243                                 return {
5244                                         label: item,
5245                                         value: item
5246                                 };
5247                         }
5248                         return $.extend({
5249                                 label: item.label || item.value,
5250                                 value: item.value || item.label
5251                         }, item );
5252                 });
5253         },
5254
5255         _suggest: function( items ) {
5256                 var ul = this.menu.element
5257                         .empty()
5258                         .zIndex( this.element.zIndex() + 1 );
5259                 this._renderMenu( ul, items );
5260                 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
5261                 this.menu.deactivate();
5262                 this.menu.refresh();
5263
5264                 // size and position menu
5265                 ul.show();
5266                 this._resizeMenu();
5267                 ul.position( $.extend({
5268                         of: this.element
5269                 }, this.options.position ));
5270
5271                 if ( this.options.autoFocus ) {
5272                         this.menu.next( new $.Event("mouseover") );
5273                 }
5274         },
5275
5276         _resizeMenu: function() {
5277                 var ul = this.menu.element;
5278                 ul.outerWidth( Math.max(
5279                         ul.width( "" ).outerWidth(),
5280                         this.element.outerWidth()
5281                 ) );
5282         },
5283
5284         _renderMenu: function( ul, items ) {
5285                 var self = this;
5286                 $.each( items, function( index, item ) {
5287                         self._renderItem( ul, item );
5288                 });
5289         },
5290
5291         _renderItem: function( ul, item) {
5292                 return $( "<li></li>" )
5293                         .data( "item.autocomplete", item )
5294                         .append( $( "<a></a>" ).text( item.label ) )
5295                         .appendTo( ul );
5296         },
5297
5298         _move: function( direction, event ) {
5299                 if ( !this.menu.element.is(":visible") ) {
5300                         this.search( null, event );
5301                         return;
5302                 }
5303                 if ( this.menu.first() && /^previous/.test(direction) ||
5304                                 this.menu.last() && /^next/.test(direction) ) {
5305                         this.element.val( this.term );
5306                         this.menu.deactivate();
5307                         return;
5308                 }
5309                 this.menu[ direction ]( event );
5310         },
5311
5312         widget: function() {
5313                 return this.menu.element;
5314         }
5315 });
5316
5317 $.extend( $.ui.autocomplete, {
5318         escapeRegex: function( value ) {
5319                 return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
5320         },
5321         filter: function(array, term) {
5322                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
5323                 return $.grep( array, function(value) {
5324                         return matcher.test( value.label || value.value || value );
5325                 });
5326         }
5327 });
5328
5329 }( jQuery ));
5330
5331 /*
5332  * jQuery UI Menu (not officially released)
5333  * 
5334  * This widget isn't yet finished and the API is subject to change. We plan to finish
5335  * it for the next release. You're welcome to give it a try anyway and give us feedback,
5336  * as long as you're okay with migrating your code later on. We can help with that, too.
5337  *
5338  * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5339  * Dual licensed under the MIT or GPL Version 2 licenses.
5340  * http://jquery.org/license
5341  *
5342  * http://docs.jquery.com/UI/Menu
5343  *
5344  * Depends:
5345  *      jquery.ui.core.js
5346  *  jquery.ui.widget.js
5347  */
5348 (function($) {
5349
5350 $.widget("ui.menu", {
5351         _create: function() {
5352                 var self = this;
5353                 this.element
5354                         .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
5355                         .attr({
5356                                 role: "listbox",
5357                                 "aria-activedescendant": "ui-active-menuitem"
5358                         })
5359                         .click(function( event ) {
5360                                 if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
5361                                         return;
5362                                 }
5363                                 // temporary
5364                                 event.preventDefault();
5365                                 self.select( event );
5366                         });
5367                 this.refresh();
5368         },
5369         
5370         refresh: function() {
5371                 var self = this;
5372
5373                 // don't refresh list items that are already adapted
5374                 var items = this.element.children("li:not(.ui-menu-item):has(a)")
5375                         .addClass("ui-menu-item")
5376                         .attr("role", "menuitem");
5377                 
5378                 items.children("a")
5379                         .addClass("ui-corner-all")
5380                         .attr("tabindex", -1)
5381                         // mouseenter doesn't work with event delegation
5382                         .mouseenter(function( event ) {
5383                                 self.activate( event, $(this).parent() );
5384                         })
5385                         .mouseleave(function() {
5386                                 self.deactivate();
5387                         });
5388         },
5389
5390         activate: function( event, item ) {
5391                 this.deactivate();
5392                 if (this.hasScroll()) {
5393                         var offset = item.offset().top - this.element.offset().top,
5394                                 scroll = this.element.scrollTop(),
5395                                 elementHeight = this.element.height();
5396                         if (offset < 0) {
5397                                 this.element.scrollTop( scroll + offset);
5398                         } else if (offset >= elementHeight) {
5399                                 this.element.scrollTop( scroll + offset - elementHeight + item.height());
5400                         }
5401                 }
5402                 this.active = item.eq(0)
5403                         .children("a")
5404                                 .addClass("ui-state-hover")
5405                                 .attr("id", "ui-active-menuitem")
5406                         .end();
5407                 this._trigger("focus", event, { item: item });
5408         },
5409
5410         deactivate: function() {
5411                 if (!this.active) { return; }
5412
5413                 this.active.children("a")
5414                         .removeClass("ui-state-hover")
5415                         .removeAttr("id");
5416                 this._trigger("blur");
5417                 this.active = null;
5418         },
5419
5420         next: function(event) {
5421                 this.move("next", ".ui-menu-item:first", event);
5422         },
5423
5424         previous: function(event) {
5425                 this.move("prev", ".ui-menu-item:last", event);
5426         },
5427
5428         first: function() {
5429                 return this.active && !this.active.prevAll(".ui-menu-item").length;
5430         },
5431
5432         last: function() {
5433                 return this.active && !this.active.nextAll(".ui-menu-item").length;
5434         },
5435
5436         move: function(direction, edge, event) {
5437                 if (!this.active) {
5438                         this.activate(event, this.element.children(edge));
5439                         return;
5440                 }
5441                 var next = this.active[direction + "All"](".ui-menu-item").eq(0);
5442                 if (next.length) {
5443                         this.activate(event, next);
5444                 } else {
5445                         this.activate(event, this.element.children(edge));
5446                 }
5447         },
5448
5449         // TODO merge with previousPage
5450         nextPage: function(event) {
5451                 if (this.hasScroll()) {
5452                         // TODO merge with no-scroll-else
5453                         if (!this.active || this.last()) {
5454                                 this.activate(event, this.element.children(".ui-menu-item:first"));
5455                                 return;
5456                         }
5457                         var base = this.active.offset().top,
5458                                 height = this.element.height(),
5459                                 result = this.element.children(".ui-menu-item").filter(function() {
5460                                         var close = $(this).offset().top - base - height + $(this).height();
5461                                         // TODO improve approximation
5462                                         return close < 10 && close > -10;
5463                                 });
5464
5465                         // TODO try to catch this earlier when scrollTop indicates the last page anyway
5466                         if (!result.length) {
5467                                 result = this.element.children(".ui-menu-item:last");
5468                         }
5469                         this.activate(event, result);
5470                 } else {
5471                         this.activate(event, this.element.children(".ui-menu-item")
5472                                 .filter(!this.active || this.last() ? ":first" : ":last"));
5473                 }
5474         },
5475
5476         // TODO merge with nextPage
5477         previousPage: function(event) {
5478                 if (this.hasScroll()) {
5479                         // TODO merge with no-scroll-else
5480                         if (!this.active || this.first()) {
5481                                 this.activate(event, this.element.children(".ui-menu-item:last"));
5482                                 return;
5483                         }
5484
5485                         var base = this.active.offset().top,
5486                                 height = this.element.height();
5487                                 result = this.element.children(".ui-menu-item").filter(function() {
5488                                         var close = $(this).offset().top - base + height - $(this).height();
5489                                         // TODO improve approximation
5490                                         return close < 10 && close > -10;
5491                                 });
5492
5493                         // TODO try to catch this earlier when scrollTop indicates the last page anyway
5494                         if (!result.length) {
5495                                 result = this.element.children(".ui-menu-item:first");
5496                         }
5497                         this.activate(event, result);
5498                 } else {
5499                         this.activate(event, this.element.children(".ui-menu-item")
5500                                 .filter(!this.active || this.first() ? ":last" : ":first"));
5501                 }
5502         },
5503
5504         hasScroll: function() {
5505                 return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
5506         },
5507
5508         select: function( event ) {
5509                 this._trigger("selected", event, { item: this.active });
5510         }
5511 });
5512
5513 }(jQuery));
5514 /*
5515  * jQuery UI Button 1.8.14
5516  *
5517  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5518  * Dual licensed under the MIT or GPL Version 2 licenses.
5519  * http://jquery.org/license
5520  *
5521  * http://docs.jquery.com/UI/Button
5522  *
5523  * Depends:
5524  *      jquery.ui.core.js
5525  *      jquery.ui.widget.js
5526  */
5527 (function( $, undefined ) {
5528
5529 var lastActive, startXPos, startYPos, clickDragged,
5530         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
5531         stateClasses = "ui-state-hover ui-state-active ",
5532         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",
5533         formResetHandler = function() {
5534                 var buttons = $( this ).find( ":ui-button" );
5535                 setTimeout(function() {
5536                         buttons.button( "refresh" );
5537                 }, 1 );
5538         },
5539         radioGroup = function( radio ) {
5540                 var name = radio.name,
5541                         form = radio.form,
5542                         radios = $( [] );
5543                 if ( name ) {
5544                         if ( form ) {
5545                                 radios = $( form ).find( "[name='" + name + "']" );
5546                         } else {
5547                                 radios = $( "[name='" + name + "']", radio.ownerDocument )
5548                                         .filter(function() {
5549                                                 return !this.form;
5550                                         });
5551                         }
5552                 }
5553                 return radios;
5554         };
5555
5556 $.widget( "ui.button", {
5557         options: {
5558                 disabled: null,
5559                 text: true,
5560                 label: null,
5561                 icons: {
5562                         primary: null,
5563                         secondary: null
5564                 }
5565         },
5566         _create: function() {
5567                 this.element.closest( "form" )
5568                         .unbind( "reset.button" )
5569                         .bind( "reset.button", formResetHandler );
5570
5571                 if ( typeof this.options.disabled !== "boolean" ) {
5572                         this.options.disabled = this.element.attr( "disabled" );
5573                 }
5574
5575                 this._determineButtonType();
5576                 this.hasTitle = !!this.buttonElement.attr( "title" );
5577
5578                 var self = this,
5579                         options = this.options,
5580                         toggleButton = this.type === "checkbox" || this.type === "radio",
5581                         hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
5582                         focusClass = "ui-state-focus";
5583
5584                 if ( options.label === null ) {
5585                         options.label = this.buttonElement.html();
5586                 }
5587
5588                 if ( this.element.is( ":disabled" ) ) {
5589                         options.disabled = true;
5590                 }
5591
5592                 this.buttonElement
5593                         .addClass( baseClasses )
5594                         .attr( "role", "button" )
5595                         .bind( "mouseenter.button", function() {
5596                                 if ( options.disabled ) {
5597                                         return;
5598                                 }
5599                                 $( this ).addClass( "ui-state-hover" );
5600                                 if ( this === lastActive ) {
5601                                         $( this ).addClass( "ui-state-active" );
5602                                 }
5603                         })
5604                         .bind( "mouseleave.button", function() {
5605                                 if ( options.disabled ) {
5606                                         return;
5607                                 }
5608                                 $( this ).removeClass( hoverClass );
5609                         })
5610                         .bind( "click.button", function( event ) {
5611                                 if ( options.disabled ) {
5612                                         event.preventDefault();
5613                                         event.stopImmediatePropagation();
5614                                 }
5615                         });
5616
5617                 this.element
5618                         .bind( "focus.button", function() {
5619                                 // no need to check disabled, focus won't be triggered anyway
5620                                 self.buttonElement.addClass( focusClass );
5621                         })
5622                         .bind( "blur.button", function() {
5623                                 self.buttonElement.removeClass( focusClass );
5624                         });
5625
5626                 if ( toggleButton ) {
5627                         this.element.bind( "change.button", function() {
5628                                 if ( clickDragged ) {
5629                                         return;
5630                                 }
5631                                 self.refresh();
5632                         });
5633                         // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
5634                         // prevents issue where button state changes but checkbox/radio checked state
5635                         // does not in Firefox (see ticket #6970)
5636                         this.buttonElement
5637                                 .bind( "mousedown.button", function( event ) {
5638                                         if ( options.disabled ) {
5639                                                 return;
5640                                         }
5641                                         clickDragged = false;
5642                                         startXPos = event.pageX;
5643                                         startYPos = event.pageY;
5644                                 })
5645                                 .bind( "mouseup.button", function( event ) {
5646                                         if ( options.disabled ) {
5647                                                 return;
5648                                         }
5649                                         if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
5650                                                 clickDragged = true;
5651                                         }
5652                         });
5653                 }
5654
5655                 if ( this.type === "checkbox" ) {
5656                         this.buttonElement.bind( "click.button", function() {
5657                                 if ( options.disabled || clickDragged ) {
5658                                         return false;
5659                                 }
5660                                 $( this ).toggleClass( "ui-state-active" );
5661                                 self.buttonElement.attr( "aria-pressed", self.element[0].checked );
5662                         });
5663                 } else if ( this.type === "radio" ) {
5664                         this.buttonElement.bind( "click.button", function() {
5665                                 if ( options.disabled || clickDragged ) {
5666                                         return false;
5667                                 }
5668                                 $( this ).addClass( "ui-state-active" );
5669                                 self.buttonElement.attr( "aria-pressed", true );
5670
5671                                 var radio = self.element[ 0 ];
5672                                 radioGroup( radio )
5673                                         .not( radio )
5674                                         .map(function() {
5675                                                 return $( this ).button( "widget" )[ 0 ];
5676                                         })
5677                                         .removeClass( "ui-state-active" )
5678                                         .attr( "aria-pressed", false );
5679                         });
5680                 } else {
5681                         this.buttonElement
5682                                 .bind( "mousedown.button", function() {
5683                                         if ( options.disabled ) {
5684                                                 return false;
5685                                         }
5686                                         $( this ).addClass( "ui-state-active" );
5687                                         lastActive = this;
5688                                         $( document ).one( "mouseup", function() {
5689                                                 lastActive = null;
5690                                         });
5691                                 })
5692                                 .bind( "mouseup.button", function() {
5693                                         if ( options.disabled ) {
5694                                                 return false;
5695                                         }
5696                                         $( this ).removeClass( "ui-state-active" );
5697                                 })
5698                                 .bind( "keydown.button", function(event) {
5699                                         if ( options.disabled ) {
5700                                                 return false;
5701                                         }
5702                                         if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
5703                                                 $( this ).addClass( "ui-state-active" );
5704                                         }
5705                                 })
5706                                 .bind( "keyup.button", function() {
5707                                         $( this ).removeClass( "ui-state-active" );
5708                                 });
5709
5710                         if ( this.buttonElement.is("a") ) {
5711                                 this.buttonElement.keyup(function(event) {
5712                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
5713                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
5714                                                 $( this ).click();
5715                                         }
5716                                 });
5717                         }
5718                 }
5719
5720                 // TODO: pull out $.Widget's handling for the disabled option into
5721                 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
5722                 // be overridden by individual plugins
5723                 this._setOption( "disabled", options.disabled );
5724                 this._resetButton();
5725         },
5726
5727         _determineButtonType: function() {
5728
5729                 if ( this.element.is(":checkbox") ) {
5730                         this.type = "checkbox";
5731                 } else if ( this.element.is(":radio") ) {
5732                         this.type = "radio";
5733                 } else if ( this.element.is("input") ) {
5734                         this.type = "input";
5735                 } else {
5736                         this.type = "button";
5737                 }
5738
5739                 if ( this.type === "checkbox" || this.type === "radio" ) {
5740                         // we don't search against the document in case the element
5741                         // is disconnected from the DOM
5742                         var ancestor = this.element.parents().filter(":last"),
5743                                 labelSelector = "label[for=" + this.element.attr("id") + "]";
5744                         this.buttonElement = ancestor.find( labelSelector );
5745                         if ( !this.buttonElement.length ) {
5746                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
5747                                 this.buttonElement = ancestor.filter( labelSelector );
5748                                 if ( !this.buttonElement.length ) {
5749                                         this.buttonElement = ancestor.find( labelSelector );
5750                                 }
5751                         }
5752                         this.element.addClass( "ui-helper-hidden-accessible" );
5753
5754                         var checked = this.element.is( ":checked" );
5755                         if ( checked ) {
5756                                 this.buttonElement.addClass( "ui-state-active" );
5757                         }
5758                         this.buttonElement.attr( "aria-pressed", checked );
5759                 } else {
5760                         this.buttonElement = this.element;
5761                 }
5762         },
5763
5764         widget: function() {
5765                 return this.buttonElement;
5766         },
5767
5768         destroy: function() {
5769                 this.element
5770                         .removeClass( "ui-helper-hidden-accessible" );
5771                 this.buttonElement
5772                         .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
5773                         .removeAttr( "role" )
5774                         .removeAttr( "aria-pressed" )
5775                         .html( this.buttonElement.find(".ui-button-text").html() );
5776
5777                 if ( !this.hasTitle ) {
5778                         this.buttonElement.removeAttr( "title" );
5779                 }
5780
5781                 $.Widget.prototype.destroy.call( this );
5782         },
5783
5784         _setOption: function( key, value ) {
5785                 $.Widget.prototype._setOption.apply( this, arguments );
5786                 if ( key === "disabled" ) {
5787                         if ( value ) {
5788                                 this.element.attr( "disabled", true );
5789                         } else {
5790                                 this.element.removeAttr( "disabled" );
5791                         }
5792                         return;
5793                 }
5794                 this._resetButton();
5795         },
5796
5797         refresh: function() {
5798                 var isDisabled = this.element.is( ":disabled" );
5799                 if ( isDisabled !== this.options.disabled ) {
5800                         this._setOption( "disabled", isDisabled );
5801                 }
5802                 if ( this.type === "radio" ) {
5803                         radioGroup( this.element[0] ).each(function() {
5804                                 if ( $( this ).is( ":checked" ) ) {
5805                                         $( this ).button( "widget" )
5806                                                 .addClass( "ui-state-active" )
5807                                                 .attr( "aria-pressed", true );
5808                                 } else {
5809                                         $( this ).button( "widget" )
5810                                                 .removeClass( "ui-state-active" )
5811                                                 .attr( "aria-pressed", false );
5812                                 }
5813                         });
5814                 } else if ( this.type === "checkbox" ) {
5815                         if ( this.element.is( ":checked" ) ) {
5816                                 this.buttonElement
5817                                         .addClass( "ui-state-active" )
5818                                         .attr( "aria-pressed", true );
5819                         } else {
5820                                 this.buttonElement
5821                                         .removeClass( "ui-state-active" )
5822                                         .attr( "aria-pressed", false );
5823                         }
5824                 }
5825         },
5826
5827         _resetButton: function() {
5828                 if ( this.type === "input" ) {
5829                         if ( this.options.label ) {
5830                                 this.element.val( this.options.label );
5831                         }
5832                         return;
5833                 }
5834                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
5835                         buttonText = $( "<span></span>" )
5836                                 .addClass( "ui-button-text" )
5837                                 .html( this.options.label )
5838                                 .appendTo( buttonElement.empty() )
5839                                 .text(),
5840                         icons = this.options.icons,
5841                         multipleIcons = icons.primary && icons.secondary,
5842                         buttonClasses = [];  
5843
5844                 if ( icons.primary || icons.secondary ) {
5845                         if ( this.options.text ) {
5846                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
5847                         }
5848
5849                         if ( icons.primary ) {
5850                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
5851                         }
5852
5853                         if ( icons.secondary ) {
5854                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
5855                         }
5856
5857                         if ( !this.options.text ) {
5858                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
5859
5860                                 if ( !this.hasTitle ) {
5861                                         buttonElement.attr( "title", buttonText );
5862                                 }
5863                         }
5864                 } else {
5865                         buttonClasses.push( "ui-button-text-only" );
5866                 }
5867                 buttonElement.addClass( buttonClasses.join( " " ) );
5868         }
5869 });
5870
5871 $.widget( "ui.buttonset", {
5872         options: {
5873                 items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
5874         },
5875
5876         _create: function() {
5877                 this.element.addClass( "ui-buttonset" );
5878         },
5879         
5880         _init: function() {
5881                 this.refresh();
5882         },
5883
5884         _setOption: function( key, value ) {
5885                 if ( key === "disabled" ) {
5886                         this.buttons.button( "option", key, value );
5887                 }
5888
5889                 $.Widget.prototype._setOption.apply( this, arguments );
5890         },
5891         
5892         refresh: function() {
5893                 var ltr = this.element.css( "direction" ) === "ltr";
5894                 
5895                 this.buttons = this.element.find( this.options.items )
5896                         .filter( ":ui-button" )
5897                                 .button( "refresh" )
5898                         .end()
5899                         .not( ":ui-button" )
5900                                 .button()
5901                         .end()
5902                         .map(function() {
5903                                 return $( this ).button( "widget" )[ 0 ];
5904                         })
5905                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
5906                                 .filter( ":first" )
5907                                         .addClass( ltr ? "ui-corner-left" : "ui-corner-right" )
5908                                 .end()
5909                                 .filter( ":last" )
5910                                         .addClass( ltr ? "ui-corner-right" : "ui-corner-left" )
5911                                 .end()
5912                         .end();
5913         },
5914
5915         destroy: function() {
5916                 this.element.removeClass( "ui-buttonset" );
5917                 this.buttons
5918                         .map(function() {
5919                                 return $( this ).button( "widget" )[ 0 ];
5920                         })
5921                                 .removeClass( "ui-corner-left ui-corner-right" )
5922                         .end()
5923                         .button( "destroy" );
5924
5925                 $.Widget.prototype.destroy.call( this );
5926         }
5927 });
5928
5929 }( jQuery ) );
5930 /*
5931  * jQuery UI Dialog 1.8.14
5932  *
5933  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5934  * Dual licensed under the MIT or GPL Version 2 licenses.
5935  * http://jquery.org/license
5936  *
5937  * http://docs.jquery.com/UI/Dialog
5938  *
5939  * Depends:
5940  *      jquery.ui.core.js
5941  *      jquery.ui.widget.js
5942  *  jquery.ui.button.js
5943  *      jquery.ui.draggable.js
5944  *      jquery.ui.mouse.js
5945  *      jquery.ui.position.js
5946  *      jquery.ui.resizable.js
5947  */
5948 (function( $, undefined ) {
5949
5950 var uiDialogClasses =
5951                 'ui-dialog ' +
5952                 'ui-widget ' +
5953                 'ui-widget-content ' +
5954                 'ui-corner-all ',
5955         sizeRelatedOptions = {
5956                 buttons: true,
5957                 height: true,
5958                 maxHeight: true,
5959                 maxWidth: true,
5960                 minHeight: true,
5961                 minWidth: true,
5962                 width: true
5963         },
5964         resizableRelatedOptions = {
5965                 maxHeight: true,
5966                 maxWidth: true,
5967                 minHeight: true,
5968                 minWidth: true
5969         },
5970         // support for jQuery 1.3.2 - handle common attrFn methods for dialog
5971         attrFn = $.attrFn || {
5972                 val: true,
5973                 css: true,
5974                 html: true,
5975                 text: true,
5976                 data: true,
5977                 width: true,
5978                 height: true,
5979                 offset: true,
5980                 click: true
5981         };
5982
5983 $.widget("ui.dialog", {
5984         options: {
5985                 autoOpen: true,
5986                 buttons: {},
5987                 closeOnEscape: true,
5988                 closeText: 'close',
5989                 dialogClass: '',
5990                 draggable: true,
5991                 hide: null,
5992                 height: 'auto',
5993                 maxHeight: false,
5994                 maxWidth: false,
5995                 minHeight: 150,
5996                 minWidth: 150,
5997                 modal: false,
5998                 position: {
5999                         my: 'center',
6000                         at: 'center',
6001                         collision: 'fit',
6002                         // ensure that the titlebar is never outside the document
6003                         using: function(pos) {
6004                                 var topOffset = $(this).css(pos).offset().top;
6005                                 if (topOffset < 0) {
6006                                         $(this).css('top', pos.top - topOffset);
6007                                 }
6008                         }
6009                 },
6010                 resizable: true,
6011                 show: null,
6012                 stack: true,
6013                 title: '',
6014                 width: 300,
6015                 zIndex: 1000
6016         },
6017
6018         _create: function() {
6019                 this.originalTitle = this.element.attr('title');
6020                 // #5742 - .attr() might return a DOMElement
6021                 if ( typeof this.originalTitle !== "string" ) {
6022                         this.originalTitle = "";
6023                 }
6024
6025                 this.options.title = this.options.title || this.originalTitle;
6026                 var self = this,
6027                         options = self.options,
6028
6029                         title = options.title || '&#160;',
6030                         titleId = $.ui.dialog.getTitleId(self.element),
6031
6032                         uiDialog = (self.uiDialog = $('<div></div>'))
6033                                 .appendTo(document.body)
6034                                 .hide()
6035                                 .addClass(uiDialogClasses + options.dialogClass)
6036                                 .css({
6037                                         zIndex: options.zIndex
6038                                 })
6039                                 // setting tabIndex makes the div focusable
6040                                 // setting outline to 0 prevents a border on focus in Mozilla
6041                                 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
6042                                         if (options.closeOnEscape && event.keyCode &&
6043                                                 event.keyCode === $.ui.keyCode.ESCAPE) {
6044                                                 
6045                                                 self.close(event);
6046                                                 event.preventDefault();
6047                                         }
6048                                 })
6049                                 .attr({
6050                                         role: 'dialog',
6051                                         'aria-labelledby': titleId
6052                                 })
6053                                 .mousedown(function(event) {
6054                                         self.moveToTop(false, event);
6055                                 }),
6056
6057                         uiDialogContent = self.element
6058                                 .show()
6059                                 .removeAttr('title')
6060                                 .addClass(
6061                                         'ui-dialog-content ' +
6062                                         'ui-widget-content')
6063                                 .appendTo(uiDialog),
6064
6065                         uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
6066                                 .addClass(
6067                                         'ui-dialog-titlebar ' +
6068                                         'ui-widget-header ' +
6069                                         'ui-corner-all ' +
6070                                         'ui-helper-clearfix'
6071                                 )
6072                                 .prependTo(uiDialog),
6073
6074                         uiDialogTitlebarClose = $('<a href="#"></a>')
6075                                 .addClass(
6076                                         'ui-dialog-titlebar-close ' +
6077                                         'ui-corner-all'
6078                                 )
6079                                 .attr('role', 'button')
6080                                 .hover(
6081                                         function() {
6082                                                 uiDialogTitlebarClose.addClass('ui-state-hover');
6083                                         },
6084                                         function() {
6085                                                 uiDialogTitlebarClose.removeClass('ui-state-hover');
6086                                         }
6087                                 )
6088                                 .focus(function() {
6089                                         uiDialogTitlebarClose.addClass('ui-state-focus');
6090                                 })
6091                                 .blur(function() {
6092                                         uiDialogTitlebarClose.removeClass('ui-state-focus');
6093                                 })
6094                                 .click(function(event) {
6095                                         self.close(event);
6096                                         return false;
6097                                 })
6098                                 .appendTo(uiDialogTitlebar),
6099
6100                         uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
6101                                 .addClass(
6102                                         'ui-icon ' +
6103                                         'ui-icon-closethick'
6104                                 )
6105                                 .text(options.closeText)
6106                                 .appendTo(uiDialogTitlebarClose),
6107
6108                         uiDialogTitle = $('<span></span>')
6109                                 .addClass('ui-dialog-title')
6110                                 .attr('id', titleId)
6111                                 .html(title)
6112                                 .prependTo(uiDialogTitlebar);
6113
6114                 //handling of deprecated beforeclose (vs beforeClose) option
6115                 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6116                 //TODO: remove in 1.9pre
6117                 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
6118                         options.beforeClose = options.beforeclose;
6119                 }
6120
6121                 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
6122
6123                 if (options.draggable && $.fn.draggable) {
6124                         self._makeDraggable();
6125                 }
6126                 if (options.resizable && $.fn.resizable) {
6127                         self._makeResizable();
6128                 }
6129
6130                 self._createButtons(options.buttons);
6131                 self._isOpen = false;
6132
6133                 if ($.fn.bgiframe) {
6134                         uiDialog.bgiframe();
6135                 }
6136         },
6137
6138         _init: function() {
6139                 if ( this.options.autoOpen ) {
6140                         this.open();
6141                 }
6142         },
6143
6144         destroy: function() {
6145                 var self = this;
6146                 
6147                 if (self.overlay) {
6148                         self.overlay.destroy();
6149                 }
6150                 self.uiDialog.hide();
6151                 self.element
6152                         .unbind('.dialog')
6153                         .removeData('dialog')
6154                         .removeClass('ui-dialog-content ui-widget-content')
6155                         .hide().appendTo('body');
6156                 self.uiDialog.remove();
6157
6158                 if (self.originalTitle) {
6159                         self.element.attr('title', self.originalTitle);
6160                 }
6161
6162                 return self;
6163         },
6164
6165         widget: function() {
6166                 return this.uiDialog;
6167         },
6168
6169         close: function(event) {
6170                 var self = this,
6171                         maxZ, thisZ;
6172                 
6173                 if (false === self._trigger('beforeClose', event)) {
6174                         return;
6175                 }
6176
6177                 if (self.overlay) {
6178                         self.overlay.destroy();
6179                 }
6180                 self.uiDialog.unbind('keypress.ui-dialog');
6181
6182                 self._isOpen = false;
6183
6184                 if (self.options.hide) {
6185                         self.uiDialog.hide(self.options.hide, function() {
6186                                 self._trigger('close', event);
6187                         });
6188                 } else {
6189                         self.uiDialog.hide();
6190                         self._trigger('close', event);
6191                 }
6192
6193                 $.ui.dialog.overlay.resize();
6194
6195                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6196                 if (self.options.modal) {
6197                         maxZ = 0;
6198                         $('.ui-dialog').each(function() {
6199                                 if (this !== self.uiDialog[0]) {
6200                                         thisZ = $(this).css('z-index');
6201                                         if(!isNaN(thisZ)) {
6202                                                 maxZ = Math.max(maxZ, thisZ);
6203                                         }
6204                                 }
6205                         });
6206                         $.ui.dialog.maxZ = maxZ;
6207                 }
6208
6209                 return self;
6210         },
6211
6212         isOpen: function() {
6213                 return this._isOpen;
6214         },
6215
6216         // the force parameter allows us to move modal dialogs to their correct
6217         // position on open
6218         moveToTop: function(force, event) {
6219                 var self = this,
6220                         options = self.options,
6221                         saveScroll;
6222
6223                 if ((options.modal && !force) ||
6224                         (!options.stack && !options.modal)) {
6225                         return self._trigger('focus', event);
6226                 }
6227
6228                 if (options.zIndex > $.ui.dialog.maxZ) {
6229                         $.ui.dialog.maxZ = options.zIndex;
6230                 }
6231                 if (self.overlay) {
6232                         $.ui.dialog.maxZ += 1;
6233                         self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
6234                 }
6235
6236                 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
6237                 //  http://ui.jquery.com/bugs/ticket/3193
6238                 saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
6239                 $.ui.dialog.maxZ += 1;
6240                 self.uiDialog.css('z-index', $.ui.dialog.maxZ);
6241                 self.element.attr(saveScroll);
6242                 self._trigger('focus', event);
6243
6244                 return self;
6245         },
6246
6247         open: function() {
6248                 if (this._isOpen) { return; }
6249
6250                 var self = this,
6251                         options = self.options,
6252                         uiDialog = self.uiDialog;
6253
6254                 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
6255                 self._size();
6256                 self._position(options.position);
6257                 uiDialog.show(options.show);
6258                 self.moveToTop(true);
6259
6260                 // prevent tabbing out of modal dialogs
6261                 if (options.modal) {
6262                         uiDialog.bind('keypress.ui-dialog', function(event) {
6263                                 if (event.keyCode !== $.ui.keyCode.TAB) {
6264                                         return;
6265                                 }
6266
6267                                 var tabbables = $(':tabbable', this),
6268                                         first = tabbables.filter(':first'),
6269                                         last  = tabbables.filter(':last');
6270
6271                                 if (event.target === last[0] && !event.shiftKey) {
6272                                         first.focus(1);
6273                                         return false;
6274                                 } else if (event.target === first[0] && event.shiftKey) {
6275                                         last.focus(1);
6276                                         return false;
6277                                 }
6278                         });
6279                 }
6280
6281                 // set focus to the first tabbable element in the content area or the first button
6282                 // if there are no tabbable elements, set focus on the dialog itself
6283                 $(self.element.find(':tabbable').get().concat(
6284                         uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
6285                                 uiDialog.get()))).eq(0).focus();
6286
6287                 self._isOpen = true;
6288                 self._trigger('open');
6289
6290                 return self;
6291         },
6292
6293         _createButtons: function(buttons) {
6294                 var self = this,
6295                         hasButtons = false,
6296                         uiDialogButtonPane = $('<div></div>')
6297                                 .addClass(
6298                                         'ui-dialog-buttonpane ' +
6299                                         'ui-widget-content ' +
6300                                         'ui-helper-clearfix'
6301                                 ),
6302                         uiButtonSet = $( "<div></div>" )
6303                                 .addClass( "ui-dialog-buttonset" )
6304                                 .appendTo( uiDialogButtonPane );
6305
6306                 // if we already have a button pane, remove it
6307                 self.uiDialog.find('.ui-dialog-buttonpane').remove();
6308
6309                 if (typeof buttons === 'object' && buttons !== null) {
6310                         $.each(buttons, function() {
6311                                 return !(hasButtons = true);
6312                         });
6313                 }
6314                 if (hasButtons) {
6315                         $.each(buttons, function(name, props) {
6316                                 props = $.isFunction( props ) ?
6317                                         { click: props, text: name } :
6318                                         props;
6319                                 var button = $('<button type="button"></button>')
6320                                         .click(function() {
6321                                                 props.click.apply(self.element[0], arguments);
6322                                         })
6323                                         .appendTo(uiButtonSet);
6324                                 // can't use .attr( props, true ) with jQuery 1.3.2.
6325                                 $.each( props, function( key, value ) {
6326                                         if ( key === "click" ) {
6327                                                 return;
6328                                         }
6329                                         if ( key in attrFn ) {
6330                                                 button[ key ]( value );
6331                                         } else {
6332                                                 button.attr( key, value );
6333                                         }
6334                                 });
6335                                 if ($.fn.button) {
6336                                         button.button();
6337                                 }
6338                         });
6339                         uiDialogButtonPane.appendTo(self.uiDialog);
6340                 }
6341         },
6342
6343         _makeDraggable: function() {
6344                 var self = this,
6345                         options = self.options,
6346                         doc = $(document),
6347                         heightBeforeDrag;
6348
6349                 function filteredUi(ui) {
6350                         return {
6351                                 position: ui.position,
6352                                 offset: ui.offset
6353                         };
6354                 }
6355
6356                 self.uiDialog.draggable({
6357                         cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
6358                         handle: '.ui-dialog-titlebar',
6359                         containment: 'document',
6360                         start: function(event, ui) {
6361                                 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
6362                                 $(this).height($(this).height()).addClass("ui-dialog-dragging");
6363                                 self._trigger('dragStart', event, filteredUi(ui));
6364                         },
6365                         drag: function(event, ui) {
6366                                 self._trigger('drag', event, filteredUi(ui));
6367                         },
6368                         stop: function(event, ui) {
6369                                 options.position = [ui.position.left - doc.scrollLeft(),
6370                                         ui.position.top - doc.scrollTop()];
6371                                 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
6372                                 self._trigger('dragStop', event, filteredUi(ui));
6373                                 $.ui.dialog.overlay.resize();
6374                         }
6375                 });
6376         },
6377
6378         _makeResizable: function(handles) {
6379                 handles = (handles === undefined ? this.options.resizable : handles);
6380                 var self = this,
6381                         options = self.options,
6382                         // .ui-resizable has position: relative defined in the stylesheet
6383                         // but dialogs have to use absolute or fixed positioning
6384                         position = self.uiDialog.css('position'),
6385                         resizeHandles = (typeof handles === 'string' ?
6386                                 handles :
6387                                 'n,e,s,w,se,sw,ne,nw'
6388                         );
6389
6390                 function filteredUi(ui) {
6391                         return {
6392                                 originalPosition: ui.originalPosition,
6393                                 originalSize: ui.originalSize,
6394                                 position: ui.position,
6395                                 size: ui.size
6396                         };
6397                 }
6398
6399                 self.uiDialog.resizable({
6400                         cancel: '.ui-dialog-content',
6401                         containment: 'document',
6402                         alsoResize: self.element,
6403                         maxWidth: options.maxWidth,
6404                         maxHeight: options.maxHeight,
6405                         minWidth: options.minWidth,
6406                         minHeight: self._minHeight(),
6407                         handles: resizeHandles,
6408                         start: function(event, ui) {
6409                                 $(this).addClass("ui-dialog-resizing");
6410                                 self._trigger('resizeStart', event, filteredUi(ui));
6411                         },
6412                         resize: function(event, ui) {
6413                                 self._trigger('resize', event, filteredUi(ui));
6414                         },
6415                         stop: function(event, ui) {
6416                                 $(this).removeClass("ui-dialog-resizing");
6417                                 options.height = $(this).height();
6418                                 options.width = $(this).width();
6419                                 self._trigger('resizeStop', event, filteredUi(ui));
6420                                 $.ui.dialog.overlay.resize();
6421                         }
6422                 })
6423                 .css('position', position)
6424                 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
6425         },
6426
6427         _minHeight: function() {
6428                 var options = this.options;
6429
6430                 if (options.height === 'auto') {
6431                         return options.minHeight;
6432                 } else {
6433                         return Math.min(options.minHeight, options.height);
6434                 }
6435         },
6436
6437         _position: function(position) {
6438                 var myAt = [],
6439                         offset = [0, 0],
6440                         isVisible;
6441
6442                 if (position) {
6443                         // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
6444         //              if (typeof position == 'string' || $.isArray(position)) {
6445         //                      myAt = $.isArray(position) ? position : position.split(' ');
6446
6447                         if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
6448                                 myAt = position.split ? position.split(' ') : [position[0], position[1]];
6449                                 if (myAt.length === 1) {
6450                                         myAt[1] = myAt[0];
6451                                 }
6452
6453                                 $.each(['left', 'top'], function(i, offsetPosition) {
6454                                         if (+myAt[i] === myAt[i]) {
6455                                                 offset[i] = myAt[i];
6456                                                 myAt[i] = offsetPosition;
6457                                         }
6458                                 });
6459
6460                                 position = {
6461                                         my: myAt.join(" "),
6462                                         at: myAt.join(" "),
6463                                         offset: offset.join(" ")
6464                                 };
6465                         } 
6466
6467                         position = $.extend({}, $.ui.dialog.prototype.options.position, position);
6468                 } else {
6469                         position = $.ui.dialog.prototype.options.position;
6470                 }
6471
6472                 // need to show the dialog to get the actual offset in the position plugin
6473                 isVisible = this.uiDialog.is(':visible');
6474                 if (!isVisible) {
6475                         this.uiDialog.show();
6476                 }
6477                 this.uiDialog
6478                         // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6479                         .css({ top: 0, left: 0 })
6480                         .position($.extend({ of: window }, position));
6481                 if (!isVisible) {
6482                         this.uiDialog.hide();
6483                 }
6484         },
6485
6486         _setOptions: function( options ) {
6487                 var self = this,
6488                         resizableOptions = {},
6489                         resize = false;
6490
6491                 $.each( options, function( key, value ) {
6492                         self._setOption( key, value );
6493                         
6494                         if ( key in sizeRelatedOptions ) {
6495                                 resize = true;
6496                         }
6497                         if ( key in resizableRelatedOptions ) {
6498                                 resizableOptions[ key ] = value;
6499                         }
6500                 });
6501
6502                 if ( resize ) {
6503                         this._size();
6504                 }
6505                 if ( this.uiDialog.is( ":data(resizable)" ) ) {
6506                         this.uiDialog.resizable( "option", resizableOptions );
6507                 }
6508         },
6509
6510         _setOption: function(key, value){
6511                 var self = this,
6512                         uiDialog = self.uiDialog;
6513
6514                 switch (key) {
6515                         //handling of deprecated beforeclose (vs beforeClose) option
6516                         //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6517                         //TODO: remove in 1.9pre
6518                         case "beforeclose":
6519                                 key = "beforeClose";
6520                                 break;
6521                         case "buttons":
6522                                 self._createButtons(value);
6523                                 break;
6524                         case "closeText":
6525                                 // ensure that we always pass a string
6526                                 self.uiDialogTitlebarCloseText.text("" + value);
6527                                 break;
6528                         case "dialogClass":
6529                                 uiDialog
6530                                         .removeClass(self.options.dialogClass)
6531                                         .addClass(uiDialogClasses + value);
6532                                 break;
6533                         case "disabled":
6534                                 if (value) {
6535                                         uiDialog.addClass('ui-dialog-disabled');
6536                                 } else {
6537                                         uiDialog.removeClass('ui-dialog-disabled');
6538                                 }
6539                                 break;
6540                         case "draggable":
6541                                 var isDraggable = uiDialog.is( ":data(draggable)" );
6542                                 if ( isDraggable && !value ) {
6543                                         uiDialog.draggable( "destroy" );
6544                                 }
6545                                 
6546                                 if ( !isDraggable && value ) {
6547                                         self._makeDraggable();
6548                                 }
6549                                 break;
6550                         case "position":
6551                                 self._position(value);
6552                                 break;
6553                         case "resizable":
6554                                 // currently resizable, becoming non-resizable
6555                                 var isResizable = uiDialog.is( ":data(resizable)" );
6556                                 if (isResizable && !value) {
6557                                         uiDialog.resizable('destroy');
6558                                 }
6559
6560                                 // currently resizable, changing handles
6561                                 if (isResizable && typeof value === 'string') {
6562                                         uiDialog.resizable('option', 'handles', value);
6563                                 }
6564
6565                                 // currently non-resizable, becoming resizable
6566                                 if (!isResizable && value !== false) {
6567                                         self._makeResizable(value);
6568                                 }
6569                                 break;
6570                         case "title":
6571                                 // convert whatever was passed in o a string, for html() to not throw up
6572                                 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
6573                                 break;
6574                 }
6575
6576                 $.Widget.prototype._setOption.apply(self, arguments);
6577         },
6578
6579         _size: function() {
6580                 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
6581                  * divs will both have width and height set, so we need to reset them
6582                  */
6583                 var options = this.options,
6584                         nonContentHeight,
6585                         minContentHeight,
6586                         isVisible = this.uiDialog.is( ":visible" );
6587
6588                 // reset content sizing
6589                 this.element.show().css({
6590                         width: 'auto',
6591                         minHeight: 0,
6592                         height: 0
6593                 });
6594
6595                 if (options.minWidth > options.width) {
6596                         options.width = options.minWidth;
6597                 }
6598
6599                 // reset wrapper sizing
6600                 // determine the height of all the non-content elements
6601                 nonContentHeight = this.uiDialog.css({
6602                                 height: 'auto',
6603                                 width: options.width
6604                         })
6605                         .height();
6606                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
6607                 
6608                 if ( options.height === "auto" ) {
6609                         // only needed for IE6 support
6610                         if ( $.support.minHeight ) {
6611                                 this.element.css({
6612                                         minHeight: minContentHeight,
6613                                         height: "auto"
6614                                 });
6615                         } else {
6616                                 this.uiDialog.show();
6617                                 var autoHeight = this.element.css( "height", "auto" ).height();
6618                                 if ( !isVisible ) {
6619                                         this.uiDialog.hide();
6620                                 }
6621                                 this.element.height( Math.max( autoHeight, minContentHeight ) );
6622                         }
6623                 } else {
6624                         this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
6625                 }
6626
6627                 if (this.uiDialog.is(':data(resizable)')) {
6628                         this.uiDialog.resizable('option', 'minHeight', this._minHeight());
6629                 }
6630         }
6631 });
6632
6633 $.extend($.ui.dialog, {
6634         version: "1.8.14",
6635
6636         uuid: 0,
6637         maxZ: 0,
6638
6639         getTitleId: function($el) {
6640                 var id = $el.attr('id');
6641                 if (!id) {
6642                         this.uuid += 1;
6643                         id = this.uuid;
6644                 }
6645                 return 'ui-dialog-title-' + id;
6646         },
6647
6648         overlay: function(dialog) {
6649                 this.$el = $.ui.dialog.overlay.create(dialog);
6650         }
6651 });
6652
6653 $.extend($.ui.dialog.overlay, {
6654         instances: [],
6655         // reuse old instances due to IE memory leak with alpha transparency (see #5185)
6656         oldInstances: [],
6657         maxZ: 0,
6658         events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
6659                 function(event) { return event + '.dialog-overlay'; }).join(' '),
6660         create: function(dialog) {
6661                 if (this.instances.length === 0) {
6662                         // prevent use of anchors and inputs
6663                         // we use a setTimeout in case the overlay is created from an
6664                         // event that we're going to be cancelling (see #2804)
6665                         setTimeout(function() {
6666                                 // handle $(el).dialog().dialog('close') (see #4065)
6667                                 if ($.ui.dialog.overlay.instances.length) {
6668                                         $(document).bind($.ui.dialog.overlay.events, function(event) {
6669                                                 // stop events if the z-index of the target is < the z-index of the overlay
6670                                                 // we cannot return true when we don't want to cancel the event (#3523)
6671                                                 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
6672                                                         return false;
6673                                                 }
6674                                         });
6675                                 }
6676                         }, 1);
6677
6678                         // allow closing by pressing the escape key
6679                         $(document).bind('keydown.dialog-overlay', function(event) {
6680                                 if (dialog.options.closeOnEscape && event.keyCode &&
6681                                         event.keyCode === $.ui.keyCode.ESCAPE) {
6682                                         
6683                                         dialog.close(event);
6684                                         event.preventDefault();
6685                                 }
6686                         });
6687
6688                         // handle window resize
6689                         $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
6690                 }
6691
6692                 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
6693                         .appendTo(document.body)
6694                         .css({
6695                                 width: this.width(),
6696                                 height: this.height()
6697                         });
6698
6699                 if ($.fn.bgiframe) {
6700                         $el.bgiframe();
6701                 }
6702
6703                 this.instances.push($el);
6704                 return $el;
6705         },
6706
6707         destroy: function($el) {
6708                 var indexOf = $.inArray($el, this.instances);
6709                 if (indexOf != -1){
6710                         this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
6711                 }
6712
6713                 if (this.instances.length === 0) {
6714                         $([document, window]).unbind('.dialog-overlay');
6715                 }
6716
6717                 $el.remove();
6718                 
6719                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6720                 var maxZ = 0;
6721                 $.each(this.instances, function() {
6722                         maxZ = Math.max(maxZ, this.css('z-index'));
6723                 });
6724                 this.maxZ = maxZ;
6725         },
6726
6727         height: function() {
6728                 var scrollHeight,
6729                         offsetHeight;
6730                 // handle IE 6
6731                 if ($.browser.msie && $.browser.version < 7) {
6732                         scrollHeight = Math.max(
6733                                 document.documentElement.scrollHeight,
6734                                 document.body.scrollHeight
6735                         );
6736                         offsetHeight = Math.max(
6737                                 document.documentElement.offsetHeight,
6738                                 document.body.offsetHeight
6739                         );
6740
6741                         if (scrollHeight < offsetHeight) {
6742                                 return $(window).height() + 'px';
6743                         } else {
6744                                 return scrollHeight + 'px';
6745                         }
6746                 // handle "good" browsers
6747                 } else {
6748                         return $(document).height() + 'px';
6749                 }
6750         },
6751
6752         width: function() {
6753                 var scrollWidth,
6754                         offsetWidth;
6755                 // handle IE
6756                 if ( $.browser.msie ) {
6757                         scrollWidth = Math.max(
6758                                 document.documentElement.scrollWidth,
6759                                 document.body.scrollWidth
6760                         );
6761                         offsetWidth = Math.max(
6762                                 document.documentElement.offsetWidth,
6763                                 document.body.offsetWidth
6764                         );
6765
6766                         if (scrollWidth < offsetWidth) {
6767                                 return $(window).width() + 'px';
6768                         } else {
6769                                 return scrollWidth + 'px';
6770                         }
6771                 // handle "good" browsers
6772                 } else {
6773                         return $(document).width() + 'px';
6774                 }
6775         },
6776
6777         resize: function() {
6778                 /* If the dialog is draggable and the user drags it past the
6779                  * right edge of the window, the document becomes wider so we
6780                  * need to stretch the overlay. If the user then drags the
6781                  * dialog back to the left, the document will become narrower,
6782                  * so we need to shrink the overlay to the appropriate size.
6783                  * This is handled by shrinking the overlay before setting it
6784                  * to the full document size.
6785                  */
6786                 var $overlays = $([]);
6787                 $.each($.ui.dialog.overlay.instances, function() {
6788                         $overlays = $overlays.add(this);
6789                 });
6790
6791                 $overlays.css({
6792                         width: 0,
6793                         height: 0
6794                 }).css({
6795                         width: $.ui.dialog.overlay.width(),
6796                         height: $.ui.dialog.overlay.height()
6797                 });
6798         }
6799 });
6800
6801 $.extend($.ui.dialog.overlay.prototype, {
6802         destroy: function() {
6803                 $.ui.dialog.overlay.destroy(this.$el);
6804         }
6805 });
6806
6807 }(jQuery));
6808 /*
6809  * jQuery UI Slider 1.8.14
6810  *
6811  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6812  * Dual licensed under the MIT or GPL Version 2 licenses.
6813  * http://jquery.org/license
6814  *
6815  * http://docs.jquery.com/UI/Slider
6816  *
6817  * Depends:
6818  *      jquery.ui.core.js
6819  *      jquery.ui.mouse.js
6820  *      jquery.ui.widget.js
6821  */
6822 (function( $, undefined ) {
6823
6824 // number of pages in a slider
6825 // (how many times can you page up/down to go through the whole range)
6826 var numPages = 5;
6827
6828 $.widget( "ui.slider", $.ui.mouse, {
6829
6830         widgetEventPrefix: "slide",
6831
6832         options: {
6833                 animate: false,
6834                 distance: 0,
6835                 max: 100,
6836                 min: 0,
6837                 orientation: "horizontal",
6838                 range: false,
6839                 step: 1,
6840                 value: 0,
6841                 values: null
6842         },
6843
6844         _create: function() {
6845                 var self = this,
6846                         o = this.options,
6847                         existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
6848                         handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
6849                         handleCount = ( o.values && o.values.length ) || 1,
6850                         handles = [];
6851
6852                 this._keySliding = false;
6853                 this._mouseSliding = false;
6854                 this._animateOff = true;
6855                 this._handleIndex = null;
6856                 this._detectOrientation();
6857                 this._mouseInit();
6858
6859                 this.element
6860                         .addClass( "ui-slider" +
6861                                 " ui-slider-" + this.orientation +
6862                                 " ui-widget" +
6863                                 " ui-widget-content" +
6864                                 " ui-corner-all" +
6865                                 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
6866
6867                 this.range = $([]);
6868
6869                 if ( o.range ) {
6870                         if ( o.range === true ) {
6871                                 if ( !o.values ) {
6872                                         o.values = [ this._valueMin(), this._valueMin() ];
6873                                 }
6874                                 if ( o.values.length && o.values.length !== 2 ) {
6875                                         o.values = [ o.values[0], o.values[0] ];
6876                                 }
6877                         }
6878
6879                         this.range = $( "<div></div>" )
6880                                 .appendTo( this.element )
6881                                 .addClass( "ui-slider-range" +
6882                                 // note: this isn't the most fittingly semantic framework class for this element,
6883                                 // but worked best visually with a variety of themes
6884                                 " ui-widget-header" + 
6885                                 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
6886                 }
6887
6888                 for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
6889                         handles.push( handle );
6890                 }
6891
6892                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
6893
6894                 this.handle = this.handles.eq( 0 );
6895
6896                 this.handles.add( this.range ).filter( "a" )
6897                         .click(function( event ) {
6898                                 event.preventDefault();
6899                         })
6900                         .hover(function() {
6901                                 if ( !o.disabled ) {
6902                                         $( this ).addClass( "ui-state-hover" );
6903                                 }
6904                         }, function() {
6905                                 $( this ).removeClass( "ui-state-hover" );
6906                         })
6907                         .focus(function() {
6908                                 if ( !o.disabled ) {
6909                                         $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
6910                                         $( this ).addClass( "ui-state-focus" );
6911                                 } else {
6912                                         $( this ).blur();
6913                                 }
6914                         })
6915                         .blur(function() {
6916                                 $( this ).removeClass( "ui-state-focus" );
6917                         });
6918
6919                 this.handles.each(function( i ) {
6920                         $( this ).data( "index.ui-slider-handle", i );
6921                 });
6922
6923                 this.handles
6924                         .keydown(function( event ) {
6925                                 var ret = true,
6926                                         index = $( this ).data( "index.ui-slider-handle" ),
6927                                         allowed,
6928                                         curVal,
6929                                         newVal,
6930                                         step;
6931         
6932                                 if ( self.options.disabled ) {
6933                                         return;
6934                                 }
6935         
6936                                 switch ( event.keyCode ) {
6937                                         case $.ui.keyCode.HOME:
6938                                         case $.ui.keyCode.END:
6939                                         case $.ui.keyCode.PAGE_UP:
6940                                         case $.ui.keyCode.PAGE_DOWN:
6941                                         case $.ui.keyCode.UP:
6942                                         case $.ui.keyCode.RIGHT:
6943                                         case $.ui.keyCode.DOWN:
6944                                         case $.ui.keyCode.LEFT:
6945                                                 ret = false;
6946                                                 if ( !self._keySliding ) {
6947                                                         self._keySliding = true;
6948                                                         $( this ).addClass( "ui-state-active" );
6949                                                         allowed = self._start( event, index );
6950                                                         if ( allowed === false ) {
6951                                                                 return;
6952                                                         }
6953                                                 }
6954                                                 break;
6955                                 }
6956         
6957                                 step = self.options.step;
6958                                 if ( self.options.values && self.options.values.length ) {
6959                                         curVal = newVal = self.values( index );
6960                                 } else {
6961                                         curVal = newVal = self.value();
6962                                 }
6963         
6964                                 switch ( event.keyCode ) {
6965                                         case $.ui.keyCode.HOME:
6966                                                 newVal = self._valueMin();
6967                                                 break;
6968                                         case $.ui.keyCode.END:
6969                                                 newVal = self._valueMax();
6970                                                 break;
6971                                         case $.ui.keyCode.PAGE_UP:
6972                                                 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
6973                                                 break;
6974                                         case $.ui.keyCode.PAGE_DOWN:
6975                                                 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
6976                                                 break;
6977                                         case $.ui.keyCode.UP:
6978                                         case $.ui.keyCode.RIGHT:
6979                                                 if ( curVal === self._valueMax() ) {
6980                                                         return;
6981                                                 }
6982                                                 newVal = self._trimAlignValue( curVal + step );
6983                                                 break;
6984                                         case $.ui.keyCode.DOWN:
6985                                         case $.ui.keyCode.LEFT:
6986                                                 if ( curVal === self._valueMin() ) {
6987                                                         return;
6988                                                 }
6989                                                 newVal = self._trimAlignValue( curVal - step );
6990                                                 break;
6991                                 }
6992         
6993                                 self._slide( event, index, newVal );
6994         
6995                                 return ret;
6996         
6997                         })
6998                         .keyup(function( event ) {
6999                                 var index = $( this ).data( "index.ui-slider-handle" );
7000         
7001                                 if ( self._keySliding ) {
7002                                         self._keySliding = false;
7003                                         self._stop( event, index );
7004                                         self._change( event, index );
7005                                         $( this ).removeClass( "ui-state-active" );
7006                                 }
7007         
7008                         });
7009
7010                 this._refreshValue();
7011
7012                 this._animateOff = false;
7013         },
7014
7015         destroy: function() {
7016                 this.handles.remove();
7017                 this.range.remove();
7018
7019                 this.element
7020                         .removeClass( "ui-slider" +
7021                                 " ui-slider-horizontal" +
7022                                 " ui-slider-vertical" +
7023                                 " ui-slider-disabled" +
7024                                 " ui-widget" +
7025                                 " ui-widget-content" +
7026                                 " ui-corner-all" )
7027                         .removeData( "slider" )
7028                         .unbind( ".slider" );
7029
7030                 this._mouseDestroy();
7031
7032                 return this;
7033         },
7034
7035         _mouseCapture: function( event ) {
7036                 var o = this.options,
7037                         position,
7038                         normValue,
7039                         distance,
7040                         closestHandle,
7041                         self,
7042                         index,
7043                         allowed,
7044                         offset,
7045                         mouseOverHandle;
7046
7047                 if ( o.disabled ) {
7048                         return false;
7049                 }
7050
7051                 this.elementSize = {
7052                         width: this.element.outerWidth(),
7053                         height: this.element.outerHeight()
7054                 };
7055                 this.elementOffset = this.element.offset();
7056
7057                 position = { x: event.pageX, y: event.pageY };
7058                 normValue = this._normValueFromMouse( position );
7059                 distance = this._valueMax() - this._valueMin() + 1;
7060                 self = this;
7061                 this.handles.each(function( i ) {
7062                         var thisDistance = Math.abs( normValue - self.values(i) );
7063                         if ( distance > thisDistance ) {
7064                                 distance = thisDistance;
7065                                 closestHandle = $( this );
7066                                 index = i;
7067                         }
7068                 });
7069
7070                 // workaround for bug #3736 (if both handles of a range are at 0,
7071                 // the first is always used as the one with least distance,
7072                 // and moving it is obviously prevented by preventing negative ranges)
7073                 if( o.range === true && this.values(1) === o.min ) {
7074                         index += 1;
7075                         closestHandle = $( this.handles[index] );
7076                 }
7077
7078                 allowed = this._start( event, index );
7079                 if ( allowed === false ) {
7080                         return false;
7081                 }
7082                 this._mouseSliding = true;
7083
7084                 self._handleIndex = index;
7085
7086                 closestHandle
7087                         .addClass( "ui-state-active" )
7088                         .focus();
7089                 
7090                 offset = closestHandle.offset();
7091                 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
7092                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
7093                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
7094                         top: event.pageY - offset.top -
7095                                 ( closestHandle.height() / 2 ) -
7096                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
7097                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
7098                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
7099                 };
7100
7101                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
7102                         this._slide( event, index, normValue );
7103                 }
7104                 this._animateOff = true;
7105                 return true;
7106         },
7107
7108         _mouseStart: function( event ) {
7109                 return true;
7110         },
7111
7112         _mouseDrag: function( event ) {
7113                 var position = { x: event.pageX, y: event.pageY },
7114                         normValue = this._normValueFromMouse( position );
7115                 
7116                 this._slide( event, this._handleIndex, normValue );
7117
7118                 return false;
7119         },
7120
7121         _mouseStop: function( event ) {
7122                 this.handles.removeClass( "ui-state-active" );
7123                 this._mouseSliding = false;
7124
7125                 this._stop( event, this._handleIndex );
7126                 this._change( event, this._handleIndex );
7127
7128                 this._handleIndex = null;
7129                 this._clickOffset = null;
7130                 this._animateOff = false;
7131
7132                 return false;
7133         },
7134         
7135         _detectOrientation: function() {
7136                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
7137         },
7138
7139         _normValueFromMouse: function( position ) {
7140                 var pixelTotal,
7141                         pixelMouse,
7142                         percentMouse,
7143                         valueTotal,
7144                         valueMouse;
7145
7146                 if ( this.orientation === "horizontal" ) {
7147                         pixelTotal = this.elementSize.width;
7148                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
7149                 } else {
7150                         pixelTotal = this.elementSize.height;
7151                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
7152                 }
7153
7154                 percentMouse = ( pixelMouse / pixelTotal );
7155                 if ( percentMouse > 1 ) {
7156                         percentMouse = 1;
7157                 }
7158                 if ( percentMouse < 0 ) {
7159                         percentMouse = 0;
7160                 }
7161                 if ( this.orientation === "vertical" ) {
7162                         percentMouse = 1 - percentMouse;
7163                 }
7164
7165                 valueTotal = this._valueMax() - this._valueMin();
7166                 valueMouse = this._valueMin() + percentMouse * valueTotal;
7167
7168                 return this._trimAlignValue( valueMouse );
7169         },
7170
7171         _start: function( event, index ) {
7172                 var uiHash = {
7173                         handle: this.handles[ index ],
7174                         value: this.value()
7175                 };
7176                 if ( this.options.values && this.options.values.length ) {
7177                         uiHash.value = this.values( index );
7178                         uiHash.values = this.values();
7179                 }
7180                 return this._trigger( "start", event, uiHash );
7181         },
7182
7183         _slide: function( event, index, newVal ) {
7184                 var otherVal,
7185                         newValues,
7186                         allowed;
7187
7188                 if ( this.options.values && this.options.values.length ) {
7189                         otherVal = this.values( index ? 0 : 1 );
7190
7191                         if ( ( this.options.values.length === 2 && this.options.range === true ) && 
7192                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
7193                                 ) {
7194                                 newVal = otherVal;
7195                         }
7196
7197                         if ( newVal !== this.values( index ) ) {
7198                                 newValues = this.values();
7199                                 newValues[ index ] = newVal;
7200                                 // A slide can be canceled by returning false from the slide callback
7201                                 allowed = this._trigger( "slide", event, {
7202                                         handle: this.handles[ index ],
7203                                         value: newVal,
7204                                         values: newValues
7205                                 } );
7206                                 otherVal = this.values( index ? 0 : 1 );
7207                                 if ( allowed !== false ) {
7208                                         this.values( index, newVal, true );
7209                                 }
7210                         }
7211                 } else {
7212                         if ( newVal !== this.value() ) {
7213                                 // A slide can be canceled by returning false from the slide callback
7214                                 allowed = this._trigger( "slide", event, {
7215                                         handle: this.handles[ index ],
7216                                         value: newVal
7217                                 } );
7218                                 if ( allowed !== false ) {
7219                                         this.value( newVal );
7220                                 }
7221                         }
7222                 }
7223         },
7224
7225         _stop: function( event, index ) {
7226                 var uiHash = {
7227                         handle: this.handles[ index ],
7228                         value: this.value()
7229                 };
7230                 if ( this.options.values && this.options.values.length ) {
7231                         uiHash.value = this.values( index );
7232                         uiHash.values = this.values();
7233                 }
7234
7235                 this._trigger( "stop", event, uiHash );
7236         },
7237
7238         _change: function( event, index ) {
7239                 if ( !this._keySliding && !this._mouseSliding ) {
7240                         var uiHash = {
7241                                 handle: this.handles[ index ],
7242                                 value: this.value()
7243                         };
7244                         if ( this.options.values && this.options.values.length ) {
7245                                 uiHash.value = this.values( index );
7246                                 uiHash.values = this.values();
7247                         }
7248
7249                         this._trigger( "change", event, uiHash );
7250                 }
7251         },
7252
7253         value: function( newValue ) {
7254                 if ( arguments.length ) {
7255                         this.options.value = this._trimAlignValue( newValue );
7256                         this._refreshValue();
7257                         this._change( null, 0 );
7258                         return;
7259                 }
7260
7261                 return this._value();
7262         },
7263
7264         values: function( index, newValue ) {
7265                 var vals,
7266                         newValues,
7267                         i;
7268
7269                 if ( arguments.length > 1 ) {
7270                         this.options.values[ index ] = this._trimAlignValue( newValue );
7271                         this._refreshValue();
7272                         this._change( null, index );
7273                         return;
7274                 }
7275
7276                 if ( arguments.length ) {
7277                         if ( $.isArray( arguments[ 0 ] ) ) {
7278                                 vals = this.options.values;
7279                                 newValues = arguments[ 0 ];
7280                                 for ( i = 0; i < vals.length; i += 1 ) {
7281                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
7282                                         this._change( null, i );
7283                                 }
7284                                 this._refreshValue();
7285                         } else {
7286                                 if ( this.options.values && this.options.values.length ) {
7287                                         return this._values( index );
7288                                 } else {
7289                                         return this.value();
7290                                 }
7291                         }
7292                 } else {
7293                         return this._values();
7294                 }
7295         },
7296
7297         _setOption: function( key, value ) {
7298                 var i,
7299                         valsLength = 0;
7300
7301                 if ( $.isArray( this.options.values ) ) {
7302                         valsLength = this.options.values.length;
7303                 }
7304
7305                 $.Widget.prototype._setOption.apply( this, arguments );
7306
7307                 switch ( key ) {
7308                         case "disabled":
7309                                 if ( value ) {
7310                                         this.handles.filter( ".ui-state-focus" ).blur();
7311                                         this.handles.removeClass( "ui-state-hover" );
7312                                         this.handles.attr( "disabled", "disabled" );
7313                                         this.element.addClass( "ui-disabled" );
7314                                 } else {
7315                                         this.handles.removeAttr( "disabled" );
7316                                         this.element.removeClass( "ui-disabled" );
7317                                 }
7318                                 break;
7319                         case "orientation":
7320                                 this._detectOrientation();
7321                                 this.element
7322                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
7323                                         .addClass( "ui-slider-" + this.orientation );
7324                                 this._refreshValue();
7325                                 break;
7326                         case "value":
7327                                 this._animateOff = true;
7328                                 this._refreshValue();
7329                                 this._change( null, 0 );
7330                                 this._animateOff = false;
7331                                 break;
7332                         case "values":
7333                                 this._animateOff = true;
7334                                 this._refreshValue();
7335                                 for ( i = 0; i < valsLength; i += 1 ) {
7336                                         this._change( null, i );
7337                                 }
7338                                 this._animateOff = false;
7339                                 break;
7340                 }
7341         },
7342
7343         //internal value getter
7344         // _value() returns value trimmed by min and max, aligned by step
7345         _value: function() {
7346                 var val = this.options.value;
7347                 val = this._trimAlignValue( val );
7348
7349                 return val;
7350         },
7351
7352         //internal values getter
7353         // _values() returns array of values trimmed by min and max, aligned by step
7354         // _values( index ) returns single value trimmed by min and max, aligned by step
7355         _values: function( index ) {
7356                 var val,
7357                         vals,
7358                         i;
7359
7360                 if ( arguments.length ) {
7361                         val = this.options.values[ index ];
7362                         val = this._trimAlignValue( val );
7363
7364                         return val;
7365                 } else {
7366                         // .slice() creates a copy of the array
7367                         // this copy gets trimmed by min and max and then returned
7368                         vals = this.options.values.slice();
7369                         for ( i = 0; i < vals.length; i+= 1) {
7370                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
7371                         }
7372
7373                         return vals;
7374                 }
7375         },
7376         
7377         // returns the step-aligned value that val is closest to, between (inclusive) min and max
7378         _trimAlignValue: function( val ) {
7379                 if ( val <= this._valueMin() ) {
7380                         return this._valueMin();
7381                 }
7382                 if ( val >= this._valueMax() ) {
7383                         return this._valueMax();
7384                 }
7385                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
7386                         valModStep = (val - this._valueMin()) % step;
7387                         alignValue = val - valModStep;
7388
7389                 if ( Math.abs(valModStep) * 2 >= step ) {
7390                         alignValue += ( valModStep > 0 ) ? step : ( -step );
7391                 }
7392
7393                 // Since JavaScript has problems with large floats, round
7394                 // the final value to 5 digits after the decimal point (see #4124)
7395                 return parseFloat( alignValue.toFixed(5) );
7396         },
7397
7398         _valueMin: function() {
7399                 return this.options.min;
7400         },
7401
7402         _valueMax: function() {
7403                 return this.options.max;
7404         },
7405         
7406         _refreshValue: function() {
7407                 var oRange = this.options.range,
7408                         o = this.options,
7409                         self = this,
7410                         animate = ( !this._animateOff ) ? o.animate : false,
7411                         valPercent,
7412                         _set = {},
7413                         lastValPercent,
7414                         value,
7415                         valueMin,
7416                         valueMax;
7417
7418                 if ( this.options.values && this.options.values.length ) {
7419                         this.handles.each(function( i, j ) {
7420                                 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
7421                                 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7422                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7423                                 if ( self.options.range === true ) {
7424                                         if ( self.orientation === "horizontal" ) {
7425                                                 if ( i === 0 ) {
7426                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
7427                                                 }
7428                                                 if ( i === 1 ) {
7429                                                         self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7430                                                 }
7431                                         } else {
7432                                                 if ( i === 0 ) {
7433                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
7434                                                 }
7435                                                 if ( i === 1 ) {
7436                                                         self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7437                                                 }
7438                                         }
7439                                 }
7440                                 lastValPercent = valPercent;
7441                         });
7442                 } else {
7443                         value = this.value();
7444                         valueMin = this._valueMin();
7445                         valueMax = this._valueMax();
7446                         valPercent = ( valueMax !== valueMin ) ?
7447                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
7448                                         0;
7449                         _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7450                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7451
7452                         if ( oRange === "min" && this.orientation === "horizontal" ) {
7453                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
7454                         }
7455                         if ( oRange === "max" && this.orientation === "horizontal" ) {
7456                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7457                         }
7458                         if ( oRange === "min" && this.orientation === "vertical" ) {
7459                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
7460                         }
7461                         if ( oRange === "max" && this.orientation === "vertical" ) {
7462                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7463                         }
7464                 }
7465         }
7466
7467 });
7468
7469 $.extend( $.ui.slider, {
7470         version: "1.8.14"
7471 });
7472
7473 }(jQuery));
7474 /*
7475  * jQuery UI Tabs 1.8.14
7476  *
7477  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
7478  * Dual licensed under the MIT or GPL Version 2 licenses.
7479  * http://jquery.org/license
7480  *
7481  * http://docs.jquery.com/UI/Tabs
7482  *
7483  * Depends:
7484  *      jquery.ui.core.js
7485  *      jquery.ui.widget.js
7486  */
7487 (function( $, undefined ) {
7488
7489 var tabId = 0,
7490         listId = 0;
7491
7492 function getNextTabId() {
7493         return ++tabId;
7494 }
7495
7496 function getNextListId() {
7497         return ++listId;
7498 }
7499
7500 $.widget( "ui.tabs", {
7501         options: {
7502                 add: null,
7503                 ajaxOptions: null,
7504                 cache: false,
7505                 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
7506                 collapsible: false,
7507                 disable: null,
7508                 disabled: [],
7509                 enable: null,
7510                 event: "click",
7511                 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
7512                 idPrefix: "ui-tabs-",
7513                 load: null,
7514                 panelTemplate: "<div></div>",
7515                 remove: null,
7516                 select: null,
7517                 show: null,
7518                 spinner: "<em>Loading&#8230;</em>",
7519                 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
7520         },
7521
7522         _create: function() {
7523                 this._tabify( true );
7524         },
7525
7526         _setOption: function( key, value ) {
7527                 if ( key == "selected" ) {
7528                         if (this.options.collapsible && value == this.options.selected ) {
7529                                 return;
7530                         }
7531                         this.select( value );
7532                 } else {
7533                         this.options[ key ] = value;
7534                         this._tabify();
7535                 }
7536         },
7537
7538         _tabId: function( a ) {
7539                 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
7540                         this.options.idPrefix + getNextTabId();
7541         },
7542
7543         _sanitizeSelector: function( hash ) {
7544                 // we need this because an id may contain a ":"
7545                 return hash.replace( /:/g, "\\:" );
7546         },
7547
7548         _cookie: function() {
7549                 var cookie = this.cookie ||
7550                         ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
7551                 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
7552         },
7553
7554         _ui: function( tab, panel ) {
7555                 return {
7556                         tab: tab,
7557                         panel: panel,
7558                         index: this.anchors.index( tab )
7559                 };
7560         },
7561
7562         _cleanup: function() {
7563                 // restore all former loading tabs labels
7564                 this.lis.filter( ".ui-state-processing" )
7565                         .removeClass( "ui-state-processing" )
7566                         .find( "span:data(label.tabs)" )
7567                                 .each(function() {
7568                                         var el = $( this );
7569                                         el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
7570                                 });
7571         },
7572
7573         _tabify: function( init ) {
7574                 var self = this,
7575                         o = this.options,
7576                         fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
7577
7578                 this.list = this.element.find( "ol,ul" ).eq( 0 );
7579                 this.lis = $( " > li:has(a[href])", this.list );
7580                 this.anchors = this.lis.map(function() {
7581                         return $( "a", this )[ 0 ];
7582                 });
7583                 this.panels = $( [] );
7584
7585                 this.anchors.each(function( i, a ) {
7586                         var href = $( a ).attr( "href" );
7587                         // For dynamically created HTML that contains a hash as href IE < 8 expands
7588                         // such href to the full page url with hash and then misinterprets tab as ajax.
7589                         // Same consideration applies for an added tab with a fragment identifier
7590                         // since a[href=#fragment-identifier] does unexpectedly not match.
7591                         // Thus normalize href attribute...
7592                         var hrefBase = href.split( "#" )[ 0 ],
7593                                 baseEl;
7594                         if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
7595                                         ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
7596                                 href = a.hash;
7597                                 a.href = href;
7598                         }
7599
7600                         // inline tab
7601                         if ( fragmentId.test( href ) ) {
7602                                 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
7603                         // remote tab
7604                         // prevent loading the page itself if href is just "#"
7605                         } else if ( href && href !== "#" ) {
7606                                 // required for restore on destroy
7607                                 $.data( a, "href.tabs", href );
7608
7609                                 // TODO until #3808 is fixed strip fragment identifier from url
7610                                 // (IE fails to load from such url)
7611                                 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
7612
7613                                 var id = self._tabId( a );
7614                                 a.href = "#" + id;
7615                                 var $panel = self.element.find( "#" + id );
7616                                 if ( !$panel.length ) {
7617                                         $panel = $( o.panelTemplate )
7618                                                 .attr( "id", id )
7619                                                 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
7620                                                 .insertAfter( self.panels[ i - 1 ] || self.list );
7621                                         $panel.data( "destroy.tabs", true );
7622                                 }
7623                                 self.panels = self.panels.add( $panel );
7624                         // invalid tab href
7625                         } else {
7626                                 o.disabled.push( i );
7627                         }
7628                 });
7629
7630                 // initialization from scratch
7631                 if ( init ) {
7632                         // attach necessary classes for styling
7633                         this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
7634                         this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7635                         this.lis.addClass( "ui-state-default ui-corner-top" );
7636                         this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
7637
7638                         // Selected tab
7639                         // use "selected" option or try to retrieve:
7640                         // 1. from fragment identifier in url
7641                         // 2. from cookie
7642                         // 3. from selected class attribute on <li>
7643                         if ( o.selected === undefined ) {
7644                                 if ( location.hash ) {
7645                                         this.anchors.each(function( i, a ) {
7646                                                 if ( a.hash == location.hash ) {
7647                                                         o.selected = i;
7648                                                         return false;
7649                                                 }
7650                                         });
7651                                 }
7652                                 if ( typeof o.selected !== "number" && o.cookie ) {
7653                                         o.selected = parseInt( self._cookie(), 10 );
7654                                 }
7655                                 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
7656                                         o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7657                                 }
7658                                 o.selected = o.selected || ( this.lis.length ? 0 : -1 );
7659                         } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
7660                                 o.selected = -1;
7661                         }
7662
7663                         // sanity check - default to first tab...
7664                         o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
7665                                 ? o.selected
7666                                 : 0;
7667
7668                         // Take disabling tabs via class attribute from HTML
7669                         // into account and update option properly.
7670                         // A selected tab cannot become disabled.
7671                         o.disabled = $.unique( o.disabled.concat(
7672                                 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
7673                                         return self.lis.index( n );
7674                                 })
7675                         ) ).sort();
7676
7677                         if ( $.inArray( o.selected, o.disabled ) != -1 ) {
7678                                 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
7679                         }
7680
7681                         // highlight selected tab
7682                         this.panels.addClass( "ui-tabs-hide" );
7683                         this.lis.removeClass( "ui-tabs-selected ui-state-active" );
7684                         // check for length avoids error when initializing empty list
7685                         if ( o.selected >= 0 && this.anchors.length ) {
7686                                 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
7687                                 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
7688
7689                                 // seems to be expected behavior that the show callback is fired
7690                                 self.element.queue( "tabs", function() {
7691                                         self._trigger( "show", null,
7692                                                 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
7693                                 });
7694
7695                                 this.load( o.selected );
7696                         }
7697
7698                         // clean up to avoid memory leaks in certain versions of IE 6
7699                         // TODO: namespace this event
7700                         $( window ).bind( "unload", function() {
7701                                 self.lis.add( self.anchors ).unbind( ".tabs" );
7702                                 self.lis = self.anchors = self.panels = null;
7703                         });
7704                 // update selected after add/remove
7705                 } else {
7706                         o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7707                 }
7708
7709                 // update collapsible
7710                 // TODO: use .toggleClass()
7711                 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
7712
7713                 // set or update cookie after init and add/remove respectively
7714                 if ( o.cookie ) {
7715                         this._cookie( o.selected, o.cookie );
7716                 }
7717
7718                 // disable tabs
7719                 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
7720                         $( li )[ $.inArray( i, o.disabled ) != -1 &&
7721                                 // TODO: use .toggleClass()
7722                                 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
7723                 }
7724
7725                 // reset cache if switching from cached to not cached
7726                 if ( o.cache === false ) {
7727                         this.anchors.removeData( "cache.tabs" );
7728                 }
7729
7730                 // remove all handlers before, tabify may run on existing tabs after add or option change
7731                 this.lis.add( this.anchors ).unbind( ".tabs" );
7732
7733                 if ( o.event !== "mouseover" ) {
7734                         var addState = function( state, el ) {
7735                                 if ( el.is( ":not(.ui-state-disabled)" ) ) {
7736                                         el.addClass( "ui-state-" + state );
7737                                 }
7738                         };
7739                         var removeState = function( state, el ) {
7740                                 el.removeClass( "ui-state-" + state );
7741                         };
7742                         this.lis.bind( "mouseover.tabs" , function() {
7743                                 addState( "hover", $( this ) );
7744                         });
7745                         this.lis.bind( "mouseout.tabs", function() {
7746                                 removeState( "hover", $( this ) );
7747                         });
7748                         this.anchors.bind( "focus.tabs", function() {
7749                                 addState( "focus", $( this ).closest( "li" ) );
7750                         });
7751                         this.anchors.bind( "blur.tabs", function() {
7752                                 removeState( "focus", $( this ).closest( "li" ) );
7753                         });
7754                 }
7755
7756                 // set up animations
7757                 var hideFx, showFx;
7758                 if ( o.fx ) {
7759                         if ( $.isArray( o.fx ) ) {
7760                                 hideFx = o.fx[ 0 ];
7761                                 showFx = o.fx[ 1 ];
7762                         } else {
7763                                 hideFx = showFx = o.fx;
7764                         }
7765                 }
7766
7767                 // Reset certain styles left over from animation
7768                 // and prevent IE's ClearType bug...
7769                 function resetStyle( $el, fx ) {
7770                         $el.css( "display", "" );
7771                         if ( !$.support.opacity && fx.opacity ) {
7772                                 $el[ 0 ].style.removeAttribute( "filter" );
7773                         }
7774                 }
7775
7776                 // Show a tab...
7777                 var showTab = showFx
7778                         ? function( clicked, $show ) {
7779                                 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7780                                 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
7781                                         .animate( showFx, showFx.duration || "normal", function() {
7782                                                 resetStyle( $show, showFx );
7783                                                 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7784                                         });
7785                         }
7786                         : function( clicked, $show ) {
7787                                 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7788                                 $show.removeClass( "ui-tabs-hide" );
7789                                 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7790                         };
7791
7792                 // Hide a tab, $show is optional...
7793                 var hideTab = hideFx
7794                         ? function( clicked, $hide ) {
7795                                 $hide.animate( hideFx, hideFx.duration || "normal", function() {
7796                                         self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7797                                         $hide.addClass( "ui-tabs-hide" );
7798                                         resetStyle( $hide, hideFx );
7799                                         self.element.dequeue( "tabs" );
7800                                 });
7801                         }
7802                         : function( clicked, $hide, $show ) {
7803                                 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7804                                 $hide.addClass( "ui-tabs-hide" );
7805                                 self.element.dequeue( "tabs" );
7806                         };
7807
7808                 // attach tab event handler, unbind to avoid duplicates from former tabifying...
7809                 this.anchors.bind( o.event + ".tabs", function() {
7810                         var el = this,
7811                                 $li = $(el).closest( "li" ),
7812                                 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
7813                                 $show = self.element.find( self._sanitizeSelector( el.hash ) );
7814
7815                         // If tab is already selected and not collapsible or tab disabled or
7816                         // or is already loading or click callback returns false stop here.
7817                         // Check if click handler returns false last so that it is not executed
7818                         // for a disabled or loading tab!
7819                         if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
7820                                 $li.hasClass( "ui-state-disabled" ) ||
7821                                 $li.hasClass( "ui-state-processing" ) ||
7822                                 self.panels.filter( ":animated" ).length ||
7823                                 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
7824                                 this.blur();
7825                                 return false;
7826                         }
7827
7828                         o.selected = self.anchors.index( this );
7829
7830                         self.abort();
7831
7832                         // if tab may be closed
7833                         if ( o.collapsible ) {
7834                                 if ( $li.hasClass( "ui-tabs-selected" ) ) {
7835                                         o.selected = -1;
7836
7837                                         if ( o.cookie ) {
7838                                                 self._cookie( o.selected, o.cookie );
7839                                         }
7840
7841                                         self.element.queue( "tabs", function() {
7842                                                 hideTab( el, $hide );
7843                                         }).dequeue( "tabs" );
7844
7845                                         this.blur();
7846                                         return false;
7847                                 } else if ( !$hide.length ) {
7848                                         if ( o.cookie ) {
7849                                                 self._cookie( o.selected, o.cookie );
7850                                         }
7851
7852                                         self.element.queue( "tabs", function() {
7853                                                 showTab( el, $show );
7854                                         });
7855
7856                                         // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
7857                                         self.load( self.anchors.index( this ) );
7858
7859                                         this.blur();
7860                                         return false;
7861                                 }
7862                         }
7863
7864                         if ( o.cookie ) {
7865                                 self._cookie( o.selected, o.cookie );
7866                         }
7867
7868                         // show new tab
7869                         if ( $show.length ) {
7870                                 if ( $hide.length ) {
7871                                         self.element.queue( "tabs", function() {
7872                                                 hideTab( el, $hide );
7873                                         });
7874                                 }
7875                                 self.element.queue( "tabs", function() {
7876                                         showTab( el, $show );
7877                                 });
7878
7879                                 self.load( self.anchors.index( this ) );
7880                         } else {
7881                                 throw "jQuery UI Tabs: Mismatching fragment identifier.";
7882                         }
7883
7884                         // Prevent IE from keeping other link focussed when using the back button
7885                         // and remove dotted border from clicked link. This is controlled via CSS
7886                         // in modern browsers; blur() removes focus from address bar in Firefox
7887                         // which can become a usability and annoying problem with tabs('rotate').
7888                         if ( $.browser.msie ) {
7889                                 this.blur();
7890                         }
7891                 });
7892
7893                 // disable click in any case
7894                 this.anchors.bind( "click.tabs", function(){
7895                         return false;
7896                 });
7897         },
7898
7899     _getIndex: function( index ) {
7900                 // meta-function to give users option to provide a href string instead of a numerical index.
7901                 // also sanitizes numerical indexes to valid values.
7902                 if ( typeof index == "string" ) {
7903                         index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
7904                 }
7905
7906                 return index;
7907         },
7908
7909         destroy: function() {
7910                 var o = this.options;
7911
7912                 this.abort();
7913
7914                 this.element
7915                         .unbind( ".tabs" )
7916                         .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
7917                         .removeData( "tabs" );
7918
7919                 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7920
7921                 this.anchors.each(function() {
7922                         var href = $.data( this, "href.tabs" );
7923                         if ( href ) {
7924                                 this.href = href;
7925                         }
7926                         var $this = $( this ).unbind( ".tabs" );
7927                         $.each( [ "href", "load", "cache" ], function( i, prefix ) {
7928                                 $this.removeData( prefix + ".tabs" );
7929                         });
7930                 });
7931
7932                 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
7933                         if ( $.data( this, "destroy.tabs" ) ) {
7934                                 $( this ).remove();
7935                         } else {
7936                                 $( this ).removeClass([
7937                                         "ui-state-default",
7938                                         "ui-corner-top",
7939                                         "ui-tabs-selected",
7940                                         "ui-state-active",
7941                                         "ui-state-hover",
7942                                         "ui-state-focus",
7943                                         "ui-state-disabled",
7944                                         "ui-tabs-panel",
7945                                         "ui-widget-content",
7946                                         "ui-corner-bottom",
7947                                         "ui-tabs-hide"
7948                                 ].join( " " ) );
7949                         }
7950                 });
7951
7952                 if ( o.cookie ) {
7953                         this._cookie( null, o.cookie );
7954                 }
7955
7956                 return this;
7957         },
7958
7959         add: function( url, label, index ) {
7960                 if ( index === undefined ) {
7961                         index = this.anchors.length;
7962                 }
7963
7964                 var self = this,
7965                         o = this.options,
7966                         $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
7967                         id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
7968
7969                 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
7970
7971                 // try to find an existing element before creating a new one
7972                 var $panel = self.element.find( "#" + id );
7973                 if ( !$panel.length ) {
7974                         $panel = $( o.panelTemplate )
7975                                 .attr( "id", id )
7976                                 .data( "destroy.tabs", true );
7977                 }
7978                 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
7979
7980                 if ( index >= this.lis.length ) {
7981                         $li.appendTo( this.list );
7982                         $panel.appendTo( this.list[ 0 ].parentNode );
7983                 } else {
7984                         $li.insertBefore( this.lis[ index ] );
7985                         $panel.insertBefore( this.panels[ index ] );
7986                 }
7987
7988                 o.disabled = $.map( o.disabled, function( n, i ) {
7989                         return n >= index ? ++n : n;
7990                 });
7991
7992                 this._tabify();
7993
7994                 if ( this.anchors.length == 1 ) {
7995                         o.selected = 0;
7996                         $li.addClass( "ui-tabs-selected ui-state-active" );
7997                         $panel.removeClass( "ui-tabs-hide" );
7998                         this.element.queue( "tabs", function() {
7999                                 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
8000                         });
8001
8002                         this.load( 0 );
8003                 }
8004
8005                 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8006                 return this;
8007         },
8008
8009         remove: function( index ) {
8010                 index = this._getIndex( index );
8011                 var o = this.options,
8012                         $li = this.lis.eq( index ).remove(),
8013                         $panel = this.panels.eq( index ).remove();
8014
8015                 // If selected tab was removed focus tab to the right or
8016                 // in case the last tab was removed the tab to the left.
8017                 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
8018                         this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
8019                 }
8020
8021                 o.disabled = $.map(
8022                         $.grep( o.disabled, function(n, i) {
8023                                 return n != index;
8024                         }),
8025                         function( n, i ) {
8026                                 return n >= index ? --n : n;
8027                         });
8028
8029                 this._tabify();
8030
8031                 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
8032                 return this;
8033         },
8034
8035         enable: function( index ) {
8036                 index = this._getIndex( index );
8037                 var o = this.options;
8038                 if ( $.inArray( index, o.disabled ) == -1 ) {
8039                         return;
8040                 }
8041
8042                 this.lis.eq( index ).removeClass( "ui-state-disabled" );
8043                 o.disabled = $.grep( o.disabled, function( n, i ) {
8044                         return n != index;
8045                 });
8046
8047                 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8048                 return this;
8049         },
8050
8051         disable: function( index ) {
8052                 index = this._getIndex( index );
8053                 var self = this, o = this.options;
8054                 // cannot disable already selected tab
8055                 if ( index != o.selected ) {
8056                         this.lis.eq( index ).addClass( "ui-state-disabled" );
8057
8058                         o.disabled.push( index );
8059                         o.disabled.sort();
8060
8061                         this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8062                 }
8063
8064                 return this;
8065         },
8066
8067         select: function( index ) {
8068                 index = this._getIndex( index );
8069                 if ( index == -1 ) {
8070                         if ( this.options.collapsible && this.options.selected != -1 ) {
8071                                 index = this.options.selected;
8072                         } else {
8073                                 return this;
8074                         }
8075                 }
8076                 this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
8077                 return this;
8078         },
8079
8080         load: function( index ) {
8081                 index = this._getIndex( index );
8082                 var self = this,
8083                         o = this.options,
8084                         a = this.anchors.eq( index )[ 0 ],
8085                         url = $.data( a, "load.tabs" );
8086
8087                 this.abort();
8088
8089                 // not remote or from cache
8090                 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
8091                         this.element.dequeue( "tabs" );
8092                         return;
8093                 }
8094
8095                 // load remote from here on
8096                 this.lis.eq( index ).addClass( "ui-state-processing" );
8097
8098                 if ( o.spinner ) {
8099                         var span = $( "span", a );
8100                         span.data( "label.tabs", span.html() ).html( o.spinner );
8101                 }
8102
8103                 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
8104                         url: url,
8105                         success: function( r, s ) {
8106                                 self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
8107
8108                                 // take care of tab labels
8109                                 self._cleanup();
8110
8111                                 if ( o.cache ) {
8112                                         $.data( a, "cache.tabs", true );
8113                                 }
8114
8115                                 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8116                                 try {
8117                                         o.ajaxOptions.success( r, s );
8118                                 }
8119                                 catch ( e ) {}
8120                         },
8121                         error: function( xhr, s, e ) {
8122                                 // take care of tab labels
8123                                 self._cleanup();
8124
8125                                 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8126                                 try {
8127                                         // Passing index avoid a race condition when this method is
8128                                         // called after the user has selected another tab.
8129                                         // Pass the anchor that initiated this request allows
8130                                         // loadError to manipulate the tab content panel via $(a.hash)
8131                                         o.ajaxOptions.error( xhr, s, index, a );
8132                                 }
8133                                 catch ( e ) {}
8134                         }
8135                 } ) );
8136
8137                 // last, so that load event is fired before show...
8138                 self.element.dequeue( "tabs" );
8139
8140                 return this;
8141         },
8142
8143         abort: function() {
8144                 // stop possibly running animations
8145                 this.element.queue( [] );
8146                 this.panels.stop( false, true );
8147
8148                 // "tabs" queue must not contain more than two elements,
8149                 // which are the callbacks for the latest clicked tab...
8150                 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
8151
8152                 // terminate pending requests from other tabs
8153                 if ( this.xhr ) {
8154                         this.xhr.abort();
8155                         delete this.xhr;
8156                 }
8157
8158                 // take care of tab labels
8159                 this._cleanup();
8160                 return this;
8161         },
8162
8163         url: function( index, url ) {
8164                 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
8165                 return this;
8166         },
8167
8168         length: function() {
8169                 return this.anchors.length;
8170         }
8171 });
8172
8173 $.extend( $.ui.tabs, {
8174         version: "1.8.14"
8175 });
8176
8177 /*
8178  * Tabs Extensions
8179  */
8180
8181 /*
8182  * Rotate
8183  */
8184 $.extend( $.ui.tabs.prototype, {
8185         rotation: null,
8186         rotate: function( ms, continuing ) {
8187                 var self = this,
8188                         o = this.options;
8189
8190                 var rotate = self._rotate || ( self._rotate = function( e ) {
8191                         clearTimeout( self.rotation );
8192                         self.rotation = setTimeout(function() {
8193                                 var t = o.selected;
8194                                 self.select( ++t < self.anchors.length ? t : 0 );
8195                         }, ms );
8196                         
8197                         if ( e ) {
8198                                 e.stopPropagation();
8199                         }
8200                 });
8201
8202                 var stop = self._unrotate || ( self._unrotate = !continuing
8203                         ? function(e) {
8204                                 if (e.clientX) { // in case of a true click
8205                                         self.rotate(null);
8206                                 }
8207                         }
8208                         : function( e ) {
8209                                 t = o.selected;
8210                                 rotate();
8211                         });
8212
8213                 // start rotation
8214                 if ( ms ) {
8215                         this.element.bind( "tabsshow", rotate );
8216                         this.anchors.bind( o.event + ".tabs", stop );
8217                         rotate();
8218                 // stop rotation
8219                 } else {
8220                         clearTimeout( self.rotation );
8221                         this.element.unbind( "tabsshow", rotate );
8222                         this.anchors.unbind( o.event + ".tabs", stop );
8223                         delete this._rotate;
8224                         delete this._unrotate;
8225                 }
8226
8227                 return this;
8228         }
8229 });
8230
8231 })( jQuery );
8232 /*
8233  * jQuery UI Datepicker 1.8.14
8234  *
8235  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
8236  * Dual licensed under the MIT or GPL Version 2 licenses.
8237  * http://jquery.org/license
8238  *
8239  * http://docs.jquery.com/UI/Datepicker
8240  *
8241  * Depends:
8242  *      jquery.ui.core.js
8243  */
8244 (function( $, undefined ) {
8245
8246 $.extend($.ui, { datepicker: { version: "1.8.14" } });
8247
8248 var PROP_NAME = 'datepicker';
8249 var dpuuid = new Date().getTime();
8250 var instActive;
8251
8252 /* Date picker manager.
8253    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8254    Settings for (groups of) date pickers are maintained in an instance object,
8255    allowing multiple different settings on the same page. */
8256
8257 function Datepicker() {
8258         this.debug = false; // Change this to true to start debugging
8259         this._curInst = null; // The current instance in use
8260         this._keyEvent = false; // If the last event was a key event
8261         this._disabledInputs = []; // List of date picker inputs that have been disabled
8262         this._datepickerShowing = false; // True if the popup picker is showing , false if not
8263         this._inDialog = false; // True if showing within a "dialog", false if not
8264         this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
8265         this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
8266         this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
8267         this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
8268         this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
8269         this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
8270         this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
8271         this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
8272         this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
8273         this.regional = []; // Available regional settings, indexed by language code
8274         this.regional[''] = { // Default regional settings
8275                 closeText: 'Done', // Display text for close link
8276                 prevText: 'Prev', // Display text for previous month link
8277                 nextText: 'Next', // Display text for next month link
8278                 currentText: 'Today', // Display text for current month link
8279                 monthNames: ['January','February','March','April','May','June',
8280                         'July','August','September','October','November','December'], // Names of months for drop-down and formatting
8281                 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
8282                 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
8283                 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
8284                 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
8285                 weekHeader: 'Wk', // Column header for week of the year
8286                 dateFormat: 'mm/dd/yy', // See format options on parseDate
8287                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8288                 isRTL: false, // True if right-to-left language, false if left-to-right
8289                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8290                 yearSuffix: '' // Additional text to append to the year in the month headers
8291         };
8292         this._defaults = { // Global defaults for all the date picker instances
8293                 showOn: 'focus', // 'focus' for popup on focus,
8294                         // 'button' for trigger button, or 'both' for either
8295                 showAnim: 'fadeIn', // Name of jQuery animation for popup
8296                 showOptions: {}, // Options for enhanced animations
8297                 defaultDate: null, // Used when field is blank: actual date,
8298                         // +/-number for offset from today, null for today
8299                 appendText: '', // Display text following the input box, e.g. showing the format
8300                 buttonText: '...', // Text for trigger button
8301                 buttonImage: '', // URL for trigger button image
8302                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8303                 hideIfNoPrevNext: false, // True to hide next/previous month links
8304                         // if not applicable, false to just disable them
8305                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8306                 gotoCurrent: false, // True if today link goes back to current selection instead
8307                 changeMonth: false, // True if month can be selected directly, false if only prev/next
8308                 changeYear: false, // True if year can be selected directly, false if only prev/next
8309                 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
8310                         // either relative to today's year (-nn:+nn), relative to currently displayed year
8311                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8312                 showOtherMonths: false, // True to show dates in other months, false to leave blank
8313                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8314                 showWeek: false, // True to show week of the year, false to not show it
8315                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8316                         // takes a Date and returns the number of the week for it
8317                 shortYearCutoff: '+10', // Short year values < this are in the current century,
8318                         // > this are in the previous century,
8319                         // string value starting with '+' for current year + value
8320                 minDate: null, // The earliest selectable date, or null for no limit
8321                 maxDate: null, // The latest selectable date, or null for no limit
8322                 duration: 'fast', // Duration of display/closure
8323                 beforeShowDay: null, // Function that takes a date and returns an array with
8324                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
8325                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8326                 beforeShow: null, // Function that takes an input field and
8327                         // returns a set of custom settings for the date picker
8328                 onSelect: null, // Define a callback function when a date is selected
8329                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
8330                 onClose: null, // Define a callback function when the datepicker is closed
8331                 numberOfMonths: 1, // Number of months to show at a time
8332                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8333                 stepMonths: 1, // Number of months to step back/forward
8334                 stepBigMonths: 12, // Number of months to step back/forward for the big links
8335                 altField: '', // Selector for an alternate field to store selected dates into
8336                 altFormat: '', // The date format to use for the alternate field
8337                 constrainInput: true, // The input is constrained by the current date format
8338                 showButtonPanel: false, // True to show button panel, false to not show it
8339                 autoSize: false // True to size the input for the date format, false to leave as is
8340         };
8341         $.extend(this._defaults, this.regional['']);
8342         this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
8343 }
8344
8345 $.extend(Datepicker.prototype, {
8346         /* Class name added to elements to indicate already configured with a date picker. */
8347         markerClassName: 'hasDatepicker',
8348         
8349         //Keep track of the maximum number of rows displayed (see #7043)
8350         maxRows: 4,
8351
8352         /* Debug logging (if enabled). */
8353         log: function () {
8354                 if (this.debug)
8355                         console.log.apply('', arguments);
8356         },
8357         
8358         // TODO rename to "widget" when switching to widget factory
8359         _widgetDatepicker: function() {
8360                 return this.dpDiv;
8361         },
8362
8363         /* Override the default settings for all instances of the date picker.
8364            @param  settings  object - the new settings to use as defaults (anonymous object)
8365            @return the manager object */
8366         setDefaults: function(settings) {
8367                 extendRemove(this._defaults, settings || {});
8368                 return this;
8369         },
8370
8371         /* Attach the date picker to a jQuery selection.
8372            @param  target    element - the target input field or division or span
8373            @param  settings  object - the new settings to use for this date picker instance (anonymous) */
8374         _attachDatepicker: function(target, settings) {
8375                 // check for settings on the control itself - in namespace 'date:'
8376                 var inlineSettings = null;
8377                 for (var attrName in this._defaults) {
8378                         var attrValue = target.getAttribute('date:' + attrName);
8379                         if (attrValue) {
8380                                 inlineSettings = inlineSettings || {};
8381                                 try {
8382                                         inlineSettings[attrName] = eval(attrValue);
8383                                 } catch (err) {
8384                                         inlineSettings[attrName] = attrValue;
8385                                 }
8386                         }
8387                 }
8388                 var nodeName = target.nodeName.toLowerCase();
8389                 var inline = (nodeName == 'div' || nodeName == 'span');
8390                 if (!target.id) {
8391                         this.uuid += 1;
8392                         target.id = 'dp' + this.uuid;
8393                 }
8394                 var inst = this._newInst($(target), inline);
8395                 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
8396                 if (nodeName == 'input') {
8397                         this._connectDatepicker(target, inst);
8398                 } else if (inline) {
8399                         this._inlineDatepicker(target, inst);
8400                 }
8401         },
8402
8403         /* Create a new instance object. */
8404         _newInst: function(target, inline) {
8405                 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
8406                 return {id: id, input: target, // associated target
8407                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8408                         drawMonth: 0, drawYear: 0, // month being drawn
8409                         inline: inline, // is datepicker inline or not
8410                         dpDiv: (!inline ? this.dpDiv : // presentation div
8411                         bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
8412         },
8413
8414         /* Attach the date picker to an input field. */
8415         _connectDatepicker: function(target, inst) {
8416                 var input = $(target);
8417                 inst.append = $([]);
8418                 inst.trigger = $([]);
8419                 if (input.hasClass(this.markerClassName))
8420                         return;
8421                 this._attachments(input, inst);
8422                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
8423                         keypress(this._doKeyPress).keyup(this._doKeyUp).
8424                         bind("setData.datepicker", function(event, key, value) {
8425                                 inst.settings[key] = value;
8426                         }).bind("getData.datepicker", function(event, key) {
8427                                 return this._get(inst, key);
8428                         });
8429                 this._autoSize(inst);
8430                 $.data(target, PROP_NAME, inst);
8431         },
8432
8433         /* Make attachments based on settings. */
8434         _attachments: function(input, inst) {
8435                 var appendText = this._get(inst, 'appendText');
8436                 var isRTL = this._get(inst, 'isRTL');
8437                 if (inst.append)
8438                         inst.append.remove();
8439                 if (appendText) {
8440                         inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
8441                         input[isRTL ? 'before' : 'after'](inst.append);
8442                 }
8443                 input.unbind('focus', this._showDatepicker);
8444                 if (inst.trigger)
8445                         inst.trigger.remove();
8446                 var showOn = this._get(inst, 'showOn');
8447                 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
8448                         input.focus(this._showDatepicker);
8449                 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
8450                         var buttonText = this._get(inst, 'buttonText');
8451                         var buttonImage = this._get(inst, 'buttonImage');
8452                         inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
8453                                 $('<img/>').addClass(this._triggerClass).
8454                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8455                                 $('<button type="button"></button>').addClass(this._triggerClass).
8456                                         html(buttonImage == '' ? buttonText : $('<img/>').attr(
8457                                         { src:buttonImage, alt:buttonText, title:buttonText })));
8458                         input[isRTL ? 'before' : 'after'](inst.trigger);
8459                         inst.trigger.click(function() {
8460                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
8461                                         $.datepicker._hideDatepicker();
8462                                 else
8463                                         $.datepicker._showDatepicker(input[0]);
8464                                 return false;
8465                         });
8466                 }
8467         },
8468
8469         /* Apply the maximum length for the date format. */
8470         _autoSize: function(inst) {
8471                 if (this._get(inst, 'autoSize') && !inst.inline) {
8472                         var date = new Date(2009, 12 - 1, 20); // Ensure double digits
8473                         var dateFormat = this._get(inst, 'dateFormat');
8474                         if (dateFormat.match(/[DM]/)) {
8475                                 var findMax = function(names) {
8476                                         var max = 0;
8477                                         var maxI = 0;
8478                                         for (var i = 0; i < names.length; i++) {
8479                                                 if (names[i].length > max) {
8480                                                         max = names[i].length;
8481                                                         maxI = i;
8482                                                 }
8483                                         }
8484                                         return maxI;
8485                                 };
8486                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8487                                         'monthNames' : 'monthNamesShort'))));
8488                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8489                                         'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
8490                         }
8491                         inst.input.attr('size', this._formatDate(inst, date).length);
8492                 }
8493         },
8494
8495         /* Attach an inline date picker to a div. */
8496         _inlineDatepicker: function(target, inst) {
8497                 var divSpan = $(target);
8498                 if (divSpan.hasClass(this.markerClassName))
8499                         return;
8500                 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
8501                         bind("setData.datepicker", function(event, key, value){
8502                                 inst.settings[key] = value;
8503                         }).bind("getData.datepicker", function(event, key){
8504                                 return this._get(inst, key);
8505                         });
8506                 $.data(target, PROP_NAME, inst);
8507                 this._setDate(inst, this._getDefaultDate(inst), true);
8508                 this._updateDatepicker(inst);
8509                 this._updateAlternate(inst);
8510                 inst.dpDiv.show();
8511         },
8512
8513         /* Pop-up the date picker in a "dialog" box.
8514            @param  input     element - ignored
8515            @param  date      string or Date - the initial date to display
8516            @param  onSelect  function - the function to call when a date is selected
8517            @param  settings  object - update the dialog date picker instance's settings (anonymous object)
8518            @param  pos       int[2] - coordinates for the dialog's position within the screen or
8519                              event - with x/y coordinates or
8520                              leave empty for default (screen centre)
8521            @return the manager object */
8522         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8523                 var inst = this._dialogInst; // internal instance
8524                 if (!inst) {
8525                         this.uuid += 1;
8526                         var id = 'dp' + this.uuid;
8527                         this._dialogInput = $('<input type="text" id="' + id +
8528                                 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
8529                         this._dialogInput.keydown(this._doKeyDown);
8530                         $('body').append(this._dialogInput);
8531                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
8532                         inst.settings = {};
8533                         $.data(this._dialogInput[0], PROP_NAME, inst);
8534                 }
8535                 extendRemove(inst.settings, settings || {});
8536                 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
8537                 this._dialogInput.val(date);
8538
8539                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8540                 if (!this._pos) {
8541                         var browserWidth = document.documentElement.clientWidth;
8542                         var browserHeight = document.documentElement.clientHeight;
8543                         var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8544                         var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8545                         this._pos = // should use actual width/height below
8546                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8547                 }
8548
8549                 // move input on screen for focus, but hidden behind dialog
8550                 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
8551                 inst.settings.onSelect = onSelect;
8552                 this._inDialog = true;
8553                 this.dpDiv.addClass(this._dialogClass);
8554                 this._showDatepicker(this._dialogInput[0]);
8555                 if ($.blockUI)
8556                         $.blockUI(this.dpDiv);
8557                 $.data(this._dialogInput[0], PROP_NAME, inst);
8558                 return this;
8559         },
8560
8561         /* Detach a datepicker from its control.
8562            @param  target    element - the target input field or division or span */
8563         _destroyDatepicker: function(target) {
8564                 var $target = $(target);
8565                 var inst = $.data(target, PROP_NAME);
8566                 if (!$target.hasClass(this.markerClassName)) {
8567                         return;
8568                 }
8569                 var nodeName = target.nodeName.toLowerCase();
8570                 $.removeData(target, PROP_NAME);
8571                 if (nodeName == 'input') {
8572                         inst.append.remove();
8573                         inst.trigger.remove();
8574                         $target.removeClass(this.markerClassName).
8575                                 unbind('focus', this._showDatepicker).
8576                                 unbind('keydown', this._doKeyDown).
8577                                 unbind('keypress', this._doKeyPress).
8578                                 unbind('keyup', this._doKeyUp);
8579                 } else if (nodeName == 'div' || nodeName == 'span')
8580                         $target.removeClass(this.markerClassName).empty();
8581         },
8582
8583         /* Enable the date picker to a jQuery selection.
8584            @param  target    element - the target input field or division or span */
8585         _enableDatepicker: function(target) {
8586                 var $target = $(target);
8587                 var inst = $.data(target, PROP_NAME);
8588                 if (!$target.hasClass(this.markerClassName)) {
8589                         return;
8590                 }
8591                 var nodeName = target.nodeName.toLowerCase();
8592                 if (nodeName == 'input') {
8593                         target.disabled = false;
8594                         inst.trigger.filter('button').
8595                                 each(function() { this.disabled = false; }).end().
8596                                 filter('img').css({opacity: '1.0', cursor: ''});
8597                 }
8598                 else if (nodeName == 'div' || nodeName == 'span') {
8599                         var inline = $target.children('.' + this._inlineClass);
8600                         inline.children().removeClass('ui-state-disabled');
8601                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8602                                 removeAttr("disabled");
8603                 }
8604                 this._disabledInputs = $.map(this._disabledInputs,
8605                         function(value) { return (value == target ? null : value); }); // delete entry
8606         },
8607
8608         /* Disable the date picker to a jQuery selection.
8609            @param  target    element - the target input field or division or span */
8610         _disableDatepicker: function(target) {
8611                 var $target = $(target);
8612                 var inst = $.data(target, PROP_NAME);
8613                 if (!$target.hasClass(this.markerClassName)) {
8614                         return;
8615                 }
8616                 var nodeName = target.nodeName.toLowerCase();
8617                 if (nodeName == 'input') {
8618                         target.disabled = true;
8619                         inst.trigger.filter('button').
8620                                 each(function() { this.disabled = true; }).end().
8621                                 filter('img').css({opacity: '0.5', cursor: 'default'});
8622                 }
8623                 else if (nodeName == 'div' || nodeName == 'span') {
8624                         var inline = $target.children('.' + this._inlineClass);
8625                         inline.children().addClass('ui-state-disabled');
8626                         inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8627                                 attr("disabled", "disabled");
8628                 }
8629                 this._disabledInputs = $.map(this._disabledInputs,
8630                         function(value) { return (value == target ? null : value); }); // delete entry
8631                 this._disabledInputs[this._disabledInputs.length] = target;
8632         },
8633
8634         /* Is the first field in a jQuery collection disabled as a datepicker?
8635            @param  target    element - the target input field or division or span
8636            @return boolean - true if disabled, false if enabled */
8637         _isDisabledDatepicker: function(target) {
8638                 if (!target) {
8639                         return false;
8640                 }
8641                 for (var i = 0; i < this._disabledInputs.length; i++) {
8642                         if (this._disabledInputs[i] == target)
8643                                 return true;
8644                 }
8645                 return false;
8646         },
8647
8648         /* Retrieve the instance data for the target control.
8649            @param  target  element - the target input field or division or span
8650            @return  object - the associated instance data
8651            @throws  error if a jQuery problem getting data */
8652         _getInst: function(target) {
8653                 try {
8654                         return $.data(target, PROP_NAME);
8655                 }
8656                 catch (err) {
8657                         throw 'Missing instance data for this datepicker';
8658                 }
8659         },
8660
8661         /* Update or retrieve the settings for a date picker attached to an input field or division.
8662            @param  target  element - the target input field or division or span
8663            @param  name    object - the new settings to update or
8664                            string - the name of the setting to change or retrieve,
8665                            when retrieving also 'all' for all instance settings or
8666                            'defaults' for all global defaults
8667            @param  value   any - the new value for the setting
8668                            (omit if above is an object or to retrieve a value) */
8669         _optionDatepicker: function(target, name, value) {
8670                 var inst = this._getInst(target);
8671                 if (arguments.length == 2 && typeof name == 'string') {
8672                         return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
8673                                 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
8674                                 this._get(inst, name)) : null));
8675                 }
8676                 var settings = name || {};
8677                 if (typeof name == 'string') {
8678                         settings = {};
8679                         settings[name] = value;
8680                 }
8681                 if (inst) {
8682                         if (this._curInst == inst) {
8683                                 this._hideDatepicker();
8684                         }
8685                         var date = this._getDateDatepicker(target, true);
8686                         var minDate = this._getMinMaxDate(inst, 'min');
8687                         var maxDate = this._getMinMaxDate(inst, 'max');
8688                         extendRemove(inst.settings, settings);
8689                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8690                         if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
8691                                 inst.settings.minDate = this._formatDate(inst, minDate);
8692                         if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
8693                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
8694                         this._attachments($(target), inst);
8695                         this._autoSize(inst);
8696                         this._setDate(inst, date);
8697                         this._updateAlternate(inst);
8698                         this._updateDatepicker(inst);
8699                 }
8700         },
8701
8702         // change method deprecated
8703         _changeDatepicker: function(target, name, value) {
8704                 this._optionDatepicker(target, name, value);
8705         },
8706
8707         /* Redraw the date picker attached to an input field or division.
8708            @param  target  element - the target input field or division or span */
8709         _refreshDatepicker: function(target) {
8710                 var inst = this._getInst(target);
8711                 if (inst) {
8712                         this._updateDatepicker(inst);
8713                 }
8714         },
8715
8716         /* Set the dates for a jQuery selection.
8717            @param  target   element - the target input field or division or span
8718            @param  date     Date - the new date */
8719         _setDateDatepicker: function(target, date) {
8720                 var inst = this._getInst(target);
8721                 if (inst) {
8722                         this._setDate(inst, date);
8723                         this._updateDatepicker(inst);
8724                         this._updateAlternate(inst);
8725                 }
8726         },
8727
8728         /* Get the date(s) for the first entry in a jQuery selection.
8729            @param  target     element - the target input field or division or span
8730            @param  noDefault  boolean - true if no default date is to be used
8731            @return Date - the current date */
8732         _getDateDatepicker: function(target, noDefault) {
8733                 var inst = this._getInst(target);
8734                 if (inst && !inst.inline)
8735                         this._setDateFromField(inst, noDefault);
8736                 return (inst ? this._getDate(inst) : null);
8737         },
8738
8739         /* Handle keystrokes. */
8740         _doKeyDown: function(event) {
8741                 var inst = $.datepicker._getInst(event.target);
8742                 var handled = true;
8743                 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
8744                 inst._keyEvent = true;
8745                 if ($.datepicker._datepickerShowing)
8746                         switch (event.keyCode) {
8747                                 case 9: $.datepicker._hideDatepicker();
8748                                                 handled = false;
8749                                                 break; // hide on tab out
8750                                 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 
8751                                                                         $.datepicker._currentClass + ')', inst.dpDiv);
8752                                                 if (sel[0])
8753                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8754                                                 else
8755                                                         $.datepicker._hideDatepicker();
8756                                                 return false; // don't submit the form
8757                                                 break; // select the value on enter
8758                                 case 27: $.datepicker._hideDatepicker();
8759                                                 break; // hide on escape
8760                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8761                                                         -$.datepicker._get(inst, 'stepBigMonths') :
8762                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
8763                                                 break; // previous month/year on page up/+ ctrl
8764                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8765                                                         +$.datepicker._get(inst, 'stepBigMonths') :
8766                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
8767                                                 break; // next month/year on page down/+ ctrl
8768                                 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
8769                                                 handled = event.ctrlKey || event.metaKey;
8770                                                 break; // clear on ctrl or command +end
8771                                 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
8772                                                 handled = event.ctrlKey || event.metaKey;
8773                                                 break; // current on ctrl or command +home
8774                                 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
8775                                                 handled = event.ctrlKey || event.metaKey;
8776                                                 // -1 day on ctrl or command +left
8777                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8778                                                                         -$.datepicker._get(inst, 'stepBigMonths') :
8779                                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
8780                                                 // next month/year on alt +left on Mac
8781                                                 break;
8782                                 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
8783                                                 handled = event.ctrlKey || event.metaKey;
8784                                                 break; // -1 week on ctrl or command +up
8785                                 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
8786                                                 handled = event.ctrlKey || event.metaKey;
8787                                                 // +1 day on ctrl or command +right
8788                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8789                                                                         +$.datepicker._get(inst, 'stepBigMonths') :
8790                                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
8791                                                 // next month/year on alt +right
8792                                                 break;
8793                                 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
8794                                                 handled = event.ctrlKey || event.metaKey;
8795                                                 break; // +1 week on ctrl or command +down
8796                                 default: handled = false;
8797                         }
8798                 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
8799                         $.datepicker._showDatepicker(this);
8800                 else {
8801                         handled = false;
8802                 }
8803                 if (handled) {
8804                         event.preventDefault();
8805                         event.stopPropagation();
8806                 }
8807         },
8808
8809         /* Filter entered characters - based on date format. */
8810         _doKeyPress: function(event) {
8811                 var inst = $.datepicker._getInst(event.target);
8812                 if ($.datepicker._get(inst, 'constrainInput')) {
8813                         var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
8814                         var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
8815                         return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
8816                 }
8817         },
8818
8819         /* Synchronise manual entry and field/alternate field. */
8820         _doKeyUp: function(event) {
8821                 var inst = $.datepicker._getInst(event.target);
8822                 if (inst.input.val() != inst.lastVal) {
8823                         try {
8824                                 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8825                                         (inst.input ? inst.input.val() : null),
8826                                         $.datepicker._getFormatConfig(inst));
8827                                 if (date) { // only if valid
8828                                         $.datepicker._setDateFromField(inst);
8829                                         $.datepicker._updateAlternate(inst);
8830                                         $.datepicker._updateDatepicker(inst);
8831                                 }
8832                         }
8833                         catch (event) {
8834                                 $.datepicker.log(event);
8835                         }
8836                 }
8837                 return true;
8838         },
8839
8840         /* Pop-up the date picker for a given input field.
8841            @param  input  element - the input field attached to the date picker or
8842                           event - if triggered by focus */
8843         _showDatepicker: function(input) {
8844                 input = input.target || input;
8845                 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
8846                         input = $('input', input.parentNode)[0];
8847                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
8848                         return;
8849                 var inst = $.datepicker._getInst(input);
8850                 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
8851                         if ( $.datepicker._datepickerShowing ) {
8852                                 $.datepicker._triggerOnClose($.datepicker._curInst);
8853                         }
8854                         $.datepicker._curInst.dpDiv.stop(true, true);
8855                 }
8856                 var beforeShow = $.datepicker._get(inst, 'beforeShow');
8857                 extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
8858                 inst.lastVal = null;
8859                 $.datepicker._lastInput = input;
8860                 $.datepicker._setDateFromField(inst);
8861                 if ($.datepicker._inDialog) // hide cursor
8862                         input.value = '';
8863                 if (!$.datepicker._pos) { // position below input
8864                         $.datepicker._pos = $.datepicker._findPos(input);
8865                         $.datepicker._pos[1] += input.offsetHeight; // add the height
8866                 }
8867                 var isFixed = false;
8868                 $(input).parents().each(function() {
8869                         isFixed |= $(this).css('position') == 'fixed';
8870                         return !isFixed;
8871                 });
8872                 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
8873                         $.datepicker._pos[0] -= document.documentElement.scrollLeft;
8874                         $.datepicker._pos[1] -= document.documentElement.scrollTop;
8875                 }
8876                 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8877                 $.datepicker._pos = null;
8878                 //to avoid flashes on Firefox
8879                 inst.dpDiv.empty();
8880                 // determine sizing offscreen
8881                 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
8882                 $.datepicker._updateDatepicker(inst);
8883                 // fix width for dynamic number of date pickers
8884                 // and adjust position before showing
8885                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
8886                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8887                         'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
8888                         left: offset.left + 'px', top: offset.top + 'px'});
8889                 if (!inst.inline) {
8890                         var showAnim = $.datepicker._get(inst, 'showAnim');
8891                         var duration = $.datepicker._get(inst, 'duration');
8892                         var postProcess = function() {
8893                                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8894                                 if( !! cover.length ){
8895                                         var borders = $.datepicker._getBorders(inst.dpDiv);
8896                                         cover.css({left: -borders[0], top: -borders[1],
8897                                                 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
8898                                 }
8899                         };
8900                         inst.dpDiv.zIndex($(input).zIndex()+1);
8901                         $.datepicker._datepickerShowing = true;
8902                         if ($.effects && $.effects[showAnim])
8903                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8904                         else
8905                                 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
8906                         if (!showAnim || !duration)
8907                                 postProcess();
8908                         if (inst.input.is(':visible') && !inst.input.is(':disabled'))
8909                                 inst.input.focus();
8910                         $.datepicker._curInst = inst;
8911                 }
8912         },
8913
8914         /* Generate the date picker content. */
8915         _updateDatepicker: function(inst) {
8916                 var self = this;
8917                 self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8918                 var borders = $.datepicker._getBorders(inst.dpDiv);
8919                 instActive = inst; // for delegate hover events
8920                 inst.dpDiv.empty().append(this._generateHTML(inst));
8921                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8922                 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
8923                         cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
8924                 }
8925                 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
8926                 var numMonths = this._getNumberOfMonths(inst);
8927                 var cols = numMonths[1];
8928                 var width = 17;
8929                 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
8930                 if (cols > 1)
8931                         inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
8932                 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
8933                         'Class']('ui-datepicker-multi');
8934                 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
8935                         'Class']('ui-datepicker-rtl');
8936                 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
8937                                 // #6694 - don't focus the input if it's already focused
8938                                 // this breaks the change event in IE
8939                                 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
8940                         inst.input.focus();
8941                 // deffered render of the years select (to avoid flashes on Firefox) 
8942                 if( inst.yearshtml ){
8943                         var origyearshtml = inst.yearshtml;
8944                         setTimeout(function(){
8945                                 //assure that inst.yearshtml didn't change.
8946                                 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8947                                         inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
8948                                 }
8949                                 origyearshtml = inst.yearshtml = null;
8950                         }, 0);
8951                 }
8952         },
8953
8954         /* Retrieve the size of left and top borders for an element.
8955            @param  elem  (jQuery object) the element of interest
8956            @return  (number[2]) the left and top borders */
8957         _getBorders: function(elem) {
8958                 var convert = function(value) {
8959                         return {thin: 1, medium: 2, thick: 3}[value] || value;
8960                 };
8961                 return [parseFloat(convert(elem.css('border-left-width'))),
8962                         parseFloat(convert(elem.css('border-top-width')))];
8963         },
8964
8965         /* Check positioning to remain on screen. */
8966         _checkOffset: function(inst, offset, isFixed) {
8967                 var dpWidth = inst.dpDiv.outerWidth();
8968                 var dpHeight = inst.dpDiv.outerHeight();
8969                 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
8970                 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
8971                 var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
8972                 var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
8973
8974                 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
8975                 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
8976                 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8977
8978                 // now check if datepicker is showing outside window viewport - move to a better place if so.
8979                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8980                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
8981                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8982                         Math.abs(dpHeight + inputHeight) : 0);
8983
8984                 return offset;
8985         },
8986
8987         /* Find an object's position on the screen. */
8988         _findPos: function(obj) {
8989                 var inst = this._getInst(obj);
8990                 var isRTL = this._get(inst, 'isRTL');
8991         while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
8992             obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
8993         }
8994         var position = $(obj).offset();
8995             return [position.left, position.top];
8996         },
8997
8998         /* Trigger custom callback of onClose. */
8999         _triggerOnClose: function(inst) {
9000                 var onClose = this._get(inst, 'onClose');
9001                 if (onClose)
9002                         onClose.apply((inst.input ? inst.input[0] : null),
9003                                                   [(inst.input ? inst.input.val() : ''), inst]);
9004         },
9005
9006         /* Hide the date picker from view.
9007            @param  input  element - the input field attached to the date picker */
9008         _hideDatepicker: function(input) {
9009                 var inst = this._curInst;
9010                 if (!inst || (input && inst != $.data(input, PROP_NAME)))
9011                         return;
9012                 if (this._datepickerShowing) {
9013                         var showAnim = this._get(inst, 'showAnim');
9014                         var duration = this._get(inst, 'duration');
9015                         var postProcess = function() {
9016                                 $.datepicker._tidyDialog(inst);
9017                                 this._curInst = null;
9018                         };
9019                         if ($.effects && $.effects[showAnim])
9020                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
9021                         else
9022                                 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
9023                                         (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
9024                         if (!showAnim)
9025                                 postProcess();
9026                         $.datepicker._triggerOnClose(inst);
9027                         this._datepickerShowing = false;
9028                         this._lastInput = null;
9029                         if (this._inDialog) {
9030                                 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
9031                                 if ($.blockUI) {
9032                                         $.unblockUI();
9033                                         $('body').append(this.dpDiv);
9034                                 }
9035                         }
9036                         this._inDialog = false;
9037                 }
9038         },
9039
9040         /* Tidy up after a dialog display. */
9041         _tidyDialog: function(inst) {
9042                 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
9043         },
9044
9045         /* Close date picker if clicked elsewhere. */
9046         _checkExternalClick: function(event) {
9047                 if (!$.datepicker._curInst)
9048                         return;
9049                 var $target = $(event.target);
9050                 if ($target[0].id != $.datepicker._mainDivId &&
9051                                 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
9052                                 !$target.hasClass($.datepicker.markerClassName) &&
9053                                 !$target.hasClass($.datepicker._triggerClass) &&
9054                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
9055                         $.datepicker._hideDatepicker();
9056         },
9057
9058         /* Adjust one of the date sub-fields. */
9059         _adjustDate: function(id, offset, period) {
9060                 var target = $(id);
9061                 var inst = this._getInst(target[0]);
9062                 if (this._isDisabledDatepicker(target[0])) {
9063                         return;
9064                 }
9065                 this._adjustInstDate(inst, offset +
9066                         (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
9067                         period);
9068                 this._updateDatepicker(inst);
9069         },
9070
9071         /* Action for current link. */
9072         _gotoToday: function(id) {
9073                 var target = $(id);
9074                 var inst = this._getInst(target[0]);
9075                 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
9076                         inst.selectedDay = inst.currentDay;
9077                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
9078                         inst.drawYear = inst.selectedYear = inst.currentYear;
9079                 }
9080                 else {
9081                         var date = new Date();
9082                         inst.selectedDay = date.getDate();
9083                         inst.drawMonth = inst.selectedMonth = date.getMonth();
9084                         inst.drawYear = inst.selectedYear = date.getFullYear();
9085                 }
9086                 this._notifyChange(inst);
9087                 this._adjustDate(target);
9088         },
9089
9090         /* Action for selecting a new month/year. */
9091         _selectMonthYear: function(id, select, period) {
9092                 var target = $(id);
9093                 var inst = this._getInst(target[0]);
9094                 inst._selectingMonthYear = false;
9095                 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
9096                 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
9097                         parseInt(select.options[select.selectedIndex].value,10);
9098                 this._notifyChange(inst);
9099                 this._adjustDate(target);
9100         },
9101
9102         /* Restore input focus after not changing month/year. */
9103         _clickMonthYear: function(id) {
9104                 var target = $(id);
9105                 var inst = this._getInst(target[0]);
9106                 if (inst.input && inst._selectingMonthYear) {
9107                         setTimeout(function() {
9108                                 inst.input.focus();
9109                         }, 0);
9110                 }
9111                 inst._selectingMonthYear = !inst._selectingMonthYear;
9112         },
9113
9114         /* Action for selecting a day. */
9115         _selectDay: function(id, month, year, td) {
9116                 var target = $(id);
9117                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
9118                         return;
9119                 }
9120                 var inst = this._getInst(target[0]);
9121                 inst.selectedDay = inst.currentDay = $('a', td).html();
9122                 inst.selectedMonth = inst.currentMonth = month;
9123                 inst.selectedYear = inst.currentYear = year;
9124                 this._selectDate(id, this._formatDate(inst,
9125                         inst.currentDay, inst.currentMonth, inst.currentYear));
9126         },
9127
9128         /* Erase the input field and hide the date picker. */
9129         _clearDate: function(id) {
9130                 var target = $(id);
9131                 var inst = this._getInst(target[0]);
9132                 this._selectDate(target, '');
9133         },
9134
9135         /* Update the input field with the selected date. */
9136         _selectDate: function(id, dateStr) {
9137                 var target = $(id);
9138                 var inst = this._getInst(target[0]);
9139                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9140                 if (inst.input)
9141                         inst.input.val(dateStr);
9142                 this._updateAlternate(inst);
9143                 var onSelect = this._get(inst, 'onSelect');
9144                 if (onSelect)
9145                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
9146                 else if (inst.input)
9147                         inst.input.trigger('change'); // fire the change event
9148                 if (inst.inline)
9149                         this._updateDatepicker(inst);
9150                 else {
9151                         this._hideDatepicker();
9152                         this._lastInput = inst.input[0];
9153                         if (typeof(inst.input[0]) != 'object')
9154                                 inst.input.focus(); // restore focus
9155                         this._lastInput = null;
9156                 }
9157         },
9158
9159         /* Update any alternate field to synchronise with the main field. */
9160         _updateAlternate: function(inst) {
9161                 var altField = this._get(inst, 'altField');
9162                 if (altField) { // update alternate field too
9163                         var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
9164                         var date = this._getDate(inst);
9165                         var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9166                         $(altField).each(function() { $(this).val(dateStr); });
9167                 }
9168         },
9169
9170         /* Set as beforeShowDay function to prevent selection of weekends.
9171            @param  date  Date - the date to customise
9172            @return [boolean, string] - is this date selectable?, what is its CSS class? */
9173         noWeekends: function(date) {
9174                 var day = date.getDay();
9175                 return [(day > 0 && day < 6), ''];
9176         },
9177
9178         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9179            @param  date  Date - the date to get the week for
9180            @return  number - the number of the week within the year that contains this date */
9181         iso8601Week: function(date) {
9182                 var checkDate = new Date(date.getTime());
9183                 // Find Thursday of this week starting on Monday
9184                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9185                 var time = checkDate.getTime();
9186                 checkDate.setMonth(0); // Compare with Jan 1
9187                 checkDate.setDate(1);
9188                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9189         },
9190
9191         /* Parse a string value into a date object.
9192            See formatDate below for the possible formats.
9193
9194            @param  format    string - the expected format of the date
9195            @param  value     string - the date in the above format
9196            @param  settings  Object - attributes include:
9197                              shortYearCutoff  number - the cutoff year for determining the century (optional)
9198                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
9199                              dayNames         string[7] - names of the days from Sunday (optional)
9200                              monthNamesShort  string[12] - abbreviated names of the months (optional)
9201                              monthNames       string[12] - names of the months (optional)
9202            @return  Date - the extracted date value or null if value is blank */
9203         parseDate: function (format, value, settings) {
9204                 if (format == null || value == null)
9205                         throw 'Invalid arguments';
9206                 value = (typeof value == 'object' ? value.toString() : value + '');
9207                 if (value == '')
9208                         return null;
9209                 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
9210                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9211                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9212                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9213                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9214                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9215                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9216                 var year = -1;
9217                 var month = -1;
9218                 var day = -1;
9219                 var doy = -1;
9220                 var literal = false;
9221                 // Check whether a format character is doubled
9222                 var lookAhead = function(match) {
9223                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9224                         if (matches)
9225                                 iFormat++;
9226                         return matches;
9227                 };
9228                 // Extract a number from the string value
9229                 var getNumber = function(match) {
9230                         var isDoubled = lookAhead(match);
9231                         var size = (match == '@' ? 14 : (match == '!' ? 20 :
9232                                 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
9233                         var digits = new RegExp('^\\d{1,' + size + '}');
9234                         var num = value.substring(iValue).match(digits);
9235                         if (!num)
9236                                 throw 'Missing number at position ' + iValue;
9237                         iValue += num[0].length;
9238                         return parseInt(num[0], 10);
9239                 };
9240                 // Extract a name from the string value and convert to an index
9241                 var getName = function(match, shortNames, longNames) {
9242                         var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9243                                 return [ [k, v] ];
9244                         }).sort(function (a, b) {
9245                                 return -(a[1].length - b[1].length);
9246                         });
9247                         var index = -1;
9248                         $.each(names, function (i, pair) {
9249                                 var name = pair[1];
9250                                 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
9251                                         index = pair[0];
9252                                         iValue += name.length;
9253                                         return false;
9254                                 }
9255                         });
9256                         if (index != -1)
9257                                 return index + 1;
9258                         else
9259                                 throw 'Unknown name at position ' + iValue;
9260                 };
9261                 // Confirm that a literal character matches the string value
9262                 var checkLiteral = function() {
9263                         if (value.charAt(iValue) != format.charAt(iFormat))
9264                                 throw 'Unexpected literal at position ' + iValue;
9265                         iValue++;
9266                 };
9267                 var iValue = 0;
9268                 for (var iFormat = 0; iFormat < format.length; iFormat++) {
9269                         if (literal)
9270                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9271                                         literal = false;
9272                                 else
9273                                         checkLiteral();
9274                         else
9275                                 switch (format.charAt(iFormat)) {
9276                                         case 'd':
9277                                                 day = getNumber('d');
9278                                                 break;
9279                                         case 'D':
9280                                                 getName('D', dayNamesShort, dayNames);
9281                                                 break;
9282                                         case 'o':
9283                                                 doy = getNumber('o');
9284                                                 break;
9285                                         case 'm':
9286                                                 month = getNumber('m');
9287                                                 break;
9288                                         case 'M':
9289                                                 month = getName('M', monthNamesShort, monthNames);
9290                                                 break;
9291                                         case 'y':
9292                                                 year = getNumber('y');
9293                                                 break;
9294                                         case '@':
9295                                                 var date = new Date(getNumber('@'));
9296                                                 year = date.getFullYear();
9297                                                 month = date.getMonth() + 1;
9298                                                 day = date.getDate();
9299                                                 break;
9300                                         case '!':
9301                                                 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
9302                                                 year = date.getFullYear();
9303                                                 month = date.getMonth() + 1;
9304                                                 day = date.getDate();
9305                                                 break;
9306                                         case "'":
9307                                                 if (lookAhead("'"))
9308                                                         checkLiteral();
9309                                                 else
9310                                                         literal = true;
9311                                                 break;
9312                                         default:
9313                                                 checkLiteral();
9314                                 }
9315                 }
9316                 if (iValue < value.length){
9317                         throw "Extra/unparsed characters found in date: " + value.substring(iValue);
9318                 }
9319                 if (year == -1)
9320                         year = new Date().getFullYear();
9321                 else if (year < 100)
9322                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9323                                 (year <= shortYearCutoff ? 0 : -100);
9324                 if (doy > -1) {
9325                         month = 1;
9326                         day = doy;
9327                         do {
9328                                 var dim = this._getDaysInMonth(year, month - 1);
9329                                 if (day <= dim)
9330                                         break;
9331                                 month++;
9332                                 day -= dim;
9333                         } while (true);
9334                 }
9335                 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9336                 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
9337                         throw 'Invalid date'; // E.g. 31/02/00
9338                 return date;
9339         },
9340
9341         /* Standard date formats. */
9342         ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
9343         COOKIE: 'D, dd M yy',
9344         ISO_8601: 'yy-mm-dd',
9345         RFC_822: 'D, d M y',
9346         RFC_850: 'DD, dd-M-y',
9347         RFC_1036: 'D, d M y',
9348         RFC_1123: 'D, d M yy',
9349         RFC_2822: 'D, d M yy',
9350         RSS: 'D, d M y', // RFC 822
9351         TICKS: '!',
9352         TIMESTAMP: '@',
9353         W3C: 'yy-mm-dd', // ISO 8601
9354
9355         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9356                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9357
9358         /* Format a date object into a string value.
9359            The format can be combinations of the following:
9360            d  - day of month (no leading zero)
9361            dd - day of month (two digit)
9362            o  - day of year (no leading zeros)
9363            oo - day of year (three digit)
9364            D  - day name short
9365            DD - day name long
9366            m  - month of year (no leading zero)
9367            mm - month of year (two digit)
9368            M  - month name short
9369            MM - month name long
9370            y  - year (two digit)
9371            yy - year (four digit)
9372            @ - Unix timestamp (ms since 01/01/1970)
9373            ! - Windows ticks (100ns since 01/01/0001)
9374            '...' - literal text
9375            '' - single quote
9376
9377            @param  format    string - the desired format of the date
9378            @param  date      Date - the date value to format
9379            @param  settings  Object - attributes include:
9380                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
9381                              dayNames         string[7] - names of the days from Sunday (optional)
9382                              monthNamesShort  string[12] - abbreviated names of the months (optional)
9383                              monthNames       string[12] - names of the months (optional)
9384            @return  string - the date in the above format */
9385         formatDate: function (format, date, settings) {
9386                 if (!date)
9387                         return '';
9388                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9389                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9390                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9391                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9392                 // Check whether a format character is doubled
9393                 var lookAhead = function(match) {
9394                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9395                         if (matches)
9396                                 iFormat++;
9397                         return matches;
9398                 };
9399                 // Format a number, with leading zero if necessary
9400                 var formatNumber = function(match, value, len) {
9401                         var num = '' + value;
9402                         if (lookAhead(match))
9403                                 while (num.length < len)
9404                                         num = '0' + num;
9405                         return num;
9406                 };
9407                 // Format a name, short or long as requested
9408                 var formatName = function(match, value, shortNames, longNames) {
9409                         return (lookAhead(match) ? longNames[value] : shortNames[value]);
9410                 };
9411                 var output = '';
9412                 var literal = false;
9413                 if (date)
9414                         for (var iFormat = 0; iFormat < format.length; iFormat++) {
9415                                 if (literal)
9416                                         if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9417                                                 literal = false;
9418                                         else
9419                                                 output += format.charAt(iFormat);
9420                                 else
9421                                         switch (format.charAt(iFormat)) {
9422                                                 case 'd':
9423                                                         output += formatNumber('d', date.getDate(), 2);
9424                                                         break;
9425                                                 case 'D':
9426                                                         output += formatName('D', date.getDay(), dayNamesShort, dayNames);
9427                                                         break;
9428                                                 case 'o':
9429                                                         output += formatNumber('o',
9430                                                                 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9431                                                         break;
9432                                                 case 'm':
9433                                                         output += formatNumber('m', date.getMonth() + 1, 2);
9434                                                         break;
9435                                                 case 'M':
9436                                                         output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
9437                                                         break;
9438                                                 case 'y':
9439                                                         output += (lookAhead('y') ? date.getFullYear() :
9440                                                                 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
9441                                                         break;
9442                                                 case '@':
9443                                                         output += date.getTime();
9444                                                         break;
9445                                                 case '!':
9446                                                         output += date.getTime() * 10000 + this._ticksTo1970;
9447                                                         break;
9448                                                 case "'":
9449                                                         if (lookAhead("'"))
9450                                                                 output += "'";
9451                                                         else
9452                                                                 literal = true;
9453                                                         break;
9454                                                 default:
9455                                                         output += format.charAt(iFormat);
9456                                         }
9457                         }
9458                 return output;
9459         },
9460
9461         /* Extract all possible characters from the date format. */
9462         _possibleChars: function (format) {
9463                 var chars = '';
9464                 var literal = false;
9465                 // Check whether a format character is doubled
9466                 var lookAhead = function(match) {
9467                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9468                         if (matches)
9469                                 iFormat++;
9470                         return matches;
9471                 };
9472                 for (var iFormat = 0; iFormat < format.length; iFormat++)
9473                         if (literal)
9474                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9475                                         literal = false;
9476                                 else
9477                                         chars += format.charAt(iFormat);
9478                         else
9479                                 switch (format.charAt(iFormat)) {
9480                                         case 'd': case 'm': case 'y': case '@':
9481                                                 chars += '0123456789';
9482                                                 break;
9483                                         case 'D': case 'M':
9484                                                 return null; // Accept anything
9485                                         case "'":
9486                                                 if (lookAhead("'"))
9487                                                         chars += "'";
9488                                                 else
9489                                                         literal = true;
9490                                                 break;
9491                                         default:
9492                                                 chars += format.charAt(iFormat);
9493                                 }
9494                 return chars;
9495         },
9496
9497         /* Get a setting value, defaulting if necessary. */
9498         _get: function(inst, name) {
9499                 return inst.settings[name] !== undefined ?
9500                         inst.settings[name] : this._defaults[name];
9501         },
9502
9503         /* Parse existing date and initialise date picker. */
9504         _setDateFromField: function(inst, noDefault) {
9505                 if (inst.input.val() == inst.lastVal) {
9506                         return;
9507                 }
9508                 var dateFormat = this._get(inst, 'dateFormat');
9509                 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
9510                 var date, defaultDate;
9511                 date = defaultDate = this._getDefaultDate(inst);
9512                 var settings = this._getFormatConfig(inst);
9513                 try {
9514                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9515                 } catch (event) {
9516                         this.log(event);
9517                         dates = (noDefault ? '' : dates);
9518                 }
9519                 inst.selectedDay = date.getDate();
9520                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9521                 inst.drawYear = inst.selectedYear = date.getFullYear();
9522                 inst.currentDay = (dates ? date.getDate() : 0);
9523                 inst.currentMonth = (dates ? date.getMonth() : 0);
9524                 inst.currentYear = (dates ? date.getFullYear() : 0);
9525                 this._adjustInstDate(inst);
9526         },
9527
9528         /* Retrieve the default date shown on opening. */
9529         _getDefaultDate: function(inst) {
9530                 return this._restrictMinMax(inst,
9531                         this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
9532         },
9533
9534         /* A date may be specified as an exact value or a relative one. */
9535         _determineDate: function(inst, date, defaultDate) {
9536                 var offsetNumeric = function(offset) {
9537                         var date = new Date();
9538                         date.setDate(date.getDate() + offset);
9539                         return date;
9540                 };
9541                 var offsetString = function(offset) {
9542                         try {
9543                                 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
9544                                         offset, $.datepicker._getFormatConfig(inst));
9545                         }
9546                         catch (e) {
9547                                 // Ignore
9548                         }
9549                         var date = (offset.toLowerCase().match(/^c/) ?
9550                                 $.datepicker._getDate(inst) : null) || new Date();
9551                         var year = date.getFullYear();
9552                         var month = date.getMonth();
9553                         var day = date.getDate();
9554                         var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
9555                         var matches = pattern.exec(offset);
9556                         while (matches) {
9557                                 switch (matches[2] || 'd') {
9558                                         case 'd' : case 'D' :
9559                                                 day += parseInt(matches[1],10); break;
9560                                         case 'w' : case 'W' :
9561                                                 day += parseInt(matches[1],10) * 7; break;
9562                                         case 'm' : case 'M' :
9563                                                 month += parseInt(matches[1],10);
9564                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9565                                                 break;
9566                                         case 'y': case 'Y' :
9567                                                 year += parseInt(matches[1],10);
9568                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9569                                                 break;
9570                                 }
9571                                 matches = pattern.exec(offset);
9572                         }
9573                         return new Date(year, month, day);
9574                 };
9575                 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
9576                         (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9577                 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
9578                 if (newDate) {
9579                         newDate.setHours(0);
9580                         newDate.setMinutes(0);
9581                         newDate.setSeconds(0);
9582                         newDate.setMilliseconds(0);
9583                 }
9584                 return this._daylightSavingAdjust(newDate);
9585         },
9586
9587         /* Handle switch to/from daylight saving.
9588            Hours may be non-zero on daylight saving cut-over:
9589            > 12 when midnight changeover, but then cannot generate
9590            midnight datetime, so jump to 1AM, otherwise reset.
9591            @param  date  (Date) the date to check
9592            @return  (Date) the corrected date */
9593         _daylightSavingAdjust: function(date) {
9594                 if (!date) return null;
9595                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9596                 return date;
9597         },
9598
9599         /* Set the date(s) directly. */
9600         _setDate: function(inst, date, noChange) {
9601                 var clear = !date;
9602                 var origMonth = inst.selectedMonth;
9603                 var origYear = inst.selectedYear;
9604                 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9605                 inst.selectedDay = inst.currentDay = newDate.getDate();
9606                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9607                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9608                 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
9609                         this._notifyChange(inst);
9610                 this._adjustInstDate(inst);
9611                 if (inst.input) {
9612                         inst.input.val(clear ? '' : this._formatDate(inst));
9613                 }
9614         },
9615
9616         /* Retrieve the date(s) directly. */
9617         _getDate: function(inst) {
9618                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
9619                         this._daylightSavingAdjust(new Date(
9620                         inst.currentYear, inst.currentMonth, inst.currentDay)));
9621                         return startDate;
9622         },
9623
9624         /* Generate the HTML for the current state of the date picker. */
9625         _generateHTML: function(inst) {
9626                 var today = new Date();
9627                 today = this._daylightSavingAdjust(
9628                         new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
9629                 var isRTL = this._get(inst, 'isRTL');
9630                 var showButtonPanel = this._get(inst, 'showButtonPanel');
9631                 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
9632                 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
9633                 var numMonths = this._getNumberOfMonths(inst);
9634                 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
9635                 var stepMonths = this._get(inst, 'stepMonths');
9636                 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
9637                 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9638                         new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9639                 var minDate = this._getMinMaxDate(inst, 'min');
9640                 var maxDate = this._getMinMaxDate(inst, 'max');
9641                 var drawMonth = inst.drawMonth - showCurrentAtPos;
9642                 var drawYear = inst.drawYear;
9643                 if (drawMonth < 0) {
9644                         drawMonth += 12;
9645                         drawYear--;
9646                 }
9647                 if (maxDate) {
9648                         var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9649                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9650                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9651                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9652                                 drawMonth--;
9653                                 if (drawMonth < 0) {
9654                                         drawMonth = 11;
9655                                         drawYear--;
9656                                 }
9657                         }
9658                 }
9659                 inst.drawMonth = drawMonth;
9660                 inst.drawYear = drawYear;
9661                 var prevText = this._get(inst, 'prevText');
9662                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9663                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9664                         this._getFormatConfig(inst)));
9665                 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9666                         '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9667                         '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
9668                         ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
9669                         (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>'));
9670                 var nextText = this._get(inst, 'nextText');
9671                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9672                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9673                         this._getFormatConfig(inst)));
9674                 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9675                         '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9676                         '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
9677                         ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
9678                         (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>'));
9679                 var currentText = this._get(inst, 'currentText');
9680                 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
9681                 currentText = (!navigationAsDateFormat ? currentText :
9682                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9683                 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9684                         '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
9685                 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
9686                         (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9687                         '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
9688                         '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
9689                 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
9690                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
9691                 var showWeek = this._get(inst, 'showWeek');
9692                 var dayNames = this._get(inst, 'dayNames');
9693                 var dayNamesShort = this._get(inst, 'dayNamesShort');
9694                 var dayNamesMin = this._get(inst, 'dayNamesMin');
9695                 var monthNames = this._get(inst, 'monthNames');
9696                 var monthNamesShort = this._get(inst, 'monthNamesShort');
9697                 var beforeShowDay = this._get(inst, 'beforeShowDay');
9698                 var showOtherMonths = this._get(inst, 'showOtherMonths');
9699                 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
9700                 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
9701                 var defaultDate = this._getDefaultDate(inst);
9702                 var html = '';
9703                 for (var row = 0; row < numMonths[0]; row++) {
9704                         var group = '';
9705                         this.maxRows = 4;
9706                         for (var col = 0; col < numMonths[1]; col++) {
9707                                 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9708                                 var cornerClass = ' ui-corner-all';
9709                                 var calender = '';
9710                                 if (isMultiMonth) {
9711                                         calender += '<div class="ui-datepicker-group';
9712                                         if (numMonths[1] > 1)
9713                                                 switch (col) {
9714                                                         case 0: calender += ' ui-datepicker-group-first';
9715                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
9716                                                         case numMonths[1]-1: calender += ' ui-datepicker-group-last';
9717                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
9718                                                         default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
9719                                                 }
9720                                         calender += '">';
9721                                 }
9722                                 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
9723                                         (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
9724                                         (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
9725                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9726                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9727                                         '</div><table class="ui-datepicker-calendar"><thead>' +
9728                                         '<tr>';
9729                                 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
9730                                 for (var dow = 0; dow < 7; dow++) { // days of the week
9731                                         var day = (dow + firstDay) % 7;
9732                                         thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
9733                                                 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
9734                                 }
9735                                 calender += thead + '</tr></thead><tbody>';
9736                                 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9737                                 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
9738                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9739                                 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9740                                 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9741                                 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9742                                 this.maxRows = numRows;
9743                                 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9744                                 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9745                                         calender += '<tr>';
9746                                         var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
9747                                                 this._get(inst, 'calculateWeek')(printDate) + '</td>');
9748                                         for (var dow = 0; dow < 7; dow++) { // create date picker days
9749                                                 var daySettings = (beforeShowDay ?
9750                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
9751                                                 var otherMonth = (printDate.getMonth() != drawMonth);
9752                                                 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9753                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9754                                                 tbody += '<td class="' +
9755                                                         ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
9756                                                         (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
9757                                                         ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
9758                                                         (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
9759                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
9760                                                         ' ' + this._dayOverClass : '') + // highlight selected day
9761                                                         (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
9762                                                         (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
9763                                                         (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
9764                                                         (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
9765                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
9766                                                         (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
9767                                                         inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
9768                                                         (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
9769                                                         (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
9770                                                         (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
9771                                                         (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
9772                                                         (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
9773                                                         '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
9774                                                 printDate.setDate(printDate.getDate() + 1);
9775                                                 printDate = this._daylightSavingAdjust(printDate);
9776                                         }
9777                                         calender += tbody + '</tr>';
9778                                 }
9779                                 drawMonth++;
9780                                 if (drawMonth > 11) {
9781                                         drawMonth = 0;
9782                                         drawYear++;
9783                                 }
9784                                 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 
9785                                                         ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
9786                                 group += calender;
9787                         }
9788                         html += group;
9789                 }
9790                 html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
9791                         '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
9792                 inst._keyEvent = false;
9793                 return html;
9794         },
9795
9796         /* Generate the month and year header. */
9797         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9798                         secondary, monthNames, monthNamesShort) {
9799                 var changeMonth = this._get(inst, 'changeMonth');
9800                 var changeYear = this._get(inst, 'changeYear');
9801                 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
9802                 var html = '<div class="ui-datepicker-title">';
9803                 var monthHtml = '';
9804                 // month selection
9805                 if (secondary || !changeMonth)
9806                         monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
9807                 else {
9808                         var inMinYear = (minDate && minDate.getFullYear() == drawYear);
9809                         var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
9810                         monthHtml += '<select class="ui-datepicker-month" ' +
9811                                 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
9812                                 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
9813                                 '>';
9814                         for (var month = 0; month < 12; month++) {
9815                                 if ((!inMinYear || month >= minDate.getMonth()) &&
9816                                                 (!inMaxYear || month <= maxDate.getMonth()))
9817                                         monthHtml += '<option value="' + month + '"' +
9818                                                 (month == drawMonth ? ' selected="selected"' : '') +
9819                                                 '>' + monthNamesShort[month] + '</option>';
9820                         }
9821                         monthHtml += '</select>';
9822                 }
9823                 if (!showMonthAfterYear)
9824                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
9825                 // year selection
9826                 if ( !inst.yearshtml ) {
9827                         inst.yearshtml = '';
9828                         if (secondary || !changeYear)
9829                                 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
9830                         else {
9831                                 // determine range of years to display
9832                                 var years = this._get(inst, 'yearRange').split(':');
9833                                 var thisYear = new Date().getFullYear();
9834                                 var determineYear = function(value) {
9835                                         var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9836                                                 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
9837                                                 parseInt(value, 10)));
9838                                         return (isNaN(year) ? thisYear : year);
9839                                 };
9840                                 var year = determineYear(years[0]);
9841                                 var endYear = Math.max(year, determineYear(years[1] || ''));
9842                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9843                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9844                                 inst.yearshtml += '<select class="ui-datepicker-year" ' +
9845                                         'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
9846                                         'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
9847                                         '>';
9848                                 for (; year <= endYear; year++) {
9849                                         inst.yearshtml += '<option value="' + year + '"' +
9850                                                 (year == drawYear ? ' selected="selected"' : '') +
9851                                                 '>' + year + '</option>';
9852                                 }
9853                                 inst.yearshtml += '</select>';
9854                                 
9855                                 html += inst.yearshtml;
9856                                 inst.yearshtml = null;
9857                         }
9858                 }
9859                 html += this._get(inst, 'yearSuffix');
9860                 if (showMonthAfterYear)
9861                         html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
9862                 html += '</div>'; // Close datepicker_header
9863                 return html;
9864         },
9865
9866         /* Adjust one of the date sub-fields. */
9867         _adjustInstDate: function(inst, offset, period) {
9868                 var year = inst.drawYear + (period == 'Y' ? offset : 0);
9869                 var month = inst.drawMonth + (period == 'M' ? offset : 0);
9870                 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
9871                         (period == 'D' ? offset : 0);
9872                 var date = this._restrictMinMax(inst,
9873                         this._daylightSavingAdjust(new Date(year, month, day)));
9874                 inst.selectedDay = date.getDate();
9875                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9876                 inst.drawYear = inst.selectedYear = date.getFullYear();
9877                 if (period == 'M' || period == 'Y')
9878                         this._notifyChange(inst);
9879         },
9880
9881         /* Ensure a date is within any min/max bounds. */
9882         _restrictMinMax: function(inst, date) {
9883                 var minDate = this._getMinMaxDate(inst, 'min');
9884                 var maxDate = this._getMinMaxDate(inst, 'max');
9885                 var newDate = (minDate && date < minDate ? minDate : date);
9886                 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
9887                 return newDate;
9888         },
9889
9890         /* Notify change of month/year. */
9891         _notifyChange: function(inst) {
9892                 var onChange = this._get(inst, 'onChangeMonthYear');
9893                 if (onChange)
9894                         onChange.apply((inst.input ? inst.input[0] : null),
9895                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9896         },
9897
9898         /* Determine the number of months to show. */
9899         _getNumberOfMonths: function(inst) {
9900                 var numMonths = this._get(inst, 'numberOfMonths');
9901                 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
9902         },
9903
9904         /* Determine the current maximum date - ensure no time components are set. */
9905         _getMinMaxDate: function(inst, minMax) {
9906                 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
9907         },
9908
9909         /* Find the number of days in a given month. */
9910         _getDaysInMonth: function(year, month) {
9911                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9912         },
9913
9914         /* Find the day of the week of the first of a month. */
9915         _getFirstDayOfMonth: function(year, month) {
9916                 return new Date(year, month, 1).getDay();
9917         },
9918
9919         /* Determines if we should allow a "next/prev" month display change. */
9920         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9921                 var numMonths = this._getNumberOfMonths(inst);
9922                 var date = this._daylightSavingAdjust(new Date(curYear,
9923                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9924                 if (offset < 0)
9925                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9926                 return this._isInRange(inst, date);
9927         },
9928
9929         /* Is the given date in the accepted range? */
9930         _isInRange: function(inst, date) {
9931                 var minDate = this._getMinMaxDate(inst, 'min');
9932                 var maxDate = this._getMinMaxDate(inst, 'max');
9933                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
9934                         (!maxDate || date.getTime() <= maxDate.getTime()));
9935         },
9936
9937         /* Provide the configuration settings for formatting/parsing. */
9938         _getFormatConfig: function(inst) {
9939                 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
9940                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9941                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9942                 return {shortYearCutoff: shortYearCutoff,
9943                         dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
9944                         monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
9945         },
9946
9947         /* Format the given date for display. */
9948         _formatDate: function(inst, day, month, year) {
9949                 if (!day) {
9950                         inst.currentDay = inst.selectedDay;
9951                         inst.currentMonth = inst.selectedMonth;
9952                         inst.currentYear = inst.selectedYear;
9953                 }
9954                 var date = (day ? (typeof day == 'object' ? day :
9955                         this._daylightSavingAdjust(new Date(year, month, day))) :
9956                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9957                 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
9958         }
9959 });
9960
9961 /*
9962  * Bind hover events for datepicker elements.
9963  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9964  * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9965  */ 
9966 function bindHover(dpDiv) {
9967         var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
9968         return dpDiv.bind('mouseout', function(event) {
9969                         var elem = $( event.target ).closest( selector );
9970                         if ( !elem.length ) {
9971                                 return;
9972                         }
9973                         elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
9974                 })
9975                 .bind('mouseover', function(event) {
9976                         var elem = $( event.target ).closest( selector );
9977                         if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
9978                                         !elem.length ) {
9979                                 return;
9980                         }
9981                         elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
9982                         elem.addClass('ui-state-hover');
9983                         if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
9984                         if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
9985                 });
9986 }
9987
9988 /* jQuery extend now ignores nulls! */
9989 function extendRemove(target, props) {
9990         $.extend(target, props);
9991         for (var name in props)
9992                 if (props[name] == null || props[name] == undefined)
9993                         target[name] = props[name];
9994         return target;
9995 };
9996
9997 /* Determine whether an object is an array. */
9998 function isArray(a) {
9999         return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
10000                 (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
10001 };
10002
10003 /* Invoke the datepicker functionality.
10004    @param  options  string - a command, optionally followed by additional parameters or
10005                     Object - settings for attaching new datepicker functionality
10006    @return  jQuery object */
10007 $.fn.datepicker = function(options){
10008         
10009         /* Verify an empty collection wasn't passed - Fixes #6976 */
10010         if ( !this.length ) {
10011                 return this;
10012         }
10013         
10014         /* Initialise the date picker. */
10015         if (!$.datepicker.initialized) {
10016                 $(document).mousedown($.datepicker._checkExternalClick).
10017                         find('body').append($.datepicker.dpDiv);
10018                 $.datepicker.initialized = true;
10019         }
10020
10021         var otherArgs = Array.prototype.slice.call(arguments, 1);
10022         if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
10023                 return $.datepicker['_' + options + 'Datepicker'].
10024                         apply($.datepicker, [this[0]].concat(otherArgs));
10025         if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
10026                 return $.datepicker['_' + options + 'Datepicker'].
10027                         apply($.datepicker, [this[0]].concat(otherArgs));
10028         return this.each(function() {
10029                 typeof options == 'string' ?
10030                         $.datepicker['_' + options + 'Datepicker'].
10031                                 apply($.datepicker, [this].concat(otherArgs)) :
10032                         $.datepicker._attachDatepicker(this, options);
10033         });
10034 };
10035
10036 $.datepicker = new Datepicker(); // singleton instance
10037 $.datepicker.initialized = false;
10038 $.datepicker.uuid = new Date().getTime();
10039 $.datepicker.version = "1.8.14";
10040
10041 // Workaround for #4055
10042 // Add another global to avoid noConflict issues with inline event handlers
10043 window['DP_jQuery_' + dpuuid] = $;
10044
10045 })(jQuery);
10046 /*
10047  * jQuery UI Progressbar 1.8.14
10048  *
10049  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10050  * Dual licensed under the MIT or GPL Version 2 licenses.
10051  * http://jquery.org/license
10052  *
10053  * http://docs.jquery.com/UI/Progressbar
10054  *
10055  * Depends:
10056  *   jquery.ui.core.js
10057  *   jquery.ui.widget.js
10058  */
10059 (function( $, undefined ) {
10060
10061 $.widget( "ui.progressbar", {
10062         options: {
10063                 value: 0,
10064                 max: 100
10065         },
10066
10067         min: 0,
10068
10069         _create: function() {
10070                 this.element
10071                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10072                         .attr({
10073                                 role: "progressbar",
10074                                 "aria-valuemin": this.min,
10075                                 "aria-valuemax": this.options.max,
10076                                 "aria-valuenow": this._value()
10077                         });
10078
10079                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10080                         .appendTo( this.element );
10081
10082                 this.oldValue = this._value();
10083                 this._refreshValue();
10084         },
10085
10086         destroy: function() {
10087                 this.element
10088                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10089                         .removeAttr( "role" )
10090                         .removeAttr( "aria-valuemin" )
10091                         .removeAttr( "aria-valuemax" )
10092                         .removeAttr( "aria-valuenow" );
10093
10094                 this.valueDiv.remove();
10095
10096                 $.Widget.prototype.destroy.apply( this, arguments );
10097         },
10098
10099         value: function( newValue ) {
10100                 if ( newValue === undefined ) {
10101                         return this._value();
10102                 }
10103
10104                 this._setOption( "value", newValue );
10105                 return this;
10106         },
10107
10108         _setOption: function( key, value ) {
10109                 if ( key === "value" ) {
10110                         this.options.value = value;
10111                         this._refreshValue();
10112                         if ( this._value() === this.options.max ) {
10113                                 this._trigger( "complete" );
10114                         }
10115                 }
10116
10117                 $.Widget.prototype._setOption.apply( this, arguments );
10118         },
10119
10120         _value: function() {
10121                 var val = this.options.value;
10122                 // normalize invalid value
10123                 if ( typeof val !== "number" ) {
10124                         val = 0;
10125                 }
10126                 return Math.min( this.options.max, Math.max( this.min, val ) );
10127         },
10128
10129         _percentage: function() {
10130                 return 100 * this._value() / this.options.max;
10131         },
10132
10133         _refreshValue: function() {
10134                 var value = this.value();
10135                 var percentage = this._percentage();
10136
10137                 if ( this.oldValue !== value ) {
10138                         this.oldValue = value;
10139                         this._trigger( "change" );
10140                 }
10141
10142                 this.valueDiv
10143                         .toggle( value > this.min )
10144                         .toggleClass( "ui-corner-right", value === this.options.max )
10145                         .width( percentage.toFixed(0) + "%" );
10146                 this.element.attr( "aria-valuenow", value );
10147         }
10148 });
10149
10150 $.extend( $.ui.progressbar, {
10151         version: "1.8.14"
10152 });
10153
10154 })( jQuery );
10155 /*
10156  * jQuery UI Effects 1.8.14
10157  *
10158  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10159  * Dual licensed under the MIT or GPL Version 2 licenses.
10160  * http://jquery.org/license
10161  *
10162  * http://docs.jquery.com/UI/Effects/
10163  */
10164 ;jQuery.effects || (function($, undefined) {
10165
10166 $.effects = {};
10167
10168
10169
10170 /******************************************************************************/
10171 /****************************** COLOR ANIMATIONS ******************************/
10172 /******************************************************************************/
10173
10174 // override the animation for color styles
10175 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
10176         'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
10177 function(i, attr) {
10178         $.fx.step[attr] = function(fx) {
10179                 if (!fx.colorInit) {
10180                         fx.start = getColor(fx.elem, attr);
10181                         fx.end = getRGB(fx.end);
10182                         fx.colorInit = true;
10183                 }
10184
10185                 fx.elem.style[attr] = 'rgb(' +
10186                         Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
10187                         Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
10188                         Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
10189         };
10190 });
10191
10192 // Color Conversion functions from highlightFade
10193 // By Blair Mitchelmore
10194 // http://jquery.offput.ca/highlightFade/
10195
10196 // Parse strings looking for color tuples [255,255,255]
10197 function getRGB(color) {
10198                 var result;
10199
10200                 // Check if we're already dealing with an array of colors
10201                 if ( color && color.constructor == Array && color.length == 3 )
10202                                 return color;
10203
10204                 // Look for rgb(num,num,num)
10205                 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
10206                                 return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
10207
10208                 // Look for rgb(num%,num%,num%)
10209                 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
10210                                 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
10211
10212                 // Look for #a0b1c2
10213                 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
10214                                 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
10215
10216                 // Look for #fff
10217                 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
10218                                 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
10219
10220                 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
10221                 if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
10222                                 return colors['transparent'];
10223
10224                 // Otherwise, we're most likely dealing with a named color
10225                 return colors[$.trim(color).toLowerCase()];
10226 }
10227
10228 function getColor(elem, attr) {
10229                 var color;
10230
10231                 do {
10232                                 color = $.curCSS(elem, attr);
10233
10234                                 // Keep going until we find an element that has color, or we hit the body
10235                                 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
10236                                                 break;
10237
10238                                 attr = "backgroundColor";
10239                 } while ( elem = elem.parentNode );
10240
10241                 return getRGB(color);
10242 };
10243
10244 // Some named colors to work with
10245 // From Interface by Stefan Petre
10246 // http://interface.eyecon.ro/
10247
10248 var colors = {
10249         aqua:[0,255,255],
10250         azure:[240,255,255],
10251         beige:[245,245,220],
10252         black:[0,0,0],
10253         blue:[0,0,255],
10254         brown:[165,42,42],
10255         cyan:[0,255,255],
10256         darkblue:[0,0,139],
10257         darkcyan:[0,139,139],
10258         darkgrey:[169,169,169],
10259         darkgreen:[0,100,0],
10260         darkkhaki:[189,183,107],
10261         darkmagenta:[139,0,139],
10262         darkolivegreen:[85,107,47],
10263         darkorange:[255,140,0],
10264         darkorchid:[153,50,204],
10265         darkred:[139,0,0],
10266         darksalmon:[233,150,122],
10267         darkviolet:[148,0,211],
10268         fuchsia:[255,0,255],
10269         gold:[255,215,0],
10270         green:[0,128,0],
10271         indigo:[75,0,130],
10272         khaki:[240,230,140],
10273         lightblue:[173,216,230],
10274         lightcyan:[224,255,255],
10275         lightgreen:[144,238,144],
10276         lightgrey:[211,211,211],
10277         lightpink:[255,182,193],
10278         lightyellow:[255,255,224],
10279         lime:[0,255,0],
10280         magenta:[255,0,255],
10281         maroon:[128,0,0],
10282         navy:[0,0,128],
10283         olive:[128,128,0],
10284         orange:[255,165,0],
10285         pink:[255,192,203],
10286         purple:[128,0,128],
10287         violet:[128,0,128],
10288         red:[255,0,0],
10289         silver:[192,192,192],
10290         white:[255,255,255],
10291         yellow:[255,255,0],
10292         transparent: [255,255,255]
10293 };
10294
10295
10296
10297 /******************************************************************************/
10298 /****************************** CLASS ANIMATIONS ******************************/
10299 /******************************************************************************/
10300
10301 var classAnimationActions = ['add', 'remove', 'toggle'],
10302         shorthandStyles = {
10303                 border: 1,
10304                 borderBottom: 1,
10305                 borderColor: 1,
10306                 borderLeft: 1,
10307                 borderRight: 1,
10308                 borderTop: 1,
10309                 borderWidth: 1,
10310                 margin: 1,
10311                 padding: 1
10312         };
10313
10314 function getElementStyles() {
10315         var style = document.defaultView
10316                         ? document.defaultView.getComputedStyle(this, null)
10317                         : this.currentStyle,
10318                 newStyle = {},
10319                 key,
10320                 camelCase;
10321
10322         // webkit enumerates style porperties
10323         if (style && style.length && style[0] && style[style[0]]) {
10324                 var len = style.length;
10325                 while (len--) {
10326                         key = style[len];
10327                         if (typeof style[key] == 'string') {
10328                                 camelCase = key.replace(/\-(\w)/g, function(all, letter){
10329                                         return letter.toUpperCase();
10330                                 });
10331                                 newStyle[camelCase] = style[key];
10332                         }
10333                 }
10334         } else {
10335                 for (key in style) {
10336                         if (typeof style[key] === 'string') {
10337                                 newStyle[key] = style[key];
10338                         }
10339                 }
10340         }
10341         
10342         return newStyle;
10343 }
10344
10345 function filterStyles(styles) {
10346         var name, value;
10347         for (name in styles) {
10348                 value = styles[name];
10349                 if (
10350                         // ignore null and undefined values
10351                         value == null ||
10352                         // ignore functions (when does this occur?)
10353                         $.isFunction(value) ||
10354                         // shorthand styles that need to be expanded
10355                         name in shorthandStyles ||
10356                         // ignore scrollbars (break in IE)
10357                         (/scrollbar/).test(name) ||
10358
10359                         // only colors or values that can be converted to numbers
10360                         (!(/color/i).test(name) && isNaN(parseFloat(value)))
10361                 ) {
10362                         delete styles[name];
10363                 }
10364         }
10365         
10366         return styles;
10367 }
10368
10369 function styleDifference(oldStyle, newStyle) {
10370         var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
10371                 name;
10372
10373         for (name in newStyle) {
10374                 if (oldStyle[name] != newStyle[name]) {
10375                         diff[name] = newStyle[name];
10376                 }
10377         }
10378
10379         return diff;
10380 }
10381
10382 $.effects.animateClass = function(value, duration, easing, callback) {
10383         if ($.isFunction(easing)) {
10384                 callback = easing;
10385                 easing = null;
10386         }
10387
10388         return this.queue(function() {
10389                 var that = $(this),
10390                         originalStyleAttr = that.attr('style') || ' ',
10391                         originalStyle = filterStyles(getElementStyles.call(this)),
10392                         newStyle,
10393                         className = that.attr('class');
10394
10395                 $.each(classAnimationActions, function(i, action) {
10396                         if (value[action]) {
10397                                 that[action + 'Class'](value[action]);
10398                         }
10399                 });
10400                 newStyle = filterStyles(getElementStyles.call(this));
10401                 that.attr('class', className);
10402
10403                 that.animate(styleDifference(originalStyle, newStyle), {
10404                         queue: false,
10405                         duration: duration,
10406                         easing: easing,
10407                         complete: function() {
10408                                 $.each(classAnimationActions, function(i, action) {
10409                                         if (value[action]) { that[action + 'Class'](value[action]); }
10410                                 });
10411                                 // work around bug in IE by clearing the cssText before setting it
10412                                 if (typeof that.attr('style') == 'object') {
10413                                         that.attr('style').cssText = '';
10414                                         that.attr('style').cssText = originalStyleAttr;
10415                                 } else {
10416                                         that.attr('style', originalStyleAttr);
10417                                 }
10418                                 if (callback) { callback.apply(this, arguments); }
10419                                 $.dequeue( this );
10420                         }
10421                 });
10422         });
10423 };
10424
10425 $.fn.extend({
10426         _addClass: $.fn.addClass,
10427         addClass: function(classNames, speed, easing, callback) {
10428                 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
10429         },
10430
10431         _removeClass: $.fn.removeClass,
10432         removeClass: function(classNames,speed,easing,callback) {
10433                 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
10434         },
10435
10436         _toggleClass: $.fn.toggleClass,
10437         toggleClass: function(classNames, force, speed, easing, callback) {
10438                 if ( typeof force == "boolean" || force === undefined ) {
10439                         if ( !speed ) {
10440                                 // without speed parameter;
10441                                 return this._toggleClass(classNames, force);
10442                         } else {
10443                                 return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
10444                         }
10445                 } else {
10446                         // without switch parameter;
10447                         return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
10448                 }
10449         },
10450
10451         switchClass: function(remove,add,speed,easing,callback) {
10452                 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
10453         }
10454 });
10455
10456
10457
10458 /******************************************************************************/
10459 /*********************************** EFFECTS **********************************/
10460 /******************************************************************************/
10461
10462 $.extend($.effects, {
10463         version: "1.8.14",
10464
10465         // Saves a set of properties in a data storage
10466         save: function(element, set) {
10467                 for(var i=0; i < set.length; i++) {
10468                         if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
10469                 }
10470         },
10471
10472         // Restores a set of previously saved properties from a data storage
10473         restore: function(element, set) {
10474                 for(var i=0; i < set.length; i++) {
10475                         if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
10476                 }
10477         },
10478
10479         setMode: function(el, mode) {
10480                 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
10481                 return mode;
10482         },
10483
10484         getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
10485                 // this should be a little more flexible in the future to handle a string & hash
10486                 var y, x;
10487                 switch (origin[0]) {
10488                         case 'top': y = 0; break;
10489                         case 'middle': y = 0.5; break;
10490                         case 'bottom': y = 1; break;
10491                         default: y = origin[0] / original.height;
10492                 };
10493                 switch (origin[1]) {
10494                         case 'left': x = 0; break;
10495                         case 'center': x = 0.5; break;
10496                         case 'right': x = 1; break;
10497                         default: x = origin[1] / original.width;
10498                 };
10499                 return {x: x, y: y};
10500         },
10501
10502         // Wraps the element around a wrapper that copies position properties
10503         createWrapper: function(element) {
10504
10505                 // if the element is already wrapped, return it
10506                 if (element.parent().is('.ui-effects-wrapper')) {
10507                         return element.parent();
10508                 }
10509
10510                 // wrap the element
10511                 var props = {
10512                                 width: element.outerWidth(true),
10513                                 height: element.outerHeight(true),
10514                                 'float': element.css('float')
10515                         },
10516                         wrapper = $('<div></div>')
10517                                 .addClass('ui-effects-wrapper')
10518                                 .css({
10519                                         fontSize: '100%',
10520                                         background: 'transparent',
10521                                         border: 'none',
10522                                         margin: 0,
10523                                         padding: 0
10524                                 });
10525
10526                 element.wrap(wrapper);
10527                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
10528
10529                 // transfer positioning properties to the wrapper
10530                 if (element.css('position') == 'static') {
10531                         wrapper.css({ position: 'relative' });
10532                         element.css({ position: 'relative' });
10533                 } else {
10534                         $.extend(props, {
10535                                 position: element.css('position'),
10536                                 zIndex: element.css('z-index')
10537                         });
10538                         $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
10539                                 props[pos] = element.css(pos);
10540                                 if (isNaN(parseInt(props[pos], 10))) {
10541                                         props[pos] = 'auto';
10542                                 }
10543                         });
10544                         element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
10545                 }
10546
10547                 return wrapper.css(props).show();
10548         },
10549
10550         removeWrapper: function(element) {
10551                 if (element.parent().is('.ui-effects-wrapper'))
10552                         return element.parent().replaceWith(element);
10553                 return element;
10554         },
10555
10556         setTransition: function(element, list, factor, value) {
10557                 value = value || {};
10558                 $.each(list, function(i, x){
10559                         unit = element.cssUnit(x);
10560                         if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
10561                 });
10562                 return value;
10563         }
10564 });
10565
10566
10567 function _normalizeArguments(effect, options, speed, callback) {
10568         // shift params for method overloading
10569         if (typeof effect == 'object') {
10570                 callback = options;
10571                 speed = null;
10572                 options = effect;
10573                 effect = options.effect;
10574         }
10575         if ($.isFunction(options)) {
10576                 callback = options;
10577                 speed = null;
10578                 options = {};
10579         }
10580         if (typeof options == 'number' || $.fx.speeds[options]) {
10581                 callback = speed;
10582                 speed = options;
10583                 options = {};
10584         }
10585         if ($.isFunction(speed)) {
10586                 callback = speed;
10587                 speed = null;
10588         }
10589
10590         options = options || {};
10591
10592         speed = speed || options.duration;
10593         speed = $.fx.off ? 0 : typeof speed == 'number'
10594                 ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
10595
10596         callback = callback || options.complete;
10597
10598         return [effect, options, speed, callback];
10599 }
10600
10601 function standardSpeed( speed ) {
10602         // valid standard speeds
10603         if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
10604                 return true;
10605         }
10606         
10607         // invalid strings - treat as "normal" speed
10608         if ( typeof speed === "string" && !$.effects[ speed ] ) {
10609                 return true;
10610         }
10611         
10612         return false;
10613 }
10614
10615 $.fn.extend({
10616         effect: function(effect, options, speed, callback) {
10617                 var args = _normalizeArguments.apply(this, arguments),
10618                         // TODO: make effects take actual parameters instead of a hash
10619                         args2 = {
10620                                 options: args[1],
10621                                 duration: args[2],
10622                                 callback: args[3]
10623                         },
10624                         mode = args2.options.mode,
10625                         effectMethod = $.effects[effect];
10626                 
10627                 if ( $.fx.off || !effectMethod ) {
10628                         // delegate to the original method (e.g., .show()) if possible
10629                         if ( mode ) {
10630                                 return this[ mode ]( args2.duration, args2.callback );
10631                         } else {
10632                                 return this.each(function() {
10633                                         if ( args2.callback ) {
10634                                                 args2.callback.call( this );
10635                                         }
10636                                 });
10637                         }
10638                 }
10639                 
10640                 return effectMethod.call(this, args2);
10641         },
10642
10643         _show: $.fn.show,
10644         show: function(speed) {
10645                 if ( standardSpeed( speed ) ) {
10646                         return this._show.apply(this, arguments);
10647                 } else {
10648                         var args = _normalizeArguments.apply(this, arguments);
10649                         args[1].mode = 'show';
10650                         return this.effect.apply(this, args);
10651                 }
10652         },
10653
10654         _hide: $.fn.hide,
10655         hide: function(speed) {
10656                 if ( standardSpeed( speed ) ) {
10657                         return this._hide.apply(this, arguments);
10658                 } else {
10659                         var args = _normalizeArguments.apply(this, arguments);
10660                         args[1].mode = 'hide';
10661                         return this.effect.apply(this, args);
10662                 }
10663         },
10664
10665         // jQuery core overloads toggle and creates _toggle
10666         __toggle: $.fn.toggle,
10667         toggle: function(speed) {
10668                 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
10669                         return this.__toggle.apply(this, arguments);
10670                 } else {
10671                         var args = _normalizeArguments.apply(this, arguments);
10672                         args[1].mode = 'toggle';
10673                         return this.effect.apply(this, args);
10674                 }
10675         },
10676
10677         // helper functions
10678         cssUnit: function(key) {
10679                 var style = this.css(key), val = [];
10680                 $.each( ['em','px','%','pt'], function(i, unit){
10681                         if(style.indexOf(unit) > 0)
10682                                 val = [parseFloat(style), unit];
10683                 });
10684                 return val;
10685         }
10686 });
10687
10688
10689
10690 /******************************************************************************/
10691 /*********************************** EASING ***********************************/
10692 /******************************************************************************/
10693
10694 /*
10695  * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
10696  *
10697  * Uses the built in easing capabilities added In jQuery 1.1
10698  * to offer multiple easing options
10699  *
10700  * TERMS OF USE - jQuery Easing
10701  *
10702  * Open source under the BSD License.
10703  *
10704  * Copyright 2008 George McGinley Smith
10705  * All rights reserved.
10706  *
10707  * Redistribution and use in source and binary forms, with or without modification,
10708  * are permitted provided that the following conditions are met:
10709  *
10710  * Redistributions of source code must retain the above copyright notice, this list of
10711  * conditions and the following disclaimer.
10712  * Redistributions in binary form must reproduce the above copyright notice, this list
10713  * of conditions and the following disclaimer in the documentation and/or other materials
10714  * provided with the distribution.
10715  *
10716  * Neither the name of the author nor the names of contributors may be used to endorse
10717  * or promote products derived from this software without specific prior written permission.
10718  *
10719  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10720  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10721  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10722  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10723  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10724  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10725  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10726  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10727  * OF THE POSSIBILITY OF SUCH DAMAGE.
10728  *
10729 */
10730
10731 // t: current time, b: begInnIng value, c: change In value, d: duration
10732 $.easing.jswing = $.easing.swing;
10733
10734 $.extend($.easing,
10735 {
10736         def: 'easeOutQuad',
10737         swing: function (x, t, b, c, d) {
10738                 //alert($.easing.default);
10739                 return $.easing[$.easing.def](x, t, b, c, d);
10740         },
10741         easeInQuad: function (x, t, b, c, d) {
10742                 return c*(t/=d)*t + b;
10743         },
10744         easeOutQuad: function (x, t, b, c, d) {
10745                 return -c *(t/=d)*(t-2) + b;
10746         },
10747         easeInOutQuad: function (x, t, b, c, d) {
10748                 if ((t/=d/2) < 1) return c/2*t*t + b;
10749                 return -c/2 * ((--t)*(t-2) - 1) + b;
10750         },
10751         easeInCubic: function (x, t, b, c, d) {
10752                 return c*(t/=d)*t*t + b;
10753         },
10754         easeOutCubic: function (x, t, b, c, d) {
10755                 return c*((t=t/d-1)*t*t + 1) + b;
10756         },
10757         easeInOutCubic: function (x, t, b, c, d) {
10758                 if ((t/=d/2) < 1) return c/2*t*t*t + b;
10759                 return c/2*((t-=2)*t*t + 2) + b;
10760         },
10761         easeInQuart: function (x, t, b, c, d) {
10762                 return c*(t/=d)*t*t*t + b;
10763         },
10764         easeOutQuart: function (x, t, b, c, d) {
10765                 return -c * ((t=t/d-1)*t*t*t - 1) + b;
10766         },
10767         easeInOutQuart: function (x, t, b, c, d) {
10768                 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
10769                 return -c/2 * ((t-=2)*t*t*t - 2) + b;
10770         },
10771         easeInQuint: function (x, t, b, c, d) {
10772                 return c*(t/=d)*t*t*t*t + b;
10773         },
10774         easeOutQuint: function (x, t, b, c, d) {
10775                 return c*((t=t/d-1)*t*t*t*t + 1) + b;
10776         },
10777         easeInOutQuint: function (x, t, b, c, d) {
10778                 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
10779                 return c/2*((t-=2)*t*t*t*t + 2) + b;
10780         },
10781         easeInSine: function (x, t, b, c, d) {
10782                 return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
10783         },
10784         easeOutSine: function (x, t, b, c, d) {
10785                 return c * Math.sin(t/d * (Math.PI/2)) + b;
10786         },
10787         easeInOutSine: function (x, t, b, c, d) {
10788                 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
10789         },
10790         easeInExpo: function (x, t, b, c, d) {
10791                 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
10792         },
10793         easeOutExpo: function (x, t, b, c, d) {
10794                 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
10795         },
10796         easeInOutExpo: function (x, t, b, c, d) {
10797                 if (t==0) return b;
10798                 if (t==d) return b+c;
10799                 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
10800                 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
10801         },
10802         easeInCirc: function (x, t, b, c, d) {
10803                 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
10804         },
10805         easeOutCirc: function (x, t, b, c, d) {
10806                 return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
10807         },
10808         easeInOutCirc: function (x, t, b, c, d) {
10809                 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
10810                 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
10811         },
10812         easeInElastic: function (x, t, b, c, d) {
10813                 var s=1.70158;var p=0;var a=c;
10814                 if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
10815                 if (a < Math.abs(c)) { a=c; var s=p/4; }
10816                 else var s = p/(2*Math.PI) * Math.asin (c/a);
10817                 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
10818         },
10819         easeOutElastic: function (x, t, b, c, d) {
10820                 var s=1.70158;var p=0;var a=c;
10821                 if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
10822                 if (a < Math.abs(c)) { a=c; var s=p/4; }
10823                 else var s = p/(2*Math.PI) * Math.asin (c/a);
10824                 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
10825         },
10826         easeInOutElastic: function (x, t, b, c, d) {
10827                 var s=1.70158;var p=0;var a=c;
10828                 if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
10829                 if (a < Math.abs(c)) { a=c; var s=p/4; }
10830                 else var s = p/(2*Math.PI) * Math.asin (c/a);
10831                 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
10832                 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
10833         },
10834         easeInBack: function (x, t, b, c, d, s) {
10835                 if (s == undefined) s = 1.70158;
10836                 return c*(t/=d)*t*((s+1)*t - s) + b;
10837         },
10838         easeOutBack: function (x, t, b, c, d, s) {
10839                 if (s == undefined) s = 1.70158;
10840                 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
10841         },
10842         easeInOutBack: function (x, t, b, c, d, s) {
10843                 if (s == undefined) s = 1.70158;
10844                 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
10845                 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
10846         },
10847         easeInBounce: function (x, t, b, c, d) {
10848                 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
10849         },
10850         easeOutBounce: function (x, t, b, c, d) {
10851                 if ((t/=d) < (1/2.75)) {
10852                         return c*(7.5625*t*t) + b;
10853                 } else if (t < (2/2.75)) {
10854                         return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
10855                 } else if (t < (2.5/2.75)) {
10856                         return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
10857                 } else {
10858                         return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
10859                 }
10860         },
10861         easeInOutBounce: function (x, t, b, c, d) {
10862                 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
10863                 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
10864         }
10865 });
10866
10867 /*
10868  *
10869  * TERMS OF USE - EASING EQUATIONS
10870  *
10871  * Open source under the BSD License.
10872  *
10873  * Copyright 2001 Robert Penner
10874  * All rights reserved.
10875  *
10876  * Redistribution and use in source and binary forms, with or without modification,
10877  * are permitted provided that the following conditions are met:
10878  *
10879  * Redistributions of source code must retain the above copyright notice, this list of
10880  * conditions and the following disclaimer.
10881  * Redistributions in binary form must reproduce the above copyright notice, this list
10882  * of conditions and the following disclaimer in the documentation and/or other materials
10883  * provided with the distribution.
10884  *
10885  * Neither the name of the author nor the names of contributors may be used to endorse
10886  * or promote products derived from this software without specific prior written permission.
10887  *
10888  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10889  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10890  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10891  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10892  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10893  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10894  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10895  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10896  * OF THE POSSIBILITY OF SUCH DAMAGE.
10897  *
10898  */
10899
10900 })(jQuery);
10901 /*
10902  * jQuery UI Effects Blind 1.8.14
10903  *
10904  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10905  * Dual licensed under the MIT or GPL Version 2 licenses.
10906  * http://jquery.org/license
10907  *
10908  * http://docs.jquery.com/UI/Effects/Blind
10909  *
10910  * Depends:
10911  *      jquery.effects.core.js
10912  */
10913 (function( $, undefined ) {
10914
10915 $.effects.blind = function(o) {
10916
10917         return this.queue(function() {
10918
10919                 // Create element
10920                 var el = $(this), props = ['position','top','bottom','left','right'];
10921
10922                 // Set options
10923                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
10924                 var direction = o.options.direction || 'vertical'; // Default direction
10925
10926                 // Adjust
10927                 $.effects.save(el, props); el.show(); // Save & Show
10928                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
10929                 var ref = (direction == 'vertical') ? 'height' : 'width';
10930                 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
10931                 if(mode == 'show') wrapper.css(ref, 0); // Shift
10932
10933                 // Animation
10934                 var animation = {};
10935                 animation[ref] = mode == 'show' ? distance : 0;
10936
10937                 // Animate
10938                 wrapper.animate(animation, o.duration, o.options.easing, function() {
10939                         if(mode == 'hide') el.hide(); // Hide
10940                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
10941                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
10942                         el.dequeue();
10943                 });
10944
10945         });
10946
10947 };
10948
10949 })(jQuery);
10950 /*
10951  * jQuery UI Effects Bounce 1.8.14
10952  *
10953  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10954  * Dual licensed under the MIT or GPL Version 2 licenses.
10955  * http://jquery.org/license
10956  *
10957  * http://docs.jquery.com/UI/Effects/Bounce
10958  *
10959  * Depends:
10960  *      jquery.effects.core.js
10961  */
10962 (function( $, undefined ) {
10963
10964 $.effects.bounce = function(o) {
10965
10966         return this.queue(function() {
10967
10968                 // Create element
10969                 var el = $(this), props = ['position','top','bottom','left','right'];
10970
10971                 // Set options
10972                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
10973                 var direction = o.options.direction || 'up'; // Default direction
10974                 var distance = o.options.distance || 20; // Default distance
10975                 var times = o.options.times || 5; // Default # of times
10976                 var speed = o.duration || 250; // Default speed per bounce
10977                 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
10978
10979                 // Adjust
10980                 $.effects.save(el, props); el.show(); // Save & Show
10981                 $.effects.createWrapper(el); // Create Wrapper
10982                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
10983                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
10984                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
10985                 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
10986                 if (mode == 'hide') distance = distance / (times * 2);
10987                 if (mode != 'hide') times--;
10988
10989                 // Animate
10990                 if (mode == 'show') { // Show Bounce
10991                         var animation = {opacity: 1};
10992                         animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
10993                         el.animate(animation, speed / 2, o.options.easing);
10994                         distance = distance / 2;
10995                         times--;
10996                 };
10997                 for (var i = 0; i < times; i++) { // Bounces
10998                         var animation1 = {}, animation2 = {};
10999                         animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11000                         animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11001                         el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
11002                         distance = (mode == 'hide') ? distance * 2 : distance / 2;
11003                 };
11004                 if (mode == 'hide') { // Last Bounce
11005                         var animation = {opacity: 0};
11006                         animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
11007                         el.animate(animation, speed / 2, o.options.easing, function(){
11008                                 el.hide(); // Hide
11009                                 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11010                                 if(o.callback) o.callback.apply(this, arguments); // Callback
11011                         });
11012                 } else {
11013                         var animation1 = {}, animation2 = {};
11014                         animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11015                         animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11016                         el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
11017                                 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11018                                 if(o.callback) o.callback.apply(this, arguments); // Callback
11019                         });
11020                 };
11021                 el.queue('fx', function() { el.dequeue(); });
11022                 el.dequeue();
11023         });
11024
11025 };
11026
11027 })(jQuery);
11028 /*
11029  * jQuery UI Effects Clip 1.8.14
11030  *
11031  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11032  * Dual licensed under the MIT or GPL Version 2 licenses.
11033  * http://jquery.org/license
11034  *
11035  * http://docs.jquery.com/UI/Effects/Clip
11036  *
11037  * Depends:
11038  *      jquery.effects.core.js
11039  */
11040 (function( $, undefined ) {
11041
11042 $.effects.clip = function(o) {
11043
11044         return this.queue(function() {
11045
11046                 // Create element
11047                 var el = $(this), props = ['position','top','bottom','left','right','height','width'];
11048
11049                 // Set options
11050                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11051                 var direction = o.options.direction || 'vertical'; // Default direction
11052
11053                 // Adjust
11054                 $.effects.save(el, props); el.show(); // Save & Show
11055                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11056                 var animate = el[0].tagName == 'IMG' ? wrapper : el;
11057                 var ref = {
11058                         size: (direction == 'vertical') ? 'height' : 'width',
11059                         position: (direction == 'vertical') ? 'top' : 'left'
11060                 };
11061                 var distance = (direction == 'vertical') ? animate.height() : animate.width();
11062                 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
11063
11064                 // Animation
11065                 var animation = {};
11066                 animation[ref.size] = mode == 'show' ? distance : 0;
11067                 animation[ref.position] = mode == 'show' ? 0 : distance / 2;
11068
11069                 // Animate
11070                 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11071                         if(mode == 'hide') el.hide(); // Hide
11072                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11073                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
11074                         el.dequeue();
11075                 }});
11076
11077         });
11078
11079 };
11080
11081 })(jQuery);
11082 /*
11083  * jQuery UI Effects Drop 1.8.14
11084  *
11085  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11086  * Dual licensed under the MIT or GPL Version 2 licenses.
11087  * http://jquery.org/license
11088  *
11089  * http://docs.jquery.com/UI/Effects/Drop
11090  *
11091  * Depends:
11092  *      jquery.effects.core.js
11093  */
11094 (function( $, undefined ) {
11095
11096 $.effects.drop = function(o) {
11097
11098         return this.queue(function() {
11099
11100                 // Create element
11101                 var el = $(this), props = ['position','top','bottom','left','right','opacity'];
11102
11103                 // Set options
11104                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11105                 var direction = o.options.direction || 'left'; // Default Direction
11106
11107                 // Adjust
11108                 $.effects.save(el, props); el.show(); // Save & Show
11109                 $.effects.createWrapper(el); // Create Wrapper
11110                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11111                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11112                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
11113                 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
11114
11115                 // Animation
11116                 var animation = {opacity: mode == 'show' ? 1 : 0};
11117                 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
11118
11119                 // Animate
11120                 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11121                         if(mode == 'hide') el.hide(); // Hide
11122                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11123                         if(o.callback) o.callback.apply(this, arguments); // Callback
11124                         el.dequeue();
11125                 }});
11126
11127         });
11128
11129 };
11130
11131 })(jQuery);
11132 /*
11133  * jQuery UI Effects Explode 1.8.14
11134  *
11135  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11136  * Dual licensed under the MIT or GPL Version 2 licenses.
11137  * http://jquery.org/license
11138  *
11139  * http://docs.jquery.com/UI/Effects/Explode
11140  *
11141  * Depends:
11142  *      jquery.effects.core.js
11143  */
11144 (function( $, undefined ) {
11145
11146 $.effects.explode = function(o) {
11147
11148         return this.queue(function() {
11149
11150         var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
11151         var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
11152
11153         o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
11154         var el = $(this).show().css('visibility', 'hidden');
11155         var offset = el.offset();
11156
11157         //Substract the margins - not fixing the problem yet.
11158         offset.top -= parseInt(el.css("marginTop"),10) || 0;
11159         offset.left -= parseInt(el.css("marginLeft"),10) || 0;
11160
11161         var width = el.outerWidth(true);
11162         var height = el.outerHeight(true);
11163
11164         for(var i=0;i<rows;i++) { // =
11165                 for(var j=0;j<cells;j++) { // ||
11166                         el
11167                                 .clone()
11168                                 .appendTo('body')
11169                                 .wrap('<div></div>')
11170                                 .css({
11171                                         position: 'absolute',
11172                                         visibility: 'visible',
11173                                         left: -j*(width/cells),
11174                                         top: -i*(height/rows)
11175                                 })
11176                                 .parent()
11177                                 .addClass('ui-effects-explode')
11178                                 .css({
11179                                         position: 'absolute',
11180                                         overflow: 'hidden',
11181                                         width: width/cells,
11182                                         height: height/rows,
11183                                         left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
11184                                         top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
11185                                         opacity: o.options.mode == 'show' ? 0 : 1
11186                                 }).animate({
11187                                         left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
11188                                         top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
11189                                         opacity: o.options.mode == 'show' ? 1 : 0
11190                                 }, o.duration || 500);
11191                 }
11192         }
11193
11194         // Set a timeout, to call the callback approx. when the other animations have finished
11195         setTimeout(function() {
11196
11197                 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
11198                                 if(o.callback) o.callback.apply(el[0]); // Callback
11199                                 el.dequeue();
11200
11201                                 $('div.ui-effects-explode').remove();
11202
11203         }, o.duration || 500);
11204
11205
11206         });
11207
11208 };
11209
11210 })(jQuery);
11211 /*
11212  * jQuery UI Effects Fade 1.8.14
11213  *
11214  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11215  * Dual licensed under the MIT or GPL Version 2 licenses.
11216  * http://jquery.org/license
11217  *
11218  * http://docs.jquery.com/UI/Effects/Fade
11219  *
11220  * Depends:
11221  *      jquery.effects.core.js
11222  */
11223 (function( $, undefined ) {
11224
11225 $.effects.fade = function(o) {
11226         return this.queue(function() {
11227                 var elem = $(this),
11228                         mode = $.effects.setMode(elem, o.options.mode || 'hide');
11229
11230                 elem.animate({ opacity: mode }, {
11231                         queue: false,
11232                         duration: o.duration,
11233                         easing: o.options.easing,
11234                         complete: function() {
11235                                 (o.callback && o.callback.apply(this, arguments));
11236                                 elem.dequeue();
11237                         }
11238                 });
11239         });
11240 };
11241
11242 })(jQuery);
11243 /*
11244  * jQuery UI Effects Fold 1.8.14
11245  *
11246  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11247  * Dual licensed under the MIT or GPL Version 2 licenses.
11248  * http://jquery.org/license
11249  *
11250  * http://docs.jquery.com/UI/Effects/Fold
11251  *
11252  * Depends:
11253  *      jquery.effects.core.js
11254  */
11255 (function( $, undefined ) {
11256
11257 $.effects.fold = function(o) {
11258
11259         return this.queue(function() {
11260
11261                 // Create element
11262                 var el = $(this), props = ['position','top','bottom','left','right'];
11263
11264                 // Set options
11265                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11266                 var size = o.options.size || 15; // Default fold size
11267                 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
11268                 var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
11269
11270                 // Adjust
11271                 $.effects.save(el, props); el.show(); // Save & Show
11272                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11273                 var widthFirst = ((mode == 'show') != horizFirst);
11274                 var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
11275                 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
11276                 var percent = /([0-9]+)%/.exec(size);
11277                 if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
11278                 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
11279
11280                 // Animation
11281                 var animation1 = {}, animation2 = {};
11282                 animation1[ref[0]] = mode == 'show' ? distance[0] : size;
11283                 animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
11284
11285                 // Animate
11286                 wrapper.animate(animation1, duration, o.options.easing)
11287                 .animate(animation2, duration, o.options.easing, function() {
11288                         if(mode == 'hide') el.hide(); // Hide
11289                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11290                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
11291                         el.dequeue();
11292                 });
11293
11294         });
11295
11296 };
11297
11298 })(jQuery);
11299 /*
11300  * jQuery UI Effects Highlight 1.8.14
11301  *
11302  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11303  * Dual licensed under the MIT or GPL Version 2 licenses.
11304  * http://jquery.org/license
11305  *
11306  * http://docs.jquery.com/UI/Effects/Highlight
11307  *
11308  * Depends:
11309  *      jquery.effects.core.js
11310  */
11311 (function( $, undefined ) {
11312
11313 $.effects.highlight = function(o) {
11314         return this.queue(function() {
11315                 var elem = $(this),
11316                         props = ['backgroundImage', 'backgroundColor', 'opacity'],
11317                         mode = $.effects.setMode(elem, o.options.mode || 'show'),
11318                         animation = {
11319                                 backgroundColor: elem.css('backgroundColor')
11320                         };
11321
11322                 if (mode == 'hide') {
11323                         animation.opacity = 0;
11324                 }
11325
11326                 $.effects.save(elem, props);
11327                 elem
11328                         .show()
11329                         .css({
11330                                 backgroundImage: 'none',
11331                                 backgroundColor: o.options.color || '#ffff99'
11332                         })
11333                         .animate(animation, {
11334                                 queue: false,
11335                                 duration: o.duration,
11336                                 easing: o.options.easing,
11337                                 complete: function() {
11338                                         (mode == 'hide' && elem.hide());
11339                                         $.effects.restore(elem, props);
11340                                         (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
11341                                         (o.callback && o.callback.apply(this, arguments));
11342                                         elem.dequeue();
11343                                 }
11344                         });
11345         });
11346 };
11347
11348 })(jQuery);
11349 /*
11350  * jQuery UI Effects Pulsate 1.8.14
11351  *
11352  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11353  * Dual licensed under the MIT or GPL Version 2 licenses.
11354  * http://jquery.org/license
11355  *
11356  * http://docs.jquery.com/UI/Effects/Pulsate
11357  *
11358  * Depends:
11359  *      jquery.effects.core.js
11360  */
11361 (function( $, undefined ) {
11362
11363 $.effects.pulsate = function(o) {
11364         return this.queue(function() {
11365                 var elem = $(this),
11366                         mode = $.effects.setMode(elem, o.options.mode || 'show');
11367                         times = ((o.options.times || 5) * 2) - 1;
11368                         duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
11369                         isVisible = elem.is(':visible'),
11370                         animateTo = 0;
11371
11372                 if (!isVisible) {
11373                         elem.css('opacity', 0).show();
11374                         animateTo = 1;
11375                 }
11376
11377                 if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
11378                         times--;
11379                 }
11380
11381                 for (var i = 0; i < times; i++) {
11382                         elem.animate({ opacity: animateTo }, duration, o.options.easing);
11383                         animateTo = (animateTo + 1) % 2;
11384                 }
11385
11386                 elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
11387                         if (animateTo == 0) {
11388                                 elem.hide();
11389                         }
11390                         (o.callback && o.callback.apply(this, arguments));
11391                 });
11392
11393                 elem
11394                         .queue('fx', function() { elem.dequeue(); })
11395                         .dequeue();
11396         });
11397 };
11398
11399 })(jQuery);
11400 /*
11401  * jQuery UI Effects Scale 1.8.14
11402  *
11403  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11404  * Dual licensed under the MIT or GPL Version 2 licenses.
11405  * http://jquery.org/license
11406  *
11407  * http://docs.jquery.com/UI/Effects/Scale
11408  *
11409  * Depends:
11410  *      jquery.effects.core.js
11411  */
11412 (function( $, undefined ) {
11413
11414 $.effects.puff = function(o) {
11415         return this.queue(function() {
11416                 var elem = $(this),
11417                         mode = $.effects.setMode(elem, o.options.mode || 'hide'),
11418                         percent = parseInt(o.options.percent, 10) || 150,
11419                         factor = percent / 100,
11420                         original = { height: elem.height(), width: elem.width() };
11421
11422                 $.extend(o.options, {
11423                         fade: true,
11424                         mode: mode,
11425                         percent: mode == 'hide' ? percent : 100,
11426                         from: mode == 'hide'
11427                                 ? original
11428                                 : {
11429                                         height: original.height * factor,
11430                                         width: original.width * factor
11431                                 }
11432                 });
11433
11434                 elem.effect('scale', o.options, o.duration, o.callback);
11435                 elem.dequeue();
11436         });
11437 };
11438
11439 $.effects.scale = function(o) {
11440
11441         return this.queue(function() {
11442
11443                 // Create element
11444                 var el = $(this);
11445
11446                 // Set options
11447                 var options = $.extend(true, {}, o.options);
11448                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11449                 var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
11450                 var direction = o.options.direction || 'both'; // Set default axis
11451                 var origin = o.options.origin; // The origin of the scaling
11452                 if (mode != 'effect') { // Set default origin and restore for show/hide
11453                         options.origin = origin || ['middle','center'];
11454                         options.restore = true;
11455                 }
11456                 var original = {height: el.height(), width: el.width()}; // Save original
11457                 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
11458
11459                 // Adjust
11460                 var factor = { // Set scaling factor
11461                         y: direction != 'horizontal' ? (percent / 100) : 1,
11462                         x: direction != 'vertical' ? (percent / 100) : 1
11463                 };
11464                 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
11465
11466                 if (o.options.fade) { // Fade option to support puff
11467                         if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
11468                         if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
11469                 };
11470
11471                 // Animation
11472                 options.from = el.from; options.to = el.to; options.mode = mode;
11473
11474                 // Animate
11475                 el.effect('size', options, o.duration, o.callback);
11476                 el.dequeue();
11477         });
11478
11479 };
11480
11481 $.effects.size = function(o) {
11482
11483         return this.queue(function() {
11484
11485                 // Create element
11486                 var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
11487                 var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
11488                 var props2 = ['width','height','overflow']; // Copy for children
11489                 var cProps = ['fontSize'];
11490                 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
11491                 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
11492
11493                 // Set options
11494                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11495                 var restore = o.options.restore || false; // Default restore
11496                 var scale = o.options.scale || 'both'; // Default scale mode
11497                 var origin = o.options.origin; // The origin of the sizing
11498                 var original = {height: el.height(), width: el.width()}; // Save original
11499                 el.from = o.options.from || original; // Default from state
11500                 el.to = o.options.to || original; // Default to state
11501                 // Adjust
11502                 if (origin) { // Calculate baseline shifts
11503                         var baseline = $.effects.getBaseline(origin, original);
11504                         el.from.top = (original.height - el.from.height) * baseline.y;
11505                         el.from.left = (original.width - el.from.width) * baseline.x;
11506                         el.to.top = (original.height - el.to.height) * baseline.y;
11507                         el.to.left = (original.width - el.to.width) * baseline.x;
11508                 };
11509                 var factor = { // Set scaling factor
11510                         from: {y: el.from.height / original.height, x: el.from.width / original.width},
11511                         to: {y: el.to.height / original.height, x: el.to.width / original.width}
11512                 };
11513                 if (scale == 'box' || scale == 'both') { // Scale the css box
11514                         if (factor.from.y != factor.to.y) { // Vertical props scaling
11515                                 props = props.concat(vProps);
11516                                 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
11517                                 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
11518                         };
11519                         if (factor.from.x != factor.to.x) { // Horizontal props scaling
11520                                 props = props.concat(hProps);
11521                                 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
11522                                 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
11523                         };
11524                 };
11525                 if (scale == 'content' || scale == 'both') { // Scale the content
11526                         if (factor.from.y != factor.to.y) { // Vertical props scaling
11527                                 props = props.concat(cProps);
11528                                 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
11529                                 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
11530                         };
11531                 };
11532                 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
11533                 $.effects.createWrapper(el); // Create Wrapper
11534                 el.css('overflow','hidden').css(el.from); // Shift
11535
11536                 // Animate
11537                 if (scale == 'content' || scale == 'both') { // Scale the children
11538                         vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
11539                         hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
11540                         props2 = props.concat(vProps).concat(hProps); // Concat
11541                         el.find("*[width]").each(function(){
11542                                 child = $(this);
11543                                 if (restore) $.effects.save(child, props2);
11544                                 var c_original = {height: child.height(), width: child.width()}; // Save original
11545                                 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
11546                                 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
11547                                 if (factor.from.y != factor.to.y) { // Vertical props scaling
11548                                         child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
11549                                         child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
11550                                 };
11551                                 if (factor.from.x != factor.to.x) { // Horizontal props scaling
11552                                         child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
11553                                         child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
11554                                 };
11555                                 child.css(child.from); // Shift children
11556                                 child.animate(child.to, o.duration, o.options.easing, function(){
11557                                         if (restore) $.effects.restore(child, props2); // Restore children
11558                                 }); // Animate children
11559                         });
11560                 };
11561
11562                 // Animate
11563                 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11564                         if (el.to.opacity === 0) {
11565                                 el.css('opacity', el.from.opacity);
11566                         }
11567                         if(mode == 'hide') el.hide(); // Hide
11568                         $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
11569                         if(o.callback) o.callback.apply(this, arguments); // Callback
11570                         el.dequeue();
11571                 }});
11572
11573         });
11574
11575 };
11576
11577 })(jQuery);
11578 /*
11579  * jQuery UI Effects Shake 1.8.14
11580  *
11581  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11582  * Dual licensed under the MIT or GPL Version 2 licenses.
11583  * http://jquery.org/license
11584  *
11585  * http://docs.jquery.com/UI/Effects/Shake
11586  *
11587  * Depends:
11588  *      jquery.effects.core.js
11589  */
11590 (function( $, undefined ) {
11591
11592 $.effects.shake = function(o) {
11593
11594         return this.queue(function() {
11595
11596                 // Create element
11597                 var el = $(this), props = ['position','top','bottom','left','right'];
11598
11599                 // Set options
11600                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11601                 var direction = o.options.direction || 'left'; // Default direction
11602                 var distance = o.options.distance || 20; // Default distance
11603                 var times = o.options.times || 3; // Default # of times
11604                 var speed = o.duration || o.options.duration || 140; // Default speed per shake
11605
11606                 // Adjust
11607                 $.effects.save(el, props); el.show(); // Save & Show
11608                 $.effects.createWrapper(el); // Create Wrapper
11609                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11610                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11611
11612                 // Animation
11613                 var animation = {}, animation1 = {}, animation2 = {};
11614                 animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
11615                 animation1[ref] = (motion == 'pos' ? '+=' : '-=')  + distance * 2;
11616                 animation2[ref] = (motion == 'pos' ? '-=' : '+=')  + distance * 2;
11617
11618                 // Animate
11619                 el.animate(animation, speed, o.options.easing);
11620                 for (var i = 1; i < times; i++) { // Shakes
11621                         el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
11622                 };
11623                 el.animate(animation1, speed, o.options.easing).
11624                 animate(animation, speed / 2, o.options.easing, function(){ // Last shake
11625                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11626                         if(o.callback) o.callback.apply(this, arguments); // Callback
11627                 });
11628                 el.queue('fx', function() { el.dequeue(); });
11629                 el.dequeue();
11630         });
11631
11632 };
11633
11634 })(jQuery);
11635 /*
11636  * jQuery UI Effects Slide 1.8.14
11637  *
11638  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11639  * Dual licensed under the MIT or GPL Version 2 licenses.
11640  * http://jquery.org/license
11641  *
11642  * http://docs.jquery.com/UI/Effects/Slide
11643  *
11644  * Depends:
11645  *      jquery.effects.core.js
11646  */
11647 (function( $, undefined ) {
11648
11649 $.effects.slide = function(o) {
11650
11651         return this.queue(function() {
11652
11653                 // Create element
11654                 var el = $(this), props = ['position','top','bottom','left','right'];
11655
11656                 // Set options
11657                 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
11658                 var direction = o.options.direction || 'left'; // Default Direction
11659
11660                 // Adjust
11661                 $.effects.save(el, props); el.show(); // Save & Show
11662                 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11663                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11664                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11665                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
11666                 if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
11667
11668                 // Animation
11669                 var animation = {};
11670                 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
11671
11672                 // Animate
11673                 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11674                         if(mode == 'hide') el.hide(); // Hide
11675                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11676                         if(o.callback) o.callback.apply(this, arguments); // Callback
11677                         el.dequeue();
11678                 }});
11679
11680         });
11681
11682 };
11683
11684 })(jQuery);
11685 /*
11686  * jQuery UI Effects Transfer 1.8.14
11687  *
11688  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11689  * Dual licensed under the MIT or GPL Version 2 licenses.
11690  * http://jquery.org/license
11691  *
11692  * http://docs.jquery.com/UI/Effects/Transfer
11693  *
11694  * Depends:
11695  *      jquery.effects.core.js
11696  */
11697 (function( $, undefined ) {
11698
11699 $.effects.transfer = function(o) {
11700         return this.queue(function() {
11701                 var elem = $(this),
11702                         target = $(o.options.to),
11703                         endPosition = target.offset(),
11704                         animation = {
11705                                 top: endPosition.top,
11706                                 left: endPosition.left,
11707                                 height: target.innerHeight(),
11708                                 width: target.innerWidth()
11709                         },
11710                         startPosition = elem.offset(),
11711                         transfer = $('<div class="ui-effects-transfer"></div>')
11712                                 .appendTo(document.body)
11713                                 .addClass(o.options.className)
11714                                 .css({
11715                                         top: startPosition.top,
11716                                         left: startPosition.left,
11717                                         height: elem.innerHeight(),
11718                                         width: elem.innerWidth(),
11719                                         position: 'absolute'
11720                                 })
11721                                 .animate(animation, o.duration, o.options.easing, function() {
11722                                         transfer.remove();
11723                                         (o.callback && o.callback.apply(elem[0], arguments));
11724                                         elem.dequeue();
11725                                 });
11726         });
11727 };
11728
11729 })(jQuery);