comparison war/scripts/jQuery/ui/jquery-ui-1.8.14.custom.js @ 3:cf06b77a8bbd

Committed branch of the e4D repos sti-gwt branch 16384. git-svn-id: http://dev.dariah.eu/svn/repos/eu.dariah.de/ap1/sti-gwt-dariah-geobrowser@36 f2b5be40-def6-11e0-8a09-b3c1cc336c6b
author StefanFunk <StefanFunk@f2b5be40-def6-11e0-8a09-b3c1cc336c6b>
date Tue, 17 Jul 2012 13:34:40 +0000
parents
children
comparison
equal deleted inserted replaced
2:2897af43ccc6 3:cf06b77a8bbd
1 /*!
2 * jQuery UI 1.8.14
3 *
4 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 * Dual licensed under the MIT or GPL Version 2 licenses.
6 * http://jquery.org/license
7 *
8 * http://docs.jquery.com/UI
9 */
10 (function( $, undefined ) {
11
12 // prevent duplicate loading
13 // this is only a problem because we proxy existing functions
14 // and we don't want to double proxy them
15 $.ui = $.ui || {};
16 if ( $.ui.version ) {
17 return;
18 }
19
20 $.extend( $.ui, {
21 version: "1.8.14",
22
23 keyCode: {
24 ALT: 18,
25 BACKSPACE: 8,
26 CAPS_LOCK: 20,
27 COMMA: 188,
28 COMMAND: 91,
29 COMMAND_LEFT: 91, // COMMAND
30 COMMAND_RIGHT: 93,
31 CONTROL: 17,
32 DELETE: 46,
33 DOWN: 40,
34 END: 35,
35 ENTER: 13,
36 ESCAPE: 27,
37 HOME: 36,
38 INSERT: 45,
39 LEFT: 37,
40 MENU: 93, // COMMAND_RIGHT
41 NUMPAD_ADD: 107,
42 NUMPAD_DECIMAL: 110,
43 NUMPAD_DIVIDE: 111,
44 NUMPAD_ENTER: 108,
45 NUMPAD_MULTIPLY: 106,
46 NUMPAD_SUBTRACT: 109,
47 PAGE_DOWN: 34,
48 PAGE_UP: 33,
49 PERIOD: 190,
50 RIGHT: 39,
51 SHIFT: 16,
52 SPACE: 32,
53 TAB: 9,
54 UP: 38,
55 WINDOWS: 91 // COMMAND
56 }
57 });
58
59 // plugins
60 $.fn.extend({
61 _focus: $.fn.focus,
62 focus: function( delay, fn ) {
63 return typeof delay === "number" ?
64 this.each(function() {
65 var elem = this;
66 setTimeout(function() {
67 $( elem ).focus();
68 if ( fn ) {
69 fn.call( elem );
70 }
71 }, delay );
72 }) :
73 this._focus.apply( this, arguments );
74 },
75
76 scrollParent: function() {
77 var scrollParent;
78 if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
79 scrollParent = this.parents().filter(function() {
80 return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
81 }).eq(0);
82 } else {
83 scrollParent = this.parents().filter(function() {
84 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
85 }).eq(0);
86 }
87
88 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
89 },
90
91 zIndex: function( zIndex ) {
92 if ( zIndex !== undefined ) {
93 return this.css( "zIndex", zIndex );
94 }
95
96 if ( this.length ) {
97 var elem = $( this[ 0 ] ), position, value;
98 while ( elem.length && elem[ 0 ] !== document ) {
99 // Ignore z-index if position is set to a value where z-index is ignored by the browser
100 // This makes behavior of this function consistent across browsers
101 // WebKit always returns auto if the element is positioned
102 position = elem.css( "position" );
103 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
104 // IE returns 0 when zIndex is not specified
105 // other browsers return a string
106 // we ignore the case of nested elements with an explicit value of 0
107 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
108 value = parseInt( elem.css( "zIndex" ), 10 );
109 if ( !isNaN( value ) && value !== 0 ) {
110 return value;
111 }
112 }
113 elem = elem.parent();
114 }
115 }
116
117 return 0;
118 },
119
120 disableSelection: function() {
121 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
122 ".ui-disableSelection", function( event ) {
123 event.preventDefault();
124 });
125 },
126
127 enableSelection: function() {
128 return this.unbind( ".ui-disableSelection" );
129 }
130 });
131
132 $.each( [ "Width", "Height" ], function( i, name ) {
133 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
134 type = name.toLowerCase(),
135 orig = {
136 innerWidth: $.fn.innerWidth,
137 innerHeight: $.fn.innerHeight,
138 outerWidth: $.fn.outerWidth,
139 outerHeight: $.fn.outerHeight
140 };
141
142 function reduce( elem, size, border, margin ) {
143 $.each( side, function() {
144 size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
145 if ( border ) {
146 size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
147 }
148 if ( margin ) {
149 size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
150 }
151 });
152 return size;
153 }
154
155 $.fn[ "inner" + name ] = function( size ) {
156 if ( size === undefined ) {
157 return orig[ "inner" + name ].call( this );
158 }
159
160 return this.each(function() {
161 $( this ).css( type, reduce( this, size ) + "px" );
162 });
163 };
164
165 $.fn[ "outer" + name] = function( size, margin ) {
166 if ( typeof size !== "number" ) {
167 return orig[ "outer" + name ].call( this, size );
168 }
169
170 return this.each(function() {
171 $( this).css( type, reduce( this, size, true, margin ) + "px" );
172 });
173 };
174 });
175
176 // selectors
177 function focusable( element, isTabIndexNotNaN ) {
178 var nodeName = element.nodeName.toLowerCase();
179 if ( "area" === nodeName ) {
180 var map = element.parentNode,
181 mapName = map.name,
182 img;
183 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
184 return false;
185 }
186 img = $( "img[usemap=#" + mapName + "]" )[0];
187 return !!img && visible( img );
188 }
189 return ( /input|select|textarea|button|object/.test( nodeName )
190 ? !element.disabled
191 : "a" == nodeName
192 ? element.href || isTabIndexNotNaN
193 : isTabIndexNotNaN)
194 // the element and all of its ancestors must be visible
195 && visible( element );
196 }
197
198 function visible( element ) {
199 return !$( element ).parents().andSelf().filter(function() {
200 return $.curCSS( this, "visibility" ) === "hidden" ||
201 $.expr.filters.hidden( this );
202 }).length;
203 }
204
205 $.extend( $.expr[ ":" ], {
206 data: function( elem, i, match ) {
207 return !!$.data( elem, match[ 3 ] );
208 },
209
210 focusable: function( element ) {
211 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
212 },
213
214 tabbable: function( element ) {
215 var tabIndex = $.attr( element, "tabindex" ),
216 isTabIndexNaN = isNaN( tabIndex );
217 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
218 }
219 });
220
221 // support
222 $(function() {
223 var body = document.body,
224 div = body.appendChild( div = document.createElement( "div" ) );
225
226 $.extend( div.style, {
227 minHeight: "100px",
228 height: "auto",
229 padding: 0,
230 borderWidth: 0
231 });
232
233 $.support.minHeight = div.offsetHeight === 100;
234 $.support.selectstart = "onselectstart" in div;
235
236 // set display to none to avoid a layout bug in IE
237 // http://dev.jquery.com/ticket/4014
238 body.removeChild( div ).style.display = "none";
239 });
240
241
242
243
244
245 // deprecated
246 $.extend( $.ui, {
247 // $.ui.plugin is deprecated. Use the proxy pattern instead.
248 plugin: {
249 add: function( module, option, set ) {
250 var proto = $.ui[ module ].prototype;
251 for ( var i in set ) {
252 proto.plugins[ i ] = proto.plugins[ i ] || [];
253 proto.plugins[ i ].push( [ option, set[ i ] ] );
254 }
255 },
256 call: function( instance, name, args ) {
257 var set = instance.plugins[ name ];
258 if ( !set || !instance.element[ 0 ].parentNode ) {
259 return;
260 }
261
262 for ( var i = 0; i < set.length; i++ ) {
263 if ( instance.options[ set[ i ][ 0 ] ] ) {
264 set[ i ][ 1 ].apply( instance.element, args );
265 }
266 }
267 }
268 },
269
270 // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
271 contains: function( a, b ) {
272 return document.compareDocumentPosition ?
273 a.compareDocumentPosition( b ) & 16 :
274 a !== b && a.contains( b );
275 },
276
277 // only used by resizable
278 hasScroll: function( el, a ) {
279
280 //If overflow is hidden, the element might have extra content, but the user wants to hide it
281 if ( $( el ).css( "overflow" ) === "hidden") {
282 return false;
283 }
284
285 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
286 has = false;
287
288 if ( el[ scroll ] > 0 ) {
289 return true;
290 }
291
292 // TODO: determine which cases actually cause this to happen
293 // if the element doesn't have the scroll set, see if it's possible to
294 // set the scroll
295 el[ scroll ] = 1;
296 has = ( el[ scroll ] > 0 );
297 el[ scroll ] = 0;
298 return has;
299 },
300
301 // these are odd functions, fix the API or move into individual plugins
302 isOverAxis: function( x, reference, size ) {
303 //Determines when x coordinate is over "b" element axis
304 return ( x > reference ) && ( x < ( reference + size ) );
305 },
306 isOver: function( y, x, top, left, height, width ) {
307 //Determines when x, y coordinates is over "b" element
308 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
309 }
310 });
311
312 })( jQuery );
313 /*!
314 * jQuery UI Widget 1.8.14
315 *
316 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
317 * Dual licensed under the MIT or GPL Version 2 licenses.
318 * http://jquery.org/license
319 *
320 * http://docs.jquery.com/UI/Widget
321 */
322 (function( $, undefined ) {
323
324 // jQuery 1.4+
325 if ( $.cleanData ) {
326 var _cleanData = $.cleanData;
327 $.cleanData = function( elems ) {
328 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
329 $( elem ).triggerHandler( "remove" );
330 }
331 _cleanData( elems );
332 };
333 } else {
334 var _remove = $.fn.remove;
335 $.fn.remove = function( selector, keepData ) {
336 return this.each(function() {
337 if ( !keepData ) {
338 if ( !selector || $.filter( selector, [ this ] ).length ) {
339 $( "*", this ).add( [ this ] ).each(function() {
340 $( this ).triggerHandler( "remove" );
341 });
342 }
343 }
344 return _remove.call( $(this), selector, keepData );
345 });
346 };
347 }
348
349 $.widget = function( name, base, prototype ) {
350 var namespace = name.split( "." )[ 0 ],
351 fullName;
352 name = name.split( "." )[ 1 ];
353 fullName = namespace + "-" + name;
354
355 if ( !prototype ) {
356 prototype = base;
357 base = $.Widget;
358 }
359
360 // create selector for plugin
361 $.expr[ ":" ][ fullName ] = function( elem ) {
362 return !!$.data( elem, name );
363 };
364
365 $[ namespace ] = $[ namespace ] || {};
366 $[ namespace ][ name ] = function( options, element ) {
367 // allow instantiation without initializing for simple inheritance
368 if ( arguments.length ) {
369 this._createWidget( options, element );
370 }
371 };
372
373 var basePrototype = new base();
374 // we need to make the options hash a property directly on the new instance
375 // otherwise we'll modify the options hash on the prototype that we're
376 // inheriting from
377 // $.each( basePrototype, function( key, val ) {
378 // if ( $.isPlainObject(val) ) {
379 // basePrototype[ key ] = $.extend( {}, val );
380 // }
381 // });
382 basePrototype.options = $.extend( true, {}, basePrototype.options );
383 $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
384 namespace: namespace,
385 widgetName: name,
386 widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
387 widgetBaseClass: fullName
388 }, prototype );
389
390 $.widget.bridge( name, $[ namespace ][ name ] );
391 };
392
393 $.widget.bridge = function( name, object ) {
394 $.fn[ name ] = function( options ) {
395 var isMethodCall = typeof options === "string",
396 args = Array.prototype.slice.call( arguments, 1 ),
397 returnValue = this;
398
399 // allow multiple hashes to be passed on init
400 options = !isMethodCall && args.length ?
401 $.extend.apply( null, [ true, options ].concat(args) ) :
402 options;
403
404 // prevent calls to internal methods
405 if ( isMethodCall && options.charAt( 0 ) === "_" ) {
406 return returnValue;
407 }
408
409 if ( isMethodCall ) {
410 this.each(function() {
411 var instance = $.data( this, name ),
412 methodValue = instance && $.isFunction( instance[options] ) ?
413 instance[ options ].apply( instance, args ) :
414 instance;
415 // TODO: add this back in 1.9 and use $.error() (see #5972)
416 // if ( !instance ) {
417 // throw "cannot call methods on " + name + " prior to initialization; " +
418 // "attempted to call method '" + options + "'";
419 // }
420 // if ( !$.isFunction( instance[options] ) ) {
421 // throw "no such method '" + options + "' for " + name + " widget instance";
422 // }
423 // var methodValue = instance[ options ].apply( instance, args );
424 if ( methodValue !== instance && methodValue !== undefined ) {
425 returnValue = methodValue;
426 return false;
427 }
428 });
429 } else {
430 this.each(function() {
431 var instance = $.data( this, name );
432 if ( instance ) {
433 instance.option( options || {} )._init();
434 } else {
435 $.data( this, name, new object( options, this ) );
436 }
437 });
438 }
439
440 return returnValue;
441 };
442 };
443
444 $.Widget = function( options, element ) {
445 // allow instantiation without initializing for simple inheritance
446 if ( arguments.length ) {
447 this._createWidget( options, element );
448 }
449 };
450
451 $.Widget.prototype = {
452 widgetName: "widget",
453 widgetEventPrefix: "",
454 options: {
455 disabled: false
456 },
457 _createWidget: function( options, element ) {
458 // $.widget.bridge stores the plugin instance, but we do it anyway
459 // so that it's stored even before the _create function runs
460 $.data( element, this.widgetName, this );
461 this.element = $( element );
462 this.options = $.extend( true, {},
463 this.options,
464 this._getCreateOptions(),
465 options );
466
467 var self = this;
468 this.element.bind( "remove." + this.widgetName, function() {
469 self.destroy();
470 });
471
472 this._create();
473 this._trigger( "create" );
474 this._init();
475 },
476 _getCreateOptions: function() {
477 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
478 },
479 _create: function() {},
480 _init: function() {},
481
482 destroy: function() {
483 this.element
484 .unbind( "." + this.widgetName )
485 .removeData( this.widgetName );
486 this.widget()
487 .unbind( "." + this.widgetName )
488 .removeAttr( "aria-disabled" )
489 .removeClass(
490 this.widgetBaseClass + "-disabled " +
491 "ui-state-disabled" );
492 },
493
494 widget: function() {
495 return this.element;
496 },
497
498 option: function( key, value ) {
499 var options = key;
500
501 if ( arguments.length === 0 ) {
502 // don't return a reference to the internal hash
503 return $.extend( {}, this.options );
504 }
505
506 if (typeof key === "string" ) {
507 if ( value === undefined ) {
508 return this.options[ key ];
509 }
510 options = {};
511 options[ key ] = value;
512 }
513
514 this._setOptions( options );
515
516 return this;
517 },
518 _setOptions: function( options ) {
519 var self = this;
520 $.each( options, function( key, value ) {
521 self._setOption( key, value );
522 });
523
524 return this;
525 },
526 _setOption: function( key, value ) {
527 this.options[ key ] = value;
528
529 if ( key === "disabled" ) {
530 this.widget()
531 [ value ? "addClass" : "removeClass"](
532 this.widgetBaseClass + "-disabled" + " " +
533 "ui-state-disabled" )
534 .attr( "aria-disabled", value );
535 }
536
537 return this;
538 },
539
540 enable: function() {
541 return this._setOption( "disabled", false );
542 },
543 disable: function() {
544 return this._setOption( "disabled", true );
545 },
546
547 _trigger: function( type, event, data ) {
548 var callback = this.options[ type ];
549
550 event = $.Event( event );
551 event.type = ( type === this.widgetEventPrefix ?
552 type :
553 this.widgetEventPrefix + type ).toLowerCase();
554 data = data || {};
555
556 // copy original event properties over to the new event
557 // this would happen if we could call $.event.fix instead of $.Event
558 // but we don't have a way to force an event to be fixed multiple times
559 if ( event.originalEvent ) {
560 for ( var i = $.event.props.length, prop; i; ) {
561 prop = $.event.props[ --i ];
562 event[ prop ] = event.originalEvent[ prop ];
563 }
564 }
565
566 this.element.trigger( event, data );
567
568 return !( $.isFunction(callback) &&
569 callback.call( this.element[0], event, data ) === false ||
570 event.isDefaultPrevented() );
571 }
572 };
573
574 })( jQuery );
575 /*!
576 * jQuery UI Mouse 1.8.14
577 *
578 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
579 * Dual licensed under the MIT or GPL Version 2 licenses.
580 * http://jquery.org/license
581 *
582 * http://docs.jquery.com/UI/Mouse
583 *
584 * Depends:
585 * jquery.ui.widget.js
586 */
587 (function( $, undefined ) {
588
589 var mouseHandled = false;
590 $(document).mousedown(function(e) {
591 mouseHandled = false;
592 });
593
594 $.widget("ui.mouse", {
595 options: {
596 cancel: ':input,option',
597 distance: 1,
598 delay: 0
599 },
600 _mouseInit: function() {
601 var self = this;
602
603 this.element
604 .bind('mousedown.'+this.widgetName, function(event) {
605 return self._mouseDown(event);
606 })
607 .bind('click.'+this.widgetName, function(event) {
608 if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
609 $.removeData(event.target, self.widgetName + '.preventClickEvent');
610 event.stopImmediatePropagation();
611 return false;
612 }
613 });
614
615 this.started = false;
616 },
617
618 // TODO: make sure destroying one instance of mouse doesn't mess with
619 // other instances of mouse
620 _mouseDestroy: function() {
621 this.element.unbind('.'+this.widgetName);
622 },
623
624 _mouseDown: function(event) {
625 // don't let more than one widget handle mouseStart
626 if(mouseHandled) {return};
627
628 // we may have missed mouseup (out of window)
629 (this._mouseStarted && this._mouseUp(event));
630
631 this._mouseDownEvent = event;
632
633 var self = this,
634 btnIsLeft = (event.which == 1),
635 elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).closest(this.options.cancel).length : false);
636 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
637 return true;
638 }
639
640 this.mouseDelayMet = !this.options.delay;
641 if (!this.mouseDelayMet) {
642 this._mouseDelayTimer = setTimeout(function() {
643 self.mouseDelayMet = true;
644 }, this.options.delay);
645 }
646
647 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
648 this._mouseStarted = (this._mouseStart(event) !== false);
649 if (!this._mouseStarted) {
650 event.preventDefault();
651 return true;
652 }
653 }
654
655 // Click event may never have fired (Gecko & Opera)
656 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
657 $.removeData(event.target, this.widgetName + '.preventClickEvent');
658 }
659
660 // these delegates are required to keep context
661 this._mouseMoveDelegate = function(event) {
662 return self._mouseMove(event);
663 };
664 this._mouseUpDelegate = function(event) {
665 return self._mouseUp(event);
666 };
667 $(document)
668 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
669 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
670
671 event.preventDefault();
672
673 mouseHandled = true;
674 return true;
675 },
676
677 _mouseMove: function(event) {
678 // IE mouseup check - mouseup happened when mouse was out of window
679 if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
680 return this._mouseUp(event);
681 }
682
683 if (this._mouseStarted) {
684 this._mouseDrag(event);
685 return event.preventDefault();
686 }
687
688 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
689 this._mouseStarted =
690 (this._mouseStart(this._mouseDownEvent, event) !== false);
691 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
692 }
693
694 return !this._mouseStarted;
695 },
696
697 _mouseUp: function(event) {
698 $(document)
699 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
700 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
701
702 if (this._mouseStarted) {
703 this._mouseStarted = false;
704
705 if (event.target == this._mouseDownEvent.target) {
706 $.data(event.target, this.widgetName + '.preventClickEvent', true);
707 }
708
709 this._mouseStop(event);
710 }
711
712 return false;
713 },
714
715 _mouseDistanceMet: function(event) {
716 return (Math.max(
717 Math.abs(this._mouseDownEvent.pageX - event.pageX),
718 Math.abs(this._mouseDownEvent.pageY - event.pageY)
719 ) >= this.options.distance
720 );
721 },
722
723 _mouseDelayMet: function(event) {
724 return this.mouseDelayMet;
725 },
726
727 // These are placeholder methods, to be overriden by extending plugin
728 _mouseStart: function(event) {},
729 _mouseDrag: function(event) {},
730 _mouseStop: function(event) {},
731 _mouseCapture: function(event) { return true; }
732 });
733
734 })(jQuery);
735 /*
736 * jQuery UI Position 1.8.14
737 *
738 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
739 * Dual licensed under the MIT or GPL Version 2 licenses.
740 * http://jquery.org/license
741 *
742 * http://docs.jquery.com/UI/Position
743 */
744 (function( $, undefined ) {
745
746 $.ui = $.ui || {};
747
748 var horizontalPositions = /left|center|right/,
749 verticalPositions = /top|center|bottom/,
750 center = "center",
751 _position = $.fn.position,
752 _offset = $.fn.offset;
753
754 $.fn.position = function( options ) {
755 if ( !options || !options.of ) {
756 return _position.apply( this, arguments );
757 }
758
759 // make a copy, we don't want to modify arguments
760 options = $.extend( {}, options );
761
762 var target = $( options.of ),
763 targetElem = target[0],
764 collision = ( options.collision || "flip" ).split( " " ),
765 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
766 targetWidth,
767 targetHeight,
768 basePosition;
769
770 if ( targetElem.nodeType === 9 ) {
771 targetWidth = target.width();
772 targetHeight = target.height();
773 basePosition = { top: 0, left: 0 };
774 // TODO: use $.isWindow() in 1.9
775 } else if ( targetElem.setTimeout ) {
776 targetWidth = target.width();
777 targetHeight = target.height();
778 basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
779 } else if ( targetElem.preventDefault ) {
780 // force left top to allow flipping
781 options.at = "left top";
782 targetWidth = targetHeight = 0;
783 basePosition = { top: options.of.pageY, left: options.of.pageX };
784 } else {
785 targetWidth = target.outerWidth();
786 targetHeight = target.outerHeight();
787 basePosition = target.offset();
788 }
789
790 // force my and at to have valid horizontal and veritcal positions
791 // if a value is missing or invalid, it will be converted to center
792 $.each( [ "my", "at" ], function() {
793 var pos = ( options[this] || "" ).split( " " );
794 if ( pos.length === 1) {
795 pos = horizontalPositions.test( pos[0] ) ?
796 pos.concat( [center] ) :
797 verticalPositions.test( pos[0] ) ?
798 [ center ].concat( pos ) :
799 [ center, center ];
800 }
801 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
802 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
803 options[ this ] = pos;
804 });
805
806 // normalize collision option
807 if ( collision.length === 1 ) {
808 collision[ 1 ] = collision[ 0 ];
809 }
810
811 // normalize offset option
812 offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
813 if ( offset.length === 1 ) {
814 offset[ 1 ] = offset[ 0 ];
815 }
816 offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
817
818 if ( options.at[0] === "right" ) {
819 basePosition.left += targetWidth;
820 } else if ( options.at[0] === center ) {
821 basePosition.left += targetWidth / 2;
822 }
823
824 if ( options.at[1] === "bottom" ) {
825 basePosition.top += targetHeight;
826 } else if ( options.at[1] === center ) {
827 basePosition.top += targetHeight / 2;
828 }
829
830 basePosition.left += offset[ 0 ];
831 basePosition.top += offset[ 1 ];
832
833 return this.each(function() {
834 var elem = $( this ),
835 elemWidth = elem.outerWidth(),
836 elemHeight = elem.outerHeight(),
837 marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
838 marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
839 collisionWidth = elemWidth + marginLeft +
840 ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
841 collisionHeight = elemHeight + marginTop +
842 ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
843 position = $.extend( {}, basePosition ),
844 collisionPosition;
845
846 if ( options.my[0] === "right" ) {
847 position.left -= elemWidth;
848 } else if ( options.my[0] === center ) {
849 position.left -= elemWidth / 2;
850 }
851
852 if ( options.my[1] === "bottom" ) {
853 position.top -= elemHeight;
854 } else if ( options.my[1] === center ) {
855 position.top -= elemHeight / 2;
856 }
857
858 // prevent fractions (see #5280)
859 position.left = Math.round( position.left );
860 position.top = Math.round( position.top );
861
862 collisionPosition = {
863 left: position.left - marginLeft,
864 top: position.top - marginTop
865 };
866
867 $.each( [ "left", "top" ], function( i, dir ) {
868 if ( $.ui.position[ collision[i] ] ) {
869 $.ui.position[ collision[i] ][ dir ]( position, {
870 targetWidth: targetWidth,
871 targetHeight: targetHeight,
872 elemWidth: elemWidth,
873 elemHeight: elemHeight,
874 collisionPosition: collisionPosition,
875 collisionWidth: collisionWidth,
876 collisionHeight: collisionHeight,
877 offset: offset,
878 my: options.my,
879 at: options.at
880 });
881 }
882 });
883
884 if ( $.fn.bgiframe ) {
885 elem.bgiframe();
886 }
887 elem.offset( $.extend( position, { using: options.using } ) );
888 });
889 };
890
891 $.ui.position = {
892 fit: {
893 left: function( position, data ) {
894 var win = $( window ),
895 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
896 position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
897 },
898 top: function( position, data ) {
899 var win = $( window ),
900 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
901 position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
902 }
903 },
904
905 flip: {
906 left: function( position, data ) {
907 if ( data.at[0] === center ) {
908 return;
909 }
910 var win = $( window ),
911 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
912 myOffset = data.my[ 0 ] === "left" ?
913 -data.elemWidth :
914 data.my[ 0 ] === "right" ?
915 data.elemWidth :
916 0,
917 atOffset = data.at[ 0 ] === "left" ?
918 data.targetWidth :
919 -data.targetWidth,
920 offset = -2 * data.offset[ 0 ];
921 position.left += data.collisionPosition.left < 0 ?
922 myOffset + atOffset + offset :
923 over > 0 ?
924 myOffset + atOffset + offset :
925 0;
926 },
927 top: function( position, data ) {
928 if ( data.at[1] === center ) {
929 return;
930 }
931 var win = $( window ),
932 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
933 myOffset = data.my[ 1 ] === "top" ?
934 -data.elemHeight :
935 data.my[ 1 ] === "bottom" ?
936 data.elemHeight :
937 0,
938 atOffset = data.at[ 1 ] === "top" ?
939 data.targetHeight :
940 -data.targetHeight,
941 offset = -2 * data.offset[ 1 ];
942 position.top += data.collisionPosition.top < 0 ?
943 myOffset + atOffset + offset :
944 over > 0 ?
945 myOffset + atOffset + offset :
946 0;
947 }
948 }
949 };
950
951 // offset setter from jQuery 1.4
952 if ( !$.offset.setOffset ) {
953 $.offset.setOffset = function( elem, options ) {
954 // set position first, in-case top/left are set even on static elem
955 if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
956 elem.style.position = "relative";
957 }
958 var curElem = $( elem ),
959 curOffset = curElem.offset(),
960 curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
961 curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
962 props = {
963 top: (options.top - curOffset.top) + curTop,
964 left: (options.left - curOffset.left) + curLeft
965 };
966
967 if ( 'using' in options ) {
968 options.using.call( elem, props );
969 } else {
970 curElem.css( props );
971 }
972 };
973
974 $.fn.offset = function( options ) {
975 var elem = this[ 0 ];
976 if ( !elem || !elem.ownerDocument ) { return null; }
977 if ( options ) {
978 return this.each(function() {
979 $.offset.setOffset( this, options );
980 });
981 }
982 return _offset.call( this );
983 };
984 }
985
986 }( jQuery ));
987 /*
988 * jQuery UI Draggable 1.8.14
989 *
990 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
991 * Dual licensed under the MIT or GPL Version 2 licenses.
992 * http://jquery.org/license
993 *
994 * http://docs.jquery.com/UI/Draggables
995 *
996 * Depends:
997 * jquery.ui.core.js
998 * jquery.ui.mouse.js
999 * jquery.ui.widget.js
1000 */
1001 (function( $, undefined ) {
1002
1003 $.widget("ui.draggable", $.ui.mouse, {
1004 widgetEventPrefix: "drag",
1005 options: {
1006 addClasses: true,
1007 appendTo: "parent",
1008 axis: false,
1009 connectToSortable: false,
1010 containment: false,
1011 cursor: "auto",
1012 cursorAt: false,
1013 grid: false,
1014 handle: false,
1015 helper: "original",
1016 iframeFix: false,
1017 opacity: false,
1018 refreshPositions: false,
1019 revert: false,
1020 revertDuration: 500,
1021 scope: "default",
1022 scroll: true,
1023 scrollSensitivity: 20,
1024 scrollSpeed: 20,
1025 snap: false,
1026 snapMode: "both",
1027 snapTolerance: 20,
1028 stack: false,
1029 zIndex: false
1030 },
1031 _create: function() {
1032
1033 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1034 this.element[0].style.position = 'relative';
1035
1036 (this.options.addClasses && this.element.addClass("ui-draggable"));
1037 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1038
1039 this._mouseInit();
1040
1041 },
1042
1043 destroy: function() {
1044 if(!this.element.data('draggable')) return;
1045 this.element
1046 .removeData("draggable")
1047 .unbind(".draggable")
1048 .removeClass("ui-draggable"
1049 + " ui-draggable-dragging"
1050 + " ui-draggable-disabled");
1051 this._mouseDestroy();
1052
1053 return this;
1054 },
1055
1056 _mouseCapture: function(event) {
1057
1058 var o = this.options;
1059
1060 // among others, prevent a drag on a resizable-handle
1061 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1062 return false;
1063
1064 //Quit if we're not on a valid handle
1065 this.handle = this._getHandle(event);
1066 if (!this.handle)
1067 return false;
1068
1069 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1070 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1071 .css({
1072 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1073 position: "absolute", opacity: "0.001", zIndex: 1000
1074 })
1075 .css($(this).offset())
1076 .appendTo("body");
1077 });
1078
1079 return true;
1080
1081 },
1082
1083 _mouseStart: function(event) {
1084
1085 var o = this.options;
1086
1087 //Create and append the visible helper
1088 this.helper = this._createHelper(event);
1089
1090 //Cache the helper size
1091 this._cacheHelperProportions();
1092
1093 //If ddmanager is used for droppables, set the global draggable
1094 if($.ui.ddmanager)
1095 $.ui.ddmanager.current = this;
1096
1097 /*
1098 * - Position generation -
1099 * This block generates everything position related - it's the core of draggables.
1100 */
1101
1102 //Cache the margins of the original element
1103 this._cacheMargins();
1104
1105 //Store the helper's css position
1106 this.cssPosition = this.helper.css("position");
1107 this.scrollParent = this.helper.scrollParent();
1108
1109 //The element's absolute position on the page minus margins
1110 this.offset = this.positionAbs = this.element.offset();
1111 this.offset = {
1112 top: this.offset.top - this.margins.top,
1113 left: this.offset.left - this.margins.left
1114 };
1115
1116 $.extend(this.offset, {
1117 click: { //Where the click happened, relative to the element
1118 left: event.pageX - this.offset.left,
1119 top: event.pageY - this.offset.top
1120 },
1121 parent: this._getParentOffset(),
1122 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1123 });
1124
1125 //Generate the original position
1126 this.originalPosition = this.position = this._generatePosition(event);
1127 this.originalPageX = event.pageX;
1128 this.originalPageY = event.pageY;
1129
1130 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1131 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1132
1133 //Set a containment if given in the options
1134 if(o.containment)
1135 this._setContainment();
1136
1137 //Trigger event + callbacks
1138 if(this._trigger("start", event) === false) {
1139 this._clear();
1140 return false;
1141 }
1142
1143 //Recache the helper size
1144 this._cacheHelperProportions();
1145
1146 //Prepare the droppable offsets
1147 if ($.ui.ddmanager && !o.dropBehaviour)
1148 $.ui.ddmanager.prepareOffsets(this, event);
1149
1150 this.helper.addClass("ui-draggable-dragging");
1151 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1152
1153 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1154 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1155
1156 return true;
1157 },
1158
1159 _mouseDrag: function(event, noPropagation) {
1160
1161 //Compute the helpers position
1162 this.position = this._generatePosition(event);
1163 this.positionAbs = this._convertPositionTo("absolute");
1164
1165 //Call plugins and callbacks and use the resulting position if something is returned
1166 if (!noPropagation) {
1167 var ui = this._uiHash();
1168 if(this._trigger('drag', event, ui) === false) {
1169 this._mouseUp({});
1170 return false;
1171 }
1172 this.position = ui.position;
1173 }
1174
1175 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1176 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1177 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1178
1179 return false;
1180 },
1181
1182 _mouseStop: function(event) {
1183
1184 //If we are using droppables, inform the manager about the drop
1185 var dropped = false;
1186 if ($.ui.ddmanager && !this.options.dropBehaviour)
1187 dropped = $.ui.ddmanager.drop(this, event);
1188
1189 //if a drop comes from outside (a sortable)
1190 if(this.dropped) {
1191 dropped = this.dropped;
1192 this.dropped = false;
1193 }
1194
1195 //if the original element is removed, don't bother to continue if helper is set to "original"
1196 if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
1197 return false;
1198
1199 if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1200 var self = this;
1201 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1202 if(self._trigger("stop", event) !== false) {
1203 self._clear();
1204 }
1205 });
1206 } else {
1207 if(this._trigger("stop", event) !== false) {
1208 this._clear();
1209 }
1210 }
1211
1212 return false;
1213 },
1214
1215 _mouseUp: function(event) {
1216 if (this.options.iframeFix === true) {
1217 $("div.ui-draggable-iframeFix").each(function() {
1218 this.parentNode.removeChild(this);
1219 }); //Remove frame helpers
1220 }
1221
1222 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1223 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1224
1225 return $.ui.mouse.prototype._mouseUp.call(this, event);
1226 },
1227
1228 cancel: function() {
1229
1230 if(this.helper.is(".ui-draggable-dragging")) {
1231 this._mouseUp({});
1232 } else {
1233 this._clear();
1234 }
1235
1236 return this;
1237
1238 },
1239
1240 _getHandle: function(event) {
1241
1242 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1243 $(this.options.handle, this.element)
1244 .find("*")
1245 .andSelf()
1246 .each(function() {
1247 if(this == event.target) handle = true;
1248 });
1249
1250 return handle;
1251
1252 },
1253
1254 _createHelper: function(event) {
1255
1256 var o = this.options;
1257 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1258
1259 if(!helper.parents('body').length)
1260 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1261
1262 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1263 helper.css("position", "absolute");
1264
1265 return helper;
1266
1267 },
1268
1269 _adjustOffsetFromHelper: function(obj) {
1270 if (typeof obj == 'string') {
1271 obj = obj.split(' ');
1272 }
1273 if ($.isArray(obj)) {
1274 obj = {left: +obj[0], top: +obj[1] || 0};
1275 }
1276 if ('left' in obj) {
1277 this.offset.click.left = obj.left + this.margins.left;
1278 }
1279 if ('right' in obj) {
1280 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1281 }
1282 if ('top' in obj) {
1283 this.offset.click.top = obj.top + this.margins.top;
1284 }
1285 if ('bottom' in obj) {
1286 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1287 }
1288 },
1289
1290 _getParentOffset: function() {
1291
1292 //Get the offsetParent and cache its position
1293 this.offsetParent = this.helper.offsetParent();
1294 var po = this.offsetParent.offset();
1295
1296 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1297 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1298 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1299 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1300 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1301 po.left += this.scrollParent.scrollLeft();
1302 po.top += this.scrollParent.scrollTop();
1303 }
1304
1305 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1306 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1307 po = { top: 0, left: 0 };
1308
1309 return {
1310 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1311 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1312 };
1313
1314 },
1315
1316 _getRelativeOffset: function() {
1317
1318 if(this.cssPosition == "relative") {
1319 var p = this.element.position();
1320 return {
1321 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1322 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1323 };
1324 } else {
1325 return { top: 0, left: 0 };
1326 }
1327
1328 },
1329
1330 _cacheMargins: function() {
1331 this.margins = {
1332 left: (parseInt(this.element.css("marginLeft"),10) || 0),
1333 top: (parseInt(this.element.css("marginTop"),10) || 0),
1334 right: (parseInt(this.element.css("marginRight"),10) || 0),
1335 bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1336 };
1337 },
1338
1339 _cacheHelperProportions: function() {
1340 this.helperProportions = {
1341 width: this.helper.outerWidth(),
1342 height: this.helper.outerHeight()
1343 };
1344 },
1345
1346 _setContainment: function() {
1347
1348 var o = this.options;
1349 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1350 if(o.containment == 'document' || o.containment == 'window') this.containment = [
1351 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1352 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1353 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1354 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1355 ];
1356
1357 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1358 var c = $(o.containment);
1359 var ce = c[0]; if(!ce) return;
1360 var co = c.offset();
1361 var over = ($(ce).css("overflow") != 'hidden');
1362
1363 this.containment = [
1364 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1365 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1366 (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1367 (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom
1368 ];
1369 this.relative_container = c;
1370
1371 } else if(o.containment.constructor == Array) {
1372 this.containment = o.containment;
1373 }
1374
1375 },
1376
1377 _convertPositionTo: function(d, pos) {
1378
1379 if(!pos) pos = this.position;
1380 var mod = d == "absolute" ? 1 : -1;
1381 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1382
1383 return {
1384 top: (
1385 pos.top // The absolute mouse position
1386 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1387 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
1388 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1389 ),
1390 left: (
1391 pos.left // The absolute mouse position
1392 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1393 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
1394 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1395 )
1396 };
1397
1398 },
1399
1400 _generatePosition: function(event) {
1401
1402 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1403 var pageX = event.pageX;
1404 var pageY = event.pageY;
1405
1406 /*
1407 * - Position constraining -
1408 * Constrain the position to a mix of grid, containment.
1409 */
1410
1411 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1412 var containment;
1413 if(this.containment) {
1414 if (this.relative_container){
1415 var co = this.relative_container.offset();
1416 containment = [ this.containment[0] + co.left,
1417 this.containment[1] + co.top,
1418 this.containment[2] + co.left,
1419 this.containment[3] + co.top ];
1420 }
1421 else {
1422 containment = this.containment;
1423 }
1424
1425 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1426 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1427 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1428 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1429 }
1430
1431 if(o.grid) {
1432 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1433 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1434 pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1435
1436 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1437 pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1438 }
1439
1440 }
1441
1442 return {
1443 top: (
1444 pageY // The absolute mouse position
1445 - this.offset.click.top // Click offset (relative to the element)
1446 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
1447 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
1448 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1449 ),
1450 left: (
1451 pageX // The absolute mouse position
1452 - this.offset.click.left // Click offset (relative to the element)
1453 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
1454 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
1455 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1456 )
1457 };
1458
1459 },
1460
1461 _clear: function() {
1462 this.helper.removeClass("ui-draggable-dragging");
1463 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1464 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1465 this.helper = null;
1466 this.cancelHelperRemoval = false;
1467 },
1468
1469 // From now on bulk stuff - mainly helpers
1470
1471 _trigger: function(type, event, ui) {
1472 ui = ui || this._uiHash();
1473 $.ui.plugin.call(this, type, [event, ui]);
1474 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1475 return $.Widget.prototype._trigger.call(this, type, event, ui);
1476 },
1477
1478 plugins: {},
1479
1480 _uiHash: function(event) {
1481 return {
1482 helper: this.helper,
1483 position: this.position,
1484 originalPosition: this.originalPosition,
1485 offset: this.positionAbs
1486 };
1487 }
1488
1489 });
1490
1491 $.extend($.ui.draggable, {
1492 version: "1.8.14"
1493 });
1494
1495 $.ui.plugin.add("draggable", "connectToSortable", {
1496 start: function(event, ui) {
1497
1498 var inst = $(this).data("draggable"), o = inst.options,
1499 uiSortable = $.extend({}, ui, { item: inst.element });
1500 inst.sortables = [];
1501 $(o.connectToSortable).each(function() {
1502 var sortable = $.data(this, 'sortable');
1503 if (sortable && !sortable.options.disabled) {
1504 inst.sortables.push({
1505 instance: sortable,
1506 shouldRevert: sortable.options.revert
1507 });
1508 sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
1509 sortable._trigger("activate", event, uiSortable);
1510 }
1511 });
1512
1513 },
1514 stop: function(event, ui) {
1515
1516 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1517 var inst = $(this).data("draggable"),
1518 uiSortable = $.extend({}, ui, { item: inst.element });
1519
1520 $.each(inst.sortables, function() {
1521 if(this.instance.isOver) {
1522
1523 this.instance.isOver = 0;
1524
1525 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1526 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1527
1528 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1529 if(this.shouldRevert) this.instance.options.revert = true;
1530
1531 //Trigger the stop of the sortable
1532 this.instance._mouseStop(event);
1533
1534 this.instance.options.helper = this.instance.options._helper;
1535
1536 //If the helper has been the original item, restore properties in the sortable
1537 if(inst.options.helper == 'original')
1538 this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1539
1540 } else {
1541 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1542 this.instance._trigger("deactivate", event, uiSortable);
1543 }
1544
1545 });
1546
1547 },
1548 drag: function(event, ui) {
1549
1550 var inst = $(this).data("draggable"), self = this;
1551
1552 var checkPos = function(o) {
1553 var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1554 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1555 var itemHeight = o.height, itemWidth = o.width;
1556 var itemTop = o.top, itemLeft = o.left;
1557
1558 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1559 };
1560
1561 $.each(inst.sortables, function(i) {
1562
1563 //Copy over some variables to allow calling the sortable's native _intersectsWith
1564 this.instance.positionAbs = inst.positionAbs;
1565 this.instance.helperProportions = inst.helperProportions;
1566 this.instance.offset.click = inst.offset.click;
1567
1568 if(this.instance._intersectsWith(this.instance.containerCache)) {
1569
1570 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1571 if(!this.instance.isOver) {
1572
1573 this.instance.isOver = 1;
1574 //Now we fake the start of dragging for the sortable instance,
1575 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1576 //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1577 this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1578 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1579 this.instance.options.helper = function() { return ui.helper[0]; };
1580
1581 event.target = this.instance.currentItem[0];
1582 this.instance._mouseCapture(event, true);
1583 this.instance._mouseStart(event, true, true);
1584
1585 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1586 this.instance.offset.click.top = inst.offset.click.top;
1587 this.instance.offset.click.left = inst.offset.click.left;
1588 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1589 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1590
1591 inst._trigger("toSortable", event);
1592 inst.dropped = this.instance.element; //draggable revert needs that
1593 //hack so receive/update callbacks work (mostly)
1594 inst.currentItem = inst.element;
1595 this.instance.fromOutside = inst;
1596
1597 }
1598
1599 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1600 if(this.instance.currentItem) this.instance._mouseDrag(event);
1601
1602 } else {
1603
1604 //If it doesn't intersect with the sortable, and it intersected before,
1605 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1606 if(this.instance.isOver) {
1607
1608 this.instance.isOver = 0;
1609 this.instance.cancelHelperRemoval = true;
1610
1611 //Prevent reverting on this forced stop
1612 this.instance.options.revert = false;
1613
1614 // The out event needs to be triggered independently
1615 this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1616
1617 this.instance._mouseStop(event, true);
1618 this.instance.options.helper = this.instance.options._helper;
1619
1620 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1621 this.instance.currentItem.remove();
1622 if(this.instance.placeholder) this.instance.placeholder.remove();
1623
1624 inst._trigger("fromSortable", event);
1625 inst.dropped = false; //draggable revert needs that
1626 }
1627
1628 };
1629
1630 });
1631
1632 }
1633 });
1634
1635 $.ui.plugin.add("draggable", "cursor", {
1636 start: function(event, ui) {
1637 var t = $('body'), o = $(this).data('draggable').options;
1638 if (t.css("cursor")) o._cursor = t.css("cursor");
1639 t.css("cursor", o.cursor);
1640 },
1641 stop: function(event, ui) {
1642 var o = $(this).data('draggable').options;
1643 if (o._cursor) $('body').css("cursor", o._cursor);
1644 }
1645 });
1646
1647 $.ui.plugin.add("draggable", "opacity", {
1648 start: function(event, ui) {
1649 var t = $(ui.helper), o = $(this).data('draggable').options;
1650 if(t.css("opacity")) o._opacity = t.css("opacity");
1651 t.css('opacity', o.opacity);
1652 },
1653 stop: function(event, ui) {
1654 var o = $(this).data('draggable').options;
1655 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1656 }
1657 });
1658
1659 $.ui.plugin.add("draggable", "scroll", {
1660 start: function(event, ui) {
1661 var i = $(this).data("draggable");
1662 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1663 },
1664 drag: function(event, ui) {
1665
1666 var i = $(this).data("draggable"), o = i.options, scrolled = false;
1667
1668 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1669
1670 if(!o.axis || o.axis != 'x') {
1671 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1672 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1673 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1674 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1675 }
1676
1677 if(!o.axis || o.axis != 'y') {
1678 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1679 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1680 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1681 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1682 }
1683
1684 } else {
1685
1686 if(!o.axis || o.axis != 'x') {
1687 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1688 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1689 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1690 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1691 }
1692
1693 if(!o.axis || o.axis != 'y') {
1694 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1695 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1696 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1697 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1698 }
1699
1700 }
1701
1702 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1703 $.ui.ddmanager.prepareOffsets(i, event);
1704
1705 }
1706 });
1707
1708 $.ui.plugin.add("draggable", "snap", {
1709 start: function(event, ui) {
1710
1711 var i = $(this).data("draggable"), o = i.options;
1712 i.snapElements = [];
1713
1714 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1715 var $t = $(this); var $o = $t.offset();
1716 if(this != i.element[0]) i.snapElements.push({
1717 item: this,
1718 width: $t.outerWidth(), height: $t.outerHeight(),
1719 top: $o.top, left: $o.left
1720 });
1721 });
1722
1723 },
1724 drag: function(event, ui) {
1725
1726 var inst = $(this).data("draggable"), o = inst.options;
1727 var d = o.snapTolerance;
1728
1729 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1730 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1731
1732 for (var i = inst.snapElements.length - 1; i >= 0; i--){
1733
1734 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1735 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1736
1737 //Yes, I know, this is insane ;)
1738 if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1739 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1740 inst.snapElements[i].snapping = false;
1741 continue;
1742 }
1743
1744 if(o.snapMode != 'inner') {
1745 var ts = Math.abs(t - y2) <= d;
1746 var bs = Math.abs(b - y1) <= d;
1747 var ls = Math.abs(l - x2) <= d;
1748 var rs = Math.abs(r - x1) <= d;
1749 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1750 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1751 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1752 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1753 }
1754
1755 var first = (ts || bs || ls || rs);
1756
1757 if(o.snapMode != 'outer') {
1758 var ts = Math.abs(t - y1) <= d;
1759 var bs = Math.abs(b - y2) <= d;
1760 var ls = Math.abs(l - x1) <= d;
1761 var rs = Math.abs(r - x2) <= d;
1762 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1763 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1764 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1765 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1766 }
1767
1768 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1769 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1770 inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1771
1772 };
1773
1774 }
1775 });
1776
1777 $.ui.plugin.add("draggable", "stack", {
1778 start: function(event, ui) {
1779
1780 var o = $(this).data("draggable").options;
1781
1782 var group = $.makeArray($(o.stack)).sort(function(a,b) {
1783 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1784 });
1785 if (!group.length) { return; }
1786
1787 var min = parseInt(group[0].style.zIndex) || 0;
1788 $(group).each(function(i) {
1789 this.style.zIndex = min + i;
1790 });
1791
1792 this[0].style.zIndex = min + group.length;
1793
1794 }
1795 });
1796
1797 $.ui.plugin.add("draggable", "zIndex", {
1798 start: function(event, ui) {
1799 var t = $(ui.helper), o = $(this).data("draggable").options;
1800 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1801 t.css('zIndex', o.zIndex);
1802 },
1803 stop: function(event, ui) {
1804 var o = $(this).data("draggable").options;
1805 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1806 }
1807 });
1808
1809 })(jQuery);
1810 /*
1811 * jQuery UI Droppable 1.8.14
1812 *
1813 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1814 * Dual licensed under the MIT or GPL Version 2 licenses.
1815 * http://jquery.org/license
1816 *
1817 * http://docs.jquery.com/UI/Droppables
1818 *
1819 * Depends:
1820 * jquery.ui.core.js
1821 * jquery.ui.widget.js
1822 * jquery.ui.mouse.js
1823 * jquery.ui.draggable.js
1824 */
1825 (function( $, undefined ) {
1826
1827 $.widget("ui.droppable", {
1828 widgetEventPrefix: "drop",
1829 options: {
1830 accept: '*',
1831 activeClass: false,
1832 addClasses: true,
1833 greedy: false,
1834 hoverClass: false,
1835 scope: 'default',
1836 tolerance: 'intersect'
1837 },
1838 _create: function() {
1839
1840 var o = this.options, accept = o.accept;
1841 this.isover = 0; this.isout = 1;
1842
1843 this.accept = $.isFunction(accept) ? accept : function(d) {
1844 return d.is(accept);
1845 };
1846
1847 //Store the droppable's proportions
1848 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1849
1850 // Add the reference and positions to the manager
1851 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1852 $.ui.ddmanager.droppables[o.scope].push(this);
1853
1854 (o.addClasses && this.element.addClass("ui-droppable"));
1855
1856 },
1857
1858 destroy: function() {
1859 var drop = $.ui.ddmanager.droppables[this.options.scope];
1860 for ( var i = 0; i < drop.length; i++ )
1861 if ( drop[i] == this )
1862 drop.splice(i, 1);
1863
1864 this.element
1865 .removeClass("ui-droppable ui-droppable-disabled")
1866 .removeData("droppable")
1867 .unbind(".droppable");
1868
1869 return this;
1870 },
1871
1872 _setOption: function(key, value) {
1873
1874 if(key == 'accept') {
1875 this.accept = $.isFunction(value) ? value : function(d) {
1876 return d.is(value);
1877 };
1878 }
1879 $.Widget.prototype._setOption.apply(this, arguments);
1880 },
1881
1882 _activate: function(event) {
1883 var draggable = $.ui.ddmanager.current;
1884 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1885 (draggable && this._trigger('activate', event, this.ui(draggable)));
1886 },
1887
1888 _deactivate: function(event) {
1889 var draggable = $.ui.ddmanager.current;
1890 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1891 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
1892 },
1893
1894 _over: function(event) {
1895
1896 var draggable = $.ui.ddmanager.current;
1897 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1898
1899 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1900 if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1901 this._trigger('over', event, this.ui(draggable));
1902 }
1903
1904 },
1905
1906 _out: function(event) {
1907
1908 var draggable = $.ui.ddmanager.current;
1909 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1910
1911 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1912 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1913 this._trigger('out', event, this.ui(draggable));
1914 }
1915
1916 },
1917
1918 _drop: function(event,custom) {
1919
1920 var draggable = custom || $.ui.ddmanager.current;
1921 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1922
1923 var childrenIntersection = false;
1924 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1925 var inst = $.data(this, 'droppable');
1926 if(
1927 inst.options.greedy
1928 && !inst.options.disabled
1929 && inst.options.scope == draggable.options.scope
1930 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1931 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1932 ) { childrenIntersection = true; return false; }
1933 });
1934 if(childrenIntersection) return false;
1935
1936 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1937 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1938 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1939 this._trigger('drop', event, this.ui(draggable));
1940 return this.element;
1941 }
1942
1943 return false;
1944
1945 },
1946
1947 ui: function(c) {
1948 return {
1949 draggable: (c.currentItem || c.element),
1950 helper: c.helper,
1951 position: c.position,
1952 offset: c.positionAbs
1953 };
1954 }
1955
1956 });
1957
1958 $.extend($.ui.droppable, {
1959 version: "1.8.14"
1960 });
1961
1962 $.ui.intersect = function(draggable, droppable, toleranceMode) {
1963
1964 if (!droppable.offset) return false;
1965
1966 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1967 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1968 var l = droppable.offset.left, r = l + droppable.proportions.width,
1969 t = droppable.offset.top, b = t + droppable.proportions.height;
1970
1971 switch (toleranceMode) {
1972 case 'fit':
1973 return (l <= x1 && x2 <= r
1974 && t <= y1 && y2 <= b);
1975 break;
1976 case 'intersect':
1977 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1978 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
1979 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1980 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1981 break;
1982 case 'pointer':
1983 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1984 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1985 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1986 return isOver;
1987 break;
1988 case 'touch':
1989 return (
1990 (y1 >= t && y1 <= b) || // Top edge touching
1991 (y2 >= t && y2 <= b) || // Bottom edge touching
1992 (y1 < t && y2 > b) // Surrounded vertically
1993 ) && (
1994 (x1 >= l && x1 <= r) || // Left edge touching
1995 (x2 >= l && x2 <= r) || // Right edge touching
1996 (x1 < l && x2 > r) // Surrounded horizontally
1997 );
1998 break;
1999 default:
2000 return false;
2001 break;
2002 }
2003
2004 };
2005
2006 /*
2007 This manager tracks offsets of draggables and droppables
2008 */
2009 $.ui.ddmanager = {
2010 current: null,
2011 droppables: { 'default': [] },
2012 prepareOffsets: function(t, event) {
2013
2014 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2015 var type = event ? event.type : null; // workaround for #2317
2016 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2017
2018 droppablesLoop: for (var i = 0; i < m.length; i++) {
2019
2020 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
2021 for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
2022 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
2023
2024 if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2025
2026 m[i].offset = m[i].element.offset();
2027 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2028
2029 }
2030
2031 },
2032 drop: function(draggable, event) {
2033
2034 var dropped = false;
2035 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2036
2037 if(!this.options) return;
2038 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2039 dropped = dropped || this._drop.call(this, event);
2040
2041 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2042 this.isout = 1; this.isover = 0;
2043 this._deactivate.call(this, event);
2044 }
2045
2046 });
2047 return dropped;
2048
2049 },
2050 dragStart: function( draggable, event ) {
2051 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2052 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2053 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2054 });
2055 },
2056 drag: function(draggable, event) {
2057
2058 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2059 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2060
2061 //Run through all droppables and check their positions based on specific tolerance options
2062 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2063
2064 if(this.options.disabled || this.greedyChild || !this.visible) return;
2065 var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2066
2067 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2068 if(!c) return;
2069
2070 var parentInstance;
2071 if (this.options.greedy) {
2072 var parent = this.element.parents(':data(droppable):eq(0)');
2073 if (parent.length) {
2074 parentInstance = $.data(parent[0], 'droppable');
2075 parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2076 }
2077 }
2078
2079 // we just moved into a greedy child
2080 if (parentInstance && c == 'isover') {
2081 parentInstance['isover'] = 0;
2082 parentInstance['isout'] = 1;
2083 parentInstance._out.call(parentInstance, event);
2084 }
2085
2086 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2087 this[c == "isover" ? "_over" : "_out"].call(this, event);
2088
2089 // we just moved out of a greedy child
2090 if (parentInstance && c == 'isout') {
2091 parentInstance['isout'] = 0;
2092 parentInstance['isover'] = 1;
2093 parentInstance._over.call(parentInstance, event);
2094 }
2095 });
2096
2097 },
2098 dragStop: function( draggable, event ) {
2099 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2100 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2101 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2102 }
2103 };
2104
2105 })(jQuery);
2106 /*
2107 * jQuery UI Resizable 1.8.14
2108 *
2109 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2110 * Dual licensed under the MIT or GPL Version 2 licenses.
2111 * http://jquery.org/license
2112 *
2113 * http://docs.jquery.com/UI/Resizables
2114 *
2115 * Depends:
2116 * jquery.ui.core.js
2117 * jquery.ui.mouse.js
2118 * jquery.ui.widget.js
2119 */
2120 (function( $, undefined ) {
2121
2122 $.widget("ui.resizable", $.ui.mouse, {
2123 widgetEventPrefix: "resize",
2124 options: {
2125 alsoResize: false,
2126 animate: false,
2127 animateDuration: "slow",
2128 animateEasing: "swing",
2129 aspectRatio: false,
2130 autoHide: false,
2131 containment: false,
2132 ghost: false,
2133 grid: false,
2134 handles: "e,s,se",
2135 helper: false,
2136 maxHeight: null,
2137 maxWidth: null,
2138 minHeight: 10,
2139 minWidth: 10,
2140 zIndex: 1000
2141 },
2142 _create: function() {
2143
2144 var self = this, o = this.options;
2145 this.element.addClass("ui-resizable");
2146
2147 $.extend(this, {
2148 _aspectRatio: !!(o.aspectRatio),
2149 aspectRatio: o.aspectRatio,
2150 originalElement: this.element,
2151 _proportionallyResizeElements: [],
2152 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2153 });
2154
2155 //Wrap the element if it cannot hold child nodes
2156 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2157
2158 //Opera fix for relative positioning
2159 if (/relative/.test(this.element.css('position')) && $.browser.opera)
2160 this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
2161
2162 //Create a wrapper element and set the wrapper to the new current internal element
2163 this.element.wrap(
2164 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2165 position: this.element.css('position'),
2166 width: this.element.outerWidth(),
2167 height: this.element.outerHeight(),
2168 top: this.element.css('top'),
2169 left: this.element.css('left')
2170 })
2171 );
2172
2173 //Overwrite the original this.element
2174 this.element = this.element.parent().data(
2175 "resizable", this.element.data('resizable')
2176 );
2177
2178 this.elementIsWrapper = true;
2179
2180 //Move margins to the wrapper
2181 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2182 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2183
2184 //Prevent Safari textarea resize
2185 this.originalResizeStyle = this.originalElement.css('resize');
2186 this.originalElement.css('resize', 'none');
2187
2188 //Push the actual element to our proportionallyResize internal array
2189 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2190
2191 // avoid IE jump (hard set the margin)
2192 this.originalElement.css({ margin: this.originalElement.css('margin') });
2193
2194 // fix handlers offset
2195 this._proportionallyResize();
2196
2197 }
2198
2199 this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
2200 if(this.handles.constructor == String) {
2201
2202 if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2203 var n = this.handles.split(","); this.handles = {};
2204
2205 for(var i = 0; i < n.length; i++) {
2206
2207 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2208 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2209
2210 // increase zIndex of sw, se, ne, nw axis
2211 //TODO : this modifies original option
2212 if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
2213
2214 //TODO : What's going on here?
2215 if ('se' == handle) {
2216 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2217 };
2218
2219 //Insert into internal handles object and append to element
2220 this.handles[handle] = '.ui-resizable-'+handle;
2221 this.element.append(axis);
2222 }
2223
2224 }
2225
2226 this._renderAxis = function(target) {
2227
2228 target = target || this.element;
2229
2230 for(var i in this.handles) {
2231
2232 if(this.handles[i].constructor == String)
2233 this.handles[i] = $(this.handles[i], this.element).show();
2234
2235 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2236 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2237
2238 var axis = $(this.handles[i], this.element), padWrapper = 0;
2239
2240 //Checking the correct pad and border
2241 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2242
2243 //The padding type i have to apply...
2244 var padPos = [ 'padding',
2245 /ne|nw|n/.test(i) ? 'Top' :
2246 /se|sw|s/.test(i) ? 'Bottom' :
2247 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
2248
2249 target.css(padPos, padWrapper);
2250
2251 this._proportionallyResize();
2252
2253 }
2254
2255 //TODO: What's that good for? There's not anything to be executed left
2256 if(!$(this.handles[i]).length)
2257 continue;
2258
2259 }
2260 };
2261
2262 //TODO: make renderAxis a prototype function
2263 this._renderAxis(this.element);
2264
2265 this._handles = $('.ui-resizable-handle', this.element)
2266 .disableSelection();
2267
2268 //Matching axis name
2269 this._handles.mouseover(function() {
2270 if (!self.resizing) {
2271 if (this.className)
2272 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2273 //Axis, default = se
2274 self.axis = axis && axis[1] ? axis[1] : 'se';
2275 }
2276 });
2277
2278 //If we want to auto hide the elements
2279 if (o.autoHide) {
2280 this._handles.hide();
2281 $(this.element)
2282 .addClass("ui-resizable-autohide")
2283 .hover(function() {
2284 if (o.disabled) return;
2285 $(this).removeClass("ui-resizable-autohide");
2286 self._handles.show();
2287 },
2288 function(){
2289 if (o.disabled) return;
2290 if (!self.resizing) {
2291 $(this).addClass("ui-resizable-autohide");
2292 self._handles.hide();
2293 }
2294 });
2295 }
2296
2297 //Initialize the mouse interaction
2298 this._mouseInit();
2299
2300 },
2301
2302 destroy: function() {
2303
2304 this._mouseDestroy();
2305
2306 var _destroy = function(exp) {
2307 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2308 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2309 };
2310
2311 //TODO: Unwrap at same DOM position
2312 if (this.elementIsWrapper) {
2313 _destroy(this.element);
2314 var wrapper = this.element;
2315 wrapper.after(
2316 this.originalElement.css({
2317 position: wrapper.css('position'),
2318 width: wrapper.outerWidth(),
2319 height: wrapper.outerHeight(),
2320 top: wrapper.css('top'),
2321 left: wrapper.css('left')
2322 })
2323 ).remove();
2324 }
2325
2326 this.originalElement.css('resize', this.originalResizeStyle);
2327 _destroy(this.originalElement);
2328
2329 return this;
2330 },
2331
2332 _mouseCapture: function(event) {
2333 var handle = false;
2334 for (var i in this.handles) {
2335 if ($(this.handles[i])[0] == event.target) {
2336 handle = true;
2337 }
2338 }
2339
2340 return !this.options.disabled && handle;
2341 },
2342
2343 _mouseStart: function(event) {
2344
2345 var o = this.options, iniPos = this.element.position(), el = this.element;
2346
2347 this.resizing = true;
2348 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2349
2350 // bugfix for http://dev.jquery.com/ticket/1749
2351 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2352 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2353 }
2354
2355 //Opera fixing relative position
2356 if ($.browser.opera && (/relative/).test(el.css('position')))
2357 el.css({ position: 'relative', top: 'auto', left: 'auto' });
2358
2359 this._renderProxy();
2360
2361 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2362
2363 if (o.containment) {
2364 curleft += $(o.containment).scrollLeft() || 0;
2365 curtop += $(o.containment).scrollTop() || 0;
2366 }
2367
2368 //Store needed variables
2369 this.offset = this.helper.offset();
2370 this.position = { left: curleft, top: curtop };
2371 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2372 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2373 this.originalPosition = { left: curleft, top: curtop };
2374 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2375 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2376
2377 //Aspect Ratio
2378 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2379
2380 var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2381 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2382
2383 el.addClass("ui-resizable-resizing");
2384 this._propagate("start", event);
2385 return true;
2386 },
2387
2388 _mouseDrag: function(event) {
2389
2390 //Increase performance, avoid regex
2391 var el = this.helper, o = this.options, props = {},
2392 self = this, smp = this.originalMousePosition, a = this.axis;
2393
2394 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2395 var trigger = this._change[a];
2396 if (!trigger) return false;
2397
2398 // Calculate the attrs that will be change
2399 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2400
2401 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2402 this._updateVirtualBoundaries(event.shiftKey);
2403 if (this._aspectRatio || event.shiftKey)
2404 data = this._updateRatio(data, event);
2405
2406 data = this._respectSize(data, event);
2407
2408 // plugins callbacks need to be called first
2409 this._propagate("resize", event);
2410
2411 el.css({
2412 top: this.position.top + "px", left: this.position.left + "px",
2413 width: this.size.width + "px", height: this.size.height + "px"
2414 });
2415
2416 if (!this._helper && this._proportionallyResizeElements.length)
2417 this._proportionallyResize();
2418
2419 this._updateCache(data);
2420
2421 // calling the user callback at the end
2422 this._trigger('resize', event, this.ui());
2423
2424 return false;
2425 },
2426
2427 _mouseStop: function(event) {
2428
2429 this.resizing = false;
2430 var o = this.options, self = this;
2431
2432 if(this._helper) {
2433 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2434 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2435 soffsetw = ista ? 0 : self.sizeDiff.width;
2436
2437 var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) },
2438 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2439 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2440
2441 if (!o.animate)
2442 this.element.css($.extend(s, { top: top, left: left }));
2443
2444 self.helper.height(self.size.height);
2445 self.helper.width(self.size.width);
2446
2447 if (this._helper && !o.animate) this._proportionallyResize();
2448 }
2449
2450 $('body').css('cursor', 'auto');
2451
2452 this.element.removeClass("ui-resizable-resizing");
2453
2454 this._propagate("stop", event);
2455
2456 if (this._helper) this.helper.remove();
2457 return false;
2458
2459 },
2460
2461 _updateVirtualBoundaries: function(forceAspectRatio) {
2462 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2463
2464 b = {
2465 minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2466 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2467 minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2468 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2469 };
2470
2471 if(this._aspectRatio || forceAspectRatio) {
2472 // We want to create an enclosing box whose aspect ration is the requested one
2473 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2474 pMinWidth = b.minHeight * this.aspectRatio;
2475 pMinHeight = b.minWidth / this.aspectRatio;
2476 pMaxWidth = b.maxHeight * this.aspectRatio;
2477 pMaxHeight = b.maxWidth / this.aspectRatio;
2478
2479 if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2480 if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2481 if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2482 if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2483 }
2484 this._vBoundaries = b;
2485 },
2486
2487 _updateCache: function(data) {
2488 var o = this.options;
2489 this.offset = this.helper.offset();
2490 if (isNumber(data.left)) this.position.left = data.left;
2491 if (isNumber(data.top)) this.position.top = data.top;
2492 if (isNumber(data.height)) this.size.height = data.height;
2493 if (isNumber(data.width)) this.size.width = data.width;
2494 },
2495
2496 _updateRatio: function(data, event) {
2497
2498 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2499
2500 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2501 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2502
2503 if (a == 'sw') {
2504 data.left = cpos.left + (csize.width - data.width);
2505 data.top = null;
2506 }
2507 if (a == 'nw') {
2508 data.top = cpos.top + (csize.height - data.height);
2509 data.left = cpos.left + (csize.width - data.width);
2510 }
2511
2512 return data;
2513 },
2514
2515 _respectSize: function(data, event) {
2516
2517 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2518 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2519 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2520
2521 if (isminw) data.width = o.minWidth;
2522 if (isminh) data.height = o.minHeight;
2523 if (ismaxw) data.width = o.maxWidth;
2524 if (ismaxh) data.height = o.maxHeight;
2525
2526 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2527 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2528
2529 if (isminw && cw) data.left = dw - o.minWidth;
2530 if (ismaxw && cw) data.left = dw - o.maxWidth;
2531 if (isminh && ch) data.top = dh - o.minHeight;
2532 if (ismaxh && ch) data.top = dh - o.maxHeight;
2533
2534 // fixing jump error on top/left - bug #2330
2535 var isNotwh = !data.width && !data.height;
2536 if (isNotwh && !data.left && data.top) data.top = null;
2537 else if (isNotwh && !data.top && data.left) data.left = null;
2538
2539 return data;
2540 },
2541
2542 _proportionallyResize: function() {
2543
2544 var o = this.options;
2545 if (!this._proportionallyResizeElements.length) return;
2546 var element = this.helper || this.element;
2547
2548 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2549
2550 var prel = this._proportionallyResizeElements[i];
2551
2552 if (!this.borderDif) {
2553 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2554 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2555
2556 this.borderDif = $.map(b, function(v, i) {
2557 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2558 return border + padding;
2559 });
2560 }
2561
2562 if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2563 continue;
2564
2565 prel.css({
2566 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2567 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2568 });
2569
2570 };
2571
2572 },
2573
2574 _renderProxy: function() {
2575
2576 var el = this.element, o = this.options;
2577 this.elementOffset = el.offset();
2578
2579 if(this._helper) {
2580
2581 this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2582
2583 // fix ie6 offset TODO: This seems broken
2584 var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2585 pxyoffset = ( ie6 ? 2 : -1 );
2586
2587 this.helper.addClass(this._helper).css({
2588 width: this.element.outerWidth() + pxyoffset,
2589 height: this.element.outerHeight() + pxyoffset,
2590 position: 'absolute',
2591 left: this.elementOffset.left - ie6offset +'px',
2592 top: this.elementOffset.top - ie6offset +'px',
2593 zIndex: ++o.zIndex //TODO: Don't modify option
2594 });
2595
2596 this.helper
2597 .appendTo("body")
2598 .disableSelection();
2599
2600 } else {
2601 this.helper = this.element;
2602 }
2603
2604 },
2605
2606 _change: {
2607 e: function(event, dx, dy) {
2608 return { width: this.originalSize.width + dx };
2609 },
2610 w: function(event, dx, dy) {
2611 var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2612 return { left: sp.left + dx, width: cs.width - dx };
2613 },
2614 n: function(event, dx, dy) {
2615 var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2616 return { top: sp.top + dy, height: cs.height - dy };
2617 },
2618 s: function(event, dx, dy) {
2619 return { height: this.originalSize.height + dy };
2620 },
2621 se: function(event, dx, dy) {
2622 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2623 },
2624 sw: function(event, dx, dy) {
2625 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2626 },
2627 ne: function(event, dx, dy) {
2628 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2629 },
2630 nw: function(event, dx, dy) {
2631 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2632 }
2633 },
2634
2635 _propagate: function(n, event) {
2636 $.ui.plugin.call(this, n, [event, this.ui()]);
2637 (n != "resize" && this._trigger(n, event, this.ui()));
2638 },
2639
2640 plugins: {},
2641
2642 ui: function() {
2643 return {
2644 originalElement: this.originalElement,
2645 element: this.element,
2646 helper: this.helper,
2647 position: this.position,
2648 size: this.size,
2649 originalSize: this.originalSize,
2650 originalPosition: this.originalPosition
2651 };
2652 }
2653
2654 });
2655
2656 $.extend($.ui.resizable, {
2657 version: "1.8.14"
2658 });
2659
2660 /*
2661 * Resizable Extensions
2662 */
2663
2664 $.ui.plugin.add("resizable", "alsoResize", {
2665
2666 start: function (event, ui) {
2667 var self = $(this).data("resizable"), o = self.options;
2668
2669 var _store = function (exp) {
2670 $(exp).each(function() {
2671 var el = $(this);
2672 el.data("resizable-alsoresize", {
2673 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2674 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
2675 position: el.css('position') // to reset Opera on stop()
2676 });
2677 });
2678 };
2679
2680 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2681 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2682 else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2683 }else{
2684 _store(o.alsoResize);
2685 }
2686 },
2687
2688 resize: function (event, ui) {
2689 var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2690
2691 var delta = {
2692 height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2693 top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2694 },
2695
2696 _alsoResize = function (exp, c) {
2697 $(exp).each(function() {
2698 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
2699 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2700
2701 $.each(css, function (i, prop) {
2702 var sum = (start[prop]||0) + (delta[prop]||0);
2703 if (sum && sum >= 0)
2704 style[prop] = sum || null;
2705 });
2706
2707 // Opera fixing relative position
2708 if ($.browser.opera && /relative/.test(el.css('position'))) {
2709 self._revertToRelativePosition = true;
2710 el.css({ position: 'absolute', top: 'auto', left: 'auto' });
2711 }
2712
2713 el.css(style);
2714 });
2715 };
2716
2717 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2718 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2719 }else{
2720 _alsoResize(o.alsoResize);
2721 }
2722 },
2723
2724 stop: function (event, ui) {
2725 var self = $(this).data("resizable"), o = self.options;
2726
2727 var _reset = function (exp) {
2728 $(exp).each(function() {
2729 var el = $(this);
2730 // reset position for Opera - no need to verify it was changed
2731 el.css({ position: el.data("resizable-alsoresize").position });
2732 });
2733 };
2734
2735 if (self._revertToRelativePosition) {
2736 self._revertToRelativePosition = false;
2737 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2738 $.each(o.alsoResize, function (exp) { _reset(exp); });
2739 }else{
2740 _reset(o.alsoResize);
2741 }
2742 }
2743
2744 $(this).removeData("resizable-alsoresize");
2745 }
2746 });
2747
2748 $.ui.plugin.add("resizable", "animate", {
2749
2750 stop: function(event, ui) {
2751 var self = $(this).data("resizable"), o = self.options;
2752
2753 var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2754 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2755 soffsetw = ista ? 0 : self.sizeDiff.width;
2756
2757 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2758 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2759 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2760
2761 self.element.animate(
2762 $.extend(style, top && left ? { top: top, left: left } : {}), {
2763 duration: o.animateDuration,
2764 easing: o.animateEasing,
2765 step: function() {
2766
2767 var data = {
2768 width: parseInt(self.element.css('width'), 10),
2769 height: parseInt(self.element.css('height'), 10),
2770 top: parseInt(self.element.css('top'), 10),
2771 left: parseInt(self.element.css('left'), 10)
2772 };
2773
2774 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2775
2776 // propagating resize, and updating values for each animation step
2777 self._updateCache(data);
2778 self._propagate("resize", event);
2779
2780 }
2781 }
2782 );
2783 }
2784
2785 });
2786
2787 $.ui.plugin.add("resizable", "containment", {
2788
2789 start: function(event, ui) {
2790 var self = $(this).data("resizable"), o = self.options, el = self.element;
2791 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2792 if (!ce) return;
2793
2794 self.containerElement = $(ce);
2795
2796 if (/document/.test(oc) || oc == document) {
2797 self.containerOffset = { left: 0, top: 0 };
2798 self.containerPosition = { left: 0, top: 0 };
2799
2800 self.parentData = {
2801 element: $(document), left: 0, top: 0,
2802 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2803 };
2804 }
2805
2806 // i'm a node, so compute top, left, right, bottom
2807 else {
2808 var element = $(ce), p = [];
2809 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2810
2811 self.containerOffset = element.offset();
2812 self.containerPosition = element.position();
2813 self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2814
2815 var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
2816 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2817
2818 self.parentData = {
2819 element: ce, left: co.left, top: co.top, width: width, height: height
2820 };
2821 }
2822 },
2823
2824 resize: function(event, ui) {
2825 var self = $(this).data("resizable"), o = self.options,
2826 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2827 pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2828
2829 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2830
2831 if (cp.left < (self._helper ? co.left : 0)) {
2832 self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2833 if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2834 self.position.left = o.helper ? co.left : 0;
2835 }
2836
2837 if (cp.top < (self._helper ? co.top : 0)) {
2838 self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2839 if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2840 self.position.top = self._helper ? co.top : 0;
2841 }
2842
2843 self.offset.left = self.parentData.left+self.position.left;
2844 self.offset.top = self.parentData.top+self.position.top;
2845
2846 var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2847 hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2848
2849 var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2850 isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2851
2852 if(isParent && isOffsetRelative) woset -= self.parentData.left;
2853
2854 if (woset + self.size.width >= self.parentData.width) {
2855 self.size.width = self.parentData.width - woset;
2856 if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2857 }
2858
2859 if (hoset + self.size.height >= self.parentData.height) {
2860 self.size.height = self.parentData.height - hoset;
2861 if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2862 }
2863 },
2864
2865 stop: function(event, ui){
2866 var self = $(this).data("resizable"), o = self.options, cp = self.position,
2867 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2868
2869 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2870
2871 if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2872 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2873
2874 if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2875 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2876
2877 }
2878 });
2879
2880 $.ui.plugin.add("resizable", "ghost", {
2881
2882 start: function(event, ui) {
2883
2884 var self = $(this).data("resizable"), o = self.options, cs = self.size;
2885
2886 self.ghost = self.originalElement.clone();
2887 self.ghost
2888 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2889 .addClass('ui-resizable-ghost')
2890 .addClass(typeof o.ghost == 'string' ? o.ghost : '');
2891
2892 self.ghost.appendTo(self.helper);
2893
2894 },
2895
2896 resize: function(event, ui){
2897 var self = $(this).data("resizable"), o = self.options;
2898 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2899 },
2900
2901 stop: function(event, ui){
2902 var self = $(this).data("resizable"), o = self.options;
2903 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2904 }
2905
2906 });
2907
2908 $.ui.plugin.add("resizable", "grid", {
2909
2910 resize: function(event, ui) {
2911 var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
2912 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2913 var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
2914
2915 if (/^(se|s|e)$/.test(a)) {
2916 self.size.width = os.width + ox;
2917 self.size.height = os.height + oy;
2918 }
2919 else if (/^(ne)$/.test(a)) {
2920 self.size.width = os.width + ox;
2921 self.size.height = os.height + oy;
2922 self.position.top = op.top - oy;
2923 }
2924 else if (/^(sw)$/.test(a)) {
2925 self.size.width = os.width + ox;
2926 self.size.height = os.height + oy;
2927 self.position.left = op.left - ox;
2928 }
2929 else {
2930 self.size.width = os.width + ox;
2931 self.size.height = os.height + oy;
2932 self.position.top = op.top - oy;
2933 self.position.left = op.left - ox;
2934 }
2935 }
2936
2937 });
2938
2939 var num = function(v) {
2940 return parseInt(v, 10) || 0;
2941 };
2942
2943 var isNumber = function(value) {
2944 return !isNaN(parseInt(value, 10));
2945 };
2946
2947 })(jQuery);
2948 /*
2949 * jQuery UI Selectable 1.8.14
2950 *
2951 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2952 * Dual licensed under the MIT or GPL Version 2 licenses.
2953 * http://jquery.org/license
2954 *
2955 * http://docs.jquery.com/UI/Selectables
2956 *
2957 * Depends:
2958 * jquery.ui.core.js
2959 * jquery.ui.mouse.js
2960 * jquery.ui.widget.js
2961 */
2962 (function( $, undefined ) {
2963
2964 $.widget("ui.selectable", $.ui.mouse, {
2965 options: {
2966 appendTo: 'body',
2967 autoRefresh: true,
2968 distance: 0,
2969 filter: '*',
2970 tolerance: 'touch'
2971 },
2972 _create: function() {
2973 var self = this;
2974
2975 this.element.addClass("ui-selectable");
2976
2977 this.dragged = false;
2978
2979 // cache selectee children based on filter
2980 var selectees;
2981 this.refresh = function() {
2982 selectees = $(self.options.filter, self.element[0]);
2983 selectees.each(function() {
2984 var $this = $(this);
2985 var pos = $this.offset();
2986 $.data(this, "selectable-item", {
2987 element: this,
2988 $element: $this,
2989 left: pos.left,
2990 top: pos.top,
2991 right: pos.left + $this.outerWidth(),
2992 bottom: pos.top + $this.outerHeight(),
2993 startselected: false,
2994 selected: $this.hasClass('ui-selected'),
2995 selecting: $this.hasClass('ui-selecting'),
2996 unselecting: $this.hasClass('ui-unselecting')
2997 });
2998 });
2999 };
3000 this.refresh();
3001
3002 this.selectees = selectees.addClass("ui-selectee");
3003
3004 this._mouseInit();
3005
3006 this.helper = $("<div class='ui-selectable-helper'></div>");
3007 },
3008
3009 destroy: function() {
3010 this.selectees
3011 .removeClass("ui-selectee")
3012 .removeData("selectable-item");
3013 this.element
3014 .removeClass("ui-selectable ui-selectable-disabled")
3015 .removeData("selectable")
3016 .unbind(".selectable");
3017 this._mouseDestroy();
3018
3019 return this;
3020 },
3021
3022 _mouseStart: function(event) {
3023 var self = this;
3024
3025 this.opos = [event.pageX, event.pageY];
3026
3027 if (this.options.disabled)
3028 return;
3029
3030 var options = this.options;
3031
3032 this.selectees = $(options.filter, this.element[0]);
3033
3034 this._trigger("start", event);
3035
3036 $(options.appendTo).append(this.helper);
3037 // position helper (lasso)
3038 this.helper.css({
3039 "left": event.clientX,
3040 "top": event.clientY,
3041 "width": 0,
3042 "height": 0
3043 });
3044
3045 if (options.autoRefresh) {
3046 this.refresh();
3047 }
3048
3049 this.selectees.filter('.ui-selected').each(function() {
3050 var selectee = $.data(this, "selectable-item");
3051 selectee.startselected = true;
3052 if (!event.metaKey) {
3053 selectee.$element.removeClass('ui-selected');
3054 selectee.selected = false;
3055 selectee.$element.addClass('ui-unselecting');
3056 selectee.unselecting = true;
3057 // selectable UNSELECTING callback
3058 self._trigger("unselecting", event, {
3059 unselecting: selectee.element
3060 });
3061 }
3062 });
3063
3064 $(event.target).parents().andSelf().each(function() {
3065 var selectee = $.data(this, "selectable-item");
3066 if (selectee) {
3067 var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
3068 selectee.$element
3069 .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3070 .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3071 selectee.unselecting = !doSelect;
3072 selectee.selecting = doSelect;
3073 selectee.selected = doSelect;
3074 // selectable (UN)SELECTING callback
3075 if (doSelect) {
3076 self._trigger("selecting", event, {
3077 selecting: selectee.element
3078 });
3079 } else {
3080 self._trigger("unselecting", event, {
3081 unselecting: selectee.element
3082 });
3083 }
3084 return false;
3085 }
3086 });
3087
3088 },
3089
3090 _mouseDrag: function(event) {
3091 var self = this;
3092 this.dragged = true;
3093
3094 if (this.options.disabled)
3095 return;
3096
3097 var options = this.options;
3098
3099 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3100 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3101 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3102 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3103
3104 this.selectees.each(function() {
3105 var selectee = $.data(this, "selectable-item");
3106 //prevent helper from being selected if appendTo: selectable
3107 if (!selectee || selectee.element == self.element[0])
3108 return;
3109 var hit = false;
3110 if (options.tolerance == 'touch') {
3111 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3112 } else if (options.tolerance == 'fit') {
3113 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3114 }
3115
3116 if (hit) {
3117 // SELECT
3118 if (selectee.selected) {
3119 selectee.$element.removeClass('ui-selected');
3120 selectee.selected = false;
3121 }
3122 if (selectee.unselecting) {
3123 selectee.$element.removeClass('ui-unselecting');
3124 selectee.unselecting = false;
3125 }
3126 if (!selectee.selecting) {
3127 selectee.$element.addClass('ui-selecting');
3128 selectee.selecting = true;
3129 // selectable SELECTING callback
3130 self._trigger("selecting", event, {
3131 selecting: selectee.element
3132 });
3133 }
3134 } else {
3135 // UNSELECT
3136 if (selectee.selecting) {
3137 if (event.metaKey && selectee.startselected) {
3138 selectee.$element.removeClass('ui-selecting');
3139 selectee.selecting = false;
3140 selectee.$element.addClass('ui-selected');
3141 selectee.selected = true;
3142 } else {
3143 selectee.$element.removeClass('ui-selecting');
3144 selectee.selecting = false;
3145 if (selectee.startselected) {
3146 selectee.$element.addClass('ui-unselecting');
3147 selectee.unselecting = true;
3148 }
3149 // selectable UNSELECTING callback
3150 self._trigger("unselecting", event, {
3151 unselecting: selectee.element
3152 });
3153 }
3154 }
3155 if (selectee.selected) {
3156 if (!event.metaKey && !selectee.startselected) {
3157 selectee.$element.removeClass('ui-selected');
3158 selectee.selected = false;
3159
3160 selectee.$element.addClass('ui-unselecting');
3161 selectee.unselecting = true;
3162 // selectable UNSELECTING callback
3163 self._trigger("unselecting", event, {
3164 unselecting: selectee.element
3165 });
3166 }
3167 }
3168 }
3169 });
3170
3171 return false;
3172 },
3173
3174 _mouseStop: function(event) {
3175 var self = this;
3176
3177 this.dragged = false;
3178
3179 var options = this.options;
3180
3181 $('.ui-unselecting', this.element[0]).each(function() {
3182 var selectee = $.data(this, "selectable-item");
3183 selectee.$element.removeClass('ui-unselecting');
3184 selectee.unselecting = false;
3185 selectee.startselected = false;
3186 self._trigger("unselected", event, {
3187 unselected: selectee.element
3188 });
3189 });
3190 $('.ui-selecting', this.element[0]).each(function() {
3191 var selectee = $.data(this, "selectable-item");
3192 selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3193 selectee.selecting = false;
3194 selectee.selected = true;
3195 selectee.startselected = true;
3196 self._trigger("selected", event, {
3197 selected: selectee.element
3198 });
3199 });
3200 this._trigger("stop", event);
3201
3202 this.helper.remove();
3203
3204 return false;
3205 }
3206
3207 });
3208
3209 $.extend($.ui.selectable, {
3210 version: "1.8.14"
3211 });
3212
3213 })(jQuery);
3214 /*
3215 * jQuery UI Sortable 1.8.14
3216 *
3217 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
3218 * Dual licensed under the MIT or GPL Version 2 licenses.
3219 * http://jquery.org/license
3220 *
3221 * http://docs.jquery.com/UI/Sortables
3222 *
3223 * Depends:
3224 * jquery.ui.core.js
3225 * jquery.ui.mouse.js
3226 * jquery.ui.widget.js
3227 */
3228 (function( $, undefined ) {
3229
3230 $.widget("ui.sortable", $.ui.mouse, {
3231 widgetEventPrefix: "sort",
3232 options: {
3233 appendTo: "parent",
3234 axis: false,
3235 connectWith: false,
3236 containment: false,
3237 cursor: 'auto',
3238 cursorAt: false,
3239 dropOnEmpty: true,
3240 forcePlaceholderSize: false,
3241 forceHelperSize: false,
3242 grid: false,
3243 handle: false,
3244 helper: "original",
3245 items: '> *',
3246 opacity: false,
3247 placeholder: false,
3248 revert: false,
3249 scroll: true,
3250 scrollSensitivity: 20,
3251 scrollSpeed: 20,
3252 scope: "default",
3253 tolerance: "intersect",
3254 zIndex: 1000
3255 },
3256 _create: function() {
3257
3258 var o = this.options;
3259 this.containerCache = {};
3260 this.element.addClass("ui-sortable");
3261
3262 //Get the items
3263 this.refresh();
3264
3265 //Let's determine if the items are being displayed horizontally
3266 this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
3267
3268 //Let's determine the parent's offset
3269 this.offset = this.element.offset();
3270
3271 //Initialize mouse events for interaction
3272 this._mouseInit();
3273
3274 },
3275
3276 destroy: function() {
3277 this.element
3278 .removeClass("ui-sortable ui-sortable-disabled")
3279 .removeData("sortable")
3280 .unbind(".sortable");
3281 this._mouseDestroy();
3282
3283 for ( var i = this.items.length - 1; i >= 0; i-- )
3284 this.items[i].item.removeData("sortable-item");
3285
3286 return this;
3287 },
3288
3289 _setOption: function(key, value){
3290 if ( key === "disabled" ) {
3291 this.options[ key ] = value;
3292
3293 this.widget()
3294 [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3295 } else {
3296 // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3297 $.Widget.prototype._setOption.apply(this, arguments);
3298 }
3299 },
3300
3301 _mouseCapture: function(event, overrideHandle) {
3302
3303 if (this.reverting) {
3304 return false;
3305 }
3306
3307 if(this.options.disabled || this.options.type == 'static') return false;
3308
3309 //We have to refresh the items data once first
3310 this._refreshItems(event);
3311
3312 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3313 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
3314 if($.data(this, 'sortable-item') == self) {
3315 currentItem = $(this);
3316 return false;
3317 }
3318 });
3319 if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
3320
3321 if(!currentItem) return false;
3322 if(this.options.handle && !overrideHandle) {
3323 var validHandle = false;
3324
3325 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3326 if(!validHandle) return false;
3327 }
3328
3329 this.currentItem = currentItem;
3330 this._removeCurrentsFromItems();
3331 return true;
3332
3333 },
3334
3335 _mouseStart: function(event, overrideHandle, noActivation) {
3336
3337 var o = this.options, self = this;
3338 this.currentContainer = this;
3339
3340 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3341 this.refreshPositions();
3342
3343 //Create and append the visible helper
3344 this.helper = this._createHelper(event);
3345
3346 //Cache the helper size
3347 this._cacheHelperProportions();
3348
3349 /*
3350 * - Position generation -
3351 * This block generates everything position related - it's the core of draggables.
3352 */
3353
3354 //Cache the margins of the original element
3355 this._cacheMargins();
3356
3357 //Get the next scrolling parent
3358 this.scrollParent = this.helper.scrollParent();
3359
3360 //The element's absolute position on the page minus margins
3361 this.offset = this.currentItem.offset();
3362 this.offset = {
3363 top: this.offset.top - this.margins.top,
3364 left: this.offset.left - this.margins.left
3365 };
3366
3367 // Only after we got the offset, we can change the helper's position to absolute
3368 // TODO: Still need to figure out a way to make relative sorting possible
3369 this.helper.css("position", "absolute");
3370 this.cssPosition = this.helper.css("position");
3371
3372 $.extend(this.offset, {
3373 click: { //Where the click happened, relative to the element
3374 left: event.pageX - this.offset.left,
3375 top: event.pageY - this.offset.top
3376 },
3377 parent: this._getParentOffset(),
3378 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3379 });
3380
3381 //Generate the original position
3382 this.originalPosition = this._generatePosition(event);
3383 this.originalPageX = event.pageX;
3384 this.originalPageY = event.pageY;
3385
3386 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3387 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3388
3389 //Cache the former DOM position
3390 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3391
3392 //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
3393 if(this.helper[0] != this.currentItem[0]) {
3394 this.currentItem.hide();
3395 }
3396
3397 //Create the placeholder
3398 this._createPlaceholder();
3399
3400 //Set a containment if given in the options
3401 if(o.containment)
3402 this._setContainment();
3403
3404 if(o.cursor) { // cursor option
3405 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3406 $('body').css("cursor", o.cursor);
3407 }
3408
3409 if(o.opacity) { // opacity option
3410 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3411 this.helper.css("opacity", o.opacity);
3412 }
3413
3414 if(o.zIndex) { // zIndex option
3415 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3416 this.helper.css("zIndex", o.zIndex);
3417 }
3418
3419 //Prepare scrolling
3420 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3421 this.overflowOffset = this.scrollParent.offset();
3422
3423 //Call callbacks
3424 this._trigger("start", event, this._uiHash());
3425
3426 //Recache the helper size
3427 if(!this._preserveHelperProportions)
3428 this._cacheHelperProportions();
3429
3430
3431 //Post 'activate' events to possible containers
3432 if(!noActivation) {
3433 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3434 }
3435
3436 //Prepare possible droppables
3437 if($.ui.ddmanager)
3438 $.ui.ddmanager.current = this;
3439
3440 if ($.ui.ddmanager && !o.dropBehaviour)
3441 $.ui.ddmanager.prepareOffsets(this, event);
3442
3443 this.dragging = true;
3444
3445 this.helper.addClass("ui-sortable-helper");
3446 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3447 return true;
3448
3449 },
3450
3451 _mouseDrag: function(event) {
3452
3453 //Compute the helpers position
3454 this.position = this._generatePosition(event);
3455 this.positionAbs = this._convertPositionTo("absolute");
3456
3457 if (!this.lastPositionAbs) {
3458 this.lastPositionAbs = this.positionAbs;
3459 }
3460
3461 //Do scrolling
3462 if(this.options.scroll) {
3463 var o = this.options, scrolled = false;
3464 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3465
3466 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3467 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3468 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3469 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3470
3471 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3472 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3473 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3474 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3475
3476 } else {
3477
3478 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3479 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3480 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3481 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3482
3483 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3484 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3485 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3486 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3487
3488 }
3489
3490 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3491 $.ui.ddmanager.prepareOffsets(this, event);
3492 }
3493
3494 //Regenerate the absolute position used for position checks
3495 this.positionAbs = this._convertPositionTo("absolute");
3496
3497 //Set the helper position
3498 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3499 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3500
3501 //Rearrange
3502 for (var i = this.items.length - 1; i >= 0; i--) {
3503
3504 //Cache variables and intersection, continue if no intersection
3505 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3506 if (!intersection) continue;
3507
3508 if(itemElement != this.currentItem[0] //cannot intersect with itself
3509 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3510 && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3511 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3512 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3513 ) {
3514
3515 this.direction = intersection == 1 ? "down" : "up";
3516
3517 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3518 this._rearrange(event, item);
3519 } else {
3520 break;
3521 }
3522
3523 this._trigger("change", event, this._uiHash());
3524 break;
3525 }
3526 }
3527
3528 //Post events to containers
3529 this._contactContainers(event);
3530
3531 //Interconnect with droppables
3532 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3533
3534 //Call callbacks
3535 this._trigger('sort', event, this._uiHash());
3536
3537 this.lastPositionAbs = this.positionAbs;
3538 return false;
3539
3540 },
3541
3542 _mouseStop: function(event, noPropagation) {
3543
3544 if(!event) return;
3545
3546 //If we are using droppables, inform the manager about the drop
3547 if ($.ui.ddmanager && !this.options.dropBehaviour)
3548 $.ui.ddmanager.drop(this, event);
3549
3550 if(this.options.revert) {
3551 var self = this;
3552 var cur = self.placeholder.offset();
3553
3554 self.reverting = true;
3555
3556 $(this.helper).animate({
3557 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3558 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3559 }, parseInt(this.options.revert, 10) || 500, function() {
3560 self._clear(event);
3561 });
3562 } else {
3563 this._clear(event, noPropagation);
3564 }
3565
3566 return false;
3567
3568 },
3569
3570 cancel: function() {
3571
3572 var self = this;
3573
3574 if(this.dragging) {
3575
3576 this._mouseUp({ target: null });
3577
3578 if(this.options.helper == "original")
3579 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3580 else
3581 this.currentItem.show();
3582
3583 //Post deactivating events to containers
3584 for (var i = this.containers.length - 1; i >= 0; i--){
3585 this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3586 if(this.containers[i].containerCache.over) {
3587 this.containers[i]._trigger("out", null, self._uiHash(this));
3588 this.containers[i].containerCache.over = 0;
3589 }
3590 }
3591
3592 }
3593
3594 if (this.placeholder) {
3595 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3596 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3597 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3598
3599 $.extend(this, {
3600 helper: null,
3601 dragging: false,
3602 reverting: false,
3603 _noFinalSort: null
3604 });
3605
3606 if(this.domPosition.prev) {
3607 $(this.domPosition.prev).after(this.currentItem);
3608 } else {
3609 $(this.domPosition.parent).prepend(this.currentItem);
3610 }
3611 }
3612
3613 return this;
3614
3615 },
3616
3617 serialize: function(o) {
3618
3619 var items = this._getItemsAsjQuery(o && o.connected);
3620 var str = []; o = o || {};
3621
3622 $(items).each(function() {
3623 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3624 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3625 });
3626
3627 if(!str.length && o.key) {
3628 str.push(o.key + '=');
3629 }
3630
3631 return str.join('&');
3632
3633 },
3634
3635 toArray: function(o) {
3636
3637 var items = this._getItemsAsjQuery(o && o.connected);
3638 var ret = []; o = o || {};
3639
3640 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3641 return ret;
3642
3643 },
3644
3645 /* Be careful with the following core functions */
3646 _intersectsWith: function(item) {
3647
3648 var x1 = this.positionAbs.left,
3649 x2 = x1 + this.helperProportions.width,
3650 y1 = this.positionAbs.top,
3651 y2 = y1 + this.helperProportions.height;
3652
3653 var l = item.left,
3654 r = l + item.width,
3655 t = item.top,
3656 b = t + item.height;
3657
3658 var dyClick = this.offset.click.top,
3659 dxClick = this.offset.click.left;
3660
3661 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3662
3663 if( this.options.tolerance == "pointer"
3664 || this.options.forcePointerForContainers
3665 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3666 ) {
3667 return isOverElement;
3668 } else {
3669
3670 return (l < x1 + (this.helperProportions.width / 2) // Right Half
3671 && x2 - (this.helperProportions.width / 2) < r // Left Half
3672 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3673 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
3674
3675 }
3676 },
3677
3678 _intersectsWithPointer: function(item) {
3679
3680 var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3681 isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3682 isOverElement = isOverElementHeight && isOverElementWidth,
3683 verticalDirection = this._getDragVerticalDirection(),
3684 horizontalDirection = this._getDragHorizontalDirection();
3685
3686 if (!isOverElement)
3687 return false;
3688
3689 return this.floating ?
3690 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3691 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3692
3693 },
3694
3695 _intersectsWithSides: function(item) {
3696
3697 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3698 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3699 verticalDirection = this._getDragVerticalDirection(),
3700 horizontalDirection = this._getDragHorizontalDirection();
3701
3702 if (this.floating && horizontalDirection) {
3703 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3704 } else {
3705 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3706 }
3707
3708 },
3709
3710 _getDragVerticalDirection: function() {
3711 var delta = this.positionAbs.top - this.lastPositionAbs.top;
3712 return delta != 0 && (delta > 0 ? "down" : "up");
3713 },
3714
3715 _getDragHorizontalDirection: function() {
3716 var delta = this.positionAbs.left - this.lastPositionAbs.left;
3717 return delta != 0 && (delta > 0 ? "right" : "left");
3718 },
3719
3720 refresh: function(event) {
3721 this._refreshItems(event);
3722 this.refreshPositions();
3723 return this;
3724 },
3725
3726 _connectWith: function() {
3727 var options = this.options;
3728 return options.connectWith.constructor == String
3729 ? [options.connectWith]
3730 : options.connectWith;
3731 },
3732
3733 _getItemsAsjQuery: function(connected) {
3734
3735 var self = this;
3736 var items = [];
3737 var queries = [];
3738 var connectWith = this._connectWith();
3739
3740 if(connectWith && connected) {
3741 for (var i = connectWith.length - 1; i >= 0; i--){
3742 var cur = $(connectWith[i]);
3743 for (var j = cur.length - 1; j >= 0; j--){
3744 var inst = $.data(cur[j], 'sortable');
3745 if(inst && inst != this && !inst.options.disabled) {
3746 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
3747 }
3748 };
3749 };
3750 }
3751
3752 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
3753
3754 for (var i = queries.length - 1; i >= 0; i--){
3755 queries[i][0].each(function() {
3756 items.push(this);
3757 });
3758 };
3759
3760 return $(items);
3761
3762 },
3763
3764 _removeCurrentsFromItems: function() {
3765
3766 var list = this.currentItem.find(":data(sortable-item)");
3767
3768 for (var i=0; i < this.items.length; i++) {
3769
3770 for (var j=0; j < list.length; j++) {
3771 if(list[j] == this.items[i].item[0])
3772 this.items.splice(i,1);
3773 };
3774
3775 };
3776
3777 },
3778
3779 _refreshItems: function(event) {
3780
3781 this.items = [];
3782 this.containers = [this];
3783 var items = this.items;
3784 var self = this;
3785 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3786 var connectWith = this._connectWith();
3787
3788 if(connectWith) {
3789 for (var i = connectWith.length - 1; i >= 0; i--){
3790 var cur = $(connectWith[i]);
3791 for (var j = cur.length - 1; j >= 0; j--){
3792 var inst = $.data(cur[j], 'sortable');
3793 if(inst && inst != this && !inst.options.disabled) {
3794 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3795 this.containers.push(inst);
3796 }
3797 };
3798 };
3799 }
3800
3801 for (var i = queries.length - 1; i >= 0; i--) {
3802 var targetData = queries[i][1];
3803 var _queries = queries[i][0];
3804
3805 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3806 var item = $(_queries[j]);
3807
3808 item.data('sortable-item', targetData); // Data for target checking (mouse manager)
3809
3810 items.push({
3811 item: item,
3812 instance: targetData,
3813 width: 0, height: 0,
3814 left: 0, top: 0
3815 });
3816 };
3817 };
3818
3819 },
3820
3821 refreshPositions: function(fast) {
3822
3823 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3824 if(this.offsetParent && this.helper) {
3825 this.offset.parent = this._getParentOffset();
3826 }
3827
3828 for (var i = this.items.length - 1; i >= 0; i--){
3829 var item = this.items[i];
3830
3831 //We ignore calculating positions of all connected containers when we're not over them
3832 if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3833 continue;
3834
3835 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3836
3837 if (!fast) {
3838 item.width = t.outerWidth();
3839 item.height = t.outerHeight();
3840 }
3841
3842 var p = t.offset();
3843 item.left = p.left;
3844 item.top = p.top;
3845 };
3846
3847 if(this.options.custom && this.options.custom.refreshContainers) {
3848 this.options.custom.refreshContainers.call(this);
3849 } else {
3850 for (var i = this.containers.length - 1; i >= 0; i--){
3851 var p = this.containers[i].element.offset();
3852 this.containers[i].containerCache.left = p.left;
3853 this.containers[i].containerCache.top = p.top;
3854 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3855 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3856 };
3857 }
3858
3859 return this;
3860 },
3861
3862 _createPlaceholder: function(that) {
3863
3864 var self = that || this, o = self.options;
3865
3866 if(!o.placeholder || o.placeholder.constructor == String) {
3867 var className = o.placeholder;
3868 o.placeholder = {
3869 element: function() {
3870
3871 var el = $(document.createElement(self.currentItem[0].nodeName))
3872 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3873 .removeClass("ui-sortable-helper")[0];
3874
3875 if(!className)
3876 el.style.visibility = "hidden";
3877
3878 return el;
3879 },
3880 update: function(container, p) {
3881
3882 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3883 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3884 if(className && !o.forcePlaceholderSize) return;
3885
3886 //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
3887 if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3888 if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3889 }
3890 };
3891 }
3892
3893 //Create the placeholder
3894 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3895
3896 //Append it after the actual current item
3897 self.currentItem.after(self.placeholder);
3898
3899 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3900 o.placeholder.update(self, self.placeholder);
3901
3902 },
3903
3904 _contactContainers: function(event) {
3905
3906 // get innermost container that intersects with item
3907 var innermostContainer = null, innermostIndex = null;
3908
3909
3910 for (var i = this.containers.length - 1; i >= 0; i--){
3911
3912 // never consider a container that's located within the item itself
3913 if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3914 continue;
3915
3916 if(this._intersectsWith(this.containers[i].containerCache)) {
3917
3918 // if we've already found a container and it's more "inner" than this, then continue
3919 if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3920 continue;
3921
3922 innermostContainer = this.containers[i];
3923 innermostIndex = i;
3924
3925 } else {
3926 // container doesn't intersect. trigger "out" event if necessary
3927 if(this.containers[i].containerCache.over) {
3928 this.containers[i]._trigger("out", event, this._uiHash(this));
3929 this.containers[i].containerCache.over = 0;
3930 }
3931 }
3932
3933 }
3934
3935 // if no intersecting containers found, return
3936 if(!innermostContainer) return;
3937
3938 // move the item into the container if it's not there already
3939 if(this.containers.length === 1) {
3940 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3941 this.containers[innermostIndex].containerCache.over = 1;
3942 } else if(this.currentContainer != this.containers[innermostIndex]) {
3943
3944 //When entering a new container, we will find the item with the least distance and append our item near it
3945 var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
3946 for (var j = this.items.length - 1; j >= 0; j--) {
3947 if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
3948 var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
3949 if(Math.abs(cur - base) < dist) {
3950 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3951 }
3952 }
3953
3954 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
3955 return;
3956
3957 this.currentContainer = this.containers[innermostIndex];
3958 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
3959 this._trigger("change", event, this._uiHash());
3960 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
3961
3962 //Update the placeholder
3963 this.options.placeholder.update(this.currentContainer, this.placeholder);
3964
3965 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3966 this.containers[innermostIndex].containerCache.over = 1;
3967 }
3968
3969
3970 },
3971
3972 _createHelper: function(event) {
3973
3974 var o = this.options;
3975 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3976
3977 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3978 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3979
3980 if(helper[0] == this.currentItem[0])
3981 this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
3982
3983 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3984 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3985
3986 return helper;
3987
3988 },
3989
3990 _adjustOffsetFromHelper: function(obj) {
3991 if (typeof obj == 'string') {
3992 obj = obj.split(' ');
3993 }
3994 if ($.isArray(obj)) {
3995 obj = {left: +obj[0], top: +obj[1] || 0};
3996 }
3997 if ('left' in obj) {
3998 this.offset.click.left = obj.left + this.margins.left;
3999 }
4000 if ('right' in obj) {
4001 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4002 }
4003 if ('top' in obj) {
4004 this.offset.click.top = obj.top + this.margins.top;
4005 }
4006 if ('bottom' in obj) {
4007 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4008 }
4009 },
4010
4011 _getParentOffset: function() {
4012
4013
4014 //Get the offsetParent and cache its position
4015 this.offsetParent = this.helper.offsetParent();
4016 var po = this.offsetParent.offset();
4017
4018 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4019 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4020 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4021 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4022 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
4023 po.left += this.scrollParent.scrollLeft();
4024 po.top += this.scrollParent.scrollTop();
4025 }
4026
4027 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4028 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
4029 po = { top: 0, left: 0 };
4030
4031 return {
4032 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4033 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4034 };
4035
4036 },
4037
4038 _getRelativeOffset: function() {
4039
4040 if(this.cssPosition == "relative") {
4041 var p = this.currentItem.position();
4042 return {
4043 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4044 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4045 };
4046 } else {
4047 return { top: 0, left: 0 };
4048 }
4049
4050 },
4051
4052 _cacheMargins: function() {
4053 this.margins = {
4054 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4055 top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4056 };
4057 },
4058
4059 _cacheHelperProportions: function() {
4060 this.helperProportions = {
4061 width: this.helper.outerWidth(),
4062 height: this.helper.outerHeight()
4063 };
4064 },
4065
4066 _setContainment: function() {
4067
4068 var o = this.options;
4069 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4070 if(o.containment == 'document' || o.containment == 'window') this.containment = [
4071 0 - this.offset.relative.left - this.offset.parent.left,
4072 0 - this.offset.relative.top - this.offset.parent.top,
4073 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4074 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4075 ];
4076
4077 if(!(/^(document|window|parent)$/).test(o.containment)) {
4078 var ce = $(o.containment)[0];
4079 var co = $(o.containment).offset();
4080 var over = ($(ce).css("overflow") != 'hidden');
4081
4082 this.containment = [
4083 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4084 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4085 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
4086 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4087 ];
4088 }
4089
4090 },
4091
4092 _convertPositionTo: function(d, pos) {
4093
4094 if(!pos) pos = this.position;
4095 var mod = d == "absolute" ? 1 : -1;
4096 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4097
4098 return {
4099 top: (
4100 pos.top // The absolute mouse position
4101 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
4102 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
4103 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4104 ),
4105 left: (
4106 pos.left // The absolute mouse position
4107 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
4108 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
4109 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4110 )
4111 };
4112
4113 },
4114
4115 _generatePosition: function(event) {
4116
4117 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4118
4119 // This is another very weird special case that only happens for relative elements:
4120 // 1. If the css position is relative
4121 // 2. and the scroll parent is the document or similar to the offset parent
4122 // we have to refresh the relative offset during the scroll so there are no jumps
4123 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4124 this.offset.relative = this._getRelativeOffset();
4125 }
4126
4127 var pageX = event.pageX;
4128 var pageY = event.pageY;
4129
4130 /*
4131 * - Position constraining -
4132 * Constrain the position to a mix of grid, containment.
4133 */
4134
4135 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4136
4137 if(this.containment) {
4138 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4139 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4140 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4141 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4142 }
4143
4144 if(o.grid) {
4145 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4146 pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
4147
4148 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4149 pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
4150 }
4151
4152 }
4153
4154 return {
4155 top: (
4156 pageY // The absolute mouse position
4157 - this.offset.click.top // Click offset (relative to the element)
4158 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
4159 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
4160 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4161 ),
4162 left: (
4163 pageX // The absolute mouse position
4164 - this.offset.click.left // Click offset (relative to the element)
4165 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
4166 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
4167 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4168 )
4169 };
4170
4171 },
4172
4173 _rearrange: function(event, i, a, hardRefresh) {
4174
4175 a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
4176
4177 //Various things done here to improve the performance:
4178 // 1. we create a setTimeout, that calls refreshPositions
4179 // 2. on the instance, we have a counter variable, that get's higher after every append
4180 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4181 // 4. this lets only the last addition to the timeout stack through
4182 this.counter = this.counter ? ++this.counter : 1;
4183 var self = this, counter = this.counter;
4184
4185 window.setTimeout(function() {
4186 if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4187 },0);
4188
4189 },
4190
4191 _clear: function(event, noPropagation) {
4192
4193 this.reverting = false;
4194 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4195 // everything else normalized again
4196 var delayedTriggers = [], self = this;
4197
4198 // We first have to update the dom position of the actual currentItem
4199 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4200 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4201 this._noFinalSort = null;
4202
4203 if(this.helper[0] == this.currentItem[0]) {
4204 for(var i in this._storedCSS) {
4205 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4206 }
4207 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4208 } else {
4209 this.currentItem.show();
4210 }
4211
4212 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4213 if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4214 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
4215 if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4216 for (var i = this.containers.length - 1; i >= 0; i--){
4217 if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
4218 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4219 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4220 }
4221 };
4222 };
4223
4224 //Post events to containers
4225 for (var i = this.containers.length - 1; i >= 0; i--){
4226 if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4227 if(this.containers[i].containerCache.over) {
4228 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4229 this.containers[i].containerCache.over = 0;
4230 }
4231 }
4232
4233 //Do what was originally in plugins
4234 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4235 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4236 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4237
4238 this.dragging = false;
4239 if(this.cancelHelperRemoval) {
4240 if(!noPropagation) {
4241 this._trigger("beforeStop", event, this._uiHash());
4242 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4243 this._trigger("stop", event, this._uiHash());
4244 }
4245 return false;
4246 }
4247
4248 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4249
4250 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4251 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4252
4253 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4254
4255 if(!noPropagation) {
4256 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4257 this._trigger("stop", event, this._uiHash());
4258 }
4259
4260 this.fromOutside = false;
4261 return true;
4262
4263 },
4264
4265 _trigger: function() {
4266 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4267 this.cancel();
4268 }
4269 },
4270
4271 _uiHash: function(inst) {
4272 var self = inst || this;
4273 return {
4274 helper: self.helper,
4275 placeholder: self.placeholder || $([]),
4276 position: self.position,
4277 originalPosition: self.originalPosition,
4278 offset: self.positionAbs,
4279 item: self.currentItem,
4280 sender: inst ? inst.element : null
4281 };
4282 }
4283
4284 });
4285
4286 $.extend($.ui.sortable, {
4287 version: "1.8.14"
4288 });
4289
4290 })(jQuery);
4291 /*
4292 * jQuery UI Accordion 1.8.14
4293 *
4294 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4295 * Dual licensed under the MIT or GPL Version 2 licenses.
4296 * http://jquery.org/license
4297 *
4298 * http://docs.jquery.com/UI/Accordion
4299 *
4300 * Depends:
4301 * jquery.ui.core.js
4302 * jquery.ui.widget.js
4303 */
4304 (function( $, undefined ) {
4305
4306 $.widget( "ui.accordion", {
4307 options: {
4308 active: 0,
4309 animated: "slide",
4310 autoHeight: true,
4311 clearStyle: false,
4312 collapsible: false,
4313 event: "click",
4314 fillSpace: false,
4315 header: "> li > :first-child,> :not(li):even",
4316 icons: {
4317 header: "ui-icon-triangle-1-e",
4318 headerSelected: "ui-icon-triangle-1-s"
4319 },
4320 navigation: false,
4321 navigationFilter: function() {
4322 return this.href.toLowerCase() === location.href.toLowerCase();
4323 }
4324 },
4325
4326 _create: function() {
4327 var self = this,
4328 options = self.options;
4329
4330 self.running = 0;
4331
4332 self.element
4333 .addClass( "ui-accordion ui-widget ui-helper-reset" )
4334 // in lack of child-selectors in CSS
4335 // we need to mark top-LIs in a UL-accordion for some IE-fix
4336 .children( "li" )
4337 .addClass( "ui-accordion-li-fix" );
4338
4339 self.headers = self.element.find( options.header )
4340 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
4341 .bind( "mouseenter.accordion", function() {
4342 if ( options.disabled ) {
4343 return;
4344 }
4345 $( this ).addClass( "ui-state-hover" );
4346 })
4347 .bind( "mouseleave.accordion", function() {
4348 if ( options.disabled ) {
4349 return;
4350 }
4351 $( this ).removeClass( "ui-state-hover" );
4352 })
4353 .bind( "focus.accordion", function() {
4354 if ( options.disabled ) {
4355 return;
4356 }
4357 $( this ).addClass( "ui-state-focus" );
4358 })
4359 .bind( "blur.accordion", function() {
4360 if ( options.disabled ) {
4361 return;
4362 }
4363 $( this ).removeClass( "ui-state-focus" );
4364 });
4365
4366 self.headers.next()
4367 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
4368
4369 if ( options.navigation ) {
4370 var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
4371 if ( current.length ) {
4372 var header = current.closest( ".ui-accordion-header" );
4373 if ( header.length ) {
4374 // anchor within header
4375 self.active = header;
4376 } else {
4377 // anchor within content
4378 self.active = current.closest( ".ui-accordion-content" ).prev();
4379 }
4380 }
4381 }
4382
4383 self.active = self._findActive( self.active || options.active )
4384 .addClass( "ui-state-default ui-state-active" )
4385 .toggleClass( "ui-corner-all" )
4386 .toggleClass( "ui-corner-top" );
4387 self.active.next().addClass( "ui-accordion-content-active" );
4388
4389 self._createIcons();
4390 self.resize();
4391
4392 // ARIA
4393 self.element.attr( "role", "tablist" );
4394
4395 self.headers
4396 .attr( "role", "tab" )
4397 .bind( "keydown.accordion", function( event ) {
4398 return self._keydown( event );
4399 })
4400 .next()
4401 .attr( "role", "tabpanel" );
4402
4403 self.headers
4404 .not( self.active || "" )
4405 .attr({
4406 "aria-expanded": "false",
4407 "aria-selected": "false",
4408 tabIndex: -1
4409 })
4410 .next()
4411 .hide();
4412
4413 // make sure at least one header is in the tab order
4414 if ( !self.active.length ) {
4415 self.headers.eq( 0 ).attr( "tabIndex", 0 );
4416 } else {
4417 self.active
4418 .attr({
4419 "aria-expanded": "true",
4420 "aria-selected": "true",
4421 tabIndex: 0
4422 });
4423 }
4424
4425 // only need links in tab order for Safari
4426 if ( !$.browser.safari ) {
4427 self.headers.find( "a" ).attr( "tabIndex", -1 );
4428 }
4429
4430 if ( options.event ) {
4431 self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
4432 self._clickHandler.call( self, event, this );
4433 event.preventDefault();
4434 });
4435 }
4436 },
4437
4438 _createIcons: function() {
4439 var options = this.options;
4440 if ( options.icons ) {
4441 $( "<span></span>" )
4442 .addClass( "ui-icon " + options.icons.header )
4443 .prependTo( this.headers );
4444 this.active.children( ".ui-icon" )
4445 .toggleClass(options.icons.header)
4446 .toggleClass(options.icons.headerSelected);
4447 this.element.addClass( "ui-accordion-icons" );
4448 }
4449 },
4450
4451 _destroyIcons: function() {
4452 this.headers.children( ".ui-icon" ).remove();
4453 this.element.removeClass( "ui-accordion-icons" );
4454 },
4455
4456 destroy: function() {
4457 var options = this.options;
4458
4459 this.element
4460 .removeClass( "ui-accordion ui-widget ui-helper-reset" )
4461 .removeAttr( "role" );
4462
4463 this.headers
4464 .unbind( ".accordion" )
4465 .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
4466 .removeAttr( "role" )
4467 .removeAttr( "aria-expanded" )
4468 .removeAttr( "aria-selected" )
4469 .removeAttr( "tabIndex" );
4470
4471 this.headers.find( "a" ).removeAttr( "tabIndex" );
4472 this._destroyIcons();
4473 var contents = this.headers.next()
4474 .css( "display", "" )
4475 .removeAttr( "role" )
4476 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
4477 if ( options.autoHeight || options.fillHeight ) {
4478 contents.css( "height", "" );
4479 }
4480
4481 return $.Widget.prototype.destroy.call( this );
4482 },
4483
4484 _setOption: function( key, value ) {
4485 $.Widget.prototype._setOption.apply( this, arguments );
4486
4487 if ( key == "active" ) {
4488 this.activate( value );
4489 }
4490 if ( key == "icons" ) {
4491 this._destroyIcons();
4492 if ( value ) {
4493 this._createIcons();
4494 }
4495 }
4496 // #5332 - opacity doesn't cascade to positioned elements in IE
4497 // so we need to add the disabled class to the headers and panels
4498 if ( key == "disabled" ) {
4499 this.headers.add(this.headers.next())
4500 [ value ? "addClass" : "removeClass" ](
4501 "ui-accordion-disabled ui-state-disabled" );
4502 }
4503 },
4504
4505 _keydown: function( event ) {
4506 if ( this.options.disabled || event.altKey || event.ctrlKey ) {
4507 return;
4508 }
4509
4510 var keyCode = $.ui.keyCode,
4511 length = this.headers.length,
4512 currentIndex = this.headers.index( event.target ),
4513 toFocus = false;
4514
4515 switch ( event.keyCode ) {
4516 case keyCode.RIGHT:
4517 case keyCode.DOWN:
4518 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4519 break;
4520 case keyCode.LEFT:
4521 case keyCode.UP:
4522 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4523 break;
4524 case keyCode.SPACE:
4525 case keyCode.ENTER:
4526 this._clickHandler( { target: event.target }, event.target );
4527 event.preventDefault();
4528 }
4529
4530 if ( toFocus ) {
4531 $( event.target ).attr( "tabIndex", -1 );
4532 $( toFocus ).attr( "tabIndex", 0 );
4533 toFocus.focus();
4534 return false;
4535 }
4536
4537 return true;
4538 },
4539
4540 resize: function() {
4541 var options = this.options,
4542 maxHeight;
4543
4544 if ( options.fillSpace ) {
4545 if ( $.browser.msie ) {
4546 var defOverflow = this.element.parent().css( "overflow" );
4547 this.element.parent().css( "overflow", "hidden");
4548 }
4549 maxHeight = this.element.parent().height();
4550 if ($.browser.msie) {
4551 this.element.parent().css( "overflow", defOverflow );
4552 }
4553
4554 this.headers.each(function() {
4555 maxHeight -= $( this ).outerHeight( true );
4556 });
4557
4558 this.headers.next()
4559 .each(function() {
4560 $( this ).height( Math.max( 0, maxHeight -
4561 $( this ).innerHeight() + $( this ).height() ) );
4562 })
4563 .css( "overflow", "auto" );
4564 } else if ( options.autoHeight ) {
4565 maxHeight = 0;
4566 this.headers.next()
4567 .each(function() {
4568 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
4569 })
4570 .height( maxHeight );
4571 }
4572
4573 return this;
4574 },
4575
4576 activate: function( index ) {
4577 // TODO this gets called on init, changing the option without an explicit call for that
4578 this.options.active = index;
4579 // call clickHandler with custom event
4580 var active = this._findActive( index )[ 0 ];
4581 this._clickHandler( { target: active }, active );
4582
4583 return this;
4584 },
4585
4586 _findActive: function( selector ) {
4587 return selector
4588 ? typeof selector === "number"
4589 ? this.headers.filter( ":eq(" + selector + ")" )
4590 : this.headers.not( this.headers.not( selector ) )
4591 : selector === false
4592 ? $( [] )
4593 : this.headers.filter( ":eq(0)" );
4594 },
4595
4596 // TODO isn't event.target enough? why the separate target argument?
4597 _clickHandler: function( event, target ) {
4598 var options = this.options;
4599 if ( options.disabled ) {
4600 return;
4601 }
4602
4603 // called only when using activate(false) to close all parts programmatically
4604 if ( !event.target ) {
4605 if ( !options.collapsible ) {
4606 return;
4607 }
4608 this.active
4609 .removeClass( "ui-state-active ui-corner-top" )
4610 .addClass( "ui-state-default ui-corner-all" )
4611 .children( ".ui-icon" )
4612 .removeClass( options.icons.headerSelected )
4613 .addClass( options.icons.header );
4614 this.active.next().addClass( "ui-accordion-content-active" );
4615 var toHide = this.active.next(),
4616 data = {
4617 options: options,
4618 newHeader: $( [] ),
4619 oldHeader: options.active,
4620 newContent: $( [] ),
4621 oldContent: toHide
4622 },
4623 toShow = ( this.active = $( [] ) );
4624 this._toggle( toShow, toHide, data );
4625 return;
4626 }
4627
4628 // get the click target
4629 var clicked = $( event.currentTarget || target ),
4630 clickedIsActive = clicked[0] === this.active[0];
4631
4632 // TODO the option is changed, is that correct?
4633 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
4634 options.active = options.collapsible && clickedIsActive ?
4635 false :
4636 this.headers.index( clicked );
4637
4638 // if animations are still active, or the active header is the target, ignore click
4639 if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
4640 return;
4641 }
4642
4643 // find elements to show and hide
4644 var active = this.active,
4645 toShow = clicked.next(),
4646 toHide = this.active.next(),
4647 data = {
4648 options: options,
4649 newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
4650 oldHeader: this.active,
4651 newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
4652 oldContent: toHide
4653 },
4654 down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
4655
4656 // when the call to ._toggle() comes after the class changes
4657 // it causes a very odd bug in IE 8 (see #6720)
4658 this.active = clickedIsActive ? $([]) : clicked;
4659 this._toggle( toShow, toHide, data, clickedIsActive, down );
4660
4661 // switch classes
4662 active
4663 .removeClass( "ui-state-active ui-corner-top" )
4664 .addClass( "ui-state-default ui-corner-all" )
4665 .children( ".ui-icon" )
4666 .removeClass( options.icons.headerSelected )
4667 .addClass( options.icons.header );
4668 if ( !clickedIsActive ) {
4669 clicked
4670 .removeClass( "ui-state-default ui-corner-all" )
4671 .addClass( "ui-state-active ui-corner-top" )
4672 .children( ".ui-icon" )
4673 .removeClass( options.icons.header )
4674 .addClass( options.icons.headerSelected );
4675 clicked
4676 .next()
4677 .addClass( "ui-accordion-content-active" );
4678 }
4679
4680 return;
4681 },
4682
4683 _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
4684 var self = this,
4685 options = self.options;
4686
4687 self.toShow = toShow;
4688 self.toHide = toHide;
4689 self.data = data;
4690
4691 var complete = function() {
4692 if ( !self ) {
4693 return;
4694 }
4695 return self._completed.apply( self, arguments );
4696 };
4697
4698 // trigger changestart event
4699 self._trigger( "changestart", null, self.data );
4700
4701 // count elements to animate
4702 self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
4703
4704 if ( options.animated ) {
4705 var animOptions = {};
4706
4707 if ( options.collapsible && clickedIsActive ) {
4708 animOptions = {
4709 toShow: $( [] ),
4710 toHide: toHide,
4711 complete: complete,
4712 down: down,
4713 autoHeight: options.autoHeight || options.fillSpace
4714 };
4715 } else {
4716 animOptions = {
4717 toShow: toShow,
4718 toHide: toHide,
4719 complete: complete,
4720 down: down,
4721 autoHeight: options.autoHeight || options.fillSpace
4722 };
4723 }
4724
4725 if ( !options.proxied ) {
4726 options.proxied = options.animated;
4727 }
4728
4729 if ( !options.proxiedDuration ) {
4730 options.proxiedDuration = options.duration;
4731 }
4732
4733 options.animated = $.isFunction( options.proxied ) ?
4734 options.proxied( animOptions ) :
4735 options.proxied;
4736
4737 options.duration = $.isFunction( options.proxiedDuration ) ?
4738 options.proxiedDuration( animOptions ) :
4739 options.proxiedDuration;
4740
4741 var animations = $.ui.accordion.animations,
4742 duration = options.duration,
4743 easing = options.animated;
4744
4745 if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
4746 easing = "slide";
4747 }
4748 if ( !animations[ easing ] ) {
4749 animations[ easing ] = function( options ) {
4750 this.slide( options, {
4751 easing: easing,
4752 duration: duration || 700
4753 });
4754 };
4755 }
4756
4757 animations[ easing ]( animOptions );
4758 } else {
4759 if ( options.collapsible && clickedIsActive ) {
4760 toShow.toggle();
4761 } else {
4762 toHide.hide();
4763 toShow.show();
4764 }
4765
4766 complete( true );
4767 }
4768
4769 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
4770 toHide.prev()
4771 .attr({
4772 "aria-expanded": "false",
4773 "aria-selected": "false",
4774 tabIndex: -1
4775 })
4776 .blur();
4777 toShow.prev()
4778 .attr({
4779 "aria-expanded": "true",
4780 "aria-selected": "true",
4781 tabIndex: 0
4782 })
4783 .focus();
4784 },
4785
4786 _completed: function( cancel ) {
4787 this.running = cancel ? 0 : --this.running;
4788 if ( this.running ) {
4789 return;
4790 }
4791
4792 if ( this.options.clearStyle ) {
4793 this.toShow.add( this.toHide ).css({
4794 height: "",
4795 overflow: ""
4796 });
4797 }
4798
4799 // other classes are removed before the animation; this one needs to stay until completed
4800 this.toHide.removeClass( "ui-accordion-content-active" );
4801 // Work around for rendering bug in IE (#5421)
4802 if ( this.toHide.length ) {
4803 this.toHide.parent()[0].className = this.toHide.parent()[0].className;
4804 }
4805
4806 this._trigger( "change", null, this.data );
4807 }
4808 });
4809
4810 $.extend( $.ui.accordion, {
4811 version: "1.8.14",
4812 animations: {
4813 slide: function( options, additions ) {
4814 options = $.extend({
4815 easing: "swing",
4816 duration: 300
4817 }, options, additions );
4818 if ( !options.toHide.size() ) {
4819 options.toShow.animate({
4820 height: "show",
4821 paddingTop: "show",
4822 paddingBottom: "show"
4823 }, options );
4824 return;
4825 }
4826 if ( !options.toShow.size() ) {
4827 options.toHide.animate({
4828 height: "hide",
4829 paddingTop: "hide",
4830 paddingBottom: "hide"
4831 }, options );
4832 return;
4833 }
4834 var overflow = options.toShow.css( "overflow" ),
4835 percentDone = 0,
4836 showProps = {},
4837 hideProps = {},
4838 fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
4839 originalWidth;
4840 // fix width before calculating height of hidden element
4841 var s = options.toShow;
4842 originalWidth = s[0].style.width;
4843 s.width( parseInt( s.parent().width(), 10 )
4844 - parseInt( s.css( "paddingLeft" ), 10 )
4845 - parseInt( s.css( "paddingRight" ), 10 )
4846 - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
4847 - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
4848
4849 $.each( fxAttrs, function( i, prop ) {
4850 hideProps[ prop ] = "hide";
4851
4852 var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
4853 showProps[ prop ] = {
4854 value: parts[ 1 ],
4855 unit: parts[ 2 ] || "px"
4856 };
4857 });
4858 options.toShow.css({ height: 0, overflow: "hidden" }).show();
4859 options.toHide
4860 .filter( ":hidden" )
4861 .each( options.complete )
4862 .end()
4863 .filter( ":visible" )
4864 .animate( hideProps, {
4865 step: function( now, settings ) {
4866 // only calculate the percent when animating height
4867 // IE gets very inconsistent results when animating elements
4868 // with small values, which is common for padding
4869 if ( settings.prop == "height" ) {
4870 percentDone = ( settings.end - settings.start === 0 ) ? 0 :
4871 ( settings.now - settings.start ) / ( settings.end - settings.start );
4872 }
4873
4874 options.toShow[ 0 ].style[ settings.prop ] =
4875 ( percentDone * showProps[ settings.prop ].value )
4876 + showProps[ settings.prop ].unit;
4877 },
4878 duration: options.duration,
4879 easing: options.easing,
4880 complete: function() {
4881 if ( !options.autoHeight ) {
4882 options.toShow.css( "height", "" );
4883 }
4884 options.toShow.css({
4885 width: originalWidth,
4886 overflow: overflow
4887 });
4888 options.complete();
4889 }
4890 });
4891 },
4892 bounceslide: function( options ) {
4893 this.slide( options, {
4894 easing: options.down ? "easeOutBounce" : "swing",
4895 duration: options.down ? 1000 : 200
4896 });
4897 }
4898 }
4899 });
4900
4901 })( jQuery );
4902 /*
4903 * jQuery UI Autocomplete 1.8.14
4904 *
4905 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4906 * Dual licensed under the MIT or GPL Version 2 licenses.
4907 * http://jquery.org/license
4908 *
4909 * http://docs.jquery.com/UI/Autocomplete
4910 *
4911 * Depends:
4912 * jquery.ui.core.js
4913 * jquery.ui.widget.js
4914 * jquery.ui.position.js
4915 */
4916 (function( $, undefined ) {
4917
4918 // used to prevent race conditions with remote data sources
4919 var requestIndex = 0;
4920
4921 $.widget( "ui.autocomplete", {
4922 options: {
4923 appendTo: "body",
4924 autoFocus: false,
4925 delay: 300,
4926 minLength: 1,
4927 position: {
4928 my: "left top",
4929 at: "left bottom",
4930 collision: "none"
4931 },
4932 source: null
4933 },
4934
4935 pending: 0,
4936
4937 _create: function() {
4938 var self = this,
4939 doc = this.element[ 0 ].ownerDocument,
4940 suppressKeyPress;
4941
4942 this.element
4943 .addClass( "ui-autocomplete-input" )
4944 .attr( "autocomplete", "off" )
4945 // TODO verify these actually work as intended
4946 .attr({
4947 role: "textbox",
4948 "aria-autocomplete": "list",
4949 "aria-haspopup": "true"
4950 })
4951 .bind( "keydown.autocomplete", function( event ) {
4952 if ( self.options.disabled || self.element.attr( "readonly" ) ) {
4953 return;
4954 }
4955
4956 suppressKeyPress = false;
4957 var keyCode = $.ui.keyCode;
4958 switch( event.keyCode ) {
4959 case keyCode.PAGE_UP:
4960 self._move( "previousPage", event );
4961 break;
4962 case keyCode.PAGE_DOWN:
4963 self._move( "nextPage", event );
4964 break;
4965 case keyCode.UP:
4966 self._move( "previous", event );
4967 // prevent moving cursor to beginning of text field in some browsers
4968 event.preventDefault();
4969 break;
4970 case keyCode.DOWN:
4971 self._move( "next", event );
4972 // prevent moving cursor to end of text field in some browsers
4973 event.preventDefault();
4974 break;
4975 case keyCode.ENTER:
4976 case keyCode.NUMPAD_ENTER:
4977 // when menu is open and has focus
4978 if ( self.menu.active ) {
4979 // #6055 - Opera still allows the keypress to occur
4980 // which causes forms to submit
4981 suppressKeyPress = true;
4982 event.preventDefault();
4983 }
4984 //passthrough - ENTER and TAB both select the current element
4985 case keyCode.TAB:
4986 if ( !self.menu.active ) {
4987 return;
4988 }
4989 self.menu.select( event );
4990 break;
4991 case keyCode.ESCAPE:
4992 self.element.val( self.term );
4993 self.close( event );
4994 break;
4995 default:
4996 // keypress is triggered before the input value is changed
4997 clearTimeout( self.searching );
4998 self.searching = setTimeout(function() {
4999 // only search if the value has changed
5000 if ( self.term != self.element.val() ) {
5001 self.selectedItem = null;
5002 self.search( null, event );
5003 }
5004 }, self.options.delay );
5005 break;
5006 }
5007 })
5008 .bind( "keypress.autocomplete", function( event ) {
5009 if ( suppressKeyPress ) {
5010 suppressKeyPress = false;
5011 event.preventDefault();
5012 }
5013 })
5014 .bind( "focus.autocomplete", function() {
5015 if ( self.options.disabled ) {
5016 return;
5017 }
5018
5019 self.selectedItem = null;
5020 self.previous = self.element.val();
5021 })
5022 .bind( "blur.autocomplete", function( event ) {
5023 if ( self.options.disabled ) {
5024 return;
5025 }
5026
5027 clearTimeout( self.searching );
5028 // clicks on the menu (or a button to trigger a search) will cause a blur event
5029 self.closing = setTimeout(function() {
5030 self.close( event );
5031 self._change( event );
5032 }, 150 );
5033 });
5034 this._initSource();
5035 this.response = function() {
5036 return self._response.apply( self, arguments );
5037 };
5038 this.menu = $( "<ul></ul>" )
5039 .addClass( "ui-autocomplete" )
5040 .appendTo( $( this.options.appendTo || "body", doc )[0] )
5041 // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
5042 .mousedown(function( event ) {
5043 // clicking on the scrollbar causes focus to shift to the body
5044 // but we can't detect a mouseup or a click immediately afterward
5045 // so we have to track the next mousedown and close the menu if
5046 // the user clicks somewhere outside of the autocomplete
5047 var menuElement = self.menu.element[ 0 ];
5048 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5049 setTimeout(function() {
5050 $( document ).one( 'mousedown', function( event ) {
5051 if ( event.target !== self.element[ 0 ] &&
5052 event.target !== menuElement &&
5053 !$.ui.contains( menuElement, event.target ) ) {
5054 self.close();
5055 }
5056 });
5057 }, 1 );
5058 }
5059
5060 // use another timeout to make sure the blur-event-handler on the input was already triggered
5061 setTimeout(function() {
5062 clearTimeout( self.closing );
5063 }, 13);
5064 })
5065 .menu({
5066 focus: function( event, ui ) {
5067 var item = ui.item.data( "item.autocomplete" );
5068 if ( false !== self._trigger( "focus", event, { item: item } ) ) {
5069 // use value to match what will end up in the input, if it was a key event
5070 if ( /^key/.test(event.originalEvent.type) ) {
5071 self.element.val( item.value );
5072 }
5073 }
5074 },
5075 selected: function( event, ui ) {
5076 var item = ui.item.data( "item.autocomplete" ),
5077 previous = self.previous;
5078
5079 // only trigger when focus was lost (click on menu)
5080 if ( self.element[0] !== doc.activeElement ) {
5081 self.element.focus();
5082 self.previous = previous;
5083 // #6109 - IE triggers two focus events and the second
5084 // is asynchronous, so we need to reset the previous
5085 // term synchronously and asynchronously :-(
5086 setTimeout(function() {
5087 self.previous = previous;
5088 self.selectedItem = item;
5089 }, 1);
5090 }
5091
5092 if ( false !== self._trigger( "select", event, { item: item } ) ) {
5093 self.element.val( item.value );
5094 }
5095 // reset the term after the select event
5096 // this allows custom select handling to work properly
5097 self.term = self.element.val();
5098
5099 self.close( event );
5100 self.selectedItem = item;
5101 },
5102 blur: function( event, ui ) {
5103 // don't set the value of the text field if it's already correct
5104 // this prevents moving the cursor unnecessarily
5105 if ( self.menu.element.is(":visible") &&
5106 ( self.element.val() !== self.term ) ) {
5107 self.element.val( self.term );
5108 }
5109 }
5110 })
5111 .zIndex( this.element.zIndex() + 1 )
5112 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
5113 .css({ top: 0, left: 0 })
5114 .hide()
5115 .data( "menu" );
5116 if ( $.fn.bgiframe ) {
5117 this.menu.element.bgiframe();
5118 }
5119 },
5120
5121 destroy: function() {
5122 this.element
5123 .removeClass( "ui-autocomplete-input" )
5124 .removeAttr( "autocomplete" )
5125 .removeAttr( "role" )
5126 .removeAttr( "aria-autocomplete" )
5127 .removeAttr( "aria-haspopup" );
5128 this.menu.element.remove();
5129 $.Widget.prototype.destroy.call( this );
5130 },
5131
5132 _setOption: function( key, value ) {
5133 $.Widget.prototype._setOption.apply( this, arguments );
5134 if ( key === "source" ) {
5135 this._initSource();
5136 }
5137 if ( key === "appendTo" ) {
5138 this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
5139 }
5140 if ( key === "disabled" && value && this.xhr ) {
5141 this.xhr.abort();
5142 }
5143 },
5144
5145 _initSource: function() {
5146 var self = this,
5147 array,
5148 url;
5149 if ( $.isArray(this.options.source) ) {
5150 array = this.options.source;
5151 this.source = function( request, response ) {
5152 response( $.ui.autocomplete.filter(array, request.term) );
5153 };
5154 } else if ( typeof this.options.source === "string" ) {
5155 url = this.options.source;
5156 this.source = function( request, response ) {
5157 if ( self.xhr ) {
5158 self.xhr.abort();
5159 }
5160 self.xhr = $.ajax({
5161 url: url,
5162 data: request,
5163 dataType: "json",
5164 autocompleteRequest: ++requestIndex,
5165 success: function( data, status ) {
5166 if ( this.autocompleteRequest === requestIndex ) {
5167 response( data );
5168 }
5169 },
5170 error: function() {
5171 if ( this.autocompleteRequest === requestIndex ) {
5172 response( [] );
5173 }
5174 }
5175 });
5176 };
5177 } else {
5178 this.source = this.options.source;
5179 }
5180 },
5181
5182 search: function( value, event ) {
5183 value = value != null ? value : this.element.val();
5184
5185 // always save the actual value, not the one passed as an argument
5186 this.term = this.element.val();
5187
5188 if ( value.length < this.options.minLength ) {
5189 return this.close( event );
5190 }
5191
5192 clearTimeout( this.closing );
5193 if ( this._trigger( "search", event ) === false ) {
5194 return;
5195 }
5196
5197 return this._search( value );
5198 },
5199
5200 _search: function( value ) {
5201 this.pending++;
5202 this.element.addClass( "ui-autocomplete-loading" );
5203
5204 this.source( { term: value }, this.response );
5205 },
5206
5207 _response: function( content ) {
5208 if ( !this.options.disabled && content && content.length ) {
5209 content = this._normalize( content );
5210 this._suggest( content );
5211 this._trigger( "open" );
5212 } else {
5213 this.close();
5214 }
5215 this.pending--;
5216 if ( !this.pending ) {
5217 this.element.removeClass( "ui-autocomplete-loading" );
5218 }
5219 },
5220
5221 close: function( event ) {
5222 clearTimeout( this.closing );
5223 if ( this.menu.element.is(":visible") ) {
5224 this.menu.element.hide();
5225 this.menu.deactivate();
5226 this._trigger( "close", event );
5227 }
5228 },
5229
5230 _change: function( event ) {
5231 if ( this.previous !== this.element.val() ) {
5232 this._trigger( "change", event, { item: this.selectedItem } );
5233 }
5234 },
5235
5236 _normalize: function( items ) {
5237 // assume all items have the right format when the first item is complete
5238 if ( items.length && items[0].label && items[0].value ) {
5239 return items;
5240 }
5241 return $.map( items, function(item) {
5242 if ( typeof item === "string" ) {
5243 return {
5244 label: item,
5245 value: item
5246 };
5247 }
5248 return $.extend({
5249 label: item.label || item.value,
5250 value: item.value || item.label
5251 }, item );
5252 });
5253 },
5254
5255 _suggest: function( items ) {
5256 var ul = this.menu.element
5257 .empty()
5258 .zIndex( this.element.zIndex() + 1 );
5259 this._renderMenu( ul, items );
5260 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
5261 this.menu.deactivate();
5262 this.menu.refresh();
5263
5264 // size and position menu
5265 ul.show();
5266 this._resizeMenu();
5267 ul.position( $.extend({
5268 of: this.element
5269 }, this.options.position ));
5270
5271 if ( this.options.autoFocus ) {
5272 this.menu.next( new $.Event("mouseover") );
5273 }
5274 },
5275
5276 _resizeMenu: function() {
5277 var ul = this.menu.element;
5278 ul.outerWidth( Math.max(
5279 ul.width( "" ).outerWidth(),
5280 this.element.outerWidth()
5281 ) );
5282 },
5283
5284 _renderMenu: function( ul, items ) {
5285 var self = this;
5286 $.each( items, function( index, item ) {
5287 self._renderItem( ul, item );
5288 });
5289 },
5290
5291 _renderItem: function( ul, item) {
5292 return $( "<li></li>" )
5293 .data( "item.autocomplete", item )
5294 .append( $( "<a></a>" ).text( item.label ) )
5295 .appendTo( ul );
5296 },
5297
5298 _move: function( direction, event ) {
5299 if ( !this.menu.element.is(":visible") ) {
5300 this.search( null, event );
5301 return;
5302 }
5303 if ( this.menu.first() && /^previous/.test(direction) ||
5304 this.menu.last() && /^next/.test(direction) ) {
5305 this.element.val( this.term );
5306 this.menu.deactivate();
5307 return;
5308 }
5309 this.menu[ direction ]( event );
5310 },
5311
5312 widget: function() {
5313 return this.menu.element;
5314 }
5315 });
5316
5317 $.extend( $.ui.autocomplete, {
5318 escapeRegex: function( value ) {
5319 return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
5320 },
5321 filter: function(array, term) {
5322 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
5323 return $.grep( array, function(value) {
5324 return matcher.test( value.label || value.value || value );
5325 });
5326 }
5327 });
5328
5329 }( jQuery ));
5330
5331 /*
5332 * jQuery UI Menu (not officially released)
5333 *
5334 * This widget isn't yet finished and the API is subject to change. We plan to finish
5335 * it for the next release. You're welcome to give it a try anyway and give us feedback,
5336 * as long as you're okay with migrating your code later on. We can help with that, too.
5337 *
5338 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5339 * Dual licensed under the MIT or GPL Version 2 licenses.
5340 * http://jquery.org/license
5341 *
5342 * http://docs.jquery.com/UI/Menu
5343 *
5344 * Depends:
5345 * jquery.ui.core.js
5346 * jquery.ui.widget.js
5347 */
5348 (function($) {
5349
5350 $.widget("ui.menu", {
5351 _create: function() {
5352 var self = this;
5353 this.element
5354 .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
5355 .attr({
5356 role: "listbox",
5357 "aria-activedescendant": "ui-active-menuitem"
5358 })
5359 .click(function( event ) {
5360 if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
5361 return;
5362 }
5363 // temporary
5364 event.preventDefault();
5365 self.select( event );
5366 });
5367 this.refresh();
5368 },
5369
5370 refresh: function() {
5371 var self = this;
5372
5373 // don't refresh list items that are already adapted
5374 var items = this.element.children("li:not(.ui-menu-item):has(a)")
5375 .addClass("ui-menu-item")
5376 .attr("role", "menuitem");
5377
5378 items.children("a")
5379 .addClass("ui-corner-all")
5380 .attr("tabindex", -1)
5381 // mouseenter doesn't work with event delegation
5382 .mouseenter(function( event ) {
5383 self.activate( event, $(this).parent() );
5384 })
5385 .mouseleave(function() {
5386 self.deactivate();
5387 });
5388 },
5389
5390 activate: function( event, item ) {
5391 this.deactivate();
5392 if (this.hasScroll()) {
5393 var offset = item.offset().top - this.element.offset().top,
5394 scroll = this.element.scrollTop(),
5395 elementHeight = this.element.height();
5396 if (offset < 0) {
5397 this.element.scrollTop( scroll + offset);
5398 } else if (offset >= elementHeight) {
5399 this.element.scrollTop( scroll + offset - elementHeight + item.height());
5400 }
5401 }
5402 this.active = item.eq(0)
5403 .children("a")
5404 .addClass("ui-state-hover")
5405 .attr("id", "ui-active-menuitem")
5406 .end();
5407 this._trigger("focus", event, { item: item });
5408 },
5409
5410 deactivate: function() {
5411 if (!this.active) { return; }
5412
5413 this.active.children("a")
5414 .removeClass("ui-state-hover")
5415 .removeAttr("id");
5416 this._trigger("blur");
5417 this.active = null;
5418 },
5419
5420 next: function(event) {
5421 this.move("next", ".ui-menu-item:first", event);
5422 },
5423
5424 previous: function(event) {
5425 this.move("prev", ".ui-menu-item:last", event);
5426 },
5427
5428 first: function() {
5429 return this.active && !this.active.prevAll(".ui-menu-item").length;
5430 },
5431
5432 last: function() {
5433 return this.active && !this.active.nextAll(".ui-menu-item").length;
5434 },
5435
5436 move: function(direction, edge, event) {
5437 if (!this.active) {
5438 this.activate(event, this.element.children(edge));
5439 return;
5440 }
5441 var next = this.active[direction + "All"](".ui-menu-item").eq(0);
5442 if (next.length) {
5443 this.activate(event, next);
5444 } else {
5445 this.activate(event, this.element.children(edge));
5446 }
5447 },
5448
5449 // TODO merge with previousPage
5450 nextPage: function(event) {
5451 if (this.hasScroll()) {
5452 // TODO merge with no-scroll-else
5453 if (!this.active || this.last()) {
5454 this.activate(event, this.element.children(".ui-menu-item:first"));
5455 return;
5456 }
5457 var base = this.active.offset().top,
5458 height = this.element.height(),
5459 result = this.element.children(".ui-menu-item").filter(function() {
5460 var close = $(this).offset().top - base - height + $(this).height();
5461 // TODO improve approximation
5462 return close < 10 && close > -10;
5463 });
5464
5465 // TODO try to catch this earlier when scrollTop indicates the last page anyway
5466 if (!result.length) {
5467 result = this.element.children(".ui-menu-item:last");
5468 }
5469 this.activate(event, result);
5470 } else {
5471 this.activate(event, this.element.children(".ui-menu-item")
5472 .filter(!this.active || this.last() ? ":first" : ":last"));
5473 }
5474 },
5475
5476 // TODO merge with nextPage
5477 previousPage: function(event) {
5478 if (this.hasScroll()) {
5479 // TODO merge with no-scroll-else
5480 if (!this.active || this.first()) {
5481 this.activate(event, this.element.children(".ui-menu-item:last"));
5482 return;
5483 }
5484
5485 var base = this.active.offset().top,
5486 height = this.element.height();
5487 result = this.element.children(".ui-menu-item").filter(function() {
5488 var close = $(this).offset().top - base + height - $(this).height();
5489 // TODO improve approximation
5490 return close < 10 && close > -10;
5491 });
5492
5493 // TODO try to catch this earlier when scrollTop indicates the last page anyway
5494 if (!result.length) {
5495 result = this.element.children(".ui-menu-item:first");
5496 }
5497 this.activate(event, result);
5498 } else {
5499 this.activate(event, this.element.children(".ui-menu-item")
5500 .filter(!this.active || this.first() ? ":last" : ":first"));
5501 }
5502 },
5503
5504 hasScroll: function() {
5505 return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
5506 },
5507
5508 select: function( event ) {
5509 this._trigger("selected", event, { item: this.active });
5510 }
5511 });
5512
5513 }(jQuery));
5514 /*
5515 * jQuery UI Button 1.8.14
5516 *
5517 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5518 * Dual licensed under the MIT or GPL Version 2 licenses.
5519 * http://jquery.org/license
5520 *
5521 * http://docs.jquery.com/UI/Button
5522 *
5523 * Depends:
5524 * jquery.ui.core.js
5525 * jquery.ui.widget.js
5526 */
5527 (function( $, undefined ) {
5528
5529 var lastActive, startXPos, startYPos, clickDragged,
5530 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
5531 stateClasses = "ui-state-hover ui-state-active ",
5532 typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
5533 formResetHandler = function() {
5534 var buttons = $( this ).find( ":ui-button" );
5535 setTimeout(function() {
5536 buttons.button( "refresh" );
5537 }, 1 );
5538 },
5539 radioGroup = function( radio ) {
5540 var name = radio.name,
5541 form = radio.form,
5542 radios = $( [] );
5543 if ( name ) {
5544 if ( form ) {
5545 radios = $( form ).find( "[name='" + name + "']" );
5546 } else {
5547 radios = $( "[name='" + name + "']", radio.ownerDocument )
5548 .filter(function() {
5549 return !this.form;
5550 });
5551 }
5552 }
5553 return radios;
5554 };
5555
5556 $.widget( "ui.button", {
5557 options: {
5558 disabled: null,
5559 text: true,
5560 label: null,
5561 icons: {
5562 primary: null,
5563 secondary: null
5564 }
5565 },
5566 _create: function() {
5567 this.element.closest( "form" )
5568 .unbind( "reset.button" )
5569 .bind( "reset.button", formResetHandler );
5570
5571 if ( typeof this.options.disabled !== "boolean" ) {
5572 this.options.disabled = this.element.attr( "disabled" );
5573 }
5574
5575 this._determineButtonType();
5576 this.hasTitle = !!this.buttonElement.attr( "title" );
5577
5578 var self = this,
5579 options = this.options,
5580 toggleButton = this.type === "checkbox" || this.type === "radio",
5581 hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
5582 focusClass = "ui-state-focus";
5583
5584 if ( options.label === null ) {
5585 options.label = this.buttonElement.html();
5586 }
5587
5588 if ( this.element.is( ":disabled" ) ) {
5589 options.disabled = true;
5590 }
5591
5592 this.buttonElement
5593 .addClass( baseClasses )
5594 .attr( "role", "button" )
5595 .bind( "mouseenter.button", function() {
5596 if ( options.disabled ) {
5597 return;
5598 }
5599 $( this ).addClass( "ui-state-hover" );
5600 if ( this === lastActive ) {
5601 $( this ).addClass( "ui-state-active" );
5602 }
5603 })
5604 .bind( "mouseleave.button", function() {
5605 if ( options.disabled ) {
5606 return;
5607 }
5608 $( this ).removeClass( hoverClass );
5609 })
5610 .bind( "click.button", function( event ) {
5611 if ( options.disabled ) {
5612 event.preventDefault();
5613 event.stopImmediatePropagation();
5614 }
5615 });
5616
5617 this.element
5618 .bind( "focus.button", function() {
5619 // no need to check disabled, focus won't be triggered anyway
5620 self.buttonElement.addClass( focusClass );
5621 })
5622 .bind( "blur.button", function() {
5623 self.buttonElement.removeClass( focusClass );
5624 });
5625
5626 if ( toggleButton ) {
5627 this.element.bind( "change.button", function() {
5628 if ( clickDragged ) {
5629 return;
5630 }
5631 self.refresh();
5632 });
5633 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
5634 // prevents issue where button state changes but checkbox/radio checked state
5635 // does not in Firefox (see ticket #6970)
5636 this.buttonElement
5637 .bind( "mousedown.button", function( event ) {
5638 if ( options.disabled ) {
5639 return;
5640 }
5641 clickDragged = false;
5642 startXPos = event.pageX;
5643 startYPos = event.pageY;
5644 })
5645 .bind( "mouseup.button", function( event ) {
5646 if ( options.disabled ) {
5647 return;
5648 }
5649 if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
5650 clickDragged = true;
5651 }
5652 });
5653 }
5654
5655 if ( this.type === "checkbox" ) {
5656 this.buttonElement.bind( "click.button", function() {
5657 if ( options.disabled || clickDragged ) {
5658 return false;
5659 }
5660 $( this ).toggleClass( "ui-state-active" );
5661 self.buttonElement.attr( "aria-pressed", self.element[0].checked );
5662 });
5663 } else if ( this.type === "radio" ) {
5664 this.buttonElement.bind( "click.button", function() {
5665 if ( options.disabled || clickDragged ) {
5666 return false;
5667 }
5668 $( this ).addClass( "ui-state-active" );
5669 self.buttonElement.attr( "aria-pressed", true );
5670
5671 var radio = self.element[ 0 ];
5672 radioGroup( radio )
5673 .not( radio )
5674 .map(function() {
5675 return $( this ).button( "widget" )[ 0 ];
5676 })
5677 .removeClass( "ui-state-active" )
5678 .attr( "aria-pressed", false );
5679 });
5680 } else {
5681 this.buttonElement
5682 .bind( "mousedown.button", function() {
5683 if ( options.disabled ) {
5684 return false;
5685 }
5686 $( this ).addClass( "ui-state-active" );
5687 lastActive = this;
5688 $( document ).one( "mouseup", function() {
5689 lastActive = null;
5690 });
5691 })
5692 .bind( "mouseup.button", function() {
5693 if ( options.disabled ) {
5694 return false;
5695 }
5696 $( this ).removeClass( "ui-state-active" );
5697 })
5698 .bind( "keydown.button", function(event) {
5699 if ( options.disabled ) {
5700 return false;
5701 }
5702 if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
5703 $( this ).addClass( "ui-state-active" );
5704 }
5705 })
5706 .bind( "keyup.button", function() {
5707 $( this ).removeClass( "ui-state-active" );
5708 });
5709
5710 if ( this.buttonElement.is("a") ) {
5711 this.buttonElement.keyup(function(event) {
5712 if ( event.keyCode === $.ui.keyCode.SPACE ) {
5713 // TODO pass through original event correctly (just as 2nd argument doesn't work)
5714 $( this ).click();
5715 }
5716 });
5717 }
5718 }
5719
5720 // TODO: pull out $.Widget's handling for the disabled option into
5721 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
5722 // be overridden by individual plugins
5723 this._setOption( "disabled", options.disabled );
5724 this._resetButton();
5725 },
5726
5727 _determineButtonType: function() {
5728
5729 if ( this.element.is(":checkbox") ) {
5730 this.type = "checkbox";
5731 } else if ( this.element.is(":radio") ) {
5732 this.type = "radio";
5733 } else if ( this.element.is("input") ) {
5734 this.type = "input";
5735 } else {
5736 this.type = "button";
5737 }
5738
5739 if ( this.type === "checkbox" || this.type === "radio" ) {
5740 // we don't search against the document in case the element
5741 // is disconnected from the DOM
5742 var ancestor = this.element.parents().filter(":last"),
5743 labelSelector = "label[for=" + this.element.attr("id") + "]";
5744 this.buttonElement = ancestor.find( labelSelector );
5745 if ( !this.buttonElement.length ) {
5746 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
5747 this.buttonElement = ancestor.filter( labelSelector );
5748 if ( !this.buttonElement.length ) {
5749 this.buttonElement = ancestor.find( labelSelector );
5750 }
5751 }
5752 this.element.addClass( "ui-helper-hidden-accessible" );
5753
5754 var checked = this.element.is( ":checked" );
5755 if ( checked ) {
5756 this.buttonElement.addClass( "ui-state-active" );
5757 }
5758 this.buttonElement.attr( "aria-pressed", checked );
5759 } else {
5760 this.buttonElement = this.element;
5761 }
5762 },
5763
5764 widget: function() {
5765 return this.buttonElement;
5766 },
5767
5768 destroy: function() {
5769 this.element
5770 .removeClass( "ui-helper-hidden-accessible" );
5771 this.buttonElement
5772 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
5773 .removeAttr( "role" )
5774 .removeAttr( "aria-pressed" )
5775 .html( this.buttonElement.find(".ui-button-text").html() );
5776
5777 if ( !this.hasTitle ) {
5778 this.buttonElement.removeAttr( "title" );
5779 }
5780
5781 $.Widget.prototype.destroy.call( this );
5782 },
5783
5784 _setOption: function( key, value ) {
5785 $.Widget.prototype._setOption.apply( this, arguments );
5786 if ( key === "disabled" ) {
5787 if ( value ) {
5788 this.element.attr( "disabled", true );
5789 } else {
5790 this.element.removeAttr( "disabled" );
5791 }
5792 return;
5793 }
5794 this._resetButton();
5795 },
5796
5797 refresh: function() {
5798 var isDisabled = this.element.is( ":disabled" );
5799 if ( isDisabled !== this.options.disabled ) {
5800 this._setOption( "disabled", isDisabled );
5801 }
5802 if ( this.type === "radio" ) {
5803 radioGroup( this.element[0] ).each(function() {
5804 if ( $( this ).is( ":checked" ) ) {
5805 $( this ).button( "widget" )
5806 .addClass( "ui-state-active" )
5807 .attr( "aria-pressed", true );
5808 } else {
5809 $( this ).button( "widget" )
5810 .removeClass( "ui-state-active" )
5811 .attr( "aria-pressed", false );
5812 }
5813 });
5814 } else if ( this.type === "checkbox" ) {
5815 if ( this.element.is( ":checked" ) ) {
5816 this.buttonElement
5817 .addClass( "ui-state-active" )
5818 .attr( "aria-pressed", true );
5819 } else {
5820 this.buttonElement
5821 .removeClass( "ui-state-active" )
5822 .attr( "aria-pressed", false );
5823 }
5824 }
5825 },
5826
5827 _resetButton: function() {
5828 if ( this.type === "input" ) {
5829 if ( this.options.label ) {
5830 this.element.val( this.options.label );
5831 }
5832 return;
5833 }
5834 var buttonElement = this.buttonElement.removeClass( typeClasses ),
5835 buttonText = $( "<span></span>" )
5836 .addClass( "ui-button-text" )
5837 .html( this.options.label )
5838 .appendTo( buttonElement.empty() )
5839 .text(),
5840 icons = this.options.icons,
5841 multipleIcons = icons.primary && icons.secondary,
5842 buttonClasses = [];
5843
5844 if ( icons.primary || icons.secondary ) {
5845 if ( this.options.text ) {
5846 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
5847 }
5848
5849 if ( icons.primary ) {
5850 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
5851 }
5852
5853 if ( icons.secondary ) {
5854 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
5855 }
5856
5857 if ( !this.options.text ) {
5858 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
5859
5860 if ( !this.hasTitle ) {
5861 buttonElement.attr( "title", buttonText );
5862 }
5863 }
5864 } else {
5865 buttonClasses.push( "ui-button-text-only" );
5866 }
5867 buttonElement.addClass( buttonClasses.join( " " ) );
5868 }
5869 });
5870
5871 $.widget( "ui.buttonset", {
5872 options: {
5873 items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
5874 },
5875
5876 _create: function() {
5877 this.element.addClass( "ui-buttonset" );
5878 },
5879
5880 _init: function() {
5881 this.refresh();
5882 },
5883
5884 _setOption: function( key, value ) {
5885 if ( key === "disabled" ) {
5886 this.buttons.button( "option", key, value );
5887 }
5888
5889 $.Widget.prototype._setOption.apply( this, arguments );
5890 },
5891
5892 refresh: function() {
5893 var ltr = this.element.css( "direction" ) === "ltr";
5894
5895 this.buttons = this.element.find( this.options.items )
5896 .filter( ":ui-button" )
5897 .button( "refresh" )
5898 .end()
5899 .not( ":ui-button" )
5900 .button()
5901 .end()
5902 .map(function() {
5903 return $( this ).button( "widget" )[ 0 ];
5904 })
5905 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
5906 .filter( ":first" )
5907 .addClass( ltr ? "ui-corner-left" : "ui-corner-right" )
5908 .end()
5909 .filter( ":last" )
5910 .addClass( ltr ? "ui-corner-right" : "ui-corner-left" )
5911 .end()
5912 .end();
5913 },
5914
5915 destroy: function() {
5916 this.element.removeClass( "ui-buttonset" );
5917 this.buttons
5918 .map(function() {
5919 return $( this ).button( "widget" )[ 0 ];
5920 })
5921 .removeClass( "ui-corner-left ui-corner-right" )
5922 .end()
5923 .button( "destroy" );
5924
5925 $.Widget.prototype.destroy.call( this );
5926 }
5927 });
5928
5929 }( jQuery ) );
5930 /*
5931 * jQuery UI Dialog 1.8.14
5932 *
5933 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5934 * Dual licensed under the MIT or GPL Version 2 licenses.
5935 * http://jquery.org/license
5936 *
5937 * http://docs.jquery.com/UI/Dialog
5938 *
5939 * Depends:
5940 * jquery.ui.core.js
5941 * jquery.ui.widget.js
5942 * jquery.ui.button.js
5943 * jquery.ui.draggable.js
5944 * jquery.ui.mouse.js
5945 * jquery.ui.position.js
5946 * jquery.ui.resizable.js
5947 */
5948 (function( $, undefined ) {
5949
5950 var uiDialogClasses =
5951 'ui-dialog ' +
5952 'ui-widget ' +
5953 'ui-widget-content ' +
5954 'ui-corner-all ',
5955 sizeRelatedOptions = {
5956 buttons: true,
5957 height: true,
5958 maxHeight: true,
5959 maxWidth: true,
5960 minHeight: true,
5961 minWidth: true,
5962 width: true
5963 },
5964 resizableRelatedOptions = {
5965 maxHeight: true,
5966 maxWidth: true,
5967 minHeight: true,
5968 minWidth: true
5969 },
5970 // support for jQuery 1.3.2 - handle common attrFn methods for dialog
5971 attrFn = $.attrFn || {
5972 val: true,
5973 css: true,
5974 html: true,
5975 text: true,
5976 data: true,
5977 width: true,
5978 height: true,
5979 offset: true,
5980 click: true
5981 };
5982
5983 $.widget("ui.dialog", {
5984 options: {
5985 autoOpen: true,
5986 buttons: {},
5987 closeOnEscape: true,
5988 closeText: 'close',
5989 dialogClass: '',
5990 draggable: true,
5991 hide: null,
5992 height: 'auto',
5993 maxHeight: false,
5994 maxWidth: false,
5995 minHeight: 150,
5996 minWidth: 150,
5997 modal: false,
5998 position: {
5999 my: 'center',
6000 at: 'center',
6001 collision: 'fit',
6002 // ensure that the titlebar is never outside the document
6003 using: function(pos) {
6004 var topOffset = $(this).css(pos).offset().top;
6005 if (topOffset < 0) {
6006 $(this).css('top', pos.top - topOffset);
6007 }
6008 }
6009 },
6010 resizable: true,
6011 show: null,
6012 stack: true,
6013 title: '',
6014 width: 300,
6015 zIndex: 1000
6016 },
6017
6018 _create: function() {
6019 this.originalTitle = this.element.attr('title');
6020 // #5742 - .attr() might return a DOMElement
6021 if ( typeof this.originalTitle !== "string" ) {
6022 this.originalTitle = "";
6023 }
6024
6025 this.options.title = this.options.title || this.originalTitle;
6026 var self = this,
6027 options = self.options,
6028
6029 title = options.title || '&#160;',
6030 titleId = $.ui.dialog.getTitleId(self.element),
6031
6032 uiDialog = (self.uiDialog = $('<div></div>'))
6033 .appendTo(document.body)
6034 .hide()
6035 .addClass(uiDialogClasses + options.dialogClass)
6036 .css({
6037 zIndex: options.zIndex
6038 })
6039 // setting tabIndex makes the div focusable
6040 // setting outline to 0 prevents a border on focus in Mozilla
6041 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
6042 if (options.closeOnEscape && event.keyCode &&
6043 event.keyCode === $.ui.keyCode.ESCAPE) {
6044
6045 self.close(event);
6046 event.preventDefault();
6047 }
6048 })
6049 .attr({
6050 role: 'dialog',
6051 'aria-labelledby': titleId
6052 })
6053 .mousedown(function(event) {
6054 self.moveToTop(false, event);
6055 }),
6056
6057 uiDialogContent = self.element
6058 .show()
6059 .removeAttr('title')
6060 .addClass(
6061 'ui-dialog-content ' +
6062 'ui-widget-content')
6063 .appendTo(uiDialog),
6064
6065 uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
6066 .addClass(
6067 'ui-dialog-titlebar ' +
6068 'ui-widget-header ' +
6069 'ui-corner-all ' +
6070 'ui-helper-clearfix'
6071 )
6072 .prependTo(uiDialog),
6073
6074 uiDialogTitlebarClose = $('<a href="#"></a>')
6075 .addClass(
6076 'ui-dialog-titlebar-close ' +
6077 'ui-corner-all'
6078 )
6079 .attr('role', 'button')
6080 .hover(
6081 function() {
6082 uiDialogTitlebarClose.addClass('ui-state-hover');
6083 },
6084 function() {
6085 uiDialogTitlebarClose.removeClass('ui-state-hover');
6086 }
6087 )
6088 .focus(function() {
6089 uiDialogTitlebarClose.addClass('ui-state-focus');
6090 })
6091 .blur(function() {
6092 uiDialogTitlebarClose.removeClass('ui-state-focus');
6093 })
6094 .click(function(event) {
6095 self.close(event);
6096 return false;
6097 })
6098 .appendTo(uiDialogTitlebar),
6099
6100 uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
6101 .addClass(
6102 'ui-icon ' +
6103 'ui-icon-closethick'
6104 )
6105 .text(options.closeText)
6106 .appendTo(uiDialogTitlebarClose),
6107
6108 uiDialogTitle = $('<span></span>')
6109 .addClass('ui-dialog-title')
6110 .attr('id', titleId)
6111 .html(title)
6112 .prependTo(uiDialogTitlebar);
6113
6114 //handling of deprecated beforeclose (vs beforeClose) option
6115 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6116 //TODO: remove in 1.9pre
6117 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
6118 options.beforeClose = options.beforeclose;
6119 }
6120
6121 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
6122
6123 if (options.draggable && $.fn.draggable) {
6124 self._makeDraggable();
6125 }
6126 if (options.resizable && $.fn.resizable) {
6127 self._makeResizable();
6128 }
6129
6130 self._createButtons(options.buttons);
6131 self._isOpen = false;
6132
6133 if ($.fn.bgiframe) {
6134 uiDialog.bgiframe();
6135 }
6136 },
6137
6138 _init: function() {
6139 if ( this.options.autoOpen ) {
6140 this.open();
6141 }
6142 },
6143
6144 destroy: function() {
6145 var self = this;
6146
6147 if (self.overlay) {
6148 self.overlay.destroy();
6149 }
6150 self.uiDialog.hide();
6151 self.element
6152 .unbind('.dialog')
6153 .removeData('dialog')
6154 .removeClass('ui-dialog-content ui-widget-content')
6155 .hide().appendTo('body');
6156 self.uiDialog.remove();
6157
6158 if (self.originalTitle) {
6159 self.element.attr('title', self.originalTitle);
6160 }
6161
6162 return self;
6163 },
6164
6165 widget: function() {
6166 return this.uiDialog;
6167 },
6168
6169 close: function(event) {
6170 var self = this,
6171 maxZ, thisZ;
6172
6173 if (false === self._trigger('beforeClose', event)) {
6174 return;
6175 }
6176
6177 if (self.overlay) {
6178 self.overlay.destroy();
6179 }
6180 self.uiDialog.unbind('keypress.ui-dialog');
6181
6182 self._isOpen = false;
6183
6184 if (self.options.hide) {
6185 self.uiDialog.hide(self.options.hide, function() {
6186 self._trigger('close', event);
6187 });
6188 } else {
6189 self.uiDialog.hide();
6190 self._trigger('close', event);
6191 }
6192
6193 $.ui.dialog.overlay.resize();
6194
6195 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6196 if (self.options.modal) {
6197 maxZ = 0;
6198 $('.ui-dialog').each(function() {
6199 if (this !== self.uiDialog[0]) {
6200 thisZ = $(this).css('z-index');
6201 if(!isNaN(thisZ)) {
6202 maxZ = Math.max(maxZ, thisZ);
6203 }
6204 }
6205 });
6206 $.ui.dialog.maxZ = maxZ;
6207 }
6208
6209 return self;
6210 },
6211
6212 isOpen: function() {
6213 return this._isOpen;
6214 },
6215
6216 // the force parameter allows us to move modal dialogs to their correct
6217 // position on open
6218 moveToTop: function(force, event) {
6219 var self = this,
6220 options = self.options,
6221 saveScroll;
6222
6223 if ((options.modal && !force) ||
6224 (!options.stack && !options.modal)) {
6225 return self._trigger('focus', event);
6226 }
6227
6228 if (options.zIndex > $.ui.dialog.maxZ) {
6229 $.ui.dialog.maxZ = options.zIndex;
6230 }
6231 if (self.overlay) {
6232 $.ui.dialog.maxZ += 1;
6233 self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
6234 }
6235
6236 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
6237 // http://ui.jquery.com/bugs/ticket/3193
6238 saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
6239 $.ui.dialog.maxZ += 1;
6240 self.uiDialog.css('z-index', $.ui.dialog.maxZ);
6241 self.element.attr(saveScroll);
6242 self._trigger('focus', event);
6243
6244 return self;
6245 },
6246
6247 open: function() {
6248 if (this._isOpen) { return; }
6249
6250 var self = this,
6251 options = self.options,
6252 uiDialog = self.uiDialog;
6253
6254 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
6255 self._size();
6256 self._position(options.position);
6257 uiDialog.show(options.show);
6258 self.moveToTop(true);
6259
6260 // prevent tabbing out of modal dialogs
6261 if (options.modal) {
6262 uiDialog.bind('keypress.ui-dialog', function(event) {
6263 if (event.keyCode !== $.ui.keyCode.TAB) {
6264 return;
6265 }
6266
6267 var tabbables = $(':tabbable', this),
6268 first = tabbables.filter(':first'),
6269 last = tabbables.filter(':last');
6270
6271 if (event.target === last[0] && !event.shiftKey) {
6272 first.focus(1);
6273 return false;
6274 } else if (event.target === first[0] && event.shiftKey) {
6275 last.focus(1);
6276 return false;
6277 }
6278 });
6279 }
6280
6281 // set focus to the first tabbable element in the content area or the first button
6282 // if there are no tabbable elements, set focus on the dialog itself
6283 $(self.element.find(':tabbable').get().concat(
6284 uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
6285 uiDialog.get()))).eq(0).focus();
6286
6287 self._isOpen = true;
6288 self._trigger('open');
6289
6290 return self;
6291 },
6292
6293 _createButtons: function(buttons) {
6294 var self = this,
6295 hasButtons = false,
6296 uiDialogButtonPane = $('<div></div>')
6297 .addClass(
6298 'ui-dialog-buttonpane ' +
6299 'ui-widget-content ' +
6300 'ui-helper-clearfix'
6301 ),
6302 uiButtonSet = $( "<div></div>" )
6303 .addClass( "ui-dialog-buttonset" )
6304 .appendTo( uiDialogButtonPane );
6305
6306 // if we already have a button pane, remove it
6307 self.uiDialog.find('.ui-dialog-buttonpane').remove();
6308
6309 if (typeof buttons === 'object' && buttons !== null) {
6310 $.each(buttons, function() {
6311 return !(hasButtons = true);
6312 });
6313 }
6314 if (hasButtons) {
6315 $.each(buttons, function(name, props) {
6316 props = $.isFunction( props ) ?
6317 { click: props, text: name } :
6318 props;
6319 var button = $('<button type="button"></button>')
6320 .click(function() {
6321 props.click.apply(self.element[0], arguments);
6322 })
6323 .appendTo(uiButtonSet);
6324 // can't use .attr( props, true ) with jQuery 1.3.2.
6325 $.each( props, function( key, value ) {
6326 if ( key === "click" ) {
6327 return;
6328 }
6329 if ( key in attrFn ) {
6330 button[ key ]( value );
6331 } else {
6332 button.attr( key, value );
6333 }
6334 });
6335 if ($.fn.button) {
6336 button.button();
6337 }
6338 });
6339 uiDialogButtonPane.appendTo(self.uiDialog);
6340 }
6341 },
6342
6343 _makeDraggable: function() {
6344 var self = this,
6345 options = self.options,
6346 doc = $(document),
6347 heightBeforeDrag;
6348
6349 function filteredUi(ui) {
6350 return {
6351 position: ui.position,
6352 offset: ui.offset
6353 };
6354 }
6355
6356 self.uiDialog.draggable({
6357 cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
6358 handle: '.ui-dialog-titlebar',
6359 containment: 'document',
6360 start: function(event, ui) {
6361 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
6362 $(this).height($(this).height()).addClass("ui-dialog-dragging");
6363 self._trigger('dragStart', event, filteredUi(ui));
6364 },
6365 drag: function(event, ui) {
6366 self._trigger('drag', event, filteredUi(ui));
6367 },
6368 stop: function(event, ui) {
6369 options.position = [ui.position.left - doc.scrollLeft(),
6370 ui.position.top - doc.scrollTop()];
6371 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
6372 self._trigger('dragStop', event, filteredUi(ui));
6373 $.ui.dialog.overlay.resize();
6374 }
6375 });
6376 },
6377
6378 _makeResizable: function(handles) {
6379 handles = (handles === undefined ? this.options.resizable : handles);
6380 var self = this,
6381 options = self.options,
6382 // .ui-resizable has position: relative defined in the stylesheet
6383 // but dialogs have to use absolute or fixed positioning
6384 position = self.uiDialog.css('position'),
6385 resizeHandles = (typeof handles === 'string' ?
6386 handles :
6387 'n,e,s,w,se,sw,ne,nw'
6388 );
6389
6390 function filteredUi(ui) {
6391 return {
6392 originalPosition: ui.originalPosition,
6393 originalSize: ui.originalSize,
6394 position: ui.position,
6395 size: ui.size
6396 };
6397 }
6398
6399 self.uiDialog.resizable({
6400 cancel: '.ui-dialog-content',
6401 containment: 'document',
6402 alsoResize: self.element,
6403 maxWidth: options.maxWidth,
6404 maxHeight: options.maxHeight,
6405 minWidth: options.minWidth,
6406 minHeight: self._minHeight(),
6407 handles: resizeHandles,
6408 start: function(event, ui) {
6409 $(this).addClass("ui-dialog-resizing");
6410 self._trigger('resizeStart', event, filteredUi(ui));
6411 },
6412 resize: function(event, ui) {
6413 self._trigger('resize', event, filteredUi(ui));
6414 },
6415 stop: function(event, ui) {
6416 $(this).removeClass("ui-dialog-resizing");
6417 options.height = $(this).height();
6418 options.width = $(this).width();
6419 self._trigger('resizeStop', event, filteredUi(ui));
6420 $.ui.dialog.overlay.resize();
6421 }
6422 })
6423 .css('position', position)
6424 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
6425 },
6426
6427 _minHeight: function() {
6428 var options = this.options;
6429
6430 if (options.height === 'auto') {
6431 return options.minHeight;
6432 } else {
6433 return Math.min(options.minHeight, options.height);
6434 }
6435 },
6436
6437 _position: function(position) {
6438 var myAt = [],
6439 offset = [0, 0],
6440 isVisible;
6441
6442 if (position) {
6443 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
6444 // if (typeof position == 'string' || $.isArray(position)) {
6445 // myAt = $.isArray(position) ? position : position.split(' ');
6446
6447 if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
6448 myAt = position.split ? position.split(' ') : [position[0], position[1]];
6449 if (myAt.length === 1) {
6450 myAt[1] = myAt[0];
6451 }
6452
6453 $.each(['left', 'top'], function(i, offsetPosition) {
6454 if (+myAt[i] === myAt[i]) {
6455 offset[i] = myAt[i];
6456 myAt[i] = offsetPosition;
6457 }
6458 });
6459
6460 position = {
6461 my: myAt.join(" "),
6462 at: myAt.join(" "),
6463 offset: offset.join(" ")
6464 };
6465 }
6466
6467 position = $.extend({}, $.ui.dialog.prototype.options.position, position);
6468 } else {
6469 position = $.ui.dialog.prototype.options.position;
6470 }
6471
6472 // need to show the dialog to get the actual offset in the position plugin
6473 isVisible = this.uiDialog.is(':visible');
6474 if (!isVisible) {
6475 this.uiDialog.show();
6476 }
6477 this.uiDialog
6478 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6479 .css({ top: 0, left: 0 })
6480 .position($.extend({ of: window }, position));
6481 if (!isVisible) {
6482 this.uiDialog.hide();
6483 }
6484 },
6485
6486 _setOptions: function( options ) {
6487 var self = this,
6488 resizableOptions = {},
6489 resize = false;
6490
6491 $.each( options, function( key, value ) {
6492 self._setOption( key, value );
6493
6494 if ( key in sizeRelatedOptions ) {
6495 resize = true;
6496 }
6497 if ( key in resizableRelatedOptions ) {
6498 resizableOptions[ key ] = value;
6499 }
6500 });
6501
6502 if ( resize ) {
6503 this._size();
6504 }
6505 if ( this.uiDialog.is( ":data(resizable)" ) ) {
6506 this.uiDialog.resizable( "option", resizableOptions );
6507 }
6508 },
6509
6510 _setOption: function(key, value){
6511 var self = this,
6512 uiDialog = self.uiDialog;
6513
6514 switch (key) {
6515 //handling of deprecated beforeclose (vs beforeClose) option
6516 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6517 //TODO: remove in 1.9pre
6518 case "beforeclose":
6519 key = "beforeClose";
6520 break;
6521 case "buttons":
6522 self._createButtons(value);
6523 break;
6524 case "closeText":
6525 // ensure that we always pass a string
6526 self.uiDialogTitlebarCloseText.text("" + value);
6527 break;
6528 case "dialogClass":
6529 uiDialog
6530 .removeClass(self.options.dialogClass)
6531 .addClass(uiDialogClasses + value);
6532 break;
6533 case "disabled":
6534 if (value) {
6535 uiDialog.addClass('ui-dialog-disabled');
6536 } else {
6537 uiDialog.removeClass('ui-dialog-disabled');
6538 }
6539 break;
6540 case "draggable":
6541 var isDraggable = uiDialog.is( ":data(draggable)" );
6542 if ( isDraggable && !value ) {
6543 uiDialog.draggable( "destroy" );
6544 }
6545
6546 if ( !isDraggable && value ) {
6547 self._makeDraggable();
6548 }
6549 break;
6550 case "position":
6551 self._position(value);
6552 break;
6553 case "resizable":
6554 // currently resizable, becoming non-resizable
6555 var isResizable = uiDialog.is( ":data(resizable)" );
6556 if (isResizable && !value) {
6557 uiDialog.resizable('destroy');
6558 }
6559
6560 // currently resizable, changing handles
6561 if (isResizable && typeof value === 'string') {
6562 uiDialog.resizable('option', 'handles', value);
6563 }
6564
6565 // currently non-resizable, becoming resizable
6566 if (!isResizable && value !== false) {
6567 self._makeResizable(value);
6568 }
6569 break;
6570 case "title":
6571 // convert whatever was passed in o a string, for html() to not throw up
6572 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
6573 break;
6574 }
6575
6576 $.Widget.prototype._setOption.apply(self, arguments);
6577 },
6578
6579 _size: function() {
6580 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
6581 * divs will both have width and height set, so we need to reset them
6582 */
6583 var options = this.options,
6584 nonContentHeight,
6585 minContentHeight,
6586 isVisible = this.uiDialog.is( ":visible" );
6587
6588 // reset content sizing
6589 this.element.show().css({
6590 width: 'auto',
6591 minHeight: 0,
6592 height: 0
6593 });
6594
6595 if (options.minWidth > options.width) {
6596 options.width = options.minWidth;
6597 }
6598
6599 // reset wrapper sizing
6600 // determine the height of all the non-content elements
6601 nonContentHeight = this.uiDialog.css({
6602 height: 'auto',
6603 width: options.width
6604 })
6605 .height();
6606 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
6607
6608 if ( options.height === "auto" ) {
6609 // only needed for IE6 support
6610 if ( $.support.minHeight ) {
6611 this.element.css({
6612 minHeight: minContentHeight,
6613 height: "auto"
6614 });
6615 } else {
6616 this.uiDialog.show();
6617 var autoHeight = this.element.css( "height", "auto" ).height();
6618 if ( !isVisible ) {
6619 this.uiDialog.hide();
6620 }
6621 this.element.height( Math.max( autoHeight, minContentHeight ) );
6622 }
6623 } else {
6624 this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
6625 }
6626
6627 if (this.uiDialog.is(':data(resizable)')) {
6628 this.uiDialog.resizable('option', 'minHeight', this._minHeight());
6629 }
6630 }
6631 });
6632
6633 $.extend($.ui.dialog, {
6634 version: "1.8.14",
6635
6636 uuid: 0,
6637 maxZ: 0,
6638
6639 getTitleId: function($el) {
6640 var id = $el.attr('id');
6641 if (!id) {
6642 this.uuid += 1;
6643 id = this.uuid;
6644 }
6645 return 'ui-dialog-title-' + id;
6646 },
6647
6648 overlay: function(dialog) {
6649 this.$el = $.ui.dialog.overlay.create(dialog);
6650 }
6651 });
6652
6653 $.extend($.ui.dialog.overlay, {
6654 instances: [],
6655 // reuse old instances due to IE memory leak with alpha transparency (see #5185)
6656 oldInstances: [],
6657 maxZ: 0,
6658 events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
6659 function(event) { return event + '.dialog-overlay'; }).join(' '),
6660 create: function(dialog) {
6661 if (this.instances.length === 0) {
6662 // prevent use of anchors and inputs
6663 // we use a setTimeout in case the overlay is created from an
6664 // event that we're going to be cancelling (see #2804)
6665 setTimeout(function() {
6666 // handle $(el).dialog().dialog('close') (see #4065)
6667 if ($.ui.dialog.overlay.instances.length) {
6668 $(document).bind($.ui.dialog.overlay.events, function(event) {
6669 // stop events if the z-index of the target is < the z-index of the overlay
6670 // we cannot return true when we don't want to cancel the event (#3523)
6671 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
6672 return false;
6673 }
6674 });
6675 }
6676 }, 1);
6677
6678 // allow closing by pressing the escape key
6679 $(document).bind('keydown.dialog-overlay', function(event) {
6680 if (dialog.options.closeOnEscape && event.keyCode &&
6681 event.keyCode === $.ui.keyCode.ESCAPE) {
6682
6683 dialog.close(event);
6684 event.preventDefault();
6685 }
6686 });
6687
6688 // handle window resize
6689 $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
6690 }
6691
6692 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
6693 .appendTo(document.body)
6694 .css({
6695 width: this.width(),
6696 height: this.height()
6697 });
6698
6699 if ($.fn.bgiframe) {
6700 $el.bgiframe();
6701 }
6702
6703 this.instances.push($el);
6704 return $el;
6705 },
6706
6707 destroy: function($el) {
6708 var indexOf = $.inArray($el, this.instances);
6709 if (indexOf != -1){
6710 this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
6711 }
6712
6713 if (this.instances.length === 0) {
6714 $([document, window]).unbind('.dialog-overlay');
6715 }
6716
6717 $el.remove();
6718
6719 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6720 var maxZ = 0;
6721 $.each(this.instances, function() {
6722 maxZ = Math.max(maxZ, this.css('z-index'));
6723 });
6724 this.maxZ = maxZ;
6725 },
6726
6727 height: function() {
6728 var scrollHeight,
6729 offsetHeight;
6730 // handle IE 6
6731 if ($.browser.msie && $.browser.version < 7) {
6732 scrollHeight = Math.max(
6733 document.documentElement.scrollHeight,
6734 document.body.scrollHeight
6735 );
6736 offsetHeight = Math.max(
6737 document.documentElement.offsetHeight,
6738 document.body.offsetHeight
6739 );
6740
6741 if (scrollHeight < offsetHeight) {
6742 return $(window).height() + 'px';
6743 } else {
6744 return scrollHeight + 'px';
6745 }
6746 // handle "good" browsers
6747 } else {
6748 return $(document).height() + 'px';
6749 }
6750 },
6751
6752 width: function() {
6753 var scrollWidth,
6754 offsetWidth;
6755 // handle IE
6756 if ( $.browser.msie ) {
6757 scrollWidth = Math.max(
6758 document.documentElement.scrollWidth,
6759 document.body.scrollWidth
6760 );
6761 offsetWidth = Math.max(
6762 document.documentElement.offsetWidth,
6763 document.body.offsetWidth
6764 );
6765
6766 if (scrollWidth < offsetWidth) {
6767 return $(window).width() + 'px';
6768 } else {
6769 return scrollWidth + 'px';
6770 }
6771 // handle "good" browsers
6772 } else {
6773 return $(document).width() + 'px';
6774 }
6775 },
6776
6777 resize: function() {
6778 /* If the dialog is draggable and the user drags it past the
6779 * right edge of the window, the document becomes wider so we
6780 * need to stretch the overlay. If the user then drags the
6781 * dialog back to the left, the document will become narrower,
6782 * so we need to shrink the overlay to the appropriate size.
6783 * This is handled by shrinking the overlay before setting it
6784 * to the full document size.
6785 */
6786 var $overlays = $([]);
6787 $.each($.ui.dialog.overlay.instances, function() {
6788 $overlays = $overlays.add(this);
6789 });
6790
6791 $overlays.css({
6792 width: 0,
6793 height: 0
6794 }).css({
6795 width: $.ui.dialog.overlay.width(),
6796 height: $.ui.dialog.overlay.height()
6797 });
6798 }
6799 });
6800
6801 $.extend($.ui.dialog.overlay.prototype, {
6802 destroy: function() {
6803 $.ui.dialog.overlay.destroy(this.$el);
6804 }
6805 });
6806
6807 }(jQuery));
6808 /*
6809 * jQuery UI Slider 1.8.14
6810 *
6811 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6812 * Dual licensed under the MIT or GPL Version 2 licenses.
6813 * http://jquery.org/license
6814 *
6815 * http://docs.jquery.com/UI/Slider
6816 *
6817 * Depends:
6818 * jquery.ui.core.js
6819 * jquery.ui.mouse.js
6820 * jquery.ui.widget.js
6821 */
6822 (function( $, undefined ) {
6823
6824 // number of pages in a slider
6825 // (how many times can you page up/down to go through the whole range)
6826 var numPages = 5;
6827
6828 $.widget( "ui.slider", $.ui.mouse, {
6829
6830 widgetEventPrefix: "slide",
6831
6832 options: {
6833 animate: false,
6834 distance: 0,
6835 max: 100,
6836 min: 0,
6837 orientation: "horizontal",
6838 range: false,
6839 step: 1,
6840 value: 0,
6841 values: null
6842 },
6843
6844 _create: function() {
6845 var self = this,
6846 o = this.options,
6847 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
6848 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
6849 handleCount = ( o.values && o.values.length ) || 1,
6850 handles = [];
6851
6852 this._keySliding = false;
6853 this._mouseSliding = false;
6854 this._animateOff = true;
6855 this._handleIndex = null;
6856 this._detectOrientation();
6857 this._mouseInit();
6858
6859 this.element
6860 .addClass( "ui-slider" +
6861 " ui-slider-" + this.orientation +
6862 " ui-widget" +
6863 " ui-widget-content" +
6864 " ui-corner-all" +
6865 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
6866
6867 this.range = $([]);
6868
6869 if ( o.range ) {
6870 if ( o.range === true ) {
6871 if ( !o.values ) {
6872 o.values = [ this._valueMin(), this._valueMin() ];
6873 }
6874 if ( o.values.length && o.values.length !== 2 ) {
6875 o.values = [ o.values[0], o.values[0] ];
6876 }
6877 }
6878
6879 this.range = $( "<div></div>" )
6880 .appendTo( this.element )
6881 .addClass( "ui-slider-range" +
6882 // note: this isn't the most fittingly semantic framework class for this element,
6883 // but worked best visually with a variety of themes
6884 " ui-widget-header" +
6885 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
6886 }
6887
6888 for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
6889 handles.push( handle );
6890 }
6891
6892 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
6893
6894 this.handle = this.handles.eq( 0 );
6895
6896 this.handles.add( this.range ).filter( "a" )
6897 .click(function( event ) {
6898 event.preventDefault();
6899 })
6900 .hover(function() {
6901 if ( !o.disabled ) {
6902 $( this ).addClass( "ui-state-hover" );
6903 }
6904 }, function() {
6905 $( this ).removeClass( "ui-state-hover" );
6906 })
6907 .focus(function() {
6908 if ( !o.disabled ) {
6909 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
6910 $( this ).addClass( "ui-state-focus" );
6911 } else {
6912 $( this ).blur();
6913 }
6914 })
6915 .blur(function() {
6916 $( this ).removeClass( "ui-state-focus" );
6917 });
6918
6919 this.handles.each(function( i ) {
6920 $( this ).data( "index.ui-slider-handle", i );
6921 });
6922
6923 this.handles
6924 .keydown(function( event ) {
6925 var ret = true,
6926 index = $( this ).data( "index.ui-slider-handle" ),
6927 allowed,
6928 curVal,
6929 newVal,
6930 step;
6931
6932 if ( self.options.disabled ) {
6933 return;
6934 }
6935
6936 switch ( event.keyCode ) {
6937 case $.ui.keyCode.HOME:
6938 case $.ui.keyCode.END:
6939 case $.ui.keyCode.PAGE_UP:
6940 case $.ui.keyCode.PAGE_DOWN:
6941 case $.ui.keyCode.UP:
6942 case $.ui.keyCode.RIGHT:
6943 case $.ui.keyCode.DOWN:
6944 case $.ui.keyCode.LEFT:
6945 ret = false;
6946 if ( !self._keySliding ) {
6947 self._keySliding = true;
6948 $( this ).addClass( "ui-state-active" );
6949 allowed = self._start( event, index );
6950 if ( allowed === false ) {
6951 return;
6952 }
6953 }
6954 break;
6955 }
6956
6957 step = self.options.step;
6958 if ( self.options.values && self.options.values.length ) {
6959 curVal = newVal = self.values( index );
6960 } else {
6961 curVal = newVal = self.value();
6962 }
6963
6964 switch ( event.keyCode ) {
6965 case $.ui.keyCode.HOME:
6966 newVal = self._valueMin();
6967 break;
6968 case $.ui.keyCode.END:
6969 newVal = self._valueMax();
6970 break;
6971 case $.ui.keyCode.PAGE_UP:
6972 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
6973 break;
6974 case $.ui.keyCode.PAGE_DOWN:
6975 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
6976 break;
6977 case $.ui.keyCode.UP:
6978 case $.ui.keyCode.RIGHT:
6979 if ( curVal === self._valueMax() ) {
6980 return;
6981 }
6982 newVal = self._trimAlignValue( curVal + step );
6983 break;
6984 case $.ui.keyCode.DOWN:
6985 case $.ui.keyCode.LEFT:
6986 if ( curVal === self._valueMin() ) {
6987 return;
6988 }
6989 newVal = self._trimAlignValue( curVal - step );
6990 break;
6991 }
6992
6993 self._slide( event, index, newVal );
6994
6995 return ret;
6996
6997 })
6998 .keyup(function( event ) {
6999 var index = $( this ).data( "index.ui-slider-handle" );
7000
7001 if ( self._keySliding ) {
7002 self._keySliding = false;
7003 self._stop( event, index );
7004 self._change( event, index );
7005 $( this ).removeClass( "ui-state-active" );
7006 }
7007
7008 });
7009
7010 this._refreshValue();
7011
7012 this._animateOff = false;
7013 },
7014
7015 destroy: function() {
7016 this.handles.remove();
7017 this.range.remove();
7018
7019 this.element
7020 .removeClass( "ui-slider" +
7021 " ui-slider-horizontal" +
7022 " ui-slider-vertical" +
7023 " ui-slider-disabled" +
7024 " ui-widget" +
7025 " ui-widget-content" +
7026 " ui-corner-all" )
7027 .removeData( "slider" )
7028 .unbind( ".slider" );
7029
7030 this._mouseDestroy();
7031
7032 return this;
7033 },
7034
7035 _mouseCapture: function( event ) {
7036 var o = this.options,
7037 position,
7038 normValue,
7039 distance,
7040 closestHandle,
7041 self,
7042 index,
7043 allowed,
7044 offset,
7045 mouseOverHandle;
7046
7047 if ( o.disabled ) {
7048 return false;
7049 }
7050
7051 this.elementSize = {
7052 width: this.element.outerWidth(),
7053 height: this.element.outerHeight()
7054 };
7055 this.elementOffset = this.element.offset();
7056
7057 position = { x: event.pageX, y: event.pageY };
7058 normValue = this._normValueFromMouse( position );
7059 distance = this._valueMax() - this._valueMin() + 1;
7060 self = this;
7061 this.handles.each(function( i ) {
7062 var thisDistance = Math.abs( normValue - self.values(i) );
7063 if ( distance > thisDistance ) {
7064 distance = thisDistance;
7065 closestHandle = $( this );
7066 index = i;
7067 }
7068 });
7069
7070 // workaround for bug #3736 (if both handles of a range are at 0,
7071 // the first is always used as the one with least distance,
7072 // and moving it is obviously prevented by preventing negative ranges)
7073 if( o.range === true && this.values(1) === o.min ) {
7074 index += 1;
7075 closestHandle = $( this.handles[index] );
7076 }
7077
7078 allowed = this._start( event, index );
7079 if ( allowed === false ) {
7080 return false;
7081 }
7082 this._mouseSliding = true;
7083
7084 self._handleIndex = index;
7085
7086 closestHandle
7087 .addClass( "ui-state-active" )
7088 .focus();
7089
7090 offset = closestHandle.offset();
7091 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
7092 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
7093 left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
7094 top: event.pageY - offset.top -
7095 ( closestHandle.height() / 2 ) -
7096 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
7097 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
7098 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
7099 };
7100
7101 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
7102 this._slide( event, index, normValue );
7103 }
7104 this._animateOff = true;
7105 return true;
7106 },
7107
7108 _mouseStart: function( event ) {
7109 return true;
7110 },
7111
7112 _mouseDrag: function( event ) {
7113 var position = { x: event.pageX, y: event.pageY },
7114 normValue = this._normValueFromMouse( position );
7115
7116 this._slide( event, this._handleIndex, normValue );
7117
7118 return false;
7119 },
7120
7121 _mouseStop: function( event ) {
7122 this.handles.removeClass( "ui-state-active" );
7123 this._mouseSliding = false;
7124
7125 this._stop( event, this._handleIndex );
7126 this._change( event, this._handleIndex );
7127
7128 this._handleIndex = null;
7129 this._clickOffset = null;
7130 this._animateOff = false;
7131
7132 return false;
7133 },
7134
7135 _detectOrientation: function() {
7136 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
7137 },
7138
7139 _normValueFromMouse: function( position ) {
7140 var pixelTotal,
7141 pixelMouse,
7142 percentMouse,
7143 valueTotal,
7144 valueMouse;
7145
7146 if ( this.orientation === "horizontal" ) {
7147 pixelTotal = this.elementSize.width;
7148 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
7149 } else {
7150 pixelTotal = this.elementSize.height;
7151 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
7152 }
7153
7154 percentMouse = ( pixelMouse / pixelTotal );
7155 if ( percentMouse > 1 ) {
7156 percentMouse = 1;
7157 }
7158 if ( percentMouse < 0 ) {
7159 percentMouse = 0;
7160 }
7161 if ( this.orientation === "vertical" ) {
7162 percentMouse = 1 - percentMouse;
7163 }
7164
7165 valueTotal = this._valueMax() - this._valueMin();
7166 valueMouse = this._valueMin() + percentMouse * valueTotal;
7167
7168 return this._trimAlignValue( valueMouse );
7169 },
7170
7171 _start: function( event, index ) {
7172 var uiHash = {
7173 handle: this.handles[ index ],
7174 value: this.value()
7175 };
7176 if ( this.options.values && this.options.values.length ) {
7177 uiHash.value = this.values( index );
7178 uiHash.values = this.values();
7179 }
7180 return this._trigger( "start", event, uiHash );
7181 },
7182
7183 _slide: function( event, index, newVal ) {
7184 var otherVal,
7185 newValues,
7186 allowed;
7187
7188 if ( this.options.values && this.options.values.length ) {
7189 otherVal = this.values( index ? 0 : 1 );
7190
7191 if ( ( this.options.values.length === 2 && this.options.range === true ) &&
7192 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
7193 ) {
7194 newVal = otherVal;
7195 }
7196
7197 if ( newVal !== this.values( index ) ) {
7198 newValues = this.values();
7199 newValues[ index ] = newVal;
7200 // A slide can be canceled by returning false from the slide callback
7201 allowed = this._trigger( "slide", event, {
7202 handle: this.handles[ index ],
7203 value: newVal,
7204 values: newValues
7205 } );
7206 otherVal = this.values( index ? 0 : 1 );
7207 if ( allowed !== false ) {
7208 this.values( index, newVal, true );
7209 }
7210 }
7211 } else {
7212 if ( newVal !== this.value() ) {
7213 // A slide can be canceled by returning false from the slide callback
7214 allowed = this._trigger( "slide", event, {
7215 handle: this.handles[ index ],
7216 value: newVal
7217 } );
7218 if ( allowed !== false ) {
7219 this.value( newVal );
7220 }
7221 }
7222 }
7223 },
7224
7225 _stop: function( event, index ) {
7226 var uiHash = {
7227 handle: this.handles[ index ],
7228 value: this.value()
7229 };
7230 if ( this.options.values && this.options.values.length ) {
7231 uiHash.value = this.values( index );
7232 uiHash.values = this.values();
7233 }
7234
7235 this._trigger( "stop", event, uiHash );
7236 },
7237
7238 _change: function( event, index ) {
7239 if ( !this._keySliding && !this._mouseSliding ) {
7240 var uiHash = {
7241 handle: this.handles[ index ],
7242 value: this.value()
7243 };
7244 if ( this.options.values && this.options.values.length ) {
7245 uiHash.value = this.values( index );
7246 uiHash.values = this.values();
7247 }
7248
7249 this._trigger( "change", event, uiHash );
7250 }
7251 },
7252
7253 value: function( newValue ) {
7254 if ( arguments.length ) {
7255 this.options.value = this._trimAlignValue( newValue );
7256 this._refreshValue();
7257 this._change( null, 0 );
7258 return;
7259 }
7260
7261 return this._value();
7262 },
7263
7264 values: function( index, newValue ) {
7265 var vals,
7266 newValues,
7267 i;
7268
7269 if ( arguments.length > 1 ) {
7270 this.options.values[ index ] = this._trimAlignValue( newValue );
7271 this._refreshValue();
7272 this._change( null, index );
7273 return;
7274 }
7275
7276 if ( arguments.length ) {
7277 if ( $.isArray( arguments[ 0 ] ) ) {
7278 vals = this.options.values;
7279 newValues = arguments[ 0 ];
7280 for ( i = 0; i < vals.length; i += 1 ) {
7281 vals[ i ] = this._trimAlignValue( newValues[ i ] );
7282 this._change( null, i );
7283 }
7284 this._refreshValue();
7285 } else {
7286 if ( this.options.values && this.options.values.length ) {
7287 return this._values( index );
7288 } else {
7289 return this.value();
7290 }
7291 }
7292 } else {
7293 return this._values();
7294 }
7295 },
7296
7297 _setOption: function( key, value ) {
7298 var i,
7299 valsLength = 0;
7300
7301 if ( $.isArray( this.options.values ) ) {
7302 valsLength = this.options.values.length;
7303 }
7304
7305 $.Widget.prototype._setOption.apply( this, arguments );
7306
7307 switch ( key ) {
7308 case "disabled":
7309 if ( value ) {
7310 this.handles.filter( ".ui-state-focus" ).blur();
7311 this.handles.removeClass( "ui-state-hover" );
7312 this.handles.attr( "disabled", "disabled" );
7313 this.element.addClass( "ui-disabled" );
7314 } else {
7315 this.handles.removeAttr( "disabled" );
7316 this.element.removeClass( "ui-disabled" );
7317 }
7318 break;
7319 case "orientation":
7320 this._detectOrientation();
7321 this.element
7322 .removeClass( "ui-slider-horizontal ui-slider-vertical" )
7323 .addClass( "ui-slider-" + this.orientation );
7324 this._refreshValue();
7325 break;
7326 case "value":
7327 this._animateOff = true;
7328 this._refreshValue();
7329 this._change( null, 0 );
7330 this._animateOff = false;
7331 break;
7332 case "values":
7333 this._animateOff = true;
7334 this._refreshValue();
7335 for ( i = 0; i < valsLength; i += 1 ) {
7336 this._change( null, i );
7337 }
7338 this._animateOff = false;
7339 break;
7340 }
7341 },
7342
7343 //internal value getter
7344 // _value() returns value trimmed by min and max, aligned by step
7345 _value: function() {
7346 var val = this.options.value;
7347 val = this._trimAlignValue( val );
7348
7349 return val;
7350 },
7351
7352 //internal values getter
7353 // _values() returns array of values trimmed by min and max, aligned by step
7354 // _values( index ) returns single value trimmed by min and max, aligned by step
7355 _values: function( index ) {
7356 var val,
7357 vals,
7358 i;
7359
7360 if ( arguments.length ) {
7361 val = this.options.values[ index ];
7362 val = this._trimAlignValue( val );
7363
7364 return val;
7365 } else {
7366 // .slice() creates a copy of the array
7367 // this copy gets trimmed by min and max and then returned
7368 vals = this.options.values.slice();
7369 for ( i = 0; i < vals.length; i+= 1) {
7370 vals[ i ] = this._trimAlignValue( vals[ i ] );
7371 }
7372
7373 return vals;
7374 }
7375 },
7376
7377 // returns the step-aligned value that val is closest to, between (inclusive) min and max
7378 _trimAlignValue: function( val ) {
7379 if ( val <= this._valueMin() ) {
7380 return this._valueMin();
7381 }
7382 if ( val >= this._valueMax() ) {
7383 return this._valueMax();
7384 }
7385 var step = ( this.options.step > 0 ) ? this.options.step : 1,
7386 valModStep = (val - this._valueMin()) % step;
7387 alignValue = val - valModStep;
7388
7389 if ( Math.abs(valModStep) * 2 >= step ) {
7390 alignValue += ( valModStep > 0 ) ? step : ( -step );
7391 }
7392
7393 // Since JavaScript has problems with large floats, round
7394 // the final value to 5 digits after the decimal point (see #4124)
7395 return parseFloat( alignValue.toFixed(5) );
7396 },
7397
7398 _valueMin: function() {
7399 return this.options.min;
7400 },
7401
7402 _valueMax: function() {
7403 return this.options.max;
7404 },
7405
7406 _refreshValue: function() {
7407 var oRange = this.options.range,
7408 o = this.options,
7409 self = this,
7410 animate = ( !this._animateOff ) ? o.animate : false,
7411 valPercent,
7412 _set = {},
7413 lastValPercent,
7414 value,
7415 valueMin,
7416 valueMax;
7417
7418 if ( this.options.values && this.options.values.length ) {
7419 this.handles.each(function( i, j ) {
7420 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
7421 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7422 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7423 if ( self.options.range === true ) {
7424 if ( self.orientation === "horizontal" ) {
7425 if ( i === 0 ) {
7426 self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
7427 }
7428 if ( i === 1 ) {
7429 self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7430 }
7431 } else {
7432 if ( i === 0 ) {
7433 self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
7434 }
7435 if ( i === 1 ) {
7436 self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7437 }
7438 }
7439 }
7440 lastValPercent = valPercent;
7441 });
7442 } else {
7443 value = this.value();
7444 valueMin = this._valueMin();
7445 valueMax = this._valueMax();
7446 valPercent = ( valueMax !== valueMin ) ?
7447 ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
7448 0;
7449 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7450 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7451
7452 if ( oRange === "min" && this.orientation === "horizontal" ) {
7453 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
7454 }
7455 if ( oRange === "max" && this.orientation === "horizontal" ) {
7456 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7457 }
7458 if ( oRange === "min" && this.orientation === "vertical" ) {
7459 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
7460 }
7461 if ( oRange === "max" && this.orientation === "vertical" ) {
7462 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7463 }
7464 }
7465 }
7466
7467 });
7468
7469 $.extend( $.ui.slider, {
7470 version: "1.8.14"
7471 });
7472
7473 }(jQuery));
7474 /*
7475 * jQuery UI Tabs 1.8.14
7476 *
7477 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
7478 * Dual licensed under the MIT or GPL Version 2 licenses.
7479 * http://jquery.org/license
7480 *
7481 * http://docs.jquery.com/UI/Tabs
7482 *
7483 * Depends:
7484 * jquery.ui.core.js
7485 * jquery.ui.widget.js
7486 */
7487 (function( $, undefined ) {
7488
7489 var tabId = 0,
7490 listId = 0;
7491
7492 function getNextTabId() {
7493 return ++tabId;
7494 }
7495
7496 function getNextListId() {
7497 return ++listId;
7498 }
7499
7500 $.widget( "ui.tabs", {
7501 options: {
7502 add: null,
7503 ajaxOptions: null,
7504 cache: false,
7505 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
7506 collapsible: false,
7507 disable: null,
7508 disabled: [],
7509 enable: null,
7510 event: "click",
7511 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
7512 idPrefix: "ui-tabs-",
7513 load: null,
7514 panelTemplate: "<div></div>",
7515 remove: null,
7516 select: null,
7517 show: null,
7518 spinner: "<em>Loading&#8230;</em>",
7519 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
7520 },
7521
7522 _create: function() {
7523 this._tabify( true );
7524 },
7525
7526 _setOption: function( key, value ) {
7527 if ( key == "selected" ) {
7528 if (this.options.collapsible && value == this.options.selected ) {
7529 return;
7530 }
7531 this.select( value );
7532 } else {
7533 this.options[ key ] = value;
7534 this._tabify();
7535 }
7536 },
7537
7538 _tabId: function( a ) {
7539 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
7540 this.options.idPrefix + getNextTabId();
7541 },
7542
7543 _sanitizeSelector: function( hash ) {
7544 // we need this because an id may contain a ":"
7545 return hash.replace( /:/g, "\\:" );
7546 },
7547
7548 _cookie: function() {
7549 var cookie = this.cookie ||
7550 ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
7551 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
7552 },
7553
7554 _ui: function( tab, panel ) {
7555 return {
7556 tab: tab,
7557 panel: panel,
7558 index: this.anchors.index( tab )
7559 };
7560 },
7561
7562 _cleanup: function() {
7563 // restore all former loading tabs labels
7564 this.lis.filter( ".ui-state-processing" )
7565 .removeClass( "ui-state-processing" )
7566 .find( "span:data(label.tabs)" )
7567 .each(function() {
7568 var el = $( this );
7569 el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
7570 });
7571 },
7572
7573 _tabify: function( init ) {
7574 var self = this,
7575 o = this.options,
7576 fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
7577
7578 this.list = this.element.find( "ol,ul" ).eq( 0 );
7579 this.lis = $( " > li:has(a[href])", this.list );
7580 this.anchors = this.lis.map(function() {
7581 return $( "a", this )[ 0 ];
7582 });
7583 this.panels = $( [] );
7584
7585 this.anchors.each(function( i, a ) {
7586 var href = $( a ).attr( "href" );
7587 // For dynamically created HTML that contains a hash as href IE < 8 expands
7588 // such href to the full page url with hash and then misinterprets tab as ajax.
7589 // Same consideration applies for an added tab with a fragment identifier
7590 // since a[href=#fragment-identifier] does unexpectedly not match.
7591 // Thus normalize href attribute...
7592 var hrefBase = href.split( "#" )[ 0 ],
7593 baseEl;
7594 if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
7595 ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
7596 href = a.hash;
7597 a.href = href;
7598 }
7599
7600 // inline tab
7601 if ( fragmentId.test( href ) ) {
7602 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
7603 // remote tab
7604 // prevent loading the page itself if href is just "#"
7605 } else if ( href && href !== "#" ) {
7606 // required for restore on destroy
7607 $.data( a, "href.tabs", href );
7608
7609 // TODO until #3808 is fixed strip fragment identifier from url
7610 // (IE fails to load from such url)
7611 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
7612
7613 var id = self._tabId( a );
7614 a.href = "#" + id;
7615 var $panel = self.element.find( "#" + id );
7616 if ( !$panel.length ) {
7617 $panel = $( o.panelTemplate )
7618 .attr( "id", id )
7619 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
7620 .insertAfter( self.panels[ i - 1 ] || self.list );
7621 $panel.data( "destroy.tabs", true );
7622 }
7623 self.panels = self.panels.add( $panel );
7624 // invalid tab href
7625 } else {
7626 o.disabled.push( i );
7627 }
7628 });
7629
7630 // initialization from scratch
7631 if ( init ) {
7632 // attach necessary classes for styling
7633 this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
7634 this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7635 this.lis.addClass( "ui-state-default ui-corner-top" );
7636 this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
7637
7638 // Selected tab
7639 // use "selected" option or try to retrieve:
7640 // 1. from fragment identifier in url
7641 // 2. from cookie
7642 // 3. from selected class attribute on <li>
7643 if ( o.selected === undefined ) {
7644 if ( location.hash ) {
7645 this.anchors.each(function( i, a ) {
7646 if ( a.hash == location.hash ) {
7647 o.selected = i;
7648 return false;
7649 }
7650 });
7651 }
7652 if ( typeof o.selected !== "number" && o.cookie ) {
7653 o.selected = parseInt( self._cookie(), 10 );
7654 }
7655 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
7656 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7657 }
7658 o.selected = o.selected || ( this.lis.length ? 0 : -1 );
7659 } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
7660 o.selected = -1;
7661 }
7662
7663 // sanity check - default to first tab...
7664 o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
7665 ? o.selected
7666 : 0;
7667
7668 // Take disabling tabs via class attribute from HTML
7669 // into account and update option properly.
7670 // A selected tab cannot become disabled.
7671 o.disabled = $.unique( o.disabled.concat(
7672 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
7673 return self.lis.index( n );
7674 })
7675 ) ).sort();
7676
7677 if ( $.inArray( o.selected, o.disabled ) != -1 ) {
7678 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
7679 }
7680
7681 // highlight selected tab
7682 this.panels.addClass( "ui-tabs-hide" );
7683 this.lis.removeClass( "ui-tabs-selected ui-state-active" );
7684 // check for length avoids error when initializing empty list
7685 if ( o.selected >= 0 && this.anchors.length ) {
7686 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
7687 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
7688
7689 // seems to be expected behavior that the show callback is fired
7690 self.element.queue( "tabs", function() {
7691 self._trigger( "show", null,
7692 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
7693 });
7694
7695 this.load( o.selected );
7696 }
7697
7698 // clean up to avoid memory leaks in certain versions of IE 6
7699 // TODO: namespace this event
7700 $( window ).bind( "unload", function() {
7701 self.lis.add( self.anchors ).unbind( ".tabs" );
7702 self.lis = self.anchors = self.panels = null;
7703 });
7704 // update selected after add/remove
7705 } else {
7706 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7707 }
7708
7709 // update collapsible
7710 // TODO: use .toggleClass()
7711 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
7712
7713 // set or update cookie after init and add/remove respectively
7714 if ( o.cookie ) {
7715 this._cookie( o.selected, o.cookie );
7716 }
7717
7718 // disable tabs
7719 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
7720 $( li )[ $.inArray( i, o.disabled ) != -1 &&
7721 // TODO: use .toggleClass()
7722 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
7723 }
7724
7725 // reset cache if switching from cached to not cached
7726 if ( o.cache === false ) {
7727 this.anchors.removeData( "cache.tabs" );
7728 }
7729
7730 // remove all handlers before, tabify may run on existing tabs after add or option change
7731 this.lis.add( this.anchors ).unbind( ".tabs" );
7732
7733 if ( o.event !== "mouseover" ) {
7734 var addState = function( state, el ) {
7735 if ( el.is( ":not(.ui-state-disabled)" ) ) {
7736 el.addClass( "ui-state-" + state );
7737 }
7738 };
7739 var removeState = function( state, el ) {
7740 el.removeClass( "ui-state-" + state );
7741 };
7742 this.lis.bind( "mouseover.tabs" , function() {
7743 addState( "hover", $( this ) );
7744 });
7745 this.lis.bind( "mouseout.tabs", function() {
7746 removeState( "hover", $( this ) );
7747 });
7748 this.anchors.bind( "focus.tabs", function() {
7749 addState( "focus", $( this ).closest( "li" ) );
7750 });
7751 this.anchors.bind( "blur.tabs", function() {
7752 removeState( "focus", $( this ).closest( "li" ) );
7753 });
7754 }
7755
7756 // set up animations
7757 var hideFx, showFx;
7758 if ( o.fx ) {
7759 if ( $.isArray( o.fx ) ) {
7760 hideFx = o.fx[ 0 ];
7761 showFx = o.fx[ 1 ];
7762 } else {
7763 hideFx = showFx = o.fx;
7764 }
7765 }
7766
7767 // Reset certain styles left over from animation
7768 // and prevent IE's ClearType bug...
7769 function resetStyle( $el, fx ) {
7770 $el.css( "display", "" );
7771 if ( !$.support.opacity && fx.opacity ) {
7772 $el[ 0 ].style.removeAttribute( "filter" );
7773 }
7774 }
7775
7776 // Show a tab...
7777 var showTab = showFx
7778 ? function( clicked, $show ) {
7779 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7780 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
7781 .animate( showFx, showFx.duration || "normal", function() {
7782 resetStyle( $show, showFx );
7783 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7784 });
7785 }
7786 : function( clicked, $show ) {
7787 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7788 $show.removeClass( "ui-tabs-hide" );
7789 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7790 };
7791
7792 // Hide a tab, $show is optional...
7793 var hideTab = hideFx
7794 ? function( clicked, $hide ) {
7795 $hide.animate( hideFx, hideFx.duration || "normal", function() {
7796 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7797 $hide.addClass( "ui-tabs-hide" );
7798 resetStyle( $hide, hideFx );
7799 self.element.dequeue( "tabs" );
7800 });
7801 }
7802 : function( clicked, $hide, $show ) {
7803 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7804 $hide.addClass( "ui-tabs-hide" );
7805 self.element.dequeue( "tabs" );
7806 };
7807
7808 // attach tab event handler, unbind to avoid duplicates from former tabifying...
7809 this.anchors.bind( o.event + ".tabs", function() {
7810 var el = this,
7811 $li = $(el).closest( "li" ),
7812 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
7813 $show = self.element.find( self._sanitizeSelector( el.hash ) );
7814
7815 // If tab is already selected and not collapsible or tab disabled or
7816 // or is already loading or click callback returns false stop here.
7817 // Check if click handler returns false last so that it is not executed
7818 // for a disabled or loading tab!
7819 if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
7820 $li.hasClass( "ui-state-disabled" ) ||
7821 $li.hasClass( "ui-state-processing" ) ||
7822 self.panels.filter( ":animated" ).length ||
7823 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
7824 this.blur();
7825 return false;
7826 }
7827
7828 o.selected = self.anchors.index( this );
7829
7830 self.abort();
7831
7832 // if tab may be closed
7833 if ( o.collapsible ) {
7834 if ( $li.hasClass( "ui-tabs-selected" ) ) {
7835 o.selected = -1;
7836
7837 if ( o.cookie ) {
7838 self._cookie( o.selected, o.cookie );
7839 }
7840
7841 self.element.queue( "tabs", function() {
7842 hideTab( el, $hide );
7843 }).dequeue( "tabs" );
7844
7845 this.blur();
7846 return false;
7847 } else if ( !$hide.length ) {
7848 if ( o.cookie ) {
7849 self._cookie( o.selected, o.cookie );
7850 }
7851
7852 self.element.queue( "tabs", function() {
7853 showTab( el, $show );
7854 });
7855
7856 // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
7857 self.load( self.anchors.index( this ) );
7858
7859 this.blur();
7860 return false;
7861 }
7862 }
7863
7864 if ( o.cookie ) {
7865 self._cookie( o.selected, o.cookie );
7866 }
7867
7868 // show new tab
7869 if ( $show.length ) {
7870 if ( $hide.length ) {
7871 self.element.queue( "tabs", function() {
7872 hideTab( el, $hide );
7873 });
7874 }
7875 self.element.queue( "tabs", function() {
7876 showTab( el, $show );
7877 });
7878
7879 self.load( self.anchors.index( this ) );
7880 } else {
7881 throw "jQuery UI Tabs: Mismatching fragment identifier.";
7882 }
7883
7884 // Prevent IE from keeping other link focussed when using the back button
7885 // and remove dotted border from clicked link. This is controlled via CSS
7886 // in modern browsers; blur() removes focus from address bar in Firefox
7887 // which can become a usability and annoying problem with tabs('rotate').
7888 if ( $.browser.msie ) {
7889 this.blur();
7890 }
7891 });
7892
7893 // disable click in any case
7894 this.anchors.bind( "click.tabs", function(){
7895 return false;
7896 });
7897 },
7898
7899 _getIndex: function( index ) {
7900 // meta-function to give users option to provide a href string instead of a numerical index.
7901 // also sanitizes numerical indexes to valid values.
7902 if ( typeof index == "string" ) {
7903 index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
7904 }
7905
7906 return index;
7907 },
7908
7909 destroy: function() {
7910 var o = this.options;
7911
7912 this.abort();
7913
7914 this.element
7915 .unbind( ".tabs" )
7916 .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
7917 .removeData( "tabs" );
7918
7919 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7920
7921 this.anchors.each(function() {
7922 var href = $.data( this, "href.tabs" );
7923 if ( href ) {
7924 this.href = href;
7925 }
7926 var $this = $( this ).unbind( ".tabs" );
7927 $.each( [ "href", "load", "cache" ], function( i, prefix ) {
7928 $this.removeData( prefix + ".tabs" );
7929 });
7930 });
7931
7932 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
7933 if ( $.data( this, "destroy.tabs" ) ) {
7934 $( this ).remove();
7935 } else {
7936 $( this ).removeClass([
7937 "ui-state-default",
7938 "ui-corner-top",
7939 "ui-tabs-selected",
7940 "ui-state-active",
7941 "ui-state-hover",
7942 "ui-state-focus",
7943 "ui-state-disabled",
7944 "ui-tabs-panel",
7945 "ui-widget-content",
7946 "ui-corner-bottom",
7947 "ui-tabs-hide"
7948 ].join( " " ) );
7949 }
7950 });
7951
7952 if ( o.cookie ) {
7953 this._cookie( null, o.cookie );
7954 }
7955
7956 return this;
7957 },
7958
7959 add: function( url, label, index ) {
7960 if ( index === undefined ) {
7961 index = this.anchors.length;
7962 }
7963
7964 var self = this,
7965 o = this.options,
7966 $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
7967 id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
7968
7969 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
7970
7971 // try to find an existing element before creating a new one
7972 var $panel = self.element.find( "#" + id );
7973 if ( !$panel.length ) {
7974 $panel = $( o.panelTemplate )
7975 .attr( "id", id )
7976 .data( "destroy.tabs", true );
7977 }
7978 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
7979
7980 if ( index >= this.lis.length ) {
7981 $li.appendTo( this.list );
7982 $panel.appendTo( this.list[ 0 ].parentNode );
7983 } else {
7984 $li.insertBefore( this.lis[ index ] );
7985 $panel.insertBefore( this.panels[ index ] );
7986 }
7987
7988 o.disabled = $.map( o.disabled, function( n, i ) {
7989 return n >= index ? ++n : n;
7990 });
7991
7992 this._tabify();
7993
7994 if ( this.anchors.length == 1 ) {
7995 o.selected = 0;
7996 $li.addClass( "ui-tabs-selected ui-state-active" );
7997 $panel.removeClass( "ui-tabs-hide" );
7998 this.element.queue( "tabs", function() {
7999 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
8000 });
8001
8002 this.load( 0 );
8003 }
8004
8005 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8006 return this;
8007 },
8008
8009 remove: function( index ) {
8010 index = this._getIndex( index );
8011 var o = this.options,
8012 $li = this.lis.eq( index ).remove(),
8013 $panel = this.panels.eq( index ).remove();
8014
8015 // If selected tab was removed focus tab to the right or
8016 // in case the last tab was removed the tab to the left.
8017 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
8018 this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
8019 }
8020
8021 o.disabled = $.map(
8022 $.grep( o.disabled, function(n, i) {
8023 return n != index;
8024 }),
8025 function( n, i ) {
8026 return n >= index ? --n : n;
8027 });
8028
8029 this._tabify();
8030
8031 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
8032 return this;
8033 },
8034
8035 enable: function( index ) {
8036 index = this._getIndex( index );
8037 var o = this.options;
8038 if ( $.inArray( index, o.disabled ) == -1 ) {
8039 return;
8040 }
8041
8042 this.lis.eq( index ).removeClass( "ui-state-disabled" );
8043 o.disabled = $.grep( o.disabled, function( n, i ) {
8044 return n != index;
8045 });
8046
8047 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8048 return this;
8049 },
8050
8051 disable: function( index ) {
8052 index = this._getIndex( index );
8053 var self = this, o = this.options;
8054 // cannot disable already selected tab
8055 if ( index != o.selected ) {
8056 this.lis.eq( index ).addClass( "ui-state-disabled" );
8057
8058 o.disabled.push( index );
8059 o.disabled.sort();
8060
8061 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8062 }
8063
8064 return this;
8065 },
8066
8067 select: function( index ) {
8068 index = this._getIndex( index );
8069 if ( index == -1 ) {
8070 if ( this.options.collapsible && this.options.selected != -1 ) {
8071 index = this.options.selected;
8072 } else {
8073 return this;
8074 }
8075 }
8076 this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
8077 return this;
8078 },
8079
8080 load: function( index ) {
8081 index = this._getIndex( index );
8082 var self = this,
8083 o = this.options,
8084 a = this.anchors.eq( index )[ 0 ],
8085 url = $.data( a, "load.tabs" );
8086
8087 this.abort();
8088
8089 // not remote or from cache
8090 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
8091 this.element.dequeue( "tabs" );
8092 return;
8093 }
8094
8095 // load remote from here on
8096 this.lis.eq( index ).addClass( "ui-state-processing" );
8097
8098 if ( o.spinner ) {
8099 var span = $( "span", a );
8100 span.data( "label.tabs", span.html() ).html( o.spinner );
8101 }
8102
8103 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
8104 url: url,
8105 success: function( r, s ) {
8106 self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
8107
8108 // take care of tab labels
8109 self._cleanup();
8110
8111 if ( o.cache ) {
8112 $.data( a, "cache.tabs", true );
8113 }
8114
8115 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8116 try {
8117 o.ajaxOptions.success( r, s );
8118 }
8119 catch ( e ) {}
8120 },
8121 error: function( xhr, s, e ) {
8122 // take care of tab labels
8123 self._cleanup();
8124
8125 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8126 try {
8127 // Passing index avoid a race condition when this method is
8128 // called after the user has selected another tab.
8129 // Pass the anchor that initiated this request allows
8130 // loadError to manipulate the tab content panel via $(a.hash)
8131 o.ajaxOptions.error( xhr, s, index, a );
8132 }
8133 catch ( e ) {}
8134 }
8135 } ) );
8136
8137 // last, so that load event is fired before show...
8138 self.element.dequeue( "tabs" );
8139
8140 return this;
8141 },
8142
8143 abort: function() {
8144 // stop possibly running animations
8145 this.element.queue( [] );
8146 this.panels.stop( false, true );
8147
8148 // "tabs" queue must not contain more than two elements,
8149 // which are the callbacks for the latest clicked tab...
8150 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
8151
8152 // terminate pending requests from other tabs
8153 if ( this.xhr ) {
8154 this.xhr.abort();
8155 delete this.xhr;
8156 }
8157
8158 // take care of tab labels
8159 this._cleanup();
8160 return this;
8161 },
8162
8163 url: function( index, url ) {
8164 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
8165 return this;
8166 },
8167
8168 length: function() {
8169 return this.anchors.length;
8170 }
8171 });
8172
8173 $.extend( $.ui.tabs, {
8174 version: "1.8.14"
8175 });
8176
8177 /*
8178 * Tabs Extensions
8179 */
8180
8181 /*
8182 * Rotate
8183 */
8184 $.extend( $.ui.tabs.prototype, {
8185 rotation: null,
8186 rotate: function( ms, continuing ) {
8187 var self = this,
8188 o = this.options;
8189
8190 var rotate = self._rotate || ( self._rotate = function( e ) {
8191 clearTimeout( self.rotation );
8192 self.rotation = setTimeout(function() {
8193 var t = o.selected;
8194 self.select( ++t < self.anchors.length ? t : 0 );
8195 }, ms );
8196
8197 if ( e ) {
8198 e.stopPropagation();
8199 }
8200 });
8201
8202 var stop = self._unrotate || ( self._unrotate = !continuing
8203 ? function(e) {
8204 if (e.clientX) { // in case of a true click
8205 self.rotate(null);
8206 }
8207 }
8208 : function( e ) {
8209 t = o.selected;
8210 rotate();
8211 });
8212
8213 // start rotation
8214 if ( ms ) {
8215 this.element.bind( "tabsshow", rotate );
8216 this.anchors.bind( o.event + ".tabs", stop );
8217 rotate();
8218 // stop rotation
8219 } else {
8220 clearTimeout( self.rotation );
8221 this.element.unbind( "tabsshow", rotate );
8222 this.anchors.unbind( o.event + ".tabs", stop );
8223 delete this._rotate;
8224 delete this._unrotate;
8225 }
8226
8227 return this;
8228 }
8229 });
8230
8231 })( jQuery );
8232 /*
8233 * jQuery UI Datepicker 1.8.14
8234 *
8235 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
8236 * Dual licensed under the MIT or GPL Version 2 licenses.
8237 * http://jquery.org/license
8238 *
8239 * http://docs.jquery.com/UI/Datepicker
8240 *
8241 * Depends:
8242 * jquery.ui.core.js
8243 */
8244 (function( $, undefined ) {
8245
8246 $.extend($.ui, { datepicker: { version: "1.8.14" } });
8247
8248 var PROP_NAME = 'datepicker';
8249 var dpuuid = new Date().getTime();
8250 var instActive;
8251
8252 /* Date picker manager.
8253 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8254 Settings for (groups of) date pickers are maintained in an instance object,
8255 allowing multiple different settings on the same page. */
8256
8257 function Datepicker() {
8258 this.debug = false; // Change this to true to start debugging
8259 this._curInst = null; // The current instance in use
8260 this._keyEvent = false; // If the last event was a key event
8261 this._disabledInputs = []; // List of date picker inputs that have been disabled
8262 this._datepickerShowing = false; // True if the popup picker is showing , false if not
8263 this._inDialog = false; // True if showing within a "dialog", false if not
8264 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
8265 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
8266 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
8267 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
8268 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
8269 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
8270 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
8271 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
8272 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
8273 this.regional = []; // Available regional settings, indexed by language code
8274 this.regional[''] = { // Default regional settings
8275 closeText: 'Done', // Display text for close link
8276 prevText: 'Prev', // Display text for previous month link
8277 nextText: 'Next', // Display text for next month link
8278 currentText: 'Today', // Display text for current month link
8279 monthNames: ['January','February','March','April','May','June',
8280 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
8281 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
8282 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
8283 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
8284 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
8285 weekHeader: 'Wk', // Column header for week of the year
8286 dateFormat: 'mm/dd/yy', // See format options on parseDate
8287 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8288 isRTL: false, // True if right-to-left language, false if left-to-right
8289 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8290 yearSuffix: '' // Additional text to append to the year in the month headers
8291 };
8292 this._defaults = { // Global defaults for all the date picker instances
8293 showOn: 'focus', // 'focus' for popup on focus,
8294 // 'button' for trigger button, or 'both' for either
8295 showAnim: 'fadeIn', // Name of jQuery animation for popup
8296 showOptions: {}, // Options for enhanced animations
8297 defaultDate: null, // Used when field is blank: actual date,
8298 // +/-number for offset from today, null for today
8299 appendText: '', // Display text following the input box, e.g. showing the format
8300 buttonText: '...', // Text for trigger button
8301 buttonImage: '', // URL for trigger button image
8302 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8303 hideIfNoPrevNext: false, // True to hide next/previous month links
8304 // if not applicable, false to just disable them
8305 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8306 gotoCurrent: false, // True if today link goes back to current selection instead
8307 changeMonth: false, // True if month can be selected directly, false if only prev/next
8308 changeYear: false, // True if year can be selected directly, false if only prev/next
8309 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
8310 // either relative to today's year (-nn:+nn), relative to currently displayed year
8311 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8312 showOtherMonths: false, // True to show dates in other months, false to leave blank
8313 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8314 showWeek: false, // True to show week of the year, false to not show it
8315 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8316 // takes a Date and returns the number of the week for it
8317 shortYearCutoff: '+10', // Short year values < this are in the current century,
8318 // > this are in the previous century,
8319 // string value starting with '+' for current year + value
8320 minDate: null, // The earliest selectable date, or null for no limit
8321 maxDate: null, // The latest selectable date, or null for no limit
8322 duration: 'fast', // Duration of display/closure
8323 beforeShowDay: null, // Function that takes a date and returns an array with
8324 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
8325 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8326 beforeShow: null, // Function that takes an input field and
8327 // returns a set of custom settings for the date picker
8328 onSelect: null, // Define a callback function when a date is selected
8329 onChangeMonthYear: null, // Define a callback function when the month or year is changed
8330 onClose: null, // Define a callback function when the datepicker is closed
8331 numberOfMonths: 1, // Number of months to show at a time
8332 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8333 stepMonths: 1, // Number of months to step back/forward
8334 stepBigMonths: 12, // Number of months to step back/forward for the big links
8335 altField: '', // Selector for an alternate field to store selected dates into
8336 altFormat: '', // The date format to use for the alternate field
8337 constrainInput: true, // The input is constrained by the current date format
8338 showButtonPanel: false, // True to show button panel, false to not show it
8339 autoSize: false // True to size the input for the date format, false to leave as is
8340 };
8341 $.extend(this._defaults, this.regional['']);
8342 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
8343 }
8344
8345 $.extend(Datepicker.prototype, {
8346 /* Class name added to elements to indicate already configured with a date picker. */
8347 markerClassName: 'hasDatepicker',
8348
8349 //Keep track of the maximum number of rows displayed (see #7043)
8350 maxRows: 4,
8351
8352 /* Debug logging (if enabled). */
8353 log: function () {
8354 if (this.debug)
8355 console.log.apply('', arguments);
8356 },
8357
8358 // TODO rename to "widget" when switching to widget factory
8359 _widgetDatepicker: function() {
8360 return this.dpDiv;
8361 },
8362
8363 /* Override the default settings for all instances of the date picker.
8364 @param settings object - the new settings to use as defaults (anonymous object)
8365 @return the manager object */
8366 setDefaults: function(settings) {
8367 extendRemove(this._defaults, settings || {});
8368 return this;
8369 },
8370
8371 /* Attach the date picker to a jQuery selection.
8372 @param target element - the target input field or division or span
8373 @param settings object - the new settings to use for this date picker instance (anonymous) */
8374 _attachDatepicker: function(target, settings) {
8375 // check for settings on the control itself - in namespace 'date:'
8376 var inlineSettings = null;
8377 for (var attrName in this._defaults) {
8378 var attrValue = target.getAttribute('date:' + attrName);
8379 if (attrValue) {
8380 inlineSettings = inlineSettings || {};
8381 try {
8382 inlineSettings[attrName] = eval(attrValue);
8383 } catch (err) {
8384 inlineSettings[attrName] = attrValue;
8385 }
8386 }
8387 }
8388 var nodeName = target.nodeName.toLowerCase();
8389 var inline = (nodeName == 'div' || nodeName == 'span');
8390 if (!target.id) {
8391 this.uuid += 1;
8392 target.id = 'dp' + this.uuid;
8393 }
8394 var inst = this._newInst($(target), inline);
8395 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
8396 if (nodeName == 'input') {
8397 this._connectDatepicker(target, inst);
8398 } else if (inline) {
8399 this._inlineDatepicker(target, inst);
8400 }
8401 },
8402
8403 /* Create a new instance object. */
8404 _newInst: function(target, inline) {
8405 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
8406 return {id: id, input: target, // associated target
8407 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8408 drawMonth: 0, drawYear: 0, // month being drawn
8409 inline: inline, // is datepicker inline or not
8410 dpDiv: (!inline ? this.dpDiv : // presentation div
8411 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
8412 },
8413
8414 /* Attach the date picker to an input field. */
8415 _connectDatepicker: function(target, inst) {
8416 var input = $(target);
8417 inst.append = $([]);
8418 inst.trigger = $([]);
8419 if (input.hasClass(this.markerClassName))
8420 return;
8421 this._attachments(input, inst);
8422 input.addClass(this.markerClassName).keydown(this._doKeyDown).
8423 keypress(this._doKeyPress).keyup(this._doKeyUp).
8424 bind("setData.datepicker", function(event, key, value) {
8425 inst.settings[key] = value;
8426 }).bind("getData.datepicker", function(event, key) {
8427 return this._get(inst, key);
8428 });
8429 this._autoSize(inst);
8430 $.data(target, PROP_NAME, inst);
8431 },
8432
8433 /* Make attachments based on settings. */
8434 _attachments: function(input, inst) {
8435 var appendText = this._get(inst, 'appendText');
8436 var isRTL = this._get(inst, 'isRTL');
8437 if (inst.append)
8438 inst.append.remove();
8439 if (appendText) {
8440 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
8441 input[isRTL ? 'before' : 'after'](inst.append);
8442 }
8443 input.unbind('focus', this._showDatepicker);
8444 if (inst.trigger)
8445 inst.trigger.remove();
8446 var showOn = this._get(inst, 'showOn');
8447 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
8448 input.focus(this._showDatepicker);
8449 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
8450 var buttonText = this._get(inst, 'buttonText');
8451 var buttonImage = this._get(inst, 'buttonImage');
8452 inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
8453 $('<img/>').addClass(this._triggerClass).
8454 attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8455 $('<button type="button"></button>').addClass(this._triggerClass).
8456 html(buttonImage == '' ? buttonText : $('<img/>').attr(
8457 { src:buttonImage, alt:buttonText, title:buttonText })));
8458 input[isRTL ? 'before' : 'after'](inst.trigger);
8459 inst.trigger.click(function() {
8460 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
8461 $.datepicker._hideDatepicker();
8462 else
8463 $.datepicker._showDatepicker(input[0]);
8464 return false;
8465 });
8466 }
8467 },
8468
8469 /* Apply the maximum length for the date format. */
8470 _autoSize: function(inst) {
8471 if (this._get(inst, 'autoSize') && !inst.inline) {
8472 var date = new Date(2009, 12 - 1, 20); // Ensure double digits
8473 var dateFormat = this._get(inst, 'dateFormat');
8474 if (dateFormat.match(/[DM]/)) {
8475 var findMax = function(names) {
8476 var max = 0;
8477 var maxI = 0;
8478 for (var i = 0; i < names.length; i++) {
8479 if (names[i].length > max) {
8480 max = names[i].length;
8481 maxI = i;
8482 }
8483 }
8484 return maxI;
8485 };
8486 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8487 'monthNames' : 'monthNamesShort'))));
8488 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8489 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
8490 }
8491 inst.input.attr('size', this._formatDate(inst, date).length);
8492 }
8493 },
8494
8495 /* Attach an inline date picker to a div. */
8496 _inlineDatepicker: function(target, inst) {
8497 var divSpan = $(target);
8498 if (divSpan.hasClass(this.markerClassName))
8499 return;
8500 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
8501 bind("setData.datepicker", function(event, key, value){
8502 inst.settings[key] = value;
8503 }).bind("getData.datepicker", function(event, key){
8504 return this._get(inst, key);
8505 });
8506 $.data(target, PROP_NAME, inst);
8507 this._setDate(inst, this._getDefaultDate(inst), true);
8508 this._updateDatepicker(inst);
8509 this._updateAlternate(inst);
8510 inst.dpDiv.show();
8511 },
8512
8513 /* Pop-up the date picker in a "dialog" box.
8514 @param input element - ignored
8515 @param date string or Date - the initial date to display
8516 @param onSelect function - the function to call when a date is selected
8517 @param settings object - update the dialog date picker instance's settings (anonymous object)
8518 @param pos int[2] - coordinates for the dialog's position within the screen or
8519 event - with x/y coordinates or
8520 leave empty for default (screen centre)
8521 @return the manager object */
8522 _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8523 var inst = this._dialogInst; // internal instance
8524 if (!inst) {
8525 this.uuid += 1;
8526 var id = 'dp' + this.uuid;
8527 this._dialogInput = $('<input type="text" id="' + id +
8528 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
8529 this._dialogInput.keydown(this._doKeyDown);
8530 $('body').append(this._dialogInput);
8531 inst = this._dialogInst = this._newInst(this._dialogInput, false);
8532 inst.settings = {};
8533 $.data(this._dialogInput[0], PROP_NAME, inst);
8534 }
8535 extendRemove(inst.settings, settings || {});
8536 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
8537 this._dialogInput.val(date);
8538
8539 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8540 if (!this._pos) {
8541 var browserWidth = document.documentElement.clientWidth;
8542 var browserHeight = document.documentElement.clientHeight;
8543 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8544 var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8545 this._pos = // should use actual width/height below
8546 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8547 }
8548
8549 // move input on screen for focus, but hidden behind dialog
8550 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
8551 inst.settings.onSelect = onSelect;
8552 this._inDialog = true;
8553 this.dpDiv.addClass(this._dialogClass);
8554 this._showDatepicker(this._dialogInput[0]);
8555 if ($.blockUI)
8556 $.blockUI(this.dpDiv);
8557 $.data(this._dialogInput[0], PROP_NAME, inst);
8558 return this;
8559 },
8560
8561 /* Detach a datepicker from its control.
8562 @param target element - the target input field or division or span */
8563 _destroyDatepicker: function(target) {
8564 var $target = $(target);
8565 var inst = $.data(target, PROP_NAME);
8566 if (!$target.hasClass(this.markerClassName)) {
8567 return;
8568 }
8569 var nodeName = target.nodeName.toLowerCase();
8570 $.removeData(target, PROP_NAME);
8571 if (nodeName == 'input') {
8572 inst.append.remove();
8573 inst.trigger.remove();
8574 $target.removeClass(this.markerClassName).
8575 unbind('focus', this._showDatepicker).
8576 unbind('keydown', this._doKeyDown).
8577 unbind('keypress', this._doKeyPress).
8578 unbind('keyup', this._doKeyUp);
8579 } else if (nodeName == 'div' || nodeName == 'span')
8580 $target.removeClass(this.markerClassName).empty();
8581 },
8582
8583 /* Enable the date picker to a jQuery selection.
8584 @param target element - the target input field or division or span */
8585 _enableDatepicker: function(target) {
8586 var $target = $(target);
8587 var inst = $.data(target, PROP_NAME);
8588 if (!$target.hasClass(this.markerClassName)) {
8589 return;
8590 }
8591 var nodeName = target.nodeName.toLowerCase();
8592 if (nodeName == 'input') {
8593 target.disabled = false;
8594 inst.trigger.filter('button').
8595 each(function() { this.disabled = false; }).end().
8596 filter('img').css({opacity: '1.0', cursor: ''});
8597 }
8598 else if (nodeName == 'div' || nodeName == 'span') {
8599 var inline = $target.children('.' + this._inlineClass);
8600 inline.children().removeClass('ui-state-disabled');
8601 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8602 removeAttr("disabled");
8603 }
8604 this._disabledInputs = $.map(this._disabledInputs,
8605 function(value) { return (value == target ? null : value); }); // delete entry
8606 },
8607
8608 /* Disable the date picker to a jQuery selection.
8609 @param target element - the target input field or division or span */
8610 _disableDatepicker: function(target) {
8611 var $target = $(target);
8612 var inst = $.data(target, PROP_NAME);
8613 if (!$target.hasClass(this.markerClassName)) {
8614 return;
8615 }
8616 var nodeName = target.nodeName.toLowerCase();
8617 if (nodeName == 'input') {
8618 target.disabled = true;
8619 inst.trigger.filter('button').
8620 each(function() { this.disabled = true; }).end().
8621 filter('img').css({opacity: '0.5', cursor: 'default'});
8622 }
8623 else if (nodeName == 'div' || nodeName == 'span') {
8624 var inline = $target.children('.' + this._inlineClass);
8625 inline.children().addClass('ui-state-disabled');
8626 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8627 attr("disabled", "disabled");
8628 }
8629 this._disabledInputs = $.map(this._disabledInputs,
8630 function(value) { return (value == target ? null : value); }); // delete entry
8631 this._disabledInputs[this._disabledInputs.length] = target;
8632 },
8633
8634 /* Is the first field in a jQuery collection disabled as a datepicker?
8635 @param target element - the target input field or division or span
8636 @return boolean - true if disabled, false if enabled */
8637 _isDisabledDatepicker: function(target) {
8638 if (!target) {
8639 return false;
8640 }
8641 for (var i = 0; i < this._disabledInputs.length; i++) {
8642 if (this._disabledInputs[i] == target)
8643 return true;
8644 }
8645 return false;
8646 },
8647
8648 /* Retrieve the instance data for the target control.
8649 @param target element - the target input field or division or span
8650 @return object - the associated instance data
8651 @throws error if a jQuery problem getting data */
8652 _getInst: function(target) {
8653 try {
8654 return $.data(target, PROP_NAME);
8655 }
8656 catch (err) {
8657 throw 'Missing instance data for this datepicker';
8658 }
8659 },
8660
8661 /* Update or retrieve the settings for a date picker attached to an input field or division.
8662 @param target element - the target input field or division or span
8663 @param name object - the new settings to update or
8664 string - the name of the setting to change or retrieve,
8665 when retrieving also 'all' for all instance settings or
8666 'defaults' for all global defaults
8667 @param value any - the new value for the setting
8668 (omit if above is an object or to retrieve a value) */
8669 _optionDatepicker: function(target, name, value) {
8670 var inst = this._getInst(target);
8671 if (arguments.length == 2 && typeof name == 'string') {
8672 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
8673 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
8674 this._get(inst, name)) : null));
8675 }
8676 var settings = name || {};
8677 if (typeof name == 'string') {
8678 settings = {};
8679 settings[name] = value;
8680 }
8681 if (inst) {
8682 if (this._curInst == inst) {
8683 this._hideDatepicker();
8684 }
8685 var date = this._getDateDatepicker(target, true);
8686 var minDate = this._getMinMaxDate(inst, 'min');
8687 var maxDate = this._getMinMaxDate(inst, 'max');
8688 extendRemove(inst.settings, settings);
8689 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8690 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
8691 inst.settings.minDate = this._formatDate(inst, minDate);
8692 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
8693 inst.settings.maxDate = this._formatDate(inst, maxDate);
8694 this._attachments($(target), inst);
8695 this._autoSize(inst);
8696 this._setDate(inst, date);
8697 this._updateAlternate(inst);
8698 this._updateDatepicker(inst);
8699 }
8700 },
8701
8702 // change method deprecated
8703 _changeDatepicker: function(target, name, value) {
8704 this._optionDatepicker(target, name, value);
8705 },
8706
8707 /* Redraw the date picker attached to an input field or division.
8708 @param target element - the target input field or division or span */
8709 _refreshDatepicker: function(target) {
8710 var inst = this._getInst(target);
8711 if (inst) {
8712 this._updateDatepicker(inst);
8713 }
8714 },
8715
8716 /* Set the dates for a jQuery selection.
8717 @param target element - the target input field or division or span
8718 @param date Date - the new date */
8719 _setDateDatepicker: function(target, date) {
8720 var inst = this._getInst(target);
8721 if (inst) {
8722 this._setDate(inst, date);
8723 this._updateDatepicker(inst);
8724 this._updateAlternate(inst);
8725 }
8726 },
8727
8728 /* Get the date(s) for the first entry in a jQuery selection.
8729 @param target element - the target input field or division or span
8730 @param noDefault boolean - true if no default date is to be used
8731 @return Date - the current date */
8732 _getDateDatepicker: function(target, noDefault) {
8733 var inst = this._getInst(target);
8734 if (inst && !inst.inline)
8735 this._setDateFromField(inst, noDefault);
8736 return (inst ? this._getDate(inst) : null);
8737 },
8738
8739 /* Handle keystrokes. */
8740 _doKeyDown: function(event) {
8741 var inst = $.datepicker._getInst(event.target);
8742 var handled = true;
8743 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
8744 inst._keyEvent = true;
8745 if ($.datepicker._datepickerShowing)
8746 switch (event.keyCode) {
8747 case 9: $.datepicker._hideDatepicker();
8748 handled = false;
8749 break; // hide on tab out
8750 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
8751 $.datepicker._currentClass + ')', inst.dpDiv);
8752 if (sel[0])
8753 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8754 else
8755 $.datepicker._hideDatepicker();
8756 return false; // don't submit the form
8757 break; // select the value on enter
8758 case 27: $.datepicker._hideDatepicker();
8759 break; // hide on escape
8760 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8761 -$.datepicker._get(inst, 'stepBigMonths') :
8762 -$.datepicker._get(inst, 'stepMonths')), 'M');
8763 break; // previous month/year on page up/+ ctrl
8764 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8765 +$.datepicker._get(inst, 'stepBigMonths') :
8766 +$.datepicker._get(inst, 'stepMonths')), 'M');
8767 break; // next month/year on page down/+ ctrl
8768 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
8769 handled = event.ctrlKey || event.metaKey;
8770 break; // clear on ctrl or command +end
8771 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
8772 handled = event.ctrlKey || event.metaKey;
8773 break; // current on ctrl or command +home
8774 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
8775 handled = event.ctrlKey || event.metaKey;
8776 // -1 day on ctrl or command +left
8777 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8778 -$.datepicker._get(inst, 'stepBigMonths') :
8779 -$.datepicker._get(inst, 'stepMonths')), 'M');
8780 // next month/year on alt +left on Mac
8781 break;
8782 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
8783 handled = event.ctrlKey || event.metaKey;
8784 break; // -1 week on ctrl or command +up
8785 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
8786 handled = event.ctrlKey || event.metaKey;
8787 // +1 day on ctrl or command +right
8788 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8789 +$.datepicker._get(inst, 'stepBigMonths') :
8790 +$.datepicker._get(inst, 'stepMonths')), 'M');
8791 // next month/year on alt +right
8792 break;
8793 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
8794 handled = event.ctrlKey || event.metaKey;
8795 break; // +1 week on ctrl or command +down
8796 default: handled = false;
8797 }
8798 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
8799 $.datepicker._showDatepicker(this);
8800 else {
8801 handled = false;
8802 }
8803 if (handled) {
8804 event.preventDefault();
8805 event.stopPropagation();
8806 }
8807 },
8808
8809 /* Filter entered characters - based on date format. */
8810 _doKeyPress: function(event) {
8811 var inst = $.datepicker._getInst(event.target);
8812 if ($.datepicker._get(inst, 'constrainInput')) {
8813 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
8814 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
8815 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
8816 }
8817 },
8818
8819 /* Synchronise manual entry and field/alternate field. */
8820 _doKeyUp: function(event) {
8821 var inst = $.datepicker._getInst(event.target);
8822 if (inst.input.val() != inst.lastVal) {
8823 try {
8824 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8825 (inst.input ? inst.input.val() : null),
8826 $.datepicker._getFormatConfig(inst));
8827 if (date) { // only if valid
8828 $.datepicker._setDateFromField(inst);
8829 $.datepicker._updateAlternate(inst);
8830 $.datepicker._updateDatepicker(inst);
8831 }
8832 }
8833 catch (event) {
8834 $.datepicker.log(event);
8835 }
8836 }
8837 return true;
8838 },
8839
8840 /* Pop-up the date picker for a given input field.
8841 @param input element - the input field attached to the date picker or
8842 event - if triggered by focus */
8843 _showDatepicker: function(input) {
8844 input = input.target || input;
8845 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
8846 input = $('input', input.parentNode)[0];
8847 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
8848 return;
8849 var inst = $.datepicker._getInst(input);
8850 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
8851 if ( $.datepicker._datepickerShowing ) {
8852 $.datepicker._triggerOnClose($.datepicker._curInst);
8853 }
8854 $.datepicker._curInst.dpDiv.stop(true, true);
8855 }
8856 var beforeShow = $.datepicker._get(inst, 'beforeShow');
8857 extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
8858 inst.lastVal = null;
8859 $.datepicker._lastInput = input;
8860 $.datepicker._setDateFromField(inst);
8861 if ($.datepicker._inDialog) // hide cursor
8862 input.value = '';
8863 if (!$.datepicker._pos) { // position below input
8864 $.datepicker._pos = $.datepicker._findPos(input);
8865 $.datepicker._pos[1] += input.offsetHeight; // add the height
8866 }
8867 var isFixed = false;
8868 $(input).parents().each(function() {
8869 isFixed |= $(this).css('position') == 'fixed';
8870 return !isFixed;
8871 });
8872 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
8873 $.datepicker._pos[0] -= document.documentElement.scrollLeft;
8874 $.datepicker._pos[1] -= document.documentElement.scrollTop;
8875 }
8876 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8877 $.datepicker._pos = null;
8878 //to avoid flashes on Firefox
8879 inst.dpDiv.empty();
8880 // determine sizing offscreen
8881 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
8882 $.datepicker._updateDatepicker(inst);
8883 // fix width for dynamic number of date pickers
8884 // and adjust position before showing
8885 offset = $.datepicker._checkOffset(inst, offset, isFixed);
8886 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8887 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
8888 left: offset.left + 'px', top: offset.top + 'px'});
8889 if (!inst.inline) {
8890 var showAnim = $.datepicker._get(inst, 'showAnim');
8891 var duration = $.datepicker._get(inst, 'duration');
8892 var postProcess = function() {
8893 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8894 if( !! cover.length ){
8895 var borders = $.datepicker._getBorders(inst.dpDiv);
8896 cover.css({left: -borders[0], top: -borders[1],
8897 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
8898 }
8899 };
8900 inst.dpDiv.zIndex($(input).zIndex()+1);
8901 $.datepicker._datepickerShowing = true;
8902 if ($.effects && $.effects[showAnim])
8903 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8904 else
8905 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
8906 if (!showAnim || !duration)
8907 postProcess();
8908 if (inst.input.is(':visible') && !inst.input.is(':disabled'))
8909 inst.input.focus();
8910 $.datepicker._curInst = inst;
8911 }
8912 },
8913
8914 /* Generate the date picker content. */
8915 _updateDatepicker: function(inst) {
8916 var self = this;
8917 self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8918 var borders = $.datepicker._getBorders(inst.dpDiv);
8919 instActive = inst; // for delegate hover events
8920 inst.dpDiv.empty().append(this._generateHTML(inst));
8921 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8922 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
8923 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
8924 }
8925 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
8926 var numMonths = this._getNumberOfMonths(inst);
8927 var cols = numMonths[1];
8928 var width = 17;
8929 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
8930 if (cols > 1)
8931 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
8932 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
8933 'Class']('ui-datepicker-multi');
8934 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
8935 'Class']('ui-datepicker-rtl');
8936 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
8937 // #6694 - don't focus the input if it's already focused
8938 // this breaks the change event in IE
8939 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
8940 inst.input.focus();
8941 // deffered render of the years select (to avoid flashes on Firefox)
8942 if( inst.yearshtml ){
8943 var origyearshtml = inst.yearshtml;
8944 setTimeout(function(){
8945 //assure that inst.yearshtml didn't change.
8946 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8947 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
8948 }
8949 origyearshtml = inst.yearshtml = null;
8950 }, 0);
8951 }
8952 },
8953
8954 /* Retrieve the size of left and top borders for an element.
8955 @param elem (jQuery object) the element of interest
8956 @return (number[2]) the left and top borders */
8957 _getBorders: function(elem) {
8958 var convert = function(value) {
8959 return {thin: 1, medium: 2, thick: 3}[value] || value;
8960 };
8961 return [parseFloat(convert(elem.css('border-left-width'))),
8962 parseFloat(convert(elem.css('border-top-width')))];
8963 },
8964
8965 /* Check positioning to remain on screen. */
8966 _checkOffset: function(inst, offset, isFixed) {
8967 var dpWidth = inst.dpDiv.outerWidth();
8968 var dpHeight = inst.dpDiv.outerHeight();
8969 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
8970 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
8971 var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
8972 var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
8973
8974 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
8975 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
8976 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8977
8978 // now check if datepicker is showing outside window viewport - move to a better place if so.
8979 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8980 Math.abs(offset.left + dpWidth - viewWidth) : 0);
8981 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8982 Math.abs(dpHeight + inputHeight) : 0);
8983
8984 return offset;
8985 },
8986
8987 /* Find an object's position on the screen. */
8988 _findPos: function(obj) {
8989 var inst = this._getInst(obj);
8990 var isRTL = this._get(inst, 'isRTL');
8991 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
8992 obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
8993 }
8994 var position = $(obj).offset();
8995 return [position.left, position.top];
8996 },
8997
8998 /* Trigger custom callback of onClose. */
8999 _triggerOnClose: function(inst) {
9000 var onClose = this._get(inst, 'onClose');
9001 if (onClose)
9002 onClose.apply((inst.input ? inst.input[0] : null),
9003 [(inst.input ? inst.input.val() : ''), inst]);
9004 },
9005
9006 /* Hide the date picker from view.
9007 @param input element - the input field attached to the date picker */
9008 _hideDatepicker: function(input) {
9009 var inst = this._curInst;
9010 if (!inst || (input && inst != $.data(input, PROP_NAME)))
9011 return;
9012 if (this._datepickerShowing) {
9013 var showAnim = this._get(inst, 'showAnim');
9014 var duration = this._get(inst, 'duration');
9015 var postProcess = function() {
9016 $.datepicker._tidyDialog(inst);
9017 this._curInst = null;
9018 };
9019 if ($.effects && $.effects[showAnim])
9020 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
9021 else
9022 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
9023 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
9024 if (!showAnim)
9025 postProcess();
9026 $.datepicker._triggerOnClose(inst);
9027 this._datepickerShowing = false;
9028 this._lastInput = null;
9029 if (this._inDialog) {
9030 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
9031 if ($.blockUI) {
9032 $.unblockUI();
9033 $('body').append(this.dpDiv);
9034 }
9035 }
9036 this._inDialog = false;
9037 }
9038 },
9039
9040 /* Tidy up after a dialog display. */
9041 _tidyDialog: function(inst) {
9042 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
9043 },
9044
9045 /* Close date picker if clicked elsewhere. */
9046 _checkExternalClick: function(event) {
9047 if (!$.datepicker._curInst)
9048 return;
9049 var $target = $(event.target);
9050 if ($target[0].id != $.datepicker._mainDivId &&
9051 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
9052 !$target.hasClass($.datepicker.markerClassName) &&
9053 !$target.hasClass($.datepicker._triggerClass) &&
9054 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
9055 $.datepicker._hideDatepicker();
9056 },
9057
9058 /* Adjust one of the date sub-fields. */
9059 _adjustDate: function(id, offset, period) {
9060 var target = $(id);
9061 var inst = this._getInst(target[0]);
9062 if (this._isDisabledDatepicker(target[0])) {
9063 return;
9064 }
9065 this._adjustInstDate(inst, offset +
9066 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
9067 period);
9068 this._updateDatepicker(inst);
9069 },
9070
9071 /* Action for current link. */
9072 _gotoToday: function(id) {
9073 var target = $(id);
9074 var inst = this._getInst(target[0]);
9075 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
9076 inst.selectedDay = inst.currentDay;
9077 inst.drawMonth = inst.selectedMonth = inst.currentMonth;
9078 inst.drawYear = inst.selectedYear = inst.currentYear;
9079 }
9080 else {
9081 var date = new Date();
9082 inst.selectedDay = date.getDate();
9083 inst.drawMonth = inst.selectedMonth = date.getMonth();
9084 inst.drawYear = inst.selectedYear = date.getFullYear();
9085 }
9086 this._notifyChange(inst);
9087 this._adjustDate(target);
9088 },
9089
9090 /* Action for selecting a new month/year. */
9091 _selectMonthYear: function(id, select, period) {
9092 var target = $(id);
9093 var inst = this._getInst(target[0]);
9094 inst._selectingMonthYear = false;
9095 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
9096 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
9097 parseInt(select.options[select.selectedIndex].value,10);
9098 this._notifyChange(inst);
9099 this._adjustDate(target);
9100 },
9101
9102 /* Restore input focus after not changing month/year. */
9103 _clickMonthYear: function(id) {
9104 var target = $(id);
9105 var inst = this._getInst(target[0]);
9106 if (inst.input && inst._selectingMonthYear) {
9107 setTimeout(function() {
9108 inst.input.focus();
9109 }, 0);
9110 }
9111 inst._selectingMonthYear = !inst._selectingMonthYear;
9112 },
9113
9114 /* Action for selecting a day. */
9115 _selectDay: function(id, month, year, td) {
9116 var target = $(id);
9117 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
9118 return;
9119 }
9120 var inst = this._getInst(target[0]);
9121 inst.selectedDay = inst.currentDay = $('a', td).html();
9122 inst.selectedMonth = inst.currentMonth = month;
9123 inst.selectedYear = inst.currentYear = year;
9124 this._selectDate(id, this._formatDate(inst,
9125 inst.currentDay, inst.currentMonth, inst.currentYear));
9126 },
9127
9128 /* Erase the input field and hide the date picker. */
9129 _clearDate: function(id) {
9130 var target = $(id);
9131 var inst = this._getInst(target[0]);
9132 this._selectDate(target, '');
9133 },
9134
9135 /* Update the input field with the selected date. */
9136 _selectDate: function(id, dateStr) {
9137 var target = $(id);
9138 var inst = this._getInst(target[0]);
9139 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9140 if (inst.input)
9141 inst.input.val(dateStr);
9142 this._updateAlternate(inst);
9143 var onSelect = this._get(inst, 'onSelect');
9144 if (onSelect)
9145 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
9146 else if (inst.input)
9147 inst.input.trigger('change'); // fire the change event
9148 if (inst.inline)
9149 this._updateDatepicker(inst);
9150 else {
9151 this._hideDatepicker();
9152 this._lastInput = inst.input[0];
9153 if (typeof(inst.input[0]) != 'object')
9154 inst.input.focus(); // restore focus
9155 this._lastInput = null;
9156 }
9157 },
9158
9159 /* Update any alternate field to synchronise with the main field. */
9160 _updateAlternate: function(inst) {
9161 var altField = this._get(inst, 'altField');
9162 if (altField) { // update alternate field too
9163 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
9164 var date = this._getDate(inst);
9165 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9166 $(altField).each(function() { $(this).val(dateStr); });
9167 }
9168 },
9169
9170 /* Set as beforeShowDay function to prevent selection of weekends.
9171 @param date Date - the date to customise
9172 @return [boolean, string] - is this date selectable?, what is its CSS class? */
9173 noWeekends: function(date) {
9174 var day = date.getDay();
9175 return [(day > 0 && day < 6), ''];
9176 },
9177
9178 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9179 @param date Date - the date to get the week for
9180 @return number - the number of the week within the year that contains this date */
9181 iso8601Week: function(date) {
9182 var checkDate = new Date(date.getTime());
9183 // Find Thursday of this week starting on Monday
9184 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9185 var time = checkDate.getTime();
9186 checkDate.setMonth(0); // Compare with Jan 1
9187 checkDate.setDate(1);
9188 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9189 },
9190
9191 /* Parse a string value into a date object.
9192 See formatDate below for the possible formats.
9193
9194 @param format string - the expected format of the date
9195 @param value string - the date in the above format
9196 @param settings Object - attributes include:
9197 shortYearCutoff number - the cutoff year for determining the century (optional)
9198 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9199 dayNames string[7] - names of the days from Sunday (optional)
9200 monthNamesShort string[12] - abbreviated names of the months (optional)
9201 monthNames string[12] - names of the months (optional)
9202 @return Date - the extracted date value or null if value is blank */
9203 parseDate: function (format, value, settings) {
9204 if (format == null || value == null)
9205 throw 'Invalid arguments';
9206 value = (typeof value == 'object' ? value.toString() : value + '');
9207 if (value == '')
9208 return null;
9209 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
9210 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9211 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9212 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9213 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9214 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9215 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9216 var year = -1;
9217 var month = -1;
9218 var day = -1;
9219 var doy = -1;
9220 var literal = false;
9221 // Check whether a format character is doubled
9222 var lookAhead = function(match) {
9223 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9224 if (matches)
9225 iFormat++;
9226 return matches;
9227 };
9228 // Extract a number from the string value
9229 var getNumber = function(match) {
9230 var isDoubled = lookAhead(match);
9231 var size = (match == '@' ? 14 : (match == '!' ? 20 :
9232 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
9233 var digits = new RegExp('^\\d{1,' + size + '}');
9234 var num = value.substring(iValue).match(digits);
9235 if (!num)
9236 throw 'Missing number at position ' + iValue;
9237 iValue += num[0].length;
9238 return parseInt(num[0], 10);
9239 };
9240 // Extract a name from the string value and convert to an index
9241 var getName = function(match, shortNames, longNames) {
9242 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9243 return [ [k, v] ];
9244 }).sort(function (a, b) {
9245 return -(a[1].length - b[1].length);
9246 });
9247 var index = -1;
9248 $.each(names, function (i, pair) {
9249 var name = pair[1];
9250 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
9251 index = pair[0];
9252 iValue += name.length;
9253 return false;
9254 }
9255 });
9256 if (index != -1)
9257 return index + 1;
9258 else
9259 throw 'Unknown name at position ' + iValue;
9260 };
9261 // Confirm that a literal character matches the string value
9262 var checkLiteral = function() {
9263 if (value.charAt(iValue) != format.charAt(iFormat))
9264 throw 'Unexpected literal at position ' + iValue;
9265 iValue++;
9266 };
9267 var iValue = 0;
9268 for (var iFormat = 0; iFormat < format.length; iFormat++) {
9269 if (literal)
9270 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9271 literal = false;
9272 else
9273 checkLiteral();
9274 else
9275 switch (format.charAt(iFormat)) {
9276 case 'd':
9277 day = getNumber('d');
9278 break;
9279 case 'D':
9280 getName('D', dayNamesShort, dayNames);
9281 break;
9282 case 'o':
9283 doy = getNumber('o');
9284 break;
9285 case 'm':
9286 month = getNumber('m');
9287 break;
9288 case 'M':
9289 month = getName('M', monthNamesShort, monthNames);
9290 break;
9291 case 'y':
9292 year = getNumber('y');
9293 break;
9294 case '@':
9295 var date = new Date(getNumber('@'));
9296 year = date.getFullYear();
9297 month = date.getMonth() + 1;
9298 day = date.getDate();
9299 break;
9300 case '!':
9301 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
9302 year = date.getFullYear();
9303 month = date.getMonth() + 1;
9304 day = date.getDate();
9305 break;
9306 case "'":
9307 if (lookAhead("'"))
9308 checkLiteral();
9309 else
9310 literal = true;
9311 break;
9312 default:
9313 checkLiteral();
9314 }
9315 }
9316 if (iValue < value.length){
9317 throw "Extra/unparsed characters found in date: " + value.substring(iValue);
9318 }
9319 if (year == -1)
9320 year = new Date().getFullYear();
9321 else if (year < 100)
9322 year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9323 (year <= shortYearCutoff ? 0 : -100);
9324 if (doy > -1) {
9325 month = 1;
9326 day = doy;
9327 do {
9328 var dim = this._getDaysInMonth(year, month - 1);
9329 if (day <= dim)
9330 break;
9331 month++;
9332 day -= dim;
9333 } while (true);
9334 }
9335 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9336 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
9337 throw 'Invalid date'; // E.g. 31/02/00
9338 return date;
9339 },
9340
9341 /* Standard date formats. */
9342 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
9343 COOKIE: 'D, dd M yy',
9344 ISO_8601: 'yy-mm-dd',
9345 RFC_822: 'D, d M y',
9346 RFC_850: 'DD, dd-M-y',
9347 RFC_1036: 'D, d M y',
9348 RFC_1123: 'D, d M yy',
9349 RFC_2822: 'D, d M yy',
9350 RSS: 'D, d M y', // RFC 822
9351 TICKS: '!',
9352 TIMESTAMP: '@',
9353 W3C: 'yy-mm-dd', // ISO 8601
9354
9355 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9356 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9357
9358 /* Format a date object into a string value.
9359 The format can be combinations of the following:
9360 d - day of month (no leading zero)
9361 dd - day of month (two digit)
9362 o - day of year (no leading zeros)
9363 oo - day of year (three digit)
9364 D - day name short
9365 DD - day name long
9366 m - month of year (no leading zero)
9367 mm - month of year (two digit)
9368 M - month name short
9369 MM - month name long
9370 y - year (two digit)
9371 yy - year (four digit)
9372 @ - Unix timestamp (ms since 01/01/1970)
9373 ! - Windows ticks (100ns since 01/01/0001)
9374 '...' - literal text
9375 '' - single quote
9376
9377 @param format string - the desired format of the date
9378 @param date Date - the date value to format
9379 @param settings Object - attributes include:
9380 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9381 dayNames string[7] - names of the days from Sunday (optional)
9382 monthNamesShort string[12] - abbreviated names of the months (optional)
9383 monthNames string[12] - names of the months (optional)
9384 @return string - the date in the above format */
9385 formatDate: function (format, date, settings) {
9386 if (!date)
9387 return '';
9388 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9389 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9390 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9391 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9392 // Check whether a format character is doubled
9393 var lookAhead = function(match) {
9394 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9395 if (matches)
9396 iFormat++;
9397 return matches;
9398 };
9399 // Format a number, with leading zero if necessary
9400 var formatNumber = function(match, value, len) {
9401 var num = '' + value;
9402 if (lookAhead(match))
9403 while (num.length < len)
9404 num = '0' + num;
9405 return num;
9406 };
9407 // Format a name, short or long as requested
9408 var formatName = function(match, value, shortNames, longNames) {
9409 return (lookAhead(match) ? longNames[value] : shortNames[value]);
9410 };
9411 var output = '';
9412 var literal = false;
9413 if (date)
9414 for (var iFormat = 0; iFormat < format.length; iFormat++) {
9415 if (literal)
9416 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9417 literal = false;
9418 else
9419 output += format.charAt(iFormat);
9420 else
9421 switch (format.charAt(iFormat)) {
9422 case 'd':
9423 output += formatNumber('d', date.getDate(), 2);
9424 break;
9425 case 'D':
9426 output += formatName('D', date.getDay(), dayNamesShort, dayNames);
9427 break;
9428 case 'o':
9429 output += formatNumber('o',
9430 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9431 break;
9432 case 'm':
9433 output += formatNumber('m', date.getMonth() + 1, 2);
9434 break;
9435 case 'M':
9436 output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
9437 break;
9438 case 'y':
9439 output += (lookAhead('y') ? date.getFullYear() :
9440 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
9441 break;
9442 case '@':
9443 output += date.getTime();
9444 break;
9445 case '!':
9446 output += date.getTime() * 10000 + this._ticksTo1970;
9447 break;
9448 case "'":
9449 if (lookAhead("'"))
9450 output += "'";
9451 else
9452 literal = true;
9453 break;
9454 default:
9455 output += format.charAt(iFormat);
9456 }
9457 }
9458 return output;
9459 },
9460
9461 /* Extract all possible characters from the date format. */
9462 _possibleChars: function (format) {
9463 var chars = '';
9464 var literal = false;
9465 // Check whether a format character is doubled
9466 var lookAhead = function(match) {
9467 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9468 if (matches)
9469 iFormat++;
9470 return matches;
9471 };
9472 for (var iFormat = 0; iFormat < format.length; iFormat++)
9473 if (literal)
9474 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9475 literal = false;
9476 else
9477 chars += format.charAt(iFormat);
9478 else
9479 switch (format.charAt(iFormat)) {
9480 case 'd': case 'm': case 'y': case '@':
9481 chars += '0123456789';
9482 break;
9483 case 'D': case 'M':
9484 return null; // Accept anything
9485 case "'":
9486 if (lookAhead("'"))
9487 chars += "'";
9488 else
9489 literal = true;
9490 break;
9491 default:
9492 chars += format.charAt(iFormat);
9493 }
9494 return chars;
9495 },
9496
9497 /* Get a setting value, defaulting if necessary. */
9498 _get: function(inst, name) {
9499 return inst.settings[name] !== undefined ?
9500 inst.settings[name] : this._defaults[name];
9501 },
9502
9503 /* Parse existing date and initialise date picker. */
9504 _setDateFromField: function(inst, noDefault) {
9505 if (inst.input.val() == inst.lastVal) {
9506 return;
9507 }
9508 var dateFormat = this._get(inst, 'dateFormat');
9509 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
9510 var date, defaultDate;
9511 date = defaultDate = this._getDefaultDate(inst);
9512 var settings = this._getFormatConfig(inst);
9513 try {
9514 date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9515 } catch (event) {
9516 this.log(event);
9517 dates = (noDefault ? '' : dates);
9518 }
9519 inst.selectedDay = date.getDate();
9520 inst.drawMonth = inst.selectedMonth = date.getMonth();
9521 inst.drawYear = inst.selectedYear = date.getFullYear();
9522 inst.currentDay = (dates ? date.getDate() : 0);
9523 inst.currentMonth = (dates ? date.getMonth() : 0);
9524 inst.currentYear = (dates ? date.getFullYear() : 0);
9525 this._adjustInstDate(inst);
9526 },
9527
9528 /* Retrieve the default date shown on opening. */
9529 _getDefaultDate: function(inst) {
9530 return this._restrictMinMax(inst,
9531 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
9532 },
9533
9534 /* A date may be specified as an exact value or a relative one. */
9535 _determineDate: function(inst, date, defaultDate) {
9536 var offsetNumeric = function(offset) {
9537 var date = new Date();
9538 date.setDate(date.getDate() + offset);
9539 return date;
9540 };
9541 var offsetString = function(offset) {
9542 try {
9543 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
9544 offset, $.datepicker._getFormatConfig(inst));
9545 }
9546 catch (e) {
9547 // Ignore
9548 }
9549 var date = (offset.toLowerCase().match(/^c/) ?
9550 $.datepicker._getDate(inst) : null) || new Date();
9551 var year = date.getFullYear();
9552 var month = date.getMonth();
9553 var day = date.getDate();
9554 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
9555 var matches = pattern.exec(offset);
9556 while (matches) {
9557 switch (matches[2] || 'd') {
9558 case 'd' : case 'D' :
9559 day += parseInt(matches[1],10); break;
9560 case 'w' : case 'W' :
9561 day += parseInt(matches[1],10) * 7; break;
9562 case 'm' : case 'M' :
9563 month += parseInt(matches[1],10);
9564 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9565 break;
9566 case 'y': case 'Y' :
9567 year += parseInt(matches[1],10);
9568 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9569 break;
9570 }
9571 matches = pattern.exec(offset);
9572 }
9573 return new Date(year, month, day);
9574 };
9575 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
9576 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9577 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
9578 if (newDate) {
9579 newDate.setHours(0);
9580 newDate.setMinutes(0);
9581 newDate.setSeconds(0);
9582 newDate.setMilliseconds(0);
9583 }
9584 return this._daylightSavingAdjust(newDate);
9585 },
9586
9587 /* Handle switch to/from daylight saving.
9588 Hours may be non-zero on daylight saving cut-over:
9589 > 12 when midnight changeover, but then cannot generate
9590 midnight datetime, so jump to 1AM, otherwise reset.
9591 @param date (Date) the date to check
9592 @return (Date) the corrected date */
9593 _daylightSavingAdjust: function(date) {
9594 if (!date) return null;
9595 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9596 return date;
9597 },
9598
9599 /* Set the date(s) directly. */
9600 _setDate: function(inst, date, noChange) {
9601 var clear = !date;
9602 var origMonth = inst.selectedMonth;
9603 var origYear = inst.selectedYear;
9604 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9605 inst.selectedDay = inst.currentDay = newDate.getDate();
9606 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9607 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9608 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
9609 this._notifyChange(inst);
9610 this._adjustInstDate(inst);
9611 if (inst.input) {
9612 inst.input.val(clear ? '' : this._formatDate(inst));
9613 }
9614 },
9615
9616 /* Retrieve the date(s) directly. */
9617 _getDate: function(inst) {
9618 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
9619 this._daylightSavingAdjust(new Date(
9620 inst.currentYear, inst.currentMonth, inst.currentDay)));
9621 return startDate;
9622 },
9623
9624 /* Generate the HTML for the current state of the date picker. */
9625 _generateHTML: function(inst) {
9626 var today = new Date();
9627 today = this._daylightSavingAdjust(
9628 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
9629 var isRTL = this._get(inst, 'isRTL');
9630 var showButtonPanel = this._get(inst, 'showButtonPanel');
9631 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
9632 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
9633 var numMonths = this._getNumberOfMonths(inst);
9634 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
9635 var stepMonths = this._get(inst, 'stepMonths');
9636 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
9637 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9638 new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9639 var minDate = this._getMinMaxDate(inst, 'min');
9640 var maxDate = this._getMinMaxDate(inst, 'max');
9641 var drawMonth = inst.drawMonth - showCurrentAtPos;
9642 var drawYear = inst.drawYear;
9643 if (drawMonth < 0) {
9644 drawMonth += 12;
9645 drawYear--;
9646 }
9647 if (maxDate) {
9648 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9649 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9650 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9651 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9652 drawMonth--;
9653 if (drawMonth < 0) {
9654 drawMonth = 11;
9655 drawYear--;
9656 }
9657 }
9658 }
9659 inst.drawMonth = drawMonth;
9660 inst.drawYear = drawYear;
9661 var prevText = this._get(inst, 'prevText');
9662 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9663 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9664 this._getFormatConfig(inst)));
9665 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9666 '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9667 '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
9668 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
9669 (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
9670 var nextText = this._get(inst, 'nextText');
9671 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9672 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9673 this._getFormatConfig(inst)));
9674 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9675 '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9676 '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
9677 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
9678 (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
9679 var currentText = this._get(inst, 'currentText');
9680 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
9681 currentText = (!navigationAsDateFormat ? currentText :
9682 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9683 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9684 '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
9685 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
9686 (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9687 '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
9688 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
9689 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
9690 firstDay = (isNaN(firstDay) ? 0 : firstDay);
9691 var showWeek = this._get(inst, 'showWeek');
9692 var dayNames = this._get(inst, 'dayNames');
9693 var dayNamesShort = this._get(inst, 'dayNamesShort');
9694 var dayNamesMin = this._get(inst, 'dayNamesMin');
9695 var monthNames = this._get(inst, 'monthNames');
9696 var monthNamesShort = this._get(inst, 'monthNamesShort');
9697 var beforeShowDay = this._get(inst, 'beforeShowDay');
9698 var showOtherMonths = this._get(inst, 'showOtherMonths');
9699 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
9700 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
9701 var defaultDate = this._getDefaultDate(inst);
9702 var html = '';
9703 for (var row = 0; row < numMonths[0]; row++) {
9704 var group = '';
9705 this.maxRows = 4;
9706 for (var col = 0; col < numMonths[1]; col++) {
9707 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9708 var cornerClass = ' ui-corner-all';
9709 var calender = '';
9710 if (isMultiMonth) {
9711 calender += '<div class="ui-datepicker-group';
9712 if (numMonths[1] > 1)
9713 switch (col) {
9714 case 0: calender += ' ui-datepicker-group-first';
9715 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
9716 case numMonths[1]-1: calender += ' ui-datepicker-group-last';
9717 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
9718 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
9719 }
9720 calender += '">';
9721 }
9722 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
9723 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
9724 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
9725 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9726 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9727 '</div><table class="ui-datepicker-calendar"><thead>' +
9728 '<tr>';
9729 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
9730 for (var dow = 0; dow < 7; dow++) { // days of the week
9731 var day = (dow + firstDay) % 7;
9732 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
9733 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
9734 }
9735 calender += thead + '</tr></thead><tbody>';
9736 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9737 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
9738 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9739 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9740 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9741 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9742 this.maxRows = numRows;
9743 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9744 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9745 calender += '<tr>';
9746 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
9747 this._get(inst, 'calculateWeek')(printDate) + '</td>');
9748 for (var dow = 0; dow < 7; dow++) { // create date picker days
9749 var daySettings = (beforeShowDay ?
9750 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
9751 var otherMonth = (printDate.getMonth() != drawMonth);
9752 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9753 (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9754 tbody += '<td class="' +
9755 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
9756 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
9757 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
9758 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
9759 // or defaultDate is current printedDate and defaultDate is selectedDate
9760 ' ' + this._dayOverClass : '') + // highlight selected day
9761 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
9762 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
9763 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
9764 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
9765 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
9766 (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
9767 inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
9768 (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
9769 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
9770 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
9771 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
9772 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
9773 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
9774 printDate.setDate(printDate.getDate() + 1);
9775 printDate = this._daylightSavingAdjust(printDate);
9776 }
9777 calender += tbody + '</tr>';
9778 }
9779 drawMonth++;
9780 if (drawMonth > 11) {
9781 drawMonth = 0;
9782 drawYear++;
9783 }
9784 calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
9785 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
9786 group += calender;
9787 }
9788 html += group;
9789 }
9790 html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
9791 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
9792 inst._keyEvent = false;
9793 return html;
9794 },
9795
9796 /* Generate the month and year header. */
9797 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9798 secondary, monthNames, monthNamesShort) {
9799 var changeMonth = this._get(inst, 'changeMonth');
9800 var changeYear = this._get(inst, 'changeYear');
9801 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
9802 var html = '<div class="ui-datepicker-title">';
9803 var monthHtml = '';
9804 // month selection
9805 if (secondary || !changeMonth)
9806 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
9807 else {
9808 var inMinYear = (minDate && minDate.getFullYear() == drawYear);
9809 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
9810 monthHtml += '<select class="ui-datepicker-month" ' +
9811 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
9812 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
9813 '>';
9814 for (var month = 0; month < 12; month++) {
9815 if ((!inMinYear || month >= minDate.getMonth()) &&
9816 (!inMaxYear || month <= maxDate.getMonth()))
9817 monthHtml += '<option value="' + month + '"' +
9818 (month == drawMonth ? ' selected="selected"' : '') +
9819 '>' + monthNamesShort[month] + '</option>';
9820 }
9821 monthHtml += '</select>';
9822 }
9823 if (!showMonthAfterYear)
9824 html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
9825 // year selection
9826 if ( !inst.yearshtml ) {
9827 inst.yearshtml = '';
9828 if (secondary || !changeYear)
9829 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
9830 else {
9831 // determine range of years to display
9832 var years = this._get(inst, 'yearRange').split(':');
9833 var thisYear = new Date().getFullYear();
9834 var determineYear = function(value) {
9835 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9836 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
9837 parseInt(value, 10)));
9838 return (isNaN(year) ? thisYear : year);
9839 };
9840 var year = determineYear(years[0]);
9841 var endYear = Math.max(year, determineYear(years[1] || ''));
9842 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9843 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9844 inst.yearshtml += '<select class="ui-datepicker-year" ' +
9845 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
9846 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
9847 '>';
9848 for (; year <= endYear; year++) {
9849 inst.yearshtml += '<option value="' + year + '"' +
9850 (year == drawYear ? ' selected="selected"' : '') +
9851 '>' + year + '</option>';
9852 }
9853 inst.yearshtml += '</select>';
9854
9855 html += inst.yearshtml;
9856 inst.yearshtml = null;
9857 }
9858 }
9859 html += this._get(inst, 'yearSuffix');
9860 if (showMonthAfterYear)
9861 html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
9862 html += '</div>'; // Close datepicker_header
9863 return html;
9864 },
9865
9866 /* Adjust one of the date sub-fields. */
9867 _adjustInstDate: function(inst, offset, period) {
9868 var year = inst.drawYear + (period == 'Y' ? offset : 0);
9869 var month = inst.drawMonth + (period == 'M' ? offset : 0);
9870 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
9871 (period == 'D' ? offset : 0);
9872 var date = this._restrictMinMax(inst,
9873 this._daylightSavingAdjust(new Date(year, month, day)));
9874 inst.selectedDay = date.getDate();
9875 inst.drawMonth = inst.selectedMonth = date.getMonth();
9876 inst.drawYear = inst.selectedYear = date.getFullYear();
9877 if (period == 'M' || period == 'Y')
9878 this._notifyChange(inst);
9879 },
9880
9881 /* Ensure a date is within any min/max bounds. */
9882 _restrictMinMax: function(inst, date) {
9883 var minDate = this._getMinMaxDate(inst, 'min');
9884 var maxDate = this._getMinMaxDate(inst, 'max');
9885 var newDate = (minDate && date < minDate ? minDate : date);
9886 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
9887 return newDate;
9888 },
9889
9890 /* Notify change of month/year. */
9891 _notifyChange: function(inst) {
9892 var onChange = this._get(inst, 'onChangeMonthYear');
9893 if (onChange)
9894 onChange.apply((inst.input ? inst.input[0] : null),
9895 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9896 },
9897
9898 /* Determine the number of months to show. */
9899 _getNumberOfMonths: function(inst) {
9900 var numMonths = this._get(inst, 'numberOfMonths');
9901 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
9902 },
9903
9904 /* Determine the current maximum date - ensure no time components are set. */
9905 _getMinMaxDate: function(inst, minMax) {
9906 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
9907 },
9908
9909 /* Find the number of days in a given month. */
9910 _getDaysInMonth: function(year, month) {
9911 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9912 },
9913
9914 /* Find the day of the week of the first of a month. */
9915 _getFirstDayOfMonth: function(year, month) {
9916 return new Date(year, month, 1).getDay();
9917 },
9918
9919 /* Determines if we should allow a "next/prev" month display change. */
9920 _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9921 var numMonths = this._getNumberOfMonths(inst);
9922 var date = this._daylightSavingAdjust(new Date(curYear,
9923 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9924 if (offset < 0)
9925 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9926 return this._isInRange(inst, date);
9927 },
9928
9929 /* Is the given date in the accepted range? */
9930 _isInRange: function(inst, date) {
9931 var minDate = this._getMinMaxDate(inst, 'min');
9932 var maxDate = this._getMinMaxDate(inst, 'max');
9933 return ((!minDate || date.getTime() >= minDate.getTime()) &&
9934 (!maxDate || date.getTime() <= maxDate.getTime()));
9935 },
9936
9937 /* Provide the configuration settings for formatting/parsing. */
9938 _getFormatConfig: function(inst) {
9939 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
9940 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9941 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9942 return {shortYearCutoff: shortYearCutoff,
9943 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
9944 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
9945 },
9946
9947 /* Format the given date for display. */
9948 _formatDate: function(inst, day, month, year) {
9949 if (!day) {
9950 inst.currentDay = inst.selectedDay;
9951 inst.currentMonth = inst.selectedMonth;
9952 inst.currentYear = inst.selectedYear;
9953 }
9954 var date = (day ? (typeof day == 'object' ? day :
9955 this._daylightSavingAdjust(new Date(year, month, day))) :
9956 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9957 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
9958 }
9959 });
9960
9961 /*
9962 * Bind hover events for datepicker elements.
9963 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9964 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9965 */
9966 function bindHover(dpDiv) {
9967 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
9968 return dpDiv.bind('mouseout', function(event) {
9969 var elem = $( event.target ).closest( selector );
9970 if ( !elem.length ) {
9971 return;
9972 }
9973 elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
9974 })
9975 .bind('mouseover', function(event) {
9976 var elem = $( event.target ).closest( selector );
9977 if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
9978 !elem.length ) {
9979 return;
9980 }
9981 elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
9982 elem.addClass('ui-state-hover');
9983 if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
9984 if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
9985 });
9986 }
9987
9988 /* jQuery extend now ignores nulls! */
9989 function extendRemove(target, props) {
9990 $.extend(target, props);
9991 for (var name in props)
9992 if (props[name] == null || props[name] == undefined)
9993 target[name] = props[name];
9994 return target;
9995 };
9996
9997 /* Determine whether an object is an array. */
9998 function isArray(a) {
9999 return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
10000 (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
10001 };
10002
10003 /* Invoke the datepicker functionality.
10004 @param options string - a command, optionally followed by additional parameters or
10005 Object - settings for attaching new datepicker functionality
10006 @return jQuery object */
10007 $.fn.datepicker = function(options){
10008
10009 /* Verify an empty collection wasn't passed - Fixes #6976 */
10010 if ( !this.length ) {
10011 return this;
10012 }
10013
10014 /* Initialise the date picker. */
10015 if (!$.datepicker.initialized) {
10016 $(document).mousedown($.datepicker._checkExternalClick).
10017 find('body').append($.datepicker.dpDiv);
10018 $.datepicker.initialized = true;
10019 }
10020
10021 var otherArgs = Array.prototype.slice.call(arguments, 1);
10022 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
10023 return $.datepicker['_' + options + 'Datepicker'].
10024 apply($.datepicker, [this[0]].concat(otherArgs));
10025 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
10026 return $.datepicker['_' + options + 'Datepicker'].
10027 apply($.datepicker, [this[0]].concat(otherArgs));
10028 return this.each(function() {
10029 typeof options == 'string' ?
10030 $.datepicker['_' + options + 'Datepicker'].
10031 apply($.datepicker, [this].concat(otherArgs)) :
10032 $.datepicker._attachDatepicker(this, options);
10033 });
10034 };
10035
10036 $.datepicker = new Datepicker(); // singleton instance
10037 $.datepicker.initialized = false;
10038 $.datepicker.uuid = new Date().getTime();
10039 $.datepicker.version = "1.8.14";
10040
10041 // Workaround for #4055
10042 // Add another global to avoid noConflict issues with inline event handlers
10043 window['DP_jQuery_' + dpuuid] = $;
10044
10045 })(jQuery);
10046 /*
10047 * jQuery UI Progressbar 1.8.14
10048 *
10049 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10050 * Dual licensed under the MIT or GPL Version 2 licenses.
10051 * http://jquery.org/license
10052 *
10053 * http://docs.jquery.com/UI/Progressbar
10054 *
10055 * Depends:
10056 * jquery.ui.core.js
10057 * jquery.ui.widget.js
10058 */
10059 (function( $, undefined ) {
10060
10061 $.widget( "ui.progressbar", {
10062 options: {
10063 value: 0,
10064 max: 100
10065 },
10066
10067 min: 0,
10068
10069 _create: function() {
10070 this.element
10071 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10072 .attr({
10073 role: "progressbar",
10074 "aria-valuemin": this.min,
10075 "aria-valuemax": this.options.max,
10076 "aria-valuenow": this._value()
10077 });
10078
10079 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10080 .appendTo( this.element );
10081
10082 this.oldValue = this._value();
10083 this._refreshValue();
10084 },
10085
10086 destroy: function() {
10087 this.element
10088 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10089 .removeAttr( "role" )
10090 .removeAttr( "aria-valuemin" )
10091 .removeAttr( "aria-valuemax" )
10092 .removeAttr( "aria-valuenow" );
10093
10094 this.valueDiv.remove();
10095
10096 $.Widget.prototype.destroy.apply( this, arguments );
10097 },
10098
10099 value: function( newValue ) {
10100 if ( newValue === undefined ) {
10101 return this._value();
10102 }
10103
10104 this._setOption( "value", newValue );
10105 return this;
10106 },
10107
10108 _setOption: function( key, value ) {
10109 if ( key === "value" ) {
10110 this.options.value = value;
10111 this._refreshValue();
10112 if ( this._value() === this.options.max ) {
10113 this._trigger( "complete" );
10114 }
10115 }
10116
10117 $.Widget.prototype._setOption.apply( this, arguments );
10118 },
10119
10120 _value: function() {
10121 var val = this.options.value;
10122 // normalize invalid value
10123 if ( typeof val !== "number" ) {
10124 val = 0;
10125 }
10126 return Math.min( this.options.max, Math.max( this.min, val ) );
10127 },
10128
10129 _percentage: function() {
10130 return 100 * this._value() / this.options.max;
10131 },
10132
10133 _refreshValue: function() {
10134 var value = this.value();
10135 var percentage = this._percentage();
10136
10137 if ( this.oldValue !== value ) {
10138 this.oldValue = value;
10139 this._trigger( "change" );
10140 }
10141
10142 this.valueDiv
10143 .toggle( value > this.min )
10144 .toggleClass( "ui-corner-right", value === this.options.max )
10145 .width( percentage.toFixed(0) + "%" );
10146 this.element.attr( "aria-valuenow", value );
10147 }
10148 });
10149
10150 $.extend( $.ui.progressbar, {
10151 version: "1.8.14"
10152 });
10153
10154 })( jQuery );
10155 /*
10156 * jQuery UI Effects 1.8.14
10157 *
10158 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10159 * Dual licensed under the MIT or GPL Version 2 licenses.
10160 * http://jquery.org/license
10161 *
10162 * http://docs.jquery.com/UI/Effects/
10163 */
10164 ;jQuery.effects || (function($, undefined) {
10165
10166 $.effects = {};
10167
10168
10169
10170 /******************************************************************************/
10171 /****************************** COLOR ANIMATIONS ******************************/
10172 /******************************************************************************/
10173
10174 // override the animation for color styles
10175 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
10176 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
10177 function(i, attr) {
10178 $.fx.step[attr] = function(fx) {
10179 if (!fx.colorInit) {
10180 fx.start = getColor(fx.elem, attr);
10181 fx.end = getRGB(fx.end);
10182 fx.colorInit = true;
10183 }
10184
10185 fx.elem.style[attr] = 'rgb(' +
10186 Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
10187 Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
10188 Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
10189 };
10190 });
10191
10192 // Color Conversion functions from highlightFade
10193 // By Blair Mitchelmore
10194 // http://jquery.offput.ca/highlightFade/
10195
10196 // Parse strings looking for color tuples [255,255,255]
10197 function getRGB(color) {
10198 var result;
10199
10200 // Check if we're already dealing with an array of colors
10201 if ( color && color.constructor == Array && color.length == 3 )
10202 return color;
10203
10204 // Look for rgb(num,num,num)
10205 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
10206 return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
10207
10208 // Look for rgb(num%,num%,num%)
10209 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
10210 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
10211
10212 // Look for #a0b1c2
10213 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
10214 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
10215
10216 // Look for #fff
10217 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
10218 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
10219
10220 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
10221 if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
10222 return colors['transparent'];
10223
10224 // Otherwise, we're most likely dealing with a named color
10225 return colors[$.trim(color).toLowerCase()];
10226 }
10227
10228 function getColor(elem, attr) {
10229 var color;
10230
10231 do {
10232 color = $.curCSS(elem, attr);
10233
10234 // Keep going until we find an element that has color, or we hit the body
10235 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
10236 break;
10237
10238 attr = "backgroundColor";
10239 } while ( elem = elem.parentNode );
10240
10241 return getRGB(color);
10242 };
10243
10244 // Some named colors to work with
10245 // From Interface by Stefan Petre
10246 // http://interface.eyecon.ro/
10247
10248 var colors = {
10249 aqua:[0,255,255],
10250 azure:[240,255,255],
10251 beige:[245,245,220],
10252 black:[0,0,0],
10253 blue:[0,0,255],
10254 brown:[165,42,42],
10255 cyan:[0,255,255],
10256 darkblue:[0,0,139],
10257 darkcyan:[0,139,139],
10258 darkgrey:[169,169,169],
10259 darkgreen:[0,100,0],
10260 darkkhaki:[189,183,107],
10261 darkmagenta:[139,0,139],
10262 darkolivegreen:[85,107,47],
10263 darkorange:[255,140,0],
10264 darkorchid:[153,50,204],
10265 darkred:[139,0,0],
10266 darksalmon:[233,150,122],
10267 darkviolet:[148,0,211],
10268 fuchsia:[255,0,255],
10269 gold:[255,215,0],
10270 green:[0,128,0],
10271 indigo:[75,0,130],
10272 khaki:[240,230,140],
10273 lightblue:[173,216,230],
10274 lightcyan:[224,255,255],
10275 lightgreen:[144,238,144],
10276 lightgrey:[211,211,211],
10277 lightpink:[255,182,193],
10278 lightyellow:[255,255,224],
10279 lime:[0,255,0],
10280 magenta:[255,0,255],
10281 maroon:[128,0,0],
10282 navy:[0,0,128],
10283 olive:[128,128,0],
10284 orange:[255,165,0],
10285 pink:[255,192,203],
10286 purple:[128,0,128],
10287 violet:[128,0,128],
10288 red:[255,0,0],
10289 silver:[192,192,192],
10290 white:[255,255,255],
10291 yellow:[255,255,0],
10292 transparent: [255,255,255]
10293 };
10294
10295
10296
10297 /******************************************************************************/
10298 /****************************** CLASS ANIMATIONS ******************************/
10299 /******************************************************************************/
10300
10301 var classAnimationActions = ['add', 'remove', 'toggle'],
10302 shorthandStyles = {
10303 border: 1,
10304 borderBottom: 1,
10305 borderColor: 1,
10306 borderLeft: 1,
10307 borderRight: 1,
10308 borderTop: 1,
10309 borderWidth: 1,
10310 margin: 1,
10311 padding: 1
10312 };
10313
10314 function getElementStyles() {
10315 var style = document.defaultView
10316 ? document.defaultView.getComputedStyle(this, null)
10317 : this.currentStyle,
10318 newStyle = {},
10319 key,
10320 camelCase;
10321
10322 // webkit enumerates style porperties
10323 if (style && style.length && style[0] && style[style[0]]) {
10324 var len = style.length;
10325 while (len--) {
10326 key = style[len];
10327 if (typeof style[key] == 'string') {
10328 camelCase = key.replace(/\-(\w)/g, function(all, letter){
10329 return letter.toUpperCase();
10330 });
10331 newStyle[camelCase] = style[key];
10332 }
10333 }
10334 } else {
10335 for (key in style) {
10336 if (typeof style[key] === 'string') {
10337 newStyle[key] = style[key];
10338 }
10339 }
10340 }
10341
10342 return newStyle;
10343 }
10344
10345 function filterStyles(styles) {
10346 var name, value;
10347 for (name in styles) {
10348 value = styles[name];
10349 if (
10350 // ignore null and undefined values
10351 value == null ||
10352 // ignore functions (when does this occur?)
10353 $.isFunction(value) ||
10354 // shorthand styles that need to be expanded
10355 name in shorthandStyles ||
10356 // ignore scrollbars (break in IE)
10357 (/scrollbar/).test(name) ||
10358
10359 // only colors or values that can be converted to numbers
10360 (!(/color/i).test(name) && isNaN(parseFloat(value)))
10361 ) {
10362 delete styles[name];
10363 }
10364 }
10365
10366 return styles;
10367 }
10368
10369 function styleDifference(oldStyle, newStyle) {
10370 var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
10371 name;
10372
10373 for (name in newStyle) {
10374 if (oldStyle[name] != newStyle[name]) {
10375 diff[name] = newStyle[name];
10376 }
10377 }
10378
10379 return diff;
10380 }
10381
10382 $.effects.animateClass = function(value, duration, easing, callback) {
10383 if ($.isFunction(easing)) {
10384 callback = easing;
10385 easing = null;
10386 }
10387
10388 return this.queue(function() {
10389 var that = $(this),
10390 originalStyleAttr = that.attr('style') || ' ',
10391 originalStyle = filterStyles(getElementStyles.call(this)),
10392 newStyle,
10393 className = that.attr('class');
10394
10395 $.each(classAnimationActions, function(i, action) {
10396 if (value[action]) {
10397 that[action + 'Class'](value[action]);
10398 }
10399 });
10400 newStyle = filterStyles(getElementStyles.call(this));
10401 that.attr('class', className);
10402
10403 that.animate(styleDifference(originalStyle, newStyle), {
10404 queue: false,
10405 duration: duration,
10406 easing: easing,
10407 complete: function() {
10408 $.each(classAnimationActions, function(i, action) {
10409 if (value[action]) { that[action + 'Class'](value[action]); }
10410 });
10411 // work around bug in IE by clearing the cssText before setting it
10412 if (typeof that.attr('style') == 'object') {
10413 that.attr('style').cssText = '';
10414 that.attr('style').cssText = originalStyleAttr;
10415 } else {
10416 that.attr('style', originalStyleAttr);
10417 }
10418 if (callback) { callback.apply(this, arguments); }
10419 $.dequeue( this );
10420 }
10421 });
10422 });
10423 };
10424
10425 $.fn.extend({
10426 _addClass: $.fn.addClass,
10427 addClass: function(classNames, speed, easing, callback) {
10428 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
10429 },
10430
10431 _removeClass: $.fn.removeClass,
10432 removeClass: function(classNames,speed,easing,callback) {
10433 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
10434 },
10435
10436 _toggleClass: $.fn.toggleClass,
10437 toggleClass: function(classNames, force, speed, easing, callback) {
10438 if ( typeof force == "boolean" || force === undefined ) {
10439 if ( !speed ) {
10440 // without speed parameter;
10441 return this._toggleClass(classNames, force);
10442 } else {
10443 return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
10444 }
10445 } else {
10446 // without switch parameter;
10447 return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
10448 }
10449 },
10450
10451 switchClass: function(remove,add,speed,easing,callback) {
10452 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
10453 }
10454 });
10455
10456
10457
10458 /******************************************************************************/
10459 /*********************************** EFFECTS **********************************/
10460 /******************************************************************************/
10461
10462 $.extend($.effects, {
10463 version: "1.8.14",
10464
10465 // Saves a set of properties in a data storage
10466 save: function(element, set) {
10467 for(var i=0; i < set.length; i++) {
10468 if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
10469 }
10470 },
10471
10472 // Restores a set of previously saved properties from a data storage
10473 restore: function(element, set) {
10474 for(var i=0; i < set.length; i++) {
10475 if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
10476 }
10477 },
10478
10479 setMode: function(el, mode) {
10480 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
10481 return mode;
10482 },
10483
10484 getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
10485 // this should be a little more flexible in the future to handle a string & hash
10486 var y, x;
10487 switch (origin[0]) {
10488 case 'top': y = 0; break;
10489 case 'middle': y = 0.5; break;
10490 case 'bottom': y = 1; break;
10491 default: y = origin[0] / original.height;
10492 };
10493 switch (origin[1]) {
10494 case 'left': x = 0; break;
10495 case 'center': x = 0.5; break;
10496 case 'right': x = 1; break;
10497 default: x = origin[1] / original.width;
10498 };
10499 return {x: x, y: y};
10500 },
10501
10502 // Wraps the element around a wrapper that copies position properties
10503 createWrapper: function(element) {
10504
10505 // if the element is already wrapped, return it
10506 if (element.parent().is('.ui-effects-wrapper')) {
10507 return element.parent();
10508 }
10509
10510 // wrap the element
10511 var props = {
10512 width: element.outerWidth(true),
10513 height: element.outerHeight(true),
10514 'float': element.css('float')
10515 },
10516 wrapper = $('<div></div>')
10517 .addClass('ui-effects-wrapper')
10518 .css({
10519 fontSize: '100%',
10520 background: 'transparent',
10521 border: 'none',
10522 margin: 0,
10523 padding: 0
10524 });
10525
10526 element.wrap(wrapper);
10527 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
10528
10529 // transfer positioning properties to the wrapper
10530 if (element.css('position') == 'static') {
10531 wrapper.css({ position: 'relative' });
10532 element.css({ position: 'relative' });
10533 } else {
10534 $.extend(props, {
10535 position: element.css('position'),
10536 zIndex: element.css('z-index')
10537 });
10538 $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
10539 props[pos] = element.css(pos);
10540 if (isNaN(parseInt(props[pos], 10))) {
10541 props[pos] = 'auto';
10542 }
10543 });
10544 element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
10545 }
10546
10547 return wrapper.css(props).show();
10548 },
10549
10550 removeWrapper: function(element) {
10551 if (element.parent().is('.ui-effects-wrapper'))
10552 return element.parent().replaceWith(element);
10553 return element;
10554 },
10555
10556 setTransition: function(element, list, factor, value) {
10557 value = value || {};
10558 $.each(list, function(i, x){
10559 unit = element.cssUnit(x);
10560 if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
10561 });
10562 return value;
10563 }
10564 });
10565
10566
10567 function _normalizeArguments(effect, options, speed, callback) {
10568 // shift params for method overloading
10569 if (typeof effect == 'object') {
10570 callback = options;
10571 speed = null;
10572 options = effect;
10573 effect = options.effect;
10574 }
10575 if ($.isFunction(options)) {
10576 callback = options;
10577 speed = null;
10578 options = {};
10579 }
10580 if (typeof options == 'number' || $.fx.speeds[options]) {
10581 callback = speed;
10582 speed = options;
10583 options = {};
10584 }
10585 if ($.isFunction(speed)) {
10586 callback = speed;
10587 speed = null;
10588 }
10589
10590 options = options || {};
10591
10592 speed = speed || options.duration;
10593 speed = $.fx.off ? 0 : typeof speed == 'number'
10594 ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
10595
10596 callback = callback || options.complete;
10597
10598 return [effect, options, speed, callback];
10599 }
10600
10601 function standardSpeed( speed ) {
10602 // valid standard speeds
10603 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
10604 return true;
10605 }
10606
10607 // invalid strings - treat as "normal" speed
10608 if ( typeof speed === "string" && !$.effects[ speed ] ) {
10609 return true;
10610 }
10611
10612 return false;
10613 }
10614
10615 $.fn.extend({
10616 effect: function(effect, options, speed, callback) {
10617 var args = _normalizeArguments.apply(this, arguments),
10618 // TODO: make effects take actual parameters instead of a hash
10619 args2 = {
10620 options: args[1],
10621 duration: args[2],
10622 callback: args[3]
10623 },
10624 mode = args2.options.mode,
10625 effectMethod = $.effects[effect];
10626
10627 if ( $.fx.off || !effectMethod ) {
10628 // delegate to the original method (e.g., .show()) if possible
10629 if ( mode ) {
10630 return this[ mode ]( args2.duration, args2.callback );
10631 } else {
10632 return this.each(function() {
10633 if ( args2.callback ) {
10634 args2.callback.call( this );
10635 }
10636 });
10637 }
10638 }
10639
10640 return effectMethod.call(this, args2);
10641 },
10642
10643 _show: $.fn.show,
10644 show: function(speed) {
10645 if ( standardSpeed( speed ) ) {
10646 return this._show.apply(this, arguments);
10647 } else {
10648 var args = _normalizeArguments.apply(this, arguments);
10649 args[1].mode = 'show';
10650 return this.effect.apply(this, args);
10651 }
10652 },
10653
10654 _hide: $.fn.hide,
10655 hide: function(speed) {
10656 if ( standardSpeed( speed ) ) {
10657 return this._hide.apply(this, arguments);
10658 } else {
10659 var args = _normalizeArguments.apply(this, arguments);
10660 args[1].mode = 'hide';
10661 return this.effect.apply(this, args);
10662 }
10663 },
10664
10665 // jQuery core overloads toggle and creates _toggle
10666 __toggle: $.fn.toggle,
10667 toggle: function(speed) {
10668 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
10669 return this.__toggle.apply(this, arguments);
10670 } else {
10671 var args = _normalizeArguments.apply(this, arguments);
10672 args[1].mode = 'toggle';
10673 return this.effect.apply(this, args);
10674 }
10675 },
10676
10677 // helper functions
10678 cssUnit: function(key) {
10679 var style = this.css(key), val = [];
10680 $.each( ['em','px','%','pt'], function(i, unit){
10681 if(style.indexOf(unit) > 0)
10682 val = [parseFloat(style), unit];
10683 });
10684 return val;
10685 }
10686 });
10687
10688
10689
10690 /******************************************************************************/
10691 /*********************************** EASING ***********************************/
10692 /******************************************************************************/
10693
10694 /*
10695 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
10696 *
10697 * Uses the built in easing capabilities added In jQuery 1.1
10698 * to offer multiple easing options
10699 *
10700 * TERMS OF USE - jQuery Easing
10701 *
10702 * Open source under the BSD License.
10703 *
10704 * Copyright 2008 George McGinley Smith
10705 * All rights reserved.
10706 *
10707 * Redistribution and use in source and binary forms, with or without modification,
10708 * are permitted provided that the following conditions are met:
10709 *
10710 * Redistributions of source code must retain the above copyright notice, this list of
10711 * conditions and the following disclaimer.
10712 * Redistributions in binary form must reproduce the above copyright notice, this list
10713 * of conditions and the following disclaimer in the documentation and/or other materials
10714 * provided with the distribution.
10715 *
10716 * Neither the name of the author nor the names of contributors may be used to endorse
10717 * or promote products derived from this software without specific prior written permission.
10718 *
10719 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10720 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10721 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10722 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10723 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10724 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10725 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10726 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10727 * OF THE POSSIBILITY OF SUCH DAMAGE.
10728 *
10729 */
10730
10731 // t: current time, b: begInnIng value, c: change In value, d: duration
10732 $.easing.jswing = $.easing.swing;
10733
10734 $.extend($.easing,
10735 {
10736 def: 'easeOutQuad',
10737 swing: function (x, t, b, c, d) {
10738 //alert($.easing.default);
10739 return $.easing[$.easing.def](x, t, b, c, d);
10740 },
10741 easeInQuad: function (x, t, b, c, d) {
10742 return c*(t/=d)*t + b;
10743 },
10744 easeOutQuad: function (x, t, b, c, d) {
10745 return -c *(t/=d)*(t-2) + b;
10746 },
10747 easeInOutQuad: function (x, t, b, c, d) {
10748 if ((t/=d/2) < 1) return c/2*t*t + b;
10749 return -c/2 * ((--t)*(t-2) - 1) + b;
10750 },
10751 easeInCubic: function (x, t, b, c, d) {
10752 return c*(t/=d)*t*t + b;
10753 },
10754 easeOutCubic: function (x, t, b, c, d) {
10755 return c*((t=t/d-1)*t*t + 1) + b;
10756 },
10757 easeInOutCubic: function (x, t, b, c, d) {
10758 if ((t/=d/2) < 1) return c/2*t*t*t + b;
10759 return c/2*((t-=2)*t*t + 2) + b;
10760 },
10761 easeInQuart: function (x, t, b, c, d) {
10762 return c*(t/=d)*t*t*t + b;
10763 },
10764 easeOutQuart: function (x, t, b, c, d) {
10765 return -c * ((t=t/d-1)*t*t*t - 1) + b;
10766 },
10767 easeInOutQuart: function (x, t, b, c, d) {
10768 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
10769 return -c/2 * ((t-=2)*t*t*t - 2) + b;
10770 },
10771 easeInQuint: function (x, t, b, c, d) {
10772 return c*(t/=d)*t*t*t*t + b;
10773 },
10774 easeOutQuint: function (x, t, b, c, d) {
10775 return c*((t=t/d-1)*t*t*t*t + 1) + b;
10776 },
10777 easeInOutQuint: function (x, t, b, c, d) {
10778 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
10779 return c/2*((t-=2)*t*t*t*t + 2) + b;
10780 },
10781 easeInSine: function (x, t, b, c, d) {
10782 return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
10783 },
10784 easeOutSine: function (x, t, b, c, d) {
10785 return c * Math.sin(t/d * (Math.PI/2)) + b;
10786 },
10787 easeInOutSine: function (x, t, b, c, d) {
10788 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
10789 },
10790 easeInExpo: function (x, t, b, c, d) {
10791 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
10792 },
10793 easeOutExpo: function (x, t, b, c, d) {
10794 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
10795 },
10796 easeInOutExpo: function (x, t, b, c, d) {
10797 if (t==0) return b;
10798 if (t==d) return b+c;
10799 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
10800 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
10801 },
10802 easeInCirc: function (x, t, b, c, d) {
10803 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
10804 },
10805 easeOutCirc: function (x, t, b, c, d) {
10806 return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
10807 },
10808 easeInOutCirc: function (x, t, b, c, d) {
10809 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
10810 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
10811 },
10812 easeInElastic: function (x, t, b, c, d) {
10813 var s=1.70158;var p=0;var a=c;
10814 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
10815 if (a < Math.abs(c)) { a=c; var s=p/4; }
10816 else var s = p/(2*Math.PI) * Math.asin (c/a);
10817 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
10818 },
10819 easeOutElastic: function (x, t, b, c, d) {
10820 var s=1.70158;var p=0;var a=c;
10821 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
10822 if (a < Math.abs(c)) { a=c; var s=p/4; }
10823 else var s = p/(2*Math.PI) * Math.asin (c/a);
10824 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
10825 },
10826 easeInOutElastic: function (x, t, b, c, d) {
10827 var s=1.70158;var p=0;var a=c;
10828 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
10829 if (a < Math.abs(c)) { a=c; var s=p/4; }
10830 else var s = p/(2*Math.PI) * Math.asin (c/a);
10831 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
10832 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
10833 },
10834 easeInBack: function (x, t, b, c, d, s) {
10835 if (s == undefined) s = 1.70158;
10836 return c*(t/=d)*t*((s+1)*t - s) + b;
10837 },
10838 easeOutBack: function (x, t, b, c, d, s) {
10839 if (s == undefined) s = 1.70158;
10840 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
10841 },
10842 easeInOutBack: function (x, t, b, c, d, s) {
10843 if (s == undefined) s = 1.70158;
10844 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
10845 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
10846 },
10847 easeInBounce: function (x, t, b, c, d) {
10848 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
10849 },
10850 easeOutBounce: function (x, t, b, c, d) {
10851 if ((t/=d) < (1/2.75)) {
10852 return c*(7.5625*t*t) + b;
10853 } else if (t < (2/2.75)) {
10854 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
10855 } else if (t < (2.5/2.75)) {
10856 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
10857 } else {
10858 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
10859 }
10860 },
10861 easeInOutBounce: function (x, t, b, c, d) {
10862 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
10863 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
10864 }
10865 });
10866
10867 /*
10868 *
10869 * TERMS OF USE - EASING EQUATIONS
10870 *
10871 * Open source under the BSD License.
10872 *
10873 * Copyright 2001 Robert Penner
10874 * All rights reserved.
10875 *
10876 * Redistribution and use in source and binary forms, with or without modification,
10877 * are permitted provided that the following conditions are met:
10878 *
10879 * Redistributions of source code must retain the above copyright notice, this list of
10880 * conditions and the following disclaimer.
10881 * Redistributions in binary form must reproduce the above copyright notice, this list
10882 * of conditions and the following disclaimer in the documentation and/or other materials
10883 * provided with the distribution.
10884 *
10885 * Neither the name of the author nor the names of contributors may be used to endorse
10886 * or promote products derived from this software without specific prior written permission.
10887 *
10888 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10889 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10890 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10891 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10892 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10893 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10894 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10895 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10896 * OF THE POSSIBILITY OF SUCH DAMAGE.
10897 *
10898 */
10899
10900 })(jQuery);
10901 /*
10902 * jQuery UI Effects Blind 1.8.14
10903 *
10904 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10905 * Dual licensed under the MIT or GPL Version 2 licenses.
10906 * http://jquery.org/license
10907 *
10908 * http://docs.jquery.com/UI/Effects/Blind
10909 *
10910 * Depends:
10911 * jquery.effects.core.js
10912 */
10913 (function( $, undefined ) {
10914
10915 $.effects.blind = function(o) {
10916
10917 return this.queue(function() {
10918
10919 // Create element
10920 var el = $(this), props = ['position','top','bottom','left','right'];
10921
10922 // Set options
10923 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
10924 var direction = o.options.direction || 'vertical'; // Default direction
10925
10926 // Adjust
10927 $.effects.save(el, props); el.show(); // Save & Show
10928 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
10929 var ref = (direction == 'vertical') ? 'height' : 'width';
10930 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
10931 if(mode == 'show') wrapper.css(ref, 0); // Shift
10932
10933 // Animation
10934 var animation = {};
10935 animation[ref] = mode == 'show' ? distance : 0;
10936
10937 // Animate
10938 wrapper.animate(animation, o.duration, o.options.easing, function() {
10939 if(mode == 'hide') el.hide(); // Hide
10940 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
10941 if(o.callback) o.callback.apply(el[0], arguments); // Callback
10942 el.dequeue();
10943 });
10944
10945 });
10946
10947 };
10948
10949 })(jQuery);
10950 /*
10951 * jQuery UI Effects Bounce 1.8.14
10952 *
10953 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10954 * Dual licensed under the MIT or GPL Version 2 licenses.
10955 * http://jquery.org/license
10956 *
10957 * http://docs.jquery.com/UI/Effects/Bounce
10958 *
10959 * Depends:
10960 * jquery.effects.core.js
10961 */
10962 (function( $, undefined ) {
10963
10964 $.effects.bounce = function(o) {
10965
10966 return this.queue(function() {
10967
10968 // Create element
10969 var el = $(this), props = ['position','top','bottom','left','right'];
10970
10971 // Set options
10972 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
10973 var direction = o.options.direction || 'up'; // Default direction
10974 var distance = o.options.distance || 20; // Default distance
10975 var times = o.options.times || 5; // Default # of times
10976 var speed = o.duration || 250; // Default speed per bounce
10977 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
10978
10979 // Adjust
10980 $.effects.save(el, props); el.show(); // Save & Show
10981 $.effects.createWrapper(el); // Create Wrapper
10982 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
10983 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
10984 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
10985 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
10986 if (mode == 'hide') distance = distance / (times * 2);
10987 if (mode != 'hide') times--;
10988
10989 // Animate
10990 if (mode == 'show') { // Show Bounce
10991 var animation = {opacity: 1};
10992 animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
10993 el.animate(animation, speed / 2, o.options.easing);
10994 distance = distance / 2;
10995 times--;
10996 };
10997 for (var i = 0; i < times; i++) { // Bounces
10998 var animation1 = {}, animation2 = {};
10999 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11000 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11001 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
11002 distance = (mode == 'hide') ? distance * 2 : distance / 2;
11003 };
11004 if (mode == 'hide') { // Last Bounce
11005 var animation = {opacity: 0};
11006 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11007 el.animate(animation, speed / 2, o.options.easing, function(){
11008 el.hide(); // Hide
11009 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11010 if(o.callback) o.callback.apply(this, arguments); // Callback
11011 });
11012 } else {
11013 var animation1 = {}, animation2 = {};
11014 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11015 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11016 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
11017 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11018 if(o.callback) o.callback.apply(this, arguments); // Callback
11019 });
11020 };
11021 el.queue('fx', function() { el.dequeue(); });
11022 el.dequeue();
11023 });
11024
11025 };
11026
11027 })(jQuery);
11028 /*
11029 * jQuery UI Effects Clip 1.8.14
11030 *
11031 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11032 * Dual licensed under the MIT or GPL Version 2 licenses.
11033 * http://jquery.org/license
11034 *
11035 * http://docs.jquery.com/UI/Effects/Clip
11036 *
11037 * Depends:
11038 * jquery.effects.core.js
11039 */
11040 (function( $, undefined ) {
11041
11042 $.effects.clip = function(o) {
11043
11044 return this.queue(function() {
11045
11046 // Create element
11047 var el = $(this), props = ['position','top','bottom','left','right','height','width'];
11048
11049 // Set options
11050 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11051 var direction = o.options.direction || 'vertical'; // Default direction
11052
11053 // Adjust
11054 $.effects.save(el, props); el.show(); // Save & Show
11055 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11056 var animate = el[0].tagName == 'IMG' ? wrapper : el;
11057 var ref = {
11058 size: (direction == 'vertical') ? 'height' : 'width',
11059 position: (direction == 'vertical') ? 'top' : 'left'
11060 };
11061 var distance = (direction == 'vertical') ? animate.height() : animate.width();
11062 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
11063
11064 // Animation
11065 var animation = {};
11066 animation[ref.size] = mode == 'show' ? distance : 0;
11067 animation[ref.position] = mode == 'show' ? 0 : distance / 2;
11068
11069 // Animate
11070 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11071 if(mode == 'hide') el.hide(); // Hide
11072 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11073 if(o.callback) o.callback.apply(el[0], arguments); // Callback
11074 el.dequeue();
11075 }});
11076
11077 });
11078
11079 };
11080
11081 })(jQuery);
11082 /*
11083 * jQuery UI Effects Drop 1.8.14
11084 *
11085 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11086 * Dual licensed under the MIT or GPL Version 2 licenses.
11087 * http://jquery.org/license
11088 *
11089 * http://docs.jquery.com/UI/Effects/Drop
11090 *
11091 * Depends:
11092 * jquery.effects.core.js
11093 */
11094 (function( $, undefined ) {
11095
11096 $.effects.drop = function(o) {
11097
11098 return this.queue(function() {
11099
11100 // Create element
11101 var el = $(this), props = ['position','top','bottom','left','right','opacity'];
11102
11103 // Set options
11104 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11105 var direction = o.options.direction || 'left'; // Default Direction
11106
11107 // Adjust
11108 $.effects.save(el, props); el.show(); // Save & Show
11109 $.effects.createWrapper(el); // Create Wrapper
11110 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11111 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11112 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
11113 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
11114
11115 // Animation
11116 var animation = {opacity: mode == 'show' ? 1 : 0};
11117 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
11118
11119 // Animate
11120 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11121 if(mode == 'hide') el.hide(); // Hide
11122 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11123 if(o.callback) o.callback.apply(this, arguments); // Callback
11124 el.dequeue();
11125 }});
11126
11127 });
11128
11129 };
11130
11131 })(jQuery);
11132 /*
11133 * jQuery UI Effects Explode 1.8.14
11134 *
11135 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11136 * Dual licensed under the MIT or GPL Version 2 licenses.
11137 * http://jquery.org/license
11138 *
11139 * http://docs.jquery.com/UI/Effects/Explode
11140 *
11141 * Depends:
11142 * jquery.effects.core.js
11143 */
11144 (function( $, undefined ) {
11145
11146 $.effects.explode = function(o) {
11147
11148 return this.queue(function() {
11149
11150 var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
11151 var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
11152
11153 o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
11154 var el = $(this).show().css('visibility', 'hidden');
11155 var offset = el.offset();
11156
11157 //Substract the margins - not fixing the problem yet.
11158 offset.top -= parseInt(el.css("marginTop"),10) || 0;
11159 offset.left -= parseInt(el.css("marginLeft"),10) || 0;
11160
11161 var width = el.outerWidth(true);
11162 var height = el.outerHeight(true);
11163
11164 for(var i=0;i<rows;i++) { // =
11165 for(var j=0;j<cells;j++) { // ||
11166 el
11167 .clone()
11168 .appendTo('body')
11169 .wrap('<div></div>')
11170 .css({
11171 position: 'absolute',
11172 visibility: 'visible',
11173 left: -j*(width/cells),
11174 top: -i*(height/rows)
11175 })
11176 .parent()
11177 .addClass('ui-effects-explode')
11178 .css({
11179 position: 'absolute',
11180 overflow: 'hidden',
11181 width: width/cells,
11182 height: height/rows,
11183 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
11184 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
11185 opacity: o.options.mode == 'show' ? 0 : 1
11186 }).animate({
11187 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
11188 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
11189 opacity: o.options.mode == 'show' ? 1 : 0
11190 }, o.duration || 500);
11191 }
11192 }
11193
11194 // Set a timeout, to call the callback approx. when the other animations have finished
11195 setTimeout(function() {
11196
11197 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
11198 if(o.callback) o.callback.apply(el[0]); // Callback
11199 el.dequeue();
11200
11201 $('div.ui-effects-explode').remove();
11202
11203 }, o.duration || 500);
11204
11205
11206 });
11207
11208 };
11209
11210 })(jQuery);
11211 /*
11212 * jQuery UI Effects Fade 1.8.14
11213 *
11214 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11215 * Dual licensed under the MIT or GPL Version 2 licenses.
11216 * http://jquery.org/license
11217 *
11218 * http://docs.jquery.com/UI/Effects/Fade
11219 *
11220 * Depends:
11221 * jquery.effects.core.js
11222 */
11223 (function( $, undefined ) {
11224
11225 $.effects.fade = function(o) {
11226 return this.queue(function() {
11227 var elem = $(this),
11228 mode = $.effects.setMode(elem, o.options.mode || 'hide');
11229
11230 elem.animate({ opacity: mode }, {
11231 queue: false,
11232 duration: o.duration,
11233 easing: o.options.easing,
11234 complete: function() {
11235 (o.callback && o.callback.apply(this, arguments));
11236 elem.dequeue();
11237 }
11238 });
11239 });
11240 };
11241
11242 })(jQuery);
11243 /*
11244 * jQuery UI Effects Fold 1.8.14
11245 *
11246 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11247 * Dual licensed under the MIT or GPL Version 2 licenses.
11248 * http://jquery.org/license
11249 *
11250 * http://docs.jquery.com/UI/Effects/Fold
11251 *
11252 * Depends:
11253 * jquery.effects.core.js
11254 */
11255 (function( $, undefined ) {
11256
11257 $.effects.fold = function(o) {
11258
11259 return this.queue(function() {
11260
11261 // Create element
11262 var el = $(this), props = ['position','top','bottom','left','right'];
11263
11264 // Set options
11265 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11266 var size = o.options.size || 15; // Default fold size
11267 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
11268 var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
11269
11270 // Adjust
11271 $.effects.save(el, props); el.show(); // Save & Show
11272 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11273 var widthFirst = ((mode == 'show') != horizFirst);
11274 var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
11275 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
11276 var percent = /([0-9]+)%/.exec(size);
11277 if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
11278 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
11279
11280 // Animation
11281 var animation1 = {}, animation2 = {};
11282 animation1[ref[0]] = mode == 'show' ? distance[0] : size;
11283 animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
11284
11285 // Animate
11286 wrapper.animate(animation1, duration, o.options.easing)
11287 .animate(animation2, duration, o.options.easing, function() {
11288 if(mode == 'hide') el.hide(); // Hide
11289 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11290 if(o.callback) o.callback.apply(el[0], arguments); // Callback
11291 el.dequeue();
11292 });
11293
11294 });
11295
11296 };
11297
11298 })(jQuery);
11299 /*
11300 * jQuery UI Effects Highlight 1.8.14
11301 *
11302 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11303 * Dual licensed under the MIT or GPL Version 2 licenses.
11304 * http://jquery.org/license
11305 *
11306 * http://docs.jquery.com/UI/Effects/Highlight
11307 *
11308 * Depends:
11309 * jquery.effects.core.js
11310 */
11311 (function( $, undefined ) {
11312
11313 $.effects.highlight = function(o) {
11314 return this.queue(function() {
11315 var elem = $(this),
11316 props = ['backgroundImage', 'backgroundColor', 'opacity'],
11317 mode = $.effects.setMode(elem, o.options.mode || 'show'),
11318 animation = {
11319 backgroundColor: elem.css('backgroundColor')
11320 };
11321
11322 if (mode == 'hide') {
11323 animation.opacity = 0;
11324 }
11325
11326 $.effects.save(elem, props);
11327 elem
11328 .show()
11329 .css({
11330 backgroundImage: 'none',
11331 backgroundColor: o.options.color || '#ffff99'
11332 })
11333 .animate(animation, {
11334 queue: false,
11335 duration: o.duration,
11336 easing: o.options.easing,
11337 complete: function() {
11338 (mode == 'hide' && elem.hide());
11339 $.effects.restore(elem, props);
11340 (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
11341 (o.callback && o.callback.apply(this, arguments));
11342 elem.dequeue();
11343 }
11344 });
11345 });
11346 };
11347
11348 })(jQuery);
11349 /*
11350 * jQuery UI Effects Pulsate 1.8.14
11351 *
11352 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11353 * Dual licensed under the MIT or GPL Version 2 licenses.
11354 * http://jquery.org/license
11355 *
11356 * http://docs.jquery.com/UI/Effects/Pulsate
11357 *
11358 * Depends:
11359 * jquery.effects.core.js
11360 */
11361 (function( $, undefined ) {
11362
11363 $.effects.pulsate = function(o) {
11364 return this.queue(function() {
11365 var elem = $(this),
11366 mode = $.effects.setMode(elem, o.options.mode || 'show');
11367 times = ((o.options.times || 5) * 2) - 1;
11368 duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
11369 isVisible = elem.is(':visible'),
11370 animateTo = 0;
11371
11372 if (!isVisible) {
11373 elem.css('opacity', 0).show();
11374 animateTo = 1;
11375 }
11376
11377 if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
11378 times--;
11379 }
11380
11381 for (var i = 0; i < times; i++) {
11382 elem.animate({ opacity: animateTo }, duration, o.options.easing);
11383 animateTo = (animateTo + 1) % 2;
11384 }
11385
11386 elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
11387 if (animateTo == 0) {
11388 elem.hide();
11389 }
11390 (o.callback && o.callback.apply(this, arguments));
11391 });
11392
11393 elem
11394 .queue('fx', function() { elem.dequeue(); })
11395 .dequeue();
11396 });
11397 };
11398
11399 })(jQuery);
11400 /*
11401 * jQuery UI Effects Scale 1.8.14
11402 *
11403 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11404 * Dual licensed under the MIT or GPL Version 2 licenses.
11405 * http://jquery.org/license
11406 *
11407 * http://docs.jquery.com/UI/Effects/Scale
11408 *
11409 * Depends:
11410 * jquery.effects.core.js
11411 */
11412 (function( $, undefined ) {
11413
11414 $.effects.puff = function(o) {
11415 return this.queue(function() {
11416 var elem = $(this),
11417 mode = $.effects.setMode(elem, o.options.mode || 'hide'),
11418 percent = parseInt(o.options.percent, 10) || 150,
11419 factor = percent / 100,
11420 original = { height: elem.height(), width: elem.width() };
11421
11422 $.extend(o.options, {
11423 fade: true,
11424 mode: mode,
11425 percent: mode == 'hide' ? percent : 100,
11426 from: mode == 'hide'
11427 ? original
11428 : {
11429 height: original.height * factor,
11430 width: original.width * factor
11431 }
11432 });
11433
11434 elem.effect('scale', o.options, o.duration, o.callback);
11435 elem.dequeue();
11436 });
11437 };
11438
11439 $.effects.scale = function(o) {
11440
11441 return this.queue(function() {
11442
11443 // Create element
11444 var el = $(this);
11445
11446 // Set options
11447 var options = $.extend(true, {}, o.options);
11448 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11449 var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
11450 var direction = o.options.direction || 'both'; // Set default axis
11451 var origin = o.options.origin; // The origin of the scaling
11452 if (mode != 'effect') { // Set default origin and restore for show/hide
11453 options.origin = origin || ['middle','center'];
11454 options.restore = true;
11455 }
11456 var original = {height: el.height(), width: el.width()}; // Save original
11457 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
11458
11459 // Adjust
11460 var factor = { // Set scaling factor
11461 y: direction != 'horizontal' ? (percent / 100) : 1,
11462 x: direction != 'vertical' ? (percent / 100) : 1
11463 };
11464 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
11465
11466 if (o.options.fade) { // Fade option to support puff
11467 if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
11468 if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
11469 };
11470
11471 // Animation
11472 options.from = el.from; options.to = el.to; options.mode = mode;
11473
11474 // Animate
11475 el.effect('size', options, o.duration, o.callback);
11476 el.dequeue();
11477 });
11478
11479 };
11480
11481 $.effects.size = function(o) {
11482
11483 return this.queue(function() {
11484
11485 // Create element
11486 var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
11487 var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
11488 var props2 = ['width','height','overflow']; // Copy for children
11489 var cProps = ['fontSize'];
11490 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
11491 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
11492
11493 // Set options
11494 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11495 var restore = o.options.restore || false; // Default restore
11496 var scale = o.options.scale || 'both'; // Default scale mode
11497 var origin = o.options.origin; // The origin of the sizing
11498 var original = {height: el.height(), width: el.width()}; // Save original
11499 el.from = o.options.from || original; // Default from state
11500 el.to = o.options.to || original; // Default to state
11501 // Adjust
11502 if (origin) { // Calculate baseline shifts
11503 var baseline = $.effects.getBaseline(origin, original);
11504 el.from.top = (original.height - el.from.height) * baseline.y;
11505 el.from.left = (original.width - el.from.width) * baseline.x;
11506 el.to.top = (original.height - el.to.height) * baseline.y;
11507 el.to.left = (original.width - el.to.width) * baseline.x;
11508 };
11509 var factor = { // Set scaling factor
11510 from: {y: el.from.height / original.height, x: el.from.width / original.width},
11511 to: {y: el.to.height / original.height, x: el.to.width / original.width}
11512 };
11513 if (scale == 'box' || scale == 'both') { // Scale the css box
11514 if (factor.from.y != factor.to.y) { // Vertical props scaling
11515 props = props.concat(vProps);
11516 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
11517 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
11518 };
11519 if (factor.from.x != factor.to.x) { // Horizontal props scaling
11520 props = props.concat(hProps);
11521 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
11522 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
11523 };
11524 };
11525 if (scale == 'content' || scale == 'both') { // Scale the content
11526 if (factor.from.y != factor.to.y) { // Vertical props scaling
11527 props = props.concat(cProps);
11528 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
11529 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
11530 };
11531 };
11532 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
11533 $.effects.createWrapper(el); // Create Wrapper
11534 el.css('overflow','hidden').css(el.from); // Shift
11535
11536 // Animate
11537 if (scale == 'content' || scale == 'both') { // Scale the children
11538 vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
11539 hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
11540 props2 = props.concat(vProps).concat(hProps); // Concat
11541 el.find("*[width]").each(function(){
11542 child = $(this);
11543 if (restore) $.effects.save(child, props2);
11544 var c_original = {height: child.height(), width: child.width()}; // Save original
11545 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
11546 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
11547 if (factor.from.y != factor.to.y) { // Vertical props scaling
11548 child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
11549 child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
11550 };
11551 if (factor.from.x != factor.to.x) { // Horizontal props scaling
11552 child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
11553 child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
11554 };
11555 child.css(child.from); // Shift children
11556 child.animate(child.to, o.duration, o.options.easing, function(){
11557 if (restore) $.effects.restore(child, props2); // Restore children
11558 }); // Animate children
11559 });
11560 };
11561
11562 // Animate
11563 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11564 if (el.to.opacity === 0) {
11565 el.css('opacity', el.from.opacity);
11566 }
11567 if(mode == 'hide') el.hide(); // Hide
11568 $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
11569 if(o.callback) o.callback.apply(this, arguments); // Callback
11570 el.dequeue();
11571 }});
11572
11573 });
11574
11575 };
11576
11577 })(jQuery);
11578 /*
11579 * jQuery UI Effects Shake 1.8.14
11580 *
11581 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11582 * Dual licensed under the MIT or GPL Version 2 licenses.
11583 * http://jquery.org/license
11584 *
11585 * http://docs.jquery.com/UI/Effects/Shake
11586 *
11587 * Depends:
11588 * jquery.effects.core.js
11589 */
11590 (function( $, undefined ) {
11591
11592 $.effects.shake = function(o) {
11593
11594 return this.queue(function() {
11595
11596 // Create element
11597 var el = $(this), props = ['position','top','bottom','left','right'];
11598
11599 // Set options
11600 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11601 var direction = o.options.direction || 'left'; // Default direction
11602 var distance = o.options.distance || 20; // Default distance
11603 var times = o.options.times || 3; // Default # of times
11604 var speed = o.duration || o.options.duration || 140; // Default speed per shake
11605
11606 // Adjust
11607 $.effects.save(el, props); el.show(); // Save & Show
11608 $.effects.createWrapper(el); // Create Wrapper
11609 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11610 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11611
11612 // Animation
11613 var animation = {}, animation1 = {}, animation2 = {};
11614 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11615 animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
11616 animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
11617
11618 // Animate
11619 el.animate(animation, speed, o.options.easing);
11620 for (var i = 1; i < times; i++) { // Shakes
11621 el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
11622 };
11623 el.animate(animation1, speed, o.options.easing).
11624 animate(animation, speed / 2, o.options.easing, function(){ // Last shake
11625 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11626 if(o.callback) o.callback.apply(this, arguments); // Callback
11627 });
11628 el.queue('fx', function() { el.dequeue(); });
11629 el.dequeue();
11630 });
11631
11632 };
11633
11634 })(jQuery);
11635 /*
11636 * jQuery UI Effects Slide 1.8.14
11637 *
11638 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11639 * Dual licensed under the MIT or GPL Version 2 licenses.
11640 * http://jquery.org/license
11641 *
11642 * http://docs.jquery.com/UI/Effects/Slide
11643 *
11644 * Depends:
11645 * jquery.effects.core.js
11646 */
11647 (function( $, undefined ) {
11648
11649 $.effects.slide = function(o) {
11650
11651 return this.queue(function() {
11652
11653 // Create element
11654 var el = $(this), props = ['position','top','bottom','left','right'];
11655
11656 // Set options
11657 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
11658 var direction = o.options.direction || 'left'; // Default Direction
11659
11660 // Adjust
11661 $.effects.save(el, props); el.show(); // Save & Show
11662 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11663 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11664 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11665 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
11666 if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
11667
11668 // Animation
11669 var animation = {};
11670 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
11671
11672 // Animate
11673 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11674 if(mode == 'hide') el.hide(); // Hide
11675 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11676 if(o.callback) o.callback.apply(this, arguments); // Callback
11677 el.dequeue();
11678 }});
11679
11680 });
11681
11682 };
11683
11684 })(jQuery);
11685 /*
11686 * jQuery UI Effects Transfer 1.8.14
11687 *
11688 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11689 * Dual licensed under the MIT or GPL Version 2 licenses.
11690 * http://jquery.org/license
11691 *
11692 * http://docs.jquery.com/UI/Effects/Transfer
11693 *
11694 * Depends:
11695 * jquery.effects.core.js
11696 */
11697 (function( $, undefined ) {
11698
11699 $.effects.transfer = function(o) {
11700 return this.queue(function() {
11701 var elem = $(this),
11702 target = $(o.options.to),
11703 endPosition = target.offset(),
11704 animation = {
11705 top: endPosition.top,
11706 left: endPosition.left,
11707 height: target.innerHeight(),
11708 width: target.innerWidth()
11709 },
11710 startPosition = elem.offset(),
11711 transfer = $('<div class="ui-effects-transfer"></div>')
11712 .appendTo(document.body)
11713 .addClass(o.options.className)
11714 .css({
11715 top: startPosition.top,
11716 left: startPosition.left,
11717 height: elem.innerHeight(),
11718 width: elem.innerWidth(),
11719 position: 'absolute'
11720 })
11721 .animate(animation, o.duration, o.options.easing, function() {
11722 transfer.remove();
11723 (o.callback && o.callback.apply(elem[0], arguments));
11724 elem.dequeue();
11725 });
11726 });
11727 };
11728
11729 })(jQuery);