adding all weblabels from weblabels.fsf.org
[weblabels.fsf.org.git] / www.fsf.org / 20131028 / files / crm.fsf.org / jquery-ui-1.8.16.custom.js
CommitLineData
5a920362 1/*!
2 * jQuery UI 1.8.16
3 *
4 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 * Dual licensed under the MIT or GPL Version 2 licenses.
6 * http://jquery.org/license
7 *
8 * http://docs.jquery.com/UI
9 */
10(function( $, undefined ) {
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 || {};
16if ( $.ui.version ) {
17 return;
18}
19
20$.extend( $.ui, {
21 version: "1.8.16",
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 propAttr: $.fn.prop || $.fn.attr,
62
63 _focus: $.fn.focus,
64 focus: function( delay, fn ) {
65 return typeof delay === "number" ?
66 this.each(function() {
67 var elem = this;
68 setTimeout(function() {
69 $( elem ).focus();
70 if ( fn ) {
71 fn.call( elem );
72 }
73 }, delay );
74 }) :
75 this._focus.apply( this, arguments );
76 },
77
78 scrollParent: function() {
79 var scrollParent;
80 if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
81 scrollParent = this.parents().filter(function() {
82 return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
83 }).eq(0);
84 } else {
85 scrollParent = this.parents().filter(function() {
86 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
87 }).eq(0);
88 }
89
90 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
91 },
92
93 zIndex: function( zIndex ) {
94 if ( zIndex !== undefined ) {
95 return this.css( "zIndex", zIndex );
96 }
97
98 if ( this.length ) {
99 var elem = $( this[ 0 ] ), position, value;
100 while ( elem.length && elem[ 0 ] !== document ) {
101 // Ignore z-index if position is set to a value where z-index is ignored by the browser
102 // This makes behavior of this function consistent across browsers
103 // WebKit always returns auto if the element is positioned
104 position = elem.css( "position" );
105 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
106 // IE returns 0 when zIndex is not specified
107 // other browsers return a string
108 // we ignore the case of nested elements with an explicit value of 0
109 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
110 value = parseInt( elem.css( "zIndex" ), 10 );
111 if ( !isNaN( value ) && value !== 0 ) {
112 return value;
113 }
114 }
115 elem = elem.parent();
116 }
117 }
118
119 return 0;
120 },
121
122 disableSelection: function() {
123 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
124 ".ui-disableSelection", function( event ) {
125 event.preventDefault();
126 });
127 },
128
129 enableSelection: function() {
130 return this.unbind( ".ui-disableSelection" );
131 }
132});
133
134$.each( [ "Width", "Height" ], function( i, name ) {
135 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
136 type = name.toLowerCase(),
137 orig = {
138 innerWidth: $.fn.innerWidth,
139 innerHeight: $.fn.innerHeight,
140 outerWidth: $.fn.outerWidth,
141 outerHeight: $.fn.outerHeight
142 };
143
144 function reduce( elem, size, border, margin ) {
145 $.each( side, function() {
146 size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
147 if ( border ) {
148 size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
149 }
150 if ( margin ) {
151 size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
152 }
153 });
154 return size;
155 }
156
157 $.fn[ "inner" + name ] = function( size ) {
158 if ( size === undefined ) {
159 return orig[ "inner" + name ].call( this );
160 }
161
162 return this.each(function() {
163 $( this ).css( type, reduce( this, size ) + "px" );
164 });
165 };
166
167 $.fn[ "outer" + name] = function( size, margin ) {
168 if ( typeof size !== "number" ) {
169 return orig[ "outer" + name ].call( this, size );
170 }
171
172 return this.each(function() {
173 $( this).css( type, reduce( this, size, true, margin ) + "px" );
174 });
175 };
176});
177
178// selectors
179function focusable( element, isTabIndexNotNaN ) {
180 var nodeName = element.nodeName.toLowerCase();
181 if ( "area" === nodeName ) {
182 var map = element.parentNode,
183 mapName = map.name,
184 img;
185 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
186 return false;
187 }
188 img = $( "img[usemap=#" + mapName + "]" )[0];
189 return !!img && visible( img );
190 }
191 return ( /input|select|textarea|button|object/.test( nodeName )
192 ? !element.disabled
193 : "a" == nodeName
194 ? element.href || isTabIndexNotNaN
195 : isTabIndexNotNaN)
196 // the element and all of its ancestors must be visible
197 && visible( element );
198}
199
200function visible( element ) {
201 return !$( element ).parents().andSelf().filter(function() {
202 return $.curCSS( this, "visibility" ) === "hidden" ||
203 $.expr.filters.hidden( this );
204 }).length;
205}
206
207$.extend( $.expr[ ":" ], {
208 data: function( elem, i, match ) {
209 return !!$.data( elem, match[ 3 ] );
210 },
211
212 focusable: function( element ) {
213 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
214 },
215
216 tabbable: function( element ) {
217 var tabIndex = $.attr( element, "tabindex" ),
218 isTabIndexNaN = isNaN( tabIndex );
219 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
220 }
221});
222
223// support
224$(function() {
225 var body = document.body,
226 div = body.appendChild( div = document.createElement( "div" ) );
227
228 $.extend( div.style, {
229 minHeight: "100px",
230 height: "auto",
231 padding: 0,
232 borderWidth: 0
233 });
234
235 $.support.minHeight = div.offsetHeight === 100;
236 $.support.selectstart = "onselectstart" in div;
237
238 // set display to none to avoid a layout bug in IE
239 // http://dev.jquery.com/ticket/4014
240 body.removeChild( div ).style.display = "none";
241});
242
243
244
245
246
247// deprecated
248$.extend( $.ui, {
249 // $.ui.plugin is deprecated. Use the proxy pattern instead.
250 plugin: {
251 add: function( module, option, set ) {
252 var proto = $.ui[ module ].prototype;
253 for ( var i in set ) {
254 proto.plugins[ i ] = proto.plugins[ i ] || [];
255 proto.plugins[ i ].push( [ option, set[ i ] ] );
256 }
257 },
258 call: function( instance, name, args ) {
259 var set = instance.plugins[ name ];
260 if ( !set || !instance.element[ 0 ].parentNode ) {
261 return;
262 }
263
264 for ( var i = 0; i < set.length; i++ ) {
265 if ( instance.options[ set[ i ][ 0 ] ] ) {
266 set[ i ][ 1 ].apply( instance.element, args );
267 }
268 }
269 }
270 },
271
272 // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
273 contains: function( a, b ) {
274 return document.compareDocumentPosition ?
275 a.compareDocumentPosition( b ) & 16 :
276 a !== b && a.contains( b );
277 },
278
279 // only used by resizable
280 hasScroll: function( el, a ) {
281
282 //If overflow is hidden, the element might have extra content, but the user wants to hide it
283 if ( $( el ).css( "overflow" ) === "hidden") {
284 return false;
285 }
286
287 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
288 has = false;
289
290 if ( el[ scroll ] > 0 ) {
291 return true;
292 }
293
294 // TODO: determine which cases actually cause this to happen
295 // if the element doesn't have the scroll set, see if it's possible to
296 // set the scroll
297 el[ scroll ] = 1;
298 has = ( el[ scroll ] > 0 );
299 el[ scroll ] = 0;
300 return has;
301 },
302
303 // these are odd functions, fix the API or move into individual plugins
304 isOverAxis: function( x, reference, size ) {
305 //Determines when x coordinate is over "b" element axis
306 return ( x > reference ) && ( x < ( reference + size ) );
307 },
308 isOver: function( y, x, top, left, height, width ) {
309 //Determines when x, y coordinates is over "b" element
310 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
311 }
312});
313
314})( jQuery );
315/*!
316 * jQuery UI Widget 1.8.16
317 *
318 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
319 * Dual licensed under the MIT or GPL Version 2 licenses.
320 * http://jquery.org/license
321 *
322 * http://docs.jquery.com/UI/Widget
323 */
324(function( $, undefined ) {
325
326// jQuery 1.4+
327if ( $.cleanData ) {
328 var _cleanData = $.cleanData;
329 $.cleanData = function( elems ) {
330 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
331 try {
332 $( elem ).triggerHandler( "remove" );
333 // http://bugs.jquery.com/ticket/8235
334 } catch( e ) {}
335 }
336 _cleanData( elems );
337 };
338} else {
339 var _remove = $.fn.remove;
340 $.fn.remove = function( selector, keepData ) {
341 return this.each(function() {
342 if ( !keepData ) {
343 if ( !selector || $.filter( selector, [ this ] ).length ) {
344 $( "*", this ).add( [ this ] ).each(function() {
345 try {
346 $( this ).triggerHandler( "remove" );
347 // http://bugs.jquery.com/ticket/8235
348 } catch( e ) {}
349 });
350 }
351 }
352 return _remove.call( $(this), selector, keepData );
353 });
354 };
355}
356
357$.widget = function( name, base, prototype ) {
358 var namespace = name.split( "." )[ 0 ],
359 fullName;
360 name = name.split( "." )[ 1 ];
361 fullName = namespace + "-" + name;
362
363 if ( !prototype ) {
364 prototype = base;
365 base = $.Widget;
366 }
367
368 // create selector for plugin
369 $.expr[ ":" ][ fullName ] = function( elem ) {
370 return !!$.data( elem, name );
371 };
372
373 $[ namespace ] = $[ namespace ] || {};
374 $[ namespace ][ name ] = function( options, element ) {
375 // allow instantiation without initializing for simple inheritance
376 if ( arguments.length ) {
377 this._createWidget( options, element );
378 }
379 };
380
381 var basePrototype = new base();
382 // we need to make the options hash a property directly on the new instance
383 // otherwise we'll modify the options hash on the prototype that we're
384 // inheriting from
385// $.each( basePrototype, function( key, val ) {
386// if ( $.isPlainObject(val) ) {
387// basePrototype[ key ] = $.extend( {}, val );
388// }
389// });
390 basePrototype.options = $.extend( true, {}, basePrototype.options );
391 $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
392 namespace: namespace,
393 widgetName: name,
394 widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
395 widgetBaseClass: fullName
396 }, prototype );
397
398 $.widget.bridge( name, $[ namespace ][ name ] );
399};
400
401$.widget.bridge = function( name, object ) {
402 $.fn[ name ] = function( options ) {
403 var isMethodCall = typeof options === "string",
404 args = Array.prototype.slice.call( arguments, 1 ),
405 returnValue = this;
406
407 // allow multiple hashes to be passed on init
408 options = !isMethodCall && args.length ?
409 $.extend.apply( null, [ true, options ].concat(args) ) :
410 options;
411
412 // prevent calls to internal methods
413 if ( isMethodCall && options.charAt( 0 ) === "_" ) {
414 return returnValue;
415 }
416
417 if ( isMethodCall ) {
418 this.each(function() {
419 var instance = $.data( this, name ),
420 methodValue = instance && $.isFunction( instance[options] ) ?
421 instance[ options ].apply( instance, args ) :
422 instance;
423 // TODO: add this back in 1.9 and use $.error() (see #5972)
424// if ( !instance ) {
425// throw "cannot call methods on " + name + " prior to initialization; " +
426// "attempted to call method '" + options + "'";
427// }
428// if ( !$.isFunction( instance[options] ) ) {
429// throw "no such method '" + options + "' for " + name + " widget instance";
430// }
431// var methodValue = instance[ options ].apply( instance, args );
432 if ( methodValue !== instance && methodValue !== undefined ) {
433 returnValue = methodValue;
434 return false;
435 }
436 });
437 } else {
438 this.each(function() {
439 var instance = $.data( this, name );
440 if ( instance ) {
441 instance.option( options || {} )._init();
442 } else {
443 $.data( this, name, new object( options, this ) );
444 }
445 });
446 }
447
448 return returnValue;
449 };
450};
451
452$.Widget = function( options, element ) {
453 // allow instantiation without initializing for simple inheritance
454 if ( arguments.length ) {
455 this._createWidget( options, element );
456 }
457};
458
459$.Widget.prototype = {
460 widgetName: "widget",
461 widgetEventPrefix: "",
462 options: {
463 disabled: false
464 },
465 _createWidget: function( options, element ) {
466 // $.widget.bridge stores the plugin instance, but we do it anyway
467 // so that it's stored even before the _create function runs
468 $.data( element, this.widgetName, this );
469 this.element = $( element );
470 this.options = $.extend( true, {},
471 this.options,
472 this._getCreateOptions(),
473 options );
474
475 var self = this;
476 this.element.bind( "remove." + this.widgetName, function() {
477 self.destroy();
478 });
479
480 this._create();
481 this._trigger( "create" );
482 this._init();
483 },
484 _getCreateOptions: function() {
485 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
486 },
487 _create: function() {},
488 _init: function() {},
489
490 destroy: function() {
491 this.element
492 .unbind( "." + this.widgetName )
493 .removeData( this.widgetName );
494 this.widget()
495 .unbind( "." + this.widgetName )
496 .removeAttr( "aria-disabled" )
497 .removeClass(
498 this.widgetBaseClass + "-disabled " +
499 "ui-state-disabled" );
500 },
501
502 widget: function() {
503 return this.element;
504 },
505
506 option: function( key, value ) {
507 var options = key;
508
509 if ( arguments.length === 0 ) {
510 // don't return a reference to the internal hash
511 return $.extend( {}, this.options );
512 }
513
514 if (typeof key === "string" ) {
515 if ( value === undefined ) {
516 return this.options[ key ];
517 }
518 options = {};
519 options[ key ] = value;
520 }
521
522 this._setOptions( options );
523
524 return this;
525 },
526 _setOptions: function( options ) {
527 var self = this;
528 $.each( options, function( key, value ) {
529 self._setOption( key, value );
530 });
531
532 return this;
533 },
534 _setOption: function( key, value ) {
535 this.options[ key ] = value;
536
537 if ( key === "disabled" ) {
538 this.widget()
539 [ value ? "addClass" : "removeClass"](
540 this.widgetBaseClass + "-disabled" + " " +
541 "ui-state-disabled" )
542 .attr( "aria-disabled", value );
543 }
544
545 return this;
546 },
547
548 enable: function() {
549 return this._setOption( "disabled", false );
550 },
551 disable: function() {
552 return this._setOption( "disabled", true );
553 },
554
555 _trigger: function( type, event, data ) {
556 var callback = this.options[ type ];
557
558 event = $.Event( event );
559 event.type = ( type === this.widgetEventPrefix ?
560 type :
561 this.widgetEventPrefix + type ).toLowerCase();
562 data = data || {};
563
564 // copy original event properties over to the new event
565 // this would happen if we could call $.event.fix instead of $.Event
566 // but we don't have a way to force an event to be fixed multiple times
567 if ( event.originalEvent ) {
568 for ( var i = $.event.props.length, prop; i; ) {
569 prop = $.event.props[ --i ];
570 event[ prop ] = event.originalEvent[ prop ];
571 }
572 }
573
574 this.element.trigger( event, data );
575
576 return !( $.isFunction(callback) &&
577 callback.call( this.element[0], event, data ) === false ||
578 event.isDefaultPrevented() );
579 }
580};
581
582})( jQuery );
583/*!
584 * jQuery UI Mouse 1.8.16
585 *
586 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
587 * Dual licensed under the MIT or GPL Version 2 licenses.
588 * http://jquery.org/license
589 *
590 * http://docs.jquery.com/UI/Mouse
591 *
592 * Depends:
593 * jquery.ui.widget.js
594 */
595(function( $, undefined ) {
596
597var mouseHandled = false;
598$( document ).mouseup( function( e ) {
599 mouseHandled = false;
600});
601
602$.widget("ui.mouse", {
603 options: {
604 cancel: ':input,option',
605 distance: 1,
606 delay: 0
607 },
608 _mouseInit: function() {
609 var self = this;
610
611 this.element
612 .bind('mousedown.'+this.widgetName, function(event) {
613 return self._mouseDown(event);
614 })
615 .bind('click.'+this.widgetName, function(event) {
616 if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
617 $.removeData(event.target, self.widgetName + '.preventClickEvent');
618 event.stopImmediatePropagation();
619 return false;
620 }
621 });
622
623 this.started = false;
624 },
625
626 // TODO: make sure destroying one instance of mouse doesn't mess with
627 // other instances of mouse
628 _mouseDestroy: function() {
629 this.element.unbind('.'+this.widgetName);
630 },
631
632 _mouseDown: function(event) {
633 // don't let more than one widget handle mouseStart
634 if( mouseHandled ) { return };
635
636 // we may have missed mouseup (out of window)
637 (this._mouseStarted && this._mouseUp(event));
638
639 this._mouseDownEvent = event;
640
641 var self = this,
642 btnIsLeft = (event.which == 1),
643 // event.target.nodeName works around a bug in IE 8 with
644 // disabled inputs (#7620)
645 elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
646 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
647 return true;
648 }
649
650 this.mouseDelayMet = !this.options.delay;
651 if (!this.mouseDelayMet) {
652 this._mouseDelayTimer = setTimeout(function() {
653 self.mouseDelayMet = true;
654 }, this.options.delay);
655 }
656
657 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
658 this._mouseStarted = (this._mouseStart(event) !== false);
659 if (!this._mouseStarted) {
660 event.preventDefault();
661 return true;
662 }
663 }
664
665 // Click event may never have fired (Gecko & Opera)
666 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
667 $.removeData(event.target, this.widgetName + '.preventClickEvent');
668 }
669
670 // these delegates are required to keep context
671 this._mouseMoveDelegate = function(event) {
672 return self._mouseMove(event);
673 };
674 this._mouseUpDelegate = function(event) {
675 return self._mouseUp(event);
676 };
677 $(document)
678 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
679 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
680
681 event.preventDefault();
682
683 mouseHandled = true;
684 return true;
685 },
686
687 _mouseMove: function(event) {
688 // IE mouseup check - mouseup happened when mouse was out of window
689 if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
690 return this._mouseUp(event);
691 }
692
693 if (this._mouseStarted) {
694 this._mouseDrag(event);
695 return event.preventDefault();
696 }
697
698 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
699 this._mouseStarted =
700 (this._mouseStart(this._mouseDownEvent, event) !== false);
701 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
702 }
703
704 return !this._mouseStarted;
705 },
706
707 _mouseUp: function(event) {
708 $(document)
709 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
710 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
711
712 if (this._mouseStarted) {
713 this._mouseStarted = false;
714
715 if (event.target == this._mouseDownEvent.target) {
716 $.data(event.target, this.widgetName + '.preventClickEvent', true);
717 }
718
719 this._mouseStop(event);
720 }
721
722 return false;
723 },
724
725 _mouseDistanceMet: function(event) {
726 return (Math.max(
727 Math.abs(this._mouseDownEvent.pageX - event.pageX),
728 Math.abs(this._mouseDownEvent.pageY - event.pageY)
729 ) >= this.options.distance
730 );
731 },
732
733 _mouseDelayMet: function(event) {
734 return this.mouseDelayMet;
735 },
736
737 // These are placeholder methods, to be overriden by extending plugin
738 _mouseStart: function(event) {},
739 _mouseDrag: function(event) {},
740 _mouseStop: function(event) {},
741 _mouseCapture: function(event) { return true; }
742});
743
744})(jQuery);
745/*
746 * jQuery UI Position 1.8.16
747 *
748 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
749 * Dual licensed under the MIT or GPL Version 2 licenses.
750 * http://jquery.org/license
751 *
752 * http://docs.jquery.com/UI/Position
753 */
754(function( $, undefined ) {
755
756$.ui = $.ui || {};
757
758var horizontalPositions = /left|center|right/,
759 verticalPositions = /top|center|bottom/,
760 center = "center",
761 _position = $.fn.position,
762 _offset = $.fn.offset;
763
764$.fn.position = function( options ) {
765 if ( !options || !options.of ) {
766 return _position.apply( this, arguments );
767 }
768
769 // make a copy, we don't want to modify arguments
770 options = $.extend( {}, options );
771
772 var target = $( options.of ),
773 targetElem = target[0],
774 collision = ( options.collision || "flip" ).split( " " ),
775 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
776 targetWidth,
777 targetHeight,
778 basePosition;
779
780 if ( targetElem.nodeType === 9 ) {
781 targetWidth = target.width();
782 targetHeight = target.height();
783 basePosition = { top: 0, left: 0 };
784 // TODO: use $.isWindow() in 1.9
785 } else if ( targetElem.setTimeout ) {
786 targetWidth = target.width();
787 targetHeight = target.height();
788 basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
789 } else if ( targetElem.preventDefault ) {
790 // force left top to allow flipping
791 options.at = "left top";
792 targetWidth = targetHeight = 0;
793 basePosition = { top: options.of.pageY, left: options.of.pageX };
794 } else {
795 targetWidth = target.outerWidth();
796 targetHeight = target.outerHeight();
797 basePosition = target.offset();
798 }
799
800 // force my and at to have valid horizontal and veritcal positions
801 // if a value is missing or invalid, it will be converted to center
802 $.each( [ "my", "at" ], function() {
803 var pos = ( options[this] || "" ).split( " " );
804 if ( pos.length === 1) {
805 pos = horizontalPositions.test( pos[0] ) ?
806 pos.concat( [center] ) :
807 verticalPositions.test( pos[0] ) ?
808 [ center ].concat( pos ) :
809 [ center, center ];
810 }
811 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
812 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
813 options[ this ] = pos;
814 });
815
816 // normalize collision option
817 if ( collision.length === 1 ) {
818 collision[ 1 ] = collision[ 0 ];
819 }
820
821 // normalize offset option
822 offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
823 if ( offset.length === 1 ) {
824 offset[ 1 ] = offset[ 0 ];
825 }
826 offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
827
828 if ( options.at[0] === "right" ) {
829 basePosition.left += targetWidth;
830 } else if ( options.at[0] === center ) {
831 basePosition.left += targetWidth / 2;
832 }
833
834 if ( options.at[1] === "bottom" ) {
835 basePosition.top += targetHeight;
836 } else if ( options.at[1] === center ) {
837 basePosition.top += targetHeight / 2;
838 }
839
840 basePosition.left += offset[ 0 ];
841 basePosition.top += offset[ 1 ];
842
843 return this.each(function() {
844 var elem = $( this ),
845 elemWidth = elem.outerWidth(),
846 elemHeight = elem.outerHeight(),
847 marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
848 marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
849 collisionWidth = elemWidth + marginLeft +
850 ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
851 collisionHeight = elemHeight + marginTop +
852 ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
853 position = $.extend( {}, basePosition ),
854 collisionPosition;
855
856 if ( options.my[0] === "right" ) {
857 position.left -= elemWidth;
858 } else if ( options.my[0] === center ) {
859 position.left -= elemWidth / 2;
860 }
861
862 if ( options.my[1] === "bottom" ) {
863 position.top -= elemHeight;
864 } else if ( options.my[1] === center ) {
865 position.top -= elemHeight / 2;
866 }
867
868 // prevent fractions (see #5280)
869 position.left = Math.round( position.left );
870 position.top = Math.round( position.top );
871
872 collisionPosition = {
873 left: position.left - marginLeft,
874 top: position.top - marginTop
875 };
876
877 $.each( [ "left", "top" ], function( i, dir ) {
878 if ( $.ui.position[ collision[i] ] ) {
879 $.ui.position[ collision[i] ][ dir ]( position, {
880 targetWidth: targetWidth,
881 targetHeight: targetHeight,
882 elemWidth: elemWidth,
883 elemHeight: elemHeight,
884 collisionPosition: collisionPosition,
885 collisionWidth: collisionWidth,
886 collisionHeight: collisionHeight,
887 offset: offset,
888 my: options.my,
889 at: options.at
890 });
891 }
892 });
893
894 if ( $.fn.bgiframe ) {
895 elem.bgiframe();
896 }
897 elem.offset( $.extend( position, { using: options.using } ) );
898 });
899};
900
901$.ui.position = {
902 fit: {
903 left: function( position, data ) {
904 var win = $( window ),
905 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
906 position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
907 },
908 top: function( position, data ) {
909 var win = $( window ),
910 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
911 position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
912 }
913 },
914
915 flip: {
916 left: function( position, data ) {
917 if ( data.at[0] === center ) {
918 return;
919 }
920 var win = $( window ),
921 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
922 myOffset = data.my[ 0 ] === "left" ?
923 -data.elemWidth :
924 data.my[ 0 ] === "right" ?
925 data.elemWidth :
926 0,
927 atOffset = data.at[ 0 ] === "left" ?
928 data.targetWidth :
929 -data.targetWidth,
930 offset = -2 * data.offset[ 0 ];
931 position.left += data.collisionPosition.left < 0 ?
932 myOffset + atOffset + offset :
933 over > 0 ?
934 myOffset + atOffset + offset :
935 0;
936 },
937 top: function( position, data ) {
938 if ( data.at[1] === center ) {
939 return;
940 }
941 var win = $( window ),
942 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
943 myOffset = data.my[ 1 ] === "top" ?
944 -data.elemHeight :
945 data.my[ 1 ] === "bottom" ?
946 data.elemHeight :
947 0,
948 atOffset = data.at[ 1 ] === "top" ?
949 data.targetHeight :
950 -data.targetHeight,
951 offset = -2 * data.offset[ 1 ];
952 position.top += data.collisionPosition.top < 0 ?
953 myOffset + atOffset + offset :
954 over > 0 ?
955 myOffset + atOffset + offset :
956 0;
957 }
958 }
959};
960
961// offset setter from jQuery 1.4
962if ( !$.offset.setOffset ) {
963 $.offset.setOffset = function( elem, options ) {
964 // set position first, in-case top/left are set even on static elem
965 if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
966 elem.style.position = "relative";
967 }
968 var curElem = $( elem ),
969 curOffset = curElem.offset(),
970 curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
971 curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
972 props = {
973 top: (options.top - curOffset.top) + curTop,
974 left: (options.left - curOffset.left) + curLeft
975 };
976
977 if ( 'using' in options ) {
978 options.using.call( elem, props );
979 } else {
980 curElem.css( props );
981 }
982 };
983
984 $.fn.offset = function( options ) {
985 var elem = this[ 0 ];
986 if ( !elem || !elem.ownerDocument ) { return null; }
987 if ( options ) {
988 return this.each(function() {
989 $.offset.setOffset( this, options );
990 });
991 }
992 return _offset.call( this );
993 };
994}
995
996}( jQuery ));
997/*
998 * jQuery UI Draggable 1.8.16
999 *
1000 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1001 * Dual licensed under the MIT or GPL Version 2 licenses.
1002 * http://jquery.org/license
1003 *
1004 * http://docs.jquery.com/UI/Draggables
1005 *
1006 * Depends:
1007 * jquery.ui.core.js
1008 * jquery.ui.mouse.js
1009 * jquery.ui.widget.js
1010 */
1011(function( $, undefined ) {
1012
1013$.widget("ui.draggable", $.ui.mouse, {
1014 widgetEventPrefix: "drag",
1015 options: {
1016 addClasses: true,
1017 appendTo: "parent",
1018 axis: false,
1019 connectToSortable: false,
1020 containment: false,
1021 cursor: "auto",
1022 cursorAt: false,
1023 grid: false,
1024 handle: false,
1025 helper: "original",
1026 iframeFix: false,
1027 opacity: false,
1028 refreshPositions: false,
1029 revert: false,
1030 revertDuration: 500,
1031 scope: "default",
1032 scroll: true,
1033 scrollSensitivity: 20,
1034 scrollSpeed: 20,
1035 snap: false,
1036 snapMode: "both",
1037 snapTolerance: 20,
1038 stack: false,
1039 zIndex: false
1040 },
1041 _create: function() {
1042
1043 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1044 this.element[0].style.position = 'relative';
1045
1046 (this.options.addClasses && this.element.addClass("ui-draggable"));
1047 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1048
1049 this._mouseInit();
1050
1051 },
1052
1053 destroy: function() {
1054 if(!this.element.data('draggable')) return;
1055 this.element
1056 .removeData("draggable")
1057 .unbind(".draggable")
1058 .removeClass("ui-draggable"
1059 + " ui-draggable-dragging"
1060 + " ui-draggable-disabled");
1061 this._mouseDestroy();
1062
1063 return this;
1064 },
1065
1066 _mouseCapture: function(event) {
1067
1068 var o = this.options;
1069
1070 // among others, prevent a drag on a resizable-handle
1071 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1072 return false;
1073
1074 //Quit if we're not on a valid handle
1075 this.handle = this._getHandle(event);
1076 if (!this.handle)
1077 return false;
1078
1079 if ( o.iframeFix ) {
1080 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1081 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1082 .css({
1083 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1084 position: "absolute", opacity: "0.001", zIndex: 1000
1085 })
1086 .css($(this).offset())
1087 .appendTo("body");
1088 });
1089 }
1090
1091 return true;
1092
1093 },
1094
1095 _mouseStart: function(event) {
1096
1097 var o = this.options;
1098
1099 //Create and append the visible helper
1100 this.helper = this._createHelper(event);
1101
1102 //Cache the helper size
1103 this._cacheHelperProportions();
1104
1105 //If ddmanager is used for droppables, set the global draggable
1106 if($.ui.ddmanager)
1107 $.ui.ddmanager.current = this;
1108
1109 /*
1110 * - Position generation -
1111 * This block generates everything position related - it's the core of draggables.
1112 */
1113
1114 //Cache the margins of the original element
1115 this._cacheMargins();
1116
1117 //Store the helper's css position
1118 this.cssPosition = this.helper.css("position");
1119 this.scrollParent = this.helper.scrollParent();
1120
1121 //The element's absolute position on the page minus margins
1122 this.offset = this.positionAbs = this.element.offset();
1123 this.offset = {
1124 top: this.offset.top - this.margins.top,
1125 left: this.offset.left - this.margins.left
1126 };
1127
1128 $.extend(this.offset, {
1129 click: { //Where the click happened, relative to the element
1130 left: event.pageX - this.offset.left,
1131 top: event.pageY - this.offset.top
1132 },
1133 parent: this._getParentOffset(),
1134 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1135 });
1136
1137 //Generate the original position
1138 this.originalPosition = this.position = this._generatePosition(event);
1139 this.originalPageX = event.pageX;
1140 this.originalPageY = event.pageY;
1141
1142 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1143 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1144
1145 //Set a containment if given in the options
1146 if(o.containment)
1147 this._setContainment();
1148
1149 //Trigger event + callbacks
1150 if(this._trigger("start", event) === false) {
1151 this._clear();
1152 return false;
1153 }
1154
1155 //Recache the helper size
1156 this._cacheHelperProportions();
1157
1158 //Prepare the droppable offsets
1159 if ($.ui.ddmanager && !o.dropBehaviour)
1160 $.ui.ddmanager.prepareOffsets(this, event);
1161
1162 this.helper.addClass("ui-draggable-dragging");
1163 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1164
1165 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1166 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1167
1168 return true;
1169 },
1170
1171 _mouseDrag: function(event, noPropagation) {
1172
1173 //Compute the helpers position
1174 this.position = this._generatePosition(event);
1175 this.positionAbs = this._convertPositionTo("absolute");
1176
1177 //Call plugins and callbacks and use the resulting position if something is returned
1178 if (!noPropagation) {
1179 var ui = this._uiHash();
1180 if(this._trigger('drag', event, ui) === false) {
1181 this._mouseUp({});
1182 return false;
1183 }
1184 this.position = ui.position;
1185 }
1186
1187 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1188 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1189 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1190
1191 return false;
1192 },
1193
1194 _mouseStop: function(event) {
1195
1196 //If we are using droppables, inform the manager about the drop
1197 var dropped = false;
1198 if ($.ui.ddmanager && !this.options.dropBehaviour)
1199 dropped = $.ui.ddmanager.drop(this, event);
1200
1201 //if a drop comes from outside (a sortable)
1202 if(this.dropped) {
1203 dropped = this.dropped;
1204 this.dropped = false;
1205 }
1206
1207 //if the original element is removed, don't bother to continue if helper is set to "original"
1208 if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
1209 return false;
1210
1211 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))) {
1212 var self = this;
1213 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1214 if(self._trigger("stop", event) !== false) {
1215 self._clear();
1216 }
1217 });
1218 } else {
1219 if(this._trigger("stop", event) !== false) {
1220 this._clear();
1221 }
1222 }
1223
1224 return false;
1225 },
1226
1227 _mouseUp: function(event) {
1228 if (this.options.iframeFix === true) {
1229 $("div.ui-draggable-iframeFix").each(function() {
1230 this.parentNode.removeChild(this);
1231 }); //Remove frame helpers
1232 }
1233
1234 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1235 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1236
1237 return $.ui.mouse.prototype._mouseUp.call(this, event);
1238 },
1239
1240 cancel: function() {
1241
1242 if(this.helper.is(".ui-draggable-dragging")) {
1243 this._mouseUp({});
1244 } else {
1245 this._clear();
1246 }
1247
1248 return this;
1249
1250 },
1251
1252 _getHandle: function(event) {
1253
1254 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1255 $(this.options.handle, this.element)
1256 .find("*")
1257 .andSelf()
1258 .each(function() {
1259 if(this == event.target) handle = true;
1260 });
1261
1262 return handle;
1263
1264 },
1265
1266 _createHelper: function(event) {
1267
1268 var o = this.options;
1269 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1270
1271 if(!helper.parents('body').length)
1272 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1273
1274 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1275 helper.css("position", "absolute");
1276
1277 return helper;
1278
1279 },
1280
1281 _adjustOffsetFromHelper: function(obj) {
1282 if (typeof obj == 'string') {
1283 obj = obj.split(' ');
1284 }
1285 if ($.isArray(obj)) {
1286 obj = {left: +obj[0], top: +obj[1] || 0};
1287 }
1288 if ('left' in obj) {
1289 this.offset.click.left = obj.left + this.margins.left;
1290 }
1291 if ('right' in obj) {
1292 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1293 }
1294 if ('top' in obj) {
1295 this.offset.click.top = obj.top + this.margins.top;
1296 }
1297 if ('bottom' in obj) {
1298 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1299 }
1300 },
1301
1302 _getParentOffset: function() {
1303
1304 //Get the offsetParent and cache its position
1305 this.offsetParent = this.helper.offsetParent();
1306 var po = this.offsetParent.offset();
1307
1308 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1309 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1310 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1311 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1312 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1313 po.left += this.scrollParent.scrollLeft();
1314 po.top += this.scrollParent.scrollTop();
1315 }
1316
1317 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1318 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1319 po = { top: 0, left: 0 };
1320
1321 return {
1322 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1323 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1324 };
1325
1326 },
1327
1328 _getRelativeOffset: function() {
1329
1330 if(this.cssPosition == "relative") {
1331 var p = this.element.position();
1332 return {
1333 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1334 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1335 };
1336 } else {
1337 return { top: 0, left: 0 };
1338 }
1339
1340 },
1341
1342 _cacheMargins: function() {
1343 this.margins = {
1344 left: (parseInt(this.element.css("marginLeft"),10) || 0),
1345 top: (parseInt(this.element.css("marginTop"),10) || 0),
1346 right: (parseInt(this.element.css("marginRight"),10) || 0),
1347 bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1348 };
1349 },
1350
1351 _cacheHelperProportions: function() {
1352 this.helperProportions = {
1353 width: this.helper.outerWidth(),
1354 height: this.helper.outerHeight()
1355 };
1356 },
1357
1358 _setContainment: function() {
1359
1360 var o = this.options;
1361 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1362 if(o.containment == 'document' || o.containment == 'window') this.containment = [
1363 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1364 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1365 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1366 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1367 ];
1368
1369 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1370 var c = $(o.containment);
1371 var ce = c[0]; if(!ce) return;
1372 var co = c.offset();
1373 var over = ($(ce).css("overflow") != 'hidden');
1374
1375 this.containment = [
1376 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1377 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1378 (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,
1379 (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
1380 ];
1381 this.relative_container = c;
1382
1383 } else if(o.containment.constructor == Array) {
1384 this.containment = o.containment;
1385 }
1386
1387 },
1388
1389 _convertPositionTo: function(d, pos) {
1390
1391 if(!pos) pos = this.position;
1392 var mod = d == "absolute" ? 1 : -1;
1393 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);
1394
1395 return {
1396 top: (
1397 pos.top // The absolute mouse position
1398 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1399 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
1400 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1401 ),
1402 left: (
1403 pos.left // The absolute mouse position
1404 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1405 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
1406 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1407 )
1408 };
1409
1410 },
1411
1412 _generatePosition: function(event) {
1413
1414 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);
1415 var pageX = event.pageX;
1416 var pageY = event.pageY;
1417
1418 /*
1419 * - Position constraining -
1420 * Constrain the position to a mix of grid, containment.
1421 */
1422
1423 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1424 var containment;
1425 if(this.containment) {
1426 if (this.relative_container){
1427 var co = this.relative_container.offset();
1428 containment = [ this.containment[0] + co.left,
1429 this.containment[1] + co.top,
1430 this.containment[2] + co.left,
1431 this.containment[3] + co.top ];
1432 }
1433 else {
1434 containment = this.containment;
1435 }
1436
1437 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1438 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1439 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1440 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1441 }
1442
1443 if(o.grid) {
1444 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1445 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1446 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;
1447
1448 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1449 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;
1450 }
1451
1452 }
1453
1454 return {
1455 top: (
1456 pageY // The absolute mouse position
1457 - this.offset.click.top // Click offset (relative to the element)
1458 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
1459 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
1460 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1461 ),
1462 left: (
1463 pageX // The absolute mouse position
1464 - this.offset.click.left // Click offset (relative to the element)
1465 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
1466 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
1467 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1468 )
1469 };
1470
1471 },
1472
1473 _clear: function() {
1474 this.helper.removeClass("ui-draggable-dragging");
1475 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1476 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1477 this.helper = null;
1478 this.cancelHelperRemoval = false;
1479 },
1480
1481 // From now on bulk stuff - mainly helpers
1482
1483 _trigger: function(type, event, ui) {
1484 ui = ui || this._uiHash();
1485 $.ui.plugin.call(this, type, [event, ui]);
1486 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1487 return $.Widget.prototype._trigger.call(this, type, event, ui);
1488 },
1489
1490 plugins: {},
1491
1492 _uiHash: function(event) {
1493 return {
1494 helper: this.helper,
1495 position: this.position,
1496 originalPosition: this.originalPosition,
1497 offset: this.positionAbs
1498 };
1499 }
1500
1501});
1502
1503$.extend($.ui.draggable, {
1504 version: "1.8.16"
1505});
1506
1507$.ui.plugin.add("draggable", "connectToSortable", {
1508 start: function(event, ui) {
1509
1510 var inst = $(this).data("draggable"), o = inst.options,
1511 uiSortable = $.extend({}, ui, { item: inst.element });
1512 inst.sortables = [];
1513 $(o.connectToSortable).each(function() {
1514 var sortable = $.data(this, 'sortable');
1515 if (sortable && !sortable.options.disabled) {
1516 inst.sortables.push({
1517 instance: sortable,
1518 shouldRevert: sortable.options.revert
1519 });
1520 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).
1521 sortable._trigger("activate", event, uiSortable);
1522 }
1523 });
1524
1525 },
1526 stop: function(event, ui) {
1527
1528 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1529 var inst = $(this).data("draggable"),
1530 uiSortable = $.extend({}, ui, { item: inst.element });
1531
1532 $.each(inst.sortables, function() {
1533 if(this.instance.isOver) {
1534
1535 this.instance.isOver = 0;
1536
1537 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1538 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1539
1540 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1541 if(this.shouldRevert) this.instance.options.revert = true;
1542
1543 //Trigger the stop of the sortable
1544 this.instance._mouseStop(event);
1545
1546 this.instance.options.helper = this.instance.options._helper;
1547
1548 //If the helper has been the original item, restore properties in the sortable
1549 if(inst.options.helper == 'original')
1550 this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1551
1552 } else {
1553 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1554 this.instance._trigger("deactivate", event, uiSortable);
1555 }
1556
1557 });
1558
1559 },
1560 drag: function(event, ui) {
1561
1562 var inst = $(this).data("draggable"), self = this;
1563
1564 var checkPos = function(o) {
1565 var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1566 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1567 var itemHeight = o.height, itemWidth = o.width;
1568 var itemTop = o.top, itemLeft = o.left;
1569
1570 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1571 };
1572
1573 $.each(inst.sortables, function(i) {
1574
1575 //Copy over some variables to allow calling the sortable's native _intersectsWith
1576 this.instance.positionAbs = inst.positionAbs;
1577 this.instance.helperProportions = inst.helperProportions;
1578 this.instance.offset.click = inst.offset.click;
1579
1580 if(this.instance._intersectsWith(this.instance.containerCache)) {
1581
1582 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1583 if(!this.instance.isOver) {
1584
1585 this.instance.isOver = 1;
1586 //Now we fake the start of dragging for the sortable instance,
1587 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1588 //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)
1589 this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1590 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1591 this.instance.options.helper = function() { return ui.helper[0]; };
1592
1593 event.target = this.instance.currentItem[0];
1594 this.instance._mouseCapture(event, true);
1595 this.instance._mouseStart(event, true, true);
1596
1597 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1598 this.instance.offset.click.top = inst.offset.click.top;
1599 this.instance.offset.click.left = inst.offset.click.left;
1600 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1601 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1602
1603 inst._trigger("toSortable", event);
1604 inst.dropped = this.instance.element; //draggable revert needs that
1605 //hack so receive/update callbacks work (mostly)
1606 inst.currentItem = inst.element;
1607 this.instance.fromOutside = inst;
1608
1609 }
1610
1611 //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
1612 if(this.instance.currentItem) this.instance._mouseDrag(event);
1613
1614 } else {
1615
1616 //If it doesn't intersect with the sortable, and it intersected before,
1617 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1618 if(this.instance.isOver) {
1619
1620 this.instance.isOver = 0;
1621 this.instance.cancelHelperRemoval = true;
1622
1623 //Prevent reverting on this forced stop
1624 this.instance.options.revert = false;
1625
1626 // The out event needs to be triggered independently
1627 this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1628
1629 this.instance._mouseStop(event, true);
1630 this.instance.options.helper = this.instance.options._helper;
1631
1632 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1633 this.instance.currentItem.remove();
1634 if(this.instance.placeholder) this.instance.placeholder.remove();
1635
1636 inst._trigger("fromSortable", event);
1637 inst.dropped = false; //draggable revert needs that
1638 }
1639
1640 };
1641
1642 });
1643
1644 }
1645});
1646
1647$.ui.plugin.add("draggable", "cursor", {
1648 start: function(event, ui) {
1649 var t = $('body'), o = $(this).data('draggable').options;
1650 if (t.css("cursor")) o._cursor = t.css("cursor");
1651 t.css("cursor", o.cursor);
1652 },
1653 stop: function(event, ui) {
1654 var o = $(this).data('draggable').options;
1655 if (o._cursor) $('body').css("cursor", o._cursor);
1656 }
1657});
1658
1659$.ui.plugin.add("draggable", "opacity", {
1660 start: function(event, ui) {
1661 var t = $(ui.helper), o = $(this).data('draggable').options;
1662 if(t.css("opacity")) o._opacity = t.css("opacity");
1663 t.css('opacity', o.opacity);
1664 },
1665 stop: function(event, ui) {
1666 var o = $(this).data('draggable').options;
1667 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1668 }
1669});
1670
1671$.ui.plugin.add("draggable", "scroll", {
1672 start: function(event, ui) {
1673 var i = $(this).data("draggable");
1674 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1675 },
1676 drag: function(event, ui) {
1677
1678 var i = $(this).data("draggable"), o = i.options, scrolled = false;
1679
1680 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1681
1682 if(!o.axis || o.axis != 'x') {
1683 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1684 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1685 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1686 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1687 }
1688
1689 if(!o.axis || o.axis != 'y') {
1690 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1691 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1692 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1693 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1694 }
1695
1696 } else {
1697
1698 if(!o.axis || o.axis != 'x') {
1699 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1700 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1701 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1702 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1703 }
1704
1705 if(!o.axis || o.axis != 'y') {
1706 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1707 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1708 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1709 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1710 }
1711
1712 }
1713
1714 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1715 $.ui.ddmanager.prepareOffsets(i, event);
1716
1717 }
1718});
1719
1720$.ui.plugin.add("draggable", "snap", {
1721 start: function(event, ui) {
1722
1723 var i = $(this).data("draggable"), o = i.options;
1724 i.snapElements = [];
1725
1726 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1727 var $t = $(this); var $o = $t.offset();
1728 if(this != i.element[0]) i.snapElements.push({
1729 item: this,
1730 width: $t.outerWidth(), height: $t.outerHeight(),
1731 top: $o.top, left: $o.left
1732 });
1733 });
1734
1735 },
1736 drag: function(event, ui) {
1737
1738 var inst = $(this).data("draggable"), o = inst.options;
1739 var d = o.snapTolerance;
1740
1741 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1742 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1743
1744 for (var i = inst.snapElements.length - 1; i >= 0; i--){
1745
1746 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1747 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1748
1749 //Yes, I know, this is insane ;)
1750 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))) {
1751 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 })));
1752 inst.snapElements[i].snapping = false;
1753 continue;
1754 }
1755
1756 if(o.snapMode != 'inner') {
1757 var ts = Math.abs(t - y2) <= d;
1758 var bs = Math.abs(b - y1) <= d;
1759 var ls = Math.abs(l - x2) <= d;
1760 var rs = Math.abs(r - x1) <= d;
1761 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1762 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1763 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1764 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1765 }
1766
1767 var first = (ts || bs || ls || rs);
1768
1769 if(o.snapMode != 'outer') {
1770 var ts = Math.abs(t - y1) <= d;
1771 var bs = Math.abs(b - y2) <= d;
1772 var ls = Math.abs(l - x1) <= d;
1773 var rs = Math.abs(r - x2) <= d;
1774 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1775 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1776 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1777 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1778 }
1779
1780 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1781 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1782 inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1783
1784 };
1785
1786 }
1787});
1788
1789$.ui.plugin.add("draggable", "stack", {
1790 start: function(event, ui) {
1791
1792 var o = $(this).data("draggable").options;
1793
1794 var group = $.makeArray($(o.stack)).sort(function(a,b) {
1795 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1796 });
1797 if (!group.length) { return; }
1798
1799 var min = parseInt(group[0].style.zIndex) || 0;
1800 $(group).each(function(i) {
1801 this.style.zIndex = min + i;
1802 });
1803
1804 this[0].style.zIndex = min + group.length;
1805
1806 }
1807});
1808
1809$.ui.plugin.add("draggable", "zIndex", {
1810 start: function(event, ui) {
1811 var t = $(ui.helper), o = $(this).data("draggable").options;
1812 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1813 t.css('zIndex', o.zIndex);
1814 },
1815 stop: function(event, ui) {
1816 var o = $(this).data("draggable").options;
1817 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1818 }
1819});
1820
1821})(jQuery);
1822/*
1823 * jQuery UI Droppable 1.8.16
1824 *
1825 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1826 * Dual licensed under the MIT or GPL Version 2 licenses.
1827 * http://jquery.org/license
1828 *
1829 * http://docs.jquery.com/UI/Droppables
1830 *
1831 * Depends:
1832 * jquery.ui.core.js
1833 * jquery.ui.widget.js
1834 * jquery.ui.mouse.js
1835 * jquery.ui.draggable.js
1836 */
1837(function( $, undefined ) {
1838
1839$.widget("ui.droppable", {
1840 widgetEventPrefix: "drop",
1841 options: {
1842 accept: '*',
1843 activeClass: false,
1844 addClasses: true,
1845 greedy: false,
1846 hoverClass: false,
1847 scope: 'default',
1848 tolerance: 'intersect'
1849 },
1850 _create: function() {
1851
1852 var o = this.options, accept = o.accept;
1853 this.isover = 0; this.isout = 1;
1854
1855 this.accept = $.isFunction(accept) ? accept : function(d) {
1856 return d.is(accept);
1857 };
1858
1859 //Store the droppable's proportions
1860 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1861
1862 // Add the reference and positions to the manager
1863 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1864 $.ui.ddmanager.droppables[o.scope].push(this);
1865
1866 (o.addClasses && this.element.addClass("ui-droppable"));
1867
1868 },
1869
1870 destroy: function() {
1871 var drop = $.ui.ddmanager.droppables[this.options.scope];
1872 for ( var i = 0; i < drop.length; i++ )
1873 if ( drop[i] == this )
1874 drop.splice(i, 1);
1875
1876 this.element
1877 .removeClass("ui-droppable ui-droppable-disabled")
1878 .removeData("droppable")
1879 .unbind(".droppable");
1880
1881 return this;
1882 },
1883
1884 _setOption: function(key, value) {
1885
1886 if(key == 'accept') {
1887 this.accept = $.isFunction(value) ? value : function(d) {
1888 return d.is(value);
1889 };
1890 }
1891 $.Widget.prototype._setOption.apply(this, arguments);
1892 },
1893
1894 _activate: function(event) {
1895 var draggable = $.ui.ddmanager.current;
1896 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1897 (draggable && this._trigger('activate', event, this.ui(draggable)));
1898 },
1899
1900 _deactivate: function(event) {
1901 var draggable = $.ui.ddmanager.current;
1902 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1903 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
1904 },
1905
1906 _over: 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.addClass(this.options.hoverClass);
1913 this._trigger('over', event, this.ui(draggable));
1914 }
1915
1916 },
1917
1918 _out: function(event) {
1919
1920 var draggable = $.ui.ddmanager.current;
1921 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1922
1923 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1924 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1925 this._trigger('out', event, this.ui(draggable));
1926 }
1927
1928 },
1929
1930 _drop: function(event,custom) {
1931
1932 var draggable = custom || $.ui.ddmanager.current;
1933 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1934
1935 var childrenIntersection = false;
1936 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1937 var inst = $.data(this, 'droppable');
1938 if(
1939 inst.options.greedy
1940 && !inst.options.disabled
1941 && inst.options.scope == draggable.options.scope
1942 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1943 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1944 ) { childrenIntersection = true; return false; }
1945 });
1946 if(childrenIntersection) return false;
1947
1948 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1949 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1950 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1951 this._trigger('drop', event, this.ui(draggable));
1952 return this.element;
1953 }
1954
1955 return false;
1956
1957 },
1958
1959 ui: function(c) {
1960 return {
1961 draggable: (c.currentItem || c.element),
1962 helper: c.helper,
1963 position: c.position,
1964 offset: c.positionAbs
1965 };
1966 }
1967
1968});
1969
1970$.extend($.ui.droppable, {
1971 version: "1.8.16"
1972});
1973
1974$.ui.intersect = function(draggable, droppable, toleranceMode) {
1975
1976 if (!droppable.offset) return false;
1977
1978 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1979 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1980 var l = droppable.offset.left, r = l + droppable.proportions.width,
1981 t = droppable.offset.top, b = t + droppable.proportions.height;
1982
1983 switch (toleranceMode) {
1984 case 'fit':
1985 return (l <= x1 && x2 <= r
1986 && t <= y1 && y2 <= b);
1987 break;
1988 case 'intersect':
1989 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1990 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
1991 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1992 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1993 break;
1994 case 'pointer':
1995 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1996 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1997 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1998 return isOver;
1999 break;
2000 case 'touch':
2001 return (
2002 (y1 >= t && y1 <= b) || // Top edge touching
2003 (y2 >= t && y2 <= b) || // Bottom edge touching
2004 (y1 < t && y2 > b) // Surrounded vertically
2005 ) && (
2006 (x1 >= l && x1 <= r) || // Left edge touching
2007 (x2 >= l && x2 <= r) || // Right edge touching
2008 (x1 < l && x2 > r) // Surrounded horizontally
2009 );
2010 break;
2011 default:
2012 return false;
2013 break;
2014 }
2015
2016};
2017
2018/*
2019 This manager tracks offsets of draggables and droppables
2020*/
2021$.ui.ddmanager = {
2022 current: null,
2023 droppables: { 'default': [] },
2024 prepareOffsets: function(t, event) {
2025
2026 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2027 var type = event ? event.type : null; // workaround for #2317
2028 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2029
2030 droppablesLoop: for (var i = 0; i < m.length; i++) {
2031
2032 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
2033 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
2034 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
2035
2036 if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2037
2038 m[i].offset = m[i].element.offset();
2039 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2040
2041 }
2042
2043 },
2044 drop: function(draggable, event) {
2045
2046 var dropped = false;
2047 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2048
2049 if(!this.options) return;
2050 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2051 dropped = dropped || this._drop.call(this, event);
2052
2053 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2054 this.isout = 1; this.isover = 0;
2055 this._deactivate.call(this, event);
2056 }
2057
2058 });
2059 return dropped;
2060
2061 },
2062 dragStart: function( draggable, event ) {
2063 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2064 draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
2065 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2066 });
2067 },
2068 drag: function(draggable, event) {
2069
2070 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2071 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2072
2073 //Run through all droppables and check their positions based on specific tolerance options
2074 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2075
2076 if(this.options.disabled || this.greedyChild || !this.visible) return;
2077 var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2078
2079 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2080 if(!c) return;
2081
2082 var parentInstance;
2083 if (this.options.greedy) {
2084 var parent = this.element.parents(':data(droppable):eq(0)');
2085 if (parent.length) {
2086 parentInstance = $.data(parent[0], 'droppable');
2087 parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2088 }
2089 }
2090
2091 // we just moved into a greedy child
2092 if (parentInstance && c == 'isover') {
2093 parentInstance['isover'] = 0;
2094 parentInstance['isout'] = 1;
2095 parentInstance._out.call(parentInstance, event);
2096 }
2097
2098 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2099 this[c == "isover" ? "_over" : "_out"].call(this, event);
2100
2101 // we just moved out of a greedy child
2102 if (parentInstance && c == 'isout') {
2103 parentInstance['isout'] = 0;
2104 parentInstance['isover'] = 1;
2105 parentInstance._over.call(parentInstance, event);
2106 }
2107 });
2108
2109 },
2110 dragStop: function( draggable, event ) {
2111 draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
2112 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2113 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2114 }
2115};
2116
2117})(jQuery);
2118/*
2119 * jQuery UI Resizable 1.8.16
2120 *
2121 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2122 * Dual licensed under the MIT or GPL Version 2 licenses.
2123 * http://jquery.org/license
2124 *
2125 * http://docs.jquery.com/UI/Resizables
2126 *
2127 * Depends:
2128 * jquery.ui.core.js
2129 * jquery.ui.mouse.js
2130 * jquery.ui.widget.js
2131 */
2132(function( $, undefined ) {
2133
2134$.widget("ui.resizable", $.ui.mouse, {
2135 widgetEventPrefix: "resize",
2136 options: {
2137 alsoResize: false,
2138 animate: false,
2139 animateDuration: "slow",
2140 animateEasing: "swing",
2141 aspectRatio: false,
2142 autoHide: false,
2143 containment: false,
2144 ghost: false,
2145 grid: false,
2146 handles: "e,s,se",
2147 helper: false,
2148 maxHeight: null,
2149 maxWidth: null,
2150 minHeight: 10,
2151 minWidth: 10,
2152 zIndex: 1000
2153 },
2154 _create: function() {
2155
2156 var self = this, o = this.options;
2157 this.element.addClass("ui-resizable");
2158
2159 $.extend(this, {
2160 _aspectRatio: !!(o.aspectRatio),
2161 aspectRatio: o.aspectRatio,
2162 originalElement: this.element,
2163 _proportionallyResizeElements: [],
2164 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2165 });
2166
2167 //Wrap the element if it cannot hold child nodes
2168 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2169
2170 //Opera fix for relative positioning
2171 if (/relative/.test(this.element.css('position')) && $.browser.opera)
2172 this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
2173
2174 //Create a wrapper element and set the wrapper to the new current internal element
2175 this.element.wrap(
2176 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2177 position: this.element.css('position'),
2178 width: this.element.outerWidth(),
2179 height: this.element.outerHeight(),
2180 top: this.element.css('top'),
2181 left: this.element.css('left')
2182 })
2183 );
2184
2185 //Overwrite the original this.element
2186 this.element = this.element.parent().data(
2187 "resizable", this.element.data('resizable')
2188 );
2189
2190 this.elementIsWrapper = true;
2191
2192 //Move margins to the wrapper
2193 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2194 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2195
2196 //Prevent Safari textarea resize
2197 this.originalResizeStyle = this.originalElement.css('resize');
2198 this.originalElement.css('resize', 'none');
2199
2200 //Push the actual element to our proportionallyResize internal array
2201 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2202
2203 // avoid IE jump (hard set the margin)
2204 this.originalElement.css({ margin: this.originalElement.css('margin') });
2205
2206 // fix handlers offset
2207 this._proportionallyResize();
2208
2209 }
2210
2211 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' });
2212 if(this.handles.constructor == String) {
2213
2214 if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2215 var n = this.handles.split(","); this.handles = {};
2216
2217 for(var i = 0; i < n.length; i++) {
2218
2219 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2220 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2221
2222 // increase zIndex of sw, se, ne, nw axis
2223 //TODO : this modifies original option
2224 if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
2225
2226 //TODO : What's going on here?
2227 if ('se' == handle) {
2228 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2229 };
2230
2231 //Insert into internal handles object and append to element
2232 this.handles[handle] = '.ui-resizable-'+handle;
2233 this.element.append(axis);
2234 }
2235
2236 }
2237
2238 this._renderAxis = function(target) {
2239
2240 target = target || this.element;
2241
2242 for(var i in this.handles) {
2243
2244 if(this.handles[i].constructor == String)
2245 this.handles[i] = $(this.handles[i], this.element).show();
2246
2247 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2248 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2249
2250 var axis = $(this.handles[i], this.element), padWrapper = 0;
2251
2252 //Checking the correct pad and border
2253 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2254
2255 //The padding type i have to apply...
2256 var padPos = [ 'padding',
2257 /ne|nw|n/.test(i) ? 'Top' :
2258 /se|sw|s/.test(i) ? 'Bottom' :
2259 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
2260
2261 target.css(padPos, padWrapper);
2262
2263 this._proportionallyResize();
2264
2265 }
2266
2267 //TODO: What's that good for? There's not anything to be executed left
2268 if(!$(this.handles[i]).length)
2269 continue;
2270
2271 }
2272 };
2273
2274 //TODO: make renderAxis a prototype function
2275 this._renderAxis(this.element);
2276
2277 this._handles = $('.ui-resizable-handle', this.element)
2278 .disableSelection();
2279
2280 //Matching axis name
2281 this._handles.mouseover(function() {
2282 if (!self.resizing) {
2283 if (this.className)
2284 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2285 //Axis, default = se
2286 self.axis = axis && axis[1] ? axis[1] : 'se';
2287 }
2288 });
2289
2290 //If we want to auto hide the elements
2291 if (o.autoHide) {
2292 this._handles.hide();
2293 $(this.element)
2294 .addClass("ui-resizable-autohide")
2295 .hover(function() {
2296 if (o.disabled) return;
2297 $(this).removeClass("ui-resizable-autohide");
2298 self._handles.show();
2299 },
2300 function(){
2301 if (o.disabled) return;
2302 if (!self.resizing) {
2303 $(this).addClass("ui-resizable-autohide");
2304 self._handles.hide();
2305 }
2306 });
2307 }
2308
2309 //Initialize the mouse interaction
2310 this._mouseInit();
2311
2312 },
2313
2314 destroy: function() {
2315
2316 this._mouseDestroy();
2317
2318 var _destroy = function(exp) {
2319 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2320 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2321 };
2322
2323 //TODO: Unwrap at same DOM position
2324 if (this.elementIsWrapper) {
2325 _destroy(this.element);
2326 var wrapper = this.element;
2327 wrapper.after(
2328 this.originalElement.css({
2329 position: wrapper.css('position'),
2330 width: wrapper.outerWidth(),
2331 height: wrapper.outerHeight(),
2332 top: wrapper.css('top'),
2333 left: wrapper.css('left')
2334 })
2335 ).remove();
2336 }
2337
2338 this.originalElement.css('resize', this.originalResizeStyle);
2339 _destroy(this.originalElement);
2340
2341 return this;
2342 },
2343
2344 _mouseCapture: function(event) {
2345 var handle = false;
2346 for (var i in this.handles) {
2347 if ($(this.handles[i])[0] == event.target) {
2348 handle = true;
2349 }
2350 }
2351
2352 return !this.options.disabled && handle;
2353 },
2354
2355 _mouseStart: function(event) {
2356
2357 var o = this.options, iniPos = this.element.position(), el = this.element;
2358
2359 this.resizing = true;
2360 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2361
2362 // bugfix for http://dev.jquery.com/ticket/1749
2363 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2364 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2365 }
2366
2367 //Opera fixing relative position
2368 if ($.browser.opera && (/relative/).test(el.css('position')))
2369 el.css({ position: 'relative', top: 'auto', left: 'auto' });
2370
2371 this._renderProxy();
2372
2373 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2374
2375 if (o.containment) {
2376 curleft += $(o.containment).scrollLeft() || 0;
2377 curtop += $(o.containment).scrollTop() || 0;
2378 }
2379
2380 //Store needed variables
2381 this.offset = this.helper.offset();
2382 this.position = { left: curleft, top: curtop };
2383 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2384 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2385 this.originalPosition = { left: curleft, top: curtop };
2386 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2387 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2388
2389 //Aspect Ratio
2390 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2391
2392 var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2393 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2394
2395 el.addClass("ui-resizable-resizing");
2396 this._propagate("start", event);
2397 return true;
2398 },
2399
2400 _mouseDrag: function(event) {
2401
2402 //Increase performance, avoid regex
2403 var el = this.helper, o = this.options, props = {},
2404 self = this, smp = this.originalMousePosition, a = this.axis;
2405
2406 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2407 var trigger = this._change[a];
2408 if (!trigger) return false;
2409
2410 // Calculate the attrs that will be change
2411 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2412
2413 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2414 this._updateVirtualBoundaries(event.shiftKey);
2415 if (this._aspectRatio || event.shiftKey)
2416 data = this._updateRatio(data, event);
2417
2418 data = this._respectSize(data, event);
2419
2420 // plugins callbacks need to be called first
2421 this._propagate("resize", event);
2422
2423 el.css({
2424 top: this.position.top + "px", left: this.position.left + "px",
2425 width: this.size.width + "px", height: this.size.height + "px"
2426 });
2427
2428 if (!this._helper && this._proportionallyResizeElements.length)
2429 this._proportionallyResize();
2430
2431 this._updateCache(data);
2432
2433 // calling the user callback at the end
2434 this._trigger('resize', event, this.ui());
2435
2436 return false;
2437 },
2438
2439 _mouseStop: function(event) {
2440
2441 this.resizing = false;
2442 var o = this.options, self = this;
2443
2444 if(this._helper) {
2445 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2446 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2447 soffsetw = ista ? 0 : self.sizeDiff.width;
2448
2449 var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) },
2450 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2451 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2452
2453 if (!o.animate)
2454 this.element.css($.extend(s, { top: top, left: left }));
2455
2456 self.helper.height(self.size.height);
2457 self.helper.width(self.size.width);
2458
2459 if (this._helper && !o.animate) this._proportionallyResize();
2460 }
2461
2462 $('body').css('cursor', 'auto');
2463
2464 this.element.removeClass("ui-resizable-resizing");
2465
2466 this._propagate("stop", event);
2467
2468 if (this._helper) this.helper.remove();
2469 return false;
2470
2471 },
2472
2473 _updateVirtualBoundaries: function(forceAspectRatio) {
2474 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2475
2476 b = {
2477 minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2478 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2479 minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2480 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2481 };
2482
2483 if(this._aspectRatio || forceAspectRatio) {
2484 // We want to create an enclosing box whose aspect ration is the requested one
2485 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2486 pMinWidth = b.minHeight * this.aspectRatio;
2487 pMinHeight = b.minWidth / this.aspectRatio;
2488 pMaxWidth = b.maxHeight * this.aspectRatio;
2489 pMaxHeight = b.maxWidth / this.aspectRatio;
2490
2491 if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2492 if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2493 if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2494 if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2495 }
2496 this._vBoundaries = b;
2497 },
2498
2499 _updateCache: function(data) {
2500 var o = this.options;
2501 this.offset = this.helper.offset();
2502 if (isNumber(data.left)) this.position.left = data.left;
2503 if (isNumber(data.top)) this.position.top = data.top;
2504 if (isNumber(data.height)) this.size.height = data.height;
2505 if (isNumber(data.width)) this.size.width = data.width;
2506 },
2507
2508 _updateRatio: function(data, event) {
2509
2510 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2511
2512 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2513 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2514
2515 if (a == 'sw') {
2516 data.left = cpos.left + (csize.width - data.width);
2517 data.top = null;
2518 }
2519 if (a == 'nw') {
2520 data.top = cpos.top + (csize.height - data.height);
2521 data.left = cpos.left + (csize.width - data.width);
2522 }
2523
2524 return data;
2525 },
2526
2527 _respectSize: function(data, event) {
2528
2529 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2530 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2531 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2532
2533 if (isminw) data.width = o.minWidth;
2534 if (isminh) data.height = o.minHeight;
2535 if (ismaxw) data.width = o.maxWidth;
2536 if (ismaxh) data.height = o.maxHeight;
2537
2538 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2539 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2540
2541 if (isminw && cw) data.left = dw - o.minWidth;
2542 if (ismaxw && cw) data.left = dw - o.maxWidth;
2543 if (isminh && ch) data.top = dh - o.minHeight;
2544 if (ismaxh && ch) data.top = dh - o.maxHeight;
2545
2546 // fixing jump error on top/left - bug #2330
2547 var isNotwh = !data.width && !data.height;
2548 if (isNotwh && !data.left && data.top) data.top = null;
2549 else if (isNotwh && !data.top && data.left) data.left = null;
2550
2551 return data;
2552 },
2553
2554 _proportionallyResize: function() {
2555
2556 var o = this.options;
2557 if (!this._proportionallyResizeElements.length) return;
2558 var element = this.helper || this.element;
2559
2560 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2561
2562 var prel = this._proportionallyResizeElements[i];
2563
2564 if (!this.borderDif) {
2565 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2566 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2567
2568 this.borderDif = $.map(b, function(v, i) {
2569 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2570 return border + padding;
2571 });
2572 }
2573
2574 if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2575 continue;
2576
2577 prel.css({
2578 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2579 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2580 });
2581
2582 };
2583
2584 },
2585
2586 _renderProxy: function() {
2587
2588 var el = this.element, o = this.options;
2589 this.elementOffset = el.offset();
2590
2591 if(this._helper) {
2592
2593 this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2594
2595 // fix ie6 offset TODO: This seems broken
2596 var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2597 pxyoffset = ( ie6 ? 2 : -1 );
2598
2599 this.helper.addClass(this._helper).css({
2600 width: this.element.outerWidth() + pxyoffset,
2601 height: this.element.outerHeight() + pxyoffset,
2602 position: 'absolute',
2603 left: this.elementOffset.left - ie6offset +'px',
2604 top: this.elementOffset.top - ie6offset +'px',
2605 zIndex: ++o.zIndex //TODO: Don't modify option
2606 });
2607
2608 this.helper
2609 .appendTo("body")
2610 .disableSelection();
2611
2612 } else {
2613 this.helper = this.element;
2614 }
2615
2616 },
2617
2618 _change: {
2619 e: function(event, dx, dy) {
2620 return { width: this.originalSize.width + dx };
2621 },
2622 w: function(event, dx, dy) {
2623 var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2624 return { left: sp.left + dx, width: cs.width - dx };
2625 },
2626 n: function(event, dx, dy) {
2627 var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2628 return { top: sp.top + dy, height: cs.height - dy };
2629 },
2630 s: function(event, dx, dy) {
2631 return { height: this.originalSize.height + dy };
2632 },
2633 se: function(event, dx, dy) {
2634 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2635 },
2636 sw: function(event, dx, dy) {
2637 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2638 },
2639 ne: function(event, dx, dy) {
2640 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2641 },
2642 nw: function(event, dx, dy) {
2643 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2644 }
2645 },
2646
2647 _propagate: function(n, event) {
2648 $.ui.plugin.call(this, n, [event, this.ui()]);
2649 (n != "resize" && this._trigger(n, event, this.ui()));
2650 },
2651
2652 plugins: {},
2653
2654 ui: function() {
2655 return {
2656 originalElement: this.originalElement,
2657 element: this.element,
2658 helper: this.helper,
2659 position: this.position,
2660 size: this.size,
2661 originalSize: this.originalSize,
2662 originalPosition: this.originalPosition
2663 };
2664 }
2665
2666});
2667
2668$.extend($.ui.resizable, {
2669 version: "1.8.16"
2670});
2671
2672/*
2673 * Resizable Extensions
2674 */
2675
2676$.ui.plugin.add("resizable", "alsoResize", {
2677
2678 start: function (event, ui) {
2679 var self = $(this).data("resizable"), o = self.options;
2680
2681 var _store = function (exp) {
2682 $(exp).each(function() {
2683 var el = $(this);
2684 el.data("resizable-alsoresize", {
2685 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2686 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
2687 position: el.css('position') // to reset Opera on stop()
2688 });
2689 });
2690 };
2691
2692 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2693 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2694 else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2695 }else{
2696 _store(o.alsoResize);
2697 }
2698 },
2699
2700 resize: function (event, ui) {
2701 var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2702
2703 var delta = {
2704 height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2705 top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2706 },
2707
2708 _alsoResize = function (exp, c) {
2709 $(exp).each(function() {
2710 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
2711 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2712
2713 $.each(css, function (i, prop) {
2714 var sum = (start[prop]||0) + (delta[prop]||0);
2715 if (sum && sum >= 0)
2716 style[prop] = sum || null;
2717 });
2718
2719 // Opera fixing relative position
2720 if ($.browser.opera && /relative/.test(el.css('position'))) {
2721 self._revertToRelativePosition = true;
2722 el.css({ position: 'absolute', top: 'auto', left: 'auto' });
2723 }
2724
2725 el.css(style);
2726 });
2727 };
2728
2729 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2730 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2731 }else{
2732 _alsoResize(o.alsoResize);
2733 }
2734 },
2735
2736 stop: function (event, ui) {
2737 var self = $(this).data("resizable"), o = self.options;
2738
2739 var _reset = function (exp) {
2740 $(exp).each(function() {
2741 var el = $(this);
2742 // reset position for Opera - no need to verify it was changed
2743 el.css({ position: el.data("resizable-alsoresize").position });
2744 });
2745 };
2746
2747 if (self._revertToRelativePosition) {
2748 self._revertToRelativePosition = false;
2749 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2750 $.each(o.alsoResize, function (exp) { _reset(exp); });
2751 }else{
2752 _reset(o.alsoResize);
2753 }
2754 }
2755
2756 $(this).removeData("resizable-alsoresize");
2757 }
2758});
2759
2760$.ui.plugin.add("resizable", "animate", {
2761
2762 stop: function(event, ui) {
2763 var self = $(this).data("resizable"), o = self.options;
2764
2765 var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2766 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2767 soffsetw = ista ? 0 : self.sizeDiff.width;
2768
2769 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2770 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2771 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2772
2773 self.element.animate(
2774 $.extend(style, top && left ? { top: top, left: left } : {}), {
2775 duration: o.animateDuration,
2776 easing: o.animateEasing,
2777 step: function() {
2778
2779 var data = {
2780 width: parseInt(self.element.css('width'), 10),
2781 height: parseInt(self.element.css('height'), 10),
2782 top: parseInt(self.element.css('top'), 10),
2783 left: parseInt(self.element.css('left'), 10)
2784 };
2785
2786 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2787
2788 // propagating resize, and updating values for each animation step
2789 self._updateCache(data);
2790 self._propagate("resize", event);
2791
2792 }
2793 }
2794 );
2795 }
2796
2797});
2798
2799$.ui.plugin.add("resizable", "containment", {
2800
2801 start: function(event, ui) {
2802 var self = $(this).data("resizable"), o = self.options, el = self.element;
2803 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2804 if (!ce) return;
2805
2806 self.containerElement = $(ce);
2807
2808 if (/document/.test(oc) || oc == document) {
2809 self.containerOffset = { left: 0, top: 0 };
2810 self.containerPosition = { left: 0, top: 0 };
2811
2812 self.parentData = {
2813 element: $(document), left: 0, top: 0,
2814 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2815 };
2816 }
2817
2818 // i'm a node, so compute top, left, right, bottom
2819 else {
2820 var element = $(ce), p = [];
2821 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2822
2823 self.containerOffset = element.offset();
2824 self.containerPosition = element.position();
2825 self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2826
2827 var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
2828 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2829
2830 self.parentData = {
2831 element: ce, left: co.left, top: co.top, width: width, height: height
2832 };
2833 }
2834 },
2835
2836 resize: function(event, ui) {
2837 var self = $(this).data("resizable"), o = self.options,
2838 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2839 pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2840
2841 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2842
2843 if (cp.left < (self._helper ? co.left : 0)) {
2844 self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2845 if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2846 self.position.left = o.helper ? co.left : 0;
2847 }
2848
2849 if (cp.top < (self._helper ? co.top : 0)) {
2850 self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2851 if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2852 self.position.top = self._helper ? co.top : 0;
2853 }
2854
2855 self.offset.left = self.parentData.left+self.position.left;
2856 self.offset.top = self.parentData.top+self.position.top;
2857
2858 var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2859 hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2860
2861 var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2862 isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2863
2864 if(isParent && isOffsetRelative) woset -= self.parentData.left;
2865
2866 if (woset + self.size.width >= self.parentData.width) {
2867 self.size.width = self.parentData.width - woset;
2868 if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2869 }
2870
2871 if (hoset + self.size.height >= self.parentData.height) {
2872 self.size.height = self.parentData.height - hoset;
2873 if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2874 }
2875 },
2876
2877 stop: function(event, ui){
2878 var self = $(this).data("resizable"), o = self.options, cp = self.position,
2879 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2880
2881 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2882
2883 if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2884 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2885
2886 if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2887 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2888
2889 }
2890});
2891
2892$.ui.plugin.add("resizable", "ghost", {
2893
2894 start: function(event, ui) {
2895
2896 var self = $(this).data("resizable"), o = self.options, cs = self.size;
2897
2898 self.ghost = self.originalElement.clone();
2899 self.ghost
2900 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2901 .addClass('ui-resizable-ghost')
2902 .addClass(typeof o.ghost == 'string' ? o.ghost : '');
2903
2904 self.ghost.appendTo(self.helper);
2905
2906 },
2907
2908 resize: function(event, ui){
2909 var self = $(this).data("resizable"), o = self.options;
2910 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2911 },
2912
2913 stop: function(event, ui){
2914 var self = $(this).data("resizable"), o = self.options;
2915 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2916 }
2917
2918});
2919
2920$.ui.plugin.add("resizable", "grid", {
2921
2922 resize: function(event, ui) {
2923 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;
2924 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2925 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);
2926
2927 if (/^(se|s|e)$/.test(a)) {
2928 self.size.width = os.width + ox;
2929 self.size.height = os.height + oy;
2930 }
2931 else if (/^(ne)$/.test(a)) {
2932 self.size.width = os.width + ox;
2933 self.size.height = os.height + oy;
2934 self.position.top = op.top - oy;
2935 }
2936 else if (/^(sw)$/.test(a)) {
2937 self.size.width = os.width + ox;
2938 self.size.height = os.height + oy;
2939 self.position.left = op.left - ox;
2940 }
2941 else {
2942 self.size.width = os.width + ox;
2943 self.size.height = os.height + oy;
2944 self.position.top = op.top - oy;
2945 self.position.left = op.left - ox;
2946 }
2947 }
2948
2949});
2950
2951var num = function(v) {
2952 return parseInt(v, 10) || 0;
2953};
2954
2955var isNumber = function(value) {
2956 return !isNaN(parseInt(value, 10));
2957};
2958
2959})(jQuery);
2960/*
2961 * jQuery UI Selectable 1.8.16
2962 *
2963 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2964 * Dual licensed under the MIT or GPL Version 2 licenses.
2965 * http://jquery.org/license
2966 *
2967 * http://docs.jquery.com/UI/Selectables
2968 *
2969 * Depends:
2970 * jquery.ui.core.js
2971 * jquery.ui.mouse.js
2972 * jquery.ui.widget.js
2973 */
2974(function( $, undefined ) {
2975
2976$.widget("ui.selectable", $.ui.mouse, {
2977 options: {
2978 appendTo: 'body',
2979 autoRefresh: true,
2980 distance: 0,
2981 filter: '*',
2982 tolerance: 'touch'
2983 },
2984 _create: function() {
2985 var self = this;
2986
2987 this.element.addClass("ui-selectable");
2988
2989 this.dragged = false;
2990
2991 // cache selectee children based on filter
2992 var selectees;
2993 this.refresh = function() {
2994 selectees = $(self.options.filter, self.element[0]);
2995 selectees.each(function() {
2996 var $this = $(this);
2997 var pos = $this.offset();
2998 $.data(this, "selectable-item", {
2999 element: this,
3000 $element: $this,
3001 left: pos.left,
3002 top: pos.top,
3003 right: pos.left + $this.outerWidth(),
3004 bottom: pos.top + $this.outerHeight(),
3005 startselected: false,
3006 selected: $this.hasClass('ui-selected'),
3007 selecting: $this.hasClass('ui-selecting'),
3008 unselecting: $this.hasClass('ui-unselecting')
3009 });
3010 });
3011 };
3012 this.refresh();
3013
3014 this.selectees = selectees.addClass("ui-selectee");
3015
3016 this._mouseInit();
3017
3018 this.helper = $("<div class='ui-selectable-helper'></div>");
3019 },
3020
3021 destroy: function() {
3022 this.selectees
3023 .removeClass("ui-selectee")
3024 .removeData("selectable-item");
3025 this.element
3026 .removeClass("ui-selectable ui-selectable-disabled")
3027 .removeData("selectable")
3028 .unbind(".selectable");
3029 this._mouseDestroy();
3030
3031 return this;
3032 },
3033
3034 _mouseStart: function(event) {
3035 var self = this;
3036
3037 this.opos = [event.pageX, event.pageY];
3038
3039 if (this.options.disabled)
3040 return;
3041
3042 var options = this.options;
3043
3044 this.selectees = $(options.filter, this.element[0]);
3045
3046 this._trigger("start", event);
3047
3048 $(options.appendTo).append(this.helper);
3049 // position helper (lasso)
3050 this.helper.css({
3051 "left": event.clientX,
3052 "top": event.clientY,
3053 "width": 0,
3054 "height": 0
3055 });
3056
3057 if (options.autoRefresh) {
3058 this.refresh();
3059 }
3060
3061 this.selectees.filter('.ui-selected').each(function() {
3062 var selectee = $.data(this, "selectable-item");
3063 selectee.startselected = true;
3064 if (!event.metaKey) {
3065 selectee.$element.removeClass('ui-selected');
3066 selectee.selected = false;
3067 selectee.$element.addClass('ui-unselecting');
3068 selectee.unselecting = true;
3069 // selectable UNSELECTING callback
3070 self._trigger("unselecting", event, {
3071 unselecting: selectee.element
3072 });
3073 }
3074 });
3075
3076 $(event.target).parents().andSelf().each(function() {
3077 var selectee = $.data(this, "selectable-item");
3078 if (selectee) {
3079 var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
3080 selectee.$element
3081 .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3082 .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3083 selectee.unselecting = !doSelect;
3084 selectee.selecting = doSelect;
3085 selectee.selected = doSelect;
3086 // selectable (UN)SELECTING callback
3087 if (doSelect) {
3088 self._trigger("selecting", event, {
3089 selecting: selectee.element
3090 });
3091 } else {
3092 self._trigger("unselecting", event, {
3093 unselecting: selectee.element
3094 });
3095 }
3096 return false;
3097 }
3098 });
3099
3100 },
3101
3102 _mouseDrag: function(event) {
3103 var self = this;
3104 this.dragged = true;
3105
3106 if (this.options.disabled)
3107 return;
3108
3109 var options = this.options;
3110
3111 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3112 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3113 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3114 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3115
3116 this.selectees.each(function() {
3117 var selectee = $.data(this, "selectable-item");
3118 //prevent helper from being selected if appendTo: selectable
3119 if (!selectee || selectee.element == self.element[0])
3120 return;
3121 var hit = false;
3122 if (options.tolerance == 'touch') {
3123 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3124 } else if (options.tolerance == 'fit') {
3125 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3126 }
3127
3128 if (hit) {
3129 // SELECT
3130 if (selectee.selected) {
3131 selectee.$element.removeClass('ui-selected');
3132 selectee.selected = false;
3133 }
3134 if (selectee.unselecting) {
3135 selectee.$element.removeClass('ui-unselecting');
3136 selectee.unselecting = false;
3137 }
3138 if (!selectee.selecting) {
3139 selectee.$element.addClass('ui-selecting');
3140 selectee.selecting = true;
3141 // selectable SELECTING callback
3142 self._trigger("selecting", event, {
3143 selecting: selectee.element
3144 });
3145 }
3146 } else {
3147 // UNSELECT
3148 if (selectee.selecting) {
3149 if (event.metaKey && selectee.startselected) {
3150 selectee.$element.removeClass('ui-selecting');
3151 selectee.selecting = false;
3152 selectee.$element.addClass('ui-selected');
3153 selectee.selected = true;
3154 } else {
3155 selectee.$element.removeClass('ui-selecting');
3156 selectee.selecting = false;
3157 if (selectee.startselected) {
3158 selectee.$element.addClass('ui-unselecting');
3159 selectee.unselecting = true;
3160 }
3161 // selectable UNSELECTING callback
3162 self._trigger("unselecting", event, {
3163 unselecting: selectee.element
3164 });
3165 }
3166 }
3167 if (selectee.selected) {
3168 if (!event.metaKey && !selectee.startselected) {
3169 selectee.$element.removeClass('ui-selected');
3170 selectee.selected = false;
3171
3172 selectee.$element.addClass('ui-unselecting');
3173 selectee.unselecting = true;
3174 // selectable UNSELECTING callback
3175 self._trigger("unselecting", event, {
3176 unselecting: selectee.element
3177 });
3178 }
3179 }
3180 }
3181 });
3182
3183 return false;
3184 },
3185
3186 _mouseStop: function(event) {
3187 var self = this;
3188
3189 this.dragged = false;
3190
3191 var options = this.options;
3192
3193 $('.ui-unselecting', this.element[0]).each(function() {
3194 var selectee = $.data(this, "selectable-item");
3195 selectee.$element.removeClass('ui-unselecting');
3196 selectee.unselecting = false;
3197 selectee.startselected = false;
3198 self._trigger("unselected", event, {
3199 unselected: selectee.element
3200 });
3201 });
3202 $('.ui-selecting', this.element[0]).each(function() {
3203 var selectee = $.data(this, "selectable-item");
3204 selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3205 selectee.selecting = false;
3206 selectee.selected = true;
3207 selectee.startselected = true;
3208 self._trigger("selected", event, {
3209 selected: selectee.element
3210 });
3211 });
3212 this._trigger("stop", event);
3213
3214 this.helper.remove();
3215
3216 return false;
3217 }
3218
3219});
3220
3221$.extend($.ui.selectable, {
3222 version: "1.8.16"
3223});
3224
3225})(jQuery);
3226/*
3227 * jQuery UI Sortable 1.8.16
3228 *
3229 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
3230 * Dual licensed under the MIT or GPL Version 2 licenses.
3231 * http://jquery.org/license
3232 *
3233 * http://docs.jquery.com/UI/Sortables
3234 *
3235 * Depends:
3236 * jquery.ui.core.js
3237 * jquery.ui.mouse.js
3238 * jquery.ui.widget.js
3239 */
3240(function( $, undefined ) {
3241
3242$.widget("ui.sortable", $.ui.mouse, {
3243 widgetEventPrefix: "sort",
3244 options: {
3245 appendTo: "parent",
3246 axis: false,
3247 connectWith: false,
3248 containment: false,
3249 cursor: 'auto',
3250 cursorAt: false,
3251 dropOnEmpty: true,
3252 forcePlaceholderSize: false,
3253 forceHelperSize: false,
3254 grid: false,
3255 handle: false,
3256 helper: "original",
3257 items: '> *',
3258 opacity: false,
3259 placeholder: false,
3260 revert: false,
3261 scroll: true,
3262 scrollSensitivity: 20,
3263 scrollSpeed: 20,
3264 scope: "default",
3265 tolerance: "intersect",
3266 zIndex: 1000
3267 },
3268 _create: function() {
3269
3270 var o = this.options;
3271 this.containerCache = {};
3272 this.element.addClass("ui-sortable");
3273
3274 //Get the items
3275 this.refresh();
3276
3277 //Let's determine if the items are being displayed horizontally
3278 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;
3279
3280 //Let's determine the parent's offset
3281 this.offset = this.element.offset();
3282
3283 //Initialize mouse events for interaction
3284 this._mouseInit();
3285
3286 },
3287
3288 destroy: function() {
3289 this.element
3290 .removeClass("ui-sortable ui-sortable-disabled")
3291 .removeData("sortable")
3292 .unbind(".sortable");
3293 this._mouseDestroy();
3294
3295 for ( var i = this.items.length - 1; i >= 0; i-- )
3296 this.items[i].item.removeData("sortable-item");
3297
3298 return this;
3299 },
3300
3301 _setOption: function(key, value){
3302 if ( key === "disabled" ) {
3303 this.options[ key ] = value;
3304
3305 this.widget()
3306 [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3307 } else {
3308 // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3309 $.Widget.prototype._setOption.apply(this, arguments);
3310 }
3311 },
3312
3313 _mouseCapture: function(event, overrideHandle) {
3314
3315 if (this.reverting) {
3316 return false;
3317 }
3318
3319 if(this.options.disabled || this.options.type == 'static') return false;
3320
3321 //We have to refresh the items data once first
3322 this._refreshItems(event);
3323
3324 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3325 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
3326 if($.data(this, 'sortable-item') == self) {
3327 currentItem = $(this);
3328 return false;
3329 }
3330 });
3331 if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
3332
3333 if(!currentItem) return false;
3334 if(this.options.handle && !overrideHandle) {
3335 var validHandle = false;
3336
3337 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3338 if(!validHandle) return false;
3339 }
3340
3341 this.currentItem = currentItem;
3342 this._removeCurrentsFromItems();
3343 return true;
3344
3345 },
3346
3347 _mouseStart: function(event, overrideHandle, noActivation) {
3348
3349 var o = this.options, self = this;
3350 this.currentContainer = this;
3351
3352 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3353 this.refreshPositions();
3354
3355 //Create and append the visible helper
3356 this.helper = this._createHelper(event);
3357
3358 //Cache the helper size
3359 this._cacheHelperProportions();
3360
3361 /*
3362 * - Position generation -
3363 * This block generates everything position related - it's the core of draggables.
3364 */
3365
3366 //Cache the margins of the original element
3367 this._cacheMargins();
3368
3369 //Get the next scrolling parent
3370 this.scrollParent = this.helper.scrollParent();
3371
3372 //The element's absolute position on the page minus margins
3373 this.offset = this.currentItem.offset();
3374 this.offset = {
3375 top: this.offset.top - this.margins.top,
3376 left: this.offset.left - this.margins.left
3377 };
3378
3379 // Only after we got the offset, we can change the helper's position to absolute
3380 // TODO: Still need to figure out a way to make relative sorting possible
3381 this.helper.css("position", "absolute");
3382 this.cssPosition = this.helper.css("position");
3383
3384 $.extend(this.offset, {
3385 click: { //Where the click happened, relative to the element
3386 left: event.pageX - this.offset.left,
3387 top: event.pageY - this.offset.top
3388 },
3389 parent: this._getParentOffset(),
3390 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3391 });
3392
3393 //Generate the original position
3394 this.originalPosition = this._generatePosition(event);
3395 this.originalPageX = event.pageX;
3396 this.originalPageY = event.pageY;
3397
3398 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3399 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3400
3401 //Cache the former DOM position
3402 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3403
3404 //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
3405 if(this.helper[0] != this.currentItem[0]) {
3406 this.currentItem.hide();
3407 }
3408
3409 //Create the placeholder
3410 this._createPlaceholder();
3411
3412 //Set a containment if given in the options
3413 if(o.containment)
3414 this._setContainment();
3415
3416 if(o.cursor) { // cursor option
3417 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3418 $('body').css("cursor", o.cursor);
3419 }
3420
3421 if(o.opacity) { // opacity option
3422 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3423 this.helper.css("opacity", o.opacity);
3424 }
3425
3426 if(o.zIndex) { // zIndex option
3427 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3428 this.helper.css("zIndex", o.zIndex);
3429 }
3430
3431 //Prepare scrolling
3432 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3433 this.overflowOffset = this.scrollParent.offset();
3434
3435 //Call callbacks
3436 this._trigger("start", event, this._uiHash());
3437
3438 //Recache the helper size
3439 if(!this._preserveHelperProportions)
3440 this._cacheHelperProportions();
3441
3442
3443 //Post 'activate' events to possible containers
3444 if(!noActivation) {
3445 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3446 }
3447
3448 //Prepare possible droppables
3449 if($.ui.ddmanager)
3450 $.ui.ddmanager.current = this;
3451
3452 if ($.ui.ddmanager && !o.dropBehaviour)
3453 $.ui.ddmanager.prepareOffsets(this, event);
3454
3455 this.dragging = true;
3456
3457 this.helper.addClass("ui-sortable-helper");
3458 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3459 return true;
3460
3461 },
3462
3463 _mouseDrag: function(event) {
3464
3465 //Compute the helpers position
3466 this.position = this._generatePosition(event);
3467 this.positionAbs = this._convertPositionTo("absolute");
3468
3469 if (!this.lastPositionAbs) {
3470 this.lastPositionAbs = this.positionAbs;
3471 }
3472
3473 //Do scrolling
3474 if(this.options.scroll) {
3475 var o = this.options, scrolled = false;
3476 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3477
3478 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3479 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3480 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3481 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3482
3483 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3484 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3485 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3486 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3487
3488 } else {
3489
3490 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3491 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3492 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3493 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3494
3495 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3496 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3497 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3498 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3499
3500 }
3501
3502 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3503 $.ui.ddmanager.prepareOffsets(this, event);
3504 }
3505
3506 //Regenerate the absolute position used for position checks
3507 this.positionAbs = this._convertPositionTo("absolute");
3508
3509 //Set the helper position
3510 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3511 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3512
3513 //Rearrange
3514 for (var i = this.items.length - 1; i >= 0; i--) {
3515
3516 //Cache variables and intersection, continue if no intersection
3517 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3518 if (!intersection) continue;
3519
3520 if(itemElement != this.currentItem[0] //cannot intersect with itself
3521 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3522 && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3523 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3524 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3525 ) {
3526
3527 this.direction = intersection == 1 ? "down" : "up";
3528
3529 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3530 this._rearrange(event, item);
3531 } else {
3532 break;
3533 }
3534
3535 this._trigger("change", event, this._uiHash());
3536 break;
3537 }
3538 }
3539
3540 //Post events to containers
3541 this._contactContainers(event);
3542
3543 //Interconnect with droppables
3544 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3545
3546 //Call callbacks
3547 this._trigger('sort', event, this._uiHash());
3548
3549 this.lastPositionAbs = this.positionAbs;
3550 return false;
3551
3552 },
3553
3554 _mouseStop: function(event, noPropagation) {
3555
3556 if(!event) return;
3557
3558 //If we are using droppables, inform the manager about the drop
3559 if ($.ui.ddmanager && !this.options.dropBehaviour)
3560 $.ui.ddmanager.drop(this, event);
3561
3562 if(this.options.revert) {
3563 var self = this;
3564 var cur = self.placeholder.offset();
3565
3566 self.reverting = true;
3567
3568 $(this.helper).animate({
3569 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3570 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3571 }, parseInt(this.options.revert, 10) || 500, function() {
3572 self._clear(event);
3573 });
3574 } else {
3575 this._clear(event, noPropagation);
3576 }
3577
3578 return false;
3579
3580 },
3581
3582 cancel: function() {
3583
3584 var self = this;
3585
3586 if(this.dragging) {
3587
3588 this._mouseUp({ target: null });
3589
3590 if(this.options.helper == "original")
3591 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3592 else
3593 this.currentItem.show();
3594
3595 //Post deactivating events to containers
3596 for (var i = this.containers.length - 1; i >= 0; i--){
3597 this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3598 if(this.containers[i].containerCache.over) {
3599 this.containers[i]._trigger("out", null, self._uiHash(this));
3600 this.containers[i].containerCache.over = 0;
3601 }
3602 }
3603
3604 }
3605
3606 if (this.placeholder) {
3607 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3608 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3609 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3610
3611 $.extend(this, {
3612 helper: null,
3613 dragging: false,
3614 reverting: false,
3615 _noFinalSort: null
3616 });
3617
3618 if(this.domPosition.prev) {
3619 $(this.domPosition.prev).after(this.currentItem);
3620 } else {
3621 $(this.domPosition.parent).prepend(this.currentItem);
3622 }
3623 }
3624
3625 return this;
3626
3627 },
3628
3629 serialize: function(o) {
3630
3631 var items = this._getItemsAsjQuery(o && o.connected);
3632 var str = []; o = o || {};
3633
3634 $(items).each(function() {
3635 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3636 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3637 });
3638
3639 if(!str.length && o.key) {
3640 str.push(o.key + '=');
3641 }
3642
3643 return str.join('&');
3644
3645 },
3646
3647 toArray: function(o) {
3648
3649 var items = this._getItemsAsjQuery(o && o.connected);
3650 var ret = []; o = o || {};
3651
3652 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3653 return ret;
3654
3655 },
3656
3657 /* Be careful with the following core functions */
3658 _intersectsWith: function(item) {
3659
3660 var x1 = this.positionAbs.left,
3661 x2 = x1 + this.helperProportions.width,
3662 y1 = this.positionAbs.top,
3663 y2 = y1 + this.helperProportions.height;
3664
3665 var l = item.left,
3666 r = l + item.width,
3667 t = item.top,
3668 b = t + item.height;
3669
3670 var dyClick = this.offset.click.top,
3671 dxClick = this.offset.click.left;
3672
3673 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3674
3675 if( this.options.tolerance == "pointer"
3676 || this.options.forcePointerForContainers
3677 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3678 ) {
3679 return isOverElement;
3680 } else {
3681
3682 return (l < x1 + (this.helperProportions.width / 2) // Right Half
3683 && x2 - (this.helperProportions.width / 2) < r // Left Half
3684 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3685 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
3686
3687 }
3688 },
3689
3690 _intersectsWithPointer: function(item) {
3691
3692 var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3693 isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3694 isOverElement = isOverElementHeight && isOverElementWidth,
3695 verticalDirection = this._getDragVerticalDirection(),
3696 horizontalDirection = this._getDragHorizontalDirection();
3697
3698 if (!isOverElement)
3699 return false;
3700
3701 return this.floating ?
3702 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3703 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3704
3705 },
3706
3707 _intersectsWithSides: function(item) {
3708
3709 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3710 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3711 verticalDirection = this._getDragVerticalDirection(),
3712 horizontalDirection = this._getDragHorizontalDirection();
3713
3714 if (this.floating && horizontalDirection) {
3715 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3716 } else {
3717 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3718 }
3719
3720 },
3721
3722 _getDragVerticalDirection: function() {
3723 var delta = this.positionAbs.top - this.lastPositionAbs.top;
3724 return delta != 0 && (delta > 0 ? "down" : "up");
3725 },
3726
3727 _getDragHorizontalDirection: function() {
3728 var delta = this.positionAbs.left - this.lastPositionAbs.left;
3729 return delta != 0 && (delta > 0 ? "right" : "left");
3730 },
3731
3732 refresh: function(event) {
3733 this._refreshItems(event);
3734 this.refreshPositions();
3735 return this;
3736 },
3737
3738 _connectWith: function() {
3739 var options = this.options;
3740 return options.connectWith.constructor == String
3741 ? [options.connectWith]
3742 : options.connectWith;
3743 },
3744
3745 _getItemsAsjQuery: function(connected) {
3746
3747 var self = this;
3748 var items = [];
3749 var queries = [];
3750 var connectWith = this._connectWith();
3751
3752 if(connectWith && connected) {
3753 for (var i = connectWith.length - 1; i >= 0; i--){
3754 var cur = $(connectWith[i]);
3755 for (var j = cur.length - 1; j >= 0; j--){
3756 var inst = $.data(cur[j], 'sortable');
3757 if(inst && inst != this && !inst.options.disabled) {
3758 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]);
3759 }
3760 };
3761 };
3762 }
3763
3764 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]);
3765
3766 for (var i = queries.length - 1; i >= 0; i--){
3767 queries[i][0].each(function() {
3768 items.push(this);
3769 });
3770 };
3771
3772 return $(items);
3773
3774 },
3775
3776 _removeCurrentsFromItems: function() {
3777
3778 var list = this.currentItem.find(":data(sortable-item)");
3779
3780 for (var i=0; i < this.items.length; i++) {
3781
3782 for (var j=0; j < list.length; j++) {
3783 if(list[j] == this.items[i].item[0])
3784 this.items.splice(i,1);
3785 };
3786
3787 };
3788
3789 },
3790
3791 _refreshItems: function(event) {
3792
3793 this.items = [];
3794 this.containers = [this];
3795 var items = this.items;
3796 var self = this;
3797 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3798 var connectWith = this._connectWith();
3799
3800 if(connectWith) {
3801 for (var i = connectWith.length - 1; i >= 0; i--){
3802 var cur = $(connectWith[i]);
3803 for (var j = cur.length - 1; j >= 0; j--){
3804 var inst = $.data(cur[j], 'sortable');
3805 if(inst && inst != this && !inst.options.disabled) {
3806 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3807 this.containers.push(inst);
3808 }
3809 };
3810 };
3811 }
3812
3813 for (var i = queries.length - 1; i >= 0; i--) {
3814 var targetData = queries[i][1];
3815 var _queries = queries[i][0];
3816
3817 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3818 var item = $(_queries[j]);
3819
3820 item.data('sortable-item', targetData); // Data for target checking (mouse manager)
3821
3822 items.push({
3823 item: item,
3824 instance: targetData,
3825 width: 0, height: 0,
3826 left: 0, top: 0
3827 });
3828 };
3829 };
3830
3831 },
3832
3833 refreshPositions: function(fast) {
3834
3835 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3836 if(this.offsetParent && this.helper) {
3837 this.offset.parent = this._getParentOffset();
3838 }
3839
3840 for (var i = this.items.length - 1; i >= 0; i--){
3841 var item = this.items[i];
3842
3843 //We ignore calculating positions of all connected containers when we're not over them
3844 if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3845 continue;
3846
3847 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3848
3849 if (!fast) {
3850 item.width = t.outerWidth();
3851 item.height = t.outerHeight();
3852 }
3853
3854 var p = t.offset();
3855 item.left = p.left;
3856 item.top = p.top;
3857 };
3858
3859 if(this.options.custom && this.options.custom.refreshContainers) {
3860 this.options.custom.refreshContainers.call(this);
3861 } else {
3862 for (var i = this.containers.length - 1; i >= 0; i--){
3863 var p = this.containers[i].element.offset();
3864 this.containers[i].containerCache.left = p.left;
3865 this.containers[i].containerCache.top = p.top;
3866 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3867 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3868 };
3869 }
3870
3871 return this;
3872 },
3873
3874 _createPlaceholder: function(that) {
3875
3876 var self = that || this, o = self.options;
3877
3878 if(!o.placeholder || o.placeholder.constructor == String) {
3879 var className = o.placeholder;
3880 o.placeholder = {
3881 element: function() {
3882
3883 var el = $(document.createElement(self.currentItem[0].nodeName))
3884 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3885 .removeClass("ui-sortable-helper")[0];
3886
3887 if(!className)
3888 el.style.visibility = "hidden";
3889
3890 return el;
3891 },
3892 update: function(container, p) {
3893
3894 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3895 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3896 if(className && !o.forcePlaceholderSize) return;
3897
3898 //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
3899 if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3900 if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3901 }
3902 };
3903 }
3904
3905 //Create the placeholder
3906 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3907
3908 //Append it after the actual current item
3909 self.currentItem.after(self.placeholder);
3910
3911 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3912 o.placeholder.update(self, self.placeholder);
3913
3914 },
3915
3916 _contactContainers: function(event) {
3917
3918 // get innermost container that intersects with item
3919 var innermostContainer = null, innermostIndex = null;
3920
3921
3922 for (var i = this.containers.length - 1; i >= 0; i--){
3923
3924 // never consider a container that's located within the item itself
3925 if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3926 continue;
3927
3928 if(this._intersectsWith(this.containers[i].containerCache)) {
3929
3930 // if we've already found a container and it's more "inner" than this, then continue
3931 if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3932 continue;
3933
3934 innermostContainer = this.containers[i];
3935 innermostIndex = i;
3936
3937 } else {
3938 // container doesn't intersect. trigger "out" event if necessary
3939 if(this.containers[i].containerCache.over) {
3940 this.containers[i]._trigger("out", event, this._uiHash(this));
3941 this.containers[i].containerCache.over = 0;
3942 }
3943 }
3944
3945 }
3946
3947 // if no intersecting containers found, return
3948 if(!innermostContainer) return;
3949
3950 // move the item into the container if it's not there already
3951 if(this.containers.length === 1) {
3952 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3953 this.containers[innermostIndex].containerCache.over = 1;
3954 } else if(this.currentContainer != this.containers[innermostIndex]) {
3955
3956 //When entering a new container, we will find the item with the least distance and append our item near it
3957 var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
3958 for (var j = this.items.length - 1; j >= 0; j--) {
3959 if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
3960 var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
3961 if(Math.abs(cur - base) < dist) {
3962 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3963 }
3964 }
3965
3966 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
3967 return;
3968
3969 this.currentContainer = this.containers[innermostIndex];
3970 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
3971 this._trigger("change", event, this._uiHash());
3972 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
3973
3974 //Update the placeholder
3975 this.options.placeholder.update(this.currentContainer, this.placeholder);
3976
3977 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3978 this.containers[innermostIndex].containerCache.over = 1;
3979 }
3980
3981
3982 },
3983
3984 _createHelper: function(event) {
3985
3986 var o = this.options;
3987 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3988
3989 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3990 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3991
3992 if(helper[0] == this.currentItem[0])
3993 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") };
3994
3995 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3996 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3997
3998 return helper;
3999
4000 },
4001
4002 _adjustOffsetFromHelper: function(obj) {
4003 if (typeof obj == 'string') {
4004 obj = obj.split(' ');
4005 }
4006 if ($.isArray(obj)) {
4007 obj = {left: +obj[0], top: +obj[1] || 0};
4008 }
4009 if ('left' in obj) {
4010 this.offset.click.left = obj.left + this.margins.left;
4011 }
4012 if ('right' in obj) {
4013 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4014 }
4015 if ('top' in obj) {
4016 this.offset.click.top = obj.top + this.margins.top;
4017 }
4018 if ('bottom' in obj) {
4019 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4020 }
4021 },
4022
4023 _getParentOffset: function() {
4024
4025
4026 //Get the offsetParent and cache its position
4027 this.offsetParent = this.helper.offsetParent();
4028 var po = this.offsetParent.offset();
4029
4030 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4031 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4032 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4033 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4034 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
4035 po.left += this.scrollParent.scrollLeft();
4036 po.top += this.scrollParent.scrollTop();
4037 }
4038
4039 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4040 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
4041 po = { top: 0, left: 0 };
4042
4043 return {
4044 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4045 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4046 };
4047
4048 },
4049
4050 _getRelativeOffset: function() {
4051
4052 if(this.cssPosition == "relative") {
4053 var p = this.currentItem.position();
4054 return {
4055 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4056 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4057 };
4058 } else {
4059 return { top: 0, left: 0 };
4060 }
4061
4062 },
4063
4064 _cacheMargins: function() {
4065 this.margins = {
4066 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4067 top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4068 };
4069 },
4070
4071 _cacheHelperProportions: function() {
4072 this.helperProportions = {
4073 width: this.helper.outerWidth(),
4074 height: this.helper.outerHeight()
4075 };
4076 },
4077
4078 _setContainment: function() {
4079
4080 var o = this.options;
4081 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4082 if(o.containment == 'document' || o.containment == 'window') this.containment = [
4083 0 - this.offset.relative.left - this.offset.parent.left,
4084 0 - this.offset.relative.top - this.offset.parent.top,
4085 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4086 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4087 ];
4088
4089 if(!(/^(document|window|parent)$/).test(o.containment)) {
4090 var ce = $(o.containment)[0];
4091 var co = $(o.containment).offset();
4092 var over = ($(ce).css("overflow") != 'hidden');
4093
4094 this.containment = [
4095 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4096 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4097 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,
4098 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
4099 ];
4100 }
4101
4102 },
4103
4104 _convertPositionTo: function(d, pos) {
4105
4106 if(!pos) pos = this.position;
4107 var mod = d == "absolute" ? 1 : -1;
4108 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);
4109
4110 return {
4111 top: (
4112 pos.top // The absolute mouse position
4113 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
4114 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
4115 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4116 ),
4117 left: (
4118 pos.left // The absolute mouse position
4119 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
4120 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
4121 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4122 )
4123 };
4124
4125 },
4126
4127 _generatePosition: function(event) {
4128
4129 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);
4130
4131 // This is another very weird special case that only happens for relative elements:
4132 // 1. If the css position is relative
4133 // 2. and the scroll parent is the document or similar to the offset parent
4134 // we have to refresh the relative offset during the scroll so there are no jumps
4135 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4136 this.offset.relative = this._getRelativeOffset();
4137 }
4138
4139 var pageX = event.pageX;
4140 var pageY = event.pageY;
4141
4142 /*
4143 * - Position constraining -
4144 * Constrain the position to a mix of grid, containment.
4145 */
4146
4147 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4148
4149 if(this.containment) {
4150 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4151 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4152 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4153 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4154 }
4155
4156 if(o.grid) {
4157 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4158 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;
4159
4160 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4161 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;
4162 }
4163
4164 }
4165
4166 return {
4167 top: (
4168 pageY // The absolute mouse position
4169 - this.offset.click.top // Click offset (relative to the element)
4170 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
4171 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
4172 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4173 ),
4174 left: (
4175 pageX // The absolute mouse position
4176 - this.offset.click.left // Click offset (relative to the element)
4177 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
4178 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
4179 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4180 )
4181 };
4182
4183 },
4184
4185 _rearrange: function(event, i, a, hardRefresh) {
4186
4187 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));
4188
4189 //Various things done here to improve the performance:
4190 // 1. we create a setTimeout, that calls refreshPositions
4191 // 2. on the instance, we have a counter variable, that get's higher after every append
4192 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4193 // 4. this lets only the last addition to the timeout stack through
4194 this.counter = this.counter ? ++this.counter : 1;
4195 var self = this, counter = this.counter;
4196
4197 window.setTimeout(function() {
4198 if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4199 },0);
4200
4201 },
4202
4203 _clear: function(event, noPropagation) {
4204
4205 this.reverting = false;
4206 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4207 // everything else normalized again
4208 var delayedTriggers = [], self = this;
4209
4210 // We first have to update the dom position of the actual currentItem
4211 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4212 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4213 this._noFinalSort = null;
4214
4215 if(this.helper[0] == this.currentItem[0]) {
4216 for(var i in this._storedCSS) {
4217 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4218 }
4219 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4220 } else {
4221 this.currentItem.show();
4222 }
4223
4224 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4225 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
4226 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
4227 if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4228 for (var i = this.containers.length - 1; i >= 0; i--){
4229 if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
4230 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4231 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4232 }
4233 };
4234 };
4235
4236 //Post events to containers
4237 for (var i = this.containers.length - 1; i >= 0; i--){
4238 if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4239 if(this.containers[i].containerCache.over) {
4240 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4241 this.containers[i].containerCache.over = 0;
4242 }
4243 }
4244
4245 //Do what was originally in plugins
4246 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4247 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4248 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4249
4250 this.dragging = false;
4251 if(this.cancelHelperRemoval) {
4252 if(!noPropagation) {
4253 this._trigger("beforeStop", event, this._uiHash());
4254 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4255 this._trigger("stop", event, this._uiHash());
4256 }
4257 return false;
4258 }
4259
4260 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4261
4262 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4263 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4264
4265 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4266
4267 if(!noPropagation) {
4268 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4269 this._trigger("stop", event, this._uiHash());
4270 }
4271
4272 this.fromOutside = false;
4273 return true;
4274
4275 },
4276
4277 _trigger: function() {
4278 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4279 this.cancel();
4280 }
4281 },
4282
4283 _uiHash: function(inst) {
4284 var self = inst || this;
4285 return {
4286 helper: self.helper,
4287 placeholder: self.placeholder || $([]),
4288 position: self.position,
4289 originalPosition: self.originalPosition,
4290 offset: self.positionAbs,
4291 item: self.currentItem,
4292 sender: inst ? inst.element : null
4293 };
4294 }
4295
4296});
4297
4298$.extend($.ui.sortable, {
4299 version: "1.8.16"
4300});
4301
4302})(jQuery);
4303/*
4304 * jQuery UI Accordion 1.8.16
4305 *
4306 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4307 * Dual licensed under the MIT or GPL Version 2 licenses.
4308 * http://jquery.org/license
4309 *
4310 * http://docs.jquery.com/UI/Accordion
4311 *
4312 * Depends:
4313 * jquery.ui.core.js
4314 * jquery.ui.widget.js
4315 */
4316(function( $, undefined ) {
4317
4318$.widget( "ui.accordion", {
4319 options: {
4320 active: 0,
4321 animated: "slide",
4322 autoHeight: true,
4323 clearStyle: false,
4324 collapsible: false,
4325 event: "click",
4326 fillSpace: false,
4327 header: "> li > :first-child,> :not(li):even",
4328 icons: {
4329 header: "ui-icon-triangle-1-e",
4330 headerSelected: "ui-icon-triangle-1-s"
4331 },
4332 navigation: false,
4333 navigationFilter: function() {
4334 return this.href.toLowerCase() === location.href.toLowerCase();
4335 }
4336 },
4337
4338 _create: function() {
4339 var self = this,
4340 options = self.options;
4341
4342 self.running = 0;
4343
4344 self.element
4345 .addClass( "ui-accordion ui-widget ui-helper-reset" )
4346 // in lack of child-selectors in CSS
4347 // we need to mark top-LIs in a UL-accordion for some IE-fix
4348 .children( "li" )
4349 .addClass( "ui-accordion-li-fix" );
4350
4351 self.headers = self.element.find( options.header )
4352 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
4353 .bind( "mouseenter.accordion", function() {
4354 if ( options.disabled ) {
4355 return;
4356 }
4357 $( this ).addClass( "ui-state-hover" );
4358 })
4359 .bind( "mouseleave.accordion", function() {
4360 if ( options.disabled ) {
4361 return;
4362 }
4363 $( this ).removeClass( "ui-state-hover" );
4364 })
4365 .bind( "focus.accordion", function() {
4366 if ( options.disabled ) {
4367 return;
4368 }
4369 $( this ).addClass( "ui-state-focus" );
4370 })
4371 .bind( "blur.accordion", function() {
4372 if ( options.disabled ) {
4373 return;
4374 }
4375 $( this ).removeClass( "ui-state-focus" );
4376 });
4377
4378 self.headers.next()
4379 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
4380
4381 if ( options.navigation ) {
4382 var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
4383 if ( current.length ) {
4384 var header = current.closest( ".ui-accordion-header" );
4385 if ( header.length ) {
4386 // anchor within header
4387 self.active = header;
4388 } else {
4389 // anchor within content
4390 self.active = current.closest( ".ui-accordion-content" ).prev();
4391 }
4392 }
4393 }
4394
4395 self.active = self._findActive( self.active || options.active )
4396 .addClass( "ui-state-default ui-state-active" )
4397 .toggleClass( "ui-corner-all" )
4398 .toggleClass( "ui-corner-top" );
4399 self.active.next().addClass( "ui-accordion-content-active" );
4400
4401 self._createIcons();
4402 self.resize();
4403
4404 // ARIA
4405 self.element.attr( "role", "tablist" );
4406
4407 self.headers
4408 .attr( "role", "tab" )
4409 .bind( "keydown.accordion", function( event ) {
4410 return self._keydown( event );
4411 })
4412 .next()
4413 .attr( "role", "tabpanel" );
4414
4415 self.headers
4416 .not( self.active || "" )
4417 .attr({
4418 "aria-expanded": "false",
4419 "aria-selected": "false",
4420 tabIndex: -1
4421 })
4422 .next()
4423 .hide();
4424
4425 // make sure at least one header is in the tab order
4426 if ( !self.active.length ) {
4427 self.headers.eq( 0 ).attr( "tabIndex", 0 );
4428 } else {
4429 self.active
4430 .attr({
4431 "aria-expanded": "true",
4432 "aria-selected": "true",
4433 tabIndex: 0
4434 });
4435 }
4436
4437 // only need links in tab order for Safari
4438 if ( !$.browser.safari ) {
4439 self.headers.find( "a" ).attr( "tabIndex", -1 );
4440 }
4441
4442 if ( options.event ) {
4443 self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
4444 self._clickHandler.call( self, event, this );
4445 event.preventDefault();
4446 });
4447 }
4448 },
4449
4450 _createIcons: function() {
4451 var options = this.options;
4452 if ( options.icons ) {
4453 $( "<span></span>" )
4454 .addClass( "ui-icon " + options.icons.header )
4455 .prependTo( this.headers );
4456 this.active.children( ".ui-icon" )
4457 .toggleClass(options.icons.header)
4458 .toggleClass(options.icons.headerSelected);
4459 this.element.addClass( "ui-accordion-icons" );
4460 }
4461 },
4462
4463 _destroyIcons: function() {
4464 this.headers.children( ".ui-icon" ).remove();
4465 this.element.removeClass( "ui-accordion-icons" );
4466 },
4467
4468 destroy: function() {
4469 var options = this.options;
4470
4471 this.element
4472 .removeClass( "ui-accordion ui-widget ui-helper-reset" )
4473 .removeAttr( "role" );
4474
4475 this.headers
4476 .unbind( ".accordion" )
4477 .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" )
4478 .removeAttr( "role" )
4479 .removeAttr( "aria-expanded" )
4480 .removeAttr( "aria-selected" )
4481 .removeAttr( "tabIndex" );
4482
4483 this.headers.find( "a" ).removeAttr( "tabIndex" );
4484 this._destroyIcons();
4485 var contents = this.headers.next()
4486 .css( "display", "" )
4487 .removeAttr( "role" )
4488 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
4489 if ( options.autoHeight || options.fillHeight ) {
4490 contents.css( "height", "" );
4491 }
4492
4493 return $.Widget.prototype.destroy.call( this );
4494 },
4495
4496 _setOption: function( key, value ) {
4497 $.Widget.prototype._setOption.apply( this, arguments );
4498
4499 if ( key == "active" ) {
4500 this.activate( value );
4501 }
4502 if ( key == "icons" ) {
4503 this._destroyIcons();
4504 if ( value ) {
4505 this._createIcons();
4506 }
4507 }
4508 // #5332 - opacity doesn't cascade to positioned elements in IE
4509 // so we need to add the disabled class to the headers and panels
4510 if ( key == "disabled" ) {
4511 this.headers.add(this.headers.next())
4512 [ value ? "addClass" : "removeClass" ](
4513 "ui-accordion-disabled ui-state-disabled" );
4514 }
4515 },
4516
4517 _keydown: function( event ) {
4518 if ( this.options.disabled || event.altKey || event.ctrlKey ) {
4519 return;
4520 }
4521
4522 var keyCode = $.ui.keyCode,
4523 length = this.headers.length,
4524 currentIndex = this.headers.index( event.target ),
4525 toFocus = false;
4526
4527 switch ( event.keyCode ) {
4528 case keyCode.RIGHT:
4529 case keyCode.DOWN:
4530 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4531 break;
4532 case keyCode.LEFT:
4533 case keyCode.UP:
4534 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4535 break;
4536 case keyCode.SPACE:
4537 case keyCode.ENTER:
4538 this._clickHandler( { target: event.target }, event.target );
4539 event.preventDefault();
4540 }
4541
4542 if ( toFocus ) {
4543 $( event.target ).attr( "tabIndex", -1 );
4544 $( toFocus ).attr( "tabIndex", 0 );
4545 toFocus.focus();
4546 return false;
4547 }
4548
4549 return true;
4550 },
4551
4552 resize: function() {
4553 var options = this.options,
4554 maxHeight;
4555
4556 if ( options.fillSpace ) {
4557 if ( $.browser.msie ) {
4558 var defOverflow = this.element.parent().css( "overflow" );
4559 this.element.parent().css( "overflow", "hidden");
4560 }
4561 maxHeight = this.element.parent().height();
4562 if ($.browser.msie) {
4563 this.element.parent().css( "overflow", defOverflow );
4564 }
4565
4566 this.headers.each(function() {
4567 maxHeight -= $( this ).outerHeight( true );
4568 });
4569
4570 this.headers.next()
4571 .each(function() {
4572 $( this ).height( Math.max( 0, maxHeight -
4573 $( this ).innerHeight() + $( this ).height() ) );
4574 })
4575 .css( "overflow", "auto" );
4576 } else if ( options.autoHeight ) {
4577 maxHeight = 0;
4578 this.headers.next()
4579 .each(function() {
4580 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
4581 })
4582 .height( maxHeight );
4583 }
4584
4585 return this;
4586 },
4587
4588 activate: function( index ) {
4589 // TODO this gets called on init, changing the option without an explicit call for that
4590 this.options.active = index;
4591 // call clickHandler with custom event
4592 var active = this._findActive( index )[ 0 ];
4593 this._clickHandler( { target: active }, active );
4594
4595 return this;
4596 },
4597
4598 _findActive: function( selector ) {
4599 return selector
4600 ? typeof selector === "number"
4601 ? this.headers.filter( ":eq(" + selector + ")" )
4602 : this.headers.not( this.headers.not( selector ) )
4603 : selector === false
4604 ? $( [] )
4605 : this.headers.filter( ":eq(0)" );
4606 },
4607
4608 // TODO isn't event.target enough? why the separate target argument?
4609 _clickHandler: function( event, target ) {
4610 var options = this.options;
4611 if ( options.disabled ) {
4612 return;
4613 }
4614
4615 // called only when using activate(false) to close all parts programmatically
4616 if ( !event.target ) {
4617 if ( !options.collapsible ) {
4618 return;
4619 }
4620 this.active
4621 .removeClass( "ui-state-active ui-corner-top" )
4622 .addClass( "ui-state-default ui-corner-all" )
4623 .children( ".ui-icon" )
4624 .removeClass( options.icons.headerSelected )
4625 .addClass( options.icons.header );
4626 this.active.next().addClass( "ui-accordion-content-active" );
4627 var toHide = this.active.next(),
4628 data = {
4629 options: options,
4630 newHeader: $( [] ),
4631 oldHeader: options.active,
4632 newContent: $( [] ),
4633 oldContent: toHide
4634 },
4635 toShow = ( this.active = $( [] ) );
4636 this._toggle( toShow, toHide, data );
4637 return;
4638 }
4639
4640 // get the click target
4641 var clicked = $( event.currentTarget || target ),
4642 clickedIsActive = clicked[0] === this.active[0];
4643
4644 // TODO the option is changed, is that correct?
4645 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
4646 options.active = options.collapsible && clickedIsActive ?
4647 false :
4648 this.headers.index( clicked );
4649
4650 // if animations are still active, or the active header is the target, ignore click
4651 if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
4652 return;
4653 }
4654
4655 // find elements to show and hide
4656 var active = this.active,
4657 toShow = clicked.next(),
4658 toHide = this.active.next(),
4659 data = {
4660 options: options,
4661 newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
4662 oldHeader: this.active,
4663 newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
4664 oldContent: toHide
4665 },
4666 down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
4667
4668 // when the call to ._toggle() comes after the class changes
4669 // it causes a very odd bug in IE 8 (see #6720)
4670 this.active = clickedIsActive ? $([]) : clicked;
4671 this._toggle( toShow, toHide, data, clickedIsActive, down );
4672
4673 // switch classes
4674 active
4675 .removeClass( "ui-state-active ui-corner-top" )
4676 .addClass( "ui-state-default ui-corner-all" )
4677 .children( ".ui-icon" )
4678 .removeClass( options.icons.headerSelected )
4679 .addClass( options.icons.header );
4680 if ( !clickedIsActive ) {
4681 clicked
4682 .removeClass( "ui-state-default ui-corner-all" )
4683 .addClass( "ui-state-active ui-corner-top" )
4684 .children( ".ui-icon" )
4685 .removeClass( options.icons.header )
4686 .addClass( options.icons.headerSelected );
4687 clicked
4688 .next()
4689 .addClass( "ui-accordion-content-active" );
4690 }
4691
4692 return;
4693 },
4694
4695 _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
4696 var self = this,
4697 options = self.options;
4698
4699 self.toShow = toShow;
4700 self.toHide = toHide;
4701 self.data = data;
4702
4703 var complete = function() {
4704 if ( !self ) {
4705 return;
4706 }
4707 return self._completed.apply( self, arguments );
4708 };
4709
4710 // trigger changestart event
4711 self._trigger( "changestart", null, self.data );
4712
4713 // count elements to animate
4714 self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
4715
4716 if ( options.animated ) {
4717 var animOptions = {};
4718
4719 if ( options.collapsible && clickedIsActive ) {
4720 animOptions = {
4721 toShow: $( [] ),
4722 toHide: toHide,
4723 complete: complete,
4724 down: down,
4725 autoHeight: options.autoHeight || options.fillSpace
4726 };
4727 } else {
4728 animOptions = {
4729 toShow: toShow,
4730 toHide: toHide,
4731 complete: complete,
4732 down: down,
4733 autoHeight: options.autoHeight || options.fillSpace
4734 };
4735 }
4736
4737 if ( !options.proxied ) {
4738 options.proxied = options.animated;
4739 }
4740
4741 if ( !options.proxiedDuration ) {
4742 options.proxiedDuration = options.duration;
4743 }
4744
4745 options.animated = $.isFunction( options.proxied ) ?
4746 options.proxied( animOptions ) :
4747 options.proxied;
4748
4749 options.duration = $.isFunction( options.proxiedDuration ) ?
4750 options.proxiedDuration( animOptions ) :
4751 options.proxiedDuration;
4752
4753 var animations = $.ui.accordion.animations,
4754 duration = options.duration,
4755 easing = options.animated;
4756
4757 if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
4758 easing = "slide";
4759 }
4760 if ( !animations[ easing ] ) {
4761 animations[ easing ] = function( options ) {
4762 this.slide( options, {
4763 easing: easing,
4764 duration: duration || 700
4765 });
4766 };
4767 }
4768
4769 animations[ easing ]( animOptions );
4770 } else {
4771 if ( options.collapsible && clickedIsActive ) {
4772 toShow.toggle();
4773 } else {
4774 toHide.hide();
4775 toShow.show();
4776 }
4777
4778 complete( true );
4779 }
4780
4781 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
4782 toHide.prev()
4783 .attr({
4784 "aria-expanded": "false",
4785 "aria-selected": "false",
4786 tabIndex: -1
4787 })
4788 .blur();
4789 toShow.prev()
4790 .attr({
4791 "aria-expanded": "true",
4792 "aria-selected": "true",
4793 tabIndex: 0
4794 })
4795 .focus();
4796 },
4797
4798 _completed: function( cancel ) {
4799 this.running = cancel ? 0 : --this.running;
4800 if ( this.running ) {
4801 return;
4802 }
4803
4804 if ( this.options.clearStyle ) {
4805 this.toShow.add( this.toHide ).css({
4806 height: "",
4807 overflow: ""
4808 });
4809 }
4810
4811 // other classes are removed before the animation; this one needs to stay until completed
4812 this.toHide.removeClass( "ui-accordion-content-active" );
4813 // Work around for rendering bug in IE (#5421)
4814 if ( this.toHide.length ) {
4815 this.toHide.parent()[0].className = this.toHide.parent()[0].className;
4816 }
4817
4818 this._trigger( "change", null, this.data );
4819 }
4820});
4821
4822$.extend( $.ui.accordion, {
4823 version: "1.8.16",
4824 animations: {
4825 slide: function( options, additions ) {
4826 options = $.extend({
4827 easing: "swing",
4828 duration: 300
4829 }, options, additions );
4830 if ( !options.toHide.size() ) {
4831 options.toShow.animate({
4832 height: "show",
4833 paddingTop: "show",
4834 paddingBottom: "show"
4835 }, options );
4836 return;
4837 }
4838 if ( !options.toShow.size() ) {
4839 options.toHide.animate({
4840 height: "hide",
4841 paddingTop: "hide",
4842 paddingBottom: "hide"
4843 }, options );
4844 return;
4845 }
4846 var overflow = options.toShow.css( "overflow" ),
4847 percentDone = 0,
4848 showProps = {},
4849 hideProps = {},
4850 fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
4851 originalWidth;
4852 // fix width before calculating height of hidden element
4853 var s = options.toShow;
4854 originalWidth = s[0].style.width;
4855 s.width( parseInt( s.parent().width(), 10 )
4856 - parseInt( s.css( "paddingLeft" ), 10 )
4857 - parseInt( s.css( "paddingRight" ), 10 )
4858 - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
4859 - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
4860
4861 $.each( fxAttrs, function( i, prop ) {
4862 hideProps[ prop ] = "hide";
4863
4864 var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
4865 showProps[ prop ] = {
4866 value: parts[ 1 ],
4867 unit: parts[ 2 ] || "px"
4868 };
4869 });
4870 options.toShow.css({ height: 0, overflow: "hidden" }).show();
4871 options.toHide
4872 .filter( ":hidden" )
4873 .each( options.complete )
4874 .end()
4875 .filter( ":visible" )
4876 .animate( hideProps, {
4877 step: function( now, settings ) {
4878 // only calculate the percent when animating height
4879 // IE gets very inconsistent results when animating elements
4880 // with small values, which is common for padding
4881 if ( settings.prop == "height" ) {
4882 percentDone = ( settings.end - settings.start === 0 ) ? 0 :
4883 ( settings.now - settings.start ) / ( settings.end - settings.start );
4884 }
4885
4886 options.toShow[ 0 ].style[ settings.prop ] =
4887 ( percentDone * showProps[ settings.prop ].value )
4888 + showProps[ settings.prop ].unit;
4889 },
4890 duration: options.duration,
4891 easing: options.easing,
4892 complete: function() {
4893 if ( !options.autoHeight ) {
4894 options.toShow.css( "height", "" );
4895 }
4896 options.toShow.css({
4897 width: originalWidth,
4898 overflow: overflow
4899 });
4900 options.complete();
4901 }
4902 });
4903 },
4904 bounceslide: function( options ) {
4905 this.slide( options, {
4906 easing: options.down ? "easeOutBounce" : "swing",
4907 duration: options.down ? 1000 : 200
4908 });
4909 }
4910 }
4911});
4912
4913})( jQuery );
4914/*
4915 * jQuery UI Autocomplete 1.8.16
4916 *
4917 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4918 * Dual licensed under the MIT or GPL Version 2 licenses.
4919 * http://jquery.org/license
4920 *
4921 * http://docs.jquery.com/UI/Autocomplete
4922 *
4923 * Depends:
4924 * jquery.ui.core.js
4925 * jquery.ui.widget.js
4926 * jquery.ui.position.js
4927 */
4928(function( $, undefined ) {
4929
4930// used to prevent race conditions with remote data sources
4931var requestIndex = 0;
4932
4933$.widget( "ui.autocomplete", {
4934 options: {
4935 appendTo: "body",
4936 autoFocus: false,
4937 delay: 300,
4938 minLength: 1,
4939 position: {
4940 my: "left top",
4941 at: "left bottom",
4942 collision: "none"
4943 },
4944 source: null
4945 },
4946
4947 pending: 0,
4948
4949 _create: function() {
4950 var self = this,
4951 doc = this.element[ 0 ].ownerDocument,
4952 suppressKeyPress;
4953
4954 this.element
4955 .addClass( "ui-autocomplete-input" )
4956 .attr( "autocomplete", "off" )
4957 // TODO verify these actually work as intended
4958 .attr({
4959 role: "textbox",
4960 "aria-autocomplete": "list",
4961 "aria-haspopup": "true"
4962 })
4963 .bind( "keydown.autocomplete", function( event ) {
4964 if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
4965 return;
4966 }
4967
4968 suppressKeyPress = false;
4969 var keyCode = $.ui.keyCode;
4970 switch( event.keyCode ) {
4971 case keyCode.PAGE_UP:
4972 self._move( "previousPage", event );
4973 break;
4974 case keyCode.PAGE_DOWN:
4975 self._move( "nextPage", event );
4976 break;
4977 case keyCode.UP:
4978 self._move( "previous", event );
4979 // prevent moving cursor to beginning of text field in some browsers
4980 event.preventDefault();
4981 break;
4982 case keyCode.DOWN:
4983 self._move( "next", event );
4984 // prevent moving cursor to end of text field in some browsers
4985 event.preventDefault();
4986 break;
4987 case keyCode.ENTER:
4988 case keyCode.NUMPAD_ENTER:
4989 // when menu is open and has focus
4990 if ( self.menu.active ) {
4991 // #6055 - Opera still allows the keypress to occur
4992 // which causes forms to submit
4993 suppressKeyPress = true;
4994 event.preventDefault();
4995 }
4996 //passthrough - ENTER and TAB both select the current element
4997 case keyCode.TAB:
4998 if ( !self.menu.active ) {
4999 return;
5000 }
5001 self.menu.select( event );
5002 break;
5003 case keyCode.ESCAPE:
5004 self.element.val( self.term );
5005 self.close( event );
5006 break;
5007 default:
5008 // keypress is triggered before the input value is changed
5009 clearTimeout( self.searching );
5010 self.searching = setTimeout(function() {
5011 // only search if the value has changed
5012 if ( self.term != self.element.val() ) {
5013 self.selectedItem = null;
5014 self.search( null, event );
5015 }
5016 }, self.options.delay );
5017 break;
5018 }
5019 })
5020 .bind( "keypress.autocomplete", function( event ) {
5021 if ( suppressKeyPress ) {
5022 suppressKeyPress = false;
5023 event.preventDefault();
5024 }
5025 })
5026 .bind( "focus.autocomplete", function() {
5027 if ( self.options.disabled ) {
5028 return;
5029 }
5030
5031 self.selectedItem = null;
5032 self.previous = self.element.val();
5033 })
5034 .bind( "blur.autocomplete", function( event ) {
5035 if ( self.options.disabled ) {
5036 return;
5037 }
5038
5039 clearTimeout( self.searching );
5040 // clicks on the menu (or a button to trigger a search) will cause a blur event
5041 self.closing = setTimeout(function() {
5042 self.close( event );
5043 self._change( event );
5044 }, 150 );
5045 });
5046 this._initSource();
5047 this.response = function() {
5048 return self._response.apply( self, arguments );
5049 };
5050 this.menu = $( "<ul></ul>" )
5051 .addClass( "ui-autocomplete" )
5052 .appendTo( $( this.options.appendTo || "body", doc )[0] )
5053 // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
5054 .mousedown(function( event ) {
5055 // clicking on the scrollbar causes focus to shift to the body
5056 // but we can't detect a mouseup or a click immediately afterward
5057 // so we have to track the next mousedown and close the menu if
5058 // the user clicks somewhere outside of the autocomplete
5059 var menuElement = self.menu.element[ 0 ];
5060 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5061 setTimeout(function() {
5062 $( document ).one( 'mousedown', function( event ) {
5063 if ( event.target !== self.element[ 0 ] &&
5064 event.target !== menuElement &&
5065 !$.ui.contains( menuElement, event.target ) ) {
5066 self.close();
5067 }
5068 });
5069 }, 1 );
5070 }
5071
5072 // use another timeout to make sure the blur-event-handler on the input was already triggered
5073 setTimeout(function() {
5074 clearTimeout( self.closing );
5075 }, 13);
5076 })
5077 .menu({
5078 focus: function( event, ui ) {
5079 var item = ui.item.data( "item.autocomplete" );
5080 if ( false !== self._trigger( "focus", event, { item: item } ) ) {
5081 // use value to match what will end up in the input, if it was a key event
5082 if ( /^key/.test(event.originalEvent.type) ) {
5083 self.element.val( item.value );
5084 }
5085 }
5086 },
5087 selected: function( event, ui ) {
5088 var item = ui.item.data( "item.autocomplete" ),
5089 previous = self.previous;
5090
5091 // only trigger when focus was lost (click on menu)
5092 if ( self.element[0] !== doc.activeElement ) {
5093 self.element.focus();
5094 self.previous = previous;
5095 // #6109 - IE triggers two focus events and the second
5096 // is asynchronous, so we need to reset the previous
5097 // term synchronously and asynchronously :-(
5098 setTimeout(function() {
5099 self.previous = previous;
5100 self.selectedItem = item;
5101 }, 1);
5102 }
5103
5104 if ( false !== self._trigger( "select", event, { item: item } ) ) {
5105 self.element.val( item.value );
5106 }
5107 // reset the term after the select event
5108 // this allows custom select handling to work properly
5109 self.term = self.element.val();
5110
5111 self.close( event );
5112 self.selectedItem = item;
5113 },
5114 blur: function( event, ui ) {
5115 // don't set the value of the text field if it's already correct
5116 // this prevents moving the cursor unnecessarily
5117 if ( self.menu.element.is(":visible") &&
5118 ( self.element.val() !== self.term ) ) {
5119 self.element.val( self.term );
5120 }
5121 }
5122 })
5123 .zIndex( this.element.zIndex() + 1 )
5124 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
5125 .css({ top: 0, left: 0 })
5126 .hide()
5127 .data( "menu" );
5128 if ( $.fn.bgiframe ) {
5129 this.menu.element.bgiframe();
5130 }
5131 },
5132
5133 destroy: function() {
5134 this.element
5135 .removeClass( "ui-autocomplete-input" )
5136 .removeAttr( "autocomplete" )
5137 .removeAttr( "role" )
5138 .removeAttr( "aria-autocomplete" )
5139 .removeAttr( "aria-haspopup" );
5140 this.menu.element.remove();
5141 $.Widget.prototype.destroy.call( this );
5142 },
5143
5144 _setOption: function( key, value ) {
5145 $.Widget.prototype._setOption.apply( this, arguments );
5146 if ( key === "source" ) {
5147 this._initSource();
5148 }
5149 if ( key === "appendTo" ) {
5150 this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
5151 }
5152 if ( key === "disabled" && value && this.xhr ) {
5153 this.xhr.abort();
5154 }
5155 },
5156
5157 _initSource: function() {
5158 var self = this,
5159 array,
5160 url;
5161 if ( $.isArray(this.options.source) ) {
5162 array = this.options.source;
5163 this.source = function( request, response ) {
5164 response( $.ui.autocomplete.filter(array, request.term) );
5165 };
5166 } else if ( typeof this.options.source === "string" ) {
5167 url = this.options.source;
5168 this.source = function( request, response ) {
5169 if ( self.xhr ) {
5170 self.xhr.abort();
5171 }
5172 self.xhr = $.ajax({
5173 url: url,
5174 data: request,
5175 dataType: "json",
5176 autocompleteRequest: ++requestIndex,
5177 success: function( data, status ) {
5178 if ( this.autocompleteRequest === requestIndex ) {
5179 response( data );
5180 }
5181 },
5182 error: function() {
5183 if ( this.autocompleteRequest === requestIndex ) {
5184 response( [] );
5185 }
5186 }
5187 });
5188 };
5189 } else {
5190 this.source = this.options.source;
5191 }
5192 },
5193
5194 search: function( value, event ) {
5195 value = value != null ? value : this.element.val();
5196
5197 // always save the actual value, not the one passed as an argument
5198 this.term = this.element.val();
5199
5200 if ( value.length < this.options.minLength ) {
5201 return this.close( event );
5202 }
5203
5204 clearTimeout( this.closing );
5205 if ( this._trigger( "search", event ) === false ) {
5206 return;
5207 }
5208
5209 return this._search( value );
5210 },
5211
5212 _search: function( value ) {
5213 this.pending++;
5214 this.element.addClass( "ui-autocomplete-loading" );
5215
5216 this.source( { term: value }, this.response );
5217 },
5218
5219 _response: function( content ) {
5220 if ( !this.options.disabled && content && content.length ) {
5221 content = this._normalize( content );
5222 this._suggest( content );
5223 this._trigger( "open" );
5224 } else {
5225 this.close();
5226 }
5227 this.pending--;
5228 if ( !this.pending ) {
5229 this.element.removeClass( "ui-autocomplete-loading" );
5230 }
5231 },
5232
5233 close: function( event ) {
5234 clearTimeout( this.closing );
5235 if ( this.menu.element.is(":visible") ) {
5236 this.menu.element.hide();
5237 this.menu.deactivate();
5238 this._trigger( "close", event );
5239 }
5240 },
5241
5242 _change: function( event ) {
5243 if ( this.previous !== this.element.val() ) {
5244 this._trigger( "change", event, { item: this.selectedItem } );
5245 }
5246 },
5247
5248 _normalize: function( items ) {
5249 // assume all items have the right format when the first item is complete
5250 if ( items.length && items[0].label && items[0].value ) {
5251 return items;
5252 }
5253 return $.map( items, function(item) {
5254 if ( typeof item === "string" ) {
5255 return {
5256 label: item,
5257 value: item
5258 };
5259 }
5260 return $.extend({
5261 label: item.label || item.value,
5262 value: item.value || item.label
5263 }, item );
5264 });
5265 },
5266
5267 _suggest: function( items ) {
5268 var ul = this.menu.element
5269 .empty()
5270 .zIndex( this.element.zIndex() + 1 );
5271 this._renderMenu( ul, items );
5272 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
5273 this.menu.deactivate();
5274 this.menu.refresh();
5275
5276 // size and position menu
5277 ul.show();
5278 this._resizeMenu();
5279 ul.position( $.extend({
5280 of: this.element
5281 }, this.options.position ));
5282
5283 if ( this.options.autoFocus ) {
5284 this.menu.next( new $.Event("mouseover") );
5285 }
5286 },
5287
5288 _resizeMenu: function() {
5289 var ul = this.menu.element;
5290 ul.outerWidth( Math.max(
5291 ul.width( "" ).outerWidth(),
5292 this.element.outerWidth()
5293 ) );
5294 },
5295
5296 _renderMenu: function( ul, items ) {
5297 var self = this;
5298 $.each( items, function( index, item ) {
5299 self._renderItem( ul, item );
5300 });
5301 },
5302
5303 _renderItem: function( ul, item) {
5304 return $( "<li></li>" )
5305 .data( "item.autocomplete", item )
5306 .append( $( "<a></a>" ).text( item.label ) )
5307 .appendTo( ul );
5308 },
5309
5310 _move: function( direction, event ) {
5311 if ( !this.menu.element.is(":visible") ) {
5312 this.search( null, event );
5313 return;
5314 }
5315 if ( this.menu.first() && /^previous/.test(direction) ||
5316 this.menu.last() && /^next/.test(direction) ) {
5317 this.element.val( this.term );
5318 this.menu.deactivate();
5319 return;
5320 }
5321 this.menu[ direction ]( event );
5322 },
5323
5324 widget: function() {
5325 return this.menu.element;
5326 }
5327});
5328
5329$.extend( $.ui.autocomplete, {
5330 escapeRegex: function( value ) {
5331 return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
5332 },
5333 filter: function(array, term) {
5334 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
5335 return $.grep( array, function(value) {
5336 return matcher.test( value.label || value.value || value );
5337 });
5338 }
5339});
5340
5341}( jQuery ));
5342
5343/*
5344 * jQuery UI Menu (not officially released)
5345 *
5346 * This widget isn't yet finished and the API is subject to change. We plan to finish
5347 * it for the next release. You're welcome to give it a try anyway and give us feedback,
5348 * as long as you're okay with migrating your code later on. We can help with that, too.
5349 *
5350 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5351 * Dual licensed under the MIT or GPL Version 2 licenses.
5352 * http://jquery.org/license
5353 *
5354 * http://docs.jquery.com/UI/Menu
5355 *
5356 * Depends:
5357 * jquery.ui.core.js
5358 * jquery.ui.widget.js
5359 */
5360(function($) {
5361
5362$.widget("ui.menu", {
5363 _create: function() {
5364 var self = this;
5365 this.element
5366 .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
5367 .attr({
5368 role: "listbox",
5369 "aria-activedescendant": "ui-active-menuitem"
5370 })
5371 .click(function( event ) {
5372 if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
5373 return;
5374 }
5375 // temporary
5376 event.preventDefault();
5377 self.select( event );
5378 });
5379 this.refresh();
5380 },
5381
5382 refresh: function() {
5383 var self = this;
5384
5385 // don't refresh list items that are already adapted
5386 var items = this.element.children("li:not(.ui-menu-item):has(a)")
5387 .addClass("ui-menu-item")
5388 .attr("role", "menuitem");
5389
5390 items.children("a")
5391 .addClass("ui-corner-all")
5392 .attr("tabindex", -1)
5393 // mouseenter doesn't work with event delegation
5394 .mouseenter(function( event ) {
5395 self.activate( event, $(this).parent() );
5396 })
5397 .mouseleave(function() {
5398 self.deactivate();
5399 });
5400 },
5401
5402 activate: function( event, item ) {
5403 this.deactivate();
5404 if (this.hasScroll()) {
5405 var offset = item.offset().top - this.element.offset().top,
5406 scroll = this.element.scrollTop(),
5407 elementHeight = this.element.height();
5408 if (offset < 0) {
5409 this.element.scrollTop( scroll + offset);
5410 } else if (offset >= elementHeight) {
5411 this.element.scrollTop( scroll + offset - elementHeight + item.height());
5412 }
5413 }
5414 this.active = item.eq(0)
5415 .children("a")
5416 .addClass("ui-state-hover")
5417 .attr("id", "ui-active-menuitem")
5418 .end();
5419 this._trigger("focus", event, { item: item });
5420 },
5421
5422 deactivate: function() {
5423 if (!this.active) { return; }
5424
5425 this.active.children("a")
5426 .removeClass("ui-state-hover")
5427 .removeAttr("id");
5428 this._trigger("blur");
5429 this.active = null;
5430 },
5431
5432 next: function(event) {
5433 this.move("next", ".ui-menu-item:first", event);
5434 },
5435
5436 previous: function(event) {
5437 this.move("prev", ".ui-menu-item:last", event);
5438 },
5439
5440 first: function() {
5441 return this.active && !this.active.prevAll(".ui-menu-item").length;
5442 },
5443
5444 last: function() {
5445 return this.active && !this.active.nextAll(".ui-menu-item").length;
5446 },
5447
5448 move: function(direction, edge, event) {
5449 if (!this.active) {
5450 this.activate(event, this.element.children(edge));
5451 return;
5452 }
5453 var next = this.active[direction + "All"](".ui-menu-item").eq(0);
5454 if (next.length) {
5455 this.activate(event, next);
5456 } else {
5457 this.activate(event, this.element.children(edge));
5458 }
5459 },
5460
5461 // TODO merge with previousPage
5462 nextPage: function(event) {
5463 if (this.hasScroll()) {
5464 // TODO merge with no-scroll-else
5465 if (!this.active || this.last()) {
5466 this.activate(event, this.element.children(".ui-menu-item:first"));
5467 return;
5468 }
5469 var base = this.active.offset().top,
5470 height = this.element.height(),
5471 result = this.element.children(".ui-menu-item").filter(function() {
5472 var close = $(this).offset().top - base - height + $(this).height();
5473 // TODO improve approximation
5474 return close < 10 && close > -10;
5475 });
5476
5477 // TODO try to catch this earlier when scrollTop indicates the last page anyway
5478 if (!result.length) {
5479 result = this.element.children(".ui-menu-item:last");
5480 }
5481 this.activate(event, result);
5482 } else {
5483 this.activate(event, this.element.children(".ui-menu-item")
5484 .filter(!this.active || this.last() ? ":first" : ":last"));
5485 }
5486 },
5487
5488 // TODO merge with nextPage
5489 previousPage: function(event) {
5490 if (this.hasScroll()) {
5491 // TODO merge with no-scroll-else
5492 if (!this.active || this.first()) {
5493 this.activate(event, this.element.children(".ui-menu-item:last"));
5494 return;
5495 }
5496
5497 var base = this.active.offset().top,
5498 height = this.element.height();
5499 result = this.element.children(".ui-menu-item").filter(function() {
5500 var close = $(this).offset().top - base + height - $(this).height();
5501 // TODO improve approximation
5502 return close < 10 && close > -10;
5503 });
5504
5505 // TODO try to catch this earlier when scrollTop indicates the last page anyway
5506 if (!result.length) {
5507 result = this.element.children(".ui-menu-item:first");
5508 }
5509 this.activate(event, result);
5510 } else {
5511 this.activate(event, this.element.children(".ui-menu-item")
5512 .filter(!this.active || this.first() ? ":last" : ":first"));
5513 }
5514 },
5515
5516 hasScroll: function() {
5517 return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
5518 },
5519
5520 select: function( event ) {
5521 this._trigger("selected", event, { item: this.active });
5522 }
5523});
5524
5525}(jQuery));
5526/*
5527 * jQuery UI Button 1.8.16
5528 *
5529 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5530 * Dual licensed under the MIT or GPL Version 2 licenses.
5531 * http://jquery.org/license
5532 *
5533 * http://docs.jquery.com/UI/Button
5534 *
5535 * Depends:
5536 * jquery.ui.core.js
5537 * jquery.ui.widget.js
5538 */
5539(function( $, undefined ) {
5540
5541var lastActive, startXPos, startYPos, clickDragged,
5542 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
5543 stateClasses = "ui-state-hover ui-state-active ",
5544 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",
5545 formResetHandler = function() {
5546 var buttons = $( this ).find( ":ui-button" );
5547 setTimeout(function() {
5548 buttons.button( "refresh" );
5549 }, 1 );
5550 },
5551 radioGroup = function( radio ) {
5552 var name = radio.name,
5553 form = radio.form,
5554 radios = $( [] );
5555 if ( name ) {
5556 if ( form ) {
5557 radios = $( form ).find( "[name='" + name + "']" );
5558 } else {
5559 radios = $( "[name='" + name + "']", radio.ownerDocument )
5560 .filter(function() {
5561 return !this.form;
5562 });
5563 }
5564 }
5565 return radios;
5566 };
5567
5568$.widget( "ui.button", {
5569 options: {
5570 disabled: null,
5571 text: true,
5572 label: null,
5573 icons: {
5574 primary: null,
5575 secondary: null
5576 }
5577 },
5578 _create: function() {
5579 this.element.closest( "form" )
5580 .unbind( "reset.button" )
5581 .bind( "reset.button", formResetHandler );
5582
5583 if ( typeof this.options.disabled !== "boolean" ) {
5584 this.options.disabled = this.element.propAttr( "disabled" );
5585 }
5586
5587 this._determineButtonType();
5588 this.hasTitle = !!this.buttonElement.attr( "title" );
5589
5590 var self = this,
5591 options = this.options,
5592 toggleButton = this.type === "checkbox" || this.type === "radio",
5593 hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
5594 focusClass = "ui-state-focus";
5595
5596 if ( options.label === null ) {
5597 options.label = this.buttonElement.html();
5598 }
5599
5600 if ( this.element.is( ":disabled" ) ) {
5601 options.disabled = true;
5602 }
5603
5604 this.buttonElement
5605 .addClass( baseClasses )
5606 .attr( "role", "button" )
5607 .bind( "mouseenter.button", function() {
5608 if ( options.disabled ) {
5609 return;
5610 }
5611 $( this ).addClass( "ui-state-hover" );
5612 if ( this === lastActive ) {
5613 $( this ).addClass( "ui-state-active" );
5614 }
5615 })
5616 .bind( "mouseleave.button", function() {
5617 if ( options.disabled ) {
5618 return;
5619 }
5620 $( this ).removeClass( hoverClass );
5621 })
5622 .bind( "click.button", function( event ) {
5623 if ( options.disabled ) {
5624 event.preventDefault();
5625 event.stopImmediatePropagation();
5626 }
5627 });
5628
5629 this.element
5630 .bind( "focus.button", function() {
5631 // no need to check disabled, focus won't be triggered anyway
5632 self.buttonElement.addClass( focusClass );
5633 })
5634 .bind( "blur.button", function() {
5635 self.buttonElement.removeClass( focusClass );
5636 });
5637
5638 if ( toggleButton ) {
5639 this.element.bind( "change.button", function() {
5640 if ( clickDragged ) {
5641 return;
5642 }
5643 self.refresh();
5644 });
5645 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
5646 // prevents issue where button state changes but checkbox/radio checked state
5647 // does not in Firefox (see ticket #6970)
5648 this.buttonElement
5649 .bind( "mousedown.button", function( event ) {
5650 if ( options.disabled ) {
5651 return;
5652 }
5653 clickDragged = false;
5654 startXPos = event.pageX;
5655 startYPos = event.pageY;
5656 })
5657 .bind( "mouseup.button", function( event ) {
5658 if ( options.disabled ) {
5659 return;
5660 }
5661 if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
5662 clickDragged = true;
5663 }
5664 });
5665 }
5666
5667 if ( this.type === "checkbox" ) {
5668 this.buttonElement.bind( "click.button", function() {
5669 if ( options.disabled || clickDragged ) {
5670 return false;
5671 }
5672 $( this ).toggleClass( "ui-state-active" );
5673 self.buttonElement.attr( "aria-pressed", self.element[0].checked );
5674 });
5675 } else if ( this.type === "radio" ) {
5676 this.buttonElement.bind( "click.button", function() {
5677 if ( options.disabled || clickDragged ) {
5678 return false;
5679 }
5680 $( this ).addClass( "ui-state-active" );
5681 self.buttonElement.attr( "aria-pressed", "true" );
5682
5683 var radio = self.element[ 0 ];
5684 radioGroup( radio )
5685 .not( radio )
5686 .map(function() {
5687 return $( this ).button( "widget" )[ 0 ];
5688 })
5689 .removeClass( "ui-state-active" )
5690 .attr( "aria-pressed", "false" );
5691 });
5692 } else {
5693 this.buttonElement
5694 .bind( "mousedown.button", function() {
5695 if ( options.disabled ) {
5696 return false;
5697 }
5698 $( this ).addClass( "ui-state-active" );
5699 lastActive = this;
5700 $( document ).one( "mouseup", function() {
5701 lastActive = null;
5702 });
5703 })
5704 .bind( "mouseup.button", function() {
5705 if ( options.disabled ) {
5706 return false;
5707 }
5708 $( this ).removeClass( "ui-state-active" );
5709 })
5710 .bind( "keydown.button", function(event) {
5711 if ( options.disabled ) {
5712 return false;
5713 }
5714 if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
5715 $( this ).addClass( "ui-state-active" );
5716 }
5717 })
5718 .bind( "keyup.button", function() {
5719 $( this ).removeClass( "ui-state-active" );
5720 });
5721
5722 if ( this.buttonElement.is("a") ) {
5723 this.buttonElement.keyup(function(event) {
5724 if ( event.keyCode === $.ui.keyCode.SPACE ) {
5725 // TODO pass through original event correctly (just as 2nd argument doesn't work)
5726 $( this ).click();
5727 }
5728 });
5729 }
5730 }
5731
5732 // TODO: pull out $.Widget's handling for the disabled option into
5733 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
5734 // be overridden by individual plugins
5735 this._setOption( "disabled", options.disabled );
5736 this._resetButton();
5737 },
5738
5739 _determineButtonType: function() {
5740
5741 if ( this.element.is(":checkbox") ) {
5742 this.type = "checkbox";
5743 } else if ( this.element.is(":radio") ) {
5744 this.type = "radio";
5745 } else if ( this.element.is("input") ) {
5746 this.type = "input";
5747 } else {
5748 this.type = "button";
5749 }
5750
5751 if ( this.type === "checkbox" || this.type === "radio" ) {
5752 // we don't search against the document in case the element
5753 // is disconnected from the DOM
5754 var ancestor = this.element.parents().filter(":last"),
5755 labelSelector = "label[for='" + this.element.attr("id") + "']";
5756 this.buttonElement = ancestor.find( labelSelector );
5757 if ( !this.buttonElement.length ) {
5758 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
5759 this.buttonElement = ancestor.filter( labelSelector );
5760 if ( !this.buttonElement.length ) {
5761 this.buttonElement = ancestor.find( labelSelector );
5762 }
5763 }
5764 this.element.addClass( "ui-helper-hidden-accessible" );
5765
5766 var checked = this.element.is( ":checked" );
5767 if ( checked ) {
5768 this.buttonElement.addClass( "ui-state-active" );
5769 }
5770 this.buttonElement.attr( "aria-pressed", checked );
5771 } else {
5772 this.buttonElement = this.element;
5773 }
5774 },
5775
5776 widget: function() {
5777 return this.buttonElement;
5778 },
5779
5780 destroy: function() {
5781 this.element
5782 .removeClass( "ui-helper-hidden-accessible" );
5783 this.buttonElement
5784 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
5785 .removeAttr( "role" )
5786 .removeAttr( "aria-pressed" )
5787 .html( this.buttonElement.find(".ui-button-text").html() );
5788
5789 if ( !this.hasTitle ) {
5790 this.buttonElement.removeAttr( "title" );
5791 }
5792
5793 $.Widget.prototype.destroy.call( this );
5794 },
5795
5796 _setOption: function( key, value ) {
5797 $.Widget.prototype._setOption.apply( this, arguments );
5798 if ( key === "disabled" ) {
5799 if ( value ) {
5800 this.element.propAttr( "disabled", true );
5801 } else {
5802 this.element.propAttr( "disabled", false );
5803 }
5804 return;
5805 }
5806 this._resetButton();
5807 },
5808
5809 refresh: function() {
5810 var isDisabled = this.element.is( ":disabled" );
5811 if ( isDisabled !== this.options.disabled ) {
5812 this._setOption( "disabled", isDisabled );
5813 }
5814 if ( this.type === "radio" ) {
5815 radioGroup( this.element[0] ).each(function() {
5816 if ( $( this ).is( ":checked" ) ) {
5817 $( this ).button( "widget" )
5818 .addClass( "ui-state-active" )
5819 .attr( "aria-pressed", "true" );
5820 } else {
5821 $( this ).button( "widget" )
5822 .removeClass( "ui-state-active" )
5823 .attr( "aria-pressed", "false" );
5824 }
5825 });
5826 } else if ( this.type === "checkbox" ) {
5827 if ( this.element.is( ":checked" ) ) {
5828 this.buttonElement
5829 .addClass( "ui-state-active" )
5830 .attr( "aria-pressed", "true" );
5831 } else {
5832 this.buttonElement
5833 .removeClass( "ui-state-active" )
5834 .attr( "aria-pressed", "false" );
5835 }
5836 }
5837 },
5838
5839 _resetButton: function() {
5840 if ( this.type === "input" ) {
5841 if ( this.options.label ) {
5842 this.element.val( this.options.label );
5843 }
5844 return;
5845 }
5846 var buttonElement = this.buttonElement.removeClass( typeClasses ),
5847 buttonText = $( "<span></span>" )
5848 .addClass( "ui-button-text" )
5849 .html( this.options.label )
5850 .appendTo( buttonElement.empty() )
5851 .text(),
5852 icons = this.options.icons,
5853 multipleIcons = icons.primary && icons.secondary,
5854 buttonClasses = [];
5855
5856 if ( icons.primary || icons.secondary ) {
5857 if ( this.options.text ) {
5858 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
5859 }
5860
5861 if ( icons.primary ) {
5862 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
5863 }
5864
5865 if ( icons.secondary ) {
5866 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
5867 }
5868
5869 if ( !this.options.text ) {
5870 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
5871
5872 if ( !this.hasTitle ) {
5873 buttonElement.attr( "title", buttonText );
5874 }
5875 }
5876 } else {
5877 buttonClasses.push( "ui-button-text-only" );
5878 }
5879 buttonElement.addClass( buttonClasses.join( " " ) );
5880 }
5881});
5882
5883$.widget( "ui.buttonset", {
5884 options: {
5885 items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
5886 },
5887
5888 _create: function() {
5889 this.element.addClass( "ui-buttonset" );
5890 },
5891
5892 _init: function() {
5893 this.refresh();
5894 },
5895
5896 _setOption: function( key, value ) {
5897 if ( key === "disabled" ) {
5898 this.buttons.button( "option", key, value );
5899 }
5900
5901 $.Widget.prototype._setOption.apply( this, arguments );
5902 },
5903
5904 refresh: function() {
5905 var ltr = this.element.css( "direction" ) === "ltr";
5906
5907 this.buttons = this.element.find( this.options.items )
5908 .filter( ":ui-button" )
5909 .button( "refresh" )
5910 .end()
5911 .not( ":ui-button" )
5912 .button()
5913 .end()
5914 .map(function() {
5915 return $( this ).button( "widget" )[ 0 ];
5916 })
5917 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
5918 .filter( ":first" )
5919 .addClass( ltr ? "ui-corner-left" : "ui-corner-right" )
5920 .end()
5921 .filter( ":last" )
5922 .addClass( ltr ? "ui-corner-right" : "ui-corner-left" )
5923 .end()
5924 .end();
5925 },
5926
5927 destroy: function() {
5928 this.element.removeClass( "ui-buttonset" );
5929 this.buttons
5930 .map(function() {
5931 return $( this ).button( "widget" )[ 0 ];
5932 })
5933 .removeClass( "ui-corner-left ui-corner-right" )
5934 .end()
5935 .button( "destroy" );
5936
5937 $.Widget.prototype.destroy.call( this );
5938 }
5939});
5940
5941}( jQuery ) );
5942/*
5943 * jQuery UI Dialog 1.8.16
5944 *
5945 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5946 * Dual licensed under the MIT or GPL Version 2 licenses.
5947 * http://jquery.org/license
5948 *
5949 * http://docs.jquery.com/UI/Dialog
5950 *
5951 * Depends:
5952 * jquery.ui.core.js
5953 * jquery.ui.widget.js
5954 * jquery.ui.button.js
5955 * jquery.ui.draggable.js
5956 * jquery.ui.mouse.js
5957 * jquery.ui.position.js
5958 * jquery.ui.resizable.js
5959 */
5960(function( $, undefined ) {
5961
5962var uiDialogClasses =
5963 'ui-dialog ' +
5964 'ui-widget ' +
5965 'ui-widget-content ' +
5966 'ui-corner-all ',
5967 sizeRelatedOptions = {
5968 buttons: true,
5969 height: true,
5970 maxHeight: true,
5971 maxWidth: true,
5972 minHeight: true,
5973 minWidth: true,
5974 width: true
5975 },
5976 resizableRelatedOptions = {
5977 maxHeight: true,
5978 maxWidth: true,
5979 minHeight: true,
5980 minWidth: true
5981 },
5982 // support for jQuery 1.3.2 - handle common attrFn methods for dialog
5983 attrFn = $.attrFn || {
5984 val: true,
5985 css: true,
5986 html: true,
5987 text: true,
5988 data: true,
5989 width: true,
5990 height: true,
5991 offset: true,
5992 click: true
5993 };
5994
5995$.widget("ui.dialog", {
5996 options: {
5997 autoOpen: true,
5998 buttons: {},
5999 closeOnEscape: true,
6000 closeText: 'close',
6001 dialogClass: '',
6002 draggable: true,
6003 hide: null,
6004 height: 'auto',
6005 maxHeight: false,
6006 maxWidth: false,
6007 minHeight: 150,
6008 minWidth: 150,
6009 modal: false,
6010 position: {
6011 my: 'center',
6012 at: 'center',
6013 collision: 'fit',
6014 // ensure that the titlebar is never outside the document
6015 using: function(pos) {
6016 var topOffset = $(this).css(pos).offset().top;
6017 if (topOffset < 0) {
6018 $(this).css('top', pos.top - topOffset);
6019 }
6020 }
6021 },
6022 resizable: true,
6023 show: null,
6024 stack: true,
6025 title: '',
6026 width: 300,
6027 zIndex: 1000
6028 },
6029
6030 _create: function() {
6031 this.originalTitle = this.element.attr('title');
6032 // #5742 - .attr() might return a DOMElement
6033 if ( typeof this.originalTitle !== "string" ) {
6034 this.originalTitle = "";
6035 }
6036
6037 this.options.title = this.options.title || this.originalTitle;
6038 var self = this,
6039 options = self.options,
6040
6041 title = options.title || '&#160;',
6042 titleId = $.ui.dialog.getTitleId(self.element),
6043
6044 uiDialog = (self.uiDialog = $('<div></div>'))
6045 .appendTo(document.body)
6046 .hide()
6047 .addClass(uiDialogClasses + options.dialogClass)
6048 .css({
6049 zIndex: options.zIndex
6050 })
6051 // setting tabIndex makes the div focusable
6052 // setting outline to 0 prevents a border on focus in Mozilla
6053 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
6054 if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
6055 event.keyCode === $.ui.keyCode.ESCAPE) {
6056
6057 self.close(event);
6058 event.preventDefault();
6059 }
6060 })
6061 .attr({
6062 role: 'dialog',
6063 'aria-labelledby': titleId
6064 })
6065 .mousedown(function(event) {
6066 self.moveToTop(false, event);
6067 }),
6068
6069 uiDialogContent = self.element
6070 .show()
6071 .removeAttr('title')
6072 .addClass(
6073 'ui-dialog-content ' +
6074 'ui-widget-content')
6075 .appendTo(uiDialog),
6076
6077 uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
6078 .addClass(
6079 'ui-dialog-titlebar ' +
6080 'ui-widget-header ' +
6081 'ui-corner-all ' +
6082 'ui-helper-clearfix'
6083 )
6084 .prependTo(uiDialog),
6085
6086 uiDialogTitlebarClose = $('<a href="#"></a>')
6087 .addClass(
6088 'ui-dialog-titlebar-close ' +
6089 'ui-corner-all'
6090 )
6091 .attr('role', 'button')
6092 .hover(
6093 function() {
6094 uiDialogTitlebarClose.addClass('ui-state-hover');
6095 },
6096 function() {
6097 uiDialogTitlebarClose.removeClass('ui-state-hover');
6098 }
6099 )
6100 .focus(function() {
6101 uiDialogTitlebarClose.addClass('ui-state-focus');
6102 })
6103 .blur(function() {
6104 uiDialogTitlebarClose.removeClass('ui-state-focus');
6105 })
6106 .click(function(event) {
6107 self.close(event);
6108 return false;
6109 })
6110 .appendTo(uiDialogTitlebar),
6111
6112 uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
6113 .addClass(
6114 'ui-icon ' +
6115 'ui-icon-closethick'
6116 )
6117 .text(options.closeText)
6118 .appendTo(uiDialogTitlebarClose),
6119
6120 uiDialogTitle = $('<span></span>')
6121 .addClass('ui-dialog-title')
6122 .attr('id', titleId)
6123 .html(title)
6124 .prependTo(uiDialogTitlebar);
6125
6126 //handling of deprecated beforeclose (vs beforeClose) option
6127 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6128 //TODO: remove in 1.9pre
6129 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
6130 options.beforeClose = options.beforeclose;
6131 }
6132
6133 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
6134
6135 if (options.draggable && $.fn.draggable) {
6136 self._makeDraggable();
6137 }
6138 if (options.resizable && $.fn.resizable) {
6139 self._makeResizable();
6140 }
6141
6142 self._createButtons(options.buttons);
6143 self._isOpen = false;
6144
6145 if ($.fn.bgiframe) {
6146 uiDialog.bgiframe();
6147 }
6148 },
6149
6150 _init: function() {
6151 if ( this.options.autoOpen ) {
6152 this.open();
6153 }
6154 },
6155
6156 destroy: function() {
6157 var self = this;
6158
6159 if (self.overlay) {
6160 self.overlay.destroy();
6161 }
6162 self.uiDialog.hide();
6163 self.element
6164 .unbind('.dialog')
6165 .removeData('dialog')
6166 .removeClass('ui-dialog-content ui-widget-content')
6167 .hide().appendTo('body');
6168 self.uiDialog.remove();
6169
6170 if (self.originalTitle) {
6171 self.element.attr('title', self.originalTitle);
6172 }
6173
6174 return self;
6175 },
6176
6177 widget: function() {
6178 return this.uiDialog;
6179 },
6180
6181 close: function(event) {
6182 var self = this,
6183 maxZ, thisZ;
6184
6185 if (false === self._trigger('beforeClose', event)) {
6186 return;
6187 }
6188
6189 if (self.overlay) {
6190 self.overlay.destroy();
6191 }
6192 self.uiDialog.unbind('keypress.ui-dialog');
6193
6194 self._isOpen = false;
6195
6196 if (self.options.hide) {
6197 self.uiDialog.hide(self.options.hide, function() {
6198 self._trigger('close', event);
6199 });
6200 } else {
6201 self.uiDialog.hide();
6202 self._trigger('close', event);
6203 }
6204
6205 $.ui.dialog.overlay.resize();
6206
6207 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6208 if (self.options.modal) {
6209 maxZ = 0;
6210 $('.ui-dialog').each(function() {
6211 if (this !== self.uiDialog[0]) {
6212 thisZ = $(this).css('z-index');
6213 if(!isNaN(thisZ)) {
6214 maxZ = Math.max(maxZ, thisZ);
6215 }
6216 }
6217 });
6218 $.ui.dialog.maxZ = maxZ;
6219 }
6220
6221 return self;
6222 },
6223
6224 isOpen: function() {
6225 return this._isOpen;
6226 },
6227
6228 // the force parameter allows us to move modal dialogs to their correct
6229 // position on open
6230 moveToTop: function(force, event) {
6231 var self = this,
6232 options = self.options,
6233 saveScroll;
6234
6235 if ((options.modal && !force) ||
6236 (!options.stack && !options.modal)) {
6237 return self._trigger('focus', event);
6238 }
6239
6240 if (options.zIndex > $.ui.dialog.maxZ) {
6241 $.ui.dialog.maxZ = options.zIndex;
6242 }
6243 if (self.overlay) {
6244 $.ui.dialog.maxZ += 1;
6245 self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
6246 }
6247
6248 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
6249 // http://ui.jquery.com/bugs/ticket/3193
6250 saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
6251 $.ui.dialog.maxZ += 1;
6252 self.uiDialog.css('z-index', $.ui.dialog.maxZ);
6253 self.element.attr(saveScroll);
6254 self._trigger('focus', event);
6255
6256 return self;
6257 },
6258
6259 open: function() {
6260 if (this._isOpen) { return; }
6261
6262 var self = this,
6263 options = self.options,
6264 uiDialog = self.uiDialog;
6265
6266 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
6267 self._size();
6268 self._position(options.position);
6269 uiDialog.show(options.show);
6270 self.moveToTop(true);
6271
6272 // prevent tabbing out of modal dialogs
6273 if (options.modal) {
6274 uiDialog.bind('keypress.ui-dialog', function(event) {
6275 if (event.keyCode !== $.ui.keyCode.TAB) {
6276 return;
6277 }
6278
6279 var tabbables = $(':tabbable', this),
6280 first = tabbables.filter(':first'),
6281 last = tabbables.filter(':last');
6282
6283 if (event.target === last[0] && !event.shiftKey) {
6284 first.focus(1);
6285 return false;
6286 } else if (event.target === first[0] && event.shiftKey) {
6287 last.focus(1);
6288 return false;
6289 }
6290 });
6291 }
6292
6293 // set focus to the first tabbable element in the content area or the first button
6294 // if there are no tabbable elements, set focus on the dialog itself
6295 $(self.element.find(':tabbable').get().concat(
6296 uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
6297 uiDialog.get()))).eq(0).focus();
6298
6299 self._isOpen = true;
6300 self._trigger('open');
6301
6302 return self;
6303 },
6304
6305 _createButtons: function(buttons) {
6306 var self = this,
6307 hasButtons = false,
6308 uiDialogButtonPane = $('<div></div>')
6309 .addClass(
6310 'ui-dialog-buttonpane ' +
6311 'ui-widget-content ' +
6312 'ui-helper-clearfix'
6313 ),
6314 uiButtonSet = $( "<div></div>" )
6315 .addClass( "ui-dialog-buttonset" )
6316 .appendTo( uiDialogButtonPane );
6317
6318 // if we already have a button pane, remove it
6319 self.uiDialog.find('.ui-dialog-buttonpane').remove();
6320
6321 if (typeof buttons === 'object' && buttons !== null) {
6322 $.each(buttons, function() {
6323 return !(hasButtons = true);
6324 });
6325 }
6326 if (hasButtons) {
6327 $.each(buttons, function(name, props) {
6328 props = $.isFunction( props ) ?
6329 { click: props, text: name } :
6330 props;
6331 var button = $('<button type="button"></button>')
6332 .click(function() {
6333 props.click.apply(self.element[0], arguments);
6334 })
6335 .appendTo(uiButtonSet);
6336 // can't use .attr( props, true ) with jQuery 1.3.2.
6337 $.each( props, function( key, value ) {
6338 if ( key === "click" ) {
6339 return;
6340 }
6341 if ( key in attrFn ) {
6342 button[ key ]( value );
6343 } else {
6344 button.attr( key, value );
6345 }
6346 });
6347 if ($.fn.button) {
6348 button.button();
6349 }
6350 });
6351 uiDialogButtonPane.appendTo(self.uiDialog);
6352 }
6353 },
6354
6355 _makeDraggable: function() {
6356 var self = this,
6357 options = self.options,
6358 doc = $(document),
6359 heightBeforeDrag;
6360
6361 function filteredUi(ui) {
6362 return {
6363 position: ui.position,
6364 offset: ui.offset
6365 };
6366 }
6367
6368 self.uiDialog.draggable({
6369 cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
6370 handle: '.ui-dialog-titlebar',
6371 containment: 'document',
6372 start: function(event, ui) {
6373 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
6374 $(this).height($(this).height()).addClass("ui-dialog-dragging");
6375 self._trigger('dragStart', event, filteredUi(ui));
6376 },
6377 drag: function(event, ui) {
6378 self._trigger('drag', event, filteredUi(ui));
6379 },
6380 stop: function(event, ui) {
6381 options.position = [ui.position.left - doc.scrollLeft(),
6382 ui.position.top - doc.scrollTop()];
6383 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
6384 self._trigger('dragStop', event, filteredUi(ui));
6385 $.ui.dialog.overlay.resize();
6386 }
6387 });
6388 },
6389
6390 _makeResizable: function(handles) {
6391 handles = (handles === undefined ? this.options.resizable : handles);
6392 var self = this,
6393 options = self.options,
6394 // .ui-resizable has position: relative defined in the stylesheet
6395 // but dialogs have to use absolute or fixed positioning
6396 position = self.uiDialog.css('position'),
6397 resizeHandles = (typeof handles === 'string' ?
6398 handles :
6399 'n,e,s,w,se,sw,ne,nw'
6400 );
6401
6402 function filteredUi(ui) {
6403 return {
6404 originalPosition: ui.originalPosition,
6405 originalSize: ui.originalSize,
6406 position: ui.position,
6407 size: ui.size
6408 };
6409 }
6410
6411 self.uiDialog.resizable({
6412 cancel: '.ui-dialog-content',
6413 containment: 'document',
6414 alsoResize: self.element,
6415 maxWidth: options.maxWidth,
6416 maxHeight: options.maxHeight,
6417 minWidth: options.minWidth,
6418 minHeight: self._minHeight(),
6419 handles: resizeHandles,
6420 start: function(event, ui) {
6421 $(this).addClass("ui-dialog-resizing");
6422 self._trigger('resizeStart', event, filteredUi(ui));
6423 },
6424 resize: function(event, ui) {
6425 self._trigger('resize', event, filteredUi(ui));
6426 },
6427 stop: function(event, ui) {
6428 $(this).removeClass("ui-dialog-resizing");
6429 options.height = $(this).height();
6430 options.width = $(this).width();
6431 self._trigger('resizeStop', event, filteredUi(ui));
6432 $.ui.dialog.overlay.resize();
6433 }
6434 })
6435 .css('position', position)
6436 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
6437 },
6438
6439 _minHeight: function() {
6440 var options = this.options;
6441
6442 if (options.height === 'auto') {
6443 return options.minHeight;
6444 } else {
6445 return Math.min(options.minHeight, options.height);
6446 }
6447 },
6448
6449 _position: function(position) {
6450 var myAt = [],
6451 offset = [0, 0],
6452 isVisible;
6453
6454 if (position) {
6455 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
6456 // if (typeof position == 'string' || $.isArray(position)) {
6457 // myAt = $.isArray(position) ? position : position.split(' ');
6458
6459 if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
6460 myAt = position.split ? position.split(' ') : [position[0], position[1]];
6461 if (myAt.length === 1) {
6462 myAt[1] = myAt[0];
6463 }
6464
6465 $.each(['left', 'top'], function(i, offsetPosition) {
6466 if (+myAt[i] === myAt[i]) {
6467 offset[i] = myAt[i];
6468 myAt[i] = offsetPosition;
6469 }
6470 });
6471
6472 position = {
6473 my: myAt.join(" "),
6474 at: myAt.join(" "),
6475 offset: offset.join(" ")
6476 };
6477 }
6478
6479 position = $.extend({}, $.ui.dialog.prototype.options.position, position);
6480 } else {
6481 position = $.ui.dialog.prototype.options.position;
6482 }
6483
6484 // need to show the dialog to get the actual offset in the position plugin
6485 isVisible = this.uiDialog.is(':visible');
6486 if (!isVisible) {
6487 this.uiDialog.show();
6488 }
6489 this.uiDialog
6490 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6491 .css({ top: 0, left: 0 })
6492 .position($.extend({ of: window }, position));
6493 if (!isVisible) {
6494 this.uiDialog.hide();
6495 }
6496 },
6497
6498 _setOptions: function( options ) {
6499 var self = this,
6500 resizableOptions = {},
6501 resize = false;
6502
6503 $.each( options, function( key, value ) {
6504 self._setOption( key, value );
6505
6506 if ( key in sizeRelatedOptions ) {
6507 resize = true;
6508 }
6509 if ( key in resizableRelatedOptions ) {
6510 resizableOptions[ key ] = value;
6511 }
6512 });
6513
6514 if ( resize ) {
6515 this._size();
6516 }
6517 if ( this.uiDialog.is( ":data(resizable)" ) ) {
6518 this.uiDialog.resizable( "option", resizableOptions );
6519 }
6520 },
6521
6522 _setOption: function(key, value){
6523 var self = this,
6524 uiDialog = self.uiDialog;
6525
6526 switch (key) {
6527 //handling of deprecated beforeclose (vs beforeClose) option
6528 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6529 //TODO: remove in 1.9pre
6530 case "beforeclose":
6531 key = "beforeClose";
6532 break;
6533 case "buttons":
6534 self._createButtons(value);
6535 break;
6536 case "closeText":
6537 // ensure that we always pass a string
6538 self.uiDialogTitlebarCloseText.text("" + value);
6539 break;
6540 case "dialogClass":
6541 uiDialog
6542 .removeClass(self.options.dialogClass)
6543 .addClass(uiDialogClasses + value);
6544 break;
6545 case "disabled":
6546 if (value) {
6547 uiDialog.addClass('ui-dialog-disabled');
6548 } else {
6549 uiDialog.removeClass('ui-dialog-disabled');
6550 }
6551 break;
6552 case "draggable":
6553 var isDraggable = uiDialog.is( ":data(draggable)" );
6554 if ( isDraggable && !value ) {
6555 uiDialog.draggable( "destroy" );
6556 }
6557
6558 if ( !isDraggable && value ) {
6559 self._makeDraggable();
6560 }
6561 break;
6562 case "position":
6563 self._position(value);
6564 break;
6565 case "resizable":
6566 // currently resizable, becoming non-resizable
6567 var isResizable = uiDialog.is( ":data(resizable)" );
6568 if (isResizable && !value) {
6569 uiDialog.resizable('destroy');
6570 }
6571
6572 // currently resizable, changing handles
6573 if (isResizable && typeof value === 'string') {
6574 uiDialog.resizable('option', 'handles', value);
6575 }
6576
6577 // currently non-resizable, becoming resizable
6578 if (!isResizable && value !== false) {
6579 self._makeResizable(value);
6580 }
6581 break;
6582 case "title":
6583 // convert whatever was passed in o a string, for html() to not throw up
6584 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
6585 break;
6586 }
6587
6588 $.Widget.prototype._setOption.apply(self, arguments);
6589 },
6590
6591 _size: function() {
6592 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
6593 * divs will both have width and height set, so we need to reset them
6594 */
6595 var options = this.options,
6596 nonContentHeight,
6597 minContentHeight,
6598 isVisible = this.uiDialog.is( ":visible" );
6599
6600 // reset content sizing
6601 this.element.show().css({
6602 width: 'auto',
6603 minHeight: 0,
6604 height: 0
6605 });
6606
6607 if (options.minWidth > options.width) {
6608 options.width = options.minWidth;
6609 }
6610
6611 // reset wrapper sizing
6612 // determine the height of all the non-content elements
6613 nonContentHeight = this.uiDialog.css({
6614 height: 'auto',
6615 width: options.width
6616 })
6617 .height();
6618 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
6619
6620 if ( options.height === "auto" ) {
6621 // only needed for IE6 support
6622 if ( $.support.minHeight ) {
6623 this.element.css({
6624 minHeight: minContentHeight,
6625 height: "auto"
6626 });
6627 } else {
6628 this.uiDialog.show();
6629 var autoHeight = this.element.css( "height", "auto" ).height();
6630 if ( !isVisible ) {
6631 this.uiDialog.hide();
6632 }
6633 this.element.height( Math.max( autoHeight, minContentHeight ) );
6634 }
6635 } else {
6636 this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
6637 }
6638
6639 if (this.uiDialog.is(':data(resizable)')) {
6640 this.uiDialog.resizable('option', 'minHeight', this._minHeight());
6641 }
6642 }
6643});
6644
6645$.extend($.ui.dialog, {
6646 version: "1.8.16",
6647
6648 uuid: 0,
6649 maxZ: 0,
6650
6651 getTitleId: function($el) {
6652 var id = $el.attr('id');
6653 if (!id) {
6654 this.uuid += 1;
6655 id = this.uuid;
6656 }
6657 return 'ui-dialog-title-' + id;
6658 },
6659
6660 overlay: function(dialog) {
6661 this.$el = $.ui.dialog.overlay.create(dialog);
6662 }
6663});
6664
6665$.extend($.ui.dialog.overlay, {
6666 instances: [],
6667 // reuse old instances due to IE memory leak with alpha transparency (see #5185)
6668 oldInstances: [],
6669 maxZ: 0,
6670 events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
6671 function(event) { return event + '.dialog-overlay'; }).join(' '),
6672 create: function(dialog) {
6673 if (this.instances.length === 0) {
6674 // prevent use of anchors and inputs
6675 // we use a setTimeout in case the overlay is created from an
6676 // event that we're going to be cancelling (see #2804)
6677 setTimeout(function() {
6678 // handle $(el).dialog().dialog('close') (see #4065)
6679 if ($.ui.dialog.overlay.instances.length) {
6680 $(document).bind($.ui.dialog.overlay.events, function(event) {
6681 // stop events if the z-index of the target is < the z-index of the overlay
6682 // we cannot return true when we don't want to cancel the event (#3523)
6683 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
6684 return false;
6685 }
6686 });
6687 }
6688 }, 1);
6689
6690 // allow closing by pressing the escape key
6691 $(document).bind('keydown.dialog-overlay', function(event) {
6692 if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
6693 event.keyCode === $.ui.keyCode.ESCAPE) {
6694
6695 dialog.close(event);
6696 event.preventDefault();
6697 }
6698 });
6699
6700 // handle window resize
6701 $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
6702 }
6703
6704 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
6705 .appendTo(document.body)
6706 .css({
6707 width: this.width(),
6708 height: this.height()
6709 });
6710
6711 if ($.fn.bgiframe) {
6712 $el.bgiframe();
6713 }
6714
6715 this.instances.push($el);
6716 return $el;
6717 },
6718
6719 destroy: function($el) {
6720 var indexOf = $.inArray($el, this.instances);
6721 if (indexOf != -1){
6722 this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
6723 }
6724
6725 if (this.instances.length === 0) {
6726 $([document, window]).unbind('.dialog-overlay');
6727 }
6728
6729 $el.remove();
6730
6731 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6732 var maxZ = 0;
6733 $.each(this.instances, function() {
6734 maxZ = Math.max(maxZ, this.css('z-index'));
6735 });
6736 this.maxZ = maxZ;
6737 },
6738
6739 height: function() {
6740 var scrollHeight,
6741 offsetHeight;
6742 // handle IE 6
6743 if ($.browser.msie && $.browser.version < 7) {
6744 scrollHeight = Math.max(
6745 document.documentElement.scrollHeight,
6746 document.body.scrollHeight
6747 );
6748 offsetHeight = Math.max(
6749 document.documentElement.offsetHeight,
6750 document.body.offsetHeight
6751 );
6752
6753 if (scrollHeight < offsetHeight) {
6754 return $(window).height() + 'px';
6755 } else {
6756 return scrollHeight + 'px';
6757 }
6758 // handle "good" browsers
6759 } else {
6760 return $(document).height() + 'px';
6761 }
6762 },
6763
6764 width: function() {
6765 var scrollWidth,
6766 offsetWidth;
6767 // handle IE
6768 if ( $.browser.msie ) {
6769 scrollWidth = Math.max(
6770 document.documentElement.scrollWidth,
6771 document.body.scrollWidth
6772 );
6773 offsetWidth = Math.max(
6774 document.documentElement.offsetWidth,
6775 document.body.offsetWidth
6776 );
6777
6778 if (scrollWidth < offsetWidth) {
6779 return $(window).width() + 'px';
6780 } else {
6781 return scrollWidth + 'px';
6782 }
6783 // handle "good" browsers
6784 } else {
6785 return $(document).width() + 'px';
6786 }
6787 },
6788
6789 resize: function() {
6790 /* If the dialog is draggable and the user drags it past the
6791 * right edge of the window, the document becomes wider so we
6792 * need to stretch the overlay. If the user then drags the
6793 * dialog back to the left, the document will become narrower,
6794 * so we need to shrink the overlay to the appropriate size.
6795 * This is handled by shrinking the overlay before setting it
6796 * to the full document size.
6797 */
6798 var $overlays = $([]);
6799 $.each($.ui.dialog.overlay.instances, function() {
6800 $overlays = $overlays.add(this);
6801 });
6802
6803 $overlays.css({
6804 width: 0,
6805 height: 0
6806 }).css({
6807 width: $.ui.dialog.overlay.width(),
6808 height: $.ui.dialog.overlay.height()
6809 });
6810 }
6811});
6812
6813$.extend($.ui.dialog.overlay.prototype, {
6814 destroy: function() {
6815 $.ui.dialog.overlay.destroy(this.$el);
6816 }
6817});
6818
6819}(jQuery));
6820/*
6821 * jQuery UI Slider 1.8.16
6822 *
6823 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6824 * Dual licensed under the MIT or GPL Version 2 licenses.
6825 * http://jquery.org/license
6826 *
6827 * http://docs.jquery.com/UI/Slider
6828 *
6829 * Depends:
6830 * jquery.ui.core.js
6831 * jquery.ui.mouse.js
6832 * jquery.ui.widget.js
6833 */
6834(function( $, undefined ) {
6835
6836// number of pages in a slider
6837// (how many times can you page up/down to go through the whole range)
6838var numPages = 5;
6839
6840$.widget( "ui.slider", $.ui.mouse, {
6841
6842 widgetEventPrefix: "slide",
6843
6844 options: {
6845 animate: false,
6846 distance: 0,
6847 max: 100,
6848 min: 0,
6849 orientation: "horizontal",
6850 range: false,
6851 step: 1,
6852 value: 0,
6853 values: null
6854 },
6855
6856 _create: function() {
6857 var self = this,
6858 o = this.options,
6859 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
6860 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
6861 handleCount = ( o.values && o.values.length ) || 1,
6862 handles = [];
6863
6864 this._keySliding = false;
6865 this._mouseSliding = false;
6866 this._animateOff = true;
6867 this._handleIndex = null;
6868 this._detectOrientation();
6869 this._mouseInit();
6870
6871 this.element
6872 .addClass( "ui-slider" +
6873 " ui-slider-" + this.orientation +
6874 " ui-widget" +
6875 " ui-widget-content" +
6876 " ui-corner-all" +
6877 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
6878
6879 this.range = $([]);
6880
6881 if ( o.range ) {
6882 if ( o.range === true ) {
6883 if ( !o.values ) {
6884 o.values = [ this._valueMin(), this._valueMin() ];
6885 }
6886 if ( o.values.length && o.values.length !== 2 ) {
6887 o.values = [ o.values[0], o.values[0] ];
6888 }
6889 }
6890
6891 this.range = $( "<div></div>" )
6892 .appendTo( this.element )
6893 .addClass( "ui-slider-range" +
6894 // note: this isn't the most fittingly semantic framework class for this element,
6895 // but worked best visually with a variety of themes
6896 " ui-widget-header" +
6897 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
6898 }
6899
6900 for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
6901 handles.push( handle );
6902 }
6903
6904 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
6905
6906 this.handle = this.handles.eq( 0 );
6907
6908 this.handles.add( this.range ).filter( "a" )
6909 .click(function( event ) {
6910 event.preventDefault();
6911 })
6912 .hover(function() {
6913 if ( !o.disabled ) {
6914 $( this ).addClass( "ui-state-hover" );
6915 }
6916 }, function() {
6917 $( this ).removeClass( "ui-state-hover" );
6918 })
6919 .focus(function() {
6920 if ( !o.disabled ) {
6921 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
6922 $( this ).addClass( "ui-state-focus" );
6923 } else {
6924 $( this ).blur();
6925 }
6926 })
6927 .blur(function() {
6928 $( this ).removeClass( "ui-state-focus" );
6929 });
6930
6931 this.handles.each(function( i ) {
6932 $( this ).data( "index.ui-slider-handle", i );
6933 });
6934
6935 this.handles
6936 .keydown(function( event ) {
6937 var ret = true,
6938 index = $( this ).data( "index.ui-slider-handle" ),
6939 allowed,
6940 curVal,
6941 newVal,
6942 step;
6943
6944 if ( self.options.disabled ) {
6945 return;
6946 }
6947
6948 switch ( event.keyCode ) {
6949 case $.ui.keyCode.HOME:
6950 case $.ui.keyCode.END:
6951 case $.ui.keyCode.PAGE_UP:
6952 case $.ui.keyCode.PAGE_DOWN:
6953 case $.ui.keyCode.UP:
6954 case $.ui.keyCode.RIGHT:
6955 case $.ui.keyCode.DOWN:
6956 case $.ui.keyCode.LEFT:
6957 ret = false;
6958 if ( !self._keySliding ) {
6959 self._keySliding = true;
6960 $( this ).addClass( "ui-state-active" );
6961 allowed = self._start( event, index );
6962 if ( allowed === false ) {
6963 return;
6964 }
6965 }
6966 break;
6967 }
6968
6969 step = self.options.step;
6970 if ( self.options.values && self.options.values.length ) {
6971 curVal = newVal = self.values( index );
6972 } else {
6973 curVal = newVal = self.value();
6974 }
6975
6976 switch ( event.keyCode ) {
6977 case $.ui.keyCode.HOME:
6978 newVal = self._valueMin();
6979 break;
6980 case $.ui.keyCode.END:
6981 newVal = self._valueMax();
6982 break;
6983 case $.ui.keyCode.PAGE_UP:
6984 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
6985 break;
6986 case $.ui.keyCode.PAGE_DOWN:
6987 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
6988 break;
6989 case $.ui.keyCode.UP:
6990 case $.ui.keyCode.RIGHT:
6991 if ( curVal === self._valueMax() ) {
6992 return;
6993 }
6994 newVal = self._trimAlignValue( curVal + step );
6995 break;
6996 case $.ui.keyCode.DOWN:
6997 case $.ui.keyCode.LEFT:
6998 if ( curVal === self._valueMin() ) {
6999 return;
7000 }
7001 newVal = self._trimAlignValue( curVal - step );
7002 break;
7003 }
7004
7005 self._slide( event, index, newVal );
7006
7007 return ret;
7008
7009 })
7010 .keyup(function( event ) {
7011 var index = $( this ).data( "index.ui-slider-handle" );
7012
7013 if ( self._keySliding ) {
7014 self._keySliding = false;
7015 self._stop( event, index );
7016 self._change( event, index );
7017 $( this ).removeClass( "ui-state-active" );
7018 }
7019
7020 });
7021
7022 this._refreshValue();
7023
7024 this._animateOff = false;
7025 },
7026
7027 destroy: function() {
7028 this.handles.remove();
7029 this.range.remove();
7030
7031 this.element
7032 .removeClass( "ui-slider" +
7033 " ui-slider-horizontal" +
7034 " ui-slider-vertical" +
7035 " ui-slider-disabled" +
7036 " ui-widget" +
7037 " ui-widget-content" +
7038 " ui-corner-all" )
7039 .removeData( "slider" )
7040 .unbind( ".slider" );
7041
7042 this._mouseDestroy();
7043
7044 return this;
7045 },
7046
7047 _mouseCapture: function( event ) {
7048 var o = this.options,
7049 position,
7050 normValue,
7051 distance,
7052 closestHandle,
7053 self,
7054 index,
7055 allowed,
7056 offset,
7057 mouseOverHandle;
7058
7059 if ( o.disabled ) {
7060 return false;
7061 }
7062
7063 this.elementSize = {
7064 width: this.element.outerWidth(),
7065 height: this.element.outerHeight()
7066 };
7067 this.elementOffset = this.element.offset();
7068
7069 position = { x: event.pageX, y: event.pageY };
7070 normValue = this._normValueFromMouse( position );
7071 distance = this._valueMax() - this._valueMin() + 1;
7072 self = this;
7073 this.handles.each(function( i ) {
7074 var thisDistance = Math.abs( normValue - self.values(i) );
7075 if ( distance > thisDistance ) {
7076 distance = thisDistance;
7077 closestHandle = $( this );
7078 index = i;
7079 }
7080 });
7081
7082 // workaround for bug #3736 (if both handles of a range are at 0,
7083 // the first is always used as the one with least distance,
7084 // and moving it is obviously prevented by preventing negative ranges)
7085 if( o.range === true && this.values(1) === o.min ) {
7086 index += 1;
7087 closestHandle = $( this.handles[index] );
7088 }
7089
7090 allowed = this._start( event, index );
7091 if ( allowed === false ) {
7092 return false;
7093 }
7094 this._mouseSliding = true;
7095
7096 self._handleIndex = index;
7097
7098 closestHandle
7099 .addClass( "ui-state-active" )
7100 .focus();
7101
7102 offset = closestHandle.offset();
7103 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
7104 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
7105 left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
7106 top: event.pageY - offset.top -
7107 ( closestHandle.height() / 2 ) -
7108 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
7109 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
7110 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
7111 };
7112
7113 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
7114 this._slide( event, index, normValue );
7115 }
7116 this._animateOff = true;
7117 return true;
7118 },
7119
7120 _mouseStart: function( event ) {
7121 return true;
7122 },
7123
7124 _mouseDrag: function( event ) {
7125 var position = { x: event.pageX, y: event.pageY },
7126 normValue = this._normValueFromMouse( position );
7127
7128 this._slide( event, this._handleIndex, normValue );
7129
7130 return false;
7131 },
7132
7133 _mouseStop: function( event ) {
7134 this.handles.removeClass( "ui-state-active" );
7135 this._mouseSliding = false;
7136
7137 this._stop( event, this._handleIndex );
7138 this._change( event, this._handleIndex );
7139
7140 this._handleIndex = null;
7141 this._clickOffset = null;
7142 this._animateOff = false;
7143
7144 return false;
7145 },
7146
7147 _detectOrientation: function() {
7148 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
7149 },
7150
7151 _normValueFromMouse: function( position ) {
7152 var pixelTotal,
7153 pixelMouse,
7154 percentMouse,
7155 valueTotal,
7156 valueMouse;
7157
7158 if ( this.orientation === "horizontal" ) {
7159 pixelTotal = this.elementSize.width;
7160 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
7161 } else {
7162 pixelTotal = this.elementSize.height;
7163 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
7164 }
7165
7166 percentMouse = ( pixelMouse / pixelTotal );
7167 if ( percentMouse > 1 ) {
7168 percentMouse = 1;
7169 }
7170 if ( percentMouse < 0 ) {
7171 percentMouse = 0;
7172 }
7173 if ( this.orientation === "vertical" ) {
7174 percentMouse = 1 - percentMouse;
7175 }
7176
7177 valueTotal = this._valueMax() - this._valueMin();
7178 valueMouse = this._valueMin() + percentMouse * valueTotal;
7179
7180 return this._trimAlignValue( valueMouse );
7181 },
7182
7183 _start: function( event, index ) {
7184 var uiHash = {
7185 handle: this.handles[ index ],
7186 value: this.value()
7187 };
7188 if ( this.options.values && this.options.values.length ) {
7189 uiHash.value = this.values( index );
7190 uiHash.values = this.values();
7191 }
7192 return this._trigger( "start", event, uiHash );
7193 },
7194
7195 _slide: function( event, index, newVal ) {
7196 var otherVal,
7197 newValues,
7198 allowed;
7199
7200 if ( this.options.values && this.options.values.length ) {
7201 otherVal = this.values( index ? 0 : 1 );
7202
7203 if ( ( this.options.values.length === 2 && this.options.range === true ) &&
7204 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
7205 ) {
7206 newVal = otherVal;
7207 }
7208
7209 if ( newVal !== this.values( index ) ) {
7210 newValues = this.values();
7211 newValues[ index ] = newVal;
7212 // A slide can be canceled by returning false from the slide callback
7213 allowed = this._trigger( "slide", event, {
7214 handle: this.handles[ index ],
7215 value: newVal,
7216 values: newValues
7217 } );
7218 otherVal = this.values( index ? 0 : 1 );
7219 if ( allowed !== false ) {
7220 this.values( index, newVal, true );
7221 }
7222 }
7223 } else {
7224 if ( newVal !== this.value() ) {
7225 // A slide can be canceled by returning false from the slide callback
7226 allowed = this._trigger( "slide", event, {
7227 handle: this.handles[ index ],
7228 value: newVal
7229 } );
7230 if ( allowed !== false ) {
7231 this.value( newVal );
7232 }
7233 }
7234 }
7235 },
7236
7237 _stop: function( event, index ) {
7238 var uiHash = {
7239 handle: this.handles[ index ],
7240 value: this.value()
7241 };
7242 if ( this.options.values && this.options.values.length ) {
7243 uiHash.value = this.values( index );
7244 uiHash.values = this.values();
7245 }
7246
7247 this._trigger( "stop", event, uiHash );
7248 },
7249
7250 _change: function( event, index ) {
7251 if ( !this._keySliding && !this._mouseSliding ) {
7252 var uiHash = {
7253 handle: this.handles[ index ],
7254 value: this.value()
7255 };
7256 if ( this.options.values && this.options.values.length ) {
7257 uiHash.value = this.values( index );
7258 uiHash.values = this.values();
7259 }
7260
7261 this._trigger( "change", event, uiHash );
7262 }
7263 },
7264
7265 value: function( newValue ) {
7266 if ( arguments.length ) {
7267 this.options.value = this._trimAlignValue( newValue );
7268 this._refreshValue();
7269 this._change( null, 0 );
7270 return;
7271 }
7272
7273 return this._value();
7274 },
7275
7276 values: function( index, newValue ) {
7277 var vals,
7278 newValues,
7279 i;
7280
7281 if ( arguments.length > 1 ) {
7282 this.options.values[ index ] = this._trimAlignValue( newValue );
7283 this._refreshValue();
7284 this._change( null, index );
7285 return;
7286 }
7287
7288 if ( arguments.length ) {
7289 if ( $.isArray( arguments[ 0 ] ) ) {
7290 vals = this.options.values;
7291 newValues = arguments[ 0 ];
7292 for ( i = 0; i < vals.length; i += 1 ) {
7293 vals[ i ] = this._trimAlignValue( newValues[ i ] );
7294 this._change( null, i );
7295 }
7296 this._refreshValue();
7297 } else {
7298 if ( this.options.values && this.options.values.length ) {
7299 return this._values( index );
7300 } else {
7301 return this.value();
7302 }
7303 }
7304 } else {
7305 return this._values();
7306 }
7307 },
7308
7309 _setOption: function( key, value ) {
7310 var i,
7311 valsLength = 0;
7312
7313 if ( $.isArray( this.options.values ) ) {
7314 valsLength = this.options.values.length;
7315 }
7316
7317 $.Widget.prototype._setOption.apply( this, arguments );
7318
7319 switch ( key ) {
7320 case "disabled":
7321 if ( value ) {
7322 this.handles.filter( ".ui-state-focus" ).blur();
7323 this.handles.removeClass( "ui-state-hover" );
7324 this.handles.propAttr( "disabled", true );
7325 this.element.addClass( "ui-disabled" );
7326 } else {
7327 this.handles.propAttr( "disabled", false );
7328 this.element.removeClass( "ui-disabled" );
7329 }
7330 break;
7331 case "orientation":
7332 this._detectOrientation();
7333 this.element
7334 .removeClass( "ui-slider-horizontal ui-slider-vertical" )
7335 .addClass( "ui-slider-" + this.orientation );
7336 this._refreshValue();
7337 break;
7338 case "value":
7339 this._animateOff = true;
7340 this._refreshValue();
7341 this._change( null, 0 );
7342 this._animateOff = false;
7343 break;
7344 case "values":
7345 this._animateOff = true;
7346 this._refreshValue();
7347 for ( i = 0; i < valsLength; i += 1 ) {
7348 this._change( null, i );
7349 }
7350 this._animateOff = false;
7351 break;
7352 }
7353 },
7354
7355 //internal value getter
7356 // _value() returns value trimmed by min and max, aligned by step
7357 _value: function() {
7358 var val = this.options.value;
7359 val = this._trimAlignValue( val );
7360
7361 return val;
7362 },
7363
7364 //internal values getter
7365 // _values() returns array of values trimmed by min and max, aligned by step
7366 // _values( index ) returns single value trimmed by min and max, aligned by step
7367 _values: function( index ) {
7368 var val,
7369 vals,
7370 i;
7371
7372 if ( arguments.length ) {
7373 val = this.options.values[ index ];
7374 val = this._trimAlignValue( val );
7375
7376 return val;
7377 } else {
7378 // .slice() creates a copy of the array
7379 // this copy gets trimmed by min and max and then returned
7380 vals = this.options.values.slice();
7381 for ( i = 0; i < vals.length; i+= 1) {
7382 vals[ i ] = this._trimAlignValue( vals[ i ] );
7383 }
7384
7385 return vals;
7386 }
7387 },
7388
7389 // returns the step-aligned value that val is closest to, between (inclusive) min and max
7390 _trimAlignValue: function( val ) {
7391 if ( val <= this._valueMin() ) {
7392 return this._valueMin();
7393 }
7394 if ( val >= this._valueMax() ) {
7395 return this._valueMax();
7396 }
7397 var step = ( this.options.step > 0 ) ? this.options.step : 1,
7398 valModStep = (val - this._valueMin()) % step,
7399 alignValue = val - valModStep;
7400
7401 if ( Math.abs(valModStep) * 2 >= step ) {
7402 alignValue += ( valModStep > 0 ) ? step : ( -step );
7403 }
7404
7405 // Since JavaScript has problems with large floats, round
7406 // the final value to 5 digits after the decimal point (see #4124)
7407 return parseFloat( alignValue.toFixed(5) );
7408 },
7409
7410 _valueMin: function() {
7411 return this.options.min;
7412 },
7413
7414 _valueMax: function() {
7415 return this.options.max;
7416 },
7417
7418 _refreshValue: function() {
7419 var oRange = this.options.range,
7420 o = this.options,
7421 self = this,
7422 animate = ( !this._animateOff ) ? o.animate : false,
7423 valPercent,
7424 _set = {},
7425 lastValPercent,
7426 value,
7427 valueMin,
7428 valueMax;
7429
7430 if ( this.options.values && this.options.values.length ) {
7431 this.handles.each(function( i, j ) {
7432 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
7433 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7434 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7435 if ( self.options.range === true ) {
7436 if ( self.orientation === "horizontal" ) {
7437 if ( i === 0 ) {
7438 self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
7439 }
7440 if ( i === 1 ) {
7441 self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7442 }
7443 } else {
7444 if ( i === 0 ) {
7445 self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
7446 }
7447 if ( i === 1 ) {
7448 self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7449 }
7450 }
7451 }
7452 lastValPercent = valPercent;
7453 });
7454 } else {
7455 value = this.value();
7456 valueMin = this._valueMin();
7457 valueMax = this._valueMax();
7458 valPercent = ( valueMax !== valueMin ) ?
7459 ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
7460 0;
7461 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7462 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7463
7464 if ( oRange === "min" && this.orientation === "horizontal" ) {
7465 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
7466 }
7467 if ( oRange === "max" && this.orientation === "horizontal" ) {
7468 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7469 }
7470 if ( oRange === "min" && this.orientation === "vertical" ) {
7471 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
7472 }
7473 if ( oRange === "max" && this.orientation === "vertical" ) {
7474 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7475 }
7476 }
7477 }
7478
7479});
7480
7481$.extend( $.ui.slider, {
7482 version: "1.8.16"
7483});
7484
7485}(jQuery));
7486/*
7487 * jQuery UI Tabs 1.8.16
7488 *
7489 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
7490 * Dual licensed under the MIT or GPL Version 2 licenses.
7491 * http://jquery.org/license
7492 *
7493 * http://docs.jquery.com/UI/Tabs
7494 *
7495 * Depends:
7496 * jquery.ui.core.js
7497 * jquery.ui.widget.js
7498 */
7499(function( $, undefined ) {
7500
7501var tabId = 0,
7502 listId = 0;
7503
7504function getNextTabId() {
7505 return ++tabId;
7506}
7507
7508function getNextListId() {
7509 return ++listId;
7510}
7511
7512$.widget( "ui.tabs", {
7513 options: {
7514 add: null,
7515 ajaxOptions: null,
7516 cache: false,
7517 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
7518 collapsible: false,
7519 disable: null,
7520 disabled: [],
7521 enable: null,
7522 event: "click",
7523 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
7524 idPrefix: "ui-tabs-",
7525 load: null,
7526 panelTemplate: "<div></div>",
7527 remove: null,
7528 select: null,
7529 show: null,
7530 spinner: "<em>Loading&#8230;</em>",
7531 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
7532 },
7533
7534 _create: function() {
7535 this._tabify( true );
7536 },
7537
7538 _setOption: function( key, value ) {
7539 if ( key == "selected" ) {
7540 if (this.options.collapsible && value == this.options.selected ) {
7541 return;
7542 }
7543 this.select( value );
7544 } else {
7545 this.options[ key ] = value;
7546 this._tabify();
7547 }
7548 },
7549
7550 _tabId: function( a ) {
7551 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
7552 this.options.idPrefix + getNextTabId();
7553 },
7554
7555 _sanitizeSelector: function( hash ) {
7556 // we need this because an id may contain a ":"
7557 return hash.replace( /:/g, "\\:" );
7558 },
7559
7560 _cookie: function() {
7561 var cookie = this.cookie ||
7562 ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
7563 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
7564 },
7565
7566 _ui: function( tab, panel ) {
7567 return {
7568 tab: tab,
7569 panel: panel,
7570 index: this.anchors.index( tab )
7571 };
7572 },
7573
7574 _cleanup: function() {
7575 // restore all former loading tabs labels
7576 this.lis.filter( ".ui-state-processing" )
7577 .removeClass( "ui-state-processing" )
7578 .find( "span:data(label.tabs)" )
7579 .each(function() {
7580 var el = $( this );
7581 el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
7582 });
7583 },
7584
7585 _tabify: function( init ) {
7586 var self = this,
7587 o = this.options,
7588 fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
7589
7590 this.list = this.element.find( "ol,ul" ).eq( 0 );
7591 this.lis = $( " > li:has(a[href])", this.list );
7592 this.anchors = this.lis.map(function() {
7593 return $( "a", this )[ 0 ];
7594 });
7595 this.panels = $( [] );
7596
7597 this.anchors.each(function( i, a ) {
7598 var href = $( a ).attr( "href" );
7599 // For dynamically created HTML that contains a hash as href IE < 8 expands
7600 // such href to the full page url with hash and then misinterprets tab as ajax.
7601 // Same consideration applies for an added tab with a fragment identifier
7602 // since a[href=#fragment-identifier] does unexpectedly not match.
7603 // Thus normalize href attribute...
7604 var hrefBase = href.split( "#" )[ 0 ],
7605 baseEl;
7606 if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
7607 ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
7608 href = a.hash;
7609 a.href = href;
7610 }
7611
7612 // inline tab
7613 if ( fragmentId.test( href ) ) {
7614 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
7615 // remote tab
7616 // prevent loading the page itself if href is just "#"
7617 } else if ( href && href !== "#" ) {
7618 // required for restore on destroy
7619 $.data( a, "href.tabs", href );
7620
7621 // TODO until #3808 is fixed strip fragment identifier from url
7622 // (IE fails to load from such url)
7623 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
7624
7625 var id = self._tabId( a );
7626 a.href = "#" + id;
7627 var $panel = self.element.find( "#" + id );
7628 if ( !$panel.length ) {
7629 $panel = $( o.panelTemplate )
7630 .attr( "id", id )
7631 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
7632 .insertAfter( self.panels[ i - 1 ] || self.list );
7633 $panel.data( "destroy.tabs", true );
7634 }
7635 self.panels = self.panels.add( $panel );
7636 // invalid tab href
7637 } else {
7638 o.disabled.push( i );
7639 }
7640 });
7641
7642 // initialization from scratch
7643 if ( init ) {
7644 // attach necessary classes for styling
7645 this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
7646 this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7647 this.lis.addClass( "ui-state-default ui-corner-top" );
7648 this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
7649
7650 // Selected tab
7651 // use "selected" option or try to retrieve:
7652 // 1. from fragment identifier in url
7653 // 2. from cookie
7654 // 3. from selected class attribute on <li>
7655 if ( o.selected === undefined ) {
7656 if ( location.hash ) {
7657 this.anchors.each(function( i, a ) {
7658 if ( a.hash == location.hash ) {
7659 o.selected = i;
7660 return false;
7661 }
7662 });
7663 }
7664 if ( typeof o.selected !== "number" && o.cookie ) {
7665 o.selected = parseInt( self._cookie(), 10 );
7666 }
7667 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
7668 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7669 }
7670 o.selected = o.selected || ( this.lis.length ? 0 : -1 );
7671 } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
7672 o.selected = -1;
7673 }
7674
7675 // sanity check - default to first tab...
7676 o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
7677 ? o.selected
7678 : 0;
7679
7680 // Take disabling tabs via class attribute from HTML
7681 // into account and update option properly.
7682 // A selected tab cannot become disabled.
7683 o.disabled = $.unique( o.disabled.concat(
7684 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
7685 return self.lis.index( n );
7686 })
7687 ) ).sort();
7688
7689 if ( $.inArray( o.selected, o.disabled ) != -1 ) {
7690 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
7691 }
7692
7693 // highlight selected tab
7694 this.panels.addClass( "ui-tabs-hide" );
7695 this.lis.removeClass( "ui-tabs-selected ui-state-active" );
7696 // check for length avoids error when initializing empty list
7697 if ( o.selected >= 0 && this.anchors.length ) {
7698 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
7699 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
7700
7701 // seems to be expected behavior that the show callback is fired
7702 self.element.queue( "tabs", function() {
7703 self._trigger( "show", null,
7704 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
7705 });
7706
7707 this.load( o.selected );
7708 }
7709
7710 // clean up to avoid memory leaks in certain versions of IE 6
7711 // TODO: namespace this event
7712 $( window ).bind( "unload", function() {
7713 self.lis.add( self.anchors ).unbind( ".tabs" );
7714 self.lis = self.anchors = self.panels = null;
7715 });
7716 // update selected after add/remove
7717 } else {
7718 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7719 }
7720
7721 // update collapsible
7722 // TODO: use .toggleClass()
7723 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
7724
7725 // set or update cookie after init and add/remove respectively
7726 if ( o.cookie ) {
7727 this._cookie( o.selected, o.cookie );
7728 }
7729
7730 // disable tabs
7731 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
7732 $( li )[ $.inArray( i, o.disabled ) != -1 &&
7733 // TODO: use .toggleClass()
7734 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
7735 }
7736
7737 // reset cache if switching from cached to not cached
7738 if ( o.cache === false ) {
7739 this.anchors.removeData( "cache.tabs" );
7740 }
7741
7742 // remove all handlers before, tabify may run on existing tabs after add or option change
7743 this.lis.add( this.anchors ).unbind( ".tabs" );
7744
7745 if ( o.event !== "mouseover" ) {
7746 var addState = function( state, el ) {
7747 if ( el.is( ":not(.ui-state-disabled)" ) ) {
7748 el.addClass( "ui-state-" + state );
7749 }
7750 };
7751 var removeState = function( state, el ) {
7752 el.removeClass( "ui-state-" + state );
7753 };
7754 this.lis.bind( "mouseover.tabs" , function() {
7755 addState( "hover", $( this ) );
7756 });
7757 this.lis.bind( "mouseout.tabs", function() {
7758 removeState( "hover", $( this ) );
7759 });
7760 this.anchors.bind( "focus.tabs", function() {
7761 addState( "focus", $( this ).closest( "li" ) );
7762 });
7763 this.anchors.bind( "blur.tabs", function() {
7764 removeState( "focus", $( this ).closest( "li" ) );
7765 });
7766 }
7767
7768 // set up animations
7769 var hideFx, showFx;
7770 if ( o.fx ) {
7771 if ( $.isArray( o.fx ) ) {
7772 hideFx = o.fx[ 0 ];
7773 showFx = o.fx[ 1 ];
7774 } else {
7775 hideFx = showFx = o.fx;
7776 }
7777 }
7778
7779 // Reset certain styles left over from animation
7780 // and prevent IE's ClearType bug...
7781 function resetStyle( $el, fx ) {
7782 $el.css( "display", "" );
7783 if ( !$.support.opacity && fx.opacity ) {
7784 $el[ 0 ].style.removeAttribute( "filter" );
7785 }
7786 }
7787
7788 // Show a tab...
7789 var showTab = showFx
7790 ? function( clicked, $show ) {
7791 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7792 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
7793 .animate( showFx, showFx.duration || "normal", function() {
7794 resetStyle( $show, showFx );
7795 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7796 });
7797 }
7798 : function( clicked, $show ) {
7799 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7800 $show.removeClass( "ui-tabs-hide" );
7801 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7802 };
7803
7804 // Hide a tab, $show is optional...
7805 var hideTab = hideFx
7806 ? function( clicked, $hide ) {
7807 $hide.animate( hideFx, hideFx.duration || "normal", function() {
7808 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7809 $hide.addClass( "ui-tabs-hide" );
7810 resetStyle( $hide, hideFx );
7811 self.element.dequeue( "tabs" );
7812 });
7813 }
7814 : function( clicked, $hide, $show ) {
7815 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7816 $hide.addClass( "ui-tabs-hide" );
7817 self.element.dequeue( "tabs" );
7818 };
7819
7820 // attach tab event handler, unbind to avoid duplicates from former tabifying...
7821 this.anchors.bind( o.event + ".tabs", function() {
7822 var el = this,
7823 $li = $(el).closest( "li" ),
7824 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
7825 $show = self.element.find( self._sanitizeSelector( el.hash ) );
7826
7827 // If tab is already selected and not collapsible or tab disabled or
7828 // or is already loading or click callback returns false stop here.
7829 // Check if click handler returns false last so that it is not executed
7830 // for a disabled or loading tab!
7831 if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
7832 $li.hasClass( "ui-state-disabled" ) ||
7833 $li.hasClass( "ui-state-processing" ) ||
7834 self.panels.filter( ":animated" ).length ||
7835 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
7836 this.blur();
7837 return false;
7838 }
7839
7840 o.selected = self.anchors.index( this );
7841
7842 self.abort();
7843
7844 // if tab may be closed
7845 if ( o.collapsible ) {
7846 if ( $li.hasClass( "ui-tabs-selected" ) ) {
7847 o.selected = -1;
7848
7849 if ( o.cookie ) {
7850 self._cookie( o.selected, o.cookie );
7851 }
7852
7853 self.element.queue( "tabs", function() {
7854 hideTab( el, $hide );
7855 }).dequeue( "tabs" );
7856
7857 this.blur();
7858 return false;
7859 } else if ( !$hide.length ) {
7860 if ( o.cookie ) {
7861 self._cookie( o.selected, o.cookie );
7862 }
7863
7864 self.element.queue( "tabs", function() {
7865 showTab( el, $show );
7866 });
7867
7868 // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
7869 self.load( self.anchors.index( this ) );
7870
7871 this.blur();
7872 return false;
7873 }
7874 }
7875
7876 if ( o.cookie ) {
7877 self._cookie( o.selected, o.cookie );
7878 }
7879
7880 // show new tab
7881 if ( $show.length ) {
7882 if ( $hide.length ) {
7883 self.element.queue( "tabs", function() {
7884 hideTab( el, $hide );
7885 });
7886 }
7887 self.element.queue( "tabs", function() {
7888 showTab( el, $show );
7889 });
7890
7891 self.load( self.anchors.index( this ) );
7892 } else {
7893 throw "jQuery UI Tabs: Mismatching fragment identifier.";
7894 }
7895
7896 // Prevent IE from keeping other link focussed when using the back button
7897 // and remove dotted border from clicked link. This is controlled via CSS
7898 // in modern browsers; blur() removes focus from address bar in Firefox
7899 // which can become a usability and annoying problem with tabs('rotate').
7900 if ( $.browser.msie ) {
7901 this.blur();
7902 }
7903 });
7904
7905 // disable click in any case
7906 this.anchors.bind( "click.tabs", function(){
7907 return false;
7908 });
7909 },
7910
7911 _getIndex: function( index ) {
7912 // meta-function to give users option to provide a href string instead of a numerical index.
7913 // also sanitizes numerical indexes to valid values.
7914 if ( typeof index == "string" ) {
7915 index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
7916 }
7917
7918 return index;
7919 },
7920
7921 destroy: function() {
7922 var o = this.options;
7923
7924 this.abort();
7925
7926 this.element
7927 .unbind( ".tabs" )
7928 .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
7929 .removeData( "tabs" );
7930
7931 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7932
7933 this.anchors.each(function() {
7934 var href = $.data( this, "href.tabs" );
7935 if ( href ) {
7936 this.href = href;
7937 }
7938 var $this = $( this ).unbind( ".tabs" );
7939 $.each( [ "href", "load", "cache" ], function( i, prefix ) {
7940 $this.removeData( prefix + ".tabs" );
7941 });
7942 });
7943
7944 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
7945 if ( $.data( this, "destroy.tabs" ) ) {
7946 $( this ).remove();
7947 } else {
7948 $( this ).removeClass([
7949 "ui-state-default",
7950 "ui-corner-top",
7951 "ui-tabs-selected",
7952 "ui-state-active",
7953 "ui-state-hover",
7954 "ui-state-focus",
7955 "ui-state-disabled",
7956 "ui-tabs-panel",
7957 "ui-widget-content",
7958 "ui-corner-bottom",
7959 "ui-tabs-hide"
7960 ].join( " " ) );
7961 }
7962 });
7963
7964 if ( o.cookie ) {
7965 this._cookie( null, o.cookie );
7966 }
7967
7968 return this;
7969 },
7970
7971 add: function( url, label, index ) {
7972 if ( index === undefined ) {
7973 index = this.anchors.length;
7974 }
7975
7976 var self = this,
7977 o = this.options,
7978 $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
7979 id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
7980
7981 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
7982
7983 // try to find an existing element before creating a new one
7984 var $panel = self.element.find( "#" + id );
7985 if ( !$panel.length ) {
7986 $panel = $( o.panelTemplate )
7987 .attr( "id", id )
7988 .data( "destroy.tabs", true );
7989 }
7990 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
7991
7992 if ( index >= this.lis.length ) {
7993 $li.appendTo( this.list );
7994 $panel.appendTo( this.list[ 0 ].parentNode );
7995 } else {
7996 $li.insertBefore( this.lis[ index ] );
7997 $panel.insertBefore( this.panels[ index ] );
7998 }
7999
8000 o.disabled = $.map( o.disabled, function( n, i ) {
8001 return n >= index ? ++n : n;
8002 });
8003
8004 this._tabify();
8005
8006 if ( this.anchors.length == 1 ) {
8007 o.selected = 0;
8008 $li.addClass( "ui-tabs-selected ui-state-active" );
8009 $panel.removeClass( "ui-tabs-hide" );
8010 this.element.queue( "tabs", function() {
8011 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
8012 });
8013
8014 this.load( 0 );
8015 }
8016
8017 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8018 return this;
8019 },
8020
8021 remove: function( index ) {
8022 index = this._getIndex( index );
8023 var o = this.options,
8024 $li = this.lis.eq( index ).remove(),
8025 $panel = this.panels.eq( index ).remove();
8026
8027 // If selected tab was removed focus tab to the right or
8028 // in case the last tab was removed the tab to the left.
8029 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
8030 this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
8031 }
8032
8033 o.disabled = $.map(
8034 $.grep( o.disabled, function(n, i) {
8035 return n != index;
8036 }),
8037 function( n, i ) {
8038 return n >= index ? --n : n;
8039 });
8040
8041 this._tabify();
8042
8043 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
8044 return this;
8045 },
8046
8047 enable: function( index ) {
8048 index = this._getIndex( index );
8049 var o = this.options;
8050 if ( $.inArray( index, o.disabled ) == -1 ) {
8051 return;
8052 }
8053
8054 this.lis.eq( index ).removeClass( "ui-state-disabled" );
8055 o.disabled = $.grep( o.disabled, function( n, i ) {
8056 return n != index;
8057 });
8058
8059 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8060 return this;
8061 },
8062
8063 disable: function( index ) {
8064 index = this._getIndex( index );
8065 var self = this, o = this.options;
8066 // cannot disable already selected tab
8067 if ( index != o.selected ) {
8068 this.lis.eq( index ).addClass( "ui-state-disabled" );
8069
8070 o.disabled.push( index );
8071 o.disabled.sort();
8072
8073 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8074 }
8075
8076 return this;
8077 },
8078
8079 select: function( index ) {
8080 index = this._getIndex( index );
8081 if ( index == -1 ) {
8082 if ( this.options.collapsible && this.options.selected != -1 ) {
8083 index = this.options.selected;
8084 } else {
8085 return this;
8086 }
8087 }
8088 this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
8089 return this;
8090 },
8091
8092 load: function( index ) {
8093 index = this._getIndex( index );
8094 var self = this,
8095 o = this.options,
8096 a = this.anchors.eq( index )[ 0 ],
8097 url = $.data( a, "load.tabs" );
8098
8099 this.abort();
8100
8101 // not remote or from cache
8102 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
8103 this.element.dequeue( "tabs" );
8104 return;
8105 }
8106
8107 // load remote from here on
8108 this.lis.eq( index ).addClass( "ui-state-processing" );
8109
8110 if ( o.spinner ) {
8111 var span = $( "span", a );
8112 span.data( "label.tabs", span.html() ).html( o.spinner );
8113 }
8114
8115 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
8116 url: url,
8117 success: function( r, s ) {
8118 self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
8119
8120 // take care of tab labels
8121 self._cleanup();
8122
8123 if ( o.cache ) {
8124 $.data( a, "cache.tabs", true );
8125 }
8126
8127 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8128 try {
8129 o.ajaxOptions.success( r, s );
8130 }
8131 catch ( e ) {}
8132 },
8133 error: function( xhr, s, e ) {
8134 // take care of tab labels
8135 self._cleanup();
8136
8137 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8138 try {
8139 // Passing index avoid a race condition when this method is
8140 // called after the user has selected another tab.
8141 // Pass the anchor that initiated this request allows
8142 // loadError to manipulate the tab content panel via $(a.hash)
8143 o.ajaxOptions.error( xhr, s, index, a );
8144 }
8145 catch ( e ) {}
8146 }
8147 } ) );
8148
8149 // last, so that load event is fired before show...
8150 self.element.dequeue( "tabs" );
8151
8152 return this;
8153 },
8154
8155 abort: function() {
8156 // stop possibly running animations
8157 this.element.queue( [] );
8158 this.panels.stop( false, true );
8159
8160 // "tabs" queue must not contain more than two elements,
8161 // which are the callbacks for the latest clicked tab...
8162 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
8163
8164 // terminate pending requests from other tabs
8165 if ( this.xhr ) {
8166 this.xhr.abort();
8167 delete this.xhr;
8168 }
8169
8170 // take care of tab labels
8171 this._cleanup();
8172 return this;
8173 },
8174
8175 url: function( index, url ) {
8176 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
8177 return this;
8178 },
8179
8180 length: function() {
8181 return this.anchors.length;
8182 }
8183});
8184
8185$.extend( $.ui.tabs, {
8186 version: "1.8.16"
8187});
8188
8189/*
8190 * Tabs Extensions
8191 */
8192
8193/*
8194 * Rotate
8195 */
8196$.extend( $.ui.tabs.prototype, {
8197 rotation: null,
8198 rotate: function( ms, continuing ) {
8199 var self = this,
8200 o = this.options;
8201
8202 var rotate = self._rotate || ( self._rotate = function( e ) {
8203 clearTimeout( self.rotation );
8204 self.rotation = setTimeout(function() {
8205 var t = o.selected;
8206 self.select( ++t < self.anchors.length ? t : 0 );
8207 }, ms );
8208
8209 if ( e ) {
8210 e.stopPropagation();
8211 }
8212 });
8213
8214 var stop = self._unrotate || ( self._unrotate = !continuing
8215 ? function(e) {
8216 if (e.clientX) { // in case of a true click
8217 self.rotate(null);
8218 }
8219 }
8220 : function( e ) {
8221 t = o.selected;
8222 rotate();
8223 });
8224
8225 // start rotation
8226 if ( ms ) {
8227 this.element.bind( "tabsshow", rotate );
8228 this.anchors.bind( o.event + ".tabs", stop );
8229 rotate();
8230 // stop rotation
8231 } else {
8232 clearTimeout( self.rotation );
8233 this.element.unbind( "tabsshow", rotate );
8234 this.anchors.unbind( o.event + ".tabs", stop );
8235 delete this._rotate;
8236 delete this._unrotate;
8237 }
8238
8239 return this;
8240 }
8241});
8242
8243})( jQuery );
8244/*
8245 * jQuery UI Datepicker 1.8.16
8246 *
8247 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
8248 * Dual licensed under the MIT or GPL Version 2 licenses.
8249 * http://jquery.org/license
8250 *
8251 * http://docs.jquery.com/UI/Datepicker
8252 *
8253 * Depends:
8254 * jquery.ui.core.js
8255 */
8256(function( $, undefined ) {
8257
8258$.extend($.ui, { datepicker: { version: "1.8.16" } });
8259
8260var PROP_NAME = 'datepicker';
8261var dpuuid = new Date().getTime();
8262var instActive;
8263
8264/* Date picker manager.
8265 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8266 Settings for (groups of) date pickers are maintained in an instance object,
8267 allowing multiple different settings on the same page. */
8268
8269function Datepicker() {
8270 this.debug = false; // Change this to true to start debugging
8271 this._curInst = null; // The current instance in use
8272 this._keyEvent = false; // If the last event was a key event
8273 this._disabledInputs = []; // List of date picker inputs that have been disabled
8274 this._datepickerShowing = false; // True if the popup picker is showing , false if not
8275 this._inDialog = false; // True if showing within a "dialog", false if not
8276 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
8277 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
8278 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
8279 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
8280 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
8281 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
8282 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
8283 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
8284 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
8285 this.regional = []; // Available regional settings, indexed by language code
8286 this.regional[''] = { // Default regional settings
8287 closeText: 'Done', // Display text for close link
8288 prevText: 'Prev', // Display text for previous month link
8289 nextText: 'Next', // Display text for next month link
8290 currentText: 'Today', // Display text for current month link
8291 monthNames: ['January','February','March','April','May','June',
8292 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
8293 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
8294 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
8295 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
8296 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
8297 weekHeader: 'Wk', // Column header for week of the year
8298 dateFormat: 'mm/dd/yy', // See format options on parseDate
8299 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8300 isRTL: false, // True if right-to-left language, false if left-to-right
8301 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8302 yearSuffix: '' // Additional text to append to the year in the month headers
8303 };
8304 this._defaults = { // Global defaults for all the date picker instances
8305 showOn: 'focus', // 'focus' for popup on focus,
8306 // 'button' for trigger button, or 'both' for either
8307 showAnim: 'fadeIn', // Name of jQuery animation for popup
8308 showOptions: {}, // Options for enhanced animations
8309 defaultDate: null, // Used when field is blank: actual date,
8310 // +/-number for offset from today, null for today
8311 appendText: '', // Display text following the input box, e.g. showing the format
8312 buttonText: '...', // Text for trigger button
8313 buttonImage: '', // URL for trigger button image
8314 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8315 hideIfNoPrevNext: false, // True to hide next/previous month links
8316 // if not applicable, false to just disable them
8317 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8318 gotoCurrent: false, // True if today link goes back to current selection instead
8319 changeMonth: false, // True if month can be selected directly, false if only prev/next
8320 changeYear: false, // True if year can be selected directly, false if only prev/next
8321 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
8322 // either relative to today's year (-nn:+nn), relative to currently displayed year
8323 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8324 showOtherMonths: false, // True to show dates in other months, false to leave blank
8325 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8326 showWeek: false, // True to show week of the year, false to not show it
8327 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8328 // takes a Date and returns the number of the week for it
8329 shortYearCutoff: '+10', // Short year values < this are in the current century,
8330 // > this are in the previous century,
8331 // string value starting with '+' for current year + value
8332 minDate: null, // The earliest selectable date, or null for no limit
8333 maxDate: null, // The latest selectable date, or null for no limit
8334 duration: 'fast', // Duration of display/closure
8335 beforeShowDay: null, // Function that takes a date and returns an array with
8336 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
8337 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8338 beforeShow: null, // Function that takes an input field and
8339 // returns a set of custom settings for the date picker
8340 onSelect: null, // Define a callback function when a date is selected
8341 onChangeMonthYear: null, // Define a callback function when the month or year is changed
8342 onClose: null, // Define a callback function when the datepicker is closed
8343 numberOfMonths: 1, // Number of months to show at a time
8344 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8345 stepMonths: 1, // Number of months to step back/forward
8346 stepBigMonths: 12, // Number of months to step back/forward for the big links
8347 altField: '', // Selector for an alternate field to store selected dates into
8348 altFormat: '', // The date format to use for the alternate field
8349 constrainInput: true, // The input is constrained by the current date format
8350 showButtonPanel: false, // True to show button panel, false to not show it
8351 autoSize: false, // True to size the input for the date format, false to leave as is
8352 disabled: false // The initial disabled state
8353 };
8354 $.extend(this._defaults, this.regional['']);
8355 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
8356}
8357
8358$.extend(Datepicker.prototype, {
8359 /* Class name added to elements to indicate already configured with a date picker. */
8360 markerClassName: 'hasDatepicker',
8361
8362 //Keep track of the maximum number of rows displayed (see #7043)
8363 maxRows: 4,
8364
8365 /* Debug logging (if enabled). */
8366 log: function () {
8367 if (this.debug)
8368 console.log.apply('', arguments);
8369 },
8370
8371 // TODO rename to "widget" when switching to widget factory
8372 _widgetDatepicker: function() {
8373 return this.dpDiv;
8374 },
8375
8376 /* Override the default settings for all instances of the date picker.
8377 @param settings object - the new settings to use as defaults (anonymous object)
8378 @return the manager object */
8379 setDefaults: function(settings) {
8380 extendRemove(this._defaults, settings || {});
8381 return this;
8382 },
8383
8384 /* Attach the date picker to a jQuery selection.
8385 @param target element - the target input field or division or span
8386 @param settings object - the new settings to use for this date picker instance (anonymous) */
8387 _attachDatepicker: function(target, settings) {
8388 // check for settings on the control itself - in namespace 'date:'
8389 var inlineSettings = null;
8390 for (var attrName in this._defaults) {
8391 var attrValue = target.getAttribute('date:' + attrName);
8392 if (attrValue) {
8393 inlineSettings = inlineSettings || {};
8394 try {
8395 inlineSettings[attrName] = eval(attrValue);
8396 } catch (err) {
8397 inlineSettings[attrName] = attrValue;
8398 }
8399 }
8400 }
8401 var nodeName = target.nodeName.toLowerCase();
8402 var inline = (nodeName == 'div' || nodeName == 'span');
8403 if (!target.id) {
8404 this.uuid += 1;
8405 target.id = 'dp' + this.uuid;
8406 }
8407 var inst = this._newInst($(target), inline);
8408 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
8409 if (nodeName == 'input') {
8410 this._connectDatepicker(target, inst);
8411 } else if (inline) {
8412 this._inlineDatepicker(target, inst);
8413 }
8414 },
8415
8416 /* Create a new instance object. */
8417 _newInst: function(target, inline) {
8418 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
8419 return {id: id, input: target, // associated target
8420 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8421 drawMonth: 0, drawYear: 0, // month being drawn
8422 inline: inline, // is datepicker inline or not
8423 dpDiv: (!inline ? this.dpDiv : // presentation div
8424 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
8425 },
8426
8427 /* Attach the date picker to an input field. */
8428 _connectDatepicker: function(target, inst) {
8429 var input = $(target);
8430 inst.append = $([]);
8431 inst.trigger = $([]);
8432 if (input.hasClass(this.markerClassName))
8433 return;
8434 this._attachments(input, inst);
8435 input.addClass(this.markerClassName).keydown(this._doKeyDown).
8436 keypress(this._doKeyPress).keyup(this._doKeyUp).
8437 bind("setData.datepicker", function(event, key, value) {
8438 inst.settings[key] = value;
8439 }).bind("getData.datepicker", function(event, key) {
8440 return this._get(inst, key);
8441 });
8442 this._autoSize(inst);
8443 $.data(target, PROP_NAME, inst);
8444 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
8445 if( inst.settings.disabled ) {
8446 this._disableDatepicker( target );
8447 }
8448 },
8449
8450 /* Make attachments based on settings. */
8451 _attachments: function(input, inst) {
8452 var appendText = this._get(inst, 'appendText');
8453 var isRTL = this._get(inst, 'isRTL');
8454 if (inst.append)
8455 inst.append.remove();
8456 if (appendText) {
8457 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
8458 input[isRTL ? 'before' : 'after'](inst.append);
8459 }
8460 input.unbind('focus', this._showDatepicker);
8461 if (inst.trigger)
8462 inst.trigger.remove();
8463 var showOn = this._get(inst, 'showOn');
8464 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
8465 input.focus(this._showDatepicker);
8466 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
8467 var buttonText = this._get(inst, 'buttonText');
8468 var buttonImage = this._get(inst, 'buttonImage');
8469 inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
8470 $('<img/>').addClass(this._triggerClass).
8471 attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8472 $('<button type="button"></button>').addClass(this._triggerClass).
8473 html(buttonImage == '' ? buttonText : $('<img/>').attr(
8474 { src:buttonImage, alt:buttonText, title:buttonText })));
8475 input[isRTL ? 'before' : 'after'](inst.trigger);
8476 inst.trigger.click(function() {
8477 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
8478 $.datepicker._hideDatepicker();
8479 else
8480 $.datepicker._showDatepicker(input[0]);
8481 return false;
8482 });
8483 }
8484 },
8485
8486 /* Apply the maximum length for the date format. */
8487 _autoSize: function(inst) {
8488 if (this._get(inst, 'autoSize') && !inst.inline) {
8489 var date = new Date(2009, 12 - 1, 20); // Ensure double digits
8490 var dateFormat = this._get(inst, 'dateFormat');
8491 if (dateFormat.match(/[DM]/)) {
8492 var findMax = function(names) {
8493 var max = 0;
8494 var maxI = 0;
8495 for (var i = 0; i < names.length; i++) {
8496 if (names[i].length > max) {
8497 max = names[i].length;
8498 maxI = i;
8499 }
8500 }
8501 return maxI;
8502 };
8503 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8504 'monthNames' : 'monthNamesShort'))));
8505 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8506 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
8507 }
8508 inst.input.attr('size', this._formatDate(inst, date).length);
8509 }
8510 },
8511
8512 /* Attach an inline date picker to a div. */
8513 _inlineDatepicker: function(target, inst) {
8514 var divSpan = $(target);
8515 if (divSpan.hasClass(this.markerClassName))
8516 return;
8517 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
8518 bind("setData.datepicker", function(event, key, value){
8519 inst.settings[key] = value;
8520 }).bind("getData.datepicker", function(event, key){
8521 return this._get(inst, key);
8522 });
8523 $.data(target, PROP_NAME, inst);
8524 this._setDate(inst, this._getDefaultDate(inst), true);
8525 this._updateDatepicker(inst);
8526 this._updateAlternate(inst);
8527 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
8528 if( inst.settings.disabled ) {
8529 this._disableDatepicker( target );
8530 }
8531 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
8532 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
8533 inst.dpDiv.css( "display", "block" );
8534 },
8535
8536 /* Pop-up the date picker in a "dialog" box.
8537 @param input element - ignored
8538 @param date string or Date - the initial date to display
8539 @param onSelect function - the function to call when a date is selected
8540 @param settings object - update the dialog date picker instance's settings (anonymous object)
8541 @param pos int[2] - coordinates for the dialog's position within the screen or
8542 event - with x/y coordinates or
8543 leave empty for default (screen centre)
8544 @return the manager object */
8545 _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8546 var inst = this._dialogInst; // internal instance
8547 if (!inst) {
8548 this.uuid += 1;
8549 var id = 'dp' + this.uuid;
8550 this._dialogInput = $('<input type="text" id="' + id +
8551 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
8552 this._dialogInput.keydown(this._doKeyDown);
8553 $('body').append(this._dialogInput);
8554 inst = this._dialogInst = this._newInst(this._dialogInput, false);
8555 inst.settings = {};
8556 $.data(this._dialogInput[0], PROP_NAME, inst);
8557 }
8558 extendRemove(inst.settings, settings || {});
8559 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
8560 this._dialogInput.val(date);
8561
8562 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8563 if (!this._pos) {
8564 var browserWidth = document.documentElement.clientWidth;
8565 var browserHeight = document.documentElement.clientHeight;
8566 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8567 var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8568 this._pos = // should use actual width/height below
8569 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8570 }
8571
8572 // move input on screen for focus, but hidden behind dialog
8573 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
8574 inst.settings.onSelect = onSelect;
8575 this._inDialog = true;
8576 this.dpDiv.addClass(this._dialogClass);
8577 this._showDatepicker(this._dialogInput[0]);
8578 if ($.blockUI)
8579 $.blockUI(this.dpDiv);
8580 $.data(this._dialogInput[0], PROP_NAME, inst);
8581 return this;
8582 },
8583
8584 /* Detach a datepicker from its control.
8585 @param target element - the target input field or division or span */
8586 _destroyDatepicker: function(target) {
8587 var $target = $(target);
8588 var inst = $.data(target, PROP_NAME);
8589 if (!$target.hasClass(this.markerClassName)) {
8590 return;
8591 }
8592 var nodeName = target.nodeName.toLowerCase();
8593 $.removeData(target, PROP_NAME);
8594 if (nodeName == 'input') {
8595 inst.append.remove();
8596 inst.trigger.remove();
8597 $target.removeClass(this.markerClassName).
8598 unbind('focus', this._showDatepicker).
8599 unbind('keydown', this._doKeyDown).
8600 unbind('keypress', this._doKeyPress).
8601 unbind('keyup', this._doKeyUp);
8602 } else if (nodeName == 'div' || nodeName == 'span')
8603 $target.removeClass(this.markerClassName).empty();
8604 },
8605
8606 /* Enable the date picker to a jQuery selection.
8607 @param target element - the target input field or division or span */
8608 _enableDatepicker: function(target) {
8609 var $target = $(target);
8610 var inst = $.data(target, PROP_NAME);
8611 if (!$target.hasClass(this.markerClassName)) {
8612 return;
8613 }
8614 var nodeName = target.nodeName.toLowerCase();
8615 if (nodeName == 'input') {
8616 target.disabled = false;
8617 inst.trigger.filter('button').
8618 each(function() { this.disabled = false; }).end().
8619 filter('img').css({opacity: '1.0', cursor: ''});
8620 }
8621 else if (nodeName == 'div' || nodeName == 'span') {
8622 var inline = $target.children('.' + this._inlineClass);
8623 inline.children().removeClass('ui-state-disabled');
8624 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8625 removeAttr("disabled");
8626 }
8627 this._disabledInputs = $.map(this._disabledInputs,
8628 function(value) { return (value == target ? null : value); }); // delete entry
8629 },
8630
8631 /* Disable the date picker to a jQuery selection.
8632 @param target element - the target input field or division or span */
8633 _disableDatepicker: function(target) {
8634 var $target = $(target);
8635 var inst = $.data(target, PROP_NAME);
8636 if (!$target.hasClass(this.markerClassName)) {
8637 return;
8638 }
8639 var nodeName = target.nodeName.toLowerCase();
8640 if (nodeName == 'input') {
8641 target.disabled = true;
8642 inst.trigger.filter('button').
8643 each(function() { this.disabled = true; }).end().
8644 filter('img').css({opacity: '0.5', cursor: 'default'});
8645 }
8646 else if (nodeName == 'div' || nodeName == 'span') {
8647 var inline = $target.children('.' + this._inlineClass);
8648 inline.children().addClass('ui-state-disabled');
8649 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8650 attr("disabled", "disabled");
8651 }
8652 this._disabledInputs = $.map(this._disabledInputs,
8653 function(value) { return (value == target ? null : value); }); // delete entry
8654 this._disabledInputs[this._disabledInputs.length] = target;
8655 },
8656
8657 /* Is the first field in a jQuery collection disabled as a datepicker?
8658 @param target element - the target input field or division or span
8659 @return boolean - true if disabled, false if enabled */
8660 _isDisabledDatepicker: function(target) {
8661 if (!target) {
8662 return false;
8663 }
8664 for (var i = 0; i < this._disabledInputs.length; i++) {
8665 if (this._disabledInputs[i] == target)
8666 return true;
8667 }
8668 return false;
8669 },
8670
8671 /* Retrieve the instance data for the target control.
8672 @param target element - the target input field or division or span
8673 @return object - the associated instance data
8674 @throws error if a jQuery problem getting data */
8675 _getInst: function(target) {
8676 try {
8677 return $.data(target, PROP_NAME);
8678 }
8679 catch (err) {
8680 throw 'Missing instance data for this datepicker';
8681 }
8682 },
8683
8684 /* Update or retrieve the settings for a date picker attached to an input field or division.
8685 @param target element - the target input field or division or span
8686 @param name object - the new settings to update or
8687 string - the name of the setting to change or retrieve,
8688 when retrieving also 'all' for all instance settings or
8689 'defaults' for all global defaults
8690 @param value any - the new value for the setting
8691 (omit if above is an object or to retrieve a value) */
8692 _optionDatepicker: function(target, name, value) {
8693 var inst = this._getInst(target);
8694 if (arguments.length == 2 && typeof name == 'string') {
8695 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
8696 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
8697 this._get(inst, name)) : null));
8698 }
8699 var settings = name || {};
8700 if (typeof name == 'string') {
8701 settings = {};
8702 settings[name] = value;
8703 }
8704 if (inst) {
8705 if (this._curInst == inst) {
8706 this._hideDatepicker();
8707 }
8708 var date = this._getDateDatepicker(target, true);
8709 var minDate = this._getMinMaxDate(inst, 'min');
8710 var maxDate = this._getMinMaxDate(inst, 'max');
8711 extendRemove(inst.settings, settings);
8712 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8713 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
8714 inst.settings.minDate = this._formatDate(inst, minDate);
8715 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
8716 inst.settings.maxDate = this._formatDate(inst, maxDate);
8717 this._attachments($(target), inst);
8718 this._autoSize(inst);
8719 this._setDate(inst, date);
8720 this._updateAlternate(inst);
8721 this._updateDatepicker(inst);
8722 }
8723 },
8724
8725 // change method deprecated
8726 _changeDatepicker: function(target, name, value) {
8727 this._optionDatepicker(target, name, value);
8728 },
8729
8730 /* Redraw the date picker attached to an input field or division.
8731 @param target element - the target input field or division or span */
8732 _refreshDatepicker: function(target) {
8733 var inst = this._getInst(target);
8734 if (inst) {
8735 this._updateDatepicker(inst);
8736 }
8737 },
8738
8739 /* Set the dates for a jQuery selection.
8740 @param target element - the target input field or division or span
8741 @param date Date - the new date */
8742 _setDateDatepicker: function(target, date) {
8743 var inst = this._getInst(target);
8744 if (inst) {
8745 this._setDate(inst, date);
8746 this._updateDatepicker(inst);
8747 this._updateAlternate(inst);
8748 }
8749 },
8750
8751 /* Get the date(s) for the first entry in a jQuery selection.
8752 @param target element - the target input field or division or span
8753 @param noDefault boolean - true if no default date is to be used
8754 @return Date - the current date */
8755 _getDateDatepicker: function(target, noDefault) {
8756 var inst = this._getInst(target);
8757 if (inst && !inst.inline)
8758 this._setDateFromField(inst, noDefault);
8759 return (inst ? this._getDate(inst) : null);
8760 },
8761
8762 /* Handle keystrokes. */
8763 _doKeyDown: function(event) {
8764 var inst = $.datepicker._getInst(event.target);
8765 var handled = true;
8766 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
8767 inst._keyEvent = true;
8768 if ($.datepicker._datepickerShowing)
8769 switch (event.keyCode) {
8770 case 9: $.datepicker._hideDatepicker();
8771 handled = false;
8772 break; // hide on tab out
8773 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
8774 $.datepicker._currentClass + ')', inst.dpDiv);
8775 if (sel[0])
8776 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8777 var onSelect = $.datepicker._get(inst, 'onSelect');
8778 if (onSelect) {
8779 var dateStr = $.datepicker._formatDate(inst);
8780
8781 // trigger custom callback
8782 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8783 }
8784 else
8785 $.datepicker._hideDatepicker();
8786 return false; // don't submit the form
8787 break; // select the value on enter
8788 case 27: $.datepicker._hideDatepicker();
8789 break; // hide on escape
8790 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8791 -$.datepicker._get(inst, 'stepBigMonths') :
8792 -$.datepicker._get(inst, 'stepMonths')), 'M');
8793 break; // previous month/year on page up/+ ctrl
8794 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8795 +$.datepicker._get(inst, 'stepBigMonths') :
8796 +$.datepicker._get(inst, 'stepMonths')), 'M');
8797 break; // next month/year on page down/+ ctrl
8798 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
8799 handled = event.ctrlKey || event.metaKey;
8800 break; // clear on ctrl or command +end
8801 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
8802 handled = event.ctrlKey || event.metaKey;
8803 break; // current on ctrl or command +home
8804 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
8805 handled = event.ctrlKey || event.metaKey;
8806 // -1 day on ctrl or command +left
8807 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8808 -$.datepicker._get(inst, 'stepBigMonths') :
8809 -$.datepicker._get(inst, 'stepMonths')), 'M');
8810 // next month/year on alt +left on Mac
8811 break;
8812 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
8813 handled = event.ctrlKey || event.metaKey;
8814 break; // -1 week on ctrl or command +up
8815 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
8816 handled = event.ctrlKey || event.metaKey;
8817 // +1 day on ctrl or command +right
8818 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8819 +$.datepicker._get(inst, 'stepBigMonths') :
8820 +$.datepicker._get(inst, 'stepMonths')), 'M');
8821 // next month/year on alt +right
8822 break;
8823 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
8824 handled = event.ctrlKey || event.metaKey;
8825 break; // +1 week on ctrl or command +down
8826 default: handled = false;
8827 }
8828 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
8829 $.datepicker._showDatepicker(this);
8830 else {
8831 handled = false;
8832 }
8833 if (handled) {
8834 event.preventDefault();
8835 event.stopPropagation();
8836 }
8837 },
8838
8839 /* Filter entered characters - based on date format. */
8840 _doKeyPress: function(event) {
8841 var inst = $.datepicker._getInst(event.target);
8842 if ($.datepicker._get(inst, 'constrainInput')) {
8843 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
8844 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
8845 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
8846 }
8847 },
8848
8849 /* Synchronise manual entry and field/alternate field. */
8850 _doKeyUp: function(event) {
8851 var inst = $.datepicker._getInst(event.target);
8852 if (inst.input.val() != inst.lastVal) {
8853 try {
8854 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8855 (inst.input ? inst.input.val() : null),
8856 $.datepicker._getFormatConfig(inst));
8857 if (date) { // only if valid
8858 $.datepicker._setDateFromField(inst);
8859 $.datepicker._updateAlternate(inst);
8860 $.datepicker._updateDatepicker(inst);
8861 }
8862 }
8863 catch (event) {
8864 $.datepicker.log(event);
8865 }
8866 }
8867 return true;
8868 },
8869
8870 /* Pop-up the date picker for a given input field.
8871 If false returned from beforeShow event handler do not show.
8872 @param input element - the input field attached to the date picker or
8873 event - if triggered by focus */
8874 _showDatepicker: function(input) {
8875 input = input.target || input;
8876 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
8877 input = $('input', input.parentNode)[0];
8878 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
8879 return;
8880 var inst = $.datepicker._getInst(input);
8881 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
8882 if ( $.datepicker._datepickerShowing ) {
8883 $.datepicker._triggerOnClose($.datepicker._curInst);
8884 }
8885 $.datepicker._curInst.dpDiv.stop(true, true);
8886 }
8887 var beforeShow = $.datepicker._get(inst, 'beforeShow');
8888 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8889 if(beforeShowSettings === false){
8890 //false
8891 return;
8892 }
8893 extendRemove(inst.settings, beforeShowSettings);
8894 inst.lastVal = null;
8895 $.datepicker._lastInput = input;
8896 $.datepicker._setDateFromField(inst);
8897 if ($.datepicker._inDialog) // hide cursor
8898 input.value = '';
8899 if (!$.datepicker._pos) { // position below input
8900 $.datepicker._pos = $.datepicker._findPos(input);
8901 $.datepicker._pos[1] += input.offsetHeight; // add the height
8902 }
8903 var isFixed = false;
8904 $(input).parents().each(function() {
8905 isFixed |= $(this).css('position') == 'fixed';
8906 return !isFixed;
8907 });
8908 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
8909 $.datepicker._pos[0] -= document.documentElement.scrollLeft;
8910 $.datepicker._pos[1] -= document.documentElement.scrollTop;
8911 }
8912 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8913 $.datepicker._pos = null;
8914 //to avoid flashes on Firefox
8915 inst.dpDiv.empty();
8916 // determine sizing offscreen
8917 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
8918 $.datepicker._updateDatepicker(inst);
8919 // fix width for dynamic number of date pickers
8920 // and adjust position before showing
8921 offset = $.datepicker._checkOffset(inst, offset, isFixed);
8922 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8923 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
8924 left: offset.left + 'px', top: offset.top + 'px'});
8925 if (!inst.inline) {
8926 var showAnim = $.datepicker._get(inst, 'showAnim');
8927 var duration = $.datepicker._get(inst, 'duration');
8928 var postProcess = function() {
8929 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8930 if( !! cover.length ){
8931 var borders = $.datepicker._getBorders(inst.dpDiv);
8932 cover.css({left: -borders[0], top: -borders[1],
8933 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
8934 }
8935 };
8936 inst.dpDiv.zIndex($(input).zIndex()+1);
8937 $.datepicker._datepickerShowing = true;
8938 if ($.effects && $.effects[showAnim])
8939 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8940 else
8941 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
8942 if (!showAnim || !duration)
8943 postProcess();
8944 if (inst.input.is(':visible') && !inst.input.is(':disabled'))
8945 inst.input.focus();
8946 $.datepicker._curInst = inst;
8947 }
8948 },
8949
8950 /* Generate the date picker content. */
8951 _updateDatepicker: function(inst) {
8952 var self = this;
8953 self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8954 var borders = $.datepicker._getBorders(inst.dpDiv);
8955 instActive = inst; // for delegate hover events
8956 inst.dpDiv.empty().append(this._generateHTML(inst));
8957 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8958 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
8959 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
8960 }
8961 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
8962 var numMonths = this._getNumberOfMonths(inst);
8963 var cols = numMonths[1];
8964 var width = 17;
8965 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
8966 if (cols > 1)
8967 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
8968 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
8969 'Class']('ui-datepicker-multi');
8970 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
8971 'Class']('ui-datepicker-rtl');
8972 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
8973 // #6694 - don't focus the input if it's already focused
8974 // this breaks the change event in IE
8975 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
8976 inst.input.focus();
8977 // deffered render of the years select (to avoid flashes on Firefox)
8978 if( inst.yearshtml ){
8979 var origyearshtml = inst.yearshtml;
8980 setTimeout(function(){
8981 //assure that inst.yearshtml didn't change.
8982 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8983 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
8984 }
8985 origyearshtml = inst.yearshtml = null;
8986 }, 0);
8987 }
8988 },
8989
8990 /* Retrieve the size of left and top borders for an element.
8991 @param elem (jQuery object) the element of interest
8992 @return (number[2]) the left and top borders */
8993 _getBorders: function(elem) {
8994 var convert = function(value) {
8995 return {thin: 1, medium: 2, thick: 3}[value] || value;
8996 };
8997 return [parseFloat(convert(elem.css('border-left-width'))),
8998 parseFloat(convert(elem.css('border-top-width')))];
8999 },
9000
9001 /* Check positioning to remain on screen. */
9002 _checkOffset: function(inst, offset, isFixed) {
9003 var dpWidth = inst.dpDiv.outerWidth();
9004 var dpHeight = inst.dpDiv.outerHeight();
9005 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
9006 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
9007 var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
9008 var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
9009
9010 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
9011 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
9012 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
9013
9014 // now check if datepicker is showing outside window viewport - move to a better place if so.
9015 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
9016 Math.abs(offset.left + dpWidth - viewWidth) : 0);
9017 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
9018 Math.abs(dpHeight + inputHeight) : 0);
9019
9020 return offset;
9021 },
9022
9023 /* Find an object's position on the screen. */
9024 _findPos: function(obj) {
9025 var inst = this._getInst(obj);
9026 var isRTL = this._get(inst, 'isRTL');
9027 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
9028 obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
9029 }
9030 var position = $(obj).offset();
9031 return [position.left, position.top];
9032 },
9033
9034 /* Trigger custom callback of onClose. */
9035 _triggerOnClose: function(inst) {
9036 var onClose = this._get(inst, 'onClose');
9037 if (onClose)
9038 onClose.apply((inst.input ? inst.input[0] : null),
9039 [(inst.input ? inst.input.val() : ''), inst]);
9040 },
9041
9042 /* Hide the date picker from view.
9043 @param input element - the input field attached to the date picker */
9044 _hideDatepicker: function(input) {
9045 var inst = this._curInst;
9046 if (!inst || (input && inst != $.data(input, PROP_NAME)))
9047 return;
9048 if (this._datepickerShowing) {
9049 var showAnim = this._get(inst, 'showAnim');
9050 var duration = this._get(inst, 'duration');
9051 var postProcess = function() {
9052 $.datepicker._tidyDialog(inst);
9053 this._curInst = null;
9054 };
9055 if ($.effects && $.effects[showAnim])
9056 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
9057 else
9058 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
9059 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
9060 if (!showAnim)
9061 postProcess();
9062 $.datepicker._triggerOnClose(inst);
9063 this._datepickerShowing = false;
9064 this._lastInput = null;
9065 if (this._inDialog) {
9066 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
9067 if ($.blockUI) {
9068 $.unblockUI();
9069 $('body').append(this.dpDiv);
9070 }
9071 }
9072 this._inDialog = false;
9073 }
9074 },
9075
9076 /* Tidy up after a dialog display. */
9077 _tidyDialog: function(inst) {
9078 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
9079 },
9080
9081 /* Close date picker if clicked elsewhere. */
9082 _checkExternalClick: function(event) {
9083 if (!$.datepicker._curInst)
9084 return;
9085 var $target = $(event.target);
9086 if ($target[0].id != $.datepicker._mainDivId &&
9087 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
9088 !$target.hasClass($.datepicker.markerClassName) &&
9089 !$target.hasClass($.datepicker._triggerClass) &&
9090 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
9091 $.datepicker._hideDatepicker();
9092 },
9093
9094 /* Adjust one of the date sub-fields. */
9095 _adjustDate: function(id, offset, period) {
9096 var target = $(id);
9097 var inst = this._getInst(target[0]);
9098 if (this._isDisabledDatepicker(target[0])) {
9099 return;
9100 }
9101 this._adjustInstDate(inst, offset +
9102 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
9103 period);
9104 this._updateDatepicker(inst);
9105 },
9106
9107 /* Action for current link. */
9108 _gotoToday: function(id) {
9109 var target = $(id);
9110 var inst = this._getInst(target[0]);
9111 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
9112 inst.selectedDay = inst.currentDay;
9113 inst.drawMonth = inst.selectedMonth = inst.currentMonth;
9114 inst.drawYear = inst.selectedYear = inst.currentYear;
9115 }
9116 else {
9117 var date = new Date();
9118 inst.selectedDay = date.getDate();
9119 inst.drawMonth = inst.selectedMonth = date.getMonth();
9120 inst.drawYear = inst.selectedYear = date.getFullYear();
9121 }
9122 this._notifyChange(inst);
9123 this._adjustDate(target);
9124 },
9125
9126 /* Action for selecting a new month/year. */
9127 _selectMonthYear: function(id, select, period) {
9128 var target = $(id);
9129 var inst = this._getInst(target[0]);
9130 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
9131 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
9132 parseInt(select.options[select.selectedIndex].value,10);
9133 this._notifyChange(inst);
9134 this._adjustDate(target);
9135 },
9136
9137 /* Action for selecting a day. */
9138 _selectDay: function(id, month, year, td) {
9139 var target = $(id);
9140 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
9141 return;
9142 }
9143 var inst = this._getInst(target[0]);
9144 inst.selectedDay = inst.currentDay = $('a', td).html();
9145 inst.selectedMonth = inst.currentMonth = month;
9146 inst.selectedYear = inst.currentYear = year;
9147 this._selectDate(id, this._formatDate(inst,
9148 inst.currentDay, inst.currentMonth, inst.currentYear));
9149 },
9150
9151 /* Erase the input field and hide the date picker. */
9152 _clearDate: function(id) {
9153 var target = $(id);
9154 var inst = this._getInst(target[0]);
9155 this._selectDate(target, '');
9156 },
9157
9158 /* Update the input field with the selected date. */
9159 _selectDate: function(id, dateStr) {
9160 var target = $(id);
9161 var inst = this._getInst(target[0]);
9162 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9163 if (inst.input)
9164 inst.input.val(dateStr);
9165 this._updateAlternate(inst);
9166 var onSelect = this._get(inst, 'onSelect');
9167 if (onSelect)
9168 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
9169 else if (inst.input)
9170 inst.input.trigger('change'); // fire the change event
9171 if (inst.inline)
9172 this._updateDatepicker(inst);
9173 else {
9174 this._hideDatepicker();
9175 this._lastInput = inst.input[0];
9176 if (typeof(inst.input[0]) != 'object')
9177 inst.input.focus(); // restore focus
9178 this._lastInput = null;
9179 }
9180 },
9181
9182 /* Update any alternate field to synchronise with the main field. */
9183 _updateAlternate: function(inst) {
9184 var altField = this._get(inst, 'altField');
9185 if (altField) { // update alternate field too
9186 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
9187 var date = this._getDate(inst);
9188 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9189 $(altField).each(function() { $(this).val(dateStr); });
9190 }
9191 },
9192
9193 /* Set as beforeShowDay function to prevent selection of weekends.
9194 @param date Date - the date to customise
9195 @return [boolean, string] - is this date selectable?, what is its CSS class? */
9196 noWeekends: function(date) {
9197 var day = date.getDay();
9198 return [(day > 0 && day < 6), ''];
9199 },
9200
9201 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9202 @param date Date - the date to get the week for
9203 @return number - the number of the week within the year that contains this date */
9204 iso8601Week: function(date) {
9205 var checkDate = new Date(date.getTime());
9206 // Find Thursday of this week starting on Monday
9207 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9208 var time = checkDate.getTime();
9209 checkDate.setMonth(0); // Compare with Jan 1
9210 checkDate.setDate(1);
9211 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9212 },
9213
9214 /* Parse a string value into a date object.
9215 See formatDate below for the possible formats.
9216
9217 @param format string - the expected format of the date
9218 @param value string - the date in the above format
9219 @param settings Object - attributes include:
9220 shortYearCutoff number - the cutoff year for determining the century (optional)
9221 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9222 dayNames string[7] - names of the days from Sunday (optional)
9223 monthNamesShort string[12] - abbreviated names of the months (optional)
9224 monthNames string[12] - names of the months (optional)
9225 @return Date - the extracted date value or null if value is blank */
9226 parseDate: function (format, value, settings) {
9227 if (format == null || value == null)
9228 throw 'Invalid arguments';
9229 value = (typeof value == 'object' ? value.toString() : value + '');
9230 if (value == '')
9231 return null;
9232 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
9233 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9234 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9235 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9236 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9237 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9238 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9239 var year = -1;
9240 var month = -1;
9241 var day = -1;
9242 var doy = -1;
9243 var literal = false;
9244 // Check whether a format character is doubled
9245 var lookAhead = function(match) {
9246 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9247 if (matches)
9248 iFormat++;
9249 return matches;
9250 };
9251 // Extract a number from the string value
9252 var getNumber = function(match) {
9253 var isDoubled = lookAhead(match);
9254 var size = (match == '@' ? 14 : (match == '!' ? 20 :
9255 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
9256 var digits = new RegExp('^\\d{1,' + size + '}');
9257 var num = value.substring(iValue).match(digits);
9258 if (!num)
9259 throw 'Missing number at position ' + iValue;
9260 iValue += num[0].length;
9261 return parseInt(num[0], 10);
9262 };
9263 // Extract a name from the string value and convert to an index
9264 var getName = function(match, shortNames, longNames) {
9265 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9266 return [ [k, v] ];
9267 }).sort(function (a, b) {
9268 return -(a[1].length - b[1].length);
9269 });
9270 var index = -1;
9271 $.each(names, function (i, pair) {
9272 var name = pair[1];
9273 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
9274 index = pair[0];
9275 iValue += name.length;
9276 return false;
9277 }
9278 });
9279 if (index != -1)
9280 return index + 1;
9281 else
9282 throw 'Unknown name at position ' + iValue;
9283 };
9284 // Confirm that a literal character matches the string value
9285 var checkLiteral = function() {
9286 if (value.charAt(iValue) != format.charAt(iFormat))
9287 throw 'Unexpected literal at position ' + iValue;
9288 iValue++;
9289 };
9290 var iValue = 0;
9291 for (var iFormat = 0; iFormat < format.length; iFormat++) {
9292 if (literal)
9293 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9294 literal = false;
9295 else
9296 checkLiteral();
9297 else
9298 switch (format.charAt(iFormat)) {
9299 case 'd':
9300 day = getNumber('d');
9301 break;
9302 case 'D':
9303 getName('D', dayNamesShort, dayNames);
9304 break;
9305 case 'o':
9306 doy = getNumber('o');
9307 break;
9308 case 'm':
9309 month = getNumber('m');
9310 break;
9311 case 'M':
9312 month = getName('M', monthNamesShort, monthNames);
9313 break;
9314 case 'y':
9315 year = getNumber('y');
9316 break;
9317 case '@':
9318 var date = new Date(getNumber('@'));
9319 year = date.getFullYear();
9320 month = date.getMonth() + 1;
9321 day = date.getDate();
9322 break;
9323 case '!':
9324 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
9325 year = date.getFullYear();
9326 month = date.getMonth() + 1;
9327 day = date.getDate();
9328 break;
9329 case "'":
9330 if (lookAhead("'"))
9331 checkLiteral();
9332 else
9333 literal = true;
9334 break;
9335 default:
9336 checkLiteral();
9337 }
9338 }
9339 if (iValue < value.length){
9340 throw "Extra/unparsed characters found in date: " + value.substring(iValue);
9341 }
9342 if (year == -1)
9343 year = new Date().getFullYear();
9344 else if (year < 100)
9345 year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9346 (year <= shortYearCutoff ? 0 : -100);
9347 if (doy > -1) {
9348 month = 1;
9349 day = doy;
9350 do {
9351 var dim = this._getDaysInMonth(year, month - 1);
9352 if (day <= dim)
9353 break;
9354 month++;
9355 day -= dim;
9356 } while (true);
9357 }
9358 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9359 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
9360 throw 'Invalid date'; // E.g. 31/02/00
9361 return date;
9362 },
9363
9364 /* Standard date formats. */
9365 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
9366 COOKIE: 'D, dd M yy',
9367 ISO_8601: 'yy-mm-dd',
9368 RFC_822: 'D, d M y',
9369 RFC_850: 'DD, dd-M-y',
9370 RFC_1036: 'D, d M y',
9371 RFC_1123: 'D, d M yy',
9372 RFC_2822: 'D, d M yy',
9373 RSS: 'D, d M y', // RFC 822
9374 TICKS: '!',
9375 TIMESTAMP: '@',
9376 W3C: 'yy-mm-dd', // ISO 8601
9377
9378 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9379 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9380
9381 /* Format a date object into a string value.
9382 The format can be combinations of the following:
9383 d - day of month (no leading zero)
9384 dd - day of month (two digit)
9385 o - day of year (no leading zeros)
9386 oo - day of year (three digit)
9387 D - day name short
9388 DD - day name long
9389 m - month of year (no leading zero)
9390 mm - month of year (two digit)
9391 M - month name short
9392 MM - month name long
9393 y - year (two digit)
9394 yy - year (four digit)
9395 @ - Unix timestamp (ms since 01/01/1970)
9396 ! - Windows ticks (100ns since 01/01/0001)
9397 '...' - literal text
9398 '' - single quote
9399
9400 @param format string - the desired format of the date
9401 @param date Date - the date value to format
9402 @param settings Object - attributes include:
9403 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9404 dayNames string[7] - names of the days from Sunday (optional)
9405 monthNamesShort string[12] - abbreviated names of the months (optional)
9406 monthNames string[12] - names of the months (optional)
9407 @return string - the date in the above format */
9408 formatDate: function (format, date, settings) {
9409 if (!date)
9410 return '';
9411 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9412 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9413 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9414 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9415 // Check whether a format character is doubled
9416 var lookAhead = function(match) {
9417 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9418 if (matches)
9419 iFormat++;
9420 return matches;
9421 };
9422 // Format a number, with leading zero if necessary
9423 var formatNumber = function(match, value, len) {
9424 var num = '' + value;
9425 if (lookAhead(match))
9426 while (num.length < len)
9427 num = '0' + num;
9428 return num;
9429 };
9430 // Format a name, short or long as requested
9431 var formatName = function(match, value, shortNames, longNames) {
9432 return (lookAhead(match) ? longNames[value] : shortNames[value]);
9433 };
9434 var output = '';
9435 var literal = false;
9436 if (date)
9437 for (var iFormat = 0; iFormat < format.length; iFormat++) {
9438 if (literal)
9439 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9440 literal = false;
9441 else
9442 output += format.charAt(iFormat);
9443 else
9444 switch (format.charAt(iFormat)) {
9445 case 'd':
9446 output += formatNumber('d', date.getDate(), 2);
9447 break;
9448 case 'D':
9449 output += formatName('D', date.getDay(), dayNamesShort, dayNames);
9450 break;
9451 case 'o':
9452 output += formatNumber('o',
9453 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9454 break;
9455 case 'm':
9456 output += formatNumber('m', date.getMonth() + 1, 2);
9457 break;
9458 case 'M':
9459 output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
9460 break;
9461 case 'y':
9462 output += (lookAhead('y') ? date.getFullYear() :
9463 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
9464 break;
9465 case '@':
9466 output += date.getTime();
9467 break;
9468 case '!':
9469 output += date.getTime() * 10000 + this._ticksTo1970;
9470 break;
9471 case "'":
9472 if (lookAhead("'"))
9473 output += "'";
9474 else
9475 literal = true;
9476 break;
9477 default:
9478 output += format.charAt(iFormat);
9479 }
9480 }
9481 return output;
9482 },
9483
9484 /* Extract all possible characters from the date format. */
9485 _possibleChars: function (format) {
9486 var chars = '';
9487 var literal = false;
9488 // Check whether a format character is doubled
9489 var lookAhead = function(match) {
9490 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9491 if (matches)
9492 iFormat++;
9493 return matches;
9494 };
9495 for (var iFormat = 0; iFormat < format.length; iFormat++)
9496 if (literal)
9497 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9498 literal = false;
9499 else
9500 chars += format.charAt(iFormat);
9501 else
9502 switch (format.charAt(iFormat)) {
9503 case 'd': case 'm': case 'y': case '@':
9504 chars += '0123456789';
9505 break;
9506 case 'D': case 'M':
9507 return null; // Accept anything
9508 case "'":
9509 if (lookAhead("'"))
9510 chars += "'";
9511 else
9512 literal = true;
9513 break;
9514 default:
9515 chars += format.charAt(iFormat);
9516 }
9517 return chars;
9518 },
9519
9520 /* Get a setting value, defaulting if necessary. */
9521 _get: function(inst, name) {
9522 return inst.settings[name] !== undefined ?
9523 inst.settings[name] : this._defaults[name];
9524 },
9525
9526 /* Parse existing date and initialise date picker. */
9527 _setDateFromField: function(inst, noDefault) {
9528 if (inst.input.val() == inst.lastVal) {
9529 return;
9530 }
9531 var dateFormat = this._get(inst, 'dateFormat');
9532 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
9533 var date, defaultDate;
9534 date = defaultDate = this._getDefaultDate(inst);
9535 var settings = this._getFormatConfig(inst);
9536 try {
9537 date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9538 } catch (event) {
9539 this.log(event);
9540 dates = (noDefault ? '' : dates);
9541 }
9542 inst.selectedDay = date.getDate();
9543 inst.drawMonth = inst.selectedMonth = date.getMonth();
9544 inst.drawYear = inst.selectedYear = date.getFullYear();
9545 inst.currentDay = (dates ? date.getDate() : 0);
9546 inst.currentMonth = (dates ? date.getMonth() : 0);
9547 inst.currentYear = (dates ? date.getFullYear() : 0);
9548 this._adjustInstDate(inst);
9549 },
9550
9551 /* Retrieve the default date shown on opening. */
9552 _getDefaultDate: function(inst) {
9553 return this._restrictMinMax(inst,
9554 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
9555 },
9556
9557 /* A date may be specified as an exact value or a relative one. */
9558 _determineDate: function(inst, date, defaultDate) {
9559 var offsetNumeric = function(offset) {
9560 var date = new Date();
9561 date.setDate(date.getDate() + offset);
9562 return date;
9563 };
9564 var offsetString = function(offset) {
9565 try {
9566 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
9567 offset, $.datepicker._getFormatConfig(inst));
9568 }
9569 catch (e) {
9570 // Ignore
9571 }
9572 var date = (offset.toLowerCase().match(/^c/) ?
9573 $.datepicker._getDate(inst) : null) || new Date();
9574 var year = date.getFullYear();
9575 var month = date.getMonth();
9576 var day = date.getDate();
9577 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
9578 var matches = pattern.exec(offset);
9579 while (matches) {
9580 switch (matches[2] || 'd') {
9581 case 'd' : case 'D' :
9582 day += parseInt(matches[1],10); break;
9583 case 'w' : case 'W' :
9584 day += parseInt(matches[1],10) * 7; break;
9585 case 'm' : case 'M' :
9586 month += parseInt(matches[1],10);
9587 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9588 break;
9589 case 'y': case 'Y' :
9590 year += parseInt(matches[1],10);
9591 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9592 break;
9593 }
9594 matches = pattern.exec(offset);
9595 }
9596 return new Date(year, month, day);
9597 };
9598 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
9599 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9600 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
9601 if (newDate) {
9602 newDate.setHours(0);
9603 newDate.setMinutes(0);
9604 newDate.setSeconds(0);
9605 newDate.setMilliseconds(0);
9606 }
9607 return this._daylightSavingAdjust(newDate);
9608 },
9609
9610 /* Handle switch to/from daylight saving.
9611 Hours may be non-zero on daylight saving cut-over:
9612 > 12 when midnight changeover, but then cannot generate
9613 midnight datetime, so jump to 1AM, otherwise reset.
9614 @param date (Date) the date to check
9615 @return (Date) the corrected date */
9616 _daylightSavingAdjust: function(date) {
9617 if (!date) return null;
9618 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9619 return date;
9620 },
9621
9622 /* Set the date(s) directly. */
9623 _setDate: function(inst, date, noChange) {
9624 var clear = !date;
9625 var origMonth = inst.selectedMonth;
9626 var origYear = inst.selectedYear;
9627 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9628 inst.selectedDay = inst.currentDay = newDate.getDate();
9629 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9630 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9631 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
9632 this._notifyChange(inst);
9633 this._adjustInstDate(inst);
9634 if (inst.input) {
9635 inst.input.val(clear ? '' : this._formatDate(inst));
9636 }
9637 },
9638
9639 /* Retrieve the date(s) directly. */
9640 _getDate: function(inst) {
9641 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
9642 this._daylightSavingAdjust(new Date(
9643 inst.currentYear, inst.currentMonth, inst.currentDay)));
9644 return startDate;
9645 },
9646
9647 /* Generate the HTML for the current state of the date picker. */
9648 _generateHTML: function(inst) {
9649 var today = new Date();
9650 today = this._daylightSavingAdjust(
9651 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
9652 var isRTL = this._get(inst, 'isRTL');
9653 var showButtonPanel = this._get(inst, 'showButtonPanel');
9654 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
9655 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
9656 var numMonths = this._getNumberOfMonths(inst);
9657 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
9658 var stepMonths = this._get(inst, 'stepMonths');
9659 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
9660 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9661 new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9662 var minDate = this._getMinMaxDate(inst, 'min');
9663 var maxDate = this._getMinMaxDate(inst, 'max');
9664 var drawMonth = inst.drawMonth - showCurrentAtPos;
9665 var drawYear = inst.drawYear;
9666 if (drawMonth < 0) {
9667 drawMonth += 12;
9668 drawYear--;
9669 }
9670 if (maxDate) {
9671 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9672 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9673 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9674 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9675 drawMonth--;
9676 if (drawMonth < 0) {
9677 drawMonth = 11;
9678 drawYear--;
9679 }
9680 }
9681 }
9682 inst.drawMonth = drawMonth;
9683 inst.drawYear = drawYear;
9684 var prevText = this._get(inst, 'prevText');
9685 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9686 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9687 this._getFormatConfig(inst)));
9688 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9689 '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9690 '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
9691 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
9692 (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>'));
9693 var nextText = this._get(inst, 'nextText');
9694 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9695 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9696 this._getFormatConfig(inst)));
9697 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9698 '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9699 '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
9700 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
9701 (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>'));
9702 var currentText = this._get(inst, 'currentText');
9703 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
9704 currentText = (!navigationAsDateFormat ? currentText :
9705 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9706 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9707 '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
9708 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
9709 (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9710 '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
9711 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
9712 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
9713 firstDay = (isNaN(firstDay) ? 0 : firstDay);
9714 var showWeek = this._get(inst, 'showWeek');
9715 var dayNames = this._get(inst, 'dayNames');
9716 var dayNamesShort = this._get(inst, 'dayNamesShort');
9717 var dayNamesMin = this._get(inst, 'dayNamesMin');
9718 var monthNames = this._get(inst, 'monthNames');
9719 var monthNamesShort = this._get(inst, 'monthNamesShort');
9720 var beforeShowDay = this._get(inst, 'beforeShowDay');
9721 var showOtherMonths = this._get(inst, 'showOtherMonths');
9722 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
9723 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
9724 var defaultDate = this._getDefaultDate(inst);
9725 var html = '';
9726 for (var row = 0; row < numMonths[0]; row++) {
9727 var group = '';
9728 this.maxRows = 4;
9729 for (var col = 0; col < numMonths[1]; col++) {
9730 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9731 var cornerClass = ' ui-corner-all';
9732 var calender = '';
9733 if (isMultiMonth) {
9734 calender += '<div class="ui-datepicker-group';
9735 if (numMonths[1] > 1)
9736 switch (col) {
9737 case 0: calender += ' ui-datepicker-group-first';
9738 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
9739 case numMonths[1]-1: calender += ' ui-datepicker-group-last';
9740 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
9741 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
9742 }
9743 calender += '">';
9744 }
9745 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
9746 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
9747 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
9748 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9749 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9750 '</div><table class="ui-datepicker-calendar"><thead>' +
9751 '<tr>';
9752 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
9753 for (var dow = 0; dow < 7; dow++) { // days of the week
9754 var day = (dow + firstDay) % 7;
9755 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
9756 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
9757 }
9758 calender += thead + '</tr></thead><tbody>';
9759 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9760 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
9761 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9762 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9763 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9764 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9765 this.maxRows = numRows;
9766 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9767 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9768 calender += '<tr>';
9769 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
9770 this._get(inst, 'calculateWeek')(printDate) + '</td>');
9771 for (var dow = 0; dow < 7; dow++) { // create date picker days
9772 var daySettings = (beforeShowDay ?
9773 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
9774 var otherMonth = (printDate.getMonth() != drawMonth);
9775 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9776 (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9777 tbody += '<td class="' +
9778 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
9779 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
9780 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
9781 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
9782 // or defaultDate is current printedDate and defaultDate is selectedDate
9783 ' ' + this._dayOverClass : '') + // highlight selected day
9784 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
9785 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
9786 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
9787 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
9788 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
9789 (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
9790 inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
9791 (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
9792 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
9793 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
9794 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
9795 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
9796 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
9797 printDate.setDate(printDate.getDate() + 1);
9798 printDate = this._daylightSavingAdjust(printDate);
9799 }
9800 calender += tbody + '</tr>';
9801 }
9802 drawMonth++;
9803 if (drawMonth > 11) {
9804 drawMonth = 0;
9805 drawYear++;
9806 }
9807 calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
9808 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
9809 group += calender;
9810 }
9811 html += group;
9812 }
9813 html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
9814 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
9815 inst._keyEvent = false;
9816 return html;
9817 },
9818
9819 /* Generate the month and year header. */
9820 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9821 secondary, monthNames, monthNamesShort) {
9822 var changeMonth = this._get(inst, 'changeMonth');
9823 var changeYear = this._get(inst, 'changeYear');
9824 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
9825 var html = '<div class="ui-datepicker-title">';
9826 var monthHtml = '';
9827 // month selection
9828 if (secondary || !changeMonth)
9829 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
9830 else {
9831 var inMinYear = (minDate && minDate.getFullYear() == drawYear);
9832 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
9833 monthHtml += '<select class="ui-datepicker-month" ' +
9834 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
9835 '>';
9836 for (var month = 0; month < 12; month++) {
9837 if ((!inMinYear || month >= minDate.getMonth()) &&
9838 (!inMaxYear || month <= maxDate.getMonth()))
9839 monthHtml += '<option value="' + month + '"' +
9840 (month == drawMonth ? ' selected="selected"' : '') +
9841 '>' + monthNamesShort[month] + '</option>';
9842 }
9843 monthHtml += '</select>';
9844 }
9845 if (!showMonthAfterYear)
9846 html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
9847 // year selection
9848 if ( !inst.yearshtml ) {
9849 inst.yearshtml = '';
9850 if (secondary || !changeYear)
9851 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
9852 else {
9853 // determine range of years to display
9854 var years = this._get(inst, 'yearRange').split(':');
9855 var thisYear = new Date().getFullYear();
9856 var determineYear = function(value) {
9857 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9858 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
9859 parseInt(value, 10)));
9860 return (isNaN(year) ? thisYear : year);
9861 };
9862 var year = determineYear(years[0]);
9863 var endYear = Math.max(year, determineYear(years[1] || ''));
9864 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9865 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9866 inst.yearshtml += '<select class="ui-datepicker-year" ' +
9867 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
9868 '>';
9869 for (; year <= endYear; year++) {
9870 inst.yearshtml += '<option value="' + year + '"' +
9871 (year == drawYear ? ' selected="selected"' : '') +
9872 '>' + year + '</option>';
9873 }
9874 inst.yearshtml += '</select>';
9875
9876 html += inst.yearshtml;
9877 inst.yearshtml = null;
9878 }
9879 }
9880 html += this._get(inst, 'yearSuffix');
9881 if (showMonthAfterYear)
9882 html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
9883 html += '</div>'; // Close datepicker_header
9884 return html;
9885 },
9886
9887 /* Adjust one of the date sub-fields. */
9888 _adjustInstDate: function(inst, offset, period) {
9889 var year = inst.drawYear + (period == 'Y' ? offset : 0);
9890 var month = inst.drawMonth + (period == 'M' ? offset : 0);
9891 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
9892 (period == 'D' ? offset : 0);
9893 var date = this._restrictMinMax(inst,
9894 this._daylightSavingAdjust(new Date(year, month, day)));
9895 inst.selectedDay = date.getDate();
9896 inst.drawMonth = inst.selectedMonth = date.getMonth();
9897 inst.drawYear = inst.selectedYear = date.getFullYear();
9898 if (period == 'M' || period == 'Y')
9899 this._notifyChange(inst);
9900 },
9901
9902 /* Ensure a date is within any min/max bounds. */
9903 _restrictMinMax: function(inst, date) {
9904 var minDate = this._getMinMaxDate(inst, 'min');
9905 var maxDate = this._getMinMaxDate(inst, 'max');
9906 var newDate = (minDate && date < minDate ? minDate : date);
9907 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
9908 return newDate;
9909 },
9910
9911 /* Notify change of month/year. */
9912 _notifyChange: function(inst) {
9913 var onChange = this._get(inst, 'onChangeMonthYear');
9914 if (onChange)
9915 onChange.apply((inst.input ? inst.input[0] : null),
9916 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9917 },
9918
9919 /* Determine the number of months to show. */
9920 _getNumberOfMonths: function(inst) {
9921 var numMonths = this._get(inst, 'numberOfMonths');
9922 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
9923 },
9924
9925 /* Determine the current maximum date - ensure no time components are set. */
9926 _getMinMaxDate: function(inst, minMax) {
9927 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
9928 },
9929
9930 /* Find the number of days in a given month. */
9931 _getDaysInMonth: function(year, month) {
9932 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9933 },
9934
9935 /* Find the day of the week of the first of a month. */
9936 _getFirstDayOfMonth: function(year, month) {
9937 return new Date(year, month, 1).getDay();
9938 },
9939
9940 /* Determines if we should allow a "next/prev" month display change. */
9941 _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9942 var numMonths = this._getNumberOfMonths(inst);
9943 var date = this._daylightSavingAdjust(new Date(curYear,
9944 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9945 if (offset < 0)
9946 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9947 return this._isInRange(inst, date);
9948 },
9949
9950 /* Is the given date in the accepted range? */
9951 _isInRange: function(inst, date) {
9952 var minDate = this._getMinMaxDate(inst, 'min');
9953 var maxDate = this._getMinMaxDate(inst, 'max');
9954 return ((!minDate || date.getTime() >= minDate.getTime()) &&
9955 (!maxDate || date.getTime() <= maxDate.getTime()));
9956 },
9957
9958 /* Provide the configuration settings for formatting/parsing. */
9959 _getFormatConfig: function(inst) {
9960 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
9961 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9962 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9963 return {shortYearCutoff: shortYearCutoff,
9964 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
9965 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
9966 },
9967
9968 /* Format the given date for display. */
9969 _formatDate: function(inst, day, month, year) {
9970 if (!day) {
9971 inst.currentDay = inst.selectedDay;
9972 inst.currentMonth = inst.selectedMonth;
9973 inst.currentYear = inst.selectedYear;
9974 }
9975 var date = (day ? (typeof day == 'object' ? day :
9976 this._daylightSavingAdjust(new Date(year, month, day))) :
9977 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9978 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
9979 }
9980});
9981
9982/*
9983 * Bind hover events for datepicker elements.
9984 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9985 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9986 */
9987function bindHover(dpDiv) {
9988 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
9989 return dpDiv.bind('mouseout', function(event) {
9990 var elem = $( event.target ).closest( selector );
9991 if ( !elem.length ) {
9992 return;
9993 }
9994 elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
9995 })
9996 .bind('mouseover', function(event) {
9997 var elem = $( event.target ).closest( selector );
9998 if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
9999 !elem.length ) {
10000 return;
10001 }
10002 elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
10003 elem.addClass('ui-state-hover');
10004 if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
10005 if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
10006 });
10007}
10008
10009/* jQuery extend now ignores nulls! */
10010function extendRemove(target, props) {
10011 $.extend(target, props);
10012 for (var name in props)
10013 if (props[name] == null || props[name] == undefined)
10014 target[name] = props[name];
10015 return target;
10016};
10017
10018/* Determine whether an object is an array. */
10019function isArray(a) {
10020 return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
10021 (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
10022};
10023
10024/* Invoke the datepicker functionality.
10025 @param options string - a command, optionally followed by additional parameters or
10026 Object - settings for attaching new datepicker functionality
10027 @return jQuery object */
10028$.fn.datepicker = function(options){
10029
10030 /* Verify an empty collection wasn't passed - Fixes #6976 */
10031 if ( !this.length ) {
10032 return this;
10033 }
10034
10035 /* Initialise the date picker. */
10036 if (!$.datepicker.initialized) {
10037 $(document).mousedown($.datepicker._checkExternalClick).
10038 find('body').append($.datepicker.dpDiv);
10039 $.datepicker.initialized = true;
10040 }
10041
10042 var otherArgs = Array.prototype.slice.call(arguments, 1);
10043 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
10044 return $.datepicker['_' + options + 'Datepicker'].
10045 apply($.datepicker, [this[0]].concat(otherArgs));
10046 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
10047 return $.datepicker['_' + options + 'Datepicker'].
10048 apply($.datepicker, [this[0]].concat(otherArgs));
10049 return this.each(function() {
10050 typeof options == 'string' ?
10051 $.datepicker['_' + options + 'Datepicker'].
10052 apply($.datepicker, [this].concat(otherArgs)) :
10053 $.datepicker._attachDatepicker(this, options);
10054 });
10055};
10056
10057$.datepicker = new Datepicker(); // singleton instance
10058$.datepicker.initialized = false;
10059$.datepicker.uuid = new Date().getTime();
10060$.datepicker.version = "1.8.16";
10061
10062// Workaround for #4055
10063// Add another global to avoid noConflict issues with inline event handlers
10064window['DP_jQuery_' + dpuuid] = $;
10065
10066})(jQuery);
10067/*
10068 * jQuery UI Progressbar 1.8.16
10069 *
10070 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10071 * Dual licensed under the MIT or GPL Version 2 licenses.
10072 * http://jquery.org/license
10073 *
10074 * http://docs.jquery.com/UI/Progressbar
10075 *
10076 * Depends:
10077 * jquery.ui.core.js
10078 * jquery.ui.widget.js
10079 */
10080(function( $, undefined ) {
10081
10082$.widget( "ui.progressbar", {
10083 options: {
10084 value: 0,
10085 max: 100
10086 },
10087
10088 min: 0,
10089
10090 _create: function() {
10091 this.element
10092 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10093 .attr({
10094 role: "progressbar",
10095 "aria-valuemin": this.min,
10096 "aria-valuemax": this.options.max,
10097 "aria-valuenow": this._value()
10098 });
10099
10100 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10101 .appendTo( this.element );
10102
10103 this.oldValue = this._value();
10104 this._refreshValue();
10105 },
10106
10107 destroy: function() {
10108 this.element
10109 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10110 .removeAttr( "role" )
10111 .removeAttr( "aria-valuemin" )
10112 .removeAttr( "aria-valuemax" )
10113 .removeAttr( "aria-valuenow" );
10114
10115 this.valueDiv.remove();
10116
10117 $.Widget.prototype.destroy.apply( this, arguments );
10118 },
10119
10120 value: function( newValue ) {
10121 if ( newValue === undefined ) {
10122 return this._value();
10123 }
10124
10125 this._setOption( "value", newValue );
10126 return this;
10127 },
10128
10129 _setOption: function( key, value ) {
10130 if ( key === "value" ) {
10131 this.options.value = value;
10132 this._refreshValue();
10133 if ( this._value() === this.options.max ) {
10134 this._trigger( "complete" );
10135 }
10136 }
10137
10138 $.Widget.prototype._setOption.apply( this, arguments );
10139 },
10140
10141 _value: function() {
10142 var val = this.options.value;
10143 // normalize invalid value
10144 if ( typeof val !== "number" ) {
10145 val = 0;
10146 }
10147 return Math.min( this.options.max, Math.max( this.min, val ) );
10148 },
10149
10150 _percentage: function() {
10151 return 100 * this._value() / this.options.max;
10152 },
10153
10154 _refreshValue: function() {
10155 var value = this.value();
10156 var percentage = this._percentage();
10157
10158 if ( this.oldValue !== value ) {
10159 this.oldValue = value;
10160 this._trigger( "change" );
10161 }
10162
10163 this.valueDiv
10164 .toggle( value > this.min )
10165 .toggleClass( "ui-corner-right", value === this.options.max )
10166 .width( percentage.toFixed(0) + "%" );
10167 this.element.attr( "aria-valuenow", value );
10168 }
10169});
10170
10171$.extend( $.ui.progressbar, {
10172 version: "1.8.16"
10173});
10174
10175})( jQuery );
10176/*
10177 * jQuery UI Effects 1.8.16
10178 *
10179 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10180 * Dual licensed under the MIT or GPL Version 2 licenses.
10181 * http://jquery.org/license
10182 *
10183 * http://docs.jquery.com/UI/Effects/
10184 */
10185;jQuery.effects || (function($, undefined) {
10186
10187$.effects = {};
10188
10189
10190
10191/******************************************************************************/
10192/****************************** COLOR ANIMATIONS ******************************/
10193/******************************************************************************/
10194
10195// override the animation for color styles
10196$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
10197 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
10198function(i, attr) {
10199 $.fx.step[attr] = function(fx) {
10200 if (!fx.colorInit) {
10201 fx.start = getColor(fx.elem, attr);
10202 fx.end = getRGB(fx.end);
10203 fx.colorInit = true;
10204 }
10205
10206 fx.elem.style[attr] = 'rgb(' +
10207 Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
10208 Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
10209 Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
10210 };
10211});
10212
10213// Color Conversion functions from highlightFade
10214// By Blair Mitchelmore
10215// http://jquery.offput.ca/highlightFade/
10216
10217// Parse strings looking for color tuples [255,255,255]
10218function getRGB(color) {
10219 var result;
10220
10221 // Check if we're already dealing with an array of colors
10222 if ( color && color.constructor == Array && color.length == 3 )
10223 return color;
10224
10225 // Look for rgb(num,num,num)
10226 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
10227 return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
10228
10229 // Look for rgb(num%,num%,num%)
10230 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
10231 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
10232
10233 // Look for #a0b1c2
10234 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
10235 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
10236
10237 // Look for #fff
10238 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
10239 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
10240
10241 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
10242 if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
10243 return colors['transparent'];
10244
10245 // Otherwise, we're most likely dealing with a named color
10246 return colors[$.trim(color).toLowerCase()];
10247}
10248
10249function getColor(elem, attr) {
10250 var color;
10251
10252 do {
10253 color = $.curCSS(elem, attr);
10254
10255 // Keep going until we find an element that has color, or we hit the body
10256 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
10257 break;
10258
10259 attr = "backgroundColor";
10260 } while ( elem = elem.parentNode );
10261
10262 return getRGB(color);
10263};
10264
10265// Some named colors to work with
10266// From Interface by Stefan Petre
10267// http://interface.eyecon.ro/
10268
10269var colors = {
10270 aqua:[0,255,255],
10271 azure:[240,255,255],
10272 beige:[245,245,220],
10273 black:[0,0,0],
10274 blue:[0,0,255],
10275 brown:[165,42,42],
10276 cyan:[0,255,255],
10277 darkblue:[0,0,139],
10278 darkcyan:[0,139,139],
10279 darkgrey:[169,169,169],
10280 darkgreen:[0,100,0],
10281 darkkhaki:[189,183,107],
10282 darkmagenta:[139,0,139],
10283 darkolivegreen:[85,107,47],
10284 darkorange:[255,140,0],
10285 darkorchid:[153,50,204],
10286 darkred:[139,0,0],
10287 darksalmon:[233,150,122],
10288 darkviolet:[148,0,211],
10289 fuchsia:[255,0,255],
10290 gold:[255,215,0],
10291 green:[0,128,0],
10292 indigo:[75,0,130],
10293 khaki:[240,230,140],
10294 lightblue:[173,216,230],
10295 lightcyan:[224,255,255],
10296 lightgreen:[144,238,144],
10297 lightgrey:[211,211,211],
10298 lightpink:[255,182,193],
10299 lightyellow:[255,255,224],
10300 lime:[0,255,0],
10301 magenta:[255,0,255],
10302 maroon:[128,0,0],
10303 navy:[0,0,128],
10304 olive:[128,128,0],
10305 orange:[255,165,0],
10306 pink:[255,192,203],
10307 purple:[128,0,128],
10308 violet:[128,0,128],
10309 red:[255,0,0],
10310 silver:[192,192,192],
10311 white:[255,255,255],
10312 yellow:[255,255,0],
10313 transparent: [255,255,255]
10314};
10315
10316
10317
10318/******************************************************************************/
10319/****************************** CLASS ANIMATIONS ******************************/
10320/******************************************************************************/
10321
10322var classAnimationActions = ['add', 'remove', 'toggle'],
10323 shorthandStyles = {
10324 border: 1,
10325 borderBottom: 1,
10326 borderColor: 1,
10327 borderLeft: 1,
10328 borderRight: 1,
10329 borderTop: 1,
10330 borderWidth: 1,
10331 margin: 1,
10332 padding: 1
10333 };
10334
10335function getElementStyles() {
10336 var style = document.defaultView
10337 ? document.defaultView.getComputedStyle(this, null)
10338 : this.currentStyle,
10339 newStyle = {},
10340 key,
10341 camelCase;
10342
10343 // webkit enumerates style porperties
10344 if (style && style.length && style[0] && style[style[0]]) {
10345 var len = style.length;
10346 while (len--) {
10347 key = style[len];
10348 if (typeof style[key] == 'string') {
10349 camelCase = key.replace(/\-(\w)/g, function(all, letter){
10350 return letter.toUpperCase();
10351 });
10352 newStyle[camelCase] = style[key];
10353 }
10354 }
10355 } else {
10356 for (key in style) {
10357 if (typeof style[key] === 'string') {
10358 newStyle[key] = style[key];
10359 }
10360 }
10361 }
10362
10363 return newStyle;
10364}
10365
10366function filterStyles(styles) {
10367 var name, value;
10368 for (name in styles) {
10369 value = styles[name];
10370 if (
10371 // ignore null and undefined values
10372 value == null ||
10373 // ignore functions (when does this occur?)
10374 $.isFunction(value) ||
10375 // shorthand styles that need to be expanded
10376 name in shorthandStyles ||
10377 // ignore scrollbars (break in IE)
10378 (/scrollbar/).test(name) ||
10379
10380 // only colors or values that can be converted to numbers
10381 (!(/color/i).test(name) && isNaN(parseFloat(value)))
10382 ) {
10383 delete styles[name];
10384 }
10385 }
10386
10387 return styles;
10388}
10389
10390function styleDifference(oldStyle, newStyle) {
10391 var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
10392 name;
10393
10394 for (name in newStyle) {
10395 if (oldStyle[name] != newStyle[name]) {
10396 diff[name] = newStyle[name];
10397 }
10398 }
10399
10400 return diff;
10401}
10402
10403$.effects.animateClass = function(value, duration, easing, callback) {
10404 if ($.isFunction(easing)) {
10405 callback = easing;
10406 easing = null;
10407 }
10408
10409 return this.queue(function() {
10410 var that = $(this),
10411 originalStyleAttr = that.attr('style') || ' ',
10412 originalStyle = filterStyles(getElementStyles.call(this)),
10413 newStyle,
10414 className = that.attr('class');
10415
10416 $.each(classAnimationActions, function(i, action) {
10417 if (value[action]) {
10418 that[action + 'Class'](value[action]);
10419 }
10420 });
10421 newStyle = filterStyles(getElementStyles.call(this));
10422 that.attr('class', className);
10423
10424 that.animate(styleDifference(originalStyle, newStyle), {
10425 queue: false,
10426 duration: duration,
10427 easing: easing,
10428 complete: function() {
10429 $.each(classAnimationActions, function(i, action) {
10430 if (value[action]) { that[action + 'Class'](value[action]); }
10431 });
10432 // work around bug in IE by clearing the cssText before setting it
10433 if (typeof that.attr('style') == 'object') {
10434 that.attr('style').cssText = '';
10435 that.attr('style').cssText = originalStyleAttr;
10436 } else {
10437 that.attr('style', originalStyleAttr);
10438 }
10439 if (callback) { callback.apply(this, arguments); }
10440 $.dequeue( this );
10441 }
10442 });
10443 });
10444};
10445
10446$.fn.extend({
10447 _addClass: $.fn.addClass,
10448 addClass: function(classNames, speed, easing, callback) {
10449 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
10450 },
10451
10452 _removeClass: $.fn.removeClass,
10453 removeClass: function(classNames,speed,easing,callback) {
10454 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
10455 },
10456
10457 _toggleClass: $.fn.toggleClass,
10458 toggleClass: function(classNames, force, speed, easing, callback) {
10459 if ( typeof force == "boolean" || force === undefined ) {
10460 if ( !speed ) {
10461 // without speed parameter;
10462 return this._toggleClass(classNames, force);
10463 } else {
10464 return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
10465 }
10466 } else {
10467 // without switch parameter;
10468 return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
10469 }
10470 },
10471
10472 switchClass: function(remove,add,speed,easing,callback) {
10473 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
10474 }
10475});
10476
10477
10478
10479/******************************************************************************/
10480/*********************************** EFFECTS **********************************/
10481/******************************************************************************/
10482
10483$.extend($.effects, {
10484 version: "1.8.16",
10485
10486 // Saves a set of properties in a data storage
10487 save: function(element, set) {
10488 for(var i=0; i < set.length; i++) {
10489 if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
10490 }
10491 },
10492
10493 // Restores a set of previously saved properties from a data storage
10494 restore: function(element, set) {
10495 for(var i=0; i < set.length; i++) {
10496 if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
10497 }
10498 },
10499
10500 setMode: function(el, mode) {
10501 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
10502 return mode;
10503 },
10504
10505 getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
10506 // this should be a little more flexible in the future to handle a string & hash
10507 var y, x;
10508 switch (origin[0]) {
10509 case 'top': y = 0; break;
10510 case 'middle': y = 0.5; break;
10511 case 'bottom': y = 1; break;
10512 default: y = origin[0] / original.height;
10513 };
10514 switch (origin[1]) {
10515 case 'left': x = 0; break;
10516 case 'center': x = 0.5; break;
10517 case 'right': x = 1; break;
10518 default: x = origin[1] / original.width;
10519 };
10520 return {x: x, y: y};
10521 },
10522
10523 // Wraps the element around a wrapper that copies position properties
10524 createWrapper: function(element) {
10525
10526 // if the element is already wrapped, return it
10527 if (element.parent().is('.ui-effects-wrapper')) {
10528 return element.parent();
10529 }
10530
10531 // wrap the element
10532 var props = {
10533 width: element.outerWidth(true),
10534 height: element.outerHeight(true),
10535 'float': element.css('float')
10536 },
10537 wrapper = $('<div></div>')
10538 .addClass('ui-effects-wrapper')
10539 .css({
10540 fontSize: '100%',
10541 background: 'transparent',
10542 border: 'none',
10543 margin: 0,
10544 padding: 0
10545 }),
10546 active = document.activeElement;
10547
10548 element.wrap(wrapper);
10549
10550 // Fixes #7595 - Elements lose focus when wrapped.
10551 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10552 $( active ).focus();
10553 }
10554
10555 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
10556
10557 // transfer positioning properties to the wrapper
10558 if (element.css('position') == 'static') {
10559 wrapper.css({ position: 'relative' });
10560 element.css({ position: 'relative' });
10561 } else {
10562 $.extend(props, {
10563 position: element.css('position'),
10564 zIndex: element.css('z-index')
10565 });
10566 $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
10567 props[pos] = element.css(pos);
10568 if (isNaN(parseInt(props[pos], 10))) {
10569 props[pos] = 'auto';
10570 }
10571 });
10572 element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
10573 }
10574
10575 return wrapper.css(props).show();
10576 },
10577
10578 removeWrapper: function(element) {
10579 var parent,
10580 active = document.activeElement;
10581
10582 if (element.parent().is('.ui-effects-wrapper')) {
10583 parent = element.parent().replaceWith(element);
10584 // Fixes #7595 - Elements lose focus when wrapped.
10585 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10586 $( active ).focus();
10587 }
10588 return parent;
10589 }
10590
10591 return element;
10592 },
10593
10594 setTransition: function(element, list, factor, value) {
10595 value = value || {};
10596 $.each(list, function(i, x){
10597 unit = element.cssUnit(x);
10598 if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
10599 });
10600 return value;
10601 }
10602});
10603
10604
10605function _normalizeArguments(effect, options, speed, callback) {
10606 // shift params for method overloading
10607 if (typeof effect == 'object') {
10608 callback = options;
10609 speed = null;
10610 options = effect;
10611 effect = options.effect;
10612 }
10613 if ($.isFunction(options)) {
10614 callback = options;
10615 speed = null;
10616 options = {};
10617 }
10618 if (typeof options == 'number' || $.fx.speeds[options]) {
10619 callback = speed;
10620 speed = options;
10621 options = {};
10622 }
10623 if ($.isFunction(speed)) {
10624 callback = speed;
10625 speed = null;
10626 }
10627
10628 options = options || {};
10629
10630 speed = speed || options.duration;
10631 speed = $.fx.off ? 0 : typeof speed == 'number'
10632 ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
10633
10634 callback = callback || options.complete;
10635
10636 return [effect, options, speed, callback];
10637}
10638
10639function standardSpeed( speed ) {
10640 // valid standard speeds
10641 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
10642 return true;
10643 }
10644
10645 // invalid strings - treat as "normal" speed
10646 if ( typeof speed === "string" && !$.effects[ speed ] ) {
10647 return true;
10648 }
10649
10650 return false;
10651}
10652
10653$.fn.extend({
10654 effect: function(effect, options, speed, callback) {
10655 var args = _normalizeArguments.apply(this, arguments),
10656 // TODO: make effects take actual parameters instead of a hash
10657 args2 = {
10658 options: args[1],
10659 duration: args[2],
10660 callback: args[3]
10661 },
10662 mode = args2.options.mode,
10663 effectMethod = $.effects[effect];
10664
10665 if ( $.fx.off || !effectMethod ) {
10666 // delegate to the original method (e.g., .show()) if possible
10667 if ( mode ) {
10668 return this[ mode ]( args2.duration, args2.callback );
10669 } else {
10670 return this.each(function() {
10671 if ( args2.callback ) {
10672 args2.callback.call( this );
10673 }
10674 });
10675 }
10676 }
10677
10678 return effectMethod.call(this, args2);
10679 },
10680
10681 _show: $.fn.show,
10682 show: function(speed) {
10683 if ( standardSpeed( speed ) ) {
10684 return this._show.apply(this, arguments);
10685 } else {
10686 var args = _normalizeArguments.apply(this, arguments);
10687 args[1].mode = 'show';
10688 return this.effect.apply(this, args);
10689 }
10690 },
10691
10692 _hide: $.fn.hide,
10693 hide: function(speed) {
10694 if ( standardSpeed( speed ) ) {
10695 return this._hide.apply(this, arguments);
10696 } else {
10697 var args = _normalizeArguments.apply(this, arguments);
10698 args[1].mode = 'hide';
10699 return this.effect.apply(this, args);
10700 }
10701 },
10702
10703 // jQuery core overloads toggle and creates _toggle
10704 __toggle: $.fn.toggle,
10705 toggle: function(speed) {
10706 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
10707 return this.__toggle.apply(this, arguments);
10708 } else {
10709 var args = _normalizeArguments.apply(this, arguments);
10710 args[1].mode = 'toggle';
10711 return this.effect.apply(this, args);
10712 }
10713 },
10714
10715 // helper functions
10716 cssUnit: function(key) {
10717 var style = this.css(key), val = [];
10718 $.each( ['em','px','%','pt'], function(i, unit){
10719 if(style.indexOf(unit) > 0)
10720 val = [parseFloat(style), unit];
10721 });
10722 return val;
10723 }
10724});
10725
10726
10727
10728/******************************************************************************/
10729/*********************************** EASING ***********************************/
10730/******************************************************************************/
10731
10732/*
10733 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
10734 *
10735 * Uses the built in easing capabilities added In jQuery 1.1
10736 * to offer multiple easing options
10737 *
10738 * TERMS OF USE - jQuery Easing
10739 *
10740 * Open source under the BSD License.
10741 *
10742 * Copyright 2008 George McGinley Smith
10743 * All rights reserved.
10744 *
10745 * Redistribution and use in source and binary forms, with or without modification,
10746 * are permitted provided that the following conditions are met:
10747 *
10748 * Redistributions of source code must retain the above copyright notice, this list of
10749 * conditions and the following disclaimer.
10750 * Redistributions in binary form must reproduce the above copyright notice, this list
10751 * of conditions and the following disclaimer in the documentation and/or other materials
10752 * provided with the distribution.
10753 *
10754 * Neither the name of the author nor the names of contributors may be used to endorse
10755 * or promote products derived from this software without specific prior written permission.
10756 *
10757 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10758 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10759 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10760 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10761 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10762 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10763 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10764 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10765 * OF THE POSSIBILITY OF SUCH DAMAGE.
10766 *
10767*/
10768
10769// t: current time, b: begInnIng value, c: change In value, d: duration
10770$.easing.jswing = $.easing.swing;
10771
10772$.extend($.easing,
10773{
10774 def: 'easeOutQuad',
10775 swing: function (x, t, b, c, d) {
10776 //alert($.easing.default);
10777 return $.easing[$.easing.def](x, t, b, c, d);
10778 },
10779 easeInQuad: function (x, t, b, c, d) {
10780 return c*(t/=d)*t + b;
10781 },
10782 easeOutQuad: function (x, t, b, c, d) {
10783 return -c *(t/=d)*(t-2) + b;
10784 },
10785 easeInOutQuad: function (x, t, b, c, d) {
10786 if ((t/=d/2) < 1) return c/2*t*t + b;
10787 return -c/2 * ((--t)*(t-2) - 1) + b;
10788 },
10789 easeInCubic: function (x, t, b, c, d) {
10790 return c*(t/=d)*t*t + b;
10791 },
10792 easeOutCubic: function (x, t, b, c, d) {
10793 return c*((t=t/d-1)*t*t + 1) + b;
10794 },
10795 easeInOutCubic: function (x, t, b, c, d) {
10796 if ((t/=d/2) < 1) return c/2*t*t*t + b;
10797 return c/2*((t-=2)*t*t + 2) + b;
10798 },
10799 easeInQuart: function (x, t, b, c, d) {
10800 return c*(t/=d)*t*t*t + b;
10801 },
10802 easeOutQuart: function (x, t, b, c, d) {
10803 return -c * ((t=t/d-1)*t*t*t - 1) + b;
10804 },
10805 easeInOutQuart: function (x, t, b, c, d) {
10806 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
10807 return -c/2 * ((t-=2)*t*t*t - 2) + b;
10808 },
10809 easeInQuint: function (x, t, b, c, d) {
10810 return c*(t/=d)*t*t*t*t + b;
10811 },
10812 easeOutQuint: function (x, t, b, c, d) {
10813 return c*((t=t/d-1)*t*t*t*t + 1) + b;
10814 },
10815 easeInOutQuint: function (x, t, b, c, d) {
10816 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
10817 return c/2*((t-=2)*t*t*t*t + 2) + b;
10818 },
10819 easeInSine: function (x, t, b, c, d) {
10820 return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
10821 },
10822 easeOutSine: function (x, t, b, c, d) {
10823 return c * Math.sin(t/d * (Math.PI/2)) + b;
10824 },
10825 easeInOutSine: function (x, t, b, c, d) {
10826 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
10827 },
10828 easeInExpo: function (x, t, b, c, d) {
10829 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
10830 },
10831 easeOutExpo: function (x, t, b, c, d) {
10832 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
10833 },
10834 easeInOutExpo: function (x, t, b, c, d) {
10835 if (t==0) return b;
10836 if (t==d) return b+c;
10837 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
10838 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
10839 },
10840 easeInCirc: function (x, t, b, c, d) {
10841 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
10842 },
10843 easeOutCirc: function (x, t, b, c, d) {
10844 return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
10845 },
10846 easeInOutCirc: function (x, t, b, c, d) {
10847 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
10848 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
10849 },
10850 easeInElastic: function (x, t, b, c, d) {
10851 var s=1.70158;var p=0;var a=c;
10852 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
10853 if (a < Math.abs(c)) { a=c; var s=p/4; }
10854 else var s = p/(2*Math.PI) * Math.asin (c/a);
10855 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
10856 },
10857 easeOutElastic: function (x, t, b, c, d) {
10858 var s=1.70158;var p=0;var a=c;
10859 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
10860 if (a < Math.abs(c)) { a=c; var s=p/4; }
10861 else var s = p/(2*Math.PI) * Math.asin (c/a);
10862 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
10863 },
10864 easeInOutElastic: function (x, t, b, c, d) {
10865 var s=1.70158;var p=0;var a=c;
10866 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
10867 if (a < Math.abs(c)) { a=c; var s=p/4; }
10868 else var s = p/(2*Math.PI) * Math.asin (c/a);
10869 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
10870 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
10871 },
10872 easeInBack: function (x, t, b, c, d, s) {
10873 if (s == undefined) s = 1.70158;
10874 return c*(t/=d)*t*((s+1)*t - s) + b;
10875 },
10876 easeOutBack: function (x, t, b, c, d, s) {
10877 if (s == undefined) s = 1.70158;
10878 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
10879 },
10880 easeInOutBack: function (x, t, b, c, d, s) {
10881 if (s == undefined) s = 1.70158;
10882 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
10883 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
10884 },
10885 easeInBounce: function (x, t, b, c, d) {
10886 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
10887 },
10888 easeOutBounce: function (x, t, b, c, d) {
10889 if ((t/=d) < (1/2.75)) {
10890 return c*(7.5625*t*t) + b;
10891 } else if (t < (2/2.75)) {
10892 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
10893 } else if (t < (2.5/2.75)) {
10894 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
10895 } else {
10896 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
10897 }
10898 },
10899 easeInOutBounce: function (x, t, b, c, d) {
10900 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
10901 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
10902 }
10903});
10904
10905/*
10906 *
10907 * TERMS OF USE - EASING EQUATIONS
10908 *
10909 * Open source under the BSD License.
10910 *
10911 * Copyright 2001 Robert Penner
10912 * All rights reserved.
10913 *
10914 * Redistribution and use in source and binary forms, with or without modification,
10915 * are permitted provided that the following conditions are met:
10916 *
10917 * Redistributions of source code must retain the above copyright notice, this list of
10918 * conditions and the following disclaimer.
10919 * Redistributions in binary form must reproduce the above copyright notice, this list
10920 * of conditions and the following disclaimer in the documentation and/or other materials
10921 * provided with the distribution.
10922 *
10923 * Neither the name of the author nor the names of contributors may be used to endorse
10924 * or promote products derived from this software without specific prior written permission.
10925 *
10926 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10927 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10928 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10929 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10930 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10931 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10932 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10933 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10934 * OF THE POSSIBILITY OF SUCH DAMAGE.
10935 *
10936 */
10937
10938})(jQuery);
10939/*
10940 * jQuery UI Effects Blind 1.8.16
10941 *
10942 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10943 * Dual licensed under the MIT or GPL Version 2 licenses.
10944 * http://jquery.org/license
10945 *
10946 * http://docs.jquery.com/UI/Effects/Blind
10947 *
10948 * Depends:
10949 * jquery.effects.core.js
10950 */
10951(function( $, undefined ) {
10952
10953$.effects.blind = function(o) {
10954
10955 return this.queue(function() {
10956
10957 // Create element
10958 var el = $(this), props = ['position','top','bottom','left','right'];
10959
10960 // Set options
10961 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
10962 var direction = o.options.direction || 'vertical'; // Default direction
10963
10964 // Adjust
10965 $.effects.save(el, props); el.show(); // Save & Show
10966 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
10967 var ref = (direction == 'vertical') ? 'height' : 'width';
10968 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
10969 if(mode == 'show') wrapper.css(ref, 0); // Shift
10970
10971 // Animation
10972 var animation = {};
10973 animation[ref] = mode == 'show' ? distance : 0;
10974
10975 // Animate
10976 wrapper.animate(animation, o.duration, o.options.easing, function() {
10977 if(mode == 'hide') el.hide(); // Hide
10978 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
10979 if(o.callback) o.callback.apply(el[0], arguments); // Callback
10980 el.dequeue();
10981 });
10982
10983 });
10984
10985};
10986
10987})(jQuery);
10988/*
10989 * jQuery UI Effects Bounce 1.8.16
10990 *
10991 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10992 * Dual licensed under the MIT or GPL Version 2 licenses.
10993 * http://jquery.org/license
10994 *
10995 * http://docs.jquery.com/UI/Effects/Bounce
10996 *
10997 * Depends:
10998 * jquery.effects.core.js
10999 */
11000(function( $, undefined ) {
11001
11002$.effects.bounce = function(o) {
11003
11004 return this.queue(function() {
11005
11006 // Create element
11007 var el = $(this), props = ['position','top','bottom','left','right'];
11008
11009 // Set options
11010 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11011 var direction = o.options.direction || 'up'; // Default direction
11012 var distance = o.options.distance || 20; // Default distance
11013 var times = o.options.times || 5; // Default # of times
11014 var speed = o.duration || 250; // Default speed per bounce
11015 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
11016
11017 // Adjust
11018 $.effects.save(el, props); el.show(); // Save & Show
11019 $.effects.createWrapper(el); // Create Wrapper
11020 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11021 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11022 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
11023 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
11024 if (mode == 'hide') distance = distance / (times * 2);
11025 if (mode != 'hide') times--;
11026
11027 // Animate
11028 if (mode == 'show') { // Show Bounce
11029 var animation = {opacity: 1};
11030 animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11031 el.animate(animation, speed / 2, o.options.easing);
11032 distance = distance / 2;
11033 times--;
11034 };
11035 for (var i = 0; i < times; i++) { // Bounces
11036 var animation1 = {}, animation2 = {};
11037 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11038 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11039 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
11040 distance = (mode == 'hide') ? distance * 2 : distance / 2;
11041 };
11042 if (mode == 'hide') { // Last Bounce
11043 var animation = {opacity: 0};
11044 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11045 el.animate(animation, speed / 2, o.options.easing, function(){
11046 el.hide(); // Hide
11047 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11048 if(o.callback) o.callback.apply(this, arguments); // Callback
11049 });
11050 } else {
11051 var animation1 = {}, animation2 = {};
11052 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11053 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11054 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
11055 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11056 if(o.callback) o.callback.apply(this, arguments); // Callback
11057 });
11058 };
11059 el.queue('fx', function() { el.dequeue(); });
11060 el.dequeue();
11061 });
11062
11063};
11064
11065})(jQuery);
11066/*
11067 * jQuery UI Effects Clip 1.8.16
11068 *
11069 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11070 * Dual licensed under the MIT or GPL Version 2 licenses.
11071 * http://jquery.org/license
11072 *
11073 * http://docs.jquery.com/UI/Effects/Clip
11074 *
11075 * Depends:
11076 * jquery.effects.core.js
11077 */
11078(function( $, undefined ) {
11079
11080$.effects.clip = function(o) {
11081
11082 return this.queue(function() {
11083
11084 // Create element
11085 var el = $(this), props = ['position','top','bottom','left','right','height','width'];
11086
11087 // Set options
11088 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11089 var direction = o.options.direction || 'vertical'; // Default direction
11090
11091 // Adjust
11092 $.effects.save(el, props); el.show(); // Save & Show
11093 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11094 var animate = el[0].tagName == 'IMG' ? wrapper : el;
11095 var ref = {
11096 size: (direction == 'vertical') ? 'height' : 'width',
11097 position: (direction == 'vertical') ? 'top' : 'left'
11098 };
11099 var distance = (direction == 'vertical') ? animate.height() : animate.width();
11100 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
11101
11102 // Animation
11103 var animation = {};
11104 animation[ref.size] = mode == 'show' ? distance : 0;
11105 animation[ref.position] = mode == 'show' ? 0 : distance / 2;
11106
11107 // Animate
11108 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11109 if(mode == 'hide') el.hide(); // Hide
11110 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11111 if(o.callback) o.callback.apply(el[0], arguments); // Callback
11112 el.dequeue();
11113 }});
11114
11115 });
11116
11117};
11118
11119})(jQuery);
11120/*
11121 * jQuery UI Effects Drop 1.8.16
11122 *
11123 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11124 * Dual licensed under the MIT or GPL Version 2 licenses.
11125 * http://jquery.org/license
11126 *
11127 * http://docs.jquery.com/UI/Effects/Drop
11128 *
11129 * Depends:
11130 * jquery.effects.core.js
11131 */
11132(function( $, undefined ) {
11133
11134$.effects.drop = function(o) {
11135
11136 return this.queue(function() {
11137
11138 // Create element
11139 var el = $(this), props = ['position','top','bottom','left','right','opacity'];
11140
11141 // Set options
11142 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11143 var direction = o.options.direction || 'left'; // Default Direction
11144
11145 // Adjust
11146 $.effects.save(el, props); el.show(); // Save & Show
11147 $.effects.createWrapper(el); // Create Wrapper
11148 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11149 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11150 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
11151 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
11152
11153 // Animation
11154 var animation = {opacity: mode == 'show' ? 1 : 0};
11155 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
11156
11157 // Animate
11158 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11159 if(mode == 'hide') el.hide(); // Hide
11160 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11161 if(o.callback) o.callback.apply(this, arguments); // Callback
11162 el.dequeue();
11163 }});
11164
11165 });
11166
11167};
11168
11169})(jQuery);
11170/*
11171 * jQuery UI Effects Explode 1.8.16
11172 *
11173 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11174 * Dual licensed under the MIT or GPL Version 2 licenses.
11175 * http://jquery.org/license
11176 *
11177 * http://docs.jquery.com/UI/Effects/Explode
11178 *
11179 * Depends:
11180 * jquery.effects.core.js
11181 */
11182(function( $, undefined ) {
11183
11184$.effects.explode = function(o) {
11185
11186 return this.queue(function() {
11187
11188 var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
11189 var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
11190
11191 o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
11192 var el = $(this).show().css('visibility', 'hidden');
11193 var offset = el.offset();
11194
11195 //Substract the margins - not fixing the problem yet.
11196 offset.top -= parseInt(el.css("marginTop"),10) || 0;
11197 offset.left -= parseInt(el.css("marginLeft"),10) || 0;
11198
11199 var width = el.outerWidth(true);
11200 var height = el.outerHeight(true);
11201
11202 for(var i=0;i<rows;i++) { // =
11203 for(var j=0;j<cells;j++) { // ||
11204 el
11205 .clone()
11206 .appendTo('body')
11207 .wrap('<div></div>')
11208 .css({
11209 position: 'absolute',
11210 visibility: 'visible',
11211 left: -j*(width/cells),
11212 top: -i*(height/rows)
11213 })
11214 .parent()
11215 .addClass('ui-effects-explode')
11216 .css({
11217 position: 'absolute',
11218 overflow: 'hidden',
11219 width: width/cells,
11220 height: height/rows,
11221 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
11222 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
11223 opacity: o.options.mode == 'show' ? 0 : 1
11224 }).animate({
11225 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
11226 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
11227 opacity: o.options.mode == 'show' ? 1 : 0
11228 }, o.duration || 500);
11229 }
11230 }
11231
11232 // Set a timeout, to call the callback approx. when the other animations have finished
11233 setTimeout(function() {
11234
11235 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
11236 if(o.callback) o.callback.apply(el[0]); // Callback
11237 el.dequeue();
11238
11239 $('div.ui-effects-explode').remove();
11240
11241 }, o.duration || 500);
11242
11243
11244 });
11245
11246};
11247
11248})(jQuery);
11249/*
11250 * jQuery UI Effects Fade 1.8.16
11251 *
11252 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11253 * Dual licensed under the MIT or GPL Version 2 licenses.
11254 * http://jquery.org/license
11255 *
11256 * http://docs.jquery.com/UI/Effects/Fade
11257 *
11258 * Depends:
11259 * jquery.effects.core.js
11260 */
11261(function( $, undefined ) {
11262
11263$.effects.fade = function(o) {
11264 return this.queue(function() {
11265 var elem = $(this),
11266 mode = $.effects.setMode(elem, o.options.mode || 'hide');
11267
11268 elem.animate({ opacity: mode }, {
11269 queue: false,
11270 duration: o.duration,
11271 easing: o.options.easing,
11272 complete: function() {
11273 (o.callback && o.callback.apply(this, arguments));
11274 elem.dequeue();
11275 }
11276 });
11277 });
11278};
11279
11280})(jQuery);
11281/*
11282 * jQuery UI Effects Fold 1.8.16
11283 *
11284 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11285 * Dual licensed under the MIT or GPL Version 2 licenses.
11286 * http://jquery.org/license
11287 *
11288 * http://docs.jquery.com/UI/Effects/Fold
11289 *
11290 * Depends:
11291 * jquery.effects.core.js
11292 */
11293(function( $, undefined ) {
11294
11295$.effects.fold = function(o) {
11296
11297 return this.queue(function() {
11298
11299 // Create element
11300 var el = $(this), props = ['position','top','bottom','left','right'];
11301
11302 // Set options
11303 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11304 var size = o.options.size || 15; // Default fold size
11305 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
11306 var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
11307
11308 // Adjust
11309 $.effects.save(el, props); el.show(); // Save & Show
11310 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11311 var widthFirst = ((mode == 'show') != horizFirst);
11312 var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
11313 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
11314 var percent = /([0-9]+)%/.exec(size);
11315 if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
11316 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
11317
11318 // Animation
11319 var animation1 = {}, animation2 = {};
11320 animation1[ref[0]] = mode == 'show' ? distance[0] : size;
11321 animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
11322
11323 // Animate
11324 wrapper.animate(animation1, duration, o.options.easing)
11325 .animate(animation2, duration, o.options.easing, function() {
11326 if(mode == 'hide') el.hide(); // Hide
11327 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11328 if(o.callback) o.callback.apply(el[0], arguments); // Callback
11329 el.dequeue();
11330 });
11331
11332 });
11333
11334};
11335
11336})(jQuery);
11337/*
11338 * jQuery UI Effects Highlight 1.8.16
11339 *
11340 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11341 * Dual licensed under the MIT or GPL Version 2 licenses.
11342 * http://jquery.org/license
11343 *
11344 * http://docs.jquery.com/UI/Effects/Highlight
11345 *
11346 * Depends:
11347 * jquery.effects.core.js
11348 */
11349(function( $, undefined ) {
11350
11351$.effects.highlight = function(o) {
11352 return this.queue(function() {
11353 var elem = $(this),
11354 props = ['backgroundImage', 'backgroundColor', 'opacity'],
11355 mode = $.effects.setMode(elem, o.options.mode || 'show'),
11356 animation = {
11357 backgroundColor: elem.css('backgroundColor')
11358 };
11359
11360 if (mode == 'hide') {
11361 animation.opacity = 0;
11362 }
11363
11364 $.effects.save(elem, props);
11365 elem
11366 .show()
11367 .css({
11368 backgroundImage: 'none',
11369 backgroundColor: o.options.color || '#ffff99'
11370 })
11371 .animate(animation, {
11372 queue: false,
11373 duration: o.duration,
11374 easing: o.options.easing,
11375 complete: function() {
11376 (mode == 'hide' && elem.hide());
11377 $.effects.restore(elem, props);
11378 (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
11379 (o.callback && o.callback.apply(this, arguments));
11380 elem.dequeue();
11381 }
11382 });
11383 });
11384};
11385
11386})(jQuery);
11387/*
11388 * jQuery UI Effects Pulsate 1.8.16
11389 *
11390 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11391 * Dual licensed under the MIT or GPL Version 2 licenses.
11392 * http://jquery.org/license
11393 *
11394 * http://docs.jquery.com/UI/Effects/Pulsate
11395 *
11396 * Depends:
11397 * jquery.effects.core.js
11398 */
11399(function( $, undefined ) {
11400
11401$.effects.pulsate = function(o) {
11402 return this.queue(function() {
11403 var elem = $(this),
11404 mode = $.effects.setMode(elem, o.options.mode || 'show');
11405 times = ((o.options.times || 5) * 2) - 1;
11406 duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
11407 isVisible = elem.is(':visible'),
11408 animateTo = 0;
11409
11410 if (!isVisible) {
11411 elem.css('opacity', 0).show();
11412 animateTo = 1;
11413 }
11414
11415 if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
11416 times--;
11417 }
11418
11419 for (var i = 0; i < times; i++) {
11420 elem.animate({ opacity: animateTo }, duration, o.options.easing);
11421 animateTo = (animateTo + 1) % 2;
11422 }
11423
11424 elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
11425 if (animateTo == 0) {
11426 elem.hide();
11427 }
11428 (o.callback && o.callback.apply(this, arguments));
11429 });
11430
11431 elem
11432 .queue('fx', function() { elem.dequeue(); })
11433 .dequeue();
11434 });
11435};
11436
11437})(jQuery);
11438/*
11439 * jQuery UI Effects Scale 1.8.16
11440 *
11441 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11442 * Dual licensed under the MIT or GPL Version 2 licenses.
11443 * http://jquery.org/license
11444 *
11445 * http://docs.jquery.com/UI/Effects/Scale
11446 *
11447 * Depends:
11448 * jquery.effects.core.js
11449 */
11450(function( $, undefined ) {
11451
11452$.effects.puff = function(o) {
11453 return this.queue(function() {
11454 var elem = $(this),
11455 mode = $.effects.setMode(elem, o.options.mode || 'hide'),
11456 percent = parseInt(o.options.percent, 10) || 150,
11457 factor = percent / 100,
11458 original = { height: elem.height(), width: elem.width() };
11459
11460 $.extend(o.options, {
11461 fade: true,
11462 mode: mode,
11463 percent: mode == 'hide' ? percent : 100,
11464 from: mode == 'hide'
11465 ? original
11466 : {
11467 height: original.height * factor,
11468 width: original.width * factor
11469 }
11470 });
11471
11472 elem.effect('scale', o.options, o.duration, o.callback);
11473 elem.dequeue();
11474 });
11475};
11476
11477$.effects.scale = function(o) {
11478
11479 return this.queue(function() {
11480
11481 // Create element
11482 var el = $(this);
11483
11484 // Set options
11485 var options = $.extend(true, {}, o.options);
11486 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11487 var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
11488 var direction = o.options.direction || 'both'; // Set default axis
11489 var origin = o.options.origin; // The origin of the scaling
11490 if (mode != 'effect') { // Set default origin and restore for show/hide
11491 options.origin = origin || ['middle','center'];
11492 options.restore = true;
11493 }
11494 var original = {height: el.height(), width: el.width()}; // Save original
11495 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
11496
11497 // Adjust
11498 var factor = { // Set scaling factor
11499 y: direction != 'horizontal' ? (percent / 100) : 1,
11500 x: direction != 'vertical' ? (percent / 100) : 1
11501 };
11502 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
11503
11504 if (o.options.fade) { // Fade option to support puff
11505 if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
11506 if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
11507 };
11508
11509 // Animation
11510 options.from = el.from; options.to = el.to; options.mode = mode;
11511
11512 // Animate
11513 el.effect('size', options, o.duration, o.callback);
11514 el.dequeue();
11515 });
11516
11517};
11518
11519$.effects.size = function(o) {
11520
11521 return this.queue(function() {
11522
11523 // Create element
11524 var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
11525 var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
11526 var props2 = ['width','height','overflow']; // Copy for children
11527 var cProps = ['fontSize'];
11528 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
11529 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
11530
11531 // Set options
11532 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11533 var restore = o.options.restore || false; // Default restore
11534 var scale = o.options.scale || 'both'; // Default scale mode
11535 var origin = o.options.origin; // The origin of the sizing
11536 var original = {height: el.height(), width: el.width()}; // Save original
11537 el.from = o.options.from || original; // Default from state
11538 el.to = o.options.to || original; // Default to state
11539 // Adjust
11540 if (origin) { // Calculate baseline shifts
11541 var baseline = $.effects.getBaseline(origin, original);
11542 el.from.top = (original.height - el.from.height) * baseline.y;
11543 el.from.left = (original.width - el.from.width) * baseline.x;
11544 el.to.top = (original.height - el.to.height) * baseline.y;
11545 el.to.left = (original.width - el.to.width) * baseline.x;
11546 };
11547 var factor = { // Set scaling factor
11548 from: {y: el.from.height / original.height, x: el.from.width / original.width},
11549 to: {y: el.to.height / original.height, x: el.to.width / original.width}
11550 };
11551 if (scale == 'box' || scale == 'both') { // Scale the css box
11552 if (factor.from.y != factor.to.y) { // Vertical props scaling
11553 props = props.concat(vProps);
11554 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
11555 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
11556 };
11557 if (factor.from.x != factor.to.x) { // Horizontal props scaling
11558 props = props.concat(hProps);
11559 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
11560 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
11561 };
11562 };
11563 if (scale == 'content' || scale == 'both') { // Scale the content
11564 if (factor.from.y != factor.to.y) { // Vertical props scaling
11565 props = props.concat(cProps);
11566 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
11567 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
11568 };
11569 };
11570 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
11571 $.effects.createWrapper(el); // Create Wrapper
11572 el.css('overflow','hidden').css(el.from); // Shift
11573
11574 // Animate
11575 if (scale == 'content' || scale == 'both') { // Scale the children
11576 vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
11577 hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
11578 props2 = props.concat(vProps).concat(hProps); // Concat
11579 el.find("*[width]").each(function(){
11580 child = $(this);
11581 if (restore) $.effects.save(child, props2);
11582 var c_original = {height: child.height(), width: child.width()}; // Save original
11583 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
11584 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
11585 if (factor.from.y != factor.to.y) { // Vertical props scaling
11586 child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
11587 child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
11588 };
11589 if (factor.from.x != factor.to.x) { // Horizontal props scaling
11590 child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
11591 child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
11592 };
11593 child.css(child.from); // Shift children
11594 child.animate(child.to, o.duration, o.options.easing, function(){
11595 if (restore) $.effects.restore(child, props2); // Restore children
11596 }); // Animate children
11597 });
11598 };
11599
11600 // Animate
11601 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11602 if (el.to.opacity === 0) {
11603 el.css('opacity', el.from.opacity);
11604 }
11605 if(mode == 'hide') el.hide(); // Hide
11606 $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
11607 if(o.callback) o.callback.apply(this, arguments); // Callback
11608 el.dequeue();
11609 }});
11610
11611 });
11612
11613};
11614
11615})(jQuery);
11616/*
11617 * jQuery UI Effects Shake 1.8.16
11618 *
11619 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11620 * Dual licensed under the MIT or GPL Version 2 licenses.
11621 * http://jquery.org/license
11622 *
11623 * http://docs.jquery.com/UI/Effects/Shake
11624 *
11625 * Depends:
11626 * jquery.effects.core.js
11627 */
11628(function( $, undefined ) {
11629
11630$.effects.shake = function(o) {
11631
11632 return this.queue(function() {
11633
11634 // Create element
11635 var el = $(this), props = ['position','top','bottom','left','right'];
11636
11637 // Set options
11638 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11639 var direction = o.options.direction || 'left'; // Default direction
11640 var distance = o.options.distance || 20; // Default distance
11641 var times = o.options.times || 3; // Default # of times
11642 var speed = o.duration || o.options.duration || 140; // Default speed per shake
11643
11644 // Adjust
11645 $.effects.save(el, props); el.show(); // Save & Show
11646 $.effects.createWrapper(el); // Create Wrapper
11647 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11648 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11649
11650 // Animation
11651 var animation = {}, animation1 = {}, animation2 = {};
11652 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11653 animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
11654 animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
11655
11656 // Animate
11657 el.animate(animation, speed, o.options.easing);
11658 for (var i = 1; i < times; i++) { // Shakes
11659 el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
11660 };
11661 el.animate(animation1, speed, o.options.easing).
11662 animate(animation, speed / 2, o.options.easing, function(){ // Last shake
11663 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11664 if(o.callback) o.callback.apply(this, arguments); // Callback
11665 });
11666 el.queue('fx', function() { el.dequeue(); });
11667 el.dequeue();
11668 });
11669
11670};
11671
11672})(jQuery);
11673/*
11674 * jQuery UI Effects Slide 1.8.16
11675 *
11676 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11677 * Dual licensed under the MIT or GPL Version 2 licenses.
11678 * http://jquery.org/license
11679 *
11680 * http://docs.jquery.com/UI/Effects/Slide
11681 *
11682 * Depends:
11683 * jquery.effects.core.js
11684 */
11685(function( $, undefined ) {
11686
11687$.effects.slide = function(o) {
11688
11689 return this.queue(function() {
11690
11691 // Create element
11692 var el = $(this), props = ['position','top','bottom','left','right'];
11693
11694 // Set options
11695 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
11696 var direction = o.options.direction || 'left'; // Default Direction
11697
11698 // Adjust
11699 $.effects.save(el, props); el.show(); // Save & Show
11700 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11701 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11702 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11703 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
11704 if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
11705
11706 // Animation
11707 var animation = {};
11708 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
11709
11710 // Animate
11711 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11712 if(mode == 'hide') el.hide(); // Hide
11713 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11714 if(o.callback) o.callback.apply(this, arguments); // Callback
11715 el.dequeue();
11716 }});
11717
11718 });
11719
11720};
11721
11722})(jQuery);
11723/*
11724 * jQuery UI Effects Transfer 1.8.16
11725 *
11726 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11727 * Dual licensed under the MIT or GPL Version 2 licenses.
11728 * http://jquery.org/license
11729 *
11730 * http://docs.jquery.com/UI/Effects/Transfer
11731 *
11732 * Depends:
11733 * jquery.effects.core.js
11734 */
11735(function( $, undefined ) {
11736
11737$.effects.transfer = function(o) {
11738 return this.queue(function() {
11739 var elem = $(this),
11740 target = $(o.options.to),
11741 endPosition = target.offset(),
11742 animation = {
11743 top: endPosition.top,
11744 left: endPosition.left,
11745 height: target.innerHeight(),
11746 width: target.innerWidth()
11747 },
11748 startPosition = elem.offset(),
11749 transfer = $('<div class="ui-effects-transfer"></div>')
11750 .appendTo(document.body)
11751 .addClass(o.options.className)
11752 .css({
11753 top: startPosition.top,
11754 left: startPosition.left,
11755 height: elem.innerHeight(),
11756 width: elem.innerWidth(),
11757 position: 'absolute'
11758 })
11759 .animate(animation, o.duration, o.options.easing, function() {
11760 transfer.remove();
11761 (o.callback && o.callback.apply(elem[0], arguments));
11762 elem.dequeue();
11763 });
11764 });
11765};
11766
11767})(jQuery);