[SPIP] +spip v3.0.17
[lhc/web/clavette_www.git] / www / plugins-dist / jquery_ui / prive / javascript / ui / jquery-ui.js
1 /*!
2 * jQuery UI 1.8.21
3 *
4 * Copyright 2012, 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.21",
22
23 keyCode: {
24 ALT: 18,
25 BACKSPACE: 8,
26 CAPS_LOCK: 20,
27 COMMA: 188,
28 COMMAND: 91,
29 COMMAND_LEFT: 91, // COMMAND
30 COMMAND_RIGHT: 93,
31 CONTROL: 17,
32 DELETE: 46,
33 DOWN: 40,
34 END: 35,
35 ENTER: 13,
36 ESCAPE: 27,
37 HOME: 36,
38 INSERT: 45,
39 LEFT: 37,
40 MENU: 93, // COMMAND_RIGHT
41 NUMPAD_ADD: 107,
42 NUMPAD_DECIMAL: 110,
43 NUMPAD_DIVIDE: 111,
44 NUMPAD_ENTER: 108,
45 NUMPAD_MULTIPLY: 106,
46 NUMPAD_SUBTRACT: 109,
47 PAGE_DOWN: 34,
48 PAGE_UP: 33,
49 PERIOD: 190,
50 RIGHT: 39,
51 SHIFT: 16,
52 SPACE: 32,
53 TAB: 9,
54 UP: 38,
55 WINDOWS: 91 // COMMAND
56 }
57 });
58
59 // plugins
60 $.fn.extend({
61 propAttr: $.fn.prop || $.fn.attr,
62
63 _focus: $.fn.focus,
64 focus: function( delay, fn ) {
65 return typeof delay === "number" ?
66 this.each(function() {
67 var elem = this;
68 setTimeout(function() {
69 $( elem ).focus();
70 if ( fn ) {
71 fn.call( elem );
72 }
73 }, delay );
74 }) :
75 this._focus.apply( this, arguments );
76 },
77
78 scrollParent: function() {
79 var scrollParent;
80 if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
81 scrollParent = this.parents().filter(function() {
82 return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
83 }).eq(0);
84 } else {
85 scrollParent = this.parents().filter(function() {
86 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
87 }).eq(0);
88 }
89
90 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
91 },
92
93 zIndex: function( zIndex ) {
94 if ( zIndex !== undefined ) {
95 return this.css( "zIndex", zIndex );
96 }
97
98 if ( this.length ) {
99 var elem = $( this[ 0 ] ), position, value;
100 while ( elem.length && elem[ 0 ] !== document ) {
101 // Ignore z-index if position is set to a value where z-index is ignored by the browser
102 // This makes behavior of this function consistent across browsers
103 // WebKit always returns auto if the element is positioned
104 position = elem.css( "position" );
105 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
106 // IE returns 0 when zIndex is not specified
107 // other browsers return a string
108 // we ignore the case of nested elements with an explicit value of 0
109 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
110 value = parseInt( elem.css( "zIndex" ), 10 );
111 if ( !isNaN( value ) && value !== 0 ) {
112 return value;
113 }
114 }
115 elem = elem.parent();
116 }
117 }
118
119 return 0;
120 },
121
122 disableSelection: function() {
123 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
124 ".ui-disableSelection", function( event ) {
125 event.preventDefault();
126 });
127 },
128
129 enableSelection: function() {
130 return this.unbind( ".ui-disableSelection" );
131 }
132 });
133
134 $.each( [ "Width", "Height" ], function( i, name ) {
135 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
136 type = name.toLowerCase(),
137 orig = {
138 innerWidth: $.fn.innerWidth,
139 innerHeight: $.fn.innerHeight,
140 outerWidth: $.fn.outerWidth,
141 outerHeight: $.fn.outerHeight
142 };
143
144 function reduce( elem, size, border, margin ) {
145 $.each( side, function() {
146 size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
147 if ( border ) {
148 size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
149 }
150 if ( margin ) {
151 size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
152 }
153 });
154 return size;
155 }
156
157 $.fn[ "inner" + name ] = function( size ) {
158 if ( size === undefined ) {
159 return orig[ "inner" + name ].call( this );
160 }
161
162 return this.each(function() {
163 $( this ).css( type, reduce( this, size ) + "px" );
164 });
165 };
166
167 $.fn[ "outer" + name] = function( size, margin ) {
168 if ( typeof size !== "number" ) {
169 return orig[ "outer" + name ].call( this, size );
170 }
171
172 return this.each(function() {
173 $( this).css( type, reduce( this, size, true, margin ) + "px" );
174 });
175 };
176 });
177
178 // selectors
179 function focusable( element, isTabIndexNotNaN ) {
180 var nodeName = element.nodeName.toLowerCase();
181 if ( "area" === nodeName ) {
182 var map = element.parentNode,
183 mapName = map.name,
184 img;
185 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
186 return false;
187 }
188 img = $( "img[usemap=#" + mapName + "]" )[0];
189 return !!img && visible( img );
190 }
191 return ( /input|select|textarea|button|object/.test( nodeName )
192 ? !element.disabled
193 : "a" == nodeName
194 ? element.href || isTabIndexNotNaN
195 : isTabIndexNotNaN)
196 // the element and all of its ancestors must be visible
197 && visible( element );
198 }
199
200 function visible( element ) {
201 return !$( element ).parents().andSelf().filter(function() {
202 return $.curCSS( this, "visibility" ) === "hidden" ||
203 $.expr.filters.hidden( this );
204 }).length;
205 }
206
207 $.extend( $.expr[ ":" ], {
208 data: function( elem, i, match ) {
209 return !!$.data( elem, match[ 3 ] );
210 },
211
212 focusable: function( element ) {
213 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
214 },
215
216 tabbable: function( element ) {
217 var tabIndex = $.attr( element, "tabindex" ),
218 isTabIndexNaN = isNaN( tabIndex );
219 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
220 }
221 });
222
223 // support
224 $(function() {
225 var body = document.body,
226 div = body.appendChild( div = document.createElement( "div" ) );
227
228 // access offsetHeight before setting the style to prevent a layout bug
229 // in IE 9 which causes the elemnt to continue to take up space even
230 // after it is removed from the DOM (#8026)
231 div.offsetHeight;
232
233 $.extend( div.style, {
234 minHeight: "100px",
235 height: "auto",
236 padding: 0,
237 borderWidth: 0
238 });
239
240 $.support.minHeight = div.offsetHeight === 100;
241 $.support.selectstart = "onselectstart" in div;
242
243 // set display to none to avoid a layout bug in IE
244 // http://dev.jquery.com/ticket/4014
245 body.removeChild( div ).style.display = "none";
246 });
247
248
249
250
251
252 // deprecated
253 $.extend( $.ui, {
254 // $.ui.plugin is deprecated. Use the proxy pattern instead.
255 plugin: {
256 add: function( module, option, set ) {
257 var proto = $.ui[ module ].prototype;
258 for ( var i in set ) {
259 proto.plugins[ i ] = proto.plugins[ i ] || [];
260 proto.plugins[ i ].push( [ option, set[ i ] ] );
261 }
262 },
263 call: function( instance, name, args ) {
264 var set = instance.plugins[ name ];
265 if ( !set || !instance.element[ 0 ].parentNode ) {
266 return;
267 }
268
269 for ( var i = 0; i < set.length; i++ ) {
270 if ( instance.options[ set[ i ][ 0 ] ] ) {
271 set[ i ][ 1 ].apply( instance.element, args );
272 }
273 }
274 }
275 },
276
277 // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
278 contains: function( a, b ) {
279 return document.compareDocumentPosition ?
280 a.compareDocumentPosition( b ) & 16 :
281 a !== b && a.contains( b );
282 },
283
284 // only used by resizable
285 hasScroll: function( el, a ) {
286
287 //If overflow is hidden, the element might have extra content, but the user wants to hide it
288 if ( $( el ).css( "overflow" ) === "hidden") {
289 return false;
290 }
291
292 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
293 has = false;
294
295 if ( el[ scroll ] > 0 ) {
296 return true;
297 }
298
299 // TODO: determine which cases actually cause this to happen
300 // if the element doesn't have the scroll set, see if it's possible to
301 // set the scroll
302 el[ scroll ] = 1;
303 has = ( el[ scroll ] > 0 );
304 el[ scroll ] = 0;
305 return has;
306 },
307
308 // these are odd functions, fix the API or move into individual plugins
309 isOverAxis: function( x, reference, size ) {
310 //Determines when x coordinate is over "b" element axis
311 return ( x > reference ) && ( x < ( reference + size ) );
312 },
313 isOver: function( y, x, top, left, height, width ) {
314 //Determines when x, y coordinates is over "b" element
315 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
316 }
317 });
318
319 })( jQuery );
320 /*!
321 * jQuery UI Widget 1.8.21
322 *
323 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
324 * Dual licensed under the MIT or GPL Version 2 licenses.
325 * http://jquery.org/license
326 *
327 * http://docs.jquery.com/UI/Widget
328 */
329 (function( $, undefined ) {
330
331 // jQuery 1.4+
332 if ( $.cleanData ) {
333 var _cleanData = $.cleanData;
334 $.cleanData = function( elems ) {
335 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
336 try {
337 $( elem ).triggerHandler( "remove" );
338 // http://bugs.jquery.com/ticket/8235
339 } catch( e ) {}
340 }
341 _cleanData( elems );
342 };
343 } else {
344 var _remove = $.fn.remove;
345 $.fn.remove = function( selector, keepData ) {
346 return this.each(function() {
347 if ( !keepData ) {
348 if ( !selector || $.filter( selector, [ this ] ).length ) {
349 $( "*", this ).add( [ this ] ).each(function() {
350 try {
351 $( this ).triggerHandler( "remove" );
352 // http://bugs.jquery.com/ticket/8235
353 } catch( e ) {}
354 });
355 }
356 }
357 return _remove.call( $(this), selector, keepData );
358 });
359 };
360 }
361
362 $.widget = function( name, base, prototype ) {
363 var namespace = name.split( "." )[ 0 ],
364 fullName;
365 name = name.split( "." )[ 1 ];
366 fullName = namespace + "-" + name;
367
368 if ( !prototype ) {
369 prototype = base;
370 base = $.Widget;
371 }
372
373 // create selector for plugin
374 $.expr[ ":" ][ fullName ] = function( elem ) {
375 return !!$.data( elem, name );
376 };
377
378 $[ namespace ] = $[ namespace ] || {};
379 $[ namespace ][ name ] = function( options, element ) {
380 // allow instantiation without initializing for simple inheritance
381 if ( arguments.length ) {
382 this._createWidget( options, element );
383 }
384 };
385
386 var basePrototype = new base();
387 // we need to make the options hash a property directly on the new instance
388 // otherwise we'll modify the options hash on the prototype that we're
389 // inheriting from
390 // $.each( basePrototype, function( key, val ) {
391 // if ( $.isPlainObject(val) ) {
392 // basePrototype[ key ] = $.extend( {}, val );
393 // }
394 // });
395 basePrototype.options = $.extend( true, {}, basePrototype.options );
396 $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
397 namespace: namespace,
398 widgetName: name,
399 widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
400 widgetBaseClass: fullName
401 }, prototype );
402
403 $.widget.bridge( name, $[ namespace ][ name ] );
404 };
405
406 $.widget.bridge = function( name, object ) {
407 $.fn[ name ] = function( options ) {
408 var isMethodCall = typeof options === "string",
409 args = Array.prototype.slice.call( arguments, 1 ),
410 returnValue = this;
411
412 // allow multiple hashes to be passed on init
413 options = !isMethodCall && args.length ?
414 $.extend.apply( null, [ true, options ].concat(args) ) :
415 options;
416
417 // prevent calls to internal methods
418 if ( isMethodCall && options.charAt( 0 ) === "_" ) {
419 return returnValue;
420 }
421
422 if ( isMethodCall ) {
423 this.each(function() {
424 var instance = $.data( this, name ),
425 methodValue = instance && $.isFunction( instance[options] ) ?
426 instance[ options ].apply( instance, args ) :
427 instance;
428 // TODO: add this back in 1.9 and use $.error() (see #5972)
429 // if ( !instance ) {
430 // throw "cannot call methods on " + name + " prior to initialization; " +
431 // "attempted to call method '" + options + "'";
432 // }
433 // if ( !$.isFunction( instance[options] ) ) {
434 // throw "no such method '" + options + "' for " + name + " widget instance";
435 // }
436 // var methodValue = instance[ options ].apply( instance, args );
437 if ( methodValue !== instance && methodValue !== undefined ) {
438 returnValue = methodValue;
439 return false;
440 }
441 });
442 } else {
443 this.each(function() {
444 var instance = $.data( this, name );
445 if ( instance ) {
446 instance.option( options || {} )._init();
447 } else {
448 $.data( this, name, new object( options, this ) );
449 }
450 });
451 }
452
453 return returnValue;
454 };
455 };
456
457 $.Widget = function( options, element ) {
458 // allow instantiation without initializing for simple inheritance
459 if ( arguments.length ) {
460 this._createWidget( options, element );
461 }
462 };
463
464 $.Widget.prototype = {
465 widgetName: "widget",
466 widgetEventPrefix: "",
467 options: {
468 disabled: false
469 },
470 _createWidget: function( options, element ) {
471 // $.widget.bridge stores the plugin instance, but we do it anyway
472 // so that it's stored even before the _create function runs
473 $.data( element, this.widgetName, this );
474 this.element = $( element );
475 this.options = $.extend( true, {},
476 this.options,
477 this._getCreateOptions(),
478 options );
479
480 var self = this;
481 this.element.bind( "remove." + this.widgetName, function() {
482 self.destroy();
483 });
484
485 this._create();
486 this._trigger( "create" );
487 this._init();
488 },
489 _getCreateOptions: function() {
490 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
491 },
492 _create: function() {},
493 _init: function() {},
494
495 destroy: function() {
496 this.element
497 .unbind( "." + this.widgetName )
498 .removeData( this.widgetName );
499 this.widget()
500 .unbind( "." + this.widgetName )
501 .removeAttr( "aria-disabled" )
502 .removeClass(
503 this.widgetBaseClass + "-disabled " +
504 "ui-state-disabled" );
505 },
506
507 widget: function() {
508 return this.element;
509 },
510
511 option: function( key, value ) {
512 var options = key;
513
514 if ( arguments.length === 0 ) {
515 // don't return a reference to the internal hash
516 return $.extend( {}, this.options );
517 }
518
519 if (typeof key === "string" ) {
520 if ( value === undefined ) {
521 return this.options[ key ];
522 }
523 options = {};
524 options[ key ] = value;
525 }
526
527 this._setOptions( options );
528
529 return this;
530 },
531 _setOptions: function( options ) {
532 var self = this;
533 $.each( options, function( key, value ) {
534 self._setOption( key, value );
535 });
536
537 return this;
538 },
539 _setOption: function( key, value ) {
540 this.options[ key ] = value;
541
542 if ( key === "disabled" ) {
543 this.widget()
544 [ value ? "addClass" : "removeClass"](
545 this.widgetBaseClass + "-disabled" + " " +
546 "ui-state-disabled" )
547 .attr( "aria-disabled", value );
548 }
549
550 return this;
551 },
552
553 enable: function() {
554 return this._setOption( "disabled", false );
555 },
556 disable: function() {
557 return this._setOption( "disabled", true );
558 },
559
560 _trigger: function( type, event, data ) {
561 var prop, orig,
562 callback = this.options[ type ];
563
564 data = data || {};
565 event = $.Event( event );
566 event.type = ( type === this.widgetEventPrefix ?
567 type :
568 this.widgetEventPrefix + type ).toLowerCase();
569 // the original event may come from any element
570 // so we need to reset the target on the new event
571 event.target = this.element[ 0 ];
572
573 // copy original event properties over to the new event
574 orig = event.originalEvent;
575 if ( orig ) {
576 for ( prop in orig ) {
577 if ( !( prop in event ) ) {
578 event[ prop ] = orig[ prop ];
579 }
580 }
581 }
582
583 this.element.trigger( event, data );
584
585 return !( $.isFunction(callback) &&
586 callback.call( this.element[0], event, data ) === false ||
587 event.isDefaultPrevented() );
588 }
589 };
590
591 })( jQuery );
592 /*!
593 * jQuery UI Mouse 1.8.21
594 *
595 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
596 * Dual licensed under the MIT or GPL Version 2 licenses.
597 * http://jquery.org/license
598 *
599 * http://docs.jquery.com/UI/Mouse
600 *
601 * Depends:
602 * jquery.ui.widget.js
603 */
604 (function( $, undefined ) {
605
606 var mouseHandled = false;
607 $( document ).mouseup( function( e ) {
608 mouseHandled = false;
609 });
610
611 $.widget("ui.mouse", {
612 options: {
613 cancel: ':input,option',
614 distance: 1,
615 delay: 0
616 },
617 _mouseInit: function() {
618 var self = this;
619
620 this.element
621 .bind('mousedown.'+this.widgetName, function(event) {
622 return self._mouseDown(event);
623 })
624 .bind('click.'+this.widgetName, function(event) {
625 if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
626 $.removeData(event.target, self.widgetName + '.preventClickEvent');
627 event.stopImmediatePropagation();
628 return false;
629 }
630 });
631
632 this.started = false;
633 },
634
635 // TODO: make sure destroying one instance of mouse doesn't mess with
636 // other instances of mouse
637 _mouseDestroy: function() {
638 this.element.unbind('.'+this.widgetName);
639 $(document)
640 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
641 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
642 },
643
644 _mouseDown: function(event) {
645 // don't let more than one widget handle mouseStart
646 if( mouseHandled ) { return };
647
648 // we may have missed mouseup (out of window)
649 (this._mouseStarted && this._mouseUp(event));
650
651 this._mouseDownEvent = event;
652
653 var self = this,
654 btnIsLeft = (event.which == 1),
655 // event.target.nodeName works around a bug in IE 8 with
656 // disabled inputs (#7620)
657 elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
658 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
659 return true;
660 }
661
662 this.mouseDelayMet = !this.options.delay;
663 if (!this.mouseDelayMet) {
664 this._mouseDelayTimer = setTimeout(function() {
665 self.mouseDelayMet = true;
666 }, this.options.delay);
667 }
668
669 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
670 this._mouseStarted = (this._mouseStart(event) !== false);
671 if (!this._mouseStarted) {
672 event.preventDefault();
673 return true;
674 }
675 }
676
677 // Click event may never have fired (Gecko & Opera)
678 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
679 $.removeData(event.target, this.widgetName + '.preventClickEvent');
680 }
681
682 // these delegates are required to keep context
683 this._mouseMoveDelegate = function(event) {
684 return self._mouseMove(event);
685 };
686 this._mouseUpDelegate = function(event) {
687 return self._mouseUp(event);
688 };
689 $(document)
690 .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
691 .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
692
693 event.preventDefault();
694
695 mouseHandled = true;
696 return true;
697 },
698
699 _mouseMove: function(event) {
700 // IE mouseup check - mouseup happened when mouse was out of window
701 if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
702 return this._mouseUp(event);
703 }
704
705 if (this._mouseStarted) {
706 this._mouseDrag(event);
707 return event.preventDefault();
708 }
709
710 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
711 this._mouseStarted =
712 (this._mouseStart(this._mouseDownEvent, event) !== false);
713 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
714 }
715
716 return !this._mouseStarted;
717 },
718
719 _mouseUp: function(event) {
720 $(document)
721 .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
722 .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
723
724 if (this._mouseStarted) {
725 this._mouseStarted = false;
726
727 if (event.target == this._mouseDownEvent.target) {
728 $.data(event.target, this.widgetName + '.preventClickEvent', true);
729 }
730
731 this._mouseStop(event);
732 }
733
734 return false;
735 },
736
737 _mouseDistanceMet: function(event) {
738 return (Math.max(
739 Math.abs(this._mouseDownEvent.pageX - event.pageX),
740 Math.abs(this._mouseDownEvent.pageY - event.pageY)
741 ) >= this.options.distance
742 );
743 },
744
745 _mouseDelayMet: function(event) {
746 return this.mouseDelayMet;
747 },
748
749 // These are placeholder methods, to be overriden by extending plugin
750 _mouseStart: function(event) {},
751 _mouseDrag: function(event) {},
752 _mouseStop: function(event) {},
753 _mouseCapture: function(event) { return true; }
754 });
755
756 })(jQuery);
757 /*!
758 * jQuery UI Position 1.8.21
759 *
760 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
761 * Dual licensed under the MIT or GPL Version 2 licenses.
762 * http://jquery.org/license
763 *
764 * http://docs.jquery.com/UI/Position
765 */
766 (function( $, undefined ) {
767
768 $.ui = $.ui || {};
769
770 var horizontalPositions = /left|center|right/,
771 verticalPositions = /top|center|bottom/,
772 center = "center",
773 support = {},
774 _position = $.fn.position,
775 _offset = $.fn.offset;
776
777 $.fn.position = function( options ) {
778 if ( !options || !options.of ) {
779 return _position.apply( this, arguments );
780 }
781
782 // make a copy, we don't want to modify arguments
783 options = $.extend( {}, options );
784
785 var target = $( options.of ),
786 targetElem = target[0],
787 collision = ( options.collision || "flip" ).split( " " ),
788 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
789 targetWidth,
790 targetHeight,
791 basePosition;
792
793 if ( targetElem.nodeType === 9 ) {
794 targetWidth = target.width();
795 targetHeight = target.height();
796 basePosition = { top: 0, left: 0 };
797 // TODO: use $.isWindow() in 1.9
798 } else if ( targetElem.setTimeout ) {
799 targetWidth = target.width();
800 targetHeight = target.height();
801 basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
802 } else if ( targetElem.preventDefault ) {
803 // force left top to allow flipping
804 options.at = "left top";
805 targetWidth = targetHeight = 0;
806 basePosition = { top: options.of.pageY, left: options.of.pageX };
807 } else {
808 targetWidth = target.outerWidth();
809 targetHeight = target.outerHeight();
810 basePosition = target.offset();
811 }
812
813 // force my and at to have valid horizontal and veritcal positions
814 // if a value is missing or invalid, it will be converted to center
815 $.each( [ "my", "at" ], function() {
816 var pos = ( options[this] || "" ).split( " " );
817 if ( pos.length === 1) {
818 pos = horizontalPositions.test( pos[0] ) ?
819 pos.concat( [center] ) :
820 verticalPositions.test( pos[0] ) ?
821 [ center ].concat( pos ) :
822 [ center, center ];
823 }
824 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
825 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
826 options[ this ] = pos;
827 });
828
829 // normalize collision option
830 if ( collision.length === 1 ) {
831 collision[ 1 ] = collision[ 0 ];
832 }
833
834 // normalize offset option
835 offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
836 if ( offset.length === 1 ) {
837 offset[ 1 ] = offset[ 0 ];
838 }
839 offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
840
841 if ( options.at[0] === "right" ) {
842 basePosition.left += targetWidth;
843 } else if ( options.at[0] === center ) {
844 basePosition.left += targetWidth / 2;
845 }
846
847 if ( options.at[1] === "bottom" ) {
848 basePosition.top += targetHeight;
849 } else if ( options.at[1] === center ) {
850 basePosition.top += targetHeight / 2;
851 }
852
853 basePosition.left += offset[ 0 ];
854 basePosition.top += offset[ 1 ];
855
856 return this.each(function() {
857 var elem = $( this ),
858 elemWidth = elem.outerWidth(),
859 elemHeight = elem.outerHeight(),
860 marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
861 marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
862 collisionWidth = elemWidth + marginLeft +
863 ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
864 collisionHeight = elemHeight + marginTop +
865 ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
866 position = $.extend( {}, basePosition ),
867 collisionPosition;
868
869 if ( options.my[0] === "right" ) {
870 position.left -= elemWidth;
871 } else if ( options.my[0] === center ) {
872 position.left -= elemWidth / 2;
873 }
874
875 if ( options.my[1] === "bottom" ) {
876 position.top -= elemHeight;
877 } else if ( options.my[1] === center ) {
878 position.top -= elemHeight / 2;
879 }
880
881 // prevent fractions if jQuery version doesn't support them (see #5280)
882 if ( !support.fractions ) {
883 position.left = Math.round( position.left );
884 position.top = Math.round( position.top );
885 }
886
887 collisionPosition = {
888 left: position.left - marginLeft,
889 top: position.top - marginTop
890 };
891
892 $.each( [ "left", "top" ], function( i, dir ) {
893 if ( $.ui.position[ collision[i] ] ) {
894 $.ui.position[ collision[i] ][ dir ]( position, {
895 targetWidth: targetWidth,
896 targetHeight: targetHeight,
897 elemWidth: elemWidth,
898 elemHeight: elemHeight,
899 collisionPosition: collisionPosition,
900 collisionWidth: collisionWidth,
901 collisionHeight: collisionHeight,
902 offset: offset,
903 my: options.my,
904 at: options.at
905 });
906 }
907 });
908
909 if ( $.fn.bgiframe ) {
910 elem.bgiframe();
911 }
912 elem.offset( $.extend( position, { using: options.using } ) );
913 });
914 };
915
916 $.ui.position = {
917 fit: {
918 left: function( position, data ) {
919 var win = $( window ),
920 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
921 position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
922 },
923 top: function( position, data ) {
924 var win = $( window ),
925 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
926 position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
927 }
928 },
929
930 flip: {
931 left: function( position, data ) {
932 if ( data.at[0] === center ) {
933 return;
934 }
935 var win = $( window ),
936 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
937 myOffset = data.my[ 0 ] === "left" ?
938 -data.elemWidth :
939 data.my[ 0 ] === "right" ?
940 data.elemWidth :
941 0,
942 atOffset = data.at[ 0 ] === "left" ?
943 data.targetWidth :
944 -data.targetWidth,
945 offset = -2 * data.offset[ 0 ];
946 position.left += data.collisionPosition.left < 0 ?
947 myOffset + atOffset + offset :
948 over > 0 ?
949 myOffset + atOffset + offset :
950 0;
951 },
952 top: function( position, data ) {
953 if ( data.at[1] === center ) {
954 return;
955 }
956 var win = $( window ),
957 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
958 myOffset = data.my[ 1 ] === "top" ?
959 -data.elemHeight :
960 data.my[ 1 ] === "bottom" ?
961 data.elemHeight :
962 0,
963 atOffset = data.at[ 1 ] === "top" ?
964 data.targetHeight :
965 -data.targetHeight,
966 offset = -2 * data.offset[ 1 ];
967 position.top += data.collisionPosition.top < 0 ?
968 myOffset + atOffset + offset :
969 over > 0 ?
970 myOffset + atOffset + offset :
971 0;
972 }
973 }
974 };
975
976 // offset setter from jQuery 1.4
977 if ( !$.offset.setOffset ) {
978 $.offset.setOffset = function( elem, options ) {
979 // set position first, in-case top/left are set even on static elem
980 if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
981 elem.style.position = "relative";
982 }
983 var curElem = $( elem ),
984 curOffset = curElem.offset(),
985 curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
986 curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
987 props = {
988 top: (options.top - curOffset.top) + curTop,
989 left: (options.left - curOffset.left) + curLeft
990 };
991
992 if ( 'using' in options ) {
993 options.using.call( elem, props );
994 } else {
995 curElem.css( props );
996 }
997 };
998
999 $.fn.offset = function( options ) {
1000 var elem = this[ 0 ];
1001 if ( !elem || !elem.ownerDocument ) { return null; }
1002 if ( options ) {
1003 if ( $.isFunction( options ) ) {
1004 return this.each(function( i ) {
1005 $( this ).offset( options.call( this, i, $( this ).offset() ) );
1006 });
1007 }
1008 return this.each(function() {
1009 $.offset.setOffset( this, options );
1010 });
1011 }
1012 return _offset.call( this );
1013 };
1014 }
1015
1016 // fraction support test (older versions of jQuery don't support fractions)
1017 (function () {
1018 var body = document.getElementsByTagName( "body" )[ 0 ],
1019 div = document.createElement( "div" ),
1020 testElement, testElementParent, testElementStyle, offset, offsetTotal;
1021
1022 //Create a "fake body" for testing based on method used in jQuery.support
1023 testElement = document.createElement( body ? "div" : "body" );
1024 testElementStyle = {
1025 visibility: "hidden",
1026 width: 0,
1027 height: 0,
1028 border: 0,
1029 margin: 0,
1030 background: "none"
1031 };
1032 if ( body ) {
1033 $.extend( testElementStyle, {
1034 position: "absolute",
1035 left: "-1000px",
1036 top: "-1000px"
1037 });
1038 }
1039 for ( var i in testElementStyle ) {
1040 testElement.style[ i ] = testElementStyle[ i ];
1041 }
1042 testElement.appendChild( div );
1043 testElementParent = body || document.documentElement;
1044 testElementParent.insertBefore( testElement, testElementParent.firstChild );
1045
1046 div.style.cssText = "position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;";
1047
1048 offset = $( div ).offset( function( _, offset ) {
1049 return offset;
1050 }).offset();
1051
1052 testElement.innerHTML = "";
1053 testElementParent.removeChild( testElement );
1054
1055 offsetTotal = offset.top + offset.left + ( body ? 2000 : 0 );
1056 support.fractions = offsetTotal > 21 && offsetTotal < 22;
1057 })();
1058
1059 }( jQuery ));
1060 /*!
1061 * jQuery UI Draggable 1.8.21
1062 *
1063 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
1064 * Dual licensed under the MIT or GPL Version 2 licenses.
1065 * http://jquery.org/license
1066 *
1067 * http://docs.jquery.com/UI/Draggables
1068 *
1069 * Depends:
1070 * jquery.ui.core.js
1071 * jquery.ui.mouse.js
1072 * jquery.ui.widget.js
1073 */
1074 (function( $, undefined ) {
1075
1076 $.widget("ui.draggable", $.ui.mouse, {
1077 widgetEventPrefix: "drag",
1078 options: {
1079 addClasses: true,
1080 appendTo: "parent",
1081 axis: false,
1082 connectToSortable: false,
1083 containment: false,
1084 cursor: "auto",
1085 cursorAt: false,
1086 grid: false,
1087 handle: false,
1088 helper: "original",
1089 iframeFix: false,
1090 opacity: false,
1091 refreshPositions: false,
1092 revert: false,
1093 revertDuration: 500,
1094 scope: "default",
1095 scroll: true,
1096 scrollSensitivity: 20,
1097 scrollSpeed: 20,
1098 snap: false,
1099 snapMode: "both",
1100 snapTolerance: 20,
1101 stack: false,
1102 zIndex: false
1103 },
1104 _create: function() {
1105
1106 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1107 this.element[0].style.position = 'relative';
1108
1109 (this.options.addClasses && this.element.addClass("ui-draggable"));
1110 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1111
1112 this._mouseInit();
1113
1114 },
1115
1116 destroy: function() {
1117 if(!this.element.data('draggable')) return;
1118 this.element
1119 .removeData("draggable")
1120 .unbind(".draggable")
1121 .removeClass("ui-draggable"
1122 + " ui-draggable-dragging"
1123 + " ui-draggable-disabled");
1124 this._mouseDestroy();
1125
1126 return this;
1127 },
1128
1129 _mouseCapture: function(event) {
1130
1131 var o = this.options;
1132
1133 // among others, prevent a drag on a resizable-handle
1134 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1135 return false;
1136
1137 //Quit if we're not on a valid handle
1138 this.handle = this._getHandle(event);
1139 if (!this.handle)
1140 return false;
1141
1142 if ( o.iframeFix ) {
1143 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1144 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1145 .css({
1146 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1147 position: "absolute", opacity: "0.001", zIndex: 1000
1148 })
1149 .css($(this).offset())
1150 .appendTo("body");
1151 });
1152 }
1153
1154 return true;
1155
1156 },
1157
1158 _mouseStart: function(event) {
1159
1160 var o = this.options;
1161
1162 //Create and append the visible helper
1163 this.helper = this._createHelper(event);
1164
1165 this.helper.addClass("ui-draggable-dragging");
1166
1167 //Cache the helper size
1168 this._cacheHelperProportions();
1169
1170 //If ddmanager is used for droppables, set the global draggable
1171 if($.ui.ddmanager)
1172 $.ui.ddmanager.current = this;
1173
1174 /*
1175 * - Position generation -
1176 * This block generates everything position related - it's the core of draggables.
1177 */
1178
1179 //Cache the margins of the original element
1180 this._cacheMargins();
1181
1182 //Store the helper's css position
1183 this.cssPosition = this.helper.css("position");
1184 this.scrollParent = this.helper.scrollParent();
1185
1186 //The element's absolute position on the page minus margins
1187 this.offset = this.positionAbs = this.element.offset();
1188 this.offset = {
1189 top: this.offset.top - this.margins.top,
1190 left: this.offset.left - this.margins.left
1191 };
1192
1193 $.extend(this.offset, {
1194 click: { //Where the click happened, relative to the element
1195 left: event.pageX - this.offset.left,
1196 top: event.pageY - this.offset.top
1197 },
1198 parent: this._getParentOffset(),
1199 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1200 });
1201
1202 //Generate the original position
1203 this.originalPosition = this.position = this._generatePosition(event);
1204 this.originalPageX = event.pageX;
1205 this.originalPageY = event.pageY;
1206
1207 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1208 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1209
1210 //Set a containment if given in the options
1211 if(o.containment)
1212 this._setContainment();
1213
1214 //Trigger event + callbacks
1215 if(this._trigger("start", event) === false) {
1216 this._clear();
1217 return false;
1218 }
1219
1220 //Recache the helper size
1221 this._cacheHelperProportions();
1222
1223 //Prepare the droppable offsets
1224 if ($.ui.ddmanager && !o.dropBehaviour)
1225 $.ui.ddmanager.prepareOffsets(this, event);
1226
1227
1228 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1229
1230 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1231 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1232
1233 return true;
1234 },
1235
1236 _mouseDrag: function(event, noPropagation) {
1237
1238 //Compute the helpers position
1239 this.position = this._generatePosition(event);
1240 this.positionAbs = this._convertPositionTo("absolute");
1241
1242 //Call plugins and callbacks and use the resulting position if something is returned
1243 if (!noPropagation) {
1244 var ui = this._uiHash();
1245 if(this._trigger('drag', event, ui) === false) {
1246 this._mouseUp({});
1247 return false;
1248 }
1249 this.position = ui.position;
1250 }
1251
1252 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1253 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1254 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1255
1256 return false;
1257 },
1258
1259 _mouseStop: function(event) {
1260
1261 //If we are using droppables, inform the manager about the drop
1262 var dropped = false;
1263 if ($.ui.ddmanager && !this.options.dropBehaviour)
1264 dropped = $.ui.ddmanager.drop(this, event);
1265
1266 //if a drop comes from outside (a sortable)
1267 if(this.dropped) {
1268 dropped = this.dropped;
1269 this.dropped = false;
1270 }
1271
1272 //if the original element is no longer in the DOM don't bother to continue (see #8269)
1273 var element = this.element[0], elementInDom = false;
1274 while ( element && (element = element.parentNode) ) {
1275 if (element == document ) {
1276 elementInDom = true;
1277 }
1278 }
1279 if ( !elementInDom && this.options.helper === "original" )
1280 return false;
1281
1282 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))) {
1283 var self = this;
1284 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1285 if(self._trigger("stop", event) !== false) {
1286 self._clear();
1287 }
1288 });
1289 } else {
1290 if(this._trigger("stop", event) !== false) {
1291 this._clear();
1292 }
1293 }
1294
1295 return false;
1296 },
1297
1298 _mouseUp: function(event) {
1299 if (this.options.iframeFix === true) {
1300 $("div.ui-draggable-iframeFix").each(function() {
1301 this.parentNode.removeChild(this);
1302 }); //Remove frame helpers
1303 }
1304
1305 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1306 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1307
1308 return $.ui.mouse.prototype._mouseUp.call(this, event);
1309 },
1310
1311 cancel: function() {
1312
1313 if(this.helper.is(".ui-draggable-dragging")) {
1314 this._mouseUp({});
1315 } else {
1316 this._clear();
1317 }
1318
1319 return this;
1320
1321 },
1322
1323 _getHandle: function(event) {
1324
1325 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1326 $(this.options.handle, this.element)
1327 .find("*")
1328 .andSelf()
1329 .each(function() {
1330 if(this == event.target) handle = true;
1331 });
1332
1333 return handle;
1334
1335 },
1336
1337 _createHelper: function(event) {
1338
1339 var o = this.options;
1340 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1341
1342 if(!helper.parents('body').length)
1343 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1344
1345 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1346 helper.css("position", "absolute");
1347
1348 return helper;
1349
1350 },
1351
1352 _adjustOffsetFromHelper: function(obj) {
1353 if (typeof obj == 'string') {
1354 obj = obj.split(' ');
1355 }
1356 if ($.isArray(obj)) {
1357 obj = {left: +obj[0], top: +obj[1] || 0};
1358 }
1359 if ('left' in obj) {
1360 this.offset.click.left = obj.left + this.margins.left;
1361 }
1362 if ('right' in obj) {
1363 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1364 }
1365 if ('top' in obj) {
1366 this.offset.click.top = obj.top + this.margins.top;
1367 }
1368 if ('bottom' in obj) {
1369 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1370 }
1371 },
1372
1373 _getParentOffset: function() {
1374
1375 //Get the offsetParent and cache its position
1376 this.offsetParent = this.helper.offsetParent();
1377 var po = this.offsetParent.offset();
1378
1379 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1380 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1381 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1382 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1383 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1384 po.left += this.scrollParent.scrollLeft();
1385 po.top += this.scrollParent.scrollTop();
1386 }
1387
1388 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1389 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1390 po = { top: 0, left: 0 };
1391
1392 return {
1393 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1394 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1395 };
1396
1397 },
1398
1399 _getRelativeOffset: function() {
1400
1401 if(this.cssPosition == "relative") {
1402 var p = this.element.position();
1403 return {
1404 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1405 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1406 };
1407 } else {
1408 return { top: 0, left: 0 };
1409 }
1410
1411 },
1412
1413 _cacheMargins: function() {
1414 this.margins = {
1415 left: (parseInt(this.element.css("marginLeft"),10) || 0),
1416 top: (parseInt(this.element.css("marginTop"),10) || 0),
1417 right: (parseInt(this.element.css("marginRight"),10) || 0),
1418 bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1419 };
1420 },
1421
1422 _cacheHelperProportions: function() {
1423 this.helperProportions = {
1424 width: this.helper.outerWidth(),
1425 height: this.helper.outerHeight()
1426 };
1427 },
1428
1429 _setContainment: function() {
1430
1431 var o = this.options;
1432 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1433 if(o.containment == 'document' || o.containment == 'window') this.containment = [
1434 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1435 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1436 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1437 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1438 ];
1439
1440 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1441 var c = $(o.containment);
1442 var ce = c[0]; if(!ce) return;
1443 var co = c.offset();
1444 var over = ($(ce).css("overflow") != 'hidden');
1445
1446 this.containment = [
1447 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1448 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1449 (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,
1450 (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
1451 ];
1452 this.relative_container = c;
1453
1454 } else if(o.containment.constructor == Array) {
1455 this.containment = o.containment;
1456 }
1457
1458 },
1459
1460 _convertPositionTo: function(d, pos) {
1461
1462 if(!pos) pos = this.position;
1463 var mod = d == "absolute" ? 1 : -1;
1464 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);
1465
1466 return {
1467 top: (
1468 pos.top // The absolute mouse position
1469 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1470 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
1471 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1472 ),
1473 left: (
1474 pos.left // The absolute mouse position
1475 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1476 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
1477 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1478 )
1479 };
1480
1481 },
1482
1483 _generatePosition: function(event) {
1484
1485 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);
1486 var pageX = event.pageX;
1487 var pageY = event.pageY;
1488
1489 /*
1490 * - Position constraining -
1491 * Constrain the position to a mix of grid, containment.
1492 */
1493
1494 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1495 var containment;
1496 if(this.containment) {
1497 if (this.relative_container){
1498 var co = this.relative_container.offset();
1499 containment = [ this.containment[0] + co.left,
1500 this.containment[1] + co.top,
1501 this.containment[2] + co.left,
1502 this.containment[3] + co.top ];
1503 }
1504 else {
1505 containment = this.containment;
1506 }
1507
1508 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1509 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1510 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1511 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1512 }
1513
1514 if(o.grid) {
1515 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1516 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1517 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;
1518
1519 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1520 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;
1521 }
1522
1523 }
1524
1525 return {
1526 top: (
1527 pageY // The absolute mouse position
1528 - this.offset.click.top // Click offset (relative to the element)
1529 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
1530 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
1531 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1532 ),
1533 left: (
1534 pageX // The absolute mouse position
1535 - this.offset.click.left // Click offset (relative to the element)
1536 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
1537 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
1538 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1539 )
1540 };
1541
1542 },
1543
1544 _clear: function() {
1545 this.helper.removeClass("ui-draggable-dragging");
1546 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1547 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1548 this.helper = null;
1549 this.cancelHelperRemoval = false;
1550 },
1551
1552 // From now on bulk stuff - mainly helpers
1553
1554 _trigger: function(type, event, ui) {
1555 ui = ui || this._uiHash();
1556 $.ui.plugin.call(this, type, [event, ui]);
1557 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1558 return $.Widget.prototype._trigger.call(this, type, event, ui);
1559 },
1560
1561 plugins: {},
1562
1563 _uiHash: function(event) {
1564 return {
1565 helper: this.helper,
1566 position: this.position,
1567 originalPosition: this.originalPosition,
1568 offset: this.positionAbs
1569 };
1570 }
1571
1572 });
1573
1574 $.extend($.ui.draggable, {
1575 version: "1.8.21"
1576 });
1577
1578 $.ui.plugin.add("draggable", "connectToSortable", {
1579 start: function(event, ui) {
1580
1581 var inst = $(this).data("draggable"), o = inst.options,
1582 uiSortable = $.extend({}, ui, { item: inst.element });
1583 inst.sortables = [];
1584 $(o.connectToSortable).each(function() {
1585 var sortable = $.data(this, 'sortable');
1586 if (sortable && !sortable.options.disabled) {
1587 inst.sortables.push({
1588 instance: sortable,
1589 shouldRevert: sortable.options.revert
1590 });
1591 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).
1592 sortable._trigger("activate", event, uiSortable);
1593 }
1594 });
1595
1596 },
1597 stop: function(event, ui) {
1598
1599 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1600 var inst = $(this).data("draggable"),
1601 uiSortable = $.extend({}, ui, { item: inst.element });
1602
1603 $.each(inst.sortables, function() {
1604 if(this.instance.isOver) {
1605
1606 this.instance.isOver = 0;
1607
1608 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1609 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1610
1611 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1612 if(this.shouldRevert) this.instance.options.revert = true;
1613
1614 //Trigger the stop of the sortable
1615 this.instance._mouseStop(event);
1616
1617 this.instance.options.helper = this.instance.options._helper;
1618
1619 //If the helper has been the original item, restore properties in the sortable
1620 if(inst.options.helper == 'original')
1621 this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1622
1623 } else {
1624 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1625 this.instance._trigger("deactivate", event, uiSortable);
1626 }
1627
1628 });
1629
1630 },
1631 drag: function(event, ui) {
1632
1633 var inst = $(this).data("draggable"), self = this;
1634
1635 var checkPos = function(o) {
1636 var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1637 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1638 var itemHeight = o.height, itemWidth = o.width;
1639 var itemTop = o.top, itemLeft = o.left;
1640
1641 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1642 };
1643
1644 $.each(inst.sortables, function(i) {
1645
1646 //Copy over some variables to allow calling the sortable's native _intersectsWith
1647 this.instance.positionAbs = inst.positionAbs;
1648 this.instance.helperProportions = inst.helperProportions;
1649 this.instance.offset.click = inst.offset.click;
1650
1651 if(this.instance._intersectsWith(this.instance.containerCache)) {
1652
1653 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1654 if(!this.instance.isOver) {
1655
1656 this.instance.isOver = 1;
1657 //Now we fake the start of dragging for the sortable instance,
1658 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1659 //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)
1660 this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1661 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1662 this.instance.options.helper = function() { return ui.helper[0]; };
1663
1664 event.target = this.instance.currentItem[0];
1665 this.instance._mouseCapture(event, true);
1666 this.instance._mouseStart(event, true, true);
1667
1668 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1669 this.instance.offset.click.top = inst.offset.click.top;
1670 this.instance.offset.click.left = inst.offset.click.left;
1671 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1672 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1673
1674 inst._trigger("toSortable", event);
1675 inst.dropped = this.instance.element; //draggable revert needs that
1676 //hack so receive/update callbacks work (mostly)
1677 inst.currentItem = inst.element;
1678 this.instance.fromOutside = inst;
1679
1680 }
1681
1682 //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
1683 if(this.instance.currentItem) this.instance._mouseDrag(event);
1684
1685 } else {
1686
1687 //If it doesn't intersect with the sortable, and it intersected before,
1688 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1689 if(this.instance.isOver) {
1690
1691 this.instance.isOver = 0;
1692 this.instance.cancelHelperRemoval = true;
1693
1694 //Prevent reverting on this forced stop
1695 this.instance.options.revert = false;
1696
1697 // The out event needs to be triggered independently
1698 this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1699
1700 this.instance._mouseStop(event, true);
1701 this.instance.options.helper = this.instance.options._helper;
1702
1703 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1704 this.instance.currentItem.remove();
1705 if(this.instance.placeholder) this.instance.placeholder.remove();
1706
1707 inst._trigger("fromSortable", event);
1708 inst.dropped = false; //draggable revert needs that
1709 }
1710
1711 };
1712
1713 });
1714
1715 }
1716 });
1717
1718 $.ui.plugin.add("draggable", "cursor", {
1719 start: function(event, ui) {
1720 var t = $('body'), o = $(this).data('draggable').options;
1721 if (t.css("cursor")) o._cursor = t.css("cursor");
1722 t.css("cursor", o.cursor);
1723 },
1724 stop: function(event, ui) {
1725 var o = $(this).data('draggable').options;
1726 if (o._cursor) $('body').css("cursor", o._cursor);
1727 }
1728 });
1729
1730 $.ui.plugin.add("draggable", "opacity", {
1731 start: function(event, ui) {
1732 var t = $(ui.helper), o = $(this).data('draggable').options;
1733 if(t.css("opacity")) o._opacity = t.css("opacity");
1734 t.css('opacity', o.opacity);
1735 },
1736 stop: function(event, ui) {
1737 var o = $(this).data('draggable').options;
1738 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1739 }
1740 });
1741
1742 $.ui.plugin.add("draggable", "scroll", {
1743 start: function(event, ui) {
1744 var i = $(this).data("draggable");
1745 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1746 },
1747 drag: function(event, ui) {
1748
1749 var i = $(this).data("draggable"), o = i.options, scrolled = false;
1750
1751 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1752
1753 if(!o.axis || o.axis != 'x') {
1754 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1755 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1756 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1757 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1758 }
1759
1760 if(!o.axis || o.axis != 'y') {
1761 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1762 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1763 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1764 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1765 }
1766
1767 } else {
1768
1769 if(!o.axis || o.axis != 'x') {
1770 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1771 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1772 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1773 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1774 }
1775
1776 if(!o.axis || o.axis != 'y') {
1777 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1778 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1779 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1780 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1781 }
1782
1783 }
1784
1785 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1786 $.ui.ddmanager.prepareOffsets(i, event);
1787
1788 }
1789 });
1790
1791 $.ui.plugin.add("draggable", "snap", {
1792 start: function(event, ui) {
1793
1794 var i = $(this).data("draggable"), o = i.options;
1795 i.snapElements = [];
1796
1797 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1798 var $t = $(this); var $o = $t.offset();
1799 if(this != i.element[0]) i.snapElements.push({
1800 item: this,
1801 width: $t.outerWidth(), height: $t.outerHeight(),
1802 top: $o.top, left: $o.left
1803 });
1804 });
1805
1806 },
1807 drag: function(event, ui) {
1808
1809 var inst = $(this).data("draggable"), o = inst.options;
1810 var d = o.snapTolerance;
1811
1812 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1813 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1814
1815 for (var i = inst.snapElements.length - 1; i >= 0; i--){
1816
1817 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1818 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1819
1820 //Yes, I know, this is insane ;)
1821 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))) {
1822 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 })));
1823 inst.snapElements[i].snapping = false;
1824 continue;
1825 }
1826
1827 if(o.snapMode != 'inner') {
1828 var ts = Math.abs(t - y2) <= d;
1829 var bs = Math.abs(b - y1) <= d;
1830 var ls = Math.abs(l - x2) <= d;
1831 var rs = Math.abs(r - x1) <= d;
1832 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1833 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1834 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1835 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1836 }
1837
1838 var first = (ts || bs || ls || rs);
1839
1840 if(o.snapMode != 'outer') {
1841 var ts = Math.abs(t - y1) <= d;
1842 var bs = Math.abs(b - y2) <= d;
1843 var ls = Math.abs(l - x1) <= d;
1844 var rs = Math.abs(r - x2) <= d;
1845 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1846 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1847 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1848 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1849 }
1850
1851 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1852 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1853 inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1854
1855 };
1856
1857 }
1858 });
1859
1860 $.ui.plugin.add("draggable", "stack", {
1861 start: function(event, ui) {
1862
1863 var o = $(this).data("draggable").options;
1864
1865 var group = $.makeArray($(o.stack)).sort(function(a,b) {
1866 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1867 });
1868 if (!group.length) { return; }
1869
1870 var min = parseInt(group[0].style.zIndex) || 0;
1871 $(group).each(function(i) {
1872 this.style.zIndex = min + i;
1873 });
1874
1875 this[0].style.zIndex = min + group.length;
1876
1877 }
1878 });
1879
1880 $.ui.plugin.add("draggable", "zIndex", {
1881 start: function(event, ui) {
1882 var t = $(ui.helper), o = $(this).data("draggable").options;
1883 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1884 t.css('zIndex', o.zIndex);
1885 },
1886 stop: function(event, ui) {
1887 var o = $(this).data("draggable").options;
1888 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1889 }
1890 });
1891
1892 })(jQuery);
1893 /*!
1894 * jQuery UI Droppable 1.8.21
1895 *
1896 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
1897 * Dual licensed under the MIT or GPL Version 2 licenses.
1898 * http://jquery.org/license
1899 *
1900 * http://docs.jquery.com/UI/Droppables
1901 *
1902 * Depends:
1903 * jquery.ui.core.js
1904 * jquery.ui.widget.js
1905 * jquery.ui.mouse.js
1906 * jquery.ui.draggable.js
1907 */
1908 (function( $, undefined ) {
1909
1910 $.widget("ui.droppable", {
1911 widgetEventPrefix: "drop",
1912 options: {
1913 accept: '*',
1914 activeClass: false,
1915 addClasses: true,
1916 greedy: false,
1917 hoverClass: false,
1918 scope: 'default',
1919 tolerance: 'intersect'
1920 },
1921 _create: function() {
1922
1923 var o = this.options, accept = o.accept;
1924 this.isover = 0; this.isout = 1;
1925
1926 this.accept = $.isFunction(accept) ? accept : function(d) {
1927 return d.is(accept);
1928 };
1929
1930 //Store the droppable's proportions
1931 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1932
1933 // Add the reference and positions to the manager
1934 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1935 $.ui.ddmanager.droppables[o.scope].push(this);
1936
1937 (o.addClasses && this.element.addClass("ui-droppable"));
1938
1939 },
1940
1941 destroy: function() {
1942 var drop = $.ui.ddmanager.droppables[this.options.scope];
1943 for ( var i = 0; i < drop.length; i++ )
1944 if ( drop[i] == this )
1945 drop.splice(i, 1);
1946
1947 this.element
1948 .removeClass("ui-droppable ui-droppable-disabled")
1949 .removeData("droppable")
1950 .unbind(".droppable");
1951
1952 return this;
1953 },
1954
1955 _setOption: function(key, value) {
1956
1957 if(key == 'accept') {
1958 this.accept = $.isFunction(value) ? value : function(d) {
1959 return d.is(value);
1960 };
1961 }
1962 $.Widget.prototype._setOption.apply(this, arguments);
1963 },
1964
1965 _activate: function(event) {
1966 var draggable = $.ui.ddmanager.current;
1967 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1968 (draggable && this._trigger('activate', event, this.ui(draggable)));
1969 },
1970
1971 _deactivate: function(event) {
1972 var draggable = $.ui.ddmanager.current;
1973 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1974 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
1975 },
1976
1977 _over: function(event) {
1978
1979 var draggable = $.ui.ddmanager.current;
1980 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1981
1982 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1983 if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1984 this._trigger('over', event, this.ui(draggable));
1985 }
1986
1987 },
1988
1989 _out: function(event) {
1990
1991 var draggable = $.ui.ddmanager.current;
1992 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1993
1994 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1995 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1996 this._trigger('out', event, this.ui(draggable));
1997 }
1998
1999 },
2000
2001 _drop: function(event,custom) {
2002
2003 var draggable = custom || $.ui.ddmanager.current;
2004 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
2005
2006 var childrenIntersection = false;
2007 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
2008 var inst = $.data(this, 'droppable');
2009 if(
2010 inst.options.greedy
2011 && !inst.options.disabled
2012 && inst.options.scope == draggable.options.scope
2013 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
2014 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2015 ) { childrenIntersection = true; return false; }
2016 });
2017 if(childrenIntersection) return false;
2018
2019 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2020 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2021 if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2022 this._trigger('drop', event, this.ui(draggable));
2023 return this.element;
2024 }
2025
2026 return false;
2027
2028 },
2029
2030 ui: function(c) {
2031 return {
2032 draggable: (c.currentItem || c.element),
2033 helper: c.helper,
2034 position: c.position,
2035 offset: c.positionAbs
2036 };
2037 }
2038
2039 });
2040
2041 $.extend($.ui.droppable, {
2042 version: "1.8.21"
2043 });
2044
2045 $.ui.intersect = function(draggable, droppable, toleranceMode) {
2046
2047 if (!droppable.offset) return false;
2048
2049 var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2050 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
2051 var l = droppable.offset.left, r = l + droppable.proportions.width,
2052 t = droppable.offset.top, b = t + droppable.proportions.height;
2053
2054 switch (toleranceMode) {
2055 case 'fit':
2056 return (l <= x1 && x2 <= r
2057 && t <= y1 && y2 <= b);
2058 break;
2059 case 'intersect':
2060 return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
2061 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
2062 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
2063 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2064 break;
2065 case 'pointer':
2066 var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2067 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2068 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2069 return isOver;
2070 break;
2071 case 'touch':
2072 return (
2073 (y1 >= t && y1 <= b) || // Top edge touching
2074 (y2 >= t && y2 <= b) || // Bottom edge touching
2075 (y1 < t && y2 > b) // Surrounded vertically
2076 ) && (
2077 (x1 >= l && x1 <= r) || // Left edge touching
2078 (x2 >= l && x2 <= r) || // Right edge touching
2079 (x1 < l && x2 > r) // Surrounded horizontally
2080 );
2081 break;
2082 default:
2083 return false;
2084 break;
2085 }
2086
2087 };
2088
2089 /*
2090 This manager tracks offsets of draggables and droppables
2091 */
2092 $.ui.ddmanager = {
2093 current: null,
2094 droppables: { 'default': [] },
2095 prepareOffsets: function(t, event) {
2096
2097 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2098 var type = event ? event.type : null; // workaround for #2317
2099 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2100
2101 droppablesLoop: for (var i = 0; i < m.length; i++) {
2102
2103 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
2104 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
2105 m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
2106
2107 if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2108
2109 m[i].offset = m[i].element.offset();
2110 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2111
2112 }
2113
2114 },
2115 drop: function(draggable, event) {
2116
2117 var dropped = false;
2118 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2119
2120 if(!this.options) return;
2121 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2122 dropped = this._drop.call(this, event) || dropped;
2123
2124 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2125 this.isout = 1; this.isover = 0;
2126 this._deactivate.call(this, event);
2127 }
2128
2129 });
2130 return dropped;
2131
2132 },
2133 dragStart: function( draggable, event ) {
2134 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2135 draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
2136 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2137 });
2138 },
2139 drag: function(draggable, event) {
2140
2141 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2142 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2143
2144 //Run through all droppables and check their positions based on specific tolerance options
2145 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2146
2147 if(this.options.disabled || this.greedyChild || !this.visible) return;
2148 var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2149
2150 var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2151 if(!c) return;
2152
2153 var parentInstance;
2154 if (this.options.greedy) {
2155 var parent = this.element.parents(':data(droppable):eq(0)');
2156 if (parent.length) {
2157 parentInstance = $.data(parent[0], 'droppable');
2158 parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2159 }
2160 }
2161
2162 // we just moved into a greedy child
2163 if (parentInstance && c == 'isover') {
2164 parentInstance['isover'] = 0;
2165 parentInstance['isout'] = 1;
2166 parentInstance._out.call(parentInstance, event);
2167 }
2168
2169 this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2170 this[c == "isover" ? "_over" : "_out"].call(this, event);
2171
2172 // we just moved out of a greedy child
2173 if (parentInstance && c == 'isout') {
2174 parentInstance['isout'] = 0;
2175 parentInstance['isover'] = 1;
2176 parentInstance._over.call(parentInstance, event);
2177 }
2178 });
2179
2180 },
2181 dragStop: function( draggable, event ) {
2182 draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
2183 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2184 if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2185 }
2186 };
2187
2188 })(jQuery);
2189 /*!
2190 * jQuery UI Resizable 1.8.21
2191 *
2192 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
2193 * Dual licensed under the MIT or GPL Version 2 licenses.
2194 * http://jquery.org/license
2195 *
2196 * http://docs.jquery.com/UI/Resizables
2197 *
2198 * Depends:
2199 * jquery.ui.core.js
2200 * jquery.ui.mouse.js
2201 * jquery.ui.widget.js
2202 */
2203 (function( $, undefined ) {
2204
2205 $.widget("ui.resizable", $.ui.mouse, {
2206 widgetEventPrefix: "resize",
2207 options: {
2208 alsoResize: false,
2209 animate: false,
2210 animateDuration: "slow",
2211 animateEasing: "swing",
2212 aspectRatio: false,
2213 autoHide: false,
2214 containment: false,
2215 ghost: false,
2216 grid: false,
2217 handles: "e,s,se",
2218 helper: false,
2219 maxHeight: null,
2220 maxWidth: null,
2221 minHeight: 10,
2222 minWidth: 10,
2223 zIndex: 1000
2224 },
2225 _create: function() {
2226
2227 var self = this, o = this.options;
2228 this.element.addClass("ui-resizable");
2229
2230 $.extend(this, {
2231 _aspectRatio: !!(o.aspectRatio),
2232 aspectRatio: o.aspectRatio,
2233 originalElement: this.element,
2234 _proportionallyResizeElements: [],
2235 _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2236 });
2237
2238 //Wrap the element if it cannot hold child nodes
2239 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2240
2241 //Create a wrapper element and set the wrapper to the new current internal element
2242 this.element.wrap(
2243 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2244 position: this.element.css('position'),
2245 width: this.element.outerWidth(),
2246 height: this.element.outerHeight(),
2247 top: this.element.css('top'),
2248 left: this.element.css('left')
2249 })
2250 );
2251
2252 //Overwrite the original this.element
2253 this.element = this.element.parent().data(
2254 "resizable", this.element.data('resizable')
2255 );
2256
2257 this.elementIsWrapper = true;
2258
2259 //Move margins to the wrapper
2260 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2261 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2262
2263 //Prevent Safari textarea resize
2264 this.originalResizeStyle = this.originalElement.css('resize');
2265 this.originalElement.css('resize', 'none');
2266
2267 //Push the actual element to our proportionallyResize internal array
2268 this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2269
2270 // avoid IE jump (hard set the margin)
2271 this.originalElement.css({ margin: this.originalElement.css('margin') });
2272
2273 // fix handlers offset
2274 this._proportionallyResize();
2275
2276 }
2277
2278 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' });
2279 if(this.handles.constructor == String) {
2280
2281 if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2282 var n = this.handles.split(","); this.handles = {};
2283
2284 for(var i = 0; i < n.length; i++) {
2285
2286 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2287 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2288
2289 // Apply zIndex to all handles - see #7960
2290 axis.css({ zIndex: o.zIndex });
2291
2292 //TODO : What's going on here?
2293 if ('se' == handle) {
2294 axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2295 };
2296
2297 //Insert into internal handles object and append to element
2298 this.handles[handle] = '.ui-resizable-'+handle;
2299 this.element.append(axis);
2300 }
2301
2302 }
2303
2304 this._renderAxis = function(target) {
2305
2306 target = target || this.element;
2307
2308 for(var i in this.handles) {
2309
2310 if(this.handles[i].constructor == String)
2311 this.handles[i] = $(this.handles[i], this.element).show();
2312
2313 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2314 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2315
2316 var axis = $(this.handles[i], this.element), padWrapper = 0;
2317
2318 //Checking the correct pad and border
2319 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2320
2321 //The padding type i have to apply...
2322 var padPos = [ 'padding',
2323 /ne|nw|n/.test(i) ? 'Top' :
2324 /se|sw|s/.test(i) ? 'Bottom' :
2325 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
2326
2327 target.css(padPos, padWrapper);
2328
2329 this._proportionallyResize();
2330
2331 }
2332
2333 //TODO: What's that good for? There's not anything to be executed left
2334 if(!$(this.handles[i]).length)
2335 continue;
2336
2337 }
2338 };
2339
2340 //TODO: make renderAxis a prototype function
2341 this._renderAxis(this.element);
2342
2343 this._handles = $('.ui-resizable-handle', this.element)
2344 .disableSelection();
2345
2346 //Matching axis name
2347 this._handles.mouseover(function() {
2348 if (!self.resizing) {
2349 if (this.className)
2350 var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2351 //Axis, default = se
2352 self.axis = axis && axis[1] ? axis[1] : 'se';
2353 }
2354 });
2355
2356 //If we want to auto hide the elements
2357 if (o.autoHide) {
2358 this._handles.hide();
2359 $(this.element)
2360 .addClass("ui-resizable-autohide")
2361 .hover(function() {
2362 if (o.disabled) return;
2363 $(this).removeClass("ui-resizable-autohide");
2364 self._handles.show();
2365 },
2366 function(){
2367 if (o.disabled) return;
2368 if (!self.resizing) {
2369 $(this).addClass("ui-resizable-autohide");
2370 self._handles.hide();
2371 }
2372 });
2373 }
2374
2375 //Initialize the mouse interaction
2376 this._mouseInit();
2377
2378 },
2379
2380 destroy: function() {
2381
2382 this._mouseDestroy();
2383
2384 var _destroy = function(exp) {
2385 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2386 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2387 };
2388
2389 //TODO: Unwrap at same DOM position
2390 if (this.elementIsWrapper) {
2391 _destroy(this.element);
2392 var wrapper = this.element;
2393 wrapper.after(
2394 this.originalElement.css({
2395 position: wrapper.css('position'),
2396 width: wrapper.outerWidth(),
2397 height: wrapper.outerHeight(),
2398 top: wrapper.css('top'),
2399 left: wrapper.css('left')
2400 })
2401 ).remove();
2402 }
2403
2404 this.originalElement.css('resize', this.originalResizeStyle);
2405 _destroy(this.originalElement);
2406
2407 return this;
2408 },
2409
2410 _mouseCapture: function(event) {
2411 var handle = false;
2412 for (var i in this.handles) {
2413 if ($(this.handles[i])[0] == event.target) {
2414 handle = true;
2415 }
2416 }
2417
2418 return !this.options.disabled && handle;
2419 },
2420
2421 _mouseStart: function(event) {
2422
2423 var o = this.options, iniPos = this.element.position(), el = this.element;
2424
2425 this.resizing = true;
2426 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2427
2428 // bugfix for http://dev.jquery.com/ticket/1749
2429 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2430 el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2431 }
2432
2433 this._renderProxy();
2434
2435 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2436
2437 if (o.containment) {
2438 curleft += $(o.containment).scrollLeft() || 0;
2439 curtop += $(o.containment).scrollTop() || 0;
2440 }
2441
2442 //Store needed variables
2443 this.offset = this.helper.offset();
2444 this.position = { left: curleft, top: curtop };
2445 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2446 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2447 this.originalPosition = { left: curleft, top: curtop };
2448 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2449 this.originalMousePosition = { left: event.pageX, top: event.pageY };
2450
2451 //Aspect Ratio
2452 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2453
2454 var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2455 $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2456
2457 el.addClass("ui-resizable-resizing");
2458 this._propagate("start", event);
2459 return true;
2460 },
2461
2462 _mouseDrag: function(event) {
2463
2464 //Increase performance, avoid regex
2465 var el = this.helper, o = this.options, props = {},
2466 self = this, smp = this.originalMousePosition, a = this.axis;
2467
2468 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2469 var trigger = this._change[a];
2470 if (!trigger) return false;
2471
2472 // Calculate the attrs that will be change
2473 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2474
2475 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2476 this._updateVirtualBoundaries(event.shiftKey);
2477 if (this._aspectRatio || event.shiftKey)
2478 data = this._updateRatio(data, event);
2479
2480 data = this._respectSize(data, event);
2481
2482 // plugins callbacks need to be called first
2483 this._propagate("resize", event);
2484
2485 el.css({
2486 top: this.position.top + "px", left: this.position.left + "px",
2487 width: this.size.width + "px", height: this.size.height + "px"
2488 });
2489
2490 if (!this._helper && this._proportionallyResizeElements.length)
2491 this._proportionallyResize();
2492
2493 this._updateCache(data);
2494
2495 // calling the user callback at the end
2496 this._trigger('resize', event, this.ui());
2497
2498 return false;
2499 },
2500
2501 _mouseStop: function(event) {
2502
2503 this.resizing = false;
2504 var o = this.options, self = this;
2505
2506 if(this._helper) {
2507 var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2508 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2509 soffsetw = ista ? 0 : self.sizeDiff.width;
2510
2511 var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) },
2512 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2513 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2514
2515 if (!o.animate)
2516 this.element.css($.extend(s, { top: top, left: left }));
2517
2518 self.helper.height(self.size.height);
2519 self.helper.width(self.size.width);
2520
2521 if (this._helper && !o.animate) this._proportionallyResize();
2522 }
2523
2524 $('body').css('cursor', 'auto');
2525
2526 this.element.removeClass("ui-resizable-resizing");
2527
2528 this._propagate("stop", event);
2529
2530 if (this._helper) this.helper.remove();
2531 return false;
2532
2533 },
2534
2535 _updateVirtualBoundaries: function(forceAspectRatio) {
2536 var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2537
2538 b = {
2539 minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2540 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2541 minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2542 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2543 };
2544
2545 if(this._aspectRatio || forceAspectRatio) {
2546 // We want to create an enclosing box whose aspect ration is the requested one
2547 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2548 pMinWidth = b.minHeight * this.aspectRatio;
2549 pMinHeight = b.minWidth / this.aspectRatio;
2550 pMaxWidth = b.maxHeight * this.aspectRatio;
2551 pMaxHeight = b.maxWidth / this.aspectRatio;
2552
2553 if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2554 if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2555 if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2556 if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2557 }
2558 this._vBoundaries = b;
2559 },
2560
2561 _updateCache: function(data) {
2562 var o = this.options;
2563 this.offset = this.helper.offset();
2564 if (isNumber(data.left)) this.position.left = data.left;
2565 if (isNumber(data.top)) this.position.top = data.top;
2566 if (isNumber(data.height)) this.size.height = data.height;
2567 if (isNumber(data.width)) this.size.width = data.width;
2568 },
2569
2570 _updateRatio: function(data, event) {
2571
2572 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2573
2574 if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2575 else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2576
2577 if (a == 'sw') {
2578 data.left = cpos.left + (csize.width - data.width);
2579 data.top = null;
2580 }
2581 if (a == 'nw') {
2582 data.top = cpos.top + (csize.height - data.height);
2583 data.left = cpos.left + (csize.width - data.width);
2584 }
2585
2586 return data;
2587 },
2588
2589 _respectSize: function(data, event) {
2590
2591 var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2592 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2593 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2594
2595 if (isminw) data.width = o.minWidth;
2596 if (isminh) data.height = o.minHeight;
2597 if (ismaxw) data.width = o.maxWidth;
2598 if (ismaxh) data.height = o.maxHeight;
2599
2600 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2601 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2602
2603 if (isminw && cw) data.left = dw - o.minWidth;
2604 if (ismaxw && cw) data.left = dw - o.maxWidth;
2605 if (isminh && ch) data.top = dh - o.minHeight;
2606 if (ismaxh && ch) data.top = dh - o.maxHeight;
2607
2608 // fixing jump error on top/left - bug #2330
2609 var isNotwh = !data.width && !data.height;
2610 if (isNotwh && !data.left && data.top) data.top = null;
2611 else if (isNotwh && !data.top && data.left) data.left = null;
2612
2613 return data;
2614 },
2615
2616 _proportionallyResize: function() {
2617
2618 var o = this.options;
2619 if (!this._proportionallyResizeElements.length) return;
2620 var element = this.helper || this.element;
2621
2622 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2623
2624 var prel = this._proportionallyResizeElements[i];
2625
2626 if (!this.borderDif) {
2627 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2628 p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2629
2630 this.borderDif = $.map(b, function(v, i) {
2631 var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2632 return border + padding;
2633 });
2634 }
2635
2636 if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2637 continue;
2638
2639 prel.css({
2640 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2641 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2642 });
2643
2644 };
2645
2646 },
2647
2648 _renderProxy: function() {
2649
2650 var el = this.element, o = this.options;
2651 this.elementOffset = el.offset();
2652
2653 if(this._helper) {
2654
2655 this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2656
2657 // fix ie6 offset TODO: This seems broken
2658 var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2659 pxyoffset = ( ie6 ? 2 : -1 );
2660
2661 this.helper.addClass(this._helper).css({
2662 width: this.element.outerWidth() + pxyoffset,
2663 height: this.element.outerHeight() + pxyoffset,
2664 position: 'absolute',
2665 left: this.elementOffset.left - ie6offset +'px',
2666 top: this.elementOffset.top - ie6offset +'px',
2667 zIndex: ++o.zIndex //TODO: Don't modify option
2668 });
2669
2670 this.helper
2671 .appendTo("body")
2672 .disableSelection();
2673
2674 } else {
2675 this.helper = this.element;
2676 }
2677
2678 },
2679
2680 _change: {
2681 e: function(event, dx, dy) {
2682 return { width: this.originalSize.width + dx };
2683 },
2684 w: function(event, dx, dy) {
2685 var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2686 return { left: sp.left + dx, width: cs.width - dx };
2687 },
2688 n: function(event, dx, dy) {
2689 var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2690 return { top: sp.top + dy, height: cs.height - dy };
2691 },
2692 s: function(event, dx, dy) {
2693 return { height: this.originalSize.height + dy };
2694 },
2695 se: function(event, dx, dy) {
2696 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2697 },
2698 sw: function(event, dx, dy) {
2699 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2700 },
2701 ne: function(event, dx, dy) {
2702 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2703 },
2704 nw: function(event, dx, dy) {
2705 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2706 }
2707 },
2708
2709 _propagate: function(n, event) {
2710 $.ui.plugin.call(this, n, [event, this.ui()]);
2711 (n != "resize" && this._trigger(n, event, this.ui()));
2712 },
2713
2714 plugins: {},
2715
2716 ui: function() {
2717 return {
2718 originalElement: this.originalElement,
2719 element: this.element,
2720 helper: this.helper,
2721 position: this.position,
2722 size: this.size,
2723 originalSize: this.originalSize,
2724 originalPosition: this.originalPosition
2725 };
2726 }
2727
2728 });
2729
2730 $.extend($.ui.resizable, {
2731 version: "1.8.21"
2732 });
2733
2734 /*
2735 * Resizable Extensions
2736 */
2737
2738 $.ui.plugin.add("resizable", "alsoResize", {
2739
2740 start: function (event, ui) {
2741 var self = $(this).data("resizable"), o = self.options;
2742
2743 var _store = function (exp) {
2744 $(exp).each(function() {
2745 var el = $(this);
2746 el.data("resizable-alsoresize", {
2747 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2748 left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
2749 });
2750 });
2751 };
2752
2753 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2754 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2755 else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2756 }else{
2757 _store(o.alsoResize);
2758 }
2759 },
2760
2761 resize: function (event, ui) {
2762 var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2763
2764 var delta = {
2765 height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2766 top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2767 },
2768
2769 _alsoResize = function (exp, c) {
2770 $(exp).each(function() {
2771 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
2772 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2773
2774 $.each(css, function (i, prop) {
2775 var sum = (start[prop]||0) + (delta[prop]||0);
2776 if (sum && sum >= 0)
2777 style[prop] = sum || null;
2778 });
2779
2780 el.css(style);
2781 });
2782 };
2783
2784 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2785 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2786 }else{
2787 _alsoResize(o.alsoResize);
2788 }
2789 },
2790
2791 stop: function (event, ui) {
2792 $(this).removeData("resizable-alsoresize");
2793 }
2794 });
2795
2796 $.ui.plugin.add("resizable", "animate", {
2797
2798 stop: function(event, ui) {
2799 var self = $(this).data("resizable"), o = self.options;
2800
2801 var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2802 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2803 soffsetw = ista ? 0 : self.sizeDiff.width;
2804
2805 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2806 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2807 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2808
2809 self.element.animate(
2810 $.extend(style, top && left ? { top: top, left: left } : {}), {
2811 duration: o.animateDuration,
2812 easing: o.animateEasing,
2813 step: function() {
2814
2815 var data = {
2816 width: parseInt(self.element.css('width'), 10),
2817 height: parseInt(self.element.css('height'), 10),
2818 top: parseInt(self.element.css('top'), 10),
2819 left: parseInt(self.element.css('left'), 10)
2820 };
2821
2822 if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2823
2824 // propagating resize, and updating values for each animation step
2825 self._updateCache(data);
2826 self._propagate("resize", event);
2827
2828 }
2829 }
2830 );
2831 }
2832
2833 });
2834
2835 $.ui.plugin.add("resizable", "containment", {
2836
2837 start: function(event, ui) {
2838 var self = $(this).data("resizable"), o = self.options, el = self.element;
2839 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2840 if (!ce) return;
2841
2842 self.containerElement = $(ce);
2843
2844 if (/document/.test(oc) || oc == document) {
2845 self.containerOffset = { left: 0, top: 0 };
2846 self.containerPosition = { left: 0, top: 0 };
2847
2848 self.parentData = {
2849 element: $(document), left: 0, top: 0,
2850 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2851 };
2852 }
2853
2854 // i'm a node, so compute top, left, right, bottom
2855 else {
2856 var element = $(ce), p = [];
2857 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2858
2859 self.containerOffset = element.offset();
2860 self.containerPosition = element.position();
2861 self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2862
2863 var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
2864 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2865
2866 self.parentData = {
2867 element: ce, left: co.left, top: co.top, width: width, height: height
2868 };
2869 }
2870 },
2871
2872 resize: function(event, ui) {
2873 var self = $(this).data("resizable"), o = self.options,
2874 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2875 pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2876
2877 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2878
2879 if (cp.left < (self._helper ? co.left : 0)) {
2880 self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2881 if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2882 self.position.left = o.helper ? co.left : 0;
2883 }
2884
2885 if (cp.top < (self._helper ? co.top : 0)) {
2886 self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2887 if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2888 self.position.top = self._helper ? co.top : 0;
2889 }
2890
2891 self.offset.left = self.parentData.left+self.position.left;
2892 self.offset.top = self.parentData.top+self.position.top;
2893
2894 var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2895 hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2896
2897 var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2898 isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2899
2900 if(isParent && isOffsetRelative) woset -= self.parentData.left;
2901
2902 if (woset + self.size.width >= self.parentData.width) {
2903 self.size.width = self.parentData.width - woset;
2904 if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2905 }
2906
2907 if (hoset + self.size.height >= self.parentData.height) {
2908 self.size.height = self.parentData.height - hoset;
2909 if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2910 }
2911 },
2912
2913 stop: function(event, ui){
2914 var self = $(this).data("resizable"), o = self.options, cp = self.position,
2915 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2916
2917 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2918
2919 if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2920 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2921
2922 if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2923 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2924
2925 }
2926 });
2927
2928 $.ui.plugin.add("resizable", "ghost", {
2929
2930 start: function(event, ui) {
2931
2932 var self = $(this).data("resizable"), o = self.options, cs = self.size;
2933
2934 self.ghost = self.originalElement.clone();
2935 self.ghost
2936 .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2937 .addClass('ui-resizable-ghost')
2938 .addClass(typeof o.ghost == 'string' ? o.ghost : '');
2939
2940 self.ghost.appendTo(self.helper);
2941
2942 },
2943
2944 resize: function(event, ui){
2945 var self = $(this).data("resizable"), o = self.options;
2946 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2947 },
2948
2949 stop: function(event, ui){
2950 var self = $(this).data("resizable"), o = self.options;
2951 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2952 }
2953
2954 });
2955
2956 $.ui.plugin.add("resizable", "grid", {
2957
2958 resize: function(event, ui) {
2959 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;
2960 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2961 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);
2962
2963 if (/^(se|s|e)$/.test(a)) {
2964 self.size.width = os.width + ox;
2965 self.size.height = os.height + oy;
2966 }
2967 else if (/^(ne)$/.test(a)) {
2968 self.size.width = os.width + ox;
2969 self.size.height = os.height + oy;
2970 self.position.top = op.top - oy;
2971 }
2972 else if (/^(sw)$/.test(a)) {
2973 self.size.width = os.width + ox;
2974 self.size.height = os.height + oy;
2975 self.position.left = op.left - ox;
2976 }
2977 else {
2978 self.size.width = os.width + ox;
2979 self.size.height = os.height + oy;
2980 self.position.top = op.top - oy;
2981 self.position.left = op.left - ox;
2982 }
2983 }
2984
2985 });
2986
2987 var num = function(v) {
2988 return parseInt(v, 10) || 0;
2989 };
2990
2991 var isNumber = function(value) {
2992 return !isNaN(parseInt(value, 10));
2993 };
2994
2995 })(jQuery);
2996 /*!
2997 * jQuery UI Selectable 1.8.21
2998 *
2999 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
3000 * Dual licensed under the MIT or GPL Version 2 licenses.
3001 * http://jquery.org/license
3002 *
3003 * http://docs.jquery.com/UI/Selectables
3004 *
3005 * Depends:
3006 * jquery.ui.core.js
3007 * jquery.ui.mouse.js
3008 * jquery.ui.widget.js
3009 */
3010 (function( $, undefined ) {
3011
3012 $.widget("ui.selectable", $.ui.mouse, {
3013 options: {
3014 appendTo: 'body',
3015 autoRefresh: true,
3016 distance: 0,
3017 filter: '*',
3018 tolerance: 'touch'
3019 },
3020 _create: function() {
3021 var self = this;
3022
3023 this.element.addClass("ui-selectable");
3024
3025 this.dragged = false;
3026
3027 // cache selectee children based on filter
3028 var selectees;
3029 this.refresh = function() {
3030 selectees = $(self.options.filter, self.element[0]);
3031 selectees.addClass("ui-selectee");
3032 selectees.each(function() {
3033 var $this = $(this);
3034 var pos = $this.offset();
3035 $.data(this, "selectable-item", {
3036 element: this,
3037 $element: $this,
3038 left: pos.left,
3039 top: pos.top,
3040 right: pos.left + $this.outerWidth(),
3041 bottom: pos.top + $this.outerHeight(),
3042 startselected: false,
3043 selected: $this.hasClass('ui-selected'),
3044 selecting: $this.hasClass('ui-selecting'),
3045 unselecting: $this.hasClass('ui-unselecting')
3046 });
3047 });
3048 };
3049 this.refresh();
3050
3051 this.selectees = selectees.addClass("ui-selectee");
3052
3053 this._mouseInit();
3054
3055 this.helper = $("<div class='ui-selectable-helper'></div>");
3056 },
3057
3058 destroy: function() {
3059 this.selectees
3060 .removeClass("ui-selectee")
3061 .removeData("selectable-item");
3062 this.element
3063 .removeClass("ui-selectable ui-selectable-disabled")
3064 .removeData("selectable")
3065 .unbind(".selectable");
3066 this._mouseDestroy();
3067
3068 return this;
3069 },
3070
3071 _mouseStart: function(event) {
3072 var self = this;
3073
3074 this.opos = [event.pageX, event.pageY];
3075
3076 if (this.options.disabled)
3077 return;
3078
3079 var options = this.options;
3080
3081 this.selectees = $(options.filter, this.element[0]);
3082
3083 this._trigger("start", event);
3084
3085 $(options.appendTo).append(this.helper);
3086 // position helper (lasso)
3087 this.helper.css({
3088 "left": event.clientX,
3089 "top": event.clientY,
3090 "width": 0,
3091 "height": 0
3092 });
3093
3094 if (options.autoRefresh) {
3095 this.refresh();
3096 }
3097
3098 this.selectees.filter('.ui-selected').each(function() {
3099 var selectee = $.data(this, "selectable-item");
3100 selectee.startselected = true;
3101 if (!event.metaKey && !event.ctrlKey) {
3102 selectee.$element.removeClass('ui-selected');
3103 selectee.selected = false;
3104 selectee.$element.addClass('ui-unselecting');
3105 selectee.unselecting = true;
3106 // selectable UNSELECTING callback
3107 self._trigger("unselecting", event, {
3108 unselecting: selectee.element
3109 });
3110 }
3111 });
3112
3113 $(event.target).parents().andSelf().each(function() {
3114 var selectee = $.data(this, "selectable-item");
3115 if (selectee) {
3116 var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
3117 selectee.$element
3118 .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3119 .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3120 selectee.unselecting = !doSelect;
3121 selectee.selecting = doSelect;
3122 selectee.selected = doSelect;
3123 // selectable (UN)SELECTING callback
3124 if (doSelect) {
3125 self._trigger("selecting", event, {
3126 selecting: selectee.element
3127 });
3128 } else {
3129 self._trigger("unselecting", event, {
3130 unselecting: selectee.element
3131 });
3132 }
3133 return false;
3134 }
3135 });
3136
3137 },
3138
3139 _mouseDrag: function(event) {
3140 var self = this;
3141 this.dragged = true;
3142
3143 if (this.options.disabled)
3144 return;
3145
3146 var options = this.options;
3147
3148 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3149 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3150 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3151 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3152
3153 this.selectees.each(function() {
3154 var selectee = $.data(this, "selectable-item");
3155 //prevent helper from being selected if appendTo: selectable
3156 if (!selectee || selectee.element == self.element[0])
3157 return;
3158 var hit = false;
3159 if (options.tolerance == 'touch') {
3160 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3161 } else if (options.tolerance == 'fit') {
3162 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3163 }
3164
3165 if (hit) {
3166 // SELECT
3167 if (selectee.selected) {
3168 selectee.$element.removeClass('ui-selected');
3169 selectee.selected = false;
3170 }
3171 if (selectee.unselecting) {
3172 selectee.$element.removeClass('ui-unselecting');
3173 selectee.unselecting = false;
3174 }
3175 if (!selectee.selecting) {
3176 selectee.$element.addClass('ui-selecting');
3177 selectee.selecting = true;
3178 // selectable SELECTING callback
3179 self._trigger("selecting", event, {
3180 selecting: selectee.element
3181 });
3182 }
3183 } else {
3184 // UNSELECT
3185 if (selectee.selecting) {
3186 if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3187 selectee.$element.removeClass('ui-selecting');
3188 selectee.selecting = false;
3189 selectee.$element.addClass('ui-selected');
3190 selectee.selected = true;
3191 } else {
3192 selectee.$element.removeClass('ui-selecting');
3193 selectee.selecting = false;
3194 if (selectee.startselected) {
3195 selectee.$element.addClass('ui-unselecting');
3196 selectee.unselecting = true;
3197 }
3198 // selectable UNSELECTING callback
3199 self._trigger("unselecting", event, {
3200 unselecting: selectee.element
3201 });
3202 }
3203 }
3204 if (selectee.selected) {
3205 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3206 selectee.$element.removeClass('ui-selected');
3207 selectee.selected = false;
3208
3209 selectee.$element.addClass('ui-unselecting');
3210 selectee.unselecting = true;
3211 // selectable UNSELECTING callback
3212 self._trigger("unselecting", event, {
3213 unselecting: selectee.element
3214 });
3215 }
3216 }
3217 }
3218 });
3219
3220 return false;
3221 },
3222
3223 _mouseStop: function(event) {
3224 var self = this;
3225
3226 this.dragged = false;
3227
3228 var options = this.options;
3229
3230 $('.ui-unselecting', this.element[0]).each(function() {
3231 var selectee = $.data(this, "selectable-item");
3232 selectee.$element.removeClass('ui-unselecting');
3233 selectee.unselecting = false;
3234 selectee.startselected = false;
3235 self._trigger("unselected", event, {
3236 unselected: selectee.element
3237 });
3238 });
3239 $('.ui-selecting', this.element[0]).each(function() {
3240 var selectee = $.data(this, "selectable-item");
3241 selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3242 selectee.selecting = false;
3243 selectee.selected = true;
3244 selectee.startselected = true;
3245 self._trigger("selected", event, {
3246 selected: selectee.element
3247 });
3248 });
3249 this._trigger("stop", event);
3250
3251 this.helper.remove();
3252
3253 return false;
3254 }
3255
3256 });
3257
3258 $.extend($.ui.selectable, {
3259 version: "1.8.21"
3260 });
3261
3262 })(jQuery);
3263 /*!
3264 * jQuery UI Sortable 1.8.21
3265 *
3266 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
3267 * Dual licensed under the MIT or GPL Version 2 licenses.
3268 * http://jquery.org/license
3269 *
3270 * http://docs.jquery.com/UI/Sortables
3271 *
3272 * Depends:
3273 * jquery.ui.core.js
3274 * jquery.ui.mouse.js
3275 * jquery.ui.widget.js
3276 */
3277 (function( $, undefined ) {
3278
3279 $.widget("ui.sortable", $.ui.mouse, {
3280 widgetEventPrefix: "sort",
3281 ready: false,
3282 options: {
3283 appendTo: "parent",
3284 axis: false,
3285 connectWith: false,
3286 containment: false,
3287 cursor: 'auto',
3288 cursorAt: false,
3289 dropOnEmpty: true,
3290 forcePlaceholderSize: false,
3291 forceHelperSize: false,
3292 grid: false,
3293 handle: false,
3294 helper: "original",
3295 items: '> *',
3296 opacity: false,
3297 placeholder: false,
3298 revert: false,
3299 scroll: true,
3300 scrollSensitivity: 20,
3301 scrollSpeed: 20,
3302 scope: "default",
3303 tolerance: "intersect",
3304 zIndex: 1000
3305 },
3306 _create: function() {
3307
3308 var o = this.options;
3309 this.containerCache = {};
3310 this.element.addClass("ui-sortable");
3311
3312 //Get the items
3313 this.refresh();
3314
3315 //Let's determine if the items are being displayed horizontally
3316 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;
3317
3318 //Let's determine the parent's offset
3319 this.offset = this.element.offset();
3320
3321 //Initialize mouse events for interaction
3322 this._mouseInit();
3323
3324 //We're ready to go
3325 this.ready = true
3326
3327 },
3328
3329 destroy: function() {
3330 $.Widget.prototype.destroy.call( this );
3331 this.element
3332 .removeClass("ui-sortable ui-sortable-disabled");
3333 this._mouseDestroy();
3334
3335 for ( var i = this.items.length - 1; i >= 0; i-- )
3336 this.items[i].item.removeData(this.widgetName + "-item");
3337
3338 return this;
3339 },
3340
3341 _setOption: function(key, value){
3342 if ( key === "disabled" ) {
3343 this.options[ key ] = value;
3344
3345 this.widget()
3346 [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3347 } else {
3348 // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3349 $.Widget.prototype._setOption.apply(this, arguments);
3350 }
3351 },
3352
3353 _mouseCapture: function(event, overrideHandle) {
3354 var that = this;
3355
3356 if (this.reverting) {
3357 return false;
3358 }
3359
3360 if(this.options.disabled || this.options.type == 'static') return false;
3361
3362 //We have to refresh the items data once first
3363 this._refreshItems(event);
3364
3365 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3366 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
3367 if($.data(this, that.widgetName + '-item') == self) {
3368 currentItem = $(this);
3369 return false;
3370 }
3371 });
3372 if($.data(event.target, that.widgetName + '-item') == self) currentItem = $(event.target);
3373
3374 if(!currentItem) return false;
3375 if(this.options.handle && !overrideHandle) {
3376 var validHandle = false;
3377
3378 $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3379 if(!validHandle) return false;
3380 }
3381
3382 this.currentItem = currentItem;
3383 this._removeCurrentsFromItems();
3384 return true;
3385
3386 },
3387
3388 _mouseStart: function(event, overrideHandle, noActivation) {
3389
3390 var o = this.options, self = this;
3391 this.currentContainer = this;
3392
3393 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3394 this.refreshPositions();
3395
3396 //Create and append the visible helper
3397 this.helper = this._createHelper(event);
3398
3399 //Cache the helper size
3400 this._cacheHelperProportions();
3401
3402 /*
3403 * - Position generation -
3404 * This block generates everything position related - it's the core of draggables.
3405 */
3406
3407 //Cache the margins of the original element
3408 this._cacheMargins();
3409
3410 //Get the next scrolling parent
3411 this.scrollParent = this.helper.scrollParent();
3412
3413 //The element's absolute position on the page minus margins
3414 this.offset = this.currentItem.offset();
3415 this.offset = {
3416 top: this.offset.top - this.margins.top,
3417 left: this.offset.left - this.margins.left
3418 };
3419
3420 $.extend(this.offset, {
3421 click: { //Where the click happened, relative to the element
3422 left: event.pageX - this.offset.left,
3423 top: event.pageY - this.offset.top
3424 },
3425 parent: this._getParentOffset(),
3426 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3427 });
3428
3429 // Only after we got the offset, we can change the helper's position to absolute
3430 // TODO: Still need to figure out a way to make relative sorting possible
3431 this.helper.css("position", "absolute");
3432 this.cssPosition = this.helper.css("position");
3433
3434 //Generate the original position
3435 this.originalPosition = this._generatePosition(event);
3436 this.originalPageX = event.pageX;
3437 this.originalPageY = event.pageY;
3438
3439 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3440 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3441
3442 //Cache the former DOM position
3443 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3444
3445 //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
3446 if(this.helper[0] != this.currentItem[0]) {
3447 this.currentItem.hide();
3448 }
3449
3450 //Create the placeholder
3451 this._createPlaceholder();
3452
3453 //Set a containment if given in the options
3454 if(o.containment)
3455 this._setContainment();
3456
3457 if(o.cursor) { // cursor option
3458 if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3459 $('body').css("cursor", o.cursor);
3460 }
3461
3462 if(o.opacity) { // opacity option
3463 if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3464 this.helper.css("opacity", o.opacity);
3465 }
3466
3467 if(o.zIndex) { // zIndex option
3468 if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3469 this.helper.css("zIndex", o.zIndex);
3470 }
3471
3472 //Prepare scrolling
3473 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3474 this.overflowOffset = this.scrollParent.offset();
3475
3476 //Call callbacks
3477 this._trigger("start", event, this._uiHash());
3478
3479 //Recache the helper size
3480 if(!this._preserveHelperProportions)
3481 this._cacheHelperProportions();
3482
3483
3484 //Post 'activate' events to possible containers
3485 if(!noActivation) {
3486 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3487 }
3488
3489 //Prepare possible droppables
3490 if($.ui.ddmanager)
3491 $.ui.ddmanager.current = this;
3492
3493 if ($.ui.ddmanager && !o.dropBehaviour)
3494 $.ui.ddmanager.prepareOffsets(this, event);
3495
3496 this.dragging = true;
3497
3498 this.helper.addClass("ui-sortable-helper");
3499 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3500 return true;
3501
3502 },
3503
3504 _mouseDrag: function(event) {
3505
3506 //Compute the helpers position
3507 this.position = this._generatePosition(event);
3508 this.positionAbs = this._convertPositionTo("absolute");
3509
3510 if (!this.lastPositionAbs) {
3511 this.lastPositionAbs = this.positionAbs;
3512 }
3513
3514 //Do scrolling
3515 if(this.options.scroll) {
3516 var o = this.options, scrolled = false;
3517 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3518
3519 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3520 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3521 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3522 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3523
3524 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3525 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3526 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3527 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3528
3529 } else {
3530
3531 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3532 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3533 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3534 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3535
3536 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3537 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3538 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3539 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3540
3541 }
3542
3543 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3544 $.ui.ddmanager.prepareOffsets(this, event);
3545 }
3546
3547 //Regenerate the absolute position used for position checks
3548 this.positionAbs = this._convertPositionTo("absolute");
3549
3550 //Set the helper position
3551 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3552 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3553
3554 //Rearrange
3555 for (var i = this.items.length - 1; i >= 0; i--) {
3556
3557 //Cache variables and intersection, continue if no intersection
3558 var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3559 if (!intersection) continue;
3560
3561 if(itemElement != this.currentItem[0] //cannot intersect with itself
3562 && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3563 && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3564 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3565 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3566 ) {
3567
3568 this.direction = intersection == 1 ? "down" : "up";
3569
3570 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3571 this._rearrange(event, item);
3572 } else {
3573 break;
3574 }
3575
3576 this._trigger("change", event, this._uiHash());
3577 break;
3578 }
3579 }
3580
3581 //Post events to containers
3582 this._contactContainers(event);
3583
3584 //Interconnect with droppables
3585 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3586
3587 //Call callbacks
3588 this._trigger('sort', event, this._uiHash());
3589
3590 this.lastPositionAbs = this.positionAbs;
3591 return false;
3592
3593 },
3594
3595 _mouseStop: function(event, noPropagation) {
3596
3597 if(!event) return;
3598
3599 //If we are using droppables, inform the manager about the drop
3600 if ($.ui.ddmanager && !this.options.dropBehaviour)
3601 $.ui.ddmanager.drop(this, event);
3602
3603 if(this.options.revert) {
3604 var self = this;
3605 var cur = self.placeholder.offset();
3606
3607 self.reverting = true;
3608
3609 $(this.helper).animate({
3610 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3611 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3612 }, parseInt(this.options.revert, 10) || 500, function() {
3613 self._clear(event);
3614 });
3615 } else {
3616 this._clear(event, noPropagation);
3617 }
3618
3619 return false;
3620
3621 },
3622
3623 cancel: function() {
3624
3625 var self = this;
3626
3627 if(this.dragging) {
3628
3629 this._mouseUp({ target: null });
3630
3631 if(this.options.helper == "original")
3632 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3633 else
3634 this.currentItem.show();
3635
3636 //Post deactivating events to containers
3637 for (var i = this.containers.length - 1; i >= 0; i--){
3638 this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3639 if(this.containers[i].containerCache.over) {
3640 this.containers[i]._trigger("out", null, self._uiHash(this));
3641 this.containers[i].containerCache.over = 0;
3642 }
3643 }
3644
3645 }
3646
3647 if (this.placeholder) {
3648 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3649 if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3650 if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3651
3652 $.extend(this, {
3653 helper: null,
3654 dragging: false,
3655 reverting: false,
3656 _noFinalSort: null
3657 });
3658
3659 if(this.domPosition.prev) {
3660 $(this.domPosition.prev).after(this.currentItem);
3661 } else {
3662 $(this.domPosition.parent).prepend(this.currentItem);
3663 }
3664 }
3665
3666 return this;
3667
3668 },
3669
3670 serialize: function(o) {
3671
3672 var items = this._getItemsAsjQuery(o && o.connected);
3673 var str = []; o = o || {};
3674
3675 $(items).each(function() {
3676 var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3677 if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3678 });
3679
3680 if(!str.length && o.key) {
3681 str.push(o.key + '=');
3682 }
3683
3684 return str.join('&');
3685
3686 },
3687
3688 toArray: function(o) {
3689
3690 var items = this._getItemsAsjQuery(o && o.connected);
3691 var ret = []; o = o || {};
3692
3693 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3694 return ret;
3695
3696 },
3697
3698 /* Be careful with the following core functions */
3699 _intersectsWith: function(item) {
3700
3701 var x1 = this.positionAbs.left,
3702 x2 = x1 + this.helperProportions.width,
3703 y1 = this.positionAbs.top,
3704 y2 = y1 + this.helperProportions.height;
3705
3706 var l = item.left,
3707 r = l + item.width,
3708 t = item.top,
3709 b = t + item.height;
3710
3711 var dyClick = this.offset.click.top,
3712 dxClick = this.offset.click.left;
3713
3714 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3715
3716 if( this.options.tolerance == "pointer"
3717 || this.options.forcePointerForContainers
3718 || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3719 ) {
3720 return isOverElement;
3721 } else {
3722
3723 return (l < x1 + (this.helperProportions.width / 2) // Right Half
3724 && x2 - (this.helperProportions.width / 2) < r // Left Half
3725 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3726 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
3727
3728 }
3729 },
3730
3731 _intersectsWithPointer: function(item) {
3732
3733 var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3734 isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3735 isOverElement = isOverElementHeight && isOverElementWidth,
3736 verticalDirection = this._getDragVerticalDirection(),
3737 horizontalDirection = this._getDragHorizontalDirection();
3738
3739 if (!isOverElement)
3740 return false;
3741
3742 return this.floating ?
3743 ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3744 : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3745
3746 },
3747
3748 _intersectsWithSides: function(item) {
3749
3750 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3751 isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3752 verticalDirection = this._getDragVerticalDirection(),
3753 horizontalDirection = this._getDragHorizontalDirection();
3754
3755 if (this.floating && horizontalDirection) {
3756 return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3757 } else {
3758 return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3759 }
3760
3761 },
3762
3763 _getDragVerticalDirection: function() {
3764 var delta = this.positionAbs.top - this.lastPositionAbs.top;
3765 return delta != 0 && (delta > 0 ? "down" : "up");
3766 },
3767
3768 _getDragHorizontalDirection: function() {
3769 var delta = this.positionAbs.left - this.lastPositionAbs.left;
3770 return delta != 0 && (delta > 0 ? "right" : "left");
3771 },
3772
3773 refresh: function(event) {
3774 this._refreshItems(event);
3775 this.refreshPositions();
3776 return this;
3777 },
3778
3779 _connectWith: function() {
3780 var options = this.options;
3781 return options.connectWith.constructor == String
3782 ? [options.connectWith]
3783 : options.connectWith;
3784 },
3785
3786 _getItemsAsjQuery: function(connected) {
3787
3788 var self = this;
3789 var items = [];
3790 var queries = [];
3791 var connectWith = this._connectWith();
3792
3793 if(connectWith && connected) {
3794 for (var i = connectWith.length - 1; i >= 0; i--){
3795 var cur = $(connectWith[i]);
3796 for (var j = cur.length - 1; j >= 0; j--){
3797 var inst = $.data(cur[j], this.widgetName);
3798 if(inst && inst != this && !inst.options.disabled) {
3799 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]);
3800 }
3801 };
3802 };
3803 }
3804
3805 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]);
3806
3807 for (var i = queries.length - 1; i >= 0; i--){
3808 queries[i][0].each(function() {
3809 items.push(this);
3810 });
3811 };
3812
3813 return $(items);
3814
3815 },
3816
3817 _removeCurrentsFromItems: function() {
3818
3819 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3820
3821 for (var i=0; i < this.items.length; i++) {
3822
3823 for (var j=0; j < list.length; j++) {
3824 if(list[j] == this.items[i].item[0])
3825 this.items.splice(i,1);
3826 };
3827
3828 };
3829
3830 },
3831
3832 _refreshItems: function(event) {
3833
3834 this.items = [];
3835 this.containers = [this];
3836 var items = this.items;
3837 var self = this;
3838 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3839 var connectWith = this._connectWith();
3840
3841 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
3842 for (var i = connectWith.length - 1; i >= 0; i--){
3843 var cur = $(connectWith[i]);
3844 for (var j = cur.length - 1; j >= 0; j--){
3845 var inst = $.data(cur[j], this.widgetName);
3846 if(inst && inst != this && !inst.options.disabled) {
3847 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3848 this.containers.push(inst);
3849 }
3850 };
3851 };
3852 }
3853
3854 for (var i = queries.length - 1; i >= 0; i--) {
3855 var targetData = queries[i][1];
3856 var _queries = queries[i][0];
3857
3858 for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3859 var item = $(_queries[j]);
3860
3861 item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
3862
3863 items.push({
3864 item: item,
3865 instance: targetData,
3866 width: 0, height: 0,
3867 left: 0, top: 0
3868 });
3869 };
3870 };
3871
3872 },
3873
3874 refreshPositions: function(fast) {
3875
3876 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3877 if(this.offsetParent && this.helper) {
3878 this.offset.parent = this._getParentOffset();
3879 }
3880
3881 for (var i = this.items.length - 1; i >= 0; i--){
3882 var item = this.items[i];
3883
3884 //We ignore calculating positions of all connected containers when we're not over them
3885 if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3886 continue;
3887
3888 var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3889
3890 if (!fast) {
3891 item.width = t.outerWidth();
3892 item.height = t.outerHeight();
3893 }
3894
3895 var p = t.offset();
3896 item.left = p.left;
3897 item.top = p.top;
3898 };
3899
3900 if(this.options.custom && this.options.custom.refreshContainers) {
3901 this.options.custom.refreshContainers.call(this);
3902 } else {
3903 for (var i = this.containers.length - 1; i >= 0; i--){
3904 var p = this.containers[i].element.offset();
3905 this.containers[i].containerCache.left = p.left;
3906 this.containers[i].containerCache.top = p.top;
3907 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3908 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3909 };
3910 }
3911
3912 return this;
3913 },
3914
3915 _createPlaceholder: function(that) {
3916
3917 var self = that || this, o = self.options;
3918
3919 if(!o.placeholder || o.placeholder.constructor == String) {
3920 var className = o.placeholder;
3921 o.placeholder = {
3922 element: function() {
3923
3924 var el = $(document.createElement(self.currentItem[0].nodeName))
3925 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3926 .removeClass("ui-sortable-helper")[0];
3927
3928 if(!className)
3929 el.style.visibility = "hidden";
3930
3931 return el;
3932 },
3933 update: function(container, p) {
3934
3935 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3936 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3937 if(className && !o.forcePlaceholderSize) return;
3938
3939 //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
3940 if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3941 if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3942 }
3943 };
3944 }
3945
3946 //Create the placeholder
3947 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3948
3949 //Append it after the actual current item
3950 self.currentItem.after(self.placeholder);
3951
3952 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3953 o.placeholder.update(self, self.placeholder);
3954
3955 },
3956
3957 _contactContainers: function(event) {
3958
3959 // get innermost container that intersects with item
3960 var innermostContainer = null, innermostIndex = null;
3961
3962
3963 for (var i = this.containers.length - 1; i >= 0; i--){
3964
3965 // never consider a container that's located within the item itself
3966 if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3967 continue;
3968
3969 if(this._intersectsWith(this.containers[i].containerCache)) {
3970
3971 // if we've already found a container and it's more "inner" than this, then continue
3972 if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3973 continue;
3974
3975 innermostContainer = this.containers[i];
3976 innermostIndex = i;
3977
3978 } else {
3979 // container doesn't intersect. trigger "out" event if necessary
3980 if(this.containers[i].containerCache.over) {
3981 this.containers[i]._trigger("out", event, this._uiHash(this));
3982 this.containers[i].containerCache.over = 0;
3983 }
3984 }
3985
3986 }
3987
3988 // if no intersecting containers found, return
3989 if(!innermostContainer) return;
3990
3991 // move the item into the container if it's not there already
3992 if(this.containers.length === 1) {
3993 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3994 this.containers[innermostIndex].containerCache.over = 1;
3995 } else if(this.currentContainer != this.containers[innermostIndex]) {
3996
3997 //When entering a new container, we will find the item with the least distance and append our item near it
3998 var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
3999 for (var j = this.items.length - 1; j >= 0; j--) {
4000 if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
4001 var cur = this.containers[innermostIndex].floating ? this.items[j].item.offset().left : this.items[j].item.offset().top;
4002 if(Math.abs(cur - base) < dist) {
4003 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4004 this.direction = (cur - base > 0) ? 'down' : 'up';
4005 }
4006 }
4007
4008 if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
4009 return;
4010
4011 this.currentContainer = this.containers[innermostIndex];
4012 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4013 this._trigger("change", event, this._uiHash());
4014 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4015
4016 //Update the placeholder
4017 this.options.placeholder.update(this.currentContainer, this.placeholder);
4018
4019 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4020 this.containers[innermostIndex].containerCache.over = 1;
4021 }
4022
4023
4024 },
4025
4026 _createHelper: function(event) {
4027
4028 var o = this.options;
4029 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
4030
4031 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
4032 $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4033
4034 if(helper[0] == this.currentItem[0])
4035 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") };
4036
4037 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
4038 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
4039
4040 return helper;
4041
4042 },
4043
4044 _adjustOffsetFromHelper: function(obj) {
4045 if (typeof obj == 'string') {
4046 obj = obj.split(' ');
4047 }
4048 if ($.isArray(obj)) {
4049 obj = {left: +obj[0], top: +obj[1] || 0};
4050 }
4051 if ('left' in obj) {
4052 this.offset.click.left = obj.left + this.margins.left;
4053 }
4054 if ('right' in obj) {
4055 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4056 }
4057 if ('top' in obj) {
4058 this.offset.click.top = obj.top + this.margins.top;
4059 }
4060 if ('bottom' in obj) {
4061 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4062 }
4063 },
4064
4065 _getParentOffset: function() {
4066
4067
4068 //Get the offsetParent and cache its position
4069 this.offsetParent = this.helper.offsetParent();
4070 var po = this.offsetParent.offset();
4071
4072 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4073 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4074 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4075 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4076 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
4077 po.left += this.scrollParent.scrollLeft();
4078 po.top += this.scrollParent.scrollTop();
4079 }
4080
4081 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4082 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
4083 po = { top: 0, left: 0 };
4084
4085 return {
4086 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4087 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4088 };
4089
4090 },
4091
4092 _getRelativeOffset: function() {
4093
4094 if(this.cssPosition == "relative") {
4095 var p = this.currentItem.position();
4096 return {
4097 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4098 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4099 };
4100 } else {
4101 return { top: 0, left: 0 };
4102 }
4103
4104 },
4105
4106 _cacheMargins: function() {
4107 this.margins = {
4108 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4109 top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4110 };
4111 },
4112
4113 _cacheHelperProportions: function() {
4114 this.helperProportions = {
4115 width: this.helper.outerWidth(),
4116 height: this.helper.outerHeight()
4117 };
4118 },
4119
4120 _setContainment: function() {
4121
4122 var o = this.options;
4123 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4124 if(o.containment == 'document' || o.containment == 'window') this.containment = [
4125 0 - this.offset.relative.left - this.offset.parent.left,
4126 0 - this.offset.relative.top - this.offset.parent.top,
4127 $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4128 ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4129 ];
4130
4131 if(!(/^(document|window|parent)$/).test(o.containment)) {
4132 var ce = $(o.containment)[0];
4133 var co = $(o.containment).offset();
4134 var over = ($(ce).css("overflow") != 'hidden');
4135
4136 this.containment = [
4137 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4138 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4139 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,
4140 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
4141 ];
4142 }
4143
4144 },
4145
4146 _convertPositionTo: function(d, pos) {
4147
4148 if(!pos) pos = this.position;
4149 var mod = d == "absolute" ? 1 : -1;
4150 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);
4151
4152 return {
4153 top: (
4154 pos.top // The absolute mouse position
4155 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
4156 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
4157 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4158 ),
4159 left: (
4160 pos.left // The absolute mouse position
4161 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
4162 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
4163 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4164 )
4165 };
4166
4167 },
4168
4169 _generatePosition: function(event) {
4170
4171 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);
4172
4173 // This is another very weird special case that only happens for relative elements:
4174 // 1. If the css position is relative
4175 // 2. and the scroll parent is the document or similar to the offset parent
4176 // we have to refresh the relative offset during the scroll so there are no jumps
4177 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4178 this.offset.relative = this._getRelativeOffset();
4179 }
4180
4181 var pageX = event.pageX;
4182 var pageY = event.pageY;
4183
4184 /*
4185 * - Position constraining -
4186 * Constrain the position to a mix of grid, containment.
4187 */
4188
4189 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4190
4191 if(this.containment) {
4192 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4193 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4194 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4195 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4196 }
4197
4198 if(o.grid) {
4199 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4200 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;
4201
4202 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4203 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;
4204 }
4205
4206 }
4207
4208 return {
4209 top: (
4210 pageY // The absolute mouse position
4211 - this.offset.click.top // Click offset (relative to the element)
4212 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
4213 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
4214 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4215 ),
4216 left: (
4217 pageX // The absolute mouse position
4218 - this.offset.click.left // Click offset (relative to the element)
4219 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
4220 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
4221 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4222 )
4223 };
4224
4225 },
4226
4227 _rearrange: function(event, i, a, hardRefresh) {
4228
4229 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));
4230
4231 //Various things done here to improve the performance:
4232 // 1. we create a setTimeout, that calls refreshPositions
4233 // 2. on the instance, we have a counter variable, that get's higher after every append
4234 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4235 // 4. this lets only the last addition to the timeout stack through
4236 this.counter = this.counter ? ++this.counter : 1;
4237 var self = this, counter = this.counter;
4238
4239 window.setTimeout(function() {
4240 if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4241 },0);
4242
4243 },
4244
4245 _clear: function(event, noPropagation) {
4246
4247 this.reverting = false;
4248 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4249 // everything else normalized again
4250 var delayedTriggers = [], self = this;
4251
4252 // We first have to update the dom position of the actual currentItem
4253 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4254 if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4255 this._noFinalSort = null;
4256
4257 if(this.helper[0] == this.currentItem[0]) {
4258 for(var i in this._storedCSS) {
4259 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4260 }
4261 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4262 } else {
4263 this.currentItem.show();
4264 }
4265
4266 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4267 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
4268 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
4269 if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4270 for (var i = this.containers.length - 1; i >= 0; i--){
4271 if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
4272 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4273 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4274 }
4275 };
4276 };
4277
4278 //Post events to containers
4279 for (var i = this.containers.length - 1; i >= 0; i--){
4280 if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4281 if(this.containers[i].containerCache.over) {
4282 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4283 this.containers[i].containerCache.over = 0;
4284 }
4285 }
4286
4287 //Do what was originally in plugins
4288 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4289 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4290 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4291
4292 this.dragging = false;
4293 if(this.cancelHelperRemoval) {
4294 if(!noPropagation) {
4295 this._trigger("beforeStop", event, this._uiHash());
4296 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4297 this._trigger("stop", event, this._uiHash());
4298 }
4299 return false;
4300 }
4301
4302 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4303
4304 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4305 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4306
4307 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4308
4309 if(!noPropagation) {
4310 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4311 this._trigger("stop", event, this._uiHash());
4312 }
4313
4314 this.fromOutside = false;
4315 return true;
4316
4317 },
4318
4319 _trigger: function() {
4320 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4321 this.cancel();
4322 }
4323 },
4324
4325 _uiHash: function(inst) {
4326 var self = inst || this;
4327 return {
4328 helper: self.helper,
4329 placeholder: self.placeholder || $([]),
4330 position: self.position,
4331 originalPosition: self.originalPosition,
4332 offset: self.positionAbs,
4333 item: self.currentItem,
4334 sender: inst ? inst.element : null
4335 };
4336 }
4337
4338 });
4339
4340 $.extend($.ui.sortable, {
4341 version: "1.8.21"
4342 });
4343
4344 })(jQuery);
4345 /*!
4346 * jQuery UI Accordion 1.8.21
4347 *
4348 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
4349 * Dual licensed under the MIT or GPL Version 2 licenses.
4350 * http://jquery.org/license
4351 *
4352 * http://docs.jquery.com/UI/Accordion
4353 *
4354 * Depends:
4355 * jquery.ui.core.js
4356 * jquery.ui.widget.js
4357 */
4358 (function( $, undefined ) {
4359
4360 $.widget( "ui.accordion", {
4361 options: {
4362 active: 0,
4363 animated: "slide",
4364 autoHeight: true,
4365 clearStyle: false,
4366 collapsible: false,
4367 event: "click",
4368 fillSpace: false,
4369 header: "> li > :first-child,> :not(li):even",
4370 icons: {
4371 header: "ui-icon-triangle-1-e",
4372 headerSelected: "ui-icon-triangle-1-s"
4373 },
4374 navigation: false,
4375 navigationFilter: function() {
4376 return this.href.toLowerCase() === location.href.toLowerCase();
4377 }
4378 },
4379
4380 _create: function() {
4381 var self = this,
4382 options = self.options;
4383
4384 self.running = 0;
4385
4386 self.element
4387 .addClass( "ui-accordion ui-widget ui-helper-reset" )
4388 // in lack of child-selectors in CSS
4389 // we need to mark top-LIs in a UL-accordion for some IE-fix
4390 .children( "li" )
4391 .addClass( "ui-accordion-li-fix" );
4392
4393 self.headers = self.element.find( options.header )
4394 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
4395 .bind( "mouseenter.accordion", function() {
4396 if ( options.disabled ) {
4397 return;
4398 }
4399 $( this ).addClass( "ui-state-hover" );
4400 })
4401 .bind( "mouseleave.accordion", function() {
4402 if ( options.disabled ) {
4403 return;
4404 }
4405 $( this ).removeClass( "ui-state-hover" );
4406 })
4407 .bind( "focus.accordion", function() {
4408 if ( options.disabled ) {
4409 return;
4410 }
4411 $( this ).addClass( "ui-state-focus" );
4412 })
4413 .bind( "blur.accordion", function() {
4414 if ( options.disabled ) {
4415 return;
4416 }
4417 $( this ).removeClass( "ui-state-focus" );
4418 });
4419
4420 self.headers.next()
4421 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
4422
4423 if ( options.navigation ) {
4424 var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
4425 if ( current.length ) {
4426 var header = current.closest( ".ui-accordion-header" );
4427 if ( header.length ) {
4428 // anchor within header
4429 self.active = header;
4430 } else {
4431 // anchor within content
4432 self.active = current.closest( ".ui-accordion-content" ).prev();
4433 }
4434 }
4435 }
4436
4437 self.active = self._findActive( self.active || options.active )
4438 .addClass( "ui-state-default ui-state-active" )
4439 .toggleClass( "ui-corner-all" )
4440 .toggleClass( "ui-corner-top" );
4441 self.active.next().addClass( "ui-accordion-content-active" );
4442
4443 self._createIcons();
4444 self.resize();
4445
4446 // ARIA
4447 self.element.attr( "role", "tablist" );
4448
4449 self.headers
4450 .attr( "role", "tab" )
4451 .bind( "keydown.accordion", function( event ) {
4452 return self._keydown( event );
4453 })
4454 .next()
4455 .attr( "role", "tabpanel" );
4456
4457 self.headers
4458 .not( self.active || "" )
4459 .attr({
4460 "aria-expanded": "false",
4461 "aria-selected": "false",
4462 tabIndex: -1
4463 })
4464 .next()
4465 .hide();
4466
4467 // make sure at least one header is in the tab order
4468 if ( !self.active.length ) {
4469 self.headers.eq( 0 ).attr( "tabIndex", 0 );
4470 } else {
4471 self.active
4472 .attr({
4473 "aria-expanded": "true",
4474 "aria-selected": "true",
4475 tabIndex: 0
4476 });
4477 }
4478
4479 // only need links in tab order for Safari
4480 if ( !$.browser.safari ) {
4481 self.headers.find( "a" ).attr( "tabIndex", -1 );
4482 }
4483
4484 if ( options.event ) {
4485 self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
4486 self._clickHandler.call( self, event, this );
4487 event.preventDefault();
4488 });
4489 }
4490 },
4491
4492 _createIcons: function() {
4493 var options = this.options;
4494 if ( options.icons ) {
4495 $( "<span></span>" )
4496 .addClass( "ui-icon " + options.icons.header )
4497 .prependTo( this.headers );
4498 this.active.children( ".ui-icon" )
4499 .toggleClass(options.icons.header)
4500 .toggleClass(options.icons.headerSelected);
4501 this.element.addClass( "ui-accordion-icons" );
4502 }
4503 },
4504
4505 _destroyIcons: function() {
4506 this.headers.children( ".ui-icon" ).remove();
4507 this.element.removeClass( "ui-accordion-icons" );
4508 },
4509
4510 destroy: function() {
4511 var options = this.options;
4512
4513 this.element
4514 .removeClass( "ui-accordion ui-widget ui-helper-reset" )
4515 .removeAttr( "role" );
4516
4517 this.headers
4518 .unbind( ".accordion" )
4519 .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" )
4520 .removeAttr( "role" )
4521 .removeAttr( "aria-expanded" )
4522 .removeAttr( "aria-selected" )
4523 .removeAttr( "tabIndex" );
4524
4525 this.headers.find( "a" ).removeAttr( "tabIndex" );
4526 this._destroyIcons();
4527 var contents = this.headers.next()
4528 .css( "display", "" )
4529 .removeAttr( "role" )
4530 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
4531 if ( options.autoHeight || options.fillHeight ) {
4532 contents.css( "height", "" );
4533 }
4534
4535 return $.Widget.prototype.destroy.call( this );
4536 },
4537
4538 _setOption: function( key, value ) {
4539 $.Widget.prototype._setOption.apply( this, arguments );
4540
4541 if ( key == "active" ) {
4542 this.activate( value );
4543 }
4544 if ( key == "icons" ) {
4545 this._destroyIcons();
4546 if ( value ) {
4547 this._createIcons();
4548 }
4549 }
4550 // #5332 - opacity doesn't cascade to positioned elements in IE
4551 // so we need to add the disabled class to the headers and panels
4552 if ( key == "disabled" ) {
4553 this.headers.add(this.headers.next())
4554 [ value ? "addClass" : "removeClass" ](
4555 "ui-accordion-disabled ui-state-disabled" );
4556 }
4557 },
4558
4559 _keydown: function( event ) {
4560 if ( this.options.disabled || event.altKey || event.ctrlKey ) {
4561 return;
4562 }
4563
4564 var keyCode = $.ui.keyCode,
4565 length = this.headers.length,
4566 currentIndex = this.headers.index( event.target ),
4567 toFocus = false;
4568
4569 switch ( event.keyCode ) {
4570 case keyCode.RIGHT:
4571 case keyCode.DOWN:
4572 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4573 break;
4574 case keyCode.LEFT:
4575 case keyCode.UP:
4576 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4577 break;
4578 case keyCode.SPACE:
4579 case keyCode.ENTER:
4580 this._clickHandler( { target: event.target }, event.target );
4581 event.preventDefault();
4582 }
4583
4584 if ( toFocus ) {
4585 $( event.target ).attr( "tabIndex", -1 );
4586 $( toFocus ).attr( "tabIndex", 0 );
4587 toFocus.focus();
4588 return false;
4589 }
4590
4591 return true;
4592 },
4593
4594 resize: function() {
4595 var options = this.options,
4596 maxHeight;
4597
4598 if ( options.fillSpace ) {
4599 if ( $.browser.msie ) {
4600 var defOverflow = this.element.parent().css( "overflow" );
4601 this.element.parent().css( "overflow", "hidden");
4602 }
4603 maxHeight = this.element.parent().height();
4604 if ($.browser.msie) {
4605 this.element.parent().css( "overflow", defOverflow );
4606 }
4607
4608 this.headers.each(function() {
4609 maxHeight -= $( this ).outerHeight( true );
4610 });
4611
4612 this.headers.next()
4613 .each(function() {
4614 $( this ).height( Math.max( 0, maxHeight -
4615 $( this ).innerHeight() + $( this ).height() ) );
4616 })
4617 .css( "overflow", "auto" );
4618 } else if ( options.autoHeight ) {
4619 maxHeight = 0;
4620 this.headers.next()
4621 .each(function() {
4622 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
4623 })
4624 .height( maxHeight );
4625 }
4626
4627 return this;
4628 },
4629
4630 activate: function( index ) {
4631 // TODO this gets called on init, changing the option without an explicit call for that
4632 this.options.active = index;
4633 // call clickHandler with custom event
4634 var active = this._findActive( index )[ 0 ];
4635 this._clickHandler( { target: active }, active );
4636
4637 return this;
4638 },
4639
4640 _findActive: function( selector ) {
4641 return selector
4642 ? typeof selector === "number"
4643 ? this.headers.filter( ":eq(" + selector + ")" )
4644 : this.headers.not( this.headers.not( selector ) )
4645 : selector === false
4646 ? $( [] )
4647 : this.headers.filter( ":eq(0)" );
4648 },
4649
4650 // TODO isn't event.target enough? why the separate target argument?
4651 _clickHandler: function( event, target ) {
4652 var options = this.options;
4653 if ( options.disabled ) {
4654 return;
4655 }
4656
4657 // called only when using activate(false) to close all parts programmatically
4658 if ( !event.target ) {
4659 if ( !options.collapsible ) {
4660 return;
4661 }
4662 this.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 this.active.next().addClass( "ui-accordion-content-active" );
4669 var toHide = this.active.next(),
4670 data = {
4671 options: options,
4672 newHeader: $( [] ),
4673 oldHeader: options.active,
4674 newContent: $( [] ),
4675 oldContent: toHide
4676 },
4677 toShow = ( this.active = $( [] ) );
4678 this._toggle( toShow, toHide, data );
4679 return;
4680 }
4681
4682 // get the click target
4683 var clicked = $( event.currentTarget || target ),
4684 clickedIsActive = clicked[0] === this.active[0];
4685
4686 // TODO the option is changed, is that correct?
4687 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
4688 options.active = options.collapsible && clickedIsActive ?
4689 false :
4690 this.headers.index( clicked );
4691
4692 // if animations are still active, or the active header is the target, ignore click
4693 if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
4694 return;
4695 }
4696
4697 // find elements to show and hide
4698 var active = this.active,
4699 toShow = clicked.next(),
4700 toHide = this.active.next(),
4701 data = {
4702 options: options,
4703 newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
4704 oldHeader: this.active,
4705 newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
4706 oldContent: toHide
4707 },
4708 down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
4709
4710 // when the call to ._toggle() comes after the class changes
4711 // it causes a very odd bug in IE 8 (see #6720)
4712 this.active = clickedIsActive ? $([]) : clicked;
4713 this._toggle( toShow, toHide, data, clickedIsActive, down );
4714
4715 // switch classes
4716 active
4717 .removeClass( "ui-state-active ui-corner-top" )
4718 .addClass( "ui-state-default ui-corner-all" )
4719 .children( ".ui-icon" )
4720 .removeClass( options.icons.headerSelected )
4721 .addClass( options.icons.header );
4722 if ( !clickedIsActive ) {
4723 clicked
4724 .removeClass( "ui-state-default ui-corner-all" )
4725 .addClass( "ui-state-active ui-corner-top" )
4726 .children( ".ui-icon" )
4727 .removeClass( options.icons.header )
4728 .addClass( options.icons.headerSelected );
4729 clicked
4730 .next()
4731 .addClass( "ui-accordion-content-active" );
4732 }
4733
4734 return;
4735 },
4736
4737 _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
4738 var self = this,
4739 options = self.options;
4740
4741 self.toShow = toShow;
4742 self.toHide = toHide;
4743 self.data = data;
4744
4745 var complete = function() {
4746 if ( !self ) {
4747 return;
4748 }
4749 return self._completed.apply( self, arguments );
4750 };
4751
4752 // trigger changestart event
4753 self._trigger( "changestart", null, self.data );
4754
4755 // count elements to animate
4756 self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
4757
4758 if ( options.animated ) {
4759 var animOptions = {};
4760
4761 if ( options.collapsible && clickedIsActive ) {
4762 animOptions = {
4763 toShow: $( [] ),
4764 toHide: toHide,
4765 complete: complete,
4766 down: down,
4767 autoHeight: options.autoHeight || options.fillSpace
4768 };
4769 } else {
4770 animOptions = {
4771 toShow: toShow,
4772 toHide: toHide,
4773 complete: complete,
4774 down: down,
4775 autoHeight: options.autoHeight || options.fillSpace
4776 };
4777 }
4778
4779 if ( !options.proxied ) {
4780 options.proxied = options.animated;
4781 }
4782
4783 if ( !options.proxiedDuration ) {
4784 options.proxiedDuration = options.duration;
4785 }
4786
4787 options.animated = $.isFunction( options.proxied ) ?
4788 options.proxied( animOptions ) :
4789 options.proxied;
4790
4791 options.duration = $.isFunction( options.proxiedDuration ) ?
4792 options.proxiedDuration( animOptions ) :
4793 options.proxiedDuration;
4794
4795 var animations = $.ui.accordion.animations,
4796 duration = options.duration,
4797 easing = options.animated;
4798
4799 if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
4800 easing = "slide";
4801 }
4802 if ( !animations[ easing ] ) {
4803 animations[ easing ] = function( options ) {
4804 this.slide( options, {
4805 easing: easing,
4806 duration: duration || 700
4807 });
4808 };
4809 }
4810
4811 animations[ easing ]( animOptions );
4812 } else {
4813 if ( options.collapsible && clickedIsActive ) {
4814 toShow.toggle();
4815 } else {
4816 toHide.hide();
4817 toShow.show();
4818 }
4819
4820 complete( true );
4821 }
4822
4823 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
4824 toHide.prev()
4825 .attr({
4826 "aria-expanded": "false",
4827 "aria-selected": "false",
4828 tabIndex: -1
4829 })
4830 .blur();
4831 toShow.prev()
4832 .attr({
4833 "aria-expanded": "true",
4834 "aria-selected": "true",
4835 tabIndex: 0
4836 })
4837 .focus();
4838 },
4839
4840 _completed: function( cancel ) {
4841 this.running = cancel ? 0 : --this.running;
4842 if ( this.running ) {
4843 return;
4844 }
4845
4846 if ( this.options.clearStyle ) {
4847 this.toShow.add( this.toHide ).css({
4848 height: "",
4849 overflow: ""
4850 });
4851 }
4852
4853 // other classes are removed before the animation; this one needs to stay until completed
4854 this.toHide.removeClass( "ui-accordion-content-active" );
4855 // Work around for rendering bug in IE (#5421)
4856 if ( this.toHide.length ) {
4857 this.toHide.parent()[0].className = this.toHide.parent()[0].className;
4858 }
4859
4860 this._trigger( "change", null, this.data );
4861 }
4862 });
4863
4864 $.extend( $.ui.accordion, {
4865 version: "1.8.21",
4866 animations: {
4867 slide: function( options, additions ) {
4868 options = $.extend({
4869 easing: "swing",
4870 duration: 300
4871 }, options, additions );
4872 if ( !options.toHide.size() ) {
4873 options.toShow.animate({
4874 height: "show",
4875 paddingTop: "show",
4876 paddingBottom: "show"
4877 }, options );
4878 return;
4879 }
4880 if ( !options.toShow.size() ) {
4881 options.toHide.animate({
4882 height: "hide",
4883 paddingTop: "hide",
4884 paddingBottom: "hide"
4885 }, options );
4886 return;
4887 }
4888 var overflow = options.toShow.css( "overflow" ),
4889 percentDone = 0,
4890 showProps = {},
4891 hideProps = {},
4892 fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
4893 originalWidth;
4894 // fix width before calculating height of hidden element
4895 var s = options.toShow;
4896 originalWidth = s[0].style.width;
4897 s.width( s.parent().width()
4898 - parseFloat( s.css( "paddingLeft" ) )
4899 - parseFloat( s.css( "paddingRight" ) )
4900 - ( parseFloat( s.css( "borderLeftWidth" ) ) || 0 )
4901 - ( parseFloat( s.css( "borderRightWidth" ) ) || 0 ) );
4902
4903 $.each( fxAttrs, function( i, prop ) {
4904 hideProps[ prop ] = "hide";
4905
4906 var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
4907 showProps[ prop ] = {
4908 value: parts[ 1 ],
4909 unit: parts[ 2 ] || "px"
4910 };
4911 });
4912 options.toShow.css({ height: 0, overflow: "hidden" }).show();
4913 options.toHide
4914 .filter( ":hidden" )
4915 .each( options.complete )
4916 .end()
4917 .filter( ":visible" )
4918 .animate( hideProps, {
4919 step: function( now, settings ) {
4920 // only calculate the percent when animating height
4921 // IE gets very inconsistent results when animating elements
4922 // with small values, which is common for padding
4923 if ( settings.prop == "height" ) {
4924 percentDone = ( settings.end - settings.start === 0 ) ? 0 :
4925 ( settings.now - settings.start ) / ( settings.end - settings.start );
4926 }
4927
4928 options.toShow[ 0 ].style[ settings.prop ] =
4929 ( percentDone * showProps[ settings.prop ].value )
4930 + showProps[ settings.prop ].unit;
4931 },
4932 duration: options.duration,
4933 easing: options.easing,
4934 complete: function() {
4935 if ( !options.autoHeight ) {
4936 options.toShow.css( "height", "" );
4937 }
4938 options.toShow.css({
4939 width: originalWidth,
4940 overflow: overflow
4941 });
4942 options.complete();
4943 }
4944 });
4945 },
4946 bounceslide: function( options ) {
4947 this.slide( options, {
4948 easing: options.down ? "easeOutBounce" : "swing",
4949 duration: options.down ? 1000 : 200
4950 });
4951 }
4952 }
4953 });
4954
4955 })( jQuery );
4956 /*!
4957 * jQuery UI Autocomplete 1.8.21
4958 *
4959 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
4960 * Dual licensed under the MIT or GPL Version 2 licenses.
4961 * http://jquery.org/license
4962 *
4963 * http://docs.jquery.com/UI/Autocomplete
4964 *
4965 * Depends:
4966 * jquery.ui.core.js
4967 * jquery.ui.widget.js
4968 * jquery.ui.position.js
4969 */
4970 (function( $, undefined ) {
4971
4972 // used to prevent race conditions with remote data sources
4973 var requestIndex = 0;
4974
4975 $.widget( "ui.autocomplete", {
4976 options: {
4977 appendTo: "body",
4978 autoFocus: false,
4979 delay: 300,
4980 minLength: 1,
4981 position: {
4982 my: "left top",
4983 at: "left bottom",
4984 collision: "none"
4985 },
4986 source: null
4987 },
4988
4989 pending: 0,
4990
4991 _create: function() {
4992 var self = this,
4993 doc = this.element[ 0 ].ownerDocument,
4994 suppressKeyPress;
4995 this.isMultiLine = this.element.is( "textarea" );
4996
4997 this.element
4998 .addClass( "ui-autocomplete-input" )
4999 .attr( "autocomplete", "off" )
5000 // TODO verify these actually work as intended
5001 .attr({
5002 role: "textbox",
5003 "aria-autocomplete": "list",
5004 "aria-haspopup": "true"
5005 })
5006 .bind( "keydown.autocomplete", function( event ) {
5007 if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
5008 return;
5009 }
5010
5011 suppressKeyPress = false;
5012 var keyCode = $.ui.keyCode;
5013 switch( event.keyCode ) {
5014 case keyCode.PAGE_UP:
5015 self._move( "previousPage", event );
5016 break;
5017 case keyCode.PAGE_DOWN:
5018 self._move( "nextPage", event );
5019 break;
5020 case keyCode.UP:
5021 self._keyEvent( "previous", event );
5022 break;
5023 case keyCode.DOWN:
5024 self._keyEvent( "next", event );
5025 break;
5026 case keyCode.ENTER:
5027 case keyCode.NUMPAD_ENTER:
5028 // when menu is open and has focus
5029 if ( self.menu.active ) {
5030 // #6055 - Opera still allows the keypress to occur
5031 // which causes forms to submit
5032 suppressKeyPress = true;
5033 event.preventDefault();
5034 }
5035 //passthrough - ENTER and TAB both select the current element
5036 case keyCode.TAB:
5037 if ( !self.menu.active ) {
5038 return;
5039 }
5040 self.menu.select( event );
5041 break;
5042 case keyCode.ESCAPE:
5043 self.element.val( self.term );
5044 self.close( event );
5045 break;
5046 default:
5047 // keypress is triggered before the input value is changed
5048 clearTimeout( self.searching );
5049 self.searching = setTimeout(function() {
5050 // only search if the value has changed
5051 if ( self.term != self.element.val() ) {
5052 self.selectedItem = null;
5053 self.search( null, event );
5054 }
5055 }, self.options.delay );
5056 break;
5057 }
5058 })
5059 .bind( "keypress.autocomplete", function( event ) {
5060 if ( suppressKeyPress ) {
5061 suppressKeyPress = false;
5062 event.preventDefault();
5063 }
5064 })
5065 .bind( "focus.autocomplete", function() {
5066 if ( self.options.disabled ) {
5067 return;
5068 }
5069
5070 self.selectedItem = null;
5071 self.previous = self.element.val();
5072 })
5073 .bind( "blur.autocomplete", function( event ) {
5074 if ( self.options.disabled ) {
5075 return;
5076 }
5077
5078 clearTimeout( self.searching );
5079 // clicks on the menu (or a button to trigger a search) will cause a blur event
5080 self.closing = setTimeout(function() {
5081 self.close( event );
5082 self._change( event );
5083 }, 150 );
5084 });
5085 this._initSource();
5086 this.menu = $( "<ul></ul>" )
5087 .addClass( "ui-autocomplete" )
5088 .appendTo( $( this.options.appendTo || "body", doc )[0] )
5089 // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
5090 .mousedown(function( event ) {
5091 // clicking on the scrollbar causes focus to shift to the body
5092 // but we can't detect a mouseup or a click immediately afterward
5093 // so we have to track the next mousedown and close the menu if
5094 // the user clicks somewhere outside of the autocomplete
5095 var menuElement = self.menu.element[ 0 ];
5096 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5097 setTimeout(function() {
5098 $( document ).one( 'mousedown', function( event ) {
5099 if ( event.target !== self.element[ 0 ] &&
5100 event.target !== menuElement &&
5101 !$.ui.contains( menuElement, event.target ) ) {
5102 self.close();
5103 }
5104 });
5105 }, 1 );
5106 }
5107
5108 // use another timeout to make sure the blur-event-handler on the input was already triggered
5109 setTimeout(function() {
5110 clearTimeout( self.closing );
5111 }, 13);
5112 })
5113 .menu({
5114 focus: function( event, ui ) {
5115 var item = ui.item.data( "item.autocomplete" );
5116 if ( false !== self._trigger( "focus", event, { item: item } ) ) {
5117 // use value to match what will end up in the input, if it was a key event
5118 if ( /^key/.test(event.originalEvent.type) ) {
5119 self.element.val( item.value );
5120 }
5121 }
5122 },
5123 selected: function( event, ui ) {
5124 var item = ui.item.data( "item.autocomplete" ),
5125 previous = self.previous;
5126
5127 // only trigger when focus was lost (click on menu)
5128 if ( self.element[0] !== doc.activeElement ) {
5129 self.element.focus();
5130 self.previous = previous;
5131 // #6109 - IE triggers two focus events and the second
5132 // is asynchronous, so we need to reset the previous
5133 // term synchronously and asynchronously :-(
5134 setTimeout(function() {
5135 self.previous = previous;
5136 self.selectedItem = item;
5137 }, 1);
5138 }
5139
5140 if ( false !== self._trigger( "select", event, { item: item } ) ) {
5141 self.element.val( item.value );
5142 }
5143 // reset the term after the select event
5144 // this allows custom select handling to work properly
5145 self.term = self.element.val();
5146
5147 self.close( event );
5148 self.selectedItem = item;
5149 },
5150 blur: function( event, ui ) {
5151 // don't set the value of the text field if it's already correct
5152 // this prevents moving the cursor unnecessarily
5153 if ( self.menu.element.is(":visible") &&
5154 ( self.element.val() !== self.term ) ) {
5155 self.element.val( self.term );
5156 }
5157 }
5158 })
5159 .zIndex( this.element.zIndex() + 1 )
5160 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
5161 .css({ top: 0, left: 0 })
5162 .hide()
5163 .data( "menu" );
5164 if ( $.fn.bgiframe ) {
5165 this.menu.element.bgiframe();
5166 }
5167 // turning off autocomplete prevents the browser from remembering the
5168 // value when navigating through history, so we re-enable autocomplete
5169 // if the page is unloaded before the widget is destroyed. #7790
5170 self.beforeunloadHandler = function() {
5171 self.element.removeAttr( "autocomplete" );
5172 };
5173 $( window ).bind( "beforeunload", self.beforeunloadHandler );
5174 },
5175
5176 destroy: function() {
5177 this.element
5178 .removeClass( "ui-autocomplete-input" )
5179 .removeAttr( "autocomplete" )
5180 .removeAttr( "role" )
5181 .removeAttr( "aria-autocomplete" )
5182 .removeAttr( "aria-haspopup" );
5183 this.menu.element.remove();
5184 $( window ).unbind( "beforeunload", this.beforeunloadHandler );
5185 $.Widget.prototype.destroy.call( this );
5186 },
5187
5188 _setOption: function( key, value ) {
5189 $.Widget.prototype._setOption.apply( this, arguments );
5190 if ( key === "source" ) {
5191 this._initSource();
5192 }
5193 if ( key === "appendTo" ) {
5194 this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
5195 }
5196 if ( key === "disabled" && value && this.xhr ) {
5197 this.xhr.abort();
5198 }
5199 },
5200
5201 _initSource: function() {
5202 var self = this,
5203 array,
5204 url;
5205 if ( $.isArray(this.options.source) ) {
5206 array = this.options.source;
5207 this.source = function( request, response ) {
5208 response( $.ui.autocomplete.filter(array, request.term) );
5209 };
5210 } else if ( typeof this.options.source === "string" ) {
5211 url = this.options.source;
5212 this.source = function( request, response ) {
5213 if ( self.xhr ) {
5214 self.xhr.abort();
5215 }
5216 self.xhr = $.ajax({
5217 url: url,
5218 data: request,
5219 dataType: "json",
5220 success: function( data, status ) {
5221 response( data );
5222 },
5223 error: function() {
5224 response( [] );
5225 }
5226 });
5227 };
5228 } else {
5229 this.source = this.options.source;
5230 }
5231 },
5232
5233 search: function( value, event ) {
5234 value = value != null ? value : this.element.val();
5235
5236 // always save the actual value, not the one passed as an argument
5237 this.term = this.element.val();
5238
5239 if ( value.length < this.options.minLength ) {
5240 return this.close( event );
5241 }
5242
5243 clearTimeout( this.closing );
5244 if ( this._trigger( "search", event ) === false ) {
5245 return;
5246 }
5247
5248 return this._search( value );
5249 },
5250
5251 _search: function( value ) {
5252 this.pending++;
5253 this.element.addClass( "ui-autocomplete-loading" );
5254
5255 this.source( { term: value }, this._response() );
5256 },
5257
5258 _response: function() {
5259 var that = this,
5260 index = ++requestIndex;
5261
5262 return function( content ) {
5263 if ( index === requestIndex ) {
5264 that.__response( content );
5265 }
5266
5267 that.pending--;
5268 if ( !that.pending ) {
5269 that.element.removeClass( "ui-autocomplete-loading" );
5270 }
5271 };
5272 },
5273
5274 __response: function( content ) {
5275 if ( !this.options.disabled && content && content.length ) {
5276 content = this._normalize( content );
5277 this._suggest( content );
5278 this._trigger( "open" );
5279 } else {
5280 this.close();
5281 }
5282 },
5283
5284 close: function( event ) {
5285 clearTimeout( this.closing );
5286 if ( this.menu.element.is(":visible") ) {
5287 this.menu.element.hide();
5288 this.menu.deactivate();
5289 this._trigger( "close", event );
5290 }
5291 },
5292
5293 _change: function( event ) {
5294 if ( this.previous !== this.element.val() ) {
5295 this._trigger( "change", event, { item: this.selectedItem } );
5296 }
5297 },
5298
5299 _normalize: function( items ) {
5300 // assume all items have the right format when the first item is complete
5301 if ( items.length && items[0].label && items[0].value ) {
5302 return items;
5303 }
5304 return $.map( items, function(item) {
5305 if ( typeof item === "string" ) {
5306 return {
5307 label: item,
5308 value: item
5309 };
5310 }
5311 return $.extend({
5312 label: item.label || item.value,
5313 value: item.value || item.label
5314 }, item );
5315 });
5316 },
5317
5318 _suggest: function( items ) {
5319 var ul = this.menu.element
5320 .empty()
5321 .zIndex( this.element.zIndex() + 1 );
5322 this._renderMenu( ul, items );
5323 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
5324 this.menu.deactivate();
5325 this.menu.refresh();
5326
5327 // size and position menu
5328 ul.show();
5329 this._resizeMenu();
5330 ul.position( $.extend({
5331 of: this.element
5332 }, this.options.position ));
5333
5334 if ( this.options.autoFocus ) {
5335 this.menu.next( new $.Event("mouseover") );
5336 }
5337 },
5338
5339 _resizeMenu: function() {
5340 var ul = this.menu.element;
5341 ul.outerWidth( Math.max(
5342 // Firefox wraps long text (possibly a rounding bug)
5343 // so we add 1px to avoid the wrapping (#7513)
5344 ul.width( "" ).outerWidth() + 1,
5345 this.element.outerWidth()
5346 ) );
5347 },
5348
5349 _renderMenu: function( ul, items ) {
5350 var self = this;
5351 $.each( items, function( index, item ) {
5352 self._renderItem( ul, item );
5353 });
5354 },
5355
5356 _renderItem: function( ul, item) {
5357 return $( "<li></li>" )
5358 .data( "item.autocomplete", item )
5359 .append( $( "<a></a>" ).text( item.label ) )
5360 .appendTo( ul );
5361 },
5362
5363 _move: function( direction, event ) {
5364 if ( !this.menu.element.is(":visible") ) {
5365 this.search( null, event );
5366 return;
5367 }
5368 if ( this.menu.first() && /^previous/.test(direction) ||
5369 this.menu.last() && /^next/.test(direction) ) {
5370 this.element.val( this.term );
5371 this.menu.deactivate();
5372 return;
5373 }
5374 this.menu[ direction ]( event );
5375 },
5376
5377 widget: function() {
5378 return this.menu.element;
5379 },
5380 _keyEvent: function( keyEvent, event ) {
5381 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5382 this._move( keyEvent, event );
5383
5384 // prevents moving cursor to beginning/end of the text field in some browsers
5385 event.preventDefault();
5386 }
5387 }
5388 });
5389
5390 $.extend( $.ui.autocomplete, {
5391 escapeRegex: function( value ) {
5392 return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
5393 },
5394 filter: function(array, term) {
5395 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
5396 return $.grep( array, function(value) {
5397 return matcher.test( value.label || value.value || value );
5398 });
5399 }
5400 });
5401
5402 }( jQuery ));
5403
5404 /*
5405 * jQuery UI Menu (not officially released)
5406 *
5407 * This widget isn't yet finished and the API is subject to change. We plan to finish
5408 * it for the next release. You're welcome to give it a try anyway and give us feedback,
5409 * as long as you're okay with migrating your code later on. We can help with that, too.
5410 *
5411 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5412 * Dual licensed under the MIT or GPL Version 2 licenses.
5413 * http://jquery.org/license
5414 *
5415 * http://docs.jquery.com/UI/Menu
5416 *
5417 * Depends:
5418 * jquery.ui.core.js
5419 * jquery.ui.widget.js
5420 */
5421 (function($) {
5422
5423 $.widget("ui.menu", {
5424 _create: function() {
5425 var self = this;
5426 this.element
5427 .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
5428 .attr({
5429 role: "listbox",
5430 "aria-activedescendant": "ui-active-menuitem"
5431 })
5432 .click(function( event ) {
5433 if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
5434 return;
5435 }
5436 // temporary
5437 event.preventDefault();
5438 self.select( event );
5439 });
5440 this.refresh();
5441 },
5442
5443 refresh: function() {
5444 var self = this;
5445
5446 // don't refresh list items that are already adapted
5447 var items = this.element.children("li:not(.ui-menu-item):has(a)")
5448 .addClass("ui-menu-item")
5449 .attr("role", "menuitem");
5450
5451 items.children("a")
5452 .addClass("ui-corner-all")
5453 .attr("tabindex", -1)
5454 // mouseenter doesn't work with event delegation
5455 .mouseenter(function( event ) {
5456 self.activate( event, $(this).parent() );
5457 })
5458 .mouseleave(function() {
5459 self.deactivate();
5460 });
5461 },
5462
5463 activate: function( event, item ) {
5464 this.deactivate();
5465 if (this.hasScroll()) {
5466 var offset = item.offset().top - this.element.offset().top,
5467 scroll = this.element.scrollTop(),
5468 elementHeight = this.element.height();
5469 if (offset < 0) {
5470 this.element.scrollTop( scroll + offset);
5471 } else if (offset >= elementHeight) {
5472 this.element.scrollTop( scroll + offset - elementHeight + item.height());
5473 }
5474 }
5475 this.active = item.eq(0)
5476 .children("a")
5477 .addClass("ui-state-hover")
5478 .attr("id", "ui-active-menuitem")
5479 .end();
5480 this._trigger("focus", event, { item: item });
5481 },
5482
5483 deactivate: function() {
5484 if (!this.active) { return; }
5485
5486 this.active.children("a")
5487 .removeClass("ui-state-hover")
5488 .removeAttr("id");
5489 this._trigger("blur");
5490 this.active = null;
5491 },
5492
5493 next: function(event) {
5494 this.move("next", ".ui-menu-item:first", event);
5495 },
5496
5497 previous: function(event) {
5498 this.move("prev", ".ui-menu-item:last", event);
5499 },
5500
5501 first: function() {
5502 return this.active && !this.active.prevAll(".ui-menu-item").length;
5503 },
5504
5505 last: function() {
5506 return this.active && !this.active.nextAll(".ui-menu-item").length;
5507 },
5508
5509 move: function(direction, edge, event) {
5510 if (!this.active) {
5511 this.activate(event, this.element.children(edge));
5512 return;
5513 }
5514 var next = this.active[direction + "All"](".ui-menu-item").eq(0);
5515 if (next.length) {
5516 this.activate(event, next);
5517 } else {
5518 this.activate(event, this.element.children(edge));
5519 }
5520 },
5521
5522 // TODO merge with previousPage
5523 nextPage: function(event) {
5524 if (this.hasScroll()) {
5525 // TODO merge with no-scroll-else
5526 if (!this.active || this.last()) {
5527 this.activate(event, this.element.children(".ui-menu-item:first"));
5528 return;
5529 }
5530 var base = this.active.offset().top,
5531 height = this.element.height(),
5532 result = this.element.children(".ui-menu-item").filter(function() {
5533 var close = $(this).offset().top - base - height + $(this).height();
5534 // TODO improve approximation
5535 return close < 10 && close > -10;
5536 });
5537
5538 // TODO try to catch this earlier when scrollTop indicates the last page anyway
5539 if (!result.length) {
5540 result = this.element.children(".ui-menu-item:last");
5541 }
5542 this.activate(event, result);
5543 } else {
5544 this.activate(event, this.element.children(".ui-menu-item")
5545 .filter(!this.active || this.last() ? ":first" : ":last"));
5546 }
5547 },
5548
5549 // TODO merge with nextPage
5550 previousPage: function(event) {
5551 if (this.hasScroll()) {
5552 // TODO merge with no-scroll-else
5553 if (!this.active || this.first()) {
5554 this.activate(event, this.element.children(".ui-menu-item:last"));
5555 return;
5556 }
5557
5558 var base = this.active.offset().top,
5559 height = this.element.height(),
5560 result = this.element.children(".ui-menu-item").filter(function() {
5561 var close = $(this).offset().top - base + height - $(this).height();
5562 // TODO improve approximation
5563 return close < 10 && close > -10;
5564 });
5565
5566 // TODO try to catch this earlier when scrollTop indicates the last page anyway
5567 if (!result.length) {
5568 result = this.element.children(".ui-menu-item:first");
5569 }
5570 this.activate(event, result);
5571 } else {
5572 this.activate(event, this.element.children(".ui-menu-item")
5573 .filter(!this.active || this.first() ? ":last" : ":first"));
5574 }
5575 },
5576
5577 hasScroll: function() {
5578 return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
5579 },
5580
5581 select: function( event ) {
5582 this._trigger("selected", event, { item: this.active });
5583 }
5584 });
5585
5586 }(jQuery));
5587 /*!
5588 * jQuery UI Button 1.8.21
5589 *
5590 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
5591 * Dual licensed under the MIT or GPL Version 2 licenses.
5592 * http://jquery.org/license
5593 *
5594 * http://docs.jquery.com/UI/Button
5595 *
5596 * Depends:
5597 * jquery.ui.core.js
5598 * jquery.ui.widget.js
5599 */
5600 (function( $, undefined ) {
5601
5602 var lastActive, startXPos, startYPos, clickDragged,
5603 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
5604 stateClasses = "ui-state-hover ui-state-active ",
5605 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",
5606 formResetHandler = function() {
5607 var buttons = $( this ).find( ":ui-button" );
5608 setTimeout(function() {
5609 buttons.button( "refresh" );
5610 }, 1 );
5611 },
5612 radioGroup = function( radio ) {
5613 var name = radio.name,
5614 form = radio.form,
5615 radios = $( [] );
5616 if ( name ) {
5617 if ( form ) {
5618 radios = $( form ).find( "[name='" + name + "']" );
5619 } else {
5620 radios = $( "[name='" + name + "']", radio.ownerDocument )
5621 .filter(function() {
5622 return !this.form;
5623 });
5624 }
5625 }
5626 return radios;
5627 };
5628
5629 $.widget( "ui.button", {
5630 options: {
5631 disabled: null,
5632 text: true,
5633 label: null,
5634 icons: {
5635 primary: null,
5636 secondary: null
5637 }
5638 },
5639 _create: function() {
5640 this.element.closest( "form" )
5641 .unbind( "reset.button" )
5642 .bind( "reset.button", formResetHandler );
5643
5644 if ( typeof this.options.disabled !== "boolean" ) {
5645 this.options.disabled = !!this.element.propAttr( "disabled" );
5646 } else {
5647 this.element.propAttr( "disabled", this.options.disabled );
5648 }
5649
5650 this._determineButtonType();
5651 this.hasTitle = !!this.buttonElement.attr( "title" );
5652
5653 var self = this,
5654 options = this.options,
5655 toggleButton = this.type === "checkbox" || this.type === "radio",
5656 hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
5657 focusClass = "ui-state-focus";
5658
5659 if ( options.label === null ) {
5660 options.label = this.buttonElement.html();
5661 }
5662
5663 this.buttonElement
5664 .addClass( baseClasses )
5665 .attr( "role", "button" )
5666 .bind( "mouseenter.button", function() {
5667 if ( options.disabled ) {
5668 return;
5669 }
5670 $( this ).addClass( "ui-state-hover" );
5671 if ( this === lastActive ) {
5672 $( this ).addClass( "ui-state-active" );
5673 }
5674 })
5675 .bind( "mouseleave.button", function() {
5676 if ( options.disabled ) {
5677 return;
5678 }
5679 $( this ).removeClass( hoverClass );
5680 })
5681 .bind( "click.button", function( event ) {
5682 if ( options.disabled ) {
5683 event.preventDefault();
5684 event.stopImmediatePropagation();
5685 }
5686 });
5687
5688 this.element
5689 .bind( "focus.button", function() {
5690 // no need to check disabled, focus won't be triggered anyway
5691 self.buttonElement.addClass( focusClass );
5692 })
5693 .bind( "blur.button", function() {
5694 self.buttonElement.removeClass( focusClass );
5695 });
5696
5697 if ( toggleButton ) {
5698 this.element.bind( "change.button", function() {
5699 if ( clickDragged ) {
5700 return;
5701 }
5702 self.refresh();
5703 });
5704 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
5705 // prevents issue where button state changes but checkbox/radio checked state
5706 // does not in Firefox (see ticket #6970)
5707 this.buttonElement
5708 .bind( "mousedown.button", function( event ) {
5709 if ( options.disabled ) {
5710 return;
5711 }
5712 clickDragged = false;
5713 startXPos = event.pageX;
5714 startYPos = event.pageY;
5715 })
5716 .bind( "mouseup.button", function( event ) {
5717 if ( options.disabled ) {
5718 return;
5719 }
5720 if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
5721 clickDragged = true;
5722 }
5723 });
5724 }
5725
5726 if ( this.type === "checkbox" ) {
5727 this.buttonElement.bind( "click.button", function() {
5728 if ( options.disabled || clickDragged ) {
5729 return false;
5730 }
5731 $( this ).toggleClass( "ui-state-active" );
5732 self.buttonElement.attr( "aria-pressed", self.element[0].checked );
5733 });
5734 } else if ( this.type === "radio" ) {
5735 this.buttonElement.bind( "click.button", function() {
5736 if ( options.disabled || clickDragged ) {
5737 return false;
5738 }
5739 $( this ).addClass( "ui-state-active" );
5740 self.buttonElement.attr( "aria-pressed", "true" );
5741
5742 var radio = self.element[ 0 ];
5743 radioGroup( radio )
5744 .not( radio )
5745 .map(function() {
5746 return $( this ).button( "widget" )[ 0 ];
5747 })
5748 .removeClass( "ui-state-active" )
5749 .attr( "aria-pressed", "false" );
5750 });
5751 } else {
5752 this.buttonElement
5753 .bind( "mousedown.button", function() {
5754 if ( options.disabled ) {
5755 return false;
5756 }
5757 $( this ).addClass( "ui-state-active" );
5758 lastActive = this;
5759 $( document ).one( "mouseup", function() {
5760 lastActive = null;
5761 });
5762 })
5763 .bind( "mouseup.button", function() {
5764 if ( options.disabled ) {
5765 return false;
5766 }
5767 $( this ).removeClass( "ui-state-active" );
5768 })
5769 .bind( "keydown.button", function(event) {
5770 if ( options.disabled ) {
5771 return false;
5772 }
5773 if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
5774 $( this ).addClass( "ui-state-active" );
5775 }
5776 })
5777 .bind( "keyup.button", function() {
5778 $( this ).removeClass( "ui-state-active" );
5779 });
5780
5781 if ( this.buttonElement.is("a") ) {
5782 this.buttonElement.keyup(function(event) {
5783 if ( event.keyCode === $.ui.keyCode.SPACE ) {
5784 // TODO pass through original event correctly (just as 2nd argument doesn't work)
5785 $( this ).click();
5786 }
5787 });
5788 }
5789 }
5790
5791 // TODO: pull out $.Widget's handling for the disabled option into
5792 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
5793 // be overridden by individual plugins
5794 this._setOption( "disabled", options.disabled );
5795 this._resetButton();
5796 },
5797
5798 _determineButtonType: function() {
5799
5800 if ( this.element.is(":checkbox") ) {
5801 this.type = "checkbox";
5802 } else if ( this.element.is(":radio") ) {
5803 this.type = "radio";
5804 } else if ( this.element.is("input") ) {
5805 this.type = "input";
5806 } else {
5807 this.type = "button";
5808 }
5809
5810 if ( this.type === "checkbox" || this.type === "radio" ) {
5811 // we don't search against the document in case the element
5812 // is disconnected from the DOM
5813 var ancestor = this.element.parents().filter(":last"),
5814 labelSelector = "label[for='" + this.element.attr("id") + "']";
5815 this.buttonElement = ancestor.find( labelSelector );
5816 if ( !this.buttonElement.length ) {
5817 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
5818 this.buttonElement = ancestor.filter( labelSelector );
5819 if ( !this.buttonElement.length ) {
5820 this.buttonElement = ancestor.find( labelSelector );
5821 }
5822 }
5823 this.element.addClass( "ui-helper-hidden-accessible" );
5824
5825 var checked = this.element.is( ":checked" );
5826 if ( checked ) {
5827 this.buttonElement.addClass( "ui-state-active" );
5828 }
5829 this.buttonElement.attr( "aria-pressed", checked );
5830 } else {
5831 this.buttonElement = this.element;
5832 }
5833 },
5834
5835 widget: function() {
5836 return this.buttonElement;
5837 },
5838
5839 destroy: function() {
5840 this.element
5841 .removeClass( "ui-helper-hidden-accessible" );
5842 this.buttonElement
5843 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
5844 .removeAttr( "role" )
5845 .removeAttr( "aria-pressed" )
5846 .html( this.buttonElement.find(".ui-button-text").html() );
5847
5848 if ( !this.hasTitle ) {
5849 this.buttonElement.removeAttr( "title" );
5850 }
5851
5852 $.Widget.prototype.destroy.call( this );
5853 },
5854
5855 _setOption: function( key, value ) {
5856 $.Widget.prototype._setOption.apply( this, arguments );
5857 if ( key === "disabled" ) {
5858 if ( value ) {
5859 this.element.propAttr( "disabled", true );
5860 } else {
5861 this.element.propAttr( "disabled", false );
5862 }
5863 return;
5864 }
5865 this._resetButton();
5866 },
5867
5868 refresh: function() {
5869 var isDisabled = this.element.is( ":disabled" );
5870 if ( isDisabled !== this.options.disabled ) {
5871 this._setOption( "disabled", isDisabled );
5872 }
5873 if ( this.type === "radio" ) {
5874 radioGroup( this.element[0] ).each(function() {
5875 if ( $( this ).is( ":checked" ) ) {
5876 $( this ).button( "widget" )
5877 .addClass( "ui-state-active" )
5878 .attr( "aria-pressed", "true" );
5879 } else {
5880 $( this ).button( "widget" )
5881 .removeClass( "ui-state-active" )
5882 .attr( "aria-pressed", "false" );
5883 }
5884 });
5885 } else if ( this.type === "checkbox" ) {
5886 if ( this.element.is( ":checked" ) ) {
5887 this.buttonElement
5888 .addClass( "ui-state-active" )
5889 .attr( "aria-pressed", "true" );
5890 } else {
5891 this.buttonElement
5892 .removeClass( "ui-state-active" )
5893 .attr( "aria-pressed", "false" );
5894 }
5895 }
5896 },
5897
5898 _resetButton: function() {
5899 if ( this.type === "input" ) {
5900 if ( this.options.label ) {
5901 this.element.val( this.options.label );
5902 }
5903 return;
5904 }
5905 var buttonElement = this.buttonElement.removeClass( typeClasses ),
5906 buttonText = $( "<span></span>", this.element[0].ownerDocument )
5907 .addClass( "ui-button-text" )
5908 .html( this.options.label )
5909 .appendTo( buttonElement.empty() )
5910 .text(),
5911 icons = this.options.icons,
5912 multipleIcons = icons.primary && icons.secondary,
5913 buttonClasses = [];
5914
5915 if ( icons.primary || icons.secondary ) {
5916 if ( this.options.text ) {
5917 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
5918 }
5919
5920 if ( icons.primary ) {
5921 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
5922 }
5923
5924 if ( icons.secondary ) {
5925 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
5926 }
5927
5928 if ( !this.options.text ) {
5929 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
5930
5931 if ( !this.hasTitle ) {
5932 buttonElement.attr( "title", buttonText );
5933 }
5934 }
5935 } else {
5936 buttonClasses.push( "ui-button-text-only" );
5937 }
5938 buttonElement.addClass( buttonClasses.join( " " ) );
5939 }
5940 });
5941
5942 $.widget( "ui.buttonset", {
5943 options: {
5944 items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
5945 },
5946
5947 _create: function() {
5948 this.element.addClass( "ui-buttonset" );
5949 },
5950
5951 _init: function() {
5952 this.refresh();
5953 },
5954
5955 _setOption: function( key, value ) {
5956 if ( key === "disabled" ) {
5957 this.buttons.button( "option", key, value );
5958 }
5959
5960 $.Widget.prototype._setOption.apply( this, arguments );
5961 },
5962
5963 refresh: function() {
5964 var rtl = this.element.css( "direction" ) === "rtl";
5965
5966 this.buttons = this.element.find( this.options.items )
5967 .filter( ":ui-button" )
5968 .button( "refresh" )
5969 .end()
5970 .not( ":ui-button" )
5971 .button()
5972 .end()
5973 .map(function() {
5974 return $( this ).button( "widget" )[ 0 ];
5975 })
5976 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
5977 .filter( ":first" )
5978 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
5979 .end()
5980 .filter( ":last" )
5981 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
5982 .end()
5983 .end();
5984 },
5985
5986 destroy: function() {
5987 this.element.removeClass( "ui-buttonset" );
5988 this.buttons
5989 .map(function() {
5990 return $( this ).button( "widget" )[ 0 ];
5991 })
5992 .removeClass( "ui-corner-left ui-corner-right" )
5993 .end()
5994 .button( "destroy" );
5995
5996 $.Widget.prototype.destroy.call( this );
5997 }
5998 });
5999
6000 }( jQuery ) );
6001 /*!
6002 * jQuery UI Dialog 1.8.21
6003 *
6004 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
6005 * Dual licensed under the MIT or GPL Version 2 licenses.
6006 * http://jquery.org/license
6007 *
6008 * http://docs.jquery.com/UI/Dialog
6009 *
6010 * Depends:
6011 * jquery.ui.core.js
6012 * jquery.ui.widget.js
6013 * jquery.ui.button.js
6014 * jquery.ui.draggable.js
6015 * jquery.ui.mouse.js
6016 * jquery.ui.position.js
6017 * jquery.ui.resizable.js
6018 */
6019 (function( $, undefined ) {
6020
6021 var uiDialogClasses =
6022 'ui-dialog ' +
6023 'ui-widget ' +
6024 'ui-widget-content ' +
6025 'ui-corner-all ',
6026 sizeRelatedOptions = {
6027 buttons: true,
6028 height: true,
6029 maxHeight: true,
6030 maxWidth: true,
6031 minHeight: true,
6032 minWidth: true,
6033 width: true
6034 },
6035 resizableRelatedOptions = {
6036 maxHeight: true,
6037 maxWidth: true,
6038 minHeight: true,
6039 minWidth: true
6040 },
6041 // support for jQuery 1.3.2 - handle common attrFn methods for dialog
6042 attrFn = $.attrFn || {
6043 val: true,
6044 css: true,
6045 html: true,
6046 text: true,
6047 data: true,
6048 width: true,
6049 height: true,
6050 offset: true,
6051 click: true
6052 };
6053
6054 $.widget("ui.dialog", {
6055 options: {
6056 autoOpen: true,
6057 buttons: {},
6058 closeOnEscape: true,
6059 closeText: 'close',
6060 dialogClass: '',
6061 draggable: true,
6062 hide: null,
6063 height: 'auto',
6064 maxHeight: false,
6065 maxWidth: false,
6066 minHeight: 150,
6067 minWidth: 150,
6068 modal: false,
6069 position: {
6070 my: 'center',
6071 at: 'center',
6072 collision: 'fit',
6073 // ensure that the titlebar is never outside the document
6074 using: function(pos) {
6075 var topOffset = $(this).css(pos).offset().top;
6076 if (topOffset < 0) {
6077 $(this).css('top', pos.top - topOffset);
6078 }
6079 }
6080 },
6081 resizable: true,
6082 show: null,
6083 stack: true,
6084 title: '',
6085 width: 300,
6086 zIndex: 1000
6087 },
6088
6089 _create: function() {
6090 this.originalTitle = this.element.attr('title');
6091 // #5742 - .attr() might return a DOMElement
6092 if ( typeof this.originalTitle !== "string" ) {
6093 this.originalTitle = "";
6094 }
6095
6096 this.options.title = this.options.title || this.originalTitle;
6097 var self = this,
6098 options = self.options,
6099
6100 title = options.title || '&#160;',
6101 titleId = $.ui.dialog.getTitleId(self.element),
6102
6103 uiDialog = (self.uiDialog = $('<div></div>'))
6104 .appendTo(document.body)
6105 .hide()
6106 .addClass(uiDialogClasses + options.dialogClass)
6107 .css({
6108 zIndex: options.zIndex
6109 })
6110 // setting tabIndex makes the div focusable
6111 // setting outline to 0 prevents a border on focus in Mozilla
6112 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
6113 if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
6114 event.keyCode === $.ui.keyCode.ESCAPE) {
6115
6116 self.close(event);
6117 event.preventDefault();
6118 }
6119 })
6120 .attr({
6121 role: 'dialog',
6122 'aria-labelledby': titleId
6123 })
6124 .mousedown(function(event) {
6125 self.moveToTop(false, event);
6126 }),
6127
6128 uiDialogContent = self.element
6129 .show()
6130 .removeAttr('title')
6131 .addClass(
6132 'ui-dialog-content ' +
6133 'ui-widget-content')
6134 .appendTo(uiDialog),
6135
6136 uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
6137 .addClass(
6138 'ui-dialog-titlebar ' +
6139 'ui-widget-header ' +
6140 'ui-corner-all ' +
6141 'ui-helper-clearfix'
6142 )
6143 .prependTo(uiDialog),
6144
6145 uiDialogTitlebarClose = $('<a href="#"></a>')
6146 .addClass(
6147 'ui-dialog-titlebar-close ' +
6148 'ui-corner-all'
6149 )
6150 .attr('role', 'button')
6151 .hover(
6152 function() {
6153 uiDialogTitlebarClose.addClass('ui-state-hover');
6154 },
6155 function() {
6156 uiDialogTitlebarClose.removeClass('ui-state-hover');
6157 }
6158 )
6159 .focus(function() {
6160 uiDialogTitlebarClose.addClass('ui-state-focus');
6161 })
6162 .blur(function() {
6163 uiDialogTitlebarClose.removeClass('ui-state-focus');
6164 })
6165 .click(function(event) {
6166 self.close(event);
6167 return false;
6168 })
6169 .appendTo(uiDialogTitlebar),
6170
6171 uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
6172 .addClass(
6173 'ui-icon ' +
6174 'ui-icon-closethick'
6175 )
6176 .text(options.closeText)
6177 .appendTo(uiDialogTitlebarClose),
6178
6179 uiDialogTitle = $('<span></span>')
6180 .addClass('ui-dialog-title')
6181 .attr('id', titleId)
6182 .html(title)
6183 .prependTo(uiDialogTitlebar);
6184
6185 //handling of deprecated beforeclose (vs beforeClose) option
6186 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6187 //TODO: remove in 1.9pre
6188 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
6189 options.beforeClose = options.beforeclose;
6190 }
6191
6192 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
6193
6194 if (options.draggable && $.fn.draggable) {
6195 self._makeDraggable();
6196 }
6197 if (options.resizable && $.fn.resizable) {
6198 self._makeResizable();
6199 }
6200
6201 self._createButtons(options.buttons);
6202 self._isOpen = false;
6203
6204 if ($.fn.bgiframe) {
6205 uiDialog.bgiframe();
6206 }
6207 },
6208
6209 _init: function() {
6210 if ( this.options.autoOpen ) {
6211 this.open();
6212 }
6213 },
6214
6215 destroy: function() {
6216 var self = this;
6217
6218 if (self.overlay) {
6219 self.overlay.destroy();
6220 }
6221 self.uiDialog.hide();
6222 self.element
6223 .unbind('.dialog')
6224 .removeData('dialog')
6225 .removeClass('ui-dialog-content ui-widget-content')
6226 .hide().appendTo('body');
6227 self.uiDialog.remove();
6228
6229 if (self.originalTitle) {
6230 self.element.attr('title', self.originalTitle);
6231 }
6232
6233 return self;
6234 },
6235
6236 widget: function() {
6237 return this.uiDialog;
6238 },
6239
6240 close: function(event) {
6241 var self = this,
6242 maxZ, thisZ;
6243
6244 if (false === self._trigger('beforeClose', event)) {
6245 return;
6246 }
6247
6248 if (self.overlay) {
6249 self.overlay.destroy();
6250 }
6251 self.uiDialog.unbind('keypress.ui-dialog');
6252
6253 self._isOpen = false;
6254
6255 if (self.options.hide) {
6256 self.uiDialog.hide(self.options.hide, function() {
6257 self._trigger('close', event);
6258 });
6259 } else {
6260 self.uiDialog.hide();
6261 self._trigger('close', event);
6262 }
6263
6264 $.ui.dialog.overlay.resize();
6265
6266 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6267 if (self.options.modal) {
6268 maxZ = 0;
6269 $('.ui-dialog').each(function() {
6270 if (this !== self.uiDialog[0]) {
6271 thisZ = $(this).css('z-index');
6272 if(!isNaN(thisZ)) {
6273 maxZ = Math.max(maxZ, thisZ);
6274 }
6275 }
6276 });
6277 $.ui.dialog.maxZ = maxZ;
6278 }
6279
6280 return self;
6281 },
6282
6283 isOpen: function() {
6284 return this._isOpen;
6285 },
6286
6287 // the force parameter allows us to move modal dialogs to their correct
6288 // position on open
6289 moveToTop: function(force, event) {
6290 var self = this,
6291 options = self.options,
6292 saveScroll;
6293
6294 if ((options.modal && !force) ||
6295 (!options.stack && !options.modal)) {
6296 return self._trigger('focus', event);
6297 }
6298
6299 if (options.zIndex > $.ui.dialog.maxZ) {
6300 $.ui.dialog.maxZ = options.zIndex;
6301 }
6302 if (self.overlay) {
6303 $.ui.dialog.maxZ += 1;
6304 self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
6305 }
6306
6307 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
6308 // http://ui.jquery.com/bugs/ticket/3193
6309 saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
6310 $.ui.dialog.maxZ += 1;
6311 self.uiDialog.css('z-index', $.ui.dialog.maxZ);
6312 self.element.attr(saveScroll);
6313 self._trigger('focus', event);
6314
6315 return self;
6316 },
6317
6318 open: function() {
6319 if (this._isOpen) { return; }
6320
6321 var self = this,
6322 options = self.options,
6323 uiDialog = self.uiDialog;
6324
6325 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
6326 self._size();
6327 self._position(options.position);
6328 uiDialog.show(options.show);
6329 self.moveToTop(true);
6330
6331 // prevent tabbing out of modal dialogs
6332 if ( options.modal ) {
6333 uiDialog.bind( "keydown.ui-dialog", function( event ) {
6334 if ( event.keyCode !== $.ui.keyCode.TAB ) {
6335 return;
6336 }
6337
6338 var tabbables = $(':tabbable', this),
6339 first = tabbables.filter(':first'),
6340 last = tabbables.filter(':last');
6341
6342 if (event.target === last[0] && !event.shiftKey) {
6343 first.focus(1);
6344 return false;
6345 } else if (event.target === first[0] && event.shiftKey) {
6346 last.focus(1);
6347 return false;
6348 }
6349 });
6350 }
6351
6352 // set focus to the first tabbable element in the content area or the first button
6353 // if there are no tabbable elements, set focus on the dialog itself
6354 $(self.element.find(':tabbable').get().concat(
6355 uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
6356 uiDialog.get()))).eq(0).focus();
6357
6358 self._isOpen = true;
6359 self._trigger('open');
6360
6361 return self;
6362 },
6363
6364 _createButtons: function(buttons) {
6365 var self = this,
6366 hasButtons = false,
6367 uiDialogButtonPane = $('<div></div>')
6368 .addClass(
6369 'ui-dialog-buttonpane ' +
6370 'ui-widget-content ' +
6371 'ui-helper-clearfix'
6372 ),
6373 uiButtonSet = $( "<div></div>" )
6374 .addClass( "ui-dialog-buttonset" )
6375 .appendTo( uiDialogButtonPane );
6376
6377 // if we already have a button pane, remove it
6378 self.uiDialog.find('.ui-dialog-buttonpane').remove();
6379
6380 if (typeof buttons === 'object' && buttons !== null) {
6381 $.each(buttons, function() {
6382 return !(hasButtons = true);
6383 });
6384 }
6385 if (hasButtons) {
6386 $.each(buttons, function(name, props) {
6387 props = $.isFunction( props ) ?
6388 { click: props, text: name } :
6389 props;
6390 var button = $('<button type="button"></button>')
6391 .click(function() {
6392 props.click.apply(self.element[0], arguments);
6393 })
6394 .appendTo(uiButtonSet);
6395 // can't use .attr( props, true ) with jQuery 1.3.2.
6396 $.each( props, function( key, value ) {
6397 if ( key === "click" ) {
6398 return;
6399 }
6400 if ( key in attrFn ) {
6401 button[ key ]( value );
6402 } else {
6403 button.attr( key, value );
6404 }
6405 });
6406 if ($.fn.button) {
6407 button.button();
6408 }
6409 });
6410 uiDialogButtonPane.appendTo(self.uiDialog);
6411 }
6412 },
6413
6414 _makeDraggable: function() {
6415 var self = this,
6416 options = self.options,
6417 doc = $(document),
6418 heightBeforeDrag;
6419
6420 function filteredUi(ui) {
6421 return {
6422 position: ui.position,
6423 offset: ui.offset
6424 };
6425 }
6426
6427 self.uiDialog.draggable({
6428 cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
6429 handle: '.ui-dialog-titlebar',
6430 containment: 'document',
6431 start: function(event, ui) {
6432 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
6433 $(this).height($(this).height()).addClass("ui-dialog-dragging");
6434 self._trigger('dragStart', event, filteredUi(ui));
6435 },
6436 drag: function(event, ui) {
6437 self._trigger('drag', event, filteredUi(ui));
6438 },
6439 stop: function(event, ui) {
6440 options.position = [ui.position.left - doc.scrollLeft(),
6441 ui.position.top - doc.scrollTop()];
6442 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
6443 self._trigger('dragStop', event, filteredUi(ui));
6444 $.ui.dialog.overlay.resize();
6445 }
6446 });
6447 },
6448
6449 _makeResizable: function(handles) {
6450 handles = (handles === undefined ? this.options.resizable : handles);
6451 var self = this,
6452 options = self.options,
6453 // .ui-resizable has position: relative defined in the stylesheet
6454 // but dialogs have to use absolute or fixed positioning
6455 position = self.uiDialog.css('position'),
6456 resizeHandles = (typeof handles === 'string' ?
6457 handles :
6458 'n,e,s,w,se,sw,ne,nw'
6459 );
6460
6461 function filteredUi(ui) {
6462 return {
6463 originalPosition: ui.originalPosition,
6464 originalSize: ui.originalSize,
6465 position: ui.position,
6466 size: ui.size
6467 };
6468 }
6469
6470 self.uiDialog.resizable({
6471 cancel: '.ui-dialog-content',
6472 containment: 'document',
6473 alsoResize: self.element,
6474 maxWidth: options.maxWidth,
6475 maxHeight: options.maxHeight,
6476 minWidth: options.minWidth,
6477 minHeight: self._minHeight(),
6478 handles: resizeHandles,
6479 start: function(event, ui) {
6480 $(this).addClass("ui-dialog-resizing");
6481 self._trigger('resizeStart', event, filteredUi(ui));
6482 },
6483 resize: function(event, ui) {
6484 self._trigger('resize', event, filteredUi(ui));
6485 },
6486 stop: function(event, ui) {
6487 $(this).removeClass("ui-dialog-resizing");
6488 options.height = $(this).height();
6489 options.width = $(this).width();
6490 self._trigger('resizeStop', event, filteredUi(ui));
6491 $.ui.dialog.overlay.resize();
6492 }
6493 })
6494 .css('position', position)
6495 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
6496 },
6497
6498 _minHeight: function() {
6499 var options = this.options;
6500
6501 if (options.height === 'auto') {
6502 return options.minHeight;
6503 } else {
6504 return Math.min(options.minHeight, options.height);
6505 }
6506 },
6507
6508 _position: function(position) {
6509 var myAt = [],
6510 offset = [0, 0],
6511 isVisible;
6512
6513 if (position) {
6514 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
6515 // if (typeof position == 'string' || $.isArray(position)) {
6516 // myAt = $.isArray(position) ? position : position.split(' ');
6517
6518 if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
6519 myAt = position.split ? position.split(' ') : [position[0], position[1]];
6520 if (myAt.length === 1) {
6521 myAt[1] = myAt[0];
6522 }
6523
6524 $.each(['left', 'top'], function(i, offsetPosition) {
6525 if (+myAt[i] === myAt[i]) {
6526 offset[i] = myAt[i];
6527 myAt[i] = offsetPosition;
6528 }
6529 });
6530
6531 position = {
6532 my: myAt.join(" "),
6533 at: myAt.join(" "),
6534 offset: offset.join(" ")
6535 };
6536 }
6537
6538 position = $.extend({}, $.ui.dialog.prototype.options.position, position);
6539 } else {
6540 position = $.ui.dialog.prototype.options.position;
6541 }
6542
6543 // need to show the dialog to get the actual offset in the position plugin
6544 isVisible = this.uiDialog.is(':visible');
6545 if (!isVisible) {
6546 this.uiDialog.show();
6547 }
6548 this.uiDialog
6549 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6550 .css({ top: 0, left: 0 })
6551 .position($.extend({ of: window }, position));
6552 if (!isVisible) {
6553 this.uiDialog.hide();
6554 }
6555 },
6556
6557 _setOptions: function( options ) {
6558 var self = this,
6559 resizableOptions = {},
6560 resize = false;
6561
6562 $.each( options, function( key, value ) {
6563 self._setOption( key, value );
6564
6565 if ( key in sizeRelatedOptions ) {
6566 resize = true;
6567 }
6568 if ( key in resizableRelatedOptions ) {
6569 resizableOptions[ key ] = value;
6570 }
6571 });
6572
6573 if ( resize ) {
6574 this._size();
6575 }
6576 if ( this.uiDialog.is( ":data(resizable)" ) ) {
6577 this.uiDialog.resizable( "option", resizableOptions );
6578 }
6579 },
6580
6581 _setOption: function(key, value){
6582 var self = this,
6583 uiDialog = self.uiDialog;
6584
6585 switch (key) {
6586 //handling of deprecated beforeclose (vs beforeClose) option
6587 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6588 //TODO: remove in 1.9pre
6589 case "beforeclose":
6590 key = "beforeClose";
6591 break;
6592 case "buttons":
6593 self._createButtons(value);
6594 break;
6595 case "closeText":
6596 // ensure that we always pass a string
6597 self.uiDialogTitlebarCloseText.text("" + value);
6598 break;
6599 case "dialogClass":
6600 uiDialog
6601 .removeClass(self.options.dialogClass)
6602 .addClass(uiDialogClasses + value);
6603 break;
6604 case "disabled":
6605 if (value) {
6606 uiDialog.addClass('ui-dialog-disabled');
6607 } else {
6608 uiDialog.removeClass('ui-dialog-disabled');
6609 }
6610 break;
6611 case "draggable":
6612 var isDraggable = uiDialog.is( ":data(draggable)" );
6613 if ( isDraggable && !value ) {
6614 uiDialog.draggable( "destroy" );
6615 }
6616
6617 if ( !isDraggable && value ) {
6618 self._makeDraggable();
6619 }
6620 break;
6621 case "position":
6622 self._position(value);
6623 break;
6624 case "resizable":
6625 // currently resizable, becoming non-resizable
6626 var isResizable = uiDialog.is( ":data(resizable)" );
6627 if (isResizable && !value) {
6628 uiDialog.resizable('destroy');
6629 }
6630
6631 // currently resizable, changing handles
6632 if (isResizable && typeof value === 'string') {
6633 uiDialog.resizable('option', 'handles', value);
6634 }
6635
6636 // currently non-resizable, becoming resizable
6637 if (!isResizable && value !== false) {
6638 self._makeResizable(value);
6639 }
6640 break;
6641 case "title":
6642 // convert whatever was passed in o a string, for html() to not throw up
6643 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
6644 break;
6645 }
6646
6647 $.Widget.prototype._setOption.apply(self, arguments);
6648 },
6649
6650 _size: function() {
6651 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
6652 * divs will both have width and height set, so we need to reset them
6653 */
6654 var options = this.options,
6655 nonContentHeight,
6656 minContentHeight,
6657 isVisible = this.uiDialog.is( ":visible" );
6658
6659 // reset content sizing
6660 this.element.show().css({
6661 width: 'auto',
6662 minHeight: 0,
6663 height: 0
6664 });
6665
6666 if (options.minWidth > options.width) {
6667 options.width = options.minWidth;
6668 }
6669
6670 // reset wrapper sizing
6671 // determine the height of all the non-content elements
6672 nonContentHeight = this.uiDialog.css({
6673 height: 'auto',
6674 width: options.width
6675 })
6676 .height();
6677 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
6678
6679 if ( options.height === "auto" ) {
6680 // only needed for IE6 support
6681 if ( $.support.minHeight ) {
6682 this.element.css({
6683 minHeight: minContentHeight,
6684 height: "auto"
6685 });
6686 } else {
6687 this.uiDialog.show();
6688 var autoHeight = this.element.css( "height", "auto" ).height();
6689 if ( !isVisible ) {
6690 this.uiDialog.hide();
6691 }
6692 this.element.height( Math.max( autoHeight, minContentHeight ) );
6693 }
6694 } else {
6695 this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
6696 }
6697
6698 if (this.uiDialog.is(':data(resizable)')) {
6699 this.uiDialog.resizable('option', 'minHeight', this._minHeight());
6700 }
6701 }
6702 });
6703
6704 $.extend($.ui.dialog, {
6705 version: "1.8.21",
6706
6707 uuid: 0,
6708 maxZ: 0,
6709
6710 getTitleId: function($el) {
6711 var id = $el.attr('id');
6712 if (!id) {
6713 this.uuid += 1;
6714 id = this.uuid;
6715 }
6716 return 'ui-dialog-title-' + id;
6717 },
6718
6719 overlay: function(dialog) {
6720 this.$el = $.ui.dialog.overlay.create(dialog);
6721 }
6722 });
6723
6724 $.extend($.ui.dialog.overlay, {
6725 instances: [],
6726 // reuse old instances due to IE memory leak with alpha transparency (see #5185)
6727 oldInstances: [],
6728 maxZ: 0,
6729 events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
6730 function(event) { return event + '.dialog-overlay'; }).join(' '),
6731 create: function(dialog) {
6732 if (this.instances.length === 0) {
6733 // prevent use of anchors and inputs
6734 // we use a setTimeout in case the overlay is created from an
6735 // event that we're going to be cancelling (see #2804)
6736 setTimeout(function() {
6737 // handle $(el).dialog().dialog('close') (see #4065)
6738 if ($.ui.dialog.overlay.instances.length) {
6739 $(document).bind($.ui.dialog.overlay.events, function(event) {
6740 // stop events if the z-index of the target is < the z-index of the overlay
6741 // we cannot return true when we don't want to cancel the event (#3523)
6742 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
6743 return false;
6744 }
6745 });
6746 }
6747 }, 1);
6748
6749 // allow closing by pressing the escape key
6750 $(document).bind('keydown.dialog-overlay', function(event) {
6751 if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
6752 event.keyCode === $.ui.keyCode.ESCAPE) {
6753
6754 dialog.close(event);
6755 event.preventDefault();
6756 }
6757 });
6758
6759 // handle window resize
6760 $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
6761 }
6762
6763 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
6764 .appendTo(document.body)
6765 .css({
6766 width: this.width(),
6767 height: this.height()
6768 });
6769
6770 if ($.fn.bgiframe) {
6771 $el.bgiframe();
6772 }
6773
6774 this.instances.push($el);
6775 return $el;
6776 },
6777
6778 destroy: function($el) {
6779 var indexOf = $.inArray($el, this.instances);
6780 if (indexOf != -1){
6781 this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
6782 }
6783
6784 if (this.instances.length === 0) {
6785 $([document, window]).unbind('.dialog-overlay');
6786 }
6787
6788 $el.remove();
6789
6790 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6791 var maxZ = 0;
6792 $.each(this.instances, function() {
6793 maxZ = Math.max(maxZ, this.css('z-index'));
6794 });
6795 this.maxZ = maxZ;
6796 },
6797
6798 height: function() {
6799 var scrollHeight,
6800 offsetHeight;
6801 // handle IE 6
6802 if ($.browser.msie && $.browser.version < 7) {
6803 scrollHeight = Math.max(
6804 document.documentElement.scrollHeight,
6805 document.body.scrollHeight
6806 );
6807 offsetHeight = Math.max(
6808 document.documentElement.offsetHeight,
6809 document.body.offsetHeight
6810 );
6811
6812 if (scrollHeight < offsetHeight) {
6813 return $(window).height() + 'px';
6814 } else {
6815 return scrollHeight + 'px';
6816 }
6817 // handle "good" browsers
6818 } else {
6819 return $(document).height() + 'px';
6820 }
6821 },
6822
6823 width: function() {
6824 var scrollWidth,
6825 offsetWidth;
6826 // handle IE
6827 if ( $.browser.msie ) {
6828 scrollWidth = Math.max(
6829 document.documentElement.scrollWidth,
6830 document.body.scrollWidth
6831 );
6832 offsetWidth = Math.max(
6833 document.documentElement.offsetWidth,
6834 document.body.offsetWidth
6835 );
6836
6837 if (scrollWidth < offsetWidth) {
6838 return $(window).width() + 'px';
6839 } else {
6840 return scrollWidth + 'px';
6841 }
6842 // handle "good" browsers
6843 } else {
6844 return $(document).width() + 'px';
6845 }
6846 },
6847
6848 resize: function() {
6849 /* If the dialog is draggable and the user drags it past the
6850 * right edge of the window, the document becomes wider so we
6851 * need to stretch the overlay. If the user then drags the
6852 * dialog back to the left, the document will become narrower,
6853 * so we need to shrink the overlay to the appropriate size.
6854 * This is handled by shrinking the overlay before setting it
6855 * to the full document size.
6856 */
6857 var $overlays = $([]);
6858 $.each($.ui.dialog.overlay.instances, function() {
6859 $overlays = $overlays.add(this);
6860 });
6861
6862 $overlays.css({
6863 width: 0,
6864 height: 0
6865 }).css({
6866 width: $.ui.dialog.overlay.width(),
6867 height: $.ui.dialog.overlay.height()
6868 });
6869 }
6870 });
6871
6872 $.extend($.ui.dialog.overlay.prototype, {
6873 destroy: function() {
6874 $.ui.dialog.overlay.destroy(this.$el);
6875 }
6876 });
6877
6878 }(jQuery));
6879 /*!
6880 * jQuery UI Slider 1.8.21
6881 *
6882 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
6883 * Dual licensed under the MIT or GPL Version 2 licenses.
6884 * http://jquery.org/license
6885 *
6886 * http://docs.jquery.com/UI/Slider
6887 *
6888 * Depends:
6889 * jquery.ui.core.js
6890 * jquery.ui.mouse.js
6891 * jquery.ui.widget.js
6892 */
6893 (function( $, undefined ) {
6894
6895 // number of pages in a slider
6896 // (how many times can you page up/down to go through the whole range)
6897 var numPages = 5;
6898
6899 $.widget( "ui.slider", $.ui.mouse, {
6900
6901 widgetEventPrefix: "slide",
6902
6903 options: {
6904 animate: false,
6905 distance: 0,
6906 max: 100,
6907 min: 0,
6908 orientation: "horizontal",
6909 range: false,
6910 step: 1,
6911 value: 0,
6912 values: null
6913 },
6914
6915 _create: function() {
6916 var self = this,
6917 o = this.options,
6918 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
6919 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
6920 handleCount = ( o.values && o.values.length ) || 1,
6921 handles = [];
6922
6923 this._keySliding = false;
6924 this._mouseSliding = false;
6925 this._animateOff = true;
6926 this._handleIndex = null;
6927 this._detectOrientation();
6928 this._mouseInit();
6929
6930 this.element
6931 .addClass( "ui-slider" +
6932 " ui-slider-" + this.orientation +
6933 " ui-widget" +
6934 " ui-widget-content" +
6935 " ui-corner-all" +
6936 ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
6937
6938 this.range = $([]);
6939
6940 if ( o.range ) {
6941 if ( o.range === true ) {
6942 if ( !o.values ) {
6943 o.values = [ this._valueMin(), this._valueMin() ];
6944 }
6945 if ( o.values.length && o.values.length !== 2 ) {
6946 o.values = [ o.values[0], o.values[0] ];
6947 }
6948 }
6949
6950 this.range = $( "<div></div>" )
6951 .appendTo( this.element )
6952 .addClass( "ui-slider-range" +
6953 // note: this isn't the most fittingly semantic framework class for this element,
6954 // but worked best visually with a variety of themes
6955 " ui-widget-header" +
6956 ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
6957 }
6958
6959 for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
6960 handles.push( handle );
6961 }
6962
6963 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
6964
6965 this.handle = this.handles.eq( 0 );
6966
6967 this.handles.add( this.range ).filter( "a" )
6968 .click(function( event ) {
6969 event.preventDefault();
6970 })
6971 .hover(function() {
6972 if ( !o.disabled ) {
6973 $( this ).addClass( "ui-state-hover" );
6974 }
6975 }, function() {
6976 $( this ).removeClass( "ui-state-hover" );
6977 })
6978 .focus(function() {
6979 if ( !o.disabled ) {
6980 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
6981 $( this ).addClass( "ui-state-focus" );
6982 } else {
6983 $( this ).blur();
6984 }
6985 })
6986 .blur(function() {
6987 $( this ).removeClass( "ui-state-focus" );
6988 });
6989
6990 this.handles.each(function( i ) {
6991 $( this ).data( "index.ui-slider-handle", i );
6992 });
6993
6994 this.handles
6995 .keydown(function( event ) {
6996 var index = $( this ).data( "index.ui-slider-handle" ),
6997 allowed,
6998 curVal,
6999 newVal,
7000 step;
7001
7002 if ( self.options.disabled ) {
7003 return;
7004 }
7005
7006 switch ( event.keyCode ) {
7007 case $.ui.keyCode.HOME:
7008 case $.ui.keyCode.END:
7009 case $.ui.keyCode.PAGE_UP:
7010 case $.ui.keyCode.PAGE_DOWN:
7011 case $.ui.keyCode.UP:
7012 case $.ui.keyCode.RIGHT:
7013 case $.ui.keyCode.DOWN:
7014 case $.ui.keyCode.LEFT:
7015 event.preventDefault();
7016 if ( !self._keySliding ) {
7017 self._keySliding = true;
7018 $( this ).addClass( "ui-state-active" );
7019 allowed = self._start( event, index );
7020 if ( allowed === false ) {
7021 return;
7022 }
7023 }
7024 break;
7025 }
7026
7027 step = self.options.step;
7028 if ( self.options.values && self.options.values.length ) {
7029 curVal = newVal = self.values( index );
7030 } else {
7031 curVal = newVal = self.value();
7032 }
7033
7034 switch ( event.keyCode ) {
7035 case $.ui.keyCode.HOME:
7036 newVal = self._valueMin();
7037 break;
7038 case $.ui.keyCode.END:
7039 newVal = self._valueMax();
7040 break;
7041 case $.ui.keyCode.PAGE_UP:
7042 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
7043 break;
7044 case $.ui.keyCode.PAGE_DOWN:
7045 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
7046 break;
7047 case $.ui.keyCode.UP:
7048 case $.ui.keyCode.RIGHT:
7049 if ( curVal === self._valueMax() ) {
7050 return;
7051 }
7052 newVal = self._trimAlignValue( curVal + step );
7053 break;
7054 case $.ui.keyCode.DOWN:
7055 case $.ui.keyCode.LEFT:
7056 if ( curVal === self._valueMin() ) {
7057 return;
7058 }
7059 newVal = self._trimAlignValue( curVal - step );
7060 break;
7061 }
7062
7063 self._slide( event, index, newVal );
7064 })
7065 .keyup(function( event ) {
7066 var index = $( this ).data( "index.ui-slider-handle" );
7067
7068 if ( self._keySliding ) {
7069 self._keySliding = false;
7070 self._stop( event, index );
7071 self._change( event, index );
7072 $( this ).removeClass( "ui-state-active" );
7073 }
7074
7075 });
7076
7077 this._refreshValue();
7078
7079 this._animateOff = false;
7080 },
7081
7082 destroy: function() {
7083 this.handles.remove();
7084 this.range.remove();
7085
7086 this.element
7087 .removeClass( "ui-slider" +
7088 " ui-slider-horizontal" +
7089 " ui-slider-vertical" +
7090 " ui-slider-disabled" +
7091 " ui-widget" +
7092 " ui-widget-content" +
7093 " ui-corner-all" )
7094 .removeData( "slider" )
7095 .unbind( ".slider" );
7096
7097 this._mouseDestroy();
7098
7099 return this;
7100 },
7101
7102 _mouseCapture: function( event ) {
7103 var o = this.options,
7104 position,
7105 normValue,
7106 distance,
7107 closestHandle,
7108 self,
7109 index,
7110 allowed,
7111 offset,
7112 mouseOverHandle;
7113
7114 if ( o.disabled ) {
7115 return false;
7116 }
7117
7118 this.elementSize = {
7119 width: this.element.outerWidth(),
7120 height: this.element.outerHeight()
7121 };
7122 this.elementOffset = this.element.offset();
7123
7124 position = { x: event.pageX, y: event.pageY };
7125 normValue = this._normValueFromMouse( position );
7126 distance = this._valueMax() - this._valueMin() + 1;
7127 self = this;
7128 this.handles.each(function( i ) {
7129 var thisDistance = Math.abs( normValue - self.values(i) );
7130 if ( distance > thisDistance ) {
7131 distance = thisDistance;
7132 closestHandle = $( this );
7133 index = i;
7134 }
7135 });
7136
7137 // workaround for bug #3736 (if both handles of a range are at 0,
7138 // the first is always used as the one with least distance,
7139 // and moving it is obviously prevented by preventing negative ranges)
7140 if( o.range === true && this.values(1) === o.min ) {
7141 index += 1;
7142 closestHandle = $( this.handles[index] );
7143 }
7144
7145 allowed = this._start( event, index );
7146 if ( allowed === false ) {
7147 return false;
7148 }
7149 this._mouseSliding = true;
7150
7151 self._handleIndex = index;
7152
7153 closestHandle
7154 .addClass( "ui-state-active" )
7155 .focus();
7156
7157 offset = closestHandle.offset();
7158 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
7159 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
7160 left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
7161 top: event.pageY - offset.top -
7162 ( closestHandle.height() / 2 ) -
7163 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
7164 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
7165 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
7166 };
7167
7168 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
7169 this._slide( event, index, normValue );
7170 }
7171 this._animateOff = true;
7172 return true;
7173 },
7174
7175 _mouseStart: function( event ) {
7176 return true;
7177 },
7178
7179 _mouseDrag: function( event ) {
7180 var position = { x: event.pageX, y: event.pageY },
7181 normValue = this._normValueFromMouse( position );
7182
7183 this._slide( event, this._handleIndex, normValue );
7184
7185 return false;
7186 },
7187
7188 _mouseStop: function( event ) {
7189 this.handles.removeClass( "ui-state-active" );
7190 this._mouseSliding = false;
7191
7192 this._stop( event, this._handleIndex );
7193 this._change( event, this._handleIndex );
7194
7195 this._handleIndex = null;
7196 this._clickOffset = null;
7197 this._animateOff = false;
7198
7199 return false;
7200 },
7201
7202 _detectOrientation: function() {
7203 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
7204 },
7205
7206 _normValueFromMouse: function( position ) {
7207 var pixelTotal,
7208 pixelMouse,
7209 percentMouse,
7210 valueTotal,
7211 valueMouse;
7212
7213 if ( this.orientation === "horizontal" ) {
7214 pixelTotal = this.elementSize.width;
7215 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
7216 } else {
7217 pixelTotal = this.elementSize.height;
7218 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
7219 }
7220
7221 percentMouse = ( pixelMouse / pixelTotal );
7222 if ( percentMouse > 1 ) {
7223 percentMouse = 1;
7224 }
7225 if ( percentMouse < 0 ) {
7226 percentMouse = 0;
7227 }
7228 if ( this.orientation === "vertical" ) {
7229 percentMouse = 1 - percentMouse;
7230 }
7231
7232 valueTotal = this._valueMax() - this._valueMin();
7233 valueMouse = this._valueMin() + percentMouse * valueTotal;
7234
7235 return this._trimAlignValue( valueMouse );
7236 },
7237
7238 _start: function( event, index ) {
7239 var uiHash = {
7240 handle: this.handles[ index ],
7241 value: this.value()
7242 };
7243 if ( this.options.values && this.options.values.length ) {
7244 uiHash.value = this.values( index );
7245 uiHash.values = this.values();
7246 }
7247 return this._trigger( "start", event, uiHash );
7248 },
7249
7250 _slide: function( event, index, newVal ) {
7251 var otherVal,
7252 newValues,
7253 allowed;
7254
7255 if ( this.options.values && this.options.values.length ) {
7256 otherVal = this.values( index ? 0 : 1 );
7257
7258 if ( ( this.options.values.length === 2 && this.options.range === true ) &&
7259 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
7260 ) {
7261 newVal = otherVal;
7262 }
7263
7264 if ( newVal !== this.values( index ) ) {
7265 newValues = this.values();
7266 newValues[ index ] = newVal;
7267 // A slide can be canceled by returning false from the slide callback
7268 allowed = this._trigger( "slide", event, {
7269 handle: this.handles[ index ],
7270 value: newVal,
7271 values: newValues
7272 } );
7273 otherVal = this.values( index ? 0 : 1 );
7274 if ( allowed !== false ) {
7275 this.values( index, newVal, true );
7276 }
7277 }
7278 } else {
7279 if ( newVal !== this.value() ) {
7280 // A slide can be canceled by returning false from the slide callback
7281 allowed = this._trigger( "slide", event, {
7282 handle: this.handles[ index ],
7283 value: newVal
7284 } );
7285 if ( allowed !== false ) {
7286 this.value( newVal );
7287 }
7288 }
7289 }
7290 },
7291
7292 _stop: function( event, index ) {
7293 var uiHash = {
7294 handle: this.handles[ index ],
7295 value: this.value()
7296 };
7297 if ( this.options.values && this.options.values.length ) {
7298 uiHash.value = this.values( index );
7299 uiHash.values = this.values();
7300 }
7301
7302 this._trigger( "stop", event, uiHash );
7303 },
7304
7305 _change: function( event, index ) {
7306 if ( !this._keySliding && !this._mouseSliding ) {
7307 var uiHash = {
7308 handle: this.handles[ index ],
7309 value: this.value()
7310 };
7311 if ( this.options.values && this.options.values.length ) {
7312 uiHash.value = this.values( index );
7313 uiHash.values = this.values();
7314 }
7315
7316 this._trigger( "change", event, uiHash );
7317 }
7318 },
7319
7320 value: function( newValue ) {
7321 if ( arguments.length ) {
7322 this.options.value = this._trimAlignValue( newValue );
7323 this._refreshValue();
7324 this._change( null, 0 );
7325 return;
7326 }
7327
7328 return this._value();
7329 },
7330
7331 values: function( index, newValue ) {
7332 var vals,
7333 newValues,
7334 i;
7335
7336 if ( arguments.length > 1 ) {
7337 this.options.values[ index ] = this._trimAlignValue( newValue );
7338 this._refreshValue();
7339 this._change( null, index );
7340 return;
7341 }
7342
7343 if ( arguments.length ) {
7344 if ( $.isArray( arguments[ 0 ] ) ) {
7345 vals = this.options.values;
7346 newValues = arguments[ 0 ];
7347 for ( i = 0; i < vals.length; i += 1 ) {
7348 vals[ i ] = this._trimAlignValue( newValues[ i ] );
7349 this._change( null, i );
7350 }
7351 this._refreshValue();
7352 } else {
7353 if ( this.options.values && this.options.values.length ) {
7354 return this._values( index );
7355 } else {
7356 return this.value();
7357 }
7358 }
7359 } else {
7360 return this._values();
7361 }
7362 },
7363
7364 _setOption: function( key, value ) {
7365 var i,
7366 valsLength = 0;
7367
7368 if ( $.isArray( this.options.values ) ) {
7369 valsLength = this.options.values.length;
7370 }
7371
7372 $.Widget.prototype._setOption.apply( this, arguments );
7373
7374 switch ( key ) {
7375 case "disabled":
7376 if ( value ) {
7377 this.handles.filter( ".ui-state-focus" ).blur();
7378 this.handles.removeClass( "ui-state-hover" );
7379 this.handles.propAttr( "disabled", true );
7380 this.element.addClass( "ui-disabled" );
7381 } else {
7382 this.handles.propAttr( "disabled", false );
7383 this.element.removeClass( "ui-disabled" );
7384 }
7385 break;
7386 case "orientation":
7387 this._detectOrientation();
7388 this.element
7389 .removeClass( "ui-slider-horizontal ui-slider-vertical" )
7390 .addClass( "ui-slider-" + this.orientation );
7391 this._refreshValue();
7392 break;
7393 case "value":
7394 this._animateOff = true;
7395 this._refreshValue();
7396 this._change( null, 0 );
7397 this._animateOff = false;
7398 break;
7399 case "values":
7400 this._animateOff = true;
7401 this._refreshValue();
7402 for ( i = 0; i < valsLength; i += 1 ) {
7403 this._change( null, i );
7404 }
7405 this._animateOff = false;
7406 break;
7407 }
7408 },
7409
7410 //internal value getter
7411 // _value() returns value trimmed by min and max, aligned by step
7412 _value: function() {
7413 var val = this.options.value;
7414 val = this._trimAlignValue( val );
7415
7416 return val;
7417 },
7418
7419 //internal values getter
7420 // _values() returns array of values trimmed by min and max, aligned by step
7421 // _values( index ) returns single value trimmed by min and max, aligned by step
7422 _values: function( index ) {
7423 var val,
7424 vals,
7425 i;
7426
7427 if ( arguments.length ) {
7428 val = this.options.values[ index ];
7429 val = this._trimAlignValue( val );
7430
7431 return val;
7432 } else {
7433 // .slice() creates a copy of the array
7434 // this copy gets trimmed by min and max and then returned
7435 vals = this.options.values.slice();
7436 for ( i = 0; i < vals.length; i+= 1) {
7437 vals[ i ] = this._trimAlignValue( vals[ i ] );
7438 }
7439
7440 return vals;
7441 }
7442 },
7443
7444 // returns the step-aligned value that val is closest to, between (inclusive) min and max
7445 _trimAlignValue: function( val ) {
7446 if ( val <= this._valueMin() ) {
7447 return this._valueMin();
7448 }
7449 if ( val >= this._valueMax() ) {
7450 return this._valueMax();
7451 }
7452 var step = ( this.options.step > 0 ) ? this.options.step : 1,
7453 valModStep = (val - this._valueMin()) % step,
7454 alignValue = val - valModStep;
7455
7456 if ( Math.abs(valModStep) * 2 >= step ) {
7457 alignValue += ( valModStep > 0 ) ? step : ( -step );
7458 }
7459
7460 // Since JavaScript has problems with large floats, round
7461 // the final value to 5 digits after the decimal point (see #4124)
7462 return parseFloat( alignValue.toFixed(5) );
7463 },
7464
7465 _valueMin: function() {
7466 return this.options.min;
7467 },
7468
7469 _valueMax: function() {
7470 return this.options.max;
7471 },
7472
7473 _refreshValue: function() {
7474 var oRange = this.options.range,
7475 o = this.options,
7476 self = this,
7477 animate = ( !this._animateOff ) ? o.animate : false,
7478 valPercent,
7479 _set = {},
7480 lastValPercent,
7481 value,
7482 valueMin,
7483 valueMax;
7484
7485 if ( this.options.values && this.options.values.length ) {
7486 this.handles.each(function( i, j ) {
7487 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
7488 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7489 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7490 if ( self.options.range === true ) {
7491 if ( self.orientation === "horizontal" ) {
7492 if ( i === 0 ) {
7493 self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
7494 }
7495 if ( i === 1 ) {
7496 self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7497 }
7498 } else {
7499 if ( i === 0 ) {
7500 self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
7501 }
7502 if ( i === 1 ) {
7503 self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7504 }
7505 }
7506 }
7507 lastValPercent = valPercent;
7508 });
7509 } else {
7510 value = this.value();
7511 valueMin = this._valueMin();
7512 valueMax = this._valueMax();
7513 valPercent = ( valueMax !== valueMin ) ?
7514 ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
7515 0;
7516 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7517 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7518
7519 if ( oRange === "min" && this.orientation === "horizontal" ) {
7520 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
7521 }
7522 if ( oRange === "max" && this.orientation === "horizontal" ) {
7523 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7524 }
7525 if ( oRange === "min" && this.orientation === "vertical" ) {
7526 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
7527 }
7528 if ( oRange === "max" && this.orientation === "vertical" ) {
7529 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7530 }
7531 }
7532 }
7533
7534 });
7535
7536 $.extend( $.ui.slider, {
7537 version: "1.8.21"
7538 });
7539
7540 }(jQuery));
7541 /*!
7542 * jQuery UI Tabs 1.8.21
7543 *
7544 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
7545 * Dual licensed under the MIT or GPL Version 2 licenses.
7546 * http://jquery.org/license
7547 *
7548 * http://docs.jquery.com/UI/Tabs
7549 *
7550 * Depends:
7551 * jquery.ui.core.js
7552 * jquery.ui.widget.js
7553 */
7554 (function( $, undefined ) {
7555
7556 var tabId = 0,
7557 listId = 0;
7558
7559 function getNextTabId() {
7560 return ++tabId;
7561 }
7562
7563 function getNextListId() {
7564 return ++listId;
7565 }
7566
7567 $.widget( "ui.tabs", {
7568 options: {
7569 add: null,
7570 ajaxOptions: null,
7571 cache: false,
7572 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
7573 collapsible: false,
7574 disable: null,
7575 disabled: [],
7576 enable: null,
7577 event: "click",
7578 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
7579 idPrefix: "ui-tabs-",
7580 load: null,
7581 panelTemplate: "<div></div>",
7582 remove: null,
7583 select: null,
7584 show: null,
7585 spinner: "<em>Loading&#8230;</em>",
7586 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
7587 },
7588
7589 _create: function() {
7590 this._tabify( true );
7591 },
7592
7593 _setOption: function( key, value ) {
7594 if ( key == "selected" ) {
7595 if (this.options.collapsible && value == this.options.selected ) {
7596 return;
7597 }
7598 this.select( value );
7599 } else {
7600 this.options[ key ] = value;
7601 this._tabify();
7602 }
7603 },
7604
7605 _tabId: function( a ) {
7606 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
7607 this.options.idPrefix + getNextTabId();
7608 },
7609
7610 _sanitizeSelector: function( hash ) {
7611 // we need this because an id may contain a ":"
7612 return hash.replace( /:/g, "\\:" );
7613 },
7614
7615 _cookie: function() {
7616 var cookie = this.cookie ||
7617 ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
7618 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
7619 },
7620
7621 _ui: function( tab, panel ) {
7622 return {
7623 tab: tab,
7624 panel: panel,
7625 index: this.anchors.index( tab )
7626 };
7627 },
7628
7629 _cleanup: function() {
7630 // restore all former loading tabs labels
7631 this.lis.filter( ".ui-state-processing" )
7632 .removeClass( "ui-state-processing" )
7633 .find( "span:data(label.tabs)" )
7634 .each(function() {
7635 var el = $( this );
7636 el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
7637 });
7638 },
7639
7640 _tabify: function( init ) {
7641 var self = this,
7642 o = this.options,
7643 fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
7644
7645 this.list = this.element.find( "ol,ul" ).eq( 0 );
7646 this.lis = $( " > li:has(a[href])", this.list );
7647 this.anchors = this.lis.map(function() {
7648 return $( "a", this )[ 0 ];
7649 });
7650 this.panels = $( [] );
7651
7652 this.anchors.each(function( i, a ) {
7653 var href = $( a ).attr( "href" );
7654 // For dynamically created HTML that contains a hash as href IE < 8 expands
7655 // such href to the full page url with hash and then misinterprets tab as ajax.
7656 // Same consideration applies for an added tab with a fragment identifier
7657 // since a[href=#fragment-identifier] does unexpectedly not match.
7658 // Thus normalize href attribute...
7659 var hrefBase = href.split( "#" )[ 0 ],
7660 baseEl;
7661 if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
7662 ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
7663 href = a.hash;
7664 a.href = href;
7665 }
7666
7667 // inline tab
7668 if ( fragmentId.test( href ) ) {
7669 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
7670 // remote tab
7671 // prevent loading the page itself if href is just "#"
7672 } else if ( href && href !== "#" ) {
7673 // required for restore on destroy
7674 $.data( a, "href.tabs", href );
7675
7676 // TODO until #3808 is fixed strip fragment identifier from url
7677 // (IE fails to load from such url)
7678 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
7679
7680 var id = self._tabId( a );
7681 a.href = "#" + id;
7682 var $panel = self.element.find( "#" + id );
7683 if ( !$panel.length ) {
7684 $panel = $( o.panelTemplate )
7685 .attr( "id", id )
7686 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
7687 .insertAfter( self.panels[ i - 1 ] || self.list );
7688 $panel.data( "destroy.tabs", true );
7689 }
7690 self.panels = self.panels.add( $panel );
7691 // invalid tab href
7692 } else {
7693 o.disabled.push( i );
7694 }
7695 });
7696
7697 // initialization from scratch
7698 if ( init ) {
7699 // attach necessary classes for styling
7700 this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
7701 this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7702 this.lis.addClass( "ui-state-default ui-corner-top" );
7703 this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
7704
7705 // Selected tab
7706 // use "selected" option or try to retrieve:
7707 // 1. from fragment identifier in url
7708 // 2. from cookie
7709 // 3. from selected class attribute on <li>
7710 if ( o.selected === undefined ) {
7711 if ( location.hash ) {
7712 this.anchors.each(function( i, a ) {
7713 if ( a.hash == location.hash ) {
7714 o.selected = i;
7715 return false;
7716 }
7717 });
7718 }
7719 if ( typeof o.selected !== "number" && o.cookie ) {
7720 o.selected = parseInt( self._cookie(), 10 );
7721 }
7722 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
7723 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7724 }
7725 o.selected = o.selected || ( this.lis.length ? 0 : -1 );
7726 } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
7727 o.selected = -1;
7728 }
7729
7730 // sanity check - default to first tab...
7731 o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
7732 ? o.selected
7733 : 0;
7734
7735 // Take disabling tabs via class attribute from HTML
7736 // into account and update option properly.
7737 // A selected tab cannot become disabled.
7738 o.disabled = $.unique( o.disabled.concat(
7739 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
7740 return self.lis.index( n );
7741 })
7742 ) ).sort();
7743
7744 if ( $.inArray( o.selected, o.disabled ) != -1 ) {
7745 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
7746 }
7747
7748 // highlight selected tab
7749 this.panels.addClass( "ui-tabs-hide" );
7750 this.lis.removeClass( "ui-tabs-selected ui-state-active" );
7751 // check for length avoids error when initializing empty list
7752 if ( o.selected >= 0 && this.anchors.length ) {
7753 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
7754 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
7755
7756 // seems to be expected behavior that the show callback is fired
7757 self.element.queue( "tabs", function() {
7758 self._trigger( "show", null,
7759 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
7760 });
7761
7762 this.load( o.selected );
7763 }
7764
7765 // clean up to avoid memory leaks in certain versions of IE 6
7766 // TODO: namespace this event
7767 $( window ).bind( "unload", function() {
7768 self.lis.add( self.anchors ).unbind( ".tabs" );
7769 self.lis = self.anchors = self.panels = null;
7770 });
7771 // update selected after add/remove
7772 } else {
7773 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7774 }
7775
7776 // update collapsible
7777 // TODO: use .toggleClass()
7778 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
7779
7780 // set or update cookie after init and add/remove respectively
7781 if ( o.cookie ) {
7782 this._cookie( o.selected, o.cookie );
7783 }
7784
7785 // disable tabs
7786 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
7787 $( li )[ $.inArray( i, o.disabled ) != -1 &&
7788 // TODO: use .toggleClass()
7789 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
7790 }
7791
7792 // reset cache if switching from cached to not cached
7793 if ( o.cache === false ) {
7794 this.anchors.removeData( "cache.tabs" );
7795 }
7796
7797 // remove all handlers before, tabify may run on existing tabs after add or option change
7798 this.lis.add( this.anchors ).unbind( ".tabs" );
7799
7800 if ( o.event !== "mouseover" ) {
7801 var addState = function( state, el ) {
7802 if ( el.is( ":not(.ui-state-disabled)" ) ) {
7803 el.addClass( "ui-state-" + state );
7804 }
7805 };
7806 var removeState = function( state, el ) {
7807 el.removeClass( "ui-state-" + state );
7808 };
7809 this.lis.bind( "mouseover.tabs" , function() {
7810 addState( "hover", $( this ) );
7811 });
7812 this.lis.bind( "mouseout.tabs", function() {
7813 removeState( "hover", $( this ) );
7814 });
7815 this.anchors.bind( "focus.tabs", function() {
7816 addState( "focus", $( this ).closest( "li" ) );
7817 });
7818 this.anchors.bind( "blur.tabs", function() {
7819 removeState( "focus", $( this ).closest( "li" ) );
7820 });
7821 }
7822
7823 // set up animations
7824 var hideFx, showFx;
7825 if ( o.fx ) {
7826 if ( $.isArray( o.fx ) ) {
7827 hideFx = o.fx[ 0 ];
7828 showFx = o.fx[ 1 ];
7829 } else {
7830 hideFx = showFx = o.fx;
7831 }
7832 }
7833
7834 // Reset certain styles left over from animation
7835 // and prevent IE's ClearType bug...
7836 function resetStyle( $el, fx ) {
7837 $el.css( "display", "" );
7838 if ( !$.support.opacity && fx.opacity ) {
7839 $el[ 0 ].style.removeAttribute( "filter" );
7840 }
7841 }
7842
7843 // Show a tab...
7844 var showTab = showFx
7845 ? function( clicked, $show ) {
7846 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7847 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
7848 .animate( showFx, showFx.duration || "normal", function() {
7849 resetStyle( $show, showFx );
7850 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7851 });
7852 }
7853 : function( clicked, $show ) {
7854 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7855 $show.removeClass( "ui-tabs-hide" );
7856 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7857 };
7858
7859 // Hide a tab, $show is optional...
7860 var hideTab = hideFx
7861 ? function( clicked, $hide ) {
7862 $hide.animate( hideFx, hideFx.duration || "normal", function() {
7863 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7864 $hide.addClass( "ui-tabs-hide" );
7865 resetStyle( $hide, hideFx );
7866 self.element.dequeue( "tabs" );
7867 });
7868 }
7869 : function( clicked, $hide, $show ) {
7870 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7871 $hide.addClass( "ui-tabs-hide" );
7872 self.element.dequeue( "tabs" );
7873 };
7874
7875 // attach tab event handler, unbind to avoid duplicates from former tabifying...
7876 this.anchors.bind( o.event + ".tabs", function() {
7877 var el = this,
7878 $li = $(el).closest( "li" ),
7879 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
7880 $show = self.element.find( self._sanitizeSelector( el.hash ) );
7881
7882 // If tab is already selected and not collapsible or tab disabled or
7883 // or is already loading or click callback returns false stop here.
7884 // Check if click handler returns false last so that it is not executed
7885 // for a disabled or loading tab!
7886 if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
7887 $li.hasClass( "ui-state-disabled" ) ||
7888 $li.hasClass( "ui-state-processing" ) ||
7889 self.panels.filter( ":animated" ).length ||
7890 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
7891 this.blur();
7892 return false;
7893 }
7894
7895 o.selected = self.anchors.index( this );
7896
7897 self.abort();
7898
7899 // if tab may be closed
7900 if ( o.collapsible ) {
7901 if ( $li.hasClass( "ui-tabs-selected" ) ) {
7902 o.selected = -1;
7903
7904 if ( o.cookie ) {
7905 self._cookie( o.selected, o.cookie );
7906 }
7907
7908 self.element.queue( "tabs", function() {
7909 hideTab( el, $hide );
7910 }).dequeue( "tabs" );
7911
7912 this.blur();
7913 return false;
7914 } else if ( !$hide.length ) {
7915 if ( o.cookie ) {
7916 self._cookie( o.selected, o.cookie );
7917 }
7918
7919 self.element.queue( "tabs", function() {
7920 showTab( el, $show );
7921 });
7922
7923 // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
7924 self.load( self.anchors.index( this ) );
7925
7926 this.blur();
7927 return false;
7928 }
7929 }
7930
7931 if ( o.cookie ) {
7932 self._cookie( o.selected, o.cookie );
7933 }
7934
7935 // show new tab
7936 if ( $show.length ) {
7937 if ( $hide.length ) {
7938 self.element.queue( "tabs", function() {
7939 hideTab( el, $hide );
7940 });
7941 }
7942 self.element.queue( "tabs", function() {
7943 showTab( el, $show );
7944 });
7945
7946 self.load( self.anchors.index( this ) );
7947 } else {
7948 throw "jQuery UI Tabs: Mismatching fragment identifier.";
7949 }
7950
7951 // Prevent IE from keeping other link focussed when using the back button
7952 // and remove dotted border from clicked link. This is controlled via CSS
7953 // in modern browsers; blur() removes focus from address bar in Firefox
7954 // which can become a usability and annoying problem with tabs('rotate').
7955 if ( $.browser.msie ) {
7956 this.blur();
7957 }
7958 });
7959
7960 // disable click in any case
7961 this.anchors.bind( "click.tabs", function(){
7962 return false;
7963 });
7964 },
7965
7966 _getIndex: function( index ) {
7967 // meta-function to give users option to provide a href string instead of a numerical index.
7968 // also sanitizes numerical indexes to valid values.
7969 if ( typeof index == "string" ) {
7970 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
7971 }
7972
7973 return index;
7974 },
7975
7976 destroy: function() {
7977 var o = this.options;
7978
7979 this.abort();
7980
7981 this.element
7982 .unbind( ".tabs" )
7983 .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
7984 .removeData( "tabs" );
7985
7986 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7987
7988 this.anchors.each(function() {
7989 var href = $.data( this, "href.tabs" );
7990 if ( href ) {
7991 this.href = href;
7992 }
7993 var $this = $( this ).unbind( ".tabs" );
7994 $.each( [ "href", "load", "cache" ], function( i, prefix ) {
7995 $this.removeData( prefix + ".tabs" );
7996 });
7997 });
7998
7999 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
8000 if ( $.data( this, "destroy.tabs" ) ) {
8001 $( this ).remove();
8002 } else {
8003 $( this ).removeClass([
8004 "ui-state-default",
8005 "ui-corner-top",
8006 "ui-tabs-selected",
8007 "ui-state-active",
8008 "ui-state-hover",
8009 "ui-state-focus",
8010 "ui-state-disabled",
8011 "ui-tabs-panel",
8012 "ui-widget-content",
8013 "ui-corner-bottom",
8014 "ui-tabs-hide"
8015 ].join( " " ) );
8016 }
8017 });
8018
8019 if ( o.cookie ) {
8020 this._cookie( null, o.cookie );
8021 }
8022
8023 return this;
8024 },
8025
8026 add: function( url, label, index ) {
8027 if ( index === undefined ) {
8028 index = this.anchors.length;
8029 }
8030
8031 var self = this,
8032 o = this.options,
8033 $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
8034 id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
8035
8036 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
8037
8038 // try to find an existing element before creating a new one
8039 var $panel = self.element.find( "#" + id );
8040 if ( !$panel.length ) {
8041 $panel = $( o.panelTemplate )
8042 .attr( "id", id )
8043 .data( "destroy.tabs", true );
8044 }
8045 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
8046
8047 if ( index >= this.lis.length ) {
8048 $li.appendTo( this.list );
8049 $panel.appendTo( this.list[ 0 ].parentNode );
8050 } else {
8051 $li.insertBefore( this.lis[ index ] );
8052 $panel.insertBefore( this.panels[ index ] );
8053 }
8054
8055 o.disabled = $.map( o.disabled, function( n, i ) {
8056 return n >= index ? ++n : n;
8057 });
8058
8059 this._tabify();
8060
8061 if ( this.anchors.length == 1 ) {
8062 o.selected = 0;
8063 $li.addClass( "ui-tabs-selected ui-state-active" );
8064 $panel.removeClass( "ui-tabs-hide" );
8065 this.element.queue( "tabs", function() {
8066 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
8067 });
8068
8069 this.load( 0 );
8070 }
8071
8072 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8073 return this;
8074 },
8075
8076 remove: function( index ) {
8077 index = this._getIndex( index );
8078 var o = this.options,
8079 $li = this.lis.eq( index ).remove(),
8080 $panel = this.panels.eq( index ).remove();
8081
8082 // If selected tab was removed focus tab to the right or
8083 // in case the last tab was removed the tab to the left.
8084 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
8085 this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
8086 }
8087
8088 o.disabled = $.map(
8089 $.grep( o.disabled, function(n, i) {
8090 return n != index;
8091 }),
8092 function( n, i ) {
8093 return n >= index ? --n : n;
8094 });
8095
8096 this._tabify();
8097
8098 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
8099 return this;
8100 },
8101
8102 enable: function( index ) {
8103 index = this._getIndex( index );
8104 var o = this.options;
8105 if ( $.inArray( index, o.disabled ) == -1 ) {
8106 return;
8107 }
8108
8109 this.lis.eq( index ).removeClass( "ui-state-disabled" );
8110 o.disabled = $.grep( o.disabled, function( n, i ) {
8111 return n != index;
8112 });
8113
8114 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8115 return this;
8116 },
8117
8118 disable: function( index ) {
8119 index = this._getIndex( index );
8120 var self = this, o = this.options;
8121 // cannot disable already selected tab
8122 if ( index != o.selected ) {
8123 this.lis.eq( index ).addClass( "ui-state-disabled" );
8124
8125 o.disabled.push( index );
8126 o.disabled.sort();
8127
8128 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8129 }
8130
8131 return this;
8132 },
8133
8134 select: function( index ) {
8135 index = this._getIndex( index );
8136 if ( index == -1 ) {
8137 if ( this.options.collapsible && this.options.selected != -1 ) {
8138 index = this.options.selected;
8139 } else {
8140 return this;
8141 }
8142 }
8143 this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
8144 return this;
8145 },
8146
8147 load: function( index ) {
8148 index = this._getIndex( index );
8149 var self = this,
8150 o = this.options,
8151 a = this.anchors.eq( index )[ 0 ],
8152 url = $.data( a, "load.tabs" );
8153
8154 this.abort();
8155
8156 // not remote or from cache
8157 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
8158 this.element.dequeue( "tabs" );
8159 return;
8160 }
8161
8162 // load remote from here on
8163 this.lis.eq( index ).addClass( "ui-state-processing" );
8164
8165 if ( o.spinner ) {
8166 var span = $( "span", a );
8167 span.data( "label.tabs", span.html() ).html( o.spinner );
8168 }
8169
8170 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
8171 url: url,
8172 success: function( r, s ) {
8173 self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
8174
8175 // take care of tab labels
8176 self._cleanup();
8177
8178 if ( o.cache ) {
8179 $.data( a, "cache.tabs", true );
8180 }
8181
8182 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8183 try {
8184 o.ajaxOptions.success( r, s );
8185 }
8186 catch ( e ) {}
8187 },
8188 error: function( xhr, s, e ) {
8189 // take care of tab labels
8190 self._cleanup();
8191
8192 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8193 try {
8194 // Passing index avoid a race condition when this method is
8195 // called after the user has selected another tab.
8196 // Pass the anchor that initiated this request allows
8197 // loadError to manipulate the tab content panel via $(a.hash)
8198 o.ajaxOptions.error( xhr, s, index, a );
8199 }
8200 catch ( e ) {}
8201 }
8202 } ) );
8203
8204 // last, so that load event is fired before show...
8205 self.element.dequeue( "tabs" );
8206
8207 return this;
8208 },
8209
8210 abort: function() {
8211 // stop possibly running animations
8212 this.element.queue( [] );
8213 this.panels.stop( false, true );
8214
8215 // "tabs" queue must not contain more than two elements,
8216 // which are the callbacks for the latest clicked tab...
8217 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
8218
8219 // terminate pending requests from other tabs
8220 if ( this.xhr ) {
8221 this.xhr.abort();
8222 delete this.xhr;
8223 }
8224
8225 // take care of tab labels
8226 this._cleanup();
8227 return this;
8228 },
8229
8230 url: function( index, url ) {
8231 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
8232 return this;
8233 },
8234
8235 length: function() {
8236 return this.anchors.length;
8237 }
8238 });
8239
8240 $.extend( $.ui.tabs, {
8241 version: "1.8.21"
8242 });
8243
8244 /*
8245 * Tabs Extensions
8246 */
8247
8248 /*
8249 * Rotate
8250 */
8251 $.extend( $.ui.tabs.prototype, {
8252 rotation: null,
8253 rotate: function( ms, continuing ) {
8254 var self = this,
8255 o = this.options;
8256
8257 var rotate = self._rotate || ( self._rotate = function( e ) {
8258 clearTimeout( self.rotation );
8259 self.rotation = setTimeout(function() {
8260 var t = o.selected;
8261 self.select( ++t < self.anchors.length ? t : 0 );
8262 }, ms );
8263
8264 if ( e ) {
8265 e.stopPropagation();
8266 }
8267 });
8268
8269 var stop = self._unrotate || ( self._unrotate = !continuing
8270 ? function(e) {
8271 if (e.clientX) { // in case of a true click
8272 self.rotate(null);
8273 }
8274 }
8275 : function( e ) {
8276 rotate();
8277 });
8278
8279 // start rotation
8280 if ( ms ) {
8281 this.element.bind( "tabsshow", rotate );
8282 this.anchors.bind( o.event + ".tabs", stop );
8283 rotate();
8284 // stop rotation
8285 } else {
8286 clearTimeout( self.rotation );
8287 this.element.unbind( "tabsshow", rotate );
8288 this.anchors.unbind( o.event + ".tabs", stop );
8289 delete this._rotate;
8290 delete this._unrotate;
8291 }
8292
8293 return this;
8294 }
8295 });
8296
8297 })( jQuery );
8298 /*!
8299 * jQuery UI Datepicker 1.8.21
8300 *
8301 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
8302 * Dual licensed under the MIT or GPL Version 2 licenses.
8303 * http://jquery.org/license
8304 *
8305 * http://docs.jquery.com/UI/Datepicker
8306 *
8307 * Depends:
8308 * jquery.ui.core.js
8309 */
8310 (function( $, undefined ) {
8311
8312 $.extend($.ui, { datepicker: { version: "1.8.21" } });
8313
8314 var PROP_NAME = 'datepicker';
8315 var dpuuid = new Date().getTime();
8316 var instActive;
8317
8318 /* Date picker manager.
8319 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8320 Settings for (groups of) date pickers are maintained in an instance object,
8321 allowing multiple different settings on the same page. */
8322
8323 function Datepicker() {
8324 this.debug = false; // Change this to true to start debugging
8325 this._curInst = null; // The current instance in use
8326 this._keyEvent = false; // If the last event was a key event
8327 this._disabledInputs = []; // List of date picker inputs that have been disabled
8328 this._datepickerShowing = false; // True if the popup picker is showing , false if not
8329 this._inDialog = false; // True if showing within a "dialog", false if not
8330 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
8331 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
8332 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
8333 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
8334 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
8335 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
8336 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
8337 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
8338 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
8339 this.regional = []; // Available regional settings, indexed by language code
8340 this.regional[''] = { // Default regional settings
8341 closeText: 'Done', // Display text for close link
8342 prevText: 'Prev', // Display text for previous month link
8343 nextText: 'Next', // Display text for next month link
8344 currentText: 'Today', // Display text for current month link
8345 monthNames: ['January','February','March','April','May','June',
8346 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
8347 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
8348 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
8349 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
8350 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
8351 weekHeader: 'Wk', // Column header for week of the year
8352 dateFormat: 'mm/dd/yy', // See format options on parseDate
8353 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8354 isRTL: false, // True if right-to-left language, false if left-to-right
8355 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8356 yearSuffix: '' // Additional text to append to the year in the month headers
8357 };
8358 this._defaults = { // Global defaults for all the date picker instances
8359 showOn: 'focus', // 'focus' for popup on focus,
8360 // 'button' for trigger button, or 'both' for either
8361 showAnim: 'fadeIn', // Name of jQuery animation for popup
8362 showOptions: {}, // Options for enhanced animations
8363 defaultDate: null, // Used when field is blank: actual date,
8364 // +/-number for offset from today, null for today
8365 appendText: '', // Display text following the input box, e.g. showing the format
8366 buttonText: '...', // Text for trigger button
8367 buttonImage: '', // URL for trigger button image
8368 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8369 hideIfNoPrevNext: false, // True to hide next/previous month links
8370 // if not applicable, false to just disable them
8371 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8372 gotoCurrent: false, // True if today link goes back to current selection instead
8373 changeMonth: false, // True if month can be selected directly, false if only prev/next
8374 changeYear: false, // True if year can be selected directly, false if only prev/next
8375 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
8376 // either relative to today's year (-nn:+nn), relative to currently displayed year
8377 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8378 showOtherMonths: false, // True to show dates in other months, false to leave blank
8379 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8380 showWeek: false, // True to show week of the year, false to not show it
8381 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8382 // takes a Date and returns the number of the week for it
8383 shortYearCutoff: '+10', // Short year values < this are in the current century,
8384 // > this are in the previous century,
8385 // string value starting with '+' for current year + value
8386 minDate: null, // The earliest selectable date, or null for no limit
8387 maxDate: null, // The latest selectable date, or null for no limit
8388 duration: 'fast', // Duration of display/closure
8389 beforeShowDay: null, // Function that takes a date and returns an array with
8390 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
8391 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8392 beforeShow: null, // Function that takes an input field and
8393 // returns a set of custom settings for the date picker
8394 onSelect: null, // Define a callback function when a date is selected
8395 onChangeMonthYear: null, // Define a callback function when the month or year is changed
8396 onClose: null, // Define a callback function when the datepicker is closed
8397 numberOfMonths: 1, // Number of months to show at a time
8398 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8399 stepMonths: 1, // Number of months to step back/forward
8400 stepBigMonths: 12, // Number of months to step back/forward for the big links
8401 altField: '', // Selector for an alternate field to store selected dates into
8402 altFormat: '', // The date format to use for the alternate field
8403 constrainInput: true, // The input is constrained by the current date format
8404 showButtonPanel: false, // True to show button panel, false to not show it
8405 autoSize: false, // True to size the input for the date format, false to leave as is
8406 disabled: false // The initial disabled state
8407 };
8408 $.extend(this._defaults, this.regional['']);
8409 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
8410 }
8411
8412 $.extend(Datepicker.prototype, {
8413 /* Class name added to elements to indicate already configured with a date picker. */
8414 markerClassName: 'hasDatepicker',
8415
8416 //Keep track of the maximum number of rows displayed (see #7043)
8417 maxRows: 4,
8418
8419 /* Debug logging (if enabled). */
8420 log: function () {
8421 if (this.debug)
8422 console.log.apply('', arguments);
8423 },
8424
8425 // TODO rename to "widget" when switching to widget factory
8426 _widgetDatepicker: function() {
8427 return this.dpDiv;
8428 },
8429
8430 /* Override the default settings for all instances of the date picker.
8431 @param settings object - the new settings to use as defaults (anonymous object)
8432 @return the manager object */
8433 setDefaults: function(settings) {
8434 extendRemove(this._defaults, settings || {});
8435 return this;
8436 },
8437
8438 /* Attach the date picker to a jQuery selection.
8439 @param target element - the target input field or division or span
8440 @param settings object - the new settings to use for this date picker instance (anonymous) */
8441 _attachDatepicker: function(target, settings) {
8442 // check for settings on the control itself - in namespace 'date:'
8443 var inlineSettings = null;
8444 for (var attrName in this._defaults) {
8445 var attrValue = target.getAttribute('date:' + attrName);
8446 if (attrValue) {
8447 inlineSettings = inlineSettings || {};
8448 try {
8449 inlineSettings[attrName] = eval(attrValue);
8450 } catch (err) {
8451 inlineSettings[attrName] = attrValue;
8452 }
8453 }
8454 }
8455 var nodeName = target.nodeName.toLowerCase();
8456 var inline = (nodeName == 'div' || nodeName == 'span');
8457 if (!target.id) {
8458 this.uuid += 1;
8459 target.id = 'dp' + this.uuid;
8460 }
8461 var inst = this._newInst($(target), inline);
8462 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
8463 if (nodeName == 'input') {
8464 this._connectDatepicker(target, inst);
8465 } else if (inline) {
8466 this._inlineDatepicker(target, inst);
8467 }
8468 },
8469
8470 /* Create a new instance object. */
8471 _newInst: function(target, inline) {
8472 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
8473 return {id: id, input: target, // associated target
8474 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8475 drawMonth: 0, drawYear: 0, // month being drawn
8476 inline: inline, // is datepicker inline or not
8477 dpDiv: (!inline ? this.dpDiv : // presentation div
8478 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
8479 },
8480
8481 /* Attach the date picker to an input field. */
8482 _connectDatepicker: function(target, inst) {
8483 var input = $(target);
8484 inst.append = $([]);
8485 inst.trigger = $([]);
8486 if (input.hasClass(this.markerClassName))
8487 return;
8488 this._attachments(input, inst);
8489 input.addClass(this.markerClassName).keydown(this._doKeyDown).
8490 keypress(this._doKeyPress).keyup(this._doKeyUp).
8491 bind("setData.datepicker", function(event, key, value) {
8492 inst.settings[key] = value;
8493 }).bind("getData.datepicker", function(event, key) {
8494 return this._get(inst, key);
8495 });
8496 this._autoSize(inst);
8497 $.data(target, PROP_NAME, inst);
8498 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
8499 if( inst.settings.disabled ) {
8500 this._disableDatepicker( target );
8501 }
8502 },
8503
8504 /* Make attachments based on settings. */
8505 _attachments: function(input, inst) {
8506 var appendText = this._get(inst, 'appendText');
8507 var isRTL = this._get(inst, 'isRTL');
8508 if (inst.append)
8509 inst.append.remove();
8510 if (appendText) {
8511 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
8512 input[isRTL ? 'before' : 'after'](inst.append);
8513 }
8514 input.unbind('focus', this._showDatepicker);
8515 if (inst.trigger)
8516 inst.trigger.remove();
8517 var showOn = this._get(inst, 'showOn');
8518 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
8519 input.focus(this._showDatepicker);
8520 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
8521 var buttonText = this._get(inst, 'buttonText');
8522 var buttonImage = this._get(inst, 'buttonImage');
8523 inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
8524 $('<img/>').addClass(this._triggerClass).
8525 attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8526 $('<button type="button"></button>').addClass(this._triggerClass).
8527 html(buttonImage == '' ? buttonText : $('<img/>').attr(
8528 { src:buttonImage, alt:buttonText, title:buttonText })));
8529 input[isRTL ? 'before' : 'after'](inst.trigger);
8530 inst.trigger.click(function() {
8531 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
8532 $.datepicker._hideDatepicker();
8533 else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
8534 $.datepicker._hideDatepicker();
8535 $.datepicker._showDatepicker(input[0]);
8536 } else
8537 $.datepicker._showDatepicker(input[0]);
8538 return false;
8539 });
8540 }
8541 },
8542
8543 /* Apply the maximum length for the date format. */
8544 _autoSize: function(inst) {
8545 if (this._get(inst, 'autoSize') && !inst.inline) {
8546 var date = new Date(2009, 12 - 1, 20); // Ensure double digits
8547 var dateFormat = this._get(inst, 'dateFormat');
8548 if (dateFormat.match(/[DM]/)) {
8549 var findMax = function(names) {
8550 var max = 0;
8551 var maxI = 0;
8552 for (var i = 0; i < names.length; i++) {
8553 if (names[i].length > max) {
8554 max = names[i].length;
8555 maxI = i;
8556 }
8557 }
8558 return maxI;
8559 };
8560 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8561 'monthNames' : 'monthNamesShort'))));
8562 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8563 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
8564 }
8565 inst.input.attr('size', this._formatDate(inst, date).length);
8566 }
8567 },
8568
8569 /* Attach an inline date picker to a div. */
8570 _inlineDatepicker: function(target, inst) {
8571 var divSpan = $(target);
8572 if (divSpan.hasClass(this.markerClassName))
8573 return;
8574 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
8575 bind("setData.datepicker", function(event, key, value){
8576 inst.settings[key] = value;
8577 }).bind("getData.datepicker", function(event, key){
8578 return this._get(inst, key);
8579 });
8580 $.data(target, PROP_NAME, inst);
8581 this._setDate(inst, this._getDefaultDate(inst), true);
8582 this._updateDatepicker(inst);
8583 this._updateAlternate(inst);
8584 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
8585 if( inst.settings.disabled ) {
8586 this._disableDatepicker( target );
8587 }
8588 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
8589 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
8590 inst.dpDiv.css( "display", "block" );
8591 },
8592
8593 /* Pop-up the date picker in a "dialog" box.
8594 @param input element - ignored
8595 @param date string or Date - the initial date to display
8596 @param onSelect function - the function to call when a date is selected
8597 @param settings object - update the dialog date picker instance's settings (anonymous object)
8598 @param pos int[2] - coordinates for the dialog's position within the screen or
8599 event - with x/y coordinates or
8600 leave empty for default (screen centre)
8601 @return the manager object */
8602 _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8603 var inst = this._dialogInst; // internal instance
8604 if (!inst) {
8605 this.uuid += 1;
8606 var id = 'dp' + this.uuid;
8607 this._dialogInput = $('<input type="text" id="' + id +
8608 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
8609 this._dialogInput.keydown(this._doKeyDown);
8610 $('body').append(this._dialogInput);
8611 inst = this._dialogInst = this._newInst(this._dialogInput, false);
8612 inst.settings = {};
8613 $.data(this._dialogInput[0], PROP_NAME, inst);
8614 }
8615 extendRemove(inst.settings, settings || {});
8616 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
8617 this._dialogInput.val(date);
8618
8619 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8620 if (!this._pos) {
8621 var browserWidth = document.documentElement.clientWidth;
8622 var browserHeight = document.documentElement.clientHeight;
8623 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8624 var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8625 this._pos = // should use actual width/height below
8626 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8627 }
8628
8629 // move input on screen for focus, but hidden behind dialog
8630 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
8631 inst.settings.onSelect = onSelect;
8632 this._inDialog = true;
8633 this.dpDiv.addClass(this._dialogClass);
8634 this._showDatepicker(this._dialogInput[0]);
8635 if ($.blockUI)
8636 $.blockUI(this.dpDiv);
8637 $.data(this._dialogInput[0], PROP_NAME, inst);
8638 return this;
8639 },
8640
8641 /* Detach a datepicker from its control.
8642 @param target element - the target input field or division or span */
8643 _destroyDatepicker: function(target) {
8644 var $target = $(target);
8645 var inst = $.data(target, PROP_NAME);
8646 if (!$target.hasClass(this.markerClassName)) {
8647 return;
8648 }
8649 var nodeName = target.nodeName.toLowerCase();
8650 $.removeData(target, PROP_NAME);
8651 if (nodeName == 'input') {
8652 inst.append.remove();
8653 inst.trigger.remove();
8654 $target.removeClass(this.markerClassName).
8655 unbind('focus', this._showDatepicker).
8656 unbind('keydown', this._doKeyDown).
8657 unbind('keypress', this._doKeyPress).
8658 unbind('keyup', this._doKeyUp);
8659 } else if (nodeName == 'div' || nodeName == 'span')
8660 $target.removeClass(this.markerClassName).empty();
8661 },
8662
8663 /* Enable the date picker to a jQuery selection.
8664 @param target element - the target input field or division or span */
8665 _enableDatepicker: function(target) {
8666 var $target = $(target);
8667 var inst = $.data(target, PROP_NAME);
8668 if (!$target.hasClass(this.markerClassName)) {
8669 return;
8670 }
8671 var nodeName = target.nodeName.toLowerCase();
8672 if (nodeName == 'input') {
8673 target.disabled = false;
8674 inst.trigger.filter('button').
8675 each(function() { this.disabled = false; }).end().
8676 filter('img').css({opacity: '1.0', cursor: ''});
8677 }
8678 else if (nodeName == 'div' || nodeName == 'span') {
8679 var inline = $target.children('.' + this._inlineClass);
8680 inline.children().removeClass('ui-state-disabled');
8681 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8682 removeAttr("disabled");
8683 }
8684 this._disabledInputs = $.map(this._disabledInputs,
8685 function(value) { return (value == target ? null : value); }); // delete entry
8686 },
8687
8688 /* Disable the date picker to a jQuery selection.
8689 @param target element - the target input field or division or span */
8690 _disableDatepicker: function(target) {
8691 var $target = $(target);
8692 var inst = $.data(target, PROP_NAME);
8693 if (!$target.hasClass(this.markerClassName)) {
8694 return;
8695 }
8696 var nodeName = target.nodeName.toLowerCase();
8697 if (nodeName == 'input') {
8698 target.disabled = true;
8699 inst.trigger.filter('button').
8700 each(function() { this.disabled = true; }).end().
8701 filter('img').css({opacity: '0.5', cursor: 'default'});
8702 }
8703 else if (nodeName == 'div' || nodeName == 'span') {
8704 var inline = $target.children('.' + this._inlineClass);
8705 inline.children().addClass('ui-state-disabled');
8706 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8707 attr("disabled", "disabled");
8708 }
8709 this._disabledInputs = $.map(this._disabledInputs,
8710 function(value) { return (value == target ? null : value); }); // delete entry
8711 this._disabledInputs[this._disabledInputs.length] = target;
8712 },
8713
8714 /* Is the first field in a jQuery collection disabled as a datepicker?
8715 @param target element - the target input field or division or span
8716 @return boolean - true if disabled, false if enabled */
8717 _isDisabledDatepicker: function(target) {
8718 if (!target) {
8719 return false;
8720 }
8721 for (var i = 0; i < this._disabledInputs.length; i++) {
8722 if (this._disabledInputs[i] == target)
8723 return true;
8724 }
8725 return false;
8726 },
8727
8728 /* Retrieve the instance data for the target control.
8729 @param target element - the target input field or division or span
8730 @return object - the associated instance data
8731 @throws error if a jQuery problem getting data */
8732 _getInst: function(target) {
8733 try {
8734 return $.data(target, PROP_NAME);
8735 }
8736 catch (err) {
8737 throw 'Missing instance data for this datepicker';
8738 }
8739 },
8740
8741 /* Update or retrieve the settings for a date picker attached to an input field or division.
8742 @param target element - the target input field or division or span
8743 @param name object - the new settings to update or
8744 string - the name of the setting to change or retrieve,
8745 when retrieving also 'all' for all instance settings or
8746 'defaults' for all global defaults
8747 @param value any - the new value for the setting
8748 (omit if above is an object or to retrieve a value) */
8749 _optionDatepicker: function(target, name, value) {
8750 var inst = this._getInst(target);
8751 if (arguments.length == 2 && typeof name == 'string') {
8752 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
8753 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
8754 this._get(inst, name)) : null));
8755 }
8756 var settings = name || {};
8757 if (typeof name == 'string') {
8758 settings = {};
8759 settings[name] = value;
8760 }
8761 if (inst) {
8762 if (this._curInst == inst) {
8763 this._hideDatepicker();
8764 }
8765 var date = this._getDateDatepicker(target, true);
8766 var minDate = this._getMinMaxDate(inst, 'min');
8767 var maxDate = this._getMinMaxDate(inst, 'max');
8768 extendRemove(inst.settings, settings);
8769 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8770 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
8771 inst.settings.minDate = this._formatDate(inst, minDate);
8772 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
8773 inst.settings.maxDate = this._formatDate(inst, maxDate);
8774 this._attachments($(target), inst);
8775 this._autoSize(inst);
8776 this._setDate(inst, date);
8777 this._updateAlternate(inst);
8778 this._updateDatepicker(inst);
8779 }
8780 },
8781
8782 // change method deprecated
8783 _changeDatepicker: function(target, name, value) {
8784 this._optionDatepicker(target, name, value);
8785 },
8786
8787 /* Redraw the date picker attached to an input field or division.
8788 @param target element - the target input field or division or span */
8789 _refreshDatepicker: function(target) {
8790 var inst = this._getInst(target);
8791 if (inst) {
8792 this._updateDatepicker(inst);
8793 }
8794 },
8795
8796 /* Set the dates for a jQuery selection.
8797 @param target element - the target input field or division or span
8798 @param date Date - the new date */
8799 _setDateDatepicker: function(target, date) {
8800 var inst = this._getInst(target);
8801 if (inst) {
8802 this._setDate(inst, date);
8803 this._updateDatepicker(inst);
8804 this._updateAlternate(inst);
8805 }
8806 },
8807
8808 /* Get the date(s) for the first entry in a jQuery selection.
8809 @param target element - the target input field or division or span
8810 @param noDefault boolean - true if no default date is to be used
8811 @return Date - the current date */
8812 _getDateDatepicker: function(target, noDefault) {
8813 var inst = this._getInst(target);
8814 if (inst && !inst.inline)
8815 this._setDateFromField(inst, noDefault);
8816 return (inst ? this._getDate(inst) : null);
8817 },
8818
8819 /* Handle keystrokes. */
8820 _doKeyDown: function(event) {
8821 var inst = $.datepicker._getInst(event.target);
8822 var handled = true;
8823 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
8824 inst._keyEvent = true;
8825 if ($.datepicker._datepickerShowing)
8826 switch (event.keyCode) {
8827 case 9: $.datepicker._hideDatepicker();
8828 handled = false;
8829 break; // hide on tab out
8830 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
8831 $.datepicker._currentClass + ')', inst.dpDiv);
8832 if (sel[0])
8833 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8834 var onSelect = $.datepicker._get(inst, 'onSelect');
8835 if (onSelect) {
8836 var dateStr = $.datepicker._formatDate(inst);
8837
8838 // trigger custom callback
8839 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8840 }
8841 else
8842 $.datepicker._hideDatepicker();
8843 return false; // don't submit the form
8844 break; // select the value on enter
8845 case 27: $.datepicker._hideDatepicker();
8846 break; // hide on escape
8847 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8848 -$.datepicker._get(inst, 'stepBigMonths') :
8849 -$.datepicker._get(inst, 'stepMonths')), 'M');
8850 break; // previous month/year on page up/+ ctrl
8851 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8852 +$.datepicker._get(inst, 'stepBigMonths') :
8853 +$.datepicker._get(inst, 'stepMonths')), 'M');
8854 break; // next month/year on page down/+ ctrl
8855 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
8856 handled = event.ctrlKey || event.metaKey;
8857 break; // clear on ctrl or command +end
8858 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
8859 handled = event.ctrlKey || event.metaKey;
8860 break; // current on ctrl or command +home
8861 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
8862 handled = event.ctrlKey || event.metaKey;
8863 // -1 day on ctrl or command +left
8864 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8865 -$.datepicker._get(inst, 'stepBigMonths') :
8866 -$.datepicker._get(inst, 'stepMonths')), 'M');
8867 // next month/year on alt +left on Mac
8868 break;
8869 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
8870 handled = event.ctrlKey || event.metaKey;
8871 break; // -1 week on ctrl or command +up
8872 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
8873 handled = event.ctrlKey || event.metaKey;
8874 // +1 day on ctrl or command +right
8875 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8876 +$.datepicker._get(inst, 'stepBigMonths') :
8877 +$.datepicker._get(inst, 'stepMonths')), 'M');
8878 // next month/year on alt +right
8879 break;
8880 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
8881 handled = event.ctrlKey || event.metaKey;
8882 break; // +1 week on ctrl or command +down
8883 default: handled = false;
8884 }
8885 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
8886 $.datepicker._showDatepicker(this);
8887 else {
8888 handled = false;
8889 }
8890 if (handled) {
8891 event.preventDefault();
8892 event.stopPropagation();
8893 }
8894 },
8895
8896 /* Filter entered characters - based on date format. */
8897 _doKeyPress: function(event) {
8898 var inst = $.datepicker._getInst(event.target);
8899 if ($.datepicker._get(inst, 'constrainInput')) {
8900 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
8901 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
8902 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
8903 }
8904 },
8905
8906 /* Synchronise manual entry and field/alternate field. */
8907 _doKeyUp: function(event) {
8908 var inst = $.datepicker._getInst(event.target);
8909 if (inst.input.val() != inst.lastVal) {
8910 try {
8911 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8912 (inst.input ? inst.input.val() : null),
8913 $.datepicker._getFormatConfig(inst));
8914 if (date) { // only if valid
8915 $.datepicker._setDateFromField(inst);
8916 $.datepicker._updateAlternate(inst);
8917 $.datepicker._updateDatepicker(inst);
8918 }
8919 }
8920 catch (err) {
8921 $.datepicker.log(err);
8922 }
8923 }
8924 return true;
8925 },
8926
8927 /* Pop-up the date picker for a given input field.
8928 If false returned from beforeShow event handler do not show.
8929 @param input element - the input field attached to the date picker or
8930 event - if triggered by focus */
8931 _showDatepicker: function(input) {
8932 input = input.target || input;
8933 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
8934 input = $('input', input.parentNode)[0];
8935 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
8936 return;
8937 var inst = $.datepicker._getInst(input);
8938 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
8939 $.datepicker._curInst.dpDiv.stop(true, true);
8940 if ( inst && $.datepicker._datepickerShowing ) {
8941 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8942 }
8943 }
8944 var beforeShow = $.datepicker._get(inst, 'beforeShow');
8945 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8946 if(beforeShowSettings === false){
8947 //false
8948 return;
8949 }
8950 extendRemove(inst.settings, beforeShowSettings);
8951 inst.lastVal = null;
8952 $.datepicker._lastInput = input;
8953 $.datepicker._setDateFromField(inst);
8954 if ($.datepicker._inDialog) // hide cursor
8955 input.value = '';
8956 if (!$.datepicker._pos) { // position below input
8957 $.datepicker._pos = $.datepicker._findPos(input);
8958 $.datepicker._pos[1] += input.offsetHeight; // add the height
8959 }
8960 var isFixed = false;
8961 $(input).parents().each(function() {
8962 isFixed |= $(this).css('position') == 'fixed';
8963 return !isFixed;
8964 });
8965 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
8966 $.datepicker._pos[0] -= document.documentElement.scrollLeft;
8967 $.datepicker._pos[1] -= document.documentElement.scrollTop;
8968 }
8969 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8970 $.datepicker._pos = null;
8971 //to avoid flashes on Firefox
8972 inst.dpDiv.empty();
8973 // determine sizing offscreen
8974 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
8975 $.datepicker._updateDatepicker(inst);
8976 // fix width for dynamic number of date pickers
8977 // and adjust position before showing
8978 offset = $.datepicker._checkOffset(inst, offset, isFixed);
8979 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8980 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
8981 left: offset.left + 'px', top: offset.top + 'px'});
8982 if (!inst.inline) {
8983 var showAnim = $.datepicker._get(inst, 'showAnim');
8984 var duration = $.datepicker._get(inst, 'duration');
8985 var postProcess = function() {
8986 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8987 if( !! cover.length ){
8988 var borders = $.datepicker._getBorders(inst.dpDiv);
8989 cover.css({left: -borders[0], top: -borders[1],
8990 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
8991 }
8992 };
8993 inst.dpDiv.zIndex($(input).zIndex()+1);
8994 $.datepicker._datepickerShowing = true;
8995 if ($.effects && $.effects[showAnim])
8996 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8997 else
8998 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
8999 if (!showAnim || !duration)
9000 postProcess();
9001 if (inst.input.is(':visible') && !inst.input.is(':disabled'))
9002 inst.input.focus();
9003 $.datepicker._curInst = inst;
9004 }
9005 },
9006
9007 /* Generate the date picker content. */
9008 _updateDatepicker: function(inst) {
9009 var self = this;
9010 self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
9011 var borders = $.datepicker._getBorders(inst.dpDiv);
9012 instActive = inst; // for delegate hover events
9013 inst.dpDiv.empty().append(this._generateHTML(inst));
9014 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
9015 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
9016 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
9017 }
9018 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
9019 var numMonths = this._getNumberOfMonths(inst);
9020 var cols = numMonths[1];
9021 var width = 17;
9022 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
9023 if (cols > 1)
9024 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
9025 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
9026 'Class']('ui-datepicker-multi');
9027 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
9028 'Class']('ui-datepicker-rtl');
9029 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
9030 // #6694 - don't focus the input if it's already focused
9031 // this breaks the change event in IE
9032 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
9033 inst.input.focus();
9034 // deffered render of the years select (to avoid flashes on Firefox)
9035 if( inst.yearshtml ){
9036 var origyearshtml = inst.yearshtml;
9037 setTimeout(function(){
9038 //assure that inst.yearshtml didn't change.
9039 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
9040 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
9041 }
9042 origyearshtml = inst.yearshtml = null;
9043 }, 0);
9044 }
9045 },
9046
9047 /* Retrieve the size of left and top borders for an element.
9048 @param elem (jQuery object) the element of interest
9049 @return (number[2]) the left and top borders */
9050 _getBorders: function(elem) {
9051 var convert = function(value) {
9052 return {thin: 1, medium: 2, thick: 3}[value] || value;
9053 };
9054 return [parseFloat(convert(elem.css('border-left-width'))),
9055 parseFloat(convert(elem.css('border-top-width')))];
9056 },
9057
9058 /* Check positioning to remain on screen. */
9059 _checkOffset: function(inst, offset, isFixed) {
9060 var dpWidth = inst.dpDiv.outerWidth();
9061 var dpHeight = inst.dpDiv.outerHeight();
9062 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
9063 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
9064 var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
9065 var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
9066
9067 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
9068 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
9069 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
9070
9071 // now check if datepicker is showing outside window viewport - move to a better place if so.
9072 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
9073 Math.abs(offset.left + dpWidth - viewWidth) : 0);
9074 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
9075 Math.abs(dpHeight + inputHeight) : 0);
9076
9077 return offset;
9078 },
9079
9080 /* Find an object's position on the screen. */
9081 _findPos: function(obj) {
9082 var inst = this._getInst(obj);
9083 var isRTL = this._get(inst, 'isRTL');
9084 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
9085 obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
9086 }
9087 var position = $(obj).offset();
9088 return [position.left, position.top];
9089 },
9090
9091 /* Hide the date picker from view.
9092 @param input element - the input field attached to the date picker */
9093 _hideDatepicker: function(input) {
9094 var inst = this._curInst;
9095 if (!inst || (input && inst != $.data(input, PROP_NAME)))
9096 return;
9097 if (this._datepickerShowing) {
9098 var showAnim = this._get(inst, 'showAnim');
9099 var duration = this._get(inst, 'duration');
9100 var postProcess = function() {
9101 $.datepicker._tidyDialog(inst);
9102 };
9103 if ($.effects && $.effects[showAnim])
9104 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
9105 else
9106 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
9107 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
9108 if (!showAnim)
9109 postProcess();
9110 this._datepickerShowing = false;
9111 var onClose = this._get(inst, 'onClose');
9112 if (onClose)
9113 onClose.apply((inst.input ? inst.input[0] : null),
9114 [(inst.input ? inst.input.val() : ''), inst]);
9115 this._lastInput = null;
9116 if (this._inDialog) {
9117 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
9118 if ($.blockUI) {
9119 $.unblockUI();
9120 $('body').append(this.dpDiv);
9121 }
9122 }
9123 this._inDialog = false;
9124 }
9125 },
9126
9127 /* Tidy up after a dialog display. */
9128 _tidyDialog: function(inst) {
9129 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
9130 },
9131
9132 /* Close date picker if clicked elsewhere. */
9133 _checkExternalClick: function(event) {
9134 if (!$.datepicker._curInst)
9135 return;
9136
9137 var $target = $(event.target),
9138 inst = $.datepicker._getInst($target[0]);
9139
9140 if ( ( ( $target[0].id != $.datepicker._mainDivId &&
9141 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
9142 !$target.hasClass($.datepicker.markerClassName) &&
9143 !$target.closest("." + $.datepicker._triggerClass).length &&
9144 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
9145 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
9146 $.datepicker._hideDatepicker();
9147 },
9148
9149 /* Adjust one of the date sub-fields. */
9150 _adjustDate: function(id, offset, period) {
9151 var target = $(id);
9152 var inst = this._getInst(target[0]);
9153 if (this._isDisabledDatepicker(target[0])) {
9154 return;
9155 }
9156 this._adjustInstDate(inst, offset +
9157 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
9158 period);
9159 this._updateDatepicker(inst);
9160 },
9161
9162 /* Action for current link. */
9163 _gotoToday: function(id) {
9164 var target = $(id);
9165 var inst = this._getInst(target[0]);
9166 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
9167 inst.selectedDay = inst.currentDay;
9168 inst.drawMonth = inst.selectedMonth = inst.currentMonth;
9169 inst.drawYear = inst.selectedYear = inst.currentYear;
9170 }
9171 else {
9172 var date = new Date();
9173 inst.selectedDay = date.getDate();
9174 inst.drawMonth = inst.selectedMonth = date.getMonth();
9175 inst.drawYear = inst.selectedYear = date.getFullYear();
9176 }
9177 this._notifyChange(inst);
9178 this._adjustDate(target);
9179 },
9180
9181 /* Action for selecting a new month/year. */
9182 _selectMonthYear: function(id, select, period) {
9183 var target = $(id);
9184 var inst = this._getInst(target[0]);
9185 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
9186 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
9187 parseInt(select.options[select.selectedIndex].value,10);
9188 this._notifyChange(inst);
9189 this._adjustDate(target);
9190 },
9191
9192 /* Action for selecting a day. */
9193 _selectDay: function(id, month, year, td) {
9194 var target = $(id);
9195 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
9196 return;
9197 }
9198 var inst = this._getInst(target[0]);
9199 inst.selectedDay = inst.currentDay = $('a', td).html();
9200 inst.selectedMonth = inst.currentMonth = month;
9201 inst.selectedYear = inst.currentYear = year;
9202 this._selectDate(id, this._formatDate(inst,
9203 inst.currentDay, inst.currentMonth, inst.currentYear));
9204 },
9205
9206 /* Erase the input field and hide the date picker. */
9207 _clearDate: function(id) {
9208 var target = $(id);
9209 var inst = this._getInst(target[0]);
9210 this._selectDate(target, '');
9211 },
9212
9213 /* Update the input field with the selected date. */
9214 _selectDate: function(id, dateStr) {
9215 var target = $(id);
9216 var inst = this._getInst(target[0]);
9217 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9218 if (inst.input)
9219 inst.input.val(dateStr);
9220 this._updateAlternate(inst);
9221 var onSelect = this._get(inst, 'onSelect');
9222 if (onSelect)
9223 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
9224 else if (inst.input)
9225 inst.input.trigger('change'); // fire the change event
9226 if (inst.inline)
9227 this._updateDatepicker(inst);
9228 else {
9229 this._hideDatepicker();
9230 this._lastInput = inst.input[0];
9231 if (typeof(inst.input[0]) != 'object')
9232 inst.input.focus(); // restore focus
9233 this._lastInput = null;
9234 }
9235 },
9236
9237 /* Update any alternate field to synchronise with the main field. */
9238 _updateAlternate: function(inst) {
9239 var altField = this._get(inst, 'altField');
9240 if (altField) { // update alternate field too
9241 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
9242 var date = this._getDate(inst);
9243 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9244 $(altField).each(function() { $(this).val(dateStr); });
9245 }
9246 },
9247
9248 /* Set as beforeShowDay function to prevent selection of weekends.
9249 @param date Date - the date to customise
9250 @return [boolean, string] - is this date selectable?, what is its CSS class? */
9251 noWeekends: function(date) {
9252 var day = date.getDay();
9253 return [(day > 0 && day < 6), ''];
9254 },
9255
9256 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9257 @param date Date - the date to get the week for
9258 @return number - the number of the week within the year that contains this date */
9259 iso8601Week: function(date) {
9260 var checkDate = new Date(date.getTime());
9261 // Find Thursday of this week starting on Monday
9262 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9263 var time = checkDate.getTime();
9264 checkDate.setMonth(0); // Compare with Jan 1
9265 checkDate.setDate(1);
9266 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9267 },
9268
9269 /* Parse a string value into a date object.
9270 See formatDate below for the possible formats.
9271
9272 @param format string - the expected format of the date
9273 @param value string - the date in the above format
9274 @param settings Object - attributes include:
9275 shortYearCutoff number - the cutoff year for determining the century (optional)
9276 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9277 dayNames string[7] - names of the days from Sunday (optional)
9278 monthNamesShort string[12] - abbreviated names of the months (optional)
9279 monthNames string[12] - names of the months (optional)
9280 @return Date - the extracted date value or null if value is blank */
9281 parseDate: function (format, value, settings) {
9282 if (format == null || value == null)
9283 throw 'Invalid arguments';
9284 value = (typeof value == 'object' ? value.toString() : value + '');
9285 if (value == '')
9286 return null;
9287 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
9288 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9289 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9290 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9291 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9292 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9293 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9294 var year = -1;
9295 var month = -1;
9296 var day = -1;
9297 var doy = -1;
9298 var literal = false;
9299 // Check whether a format character is doubled
9300 var lookAhead = function(match) {
9301 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9302 if (matches)
9303 iFormat++;
9304 return matches;
9305 };
9306 // Extract a number from the string value
9307 var getNumber = function(match) {
9308 var isDoubled = lookAhead(match);
9309 var size = (match == '@' ? 14 : (match == '!' ? 20 :
9310 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
9311 var digits = new RegExp('^\\d{1,' + size + '}');
9312 var num = value.substring(iValue).match(digits);
9313 if (!num)
9314 throw 'Missing number at position ' + iValue;
9315 iValue += num[0].length;
9316 return parseInt(num[0], 10);
9317 };
9318 // Extract a name from the string value and convert to an index
9319 var getName = function(match, shortNames, longNames) {
9320 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9321 return [ [k, v] ];
9322 }).sort(function (a, b) {
9323 return -(a[1].length - b[1].length);
9324 });
9325 var index = -1;
9326 $.each(names, function (i, pair) {
9327 var name = pair[1];
9328 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
9329 index = pair[0];
9330 iValue += name.length;
9331 return false;
9332 }
9333 });
9334 if (index != -1)
9335 return index + 1;
9336 else
9337 throw 'Unknown name at position ' + iValue;
9338 };
9339 // Confirm that a literal character matches the string value
9340 var checkLiteral = function() {
9341 if (value.charAt(iValue) != format.charAt(iFormat))
9342 throw 'Unexpected literal at position ' + iValue;
9343 iValue++;
9344 };
9345 var iValue = 0;
9346 for (var iFormat = 0; iFormat < format.length; iFormat++) {
9347 if (literal)
9348 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9349 literal = false;
9350 else
9351 checkLiteral();
9352 else
9353 switch (format.charAt(iFormat)) {
9354 case 'd':
9355 day = getNumber('d');
9356 break;
9357 case 'D':
9358 getName('D', dayNamesShort, dayNames);
9359 break;
9360 case 'o':
9361 doy = getNumber('o');
9362 break;
9363 case 'm':
9364 month = getNumber('m');
9365 break;
9366 case 'M':
9367 month = getName('M', monthNamesShort, monthNames);
9368 break;
9369 case 'y':
9370 year = getNumber('y');
9371 break;
9372 case '@':
9373 var date = new Date(getNumber('@'));
9374 year = date.getFullYear();
9375 month = date.getMonth() + 1;
9376 day = date.getDate();
9377 break;
9378 case '!':
9379 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
9380 year = date.getFullYear();
9381 month = date.getMonth() + 1;
9382 day = date.getDate();
9383 break;
9384 case "'":
9385 if (lookAhead("'"))
9386 checkLiteral();
9387 else
9388 literal = true;
9389 break;
9390 default:
9391 checkLiteral();
9392 }
9393 }
9394 if (iValue < value.length){
9395 throw "Extra/unparsed characters found in date: " + value.substring(iValue);
9396 }
9397 if (year == -1)
9398 year = new Date().getFullYear();
9399 else if (year < 100)
9400 year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9401 (year <= shortYearCutoff ? 0 : -100);
9402 if (doy > -1) {
9403 month = 1;
9404 day = doy;
9405 do {
9406 var dim = this._getDaysInMonth(year, month - 1);
9407 if (day <= dim)
9408 break;
9409 month++;
9410 day -= dim;
9411 } while (true);
9412 }
9413 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9414 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
9415 throw 'Invalid date'; // E.g. 31/02/00
9416 return date;
9417 },
9418
9419 /* Standard date formats. */
9420 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
9421 COOKIE: 'D, dd M yy',
9422 ISO_8601: 'yy-mm-dd',
9423 RFC_822: 'D, d M y',
9424 RFC_850: 'DD, dd-M-y',
9425 RFC_1036: 'D, d M y',
9426 RFC_1123: 'D, d M yy',
9427 RFC_2822: 'D, d M yy',
9428 RSS: 'D, d M y', // RFC 822
9429 TICKS: '!',
9430 TIMESTAMP: '@',
9431 W3C: 'yy-mm-dd', // ISO 8601
9432
9433 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9434 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9435
9436 /* Format a date object into a string value.
9437 The format can be combinations of the following:
9438 d - day of month (no leading zero)
9439 dd - day of month (two digit)
9440 o - day of year (no leading zeros)
9441 oo - day of year (three digit)
9442 D - day name short
9443 DD - day name long
9444 m - month of year (no leading zero)
9445 mm - month of year (two digit)
9446 M - month name short
9447 MM - month name long
9448 y - year (two digit)
9449 yy - year (four digit)
9450 @ - Unix timestamp (ms since 01/01/1970)
9451 ! - Windows ticks (100ns since 01/01/0001)
9452 '...' - literal text
9453 '' - single quote
9454
9455 @param format string - the desired format of the date
9456 @param date Date - the date value to format
9457 @param settings Object - attributes include:
9458 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9459 dayNames string[7] - names of the days from Sunday (optional)
9460 monthNamesShort string[12] - abbreviated names of the months (optional)
9461 monthNames string[12] - names of the months (optional)
9462 @return string - the date in the above format */
9463 formatDate: function (format, date, settings) {
9464 if (!date)
9465 return '';
9466 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9467 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9468 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9469 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9470 // Check whether a format character is doubled
9471 var lookAhead = function(match) {
9472 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9473 if (matches)
9474 iFormat++;
9475 return matches;
9476 };
9477 // Format a number, with leading zero if necessary
9478 var formatNumber = function(match, value, len) {
9479 var num = '' + value;
9480 if (lookAhead(match))
9481 while (num.length < len)
9482 num = '0' + num;
9483 return num;
9484 };
9485 // Format a name, short or long as requested
9486 var formatName = function(match, value, shortNames, longNames) {
9487 return (lookAhead(match) ? longNames[value] : shortNames[value]);
9488 };
9489 var output = '';
9490 var literal = false;
9491 if (date)
9492 for (var iFormat = 0; iFormat < format.length; iFormat++) {
9493 if (literal)
9494 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9495 literal = false;
9496 else
9497 output += format.charAt(iFormat);
9498 else
9499 switch (format.charAt(iFormat)) {
9500 case 'd':
9501 output += formatNumber('d', date.getDate(), 2);
9502 break;
9503 case 'D':
9504 output += formatName('D', date.getDay(), dayNamesShort, dayNames);
9505 break;
9506 case 'o':
9507 output += formatNumber('o',
9508 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9509 break;
9510 case 'm':
9511 output += formatNumber('m', date.getMonth() + 1, 2);
9512 break;
9513 case 'M':
9514 output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
9515 break;
9516 case 'y':
9517 output += (lookAhead('y') ? date.getFullYear() :
9518 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
9519 break;
9520 case '@':
9521 output += date.getTime();
9522 break;
9523 case '!':
9524 output += date.getTime() * 10000 + this._ticksTo1970;
9525 break;
9526 case "'":
9527 if (lookAhead("'"))
9528 output += "'";
9529 else
9530 literal = true;
9531 break;
9532 default:
9533 output += format.charAt(iFormat);
9534 }
9535 }
9536 return output;
9537 },
9538
9539 /* Extract all possible characters from the date format. */
9540 _possibleChars: function (format) {
9541 var chars = '';
9542 var literal = false;
9543 // Check whether a format character is doubled
9544 var lookAhead = function(match) {
9545 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9546 if (matches)
9547 iFormat++;
9548 return matches;
9549 };
9550 for (var iFormat = 0; iFormat < format.length; iFormat++)
9551 if (literal)
9552 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9553 literal = false;
9554 else
9555 chars += format.charAt(iFormat);
9556 else
9557 switch (format.charAt(iFormat)) {
9558 case 'd': case 'm': case 'y': case '@':
9559 chars += '0123456789';
9560 break;
9561 case 'D': case 'M':
9562 return null; // Accept anything
9563 case "'":
9564 if (lookAhead("'"))
9565 chars += "'";
9566 else
9567 literal = true;
9568 break;
9569 default:
9570 chars += format.charAt(iFormat);
9571 }
9572 return chars;
9573 },
9574
9575 /* Get a setting value, defaulting if necessary. */
9576 _get: function(inst, name) {
9577 return inst.settings[name] !== undefined ?
9578 inst.settings[name] : this._defaults[name];
9579 },
9580
9581 /* Parse existing date and initialise date picker. */
9582 _setDateFromField: function(inst, noDefault) {
9583 if (inst.input.val() == inst.lastVal) {
9584 return;
9585 }
9586 var dateFormat = this._get(inst, 'dateFormat');
9587 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
9588 var date, defaultDate;
9589 date = defaultDate = this._getDefaultDate(inst);
9590 var settings = this._getFormatConfig(inst);
9591 try {
9592 date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9593 } catch (event) {
9594 this.log(event);
9595 dates = (noDefault ? '' : dates);
9596 }
9597 inst.selectedDay = date.getDate();
9598 inst.drawMonth = inst.selectedMonth = date.getMonth();
9599 inst.drawYear = inst.selectedYear = date.getFullYear();
9600 inst.currentDay = (dates ? date.getDate() : 0);
9601 inst.currentMonth = (dates ? date.getMonth() : 0);
9602 inst.currentYear = (dates ? date.getFullYear() : 0);
9603 this._adjustInstDate(inst);
9604 },
9605
9606 /* Retrieve the default date shown on opening. */
9607 _getDefaultDate: function(inst) {
9608 return this._restrictMinMax(inst,
9609 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
9610 },
9611
9612 /* A date may be specified as an exact value or a relative one. */
9613 _determineDate: function(inst, date, defaultDate) {
9614 var offsetNumeric = function(offset) {
9615 var date = new Date();
9616 date.setDate(date.getDate() + offset);
9617 return date;
9618 };
9619 var offsetString = function(offset) {
9620 try {
9621 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
9622 offset, $.datepicker._getFormatConfig(inst));
9623 }
9624 catch (e) {
9625 // Ignore
9626 }
9627 var date = (offset.toLowerCase().match(/^c/) ?
9628 $.datepicker._getDate(inst) : null) || new Date();
9629 var year = date.getFullYear();
9630 var month = date.getMonth();
9631 var day = date.getDate();
9632 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
9633 var matches = pattern.exec(offset);
9634 while (matches) {
9635 switch (matches[2] || 'd') {
9636 case 'd' : case 'D' :
9637 day += parseInt(matches[1],10); break;
9638 case 'w' : case 'W' :
9639 day += parseInt(matches[1],10) * 7; break;
9640 case 'm' : case 'M' :
9641 month += parseInt(matches[1],10);
9642 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9643 break;
9644 case 'y': case 'Y' :
9645 year += parseInt(matches[1],10);
9646 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9647 break;
9648 }
9649 matches = pattern.exec(offset);
9650 }
9651 return new Date(year, month, day);
9652 };
9653 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
9654 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9655 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
9656 if (newDate) {
9657 newDate.setHours(0);
9658 newDate.setMinutes(0);
9659 newDate.setSeconds(0);
9660 newDate.setMilliseconds(0);
9661 }
9662 return this._daylightSavingAdjust(newDate);
9663 },
9664
9665 /* Handle switch to/from daylight saving.
9666 Hours may be non-zero on daylight saving cut-over:
9667 > 12 when midnight changeover, but then cannot generate
9668 midnight datetime, so jump to 1AM, otherwise reset.
9669 @param date (Date) the date to check
9670 @return (Date) the corrected date */
9671 _daylightSavingAdjust: function(date) {
9672 if (!date) return null;
9673 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9674 return date;
9675 },
9676
9677 /* Set the date(s) directly. */
9678 _setDate: function(inst, date, noChange) {
9679 var clear = !date;
9680 var origMonth = inst.selectedMonth;
9681 var origYear = inst.selectedYear;
9682 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9683 inst.selectedDay = inst.currentDay = newDate.getDate();
9684 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9685 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9686 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
9687 this._notifyChange(inst);
9688 this._adjustInstDate(inst);
9689 if (inst.input) {
9690 inst.input.val(clear ? '' : this._formatDate(inst));
9691 }
9692 },
9693
9694 /* Retrieve the date(s) directly. */
9695 _getDate: function(inst) {
9696 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
9697 this._daylightSavingAdjust(new Date(
9698 inst.currentYear, inst.currentMonth, inst.currentDay)));
9699 return startDate;
9700 },
9701
9702 /* Generate the HTML for the current state of the date picker. */
9703 _generateHTML: function(inst) {
9704 var today = new Date();
9705 today = this._daylightSavingAdjust(
9706 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
9707 var isRTL = this._get(inst, 'isRTL');
9708 var showButtonPanel = this._get(inst, 'showButtonPanel');
9709 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
9710 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
9711 var numMonths = this._getNumberOfMonths(inst);
9712 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
9713 var stepMonths = this._get(inst, 'stepMonths');
9714 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
9715 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9716 new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9717 var minDate = this._getMinMaxDate(inst, 'min');
9718 var maxDate = this._getMinMaxDate(inst, 'max');
9719 var drawMonth = inst.drawMonth - showCurrentAtPos;
9720 var drawYear = inst.drawYear;
9721 if (drawMonth < 0) {
9722 drawMonth += 12;
9723 drawYear--;
9724 }
9725 if (maxDate) {
9726 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9727 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9728 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9729 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9730 drawMonth--;
9731 if (drawMonth < 0) {
9732 drawMonth = 11;
9733 drawYear--;
9734 }
9735 }
9736 }
9737 inst.drawMonth = drawMonth;
9738 inst.drawYear = drawYear;
9739 var prevText = this._get(inst, 'prevText');
9740 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9741 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9742 this._getFormatConfig(inst)));
9743 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9744 '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9745 '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
9746 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
9747 (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>'));
9748 var nextText = this._get(inst, 'nextText');
9749 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9750 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9751 this._getFormatConfig(inst)));
9752 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9753 '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9754 '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
9755 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
9756 (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>'));
9757 var currentText = this._get(inst, 'currentText');
9758 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
9759 currentText = (!navigationAsDateFormat ? currentText :
9760 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9761 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9762 '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
9763 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
9764 (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
9765 '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
9766 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
9767 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
9768 firstDay = (isNaN(firstDay) ? 0 : firstDay);
9769 var showWeek = this._get(inst, 'showWeek');
9770 var dayNames = this._get(inst, 'dayNames');
9771 var dayNamesShort = this._get(inst, 'dayNamesShort');
9772 var dayNamesMin = this._get(inst, 'dayNamesMin');
9773 var monthNames = this._get(inst, 'monthNames');
9774 var monthNamesShort = this._get(inst, 'monthNamesShort');
9775 var beforeShowDay = this._get(inst, 'beforeShowDay');
9776 var showOtherMonths = this._get(inst, 'showOtherMonths');
9777 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
9778 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
9779 var defaultDate = this._getDefaultDate(inst);
9780 var html = '';
9781 for (var row = 0; row < numMonths[0]; row++) {
9782 var group = '';
9783 this.maxRows = 4;
9784 for (var col = 0; col < numMonths[1]; col++) {
9785 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9786 var cornerClass = ' ui-corner-all';
9787 var calender = '';
9788 if (isMultiMonth) {
9789 calender += '<div class="ui-datepicker-group';
9790 if (numMonths[1] > 1)
9791 switch (col) {
9792 case 0: calender += ' ui-datepicker-group-first';
9793 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
9794 case numMonths[1]-1: calender += ' ui-datepicker-group-last';
9795 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
9796 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
9797 }
9798 calender += '">';
9799 }
9800 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
9801 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
9802 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
9803 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9804 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9805 '</div><table class="ui-datepicker-calendar"><thead>' +
9806 '<tr>';
9807 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
9808 for (var dow = 0; dow < 7; dow++) { // days of the week
9809 var day = (dow + firstDay) % 7;
9810 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
9811 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
9812 }
9813 calender += thead + '</tr></thead><tbody>';
9814 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9815 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
9816 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9817 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9818 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9819 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9820 this.maxRows = numRows;
9821 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9822 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9823 calender += '<tr>';
9824 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
9825 this._get(inst, 'calculateWeek')(printDate) + '</td>');
9826 for (var dow = 0; dow < 7; dow++) { // create date picker days
9827 var daySettings = (beforeShowDay ?
9828 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
9829 var otherMonth = (printDate.getMonth() != drawMonth);
9830 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9831 (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9832 tbody += '<td class="' +
9833 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
9834 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
9835 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
9836 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
9837 // or defaultDate is current printedDate and defaultDate is selectedDate
9838 ' ' + this._dayOverClass : '') + // highlight selected day
9839 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
9840 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
9841 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
9842 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
9843 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
9844 (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
9845 inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
9846 (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
9847 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
9848 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
9849 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
9850 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
9851 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
9852 printDate.setDate(printDate.getDate() + 1);
9853 printDate = this._daylightSavingAdjust(printDate);
9854 }
9855 calender += tbody + '</tr>';
9856 }
9857 drawMonth++;
9858 if (drawMonth > 11) {
9859 drawMonth = 0;
9860 drawYear++;
9861 }
9862 calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
9863 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
9864 group += calender;
9865 }
9866 html += group;
9867 }
9868 html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
9869 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
9870 inst._keyEvent = false;
9871 return html;
9872 },
9873
9874 /* Generate the month and year header. */
9875 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9876 secondary, monthNames, monthNamesShort) {
9877 var changeMonth = this._get(inst, 'changeMonth');
9878 var changeYear = this._get(inst, 'changeYear');
9879 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
9880 var html = '<div class="ui-datepicker-title">';
9881 var monthHtml = '';
9882 // month selection
9883 if (secondary || !changeMonth)
9884 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
9885 else {
9886 var inMinYear = (minDate && minDate.getFullYear() == drawYear);
9887 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
9888 monthHtml += '<select class="ui-datepicker-month" ' +
9889 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
9890 '>';
9891 for (var month = 0; month < 12; month++) {
9892 if ((!inMinYear || month >= minDate.getMonth()) &&
9893 (!inMaxYear || month <= maxDate.getMonth()))
9894 monthHtml += '<option value="' + month + '"' +
9895 (month == drawMonth ? ' selected="selected"' : '') +
9896 '>' + monthNamesShort[month] + '</option>';
9897 }
9898 monthHtml += '</select>';
9899 }
9900 if (!showMonthAfterYear)
9901 html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
9902 // year selection
9903 if ( !inst.yearshtml ) {
9904 inst.yearshtml = '';
9905 if (secondary || !changeYear)
9906 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
9907 else {
9908 // determine range of years to display
9909 var years = this._get(inst, 'yearRange').split(':');
9910 var thisYear = new Date().getFullYear();
9911 var determineYear = function(value) {
9912 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9913 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
9914 parseInt(value, 10)));
9915 return (isNaN(year) ? thisYear : year);
9916 };
9917 var year = determineYear(years[0]);
9918 var endYear = Math.max(year, determineYear(years[1] || ''));
9919 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9920 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9921 inst.yearshtml += '<select class="ui-datepicker-year" ' +
9922 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
9923 '>';
9924 for (; year <= endYear; year++) {
9925 inst.yearshtml += '<option value="' + year + '"' +
9926 (year == drawYear ? ' selected="selected"' : '') +
9927 '>' + year + '</option>';
9928 }
9929 inst.yearshtml += '</select>';
9930
9931 html += inst.yearshtml;
9932 inst.yearshtml = null;
9933 }
9934 }
9935 html += this._get(inst, 'yearSuffix');
9936 if (showMonthAfterYear)
9937 html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
9938 html += '</div>'; // Close datepicker_header
9939 return html;
9940 },
9941
9942 /* Adjust one of the date sub-fields. */
9943 _adjustInstDate: function(inst, offset, period) {
9944 var year = inst.drawYear + (period == 'Y' ? offset : 0);
9945 var month = inst.drawMonth + (period == 'M' ? offset : 0);
9946 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
9947 (period == 'D' ? offset : 0);
9948 var date = this._restrictMinMax(inst,
9949 this._daylightSavingAdjust(new Date(year, month, day)));
9950 inst.selectedDay = date.getDate();
9951 inst.drawMonth = inst.selectedMonth = date.getMonth();
9952 inst.drawYear = inst.selectedYear = date.getFullYear();
9953 if (period == 'M' || period == 'Y')
9954 this._notifyChange(inst);
9955 },
9956
9957 /* Ensure a date is within any min/max bounds. */
9958 _restrictMinMax: function(inst, date) {
9959 var minDate = this._getMinMaxDate(inst, 'min');
9960 var maxDate = this._getMinMaxDate(inst, 'max');
9961 var newDate = (minDate && date < minDate ? minDate : date);
9962 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
9963 return newDate;
9964 },
9965
9966 /* Notify change of month/year. */
9967 _notifyChange: function(inst) {
9968 var onChange = this._get(inst, 'onChangeMonthYear');
9969 if (onChange)
9970 onChange.apply((inst.input ? inst.input[0] : null),
9971 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9972 },
9973
9974 /* Determine the number of months to show. */
9975 _getNumberOfMonths: function(inst) {
9976 var numMonths = this._get(inst, 'numberOfMonths');
9977 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
9978 },
9979
9980 /* Determine the current maximum date - ensure no time components are set. */
9981 _getMinMaxDate: function(inst, minMax) {
9982 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
9983 },
9984
9985 /* Find the number of days in a given month. */
9986 _getDaysInMonth: function(year, month) {
9987 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9988 },
9989
9990 /* Find the day of the week of the first of a month. */
9991 _getFirstDayOfMonth: function(year, month) {
9992 return new Date(year, month, 1).getDay();
9993 },
9994
9995 /* Determines if we should allow a "next/prev" month display change. */
9996 _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9997 var numMonths = this._getNumberOfMonths(inst);
9998 var date = this._daylightSavingAdjust(new Date(curYear,
9999 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
10000 if (offset < 0)
10001 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
10002 return this._isInRange(inst, date);
10003 },
10004
10005 /* Is the given date in the accepted range? */
10006 _isInRange: function(inst, date) {
10007 var minDate = this._getMinMaxDate(inst, 'min');
10008 var maxDate = this._getMinMaxDate(inst, 'max');
10009 return ((!minDate || date.getTime() >= minDate.getTime()) &&
10010 (!maxDate || date.getTime() <= maxDate.getTime()));
10011 },
10012
10013 /* Provide the configuration settings for formatting/parsing. */
10014 _getFormatConfig: function(inst) {
10015 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
10016 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
10017 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
10018 return {shortYearCutoff: shortYearCutoff,
10019 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
10020 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
10021 },
10022
10023 /* Format the given date for display. */
10024 _formatDate: function(inst, day, month, year) {
10025 if (!day) {
10026 inst.currentDay = inst.selectedDay;
10027 inst.currentMonth = inst.selectedMonth;
10028 inst.currentYear = inst.selectedYear;
10029 }
10030 var date = (day ? (typeof day == 'object' ? day :
10031 this._daylightSavingAdjust(new Date(year, month, day))) :
10032 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
10033 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
10034 }
10035 });
10036
10037 /*
10038 * Bind hover events for datepicker elements.
10039 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
10040 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
10041 */
10042 function bindHover(dpDiv) {
10043 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
10044 return dpDiv.bind('mouseout', function(event) {
10045 var elem = $( event.target ).closest( selector );
10046 if ( !elem.length ) {
10047 return;
10048 }
10049 elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
10050 })
10051 .bind('mouseover', function(event) {
10052 var elem = $( event.target ).closest( selector );
10053 if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
10054 !elem.length ) {
10055 return;
10056 }
10057 elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
10058 elem.addClass('ui-state-hover');
10059 if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
10060 if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
10061 });
10062 }
10063
10064 /* jQuery extend now ignores nulls! */
10065 function extendRemove(target, props) {
10066 $.extend(target, props);
10067 for (var name in props)
10068 if (props[name] == null || props[name] == undefined)
10069 target[name] = props[name];
10070 return target;
10071 };
10072
10073 /* Determine whether an object is an array. */
10074 function isArray(a) {
10075 return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
10076 (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
10077 };
10078
10079 /* Invoke the datepicker functionality.
10080 @param options string - a command, optionally followed by additional parameters or
10081 Object - settings for attaching new datepicker functionality
10082 @return jQuery object */
10083 $.fn.datepicker = function(options){
10084
10085 /* Verify an empty collection wasn't passed - Fixes #6976 */
10086 if ( !this.length ) {
10087 return this;
10088 }
10089
10090 /* Initialise the date picker. */
10091 if (!$.datepicker.initialized) {
10092 $(document).mousedown($.datepicker._checkExternalClick).
10093 find('body').append($.datepicker.dpDiv);
10094 $.datepicker.initialized = true;
10095 }
10096
10097 var otherArgs = Array.prototype.slice.call(arguments, 1);
10098 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
10099 return $.datepicker['_' + options + 'Datepicker'].
10100 apply($.datepicker, [this[0]].concat(otherArgs));
10101 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
10102 return $.datepicker['_' + options + 'Datepicker'].
10103 apply($.datepicker, [this[0]].concat(otherArgs));
10104 return this.each(function() {
10105 typeof options == 'string' ?
10106 $.datepicker['_' + options + 'Datepicker'].
10107 apply($.datepicker, [this].concat(otherArgs)) :
10108 $.datepicker._attachDatepicker(this, options);
10109 });
10110 };
10111
10112 $.datepicker = new Datepicker(); // singleton instance
10113 $.datepicker.initialized = false;
10114 $.datepicker.uuid = new Date().getTime();
10115 $.datepicker.version = "1.8.21";
10116
10117 // Workaround for #4055
10118 // Add another global to avoid noConflict issues with inline event handlers
10119 window['DP_jQuery_' + dpuuid] = $;
10120
10121 })(jQuery);
10122 /*!
10123 * jQuery UI Progressbar 1.8.21
10124 *
10125 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
10126 * Dual licensed under the MIT or GPL Version 2 licenses.
10127 * http://jquery.org/license
10128 *
10129 * http://docs.jquery.com/UI/Progressbar
10130 *
10131 * Depends:
10132 * jquery.ui.core.js
10133 * jquery.ui.widget.js
10134 */
10135 (function( $, undefined ) {
10136
10137 $.widget( "ui.progressbar", {
10138 options: {
10139 value: 0,
10140 max: 100
10141 },
10142
10143 min: 0,
10144
10145 _create: function() {
10146 this.element
10147 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10148 .attr({
10149 role: "progressbar",
10150 "aria-valuemin": this.min,
10151 "aria-valuemax": this.options.max,
10152 "aria-valuenow": this._value()
10153 });
10154
10155 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10156 .appendTo( this.element );
10157
10158 this.oldValue = this._value();
10159 this._refreshValue();
10160 },
10161
10162 destroy: function() {
10163 this.element
10164 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10165 .removeAttr( "role" )
10166 .removeAttr( "aria-valuemin" )
10167 .removeAttr( "aria-valuemax" )
10168 .removeAttr( "aria-valuenow" );
10169
10170 this.valueDiv.remove();
10171
10172 $.Widget.prototype.destroy.apply( this, arguments );
10173 },
10174
10175 value: function( newValue ) {
10176 if ( newValue === undefined ) {
10177 return this._value();
10178 }
10179
10180 this._setOption( "value", newValue );
10181 return this;
10182 },
10183
10184 _setOption: function( key, value ) {
10185 if ( key === "value" ) {
10186 this.options.value = value;
10187 this._refreshValue();
10188 if ( this._value() === this.options.max ) {
10189 this._trigger( "complete" );
10190 }
10191 }
10192
10193 $.Widget.prototype._setOption.apply( this, arguments );
10194 },
10195
10196 _value: function() {
10197 var val = this.options.value;
10198 // normalize invalid value
10199 if ( typeof val !== "number" ) {
10200 val = 0;
10201 }
10202 return Math.min( this.options.max, Math.max( this.min, val ) );
10203 },
10204
10205 _percentage: function() {
10206 return 100 * this._value() / this.options.max;
10207 },
10208
10209 _refreshValue: function() {
10210 var value = this.value();
10211 var percentage = this._percentage();
10212
10213 if ( this.oldValue !== value ) {
10214 this.oldValue = value;
10215 this._trigger( "change" );
10216 }
10217
10218 this.valueDiv
10219 .toggle( value > this.min )
10220 .toggleClass( "ui-corner-right", value === this.options.max )
10221 .width( percentage.toFixed(0) + "%" );
10222 this.element.attr( "aria-valuenow", value );
10223 }
10224 });
10225
10226 $.extend( $.ui.progressbar, {
10227 version: "1.8.21"
10228 });
10229
10230 })( jQuery );
10231 /*!
10232 * jQuery UI Effects 1.8.21
10233 *
10234 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
10235 * Dual licensed under the MIT or GPL Version 2 licenses.
10236 * http://jquery.org/license
10237 *
10238 * http://docs.jquery.com/UI/Effects/
10239 */
10240 ;jQuery.effects || (function($, undefined) {
10241
10242 $.effects = {};
10243
10244
10245
10246 /******************************************************************************/
10247 /****************************** COLOR ANIMATIONS ******************************/
10248 /******************************************************************************/
10249
10250 // override the animation for color styles
10251 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
10252 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
10253 function(i, attr) {
10254 $.fx.step[attr] = function(fx) {
10255 if (!fx.colorInit) {
10256 fx.start = getColor(fx.elem, attr);
10257 fx.end = getRGB(fx.end);
10258 fx.colorInit = true;
10259 }
10260
10261 fx.elem.style[attr] = 'rgb(' +
10262 Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
10263 Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
10264 Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
10265 };
10266 });
10267
10268 // Color Conversion functions from highlightFade
10269 // By Blair Mitchelmore
10270 // http://jquery.offput.ca/highlightFade/
10271
10272 // Parse strings looking for color tuples [255,255,255]
10273 function getRGB(color) {
10274 var result;
10275
10276 // Check if we're already dealing with an array of colors
10277 if ( color && color.constructor == Array && color.length == 3 )
10278 return color;
10279
10280 // Look for rgb(num,num,num)
10281 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
10282 return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
10283
10284 // Look for rgb(num%,num%,num%)
10285 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
10286 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
10287
10288 // Look for #a0b1c2
10289 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
10290 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
10291
10292 // Look for #fff
10293 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
10294 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
10295
10296 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
10297 if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
10298 return colors['transparent'];
10299
10300 // Otherwise, we're most likely dealing with a named color
10301 return colors[$.trim(color).toLowerCase()];
10302 }
10303
10304 function getColor(elem, attr) {
10305 var color;
10306
10307 do {
10308 color = $.curCSS(elem, attr);
10309
10310 // Keep going until we find an element that has color, or we hit the body
10311 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
10312 break;
10313
10314 attr = "backgroundColor";
10315 } while ( elem = elem.parentNode );
10316
10317 return getRGB(color);
10318 };
10319
10320 // Some named colors to work with
10321 // From Interface by Stefan Petre
10322 // http://interface.eyecon.ro/
10323
10324 var colors = {
10325 aqua:[0,255,255],
10326 azure:[240,255,255],
10327 beige:[245,245,220],
10328 black:[0,0,0],
10329 blue:[0,0,255],
10330 brown:[165,42,42],
10331 cyan:[0,255,255],
10332 darkblue:[0,0,139],
10333 darkcyan:[0,139,139],
10334 darkgrey:[169,169,169],
10335 darkgreen:[0,100,0],
10336 darkkhaki:[189,183,107],
10337 darkmagenta:[139,0,139],
10338 darkolivegreen:[85,107,47],
10339 darkorange:[255,140,0],
10340 darkorchid:[153,50,204],
10341 darkred:[139,0,0],
10342 darksalmon:[233,150,122],
10343 darkviolet:[148,0,211],
10344 fuchsia:[255,0,255],
10345 gold:[255,215,0],
10346 green:[0,128,0],
10347 indigo:[75,0,130],
10348 khaki:[240,230,140],
10349 lightblue:[173,216,230],
10350 lightcyan:[224,255,255],
10351 lightgreen:[144,238,144],
10352 lightgrey:[211,211,211],
10353 lightpink:[255,182,193],
10354 lightyellow:[255,255,224],
10355 lime:[0,255,0],
10356 magenta:[255,0,255],
10357 maroon:[128,0,0],
10358 navy:[0,0,128],
10359 olive:[128,128,0],
10360 orange:[255,165,0],
10361 pink:[255,192,203],
10362 purple:[128,0,128],
10363 violet:[128,0,128],
10364 red:[255,0,0],
10365 silver:[192,192,192],
10366 white:[255,255,255],
10367 yellow:[255,255,0],
10368 transparent: [255,255,255]
10369 };
10370
10371
10372
10373 /******************************************************************************/
10374 /****************************** CLASS ANIMATIONS ******************************/
10375 /******************************************************************************/
10376
10377 var classAnimationActions = ['add', 'remove', 'toggle'],
10378 shorthandStyles = {
10379 border: 1,
10380 borderBottom: 1,
10381 borderColor: 1,
10382 borderLeft: 1,
10383 borderRight: 1,
10384 borderTop: 1,
10385 borderWidth: 1,
10386 margin: 1,
10387 padding: 1
10388 };
10389
10390 function getElementStyles() {
10391 var style = document.defaultView
10392 ? document.defaultView.getComputedStyle(this, null)
10393 : this.currentStyle,
10394 newStyle = {},
10395 key,
10396 camelCase;
10397
10398 // webkit enumerates style porperties
10399 if (style && style.length && style[0] && style[style[0]]) {
10400 var len = style.length;
10401 while (len--) {
10402 key = style[len];
10403 if (typeof style[key] == 'string') {
10404 camelCase = key.replace(/\-(\w)/g, function(all, letter){
10405 return letter.toUpperCase();
10406 });
10407 newStyle[camelCase] = style[key];
10408 }
10409 }
10410 } else {
10411 for (key in style) {
10412 if (typeof style[key] === 'string') {
10413 newStyle[key] = style[key];
10414 }
10415 }
10416 }
10417
10418 return newStyle;
10419 }
10420
10421 function filterStyles(styles) {
10422 var name, value;
10423 for (name in styles) {
10424 value = styles[name];
10425 if (
10426 // ignore null and undefined values
10427 value == null ||
10428 // ignore functions (when does this occur?)
10429 $.isFunction(value) ||
10430 // shorthand styles that need to be expanded
10431 name in shorthandStyles ||
10432 // ignore scrollbars (break in IE)
10433 (/scrollbar/).test(name) ||
10434
10435 // only colors or values that can be converted to numbers
10436 (!(/color/i).test(name) && isNaN(parseFloat(value)))
10437 ) {
10438 delete styles[name];
10439 }
10440 }
10441
10442 return styles;
10443 }
10444
10445 function styleDifference(oldStyle, newStyle) {
10446 var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
10447 name;
10448
10449 for (name in newStyle) {
10450 if (oldStyle[name] != newStyle[name]) {
10451 diff[name] = newStyle[name];
10452 }
10453 }
10454
10455 return diff;
10456 }
10457
10458 $.effects.animateClass = function(value, duration, easing, callback) {
10459 if ($.isFunction(easing)) {
10460 callback = easing;
10461 easing = null;
10462 }
10463
10464 return this.queue(function() {
10465 var that = $(this),
10466 originalStyleAttr = that.attr('style') || ' ',
10467 originalStyle = filterStyles(getElementStyles.call(this)),
10468 newStyle,
10469 className = that.attr('class') || "";
10470
10471 $.each(classAnimationActions, function(i, action) {
10472 if (value[action]) {
10473 that[action + 'Class'](value[action]);
10474 }
10475 });
10476 newStyle = filterStyles(getElementStyles.call(this));
10477 that.attr('class', className);
10478
10479 that.animate(styleDifference(originalStyle, newStyle), {
10480 queue: false,
10481 duration: duration,
10482 easing: easing,
10483 complete: function() {
10484 $.each(classAnimationActions, function(i, action) {
10485 if (value[action]) { that[action + 'Class'](value[action]); }
10486 });
10487 // work around bug in IE by clearing the cssText before setting it
10488 if (typeof that.attr('style') == 'object') {
10489 that.attr('style').cssText = '';
10490 that.attr('style').cssText = originalStyleAttr;
10491 } else {
10492 that.attr('style', originalStyleAttr);
10493 }
10494 if (callback) { callback.apply(this, arguments); }
10495 $.dequeue( this );
10496 }
10497 });
10498 });
10499 };
10500
10501 $.fn.extend({
10502 _addClass: $.fn.addClass,
10503 addClass: function(classNames, speed, easing, callback) {
10504 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
10505 },
10506
10507 _removeClass: $.fn.removeClass,
10508 removeClass: function(classNames,speed,easing,callback) {
10509 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
10510 },
10511
10512 _toggleClass: $.fn.toggleClass,
10513 toggleClass: function(classNames, force, speed, easing, callback) {
10514 if ( typeof force == "boolean" || force === undefined ) {
10515 if ( !speed ) {
10516 // without speed parameter;
10517 return this._toggleClass(classNames, force);
10518 } else {
10519 return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
10520 }
10521 } else {
10522 // without switch parameter;
10523 return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
10524 }
10525 },
10526
10527 switchClass: function(remove,add,speed,easing,callback) {
10528 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
10529 }
10530 });
10531
10532
10533
10534 /******************************************************************************/
10535 /*********************************** EFFECTS **********************************/
10536 /******************************************************************************/
10537
10538 $.extend($.effects, {
10539 version: "1.8.21",
10540
10541 // Saves a set of properties in a data storage
10542 save: function(element, set) {
10543 for(var i=0; i < set.length; i++) {
10544 if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
10545 }
10546 },
10547
10548 // Restores a set of previously saved properties from a data storage
10549 restore: function(element, set) {
10550 for(var i=0; i < set.length; i++) {
10551 if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
10552 }
10553 },
10554
10555 setMode: function(el, mode) {
10556 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
10557 return mode;
10558 },
10559
10560 getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
10561 // this should be a little more flexible in the future to handle a string & hash
10562 var y, x;
10563 switch (origin[0]) {
10564 case 'top': y = 0; break;
10565 case 'middle': y = 0.5; break;
10566 case 'bottom': y = 1; break;
10567 default: y = origin[0] / original.height;
10568 };
10569 switch (origin[1]) {
10570 case 'left': x = 0; break;
10571 case 'center': x = 0.5; break;
10572 case 'right': x = 1; break;
10573 default: x = origin[1] / original.width;
10574 };
10575 return {x: x, y: y};
10576 },
10577
10578 // Wraps the element around a wrapper that copies position properties
10579 createWrapper: function(element) {
10580
10581 // if the element is already wrapped, return it
10582 if (element.parent().is('.ui-effects-wrapper')) {
10583 return element.parent();
10584 }
10585
10586 // wrap the element
10587 var props = {
10588 width: element.outerWidth(true),
10589 height: element.outerHeight(true),
10590 'float': element.css('float')
10591 },
10592 wrapper = $('<div></div>')
10593 .addClass('ui-effects-wrapper')
10594 .css({
10595 fontSize: '100%',
10596 background: 'transparent',
10597 border: 'none',
10598 margin: 0,
10599 padding: 0
10600 }),
10601 active = document.activeElement;
10602
10603 // support: Firefox
10604 // Firefox incorrectly exposes anonymous content
10605 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10606 try {
10607 active.id;
10608 } catch( e ) {
10609 active = document.body;
10610 }
10611
10612 element.wrap( wrapper );
10613
10614 // Fixes #7595 - Elements lose focus when wrapped.
10615 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10616 $( active ).focus();
10617 }
10618
10619 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
10620
10621 // transfer positioning properties to the wrapper
10622 if (element.css('position') == 'static') {
10623 wrapper.css({ position: 'relative' });
10624 element.css({ position: 'relative' });
10625 } else {
10626 $.extend(props, {
10627 position: element.css('position'),
10628 zIndex: element.css('z-index')
10629 });
10630 $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
10631 props[pos] = element.css(pos);
10632 if (isNaN(parseInt(props[pos], 10))) {
10633 props[pos] = 'auto';
10634 }
10635 });
10636 element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
10637 }
10638
10639 return wrapper.css(props).show();
10640 },
10641
10642 removeWrapper: function(element) {
10643 var parent,
10644 active = document.activeElement;
10645
10646 if (element.parent().is('.ui-effects-wrapper')) {
10647 parent = element.parent().replaceWith(element);
10648 // Fixes #7595 - Elements lose focus when wrapped.
10649 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10650 $( active ).focus();
10651 }
10652 return parent;
10653 }
10654
10655 return element;
10656 },
10657
10658 setTransition: function(element, list, factor, value) {
10659 value = value || {};
10660 $.each(list, function(i, x){
10661 var unit = element.cssUnit(x);
10662 if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
10663 });
10664 return value;
10665 }
10666 });
10667
10668
10669 function _normalizeArguments(effect, options, speed, callback) {
10670 // shift params for method overloading
10671 if (typeof effect == 'object') {
10672 callback = options;
10673 speed = null;
10674 options = effect;
10675 effect = options.effect;
10676 }
10677 if ($.isFunction(options)) {
10678 callback = options;
10679 speed = null;
10680 options = {};
10681 }
10682 if (typeof options == 'number' || $.fx.speeds[options]) {
10683 callback = speed;
10684 speed = options;
10685 options = {};
10686 }
10687 if ($.isFunction(speed)) {
10688 callback = speed;
10689 speed = null;
10690 }
10691
10692 options = options || {};
10693
10694 speed = speed || options.duration;
10695 speed = $.fx.off ? 0 : typeof speed == 'number'
10696 ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
10697
10698 callback = callback || options.complete;
10699
10700 return [effect, options, speed, callback];
10701 }
10702
10703 function standardSpeed( speed ) {
10704 // valid standard speeds
10705 if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
10706 return true;
10707 }
10708
10709 // invalid strings - treat as "normal" speed
10710 if ( typeof speed === "string" && !$.effects[ speed ] ) {
10711 return true;
10712 }
10713
10714 return false;
10715 }
10716
10717 $.fn.extend({
10718 effect: function(effect, options, speed, callback) {
10719 var args = _normalizeArguments.apply(this, arguments),
10720 // TODO: make effects take actual parameters instead of a hash
10721 args2 = {
10722 options: args[1],
10723 duration: args[2],
10724 callback: args[3]
10725 },
10726 mode = args2.options.mode,
10727 effectMethod = $.effects[effect];
10728
10729 if ( $.fx.off || !effectMethod ) {
10730 // delegate to the original method (e.g., .show()) if possible
10731 if ( mode ) {
10732 return this[ mode ]( args2.duration, args2.callback );
10733 } else {
10734 return this.each(function() {
10735 if ( args2.callback ) {
10736 args2.callback.call( this );
10737 }
10738 });
10739 }
10740 }
10741
10742 return effectMethod.call(this, args2);
10743 },
10744
10745 _show: $.fn.show,
10746 show: function(speed) {
10747 if ( standardSpeed( speed ) ) {
10748 return this._show.apply(this, arguments);
10749 } else {
10750 var args = _normalizeArguments.apply(this, arguments);
10751 args[1].mode = 'show';
10752 return this.effect.apply(this, args);
10753 }
10754 },
10755
10756 _hide: $.fn.hide,
10757 hide: function(speed) {
10758 if ( standardSpeed( speed ) ) {
10759 return this._hide.apply(this, arguments);
10760 } else {
10761 var args = _normalizeArguments.apply(this, arguments);
10762 args[1].mode = 'hide';
10763 return this.effect.apply(this, args);
10764 }
10765 },
10766
10767 // jQuery core overloads toggle and creates _toggle
10768 __toggle: $.fn.toggle,
10769 toggle: function(speed) {
10770 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
10771 return this.__toggle.apply(this, arguments);
10772 } else {
10773 var args = _normalizeArguments.apply(this, arguments);
10774 args[1].mode = 'toggle';
10775 return this.effect.apply(this, args);
10776 }
10777 },
10778
10779 // helper functions
10780 cssUnit: function(key) {
10781 var style = this.css(key), val = [];
10782 $.each( ['em','px','%','pt'], function(i, unit){
10783 if(style.indexOf(unit) > 0)
10784 val = [parseFloat(style), unit];
10785 });
10786 return val;
10787 }
10788 });
10789
10790
10791
10792 /******************************************************************************/
10793 /*********************************** EASING ***********************************/
10794 /******************************************************************************/
10795
10796 /*
10797 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
10798 *
10799 * Uses the built in easing capabilities added In jQuery 1.1
10800 * to offer multiple easing options
10801 *
10802 * TERMS OF USE - jQuery Easing
10803 *
10804 * Open source under the BSD License.
10805 *
10806 * Copyright 2008 George McGinley Smith
10807 * All rights reserved.
10808 *
10809 * Redistribution and use in source and binary forms, with or without modification,
10810 * are permitted provided that the following conditions are met:
10811 *
10812 * Redistributions of source code must retain the above copyright notice, this list of
10813 * conditions and the following disclaimer.
10814 * Redistributions in binary form must reproduce the above copyright notice, this list
10815 * of conditions and the following disclaimer in the documentation and/or other materials
10816 * provided with the distribution.
10817 *
10818 * Neither the name of the author nor the names of contributors may be used to endorse
10819 * or promote products derived from this software without specific prior written permission.
10820 *
10821 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10822 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10823 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10824 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10825 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10826 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10827 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10828 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10829 * OF THE POSSIBILITY OF SUCH DAMAGE.
10830 *
10831 */
10832
10833 // t: current time, b: begInnIng value, c: change In value, d: duration
10834 $.easing.jswing = $.easing.swing;
10835
10836 $.extend($.easing,
10837 {
10838 def: 'easeOutQuad',
10839 swing: function (x, t, b, c, d) {
10840 //alert($.easing.default);
10841 return $.easing[$.easing.def](x, t, b, c, d);
10842 },
10843 easeInQuad: function (x, t, b, c, d) {
10844 return c*(t/=d)*t + b;
10845 },
10846 easeOutQuad: function (x, t, b, c, d) {
10847 return -c *(t/=d)*(t-2) + b;
10848 },
10849 easeInOutQuad: function (x, t, b, c, d) {
10850 if ((t/=d/2) < 1) return c/2*t*t + b;
10851 return -c/2 * ((--t)*(t-2) - 1) + b;
10852 },
10853 easeInCubic: function (x, t, b, c, d) {
10854 return c*(t/=d)*t*t + b;
10855 },
10856 easeOutCubic: function (x, t, b, c, d) {
10857 return c*((t=t/d-1)*t*t + 1) + b;
10858 },
10859 easeInOutCubic: function (x, t, b, c, d) {
10860 if ((t/=d/2) < 1) return c/2*t*t*t + b;
10861 return c/2*((t-=2)*t*t + 2) + b;
10862 },
10863 easeInQuart: function (x, t, b, c, d) {
10864 return c*(t/=d)*t*t*t + b;
10865 },
10866 easeOutQuart: function (x, t, b, c, d) {
10867 return -c * ((t=t/d-1)*t*t*t - 1) + b;
10868 },
10869 easeInOutQuart: function (x, t, b, c, d) {
10870 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
10871 return -c/2 * ((t-=2)*t*t*t - 2) + b;
10872 },
10873 easeInQuint: function (x, t, b, c, d) {
10874 return c*(t/=d)*t*t*t*t + b;
10875 },
10876 easeOutQuint: function (x, t, b, c, d) {
10877 return c*((t=t/d-1)*t*t*t*t + 1) + b;
10878 },
10879 easeInOutQuint: function (x, t, b, c, d) {
10880 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
10881 return c/2*((t-=2)*t*t*t*t + 2) + b;
10882 },
10883 easeInSine: function (x, t, b, c, d) {
10884 return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
10885 },
10886 easeOutSine: function (x, t, b, c, d) {
10887 return c * Math.sin(t/d * (Math.PI/2)) + b;
10888 },
10889 easeInOutSine: function (x, t, b, c, d) {
10890 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
10891 },
10892 easeInExpo: function (x, t, b, c, d) {
10893 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
10894 },
10895 easeOutExpo: function (x, t, b, c, d) {
10896 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
10897 },
10898 easeInOutExpo: function (x, t, b, c, d) {
10899 if (t==0) return b;
10900 if (t==d) return b+c;
10901 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
10902 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
10903 },
10904 easeInCirc: function (x, t, b, c, d) {
10905 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
10906 },
10907 easeOutCirc: function (x, t, b, c, d) {
10908 return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
10909 },
10910 easeInOutCirc: function (x, t, b, c, d) {
10911 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
10912 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
10913 },
10914 easeInElastic: function (x, t, b, c, d) {
10915 var s=1.70158;var p=0;var a=c;
10916 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
10917 if (a < Math.abs(c)) { a=c; var s=p/4; }
10918 else var s = p/(2*Math.PI) * Math.asin (c/a);
10919 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
10920 },
10921 easeOutElastic: function (x, t, b, c, d) {
10922 var s=1.70158;var p=0;var a=c;
10923 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
10924 if (a < Math.abs(c)) { a=c; var s=p/4; }
10925 else var s = p/(2*Math.PI) * Math.asin (c/a);
10926 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
10927 },
10928 easeInOutElastic: function (x, t, b, c, d) {
10929 var s=1.70158;var p=0;var a=c;
10930 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
10931 if (a < Math.abs(c)) { a=c; var s=p/4; }
10932 else var s = p/(2*Math.PI) * Math.asin (c/a);
10933 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
10934 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
10935 },
10936 easeInBack: function (x, t, b, c, d, s) {
10937 if (s == undefined) s = 1.70158;
10938 return c*(t/=d)*t*((s+1)*t - s) + b;
10939 },
10940 easeOutBack: function (x, t, b, c, d, s) {
10941 if (s == undefined) s = 1.70158;
10942 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
10943 },
10944 easeInOutBack: function (x, t, b, c, d, s) {
10945 if (s == undefined) s = 1.70158;
10946 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
10947 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
10948 },
10949 easeInBounce: function (x, t, b, c, d) {
10950 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
10951 },
10952 easeOutBounce: function (x, t, b, c, d) {
10953 if ((t/=d) < (1/2.75)) {
10954 return c*(7.5625*t*t) + b;
10955 } else if (t < (2/2.75)) {
10956 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
10957 } else if (t < (2.5/2.75)) {
10958 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
10959 } else {
10960 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
10961 }
10962 },
10963 easeInOutBounce: function (x, t, b, c, d) {
10964 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
10965 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
10966 }
10967 });
10968
10969 /*
10970 *
10971 * TERMS OF USE - EASING EQUATIONS
10972 *
10973 * Open source under the BSD License.
10974 *
10975 * Copyright 2001 Robert Penner
10976 * All rights reserved.
10977 *
10978 * Redistribution and use in source and binary forms, with or without modification,
10979 * are permitted provided that the following conditions are met:
10980 *
10981 * Redistributions of source code must retain the above copyright notice, this list of
10982 * conditions and the following disclaimer.
10983 * Redistributions in binary form must reproduce the above copyright notice, this list
10984 * of conditions and the following disclaimer in the documentation and/or other materials
10985 * provided with the distribution.
10986 *
10987 * Neither the name of the author nor the names of contributors may be used to endorse
10988 * or promote products derived from this software without specific prior written permission.
10989 *
10990 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10991 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10992 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10993 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10994 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10995 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10996 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10997 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10998 * OF THE POSSIBILITY OF SUCH DAMAGE.
10999 *
11000 */
11001
11002 })(jQuery);
11003 /*!
11004 * jQuery UI Effects Blind 1.8.21
11005 *
11006 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11007 * Dual licensed under the MIT or GPL Version 2 licenses.
11008 * http://jquery.org/license
11009 *
11010 * http://docs.jquery.com/UI/Effects/Blind
11011 *
11012 * Depends:
11013 * jquery.effects.core.js
11014 */
11015 (function( $, undefined ) {
11016
11017 $.effects.blind = function(o) {
11018
11019 return this.queue(function() {
11020
11021 // Create element
11022 var el = $(this), props = ['position','top','bottom','left','right'];
11023
11024 // Set options
11025 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11026 var direction = o.options.direction || 'vertical'; // Default direction
11027
11028 // Adjust
11029 $.effects.save(el, props); el.show(); // Save & Show
11030 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11031 var ref = (direction == 'vertical') ? 'height' : 'width';
11032 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
11033 if(mode == 'show') wrapper.css(ref, 0); // Shift
11034
11035 // Animation
11036 var animation = {};
11037 animation[ref] = mode == 'show' ? distance : 0;
11038
11039 // Animate
11040 wrapper.animate(animation, o.duration, o.options.easing, function() {
11041 if(mode == 'hide') el.hide(); // Hide
11042 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11043 if(o.callback) o.callback.apply(el[0], arguments); // Callback
11044 el.dequeue();
11045 });
11046
11047 });
11048
11049 };
11050
11051 })(jQuery);
11052 /*!
11053 * jQuery UI Effects Bounce 1.8.21
11054 *
11055 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11056 * Dual licensed under the MIT or GPL Version 2 licenses.
11057 * http://jquery.org/license
11058 *
11059 * http://docs.jquery.com/UI/Effects/Bounce
11060 *
11061 * Depends:
11062 * jquery.effects.core.js
11063 */
11064 (function( $, undefined ) {
11065
11066 $.effects.bounce = function(o) {
11067
11068 return this.queue(function() {
11069
11070 // Create element
11071 var el = $(this), props = ['position','top','bottom','left','right'];
11072
11073 // Set options
11074 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11075 var direction = o.options.direction || 'up'; // Default direction
11076 var distance = o.options.distance || 20; // Default distance
11077 var times = o.options.times || 5; // Default # of times
11078 var speed = o.duration || 250; // Default speed per bounce
11079 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
11080
11081 // Adjust
11082 $.effects.save(el, props); el.show(); // Save & Show
11083 $.effects.createWrapper(el); // Create Wrapper
11084 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11085 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11086 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
11087 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
11088 if (mode == 'hide') distance = distance / (times * 2);
11089 if (mode != 'hide') times--;
11090
11091 // Animate
11092 if (mode == 'show') { // Show Bounce
11093 var animation = {opacity: 1};
11094 animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11095 el.animate(animation, speed / 2, o.options.easing);
11096 distance = distance / 2;
11097 times--;
11098 };
11099 for (var i = 0; i < times; i++) { // Bounces
11100 var animation1 = {}, animation2 = {};
11101 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11102 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11103 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
11104 distance = (mode == 'hide') ? distance * 2 : distance / 2;
11105 };
11106 if (mode == 'hide') { // Last Bounce
11107 var animation = {opacity: 0};
11108 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11109 el.animate(animation, speed / 2, o.options.easing, function(){
11110 el.hide(); // Hide
11111 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11112 if(o.callback) o.callback.apply(this, arguments); // Callback
11113 });
11114 } else {
11115 var animation1 = {}, animation2 = {};
11116 animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11117 animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
11118 el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
11119 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11120 if(o.callback) o.callback.apply(this, arguments); // Callback
11121 });
11122 };
11123 el.queue('fx', function() { el.dequeue(); });
11124 el.dequeue();
11125 });
11126
11127 };
11128
11129 })(jQuery);
11130 /*!
11131 * jQuery UI Effects Clip 1.8.21
11132 *
11133 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11134 * Dual licensed under the MIT or GPL Version 2 licenses.
11135 * http://jquery.org/license
11136 *
11137 * http://docs.jquery.com/UI/Effects/Clip
11138 *
11139 * Depends:
11140 * jquery.effects.core.js
11141 */
11142 (function( $, undefined ) {
11143
11144 $.effects.clip = function(o) {
11145
11146 return this.queue(function() {
11147
11148 // Create element
11149 var el = $(this), props = ['position','top','bottom','left','right','height','width'];
11150
11151 // Set options
11152 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11153 var direction = o.options.direction || 'vertical'; // Default direction
11154
11155 // Adjust
11156 $.effects.save(el, props); el.show(); // Save & Show
11157 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11158 var animate = el[0].tagName == 'IMG' ? wrapper : el;
11159 var ref = {
11160 size: (direction == 'vertical') ? 'height' : 'width',
11161 position: (direction == 'vertical') ? 'top' : 'left'
11162 };
11163 var distance = (direction == 'vertical') ? animate.height() : animate.width();
11164 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
11165
11166 // Animation
11167 var animation = {};
11168 animation[ref.size] = mode == 'show' ? distance : 0;
11169 animation[ref.position] = mode == 'show' ? 0 : distance / 2;
11170
11171 // Animate
11172 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11173 if(mode == 'hide') el.hide(); // Hide
11174 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11175 if(o.callback) o.callback.apply(el[0], arguments); // Callback
11176 el.dequeue();
11177 }});
11178
11179 });
11180
11181 };
11182
11183 })(jQuery);
11184 /*!
11185 * jQuery UI Effects Drop 1.8.21
11186 *
11187 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11188 * Dual licensed under the MIT or GPL Version 2 licenses.
11189 * http://jquery.org/license
11190 *
11191 * http://docs.jquery.com/UI/Effects/Drop
11192 *
11193 * Depends:
11194 * jquery.effects.core.js
11195 */
11196 (function( $, undefined ) {
11197
11198 $.effects.drop = function(o) {
11199
11200 return this.queue(function() {
11201
11202 // Create element
11203 var el = $(this), props = ['position','top','bottom','left','right','opacity'];
11204
11205 // Set options
11206 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11207 var direction = o.options.direction || 'left'; // Default Direction
11208
11209 // Adjust
11210 $.effects.save(el, props); el.show(); // Save & Show
11211 $.effects.createWrapper(el); // Create Wrapper
11212 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11213 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11214 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
11215 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
11216
11217 // Animation
11218 var animation = {opacity: mode == 'show' ? 1 : 0};
11219 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
11220
11221 // Animate
11222 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11223 if(mode == 'hide') el.hide(); // Hide
11224 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11225 if(o.callback) o.callback.apply(this, arguments); // Callback
11226 el.dequeue();
11227 }});
11228
11229 });
11230
11231 };
11232
11233 })(jQuery);
11234 /*!
11235 * jQuery UI Effects Explode 1.8.21
11236 *
11237 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11238 * Dual licensed under the MIT or GPL Version 2 licenses.
11239 * http://jquery.org/license
11240 *
11241 * http://docs.jquery.com/UI/Effects/Explode
11242 *
11243 * Depends:
11244 * jquery.effects.core.js
11245 */
11246 (function( $, undefined ) {
11247
11248 $.effects.explode = function(o) {
11249
11250 return this.queue(function() {
11251
11252 var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
11253 var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
11254
11255 o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
11256 var el = $(this).show().css('visibility', 'hidden');
11257 var offset = el.offset();
11258
11259 //Substract the margins - not fixing the problem yet.
11260 offset.top -= parseInt(el.css("marginTop"),10) || 0;
11261 offset.left -= parseInt(el.css("marginLeft"),10) || 0;
11262
11263 var width = el.outerWidth(true);
11264 var height = el.outerHeight(true);
11265
11266 for(var i=0;i<rows;i++) { // =
11267 for(var j=0;j<cells;j++) { // ||
11268 el
11269 .clone()
11270 .appendTo('body')
11271 .wrap('<div></div>')
11272 .css({
11273 position: 'absolute',
11274 visibility: 'visible',
11275 left: -j*(width/cells),
11276 top: -i*(height/rows)
11277 })
11278 .parent()
11279 .addClass('ui-effects-explode')
11280 .css({
11281 position: 'absolute',
11282 overflow: 'hidden',
11283 width: width/cells,
11284 height: height/rows,
11285 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
11286 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
11287 opacity: o.options.mode == 'show' ? 0 : 1
11288 }).animate({
11289 left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
11290 top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
11291 opacity: o.options.mode == 'show' ? 1 : 0
11292 }, o.duration || 500);
11293 }
11294 }
11295
11296 // Set a timeout, to call the callback approx. when the other animations have finished
11297 setTimeout(function() {
11298
11299 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
11300 if(o.callback) o.callback.apply(el[0]); // Callback
11301 el.dequeue();
11302
11303 $('div.ui-effects-explode').remove();
11304
11305 }, o.duration || 500);
11306
11307
11308 });
11309
11310 };
11311
11312 })(jQuery);
11313 /*!
11314 * jQuery UI Effects Fade 1.8.21
11315 *
11316 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11317 * Dual licensed under the MIT or GPL Version 2 licenses.
11318 * http://jquery.org/license
11319 *
11320 * http://docs.jquery.com/UI/Effects/Fade
11321 *
11322 * Depends:
11323 * jquery.effects.core.js
11324 */
11325 (function( $, undefined ) {
11326
11327 $.effects.fade = function(o) {
11328 return this.queue(function() {
11329 var elem = $(this),
11330 mode = $.effects.setMode(elem, o.options.mode || 'hide');
11331
11332 elem.animate({ opacity: mode }, {
11333 queue: false,
11334 duration: o.duration,
11335 easing: o.options.easing,
11336 complete: function() {
11337 (o.callback && o.callback.apply(this, arguments));
11338 elem.dequeue();
11339 }
11340 });
11341 });
11342 };
11343
11344 })(jQuery);
11345 /*!
11346 * jQuery UI Effects Fold 1.8.21
11347 *
11348 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11349 * Dual licensed under the MIT or GPL Version 2 licenses.
11350 * http://jquery.org/license
11351 *
11352 * http://docs.jquery.com/UI/Effects/Fold
11353 *
11354 * Depends:
11355 * jquery.effects.core.js
11356 */
11357 (function( $, undefined ) {
11358
11359 $.effects.fold = function(o) {
11360
11361 return this.queue(function() {
11362
11363 // Create element
11364 var el = $(this), props = ['position','top','bottom','left','right'];
11365
11366 // Set options
11367 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
11368 var size = o.options.size || 15; // Default fold size
11369 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
11370 var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
11371
11372 // Adjust
11373 $.effects.save(el, props); el.show(); // Save & Show
11374 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11375 var widthFirst = ((mode == 'show') != horizFirst);
11376 var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
11377 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
11378 var percent = /([0-9]+)%/.exec(size);
11379 if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
11380 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
11381
11382 // Animation
11383 var animation1 = {}, animation2 = {};
11384 animation1[ref[0]] = mode == 'show' ? distance[0] : size;
11385 animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
11386
11387 // Animate
11388 wrapper.animate(animation1, duration, o.options.easing)
11389 .animate(animation2, duration, o.options.easing, function() {
11390 if(mode == 'hide') el.hide(); // Hide
11391 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11392 if(o.callback) o.callback.apply(el[0], arguments); // Callback
11393 el.dequeue();
11394 });
11395
11396 });
11397
11398 };
11399
11400 })(jQuery);
11401 /*!
11402 * jQuery UI Effects Highlight 1.8.21
11403 *
11404 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11405 * Dual licensed under the MIT or GPL Version 2 licenses.
11406 * http://jquery.org/license
11407 *
11408 * http://docs.jquery.com/UI/Effects/Highlight
11409 *
11410 * Depends:
11411 * jquery.effects.core.js
11412 */
11413 (function( $, undefined ) {
11414
11415 $.effects.highlight = function(o) {
11416 return this.queue(function() {
11417 var elem = $(this),
11418 props = ['backgroundImage', 'backgroundColor', 'opacity'],
11419 mode = $.effects.setMode(elem, o.options.mode || 'show'),
11420 animation = {
11421 backgroundColor: elem.css('backgroundColor')
11422 };
11423
11424 if (mode == 'hide') {
11425 animation.opacity = 0;
11426 }
11427
11428 $.effects.save(elem, props);
11429 elem
11430 .show()
11431 .css({
11432 backgroundImage: 'none',
11433 backgroundColor: o.options.color || '#ffff99'
11434 })
11435 .animate(animation, {
11436 queue: false,
11437 duration: o.duration,
11438 easing: o.options.easing,
11439 complete: function() {
11440 (mode == 'hide' && elem.hide());
11441 $.effects.restore(elem, props);
11442 (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
11443 (o.callback && o.callback.apply(this, arguments));
11444 elem.dequeue();
11445 }
11446 });
11447 });
11448 };
11449
11450 })(jQuery);
11451 /*!
11452 * jQuery UI Effects Pulsate 1.8.21
11453 *
11454 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11455 * Dual licensed under the MIT or GPL Version 2 licenses.
11456 * http://jquery.org/license
11457 *
11458 * http://docs.jquery.com/UI/Effects/Pulsate
11459 *
11460 * Depends:
11461 * jquery.effects.core.js
11462 */
11463 (function( $, undefined ) {
11464
11465 $.effects.pulsate = function(o) {
11466 return this.queue(function() {
11467 var elem = $(this),
11468 mode = $.effects.setMode(elem, o.options.mode || 'show'),
11469 times = ((o.options.times || 5) * 2) - 1,
11470 duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
11471 isVisible = elem.is(':visible'),
11472 animateTo = 0;
11473
11474 if (!isVisible) {
11475 elem.css('opacity', 0).show();
11476 animateTo = 1;
11477 }
11478
11479 if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
11480 times--;
11481 }
11482
11483 for (var i = 0; i < times; i++) {
11484 elem.animate({ opacity: animateTo }, duration, o.options.easing);
11485 animateTo = (animateTo + 1) % 2;
11486 }
11487
11488 elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
11489 if (animateTo == 0) {
11490 elem.hide();
11491 }
11492 (o.callback && o.callback.apply(this, arguments));
11493 });
11494
11495 elem
11496 .queue('fx', function() { elem.dequeue(); })
11497 .dequeue();
11498 });
11499 };
11500
11501 })(jQuery);
11502 /*!
11503 * jQuery UI Effects Scale 1.8.21
11504 *
11505 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11506 * Dual licensed under the MIT or GPL Version 2 licenses.
11507 * http://jquery.org/license
11508 *
11509 * http://docs.jquery.com/UI/Effects/Scale
11510 *
11511 * Depends:
11512 * jquery.effects.core.js
11513 */
11514 (function( $, undefined ) {
11515
11516 $.effects.puff = function(o) {
11517 return this.queue(function() {
11518 var elem = $(this),
11519 mode = $.effects.setMode(elem, o.options.mode || 'hide'),
11520 percent = parseInt(o.options.percent, 10) || 150,
11521 factor = percent / 100,
11522 original = { height: elem.height(), width: elem.width() };
11523
11524 $.extend(o.options, {
11525 fade: true,
11526 mode: mode,
11527 percent: mode == 'hide' ? percent : 100,
11528 from: mode == 'hide'
11529 ? original
11530 : {
11531 height: original.height * factor,
11532 width: original.width * factor
11533 }
11534 });
11535
11536 elem.effect('scale', o.options, o.duration, o.callback);
11537 elem.dequeue();
11538 });
11539 };
11540
11541 $.effects.scale = function(o) {
11542
11543 return this.queue(function() {
11544
11545 // Create element
11546 var el = $(this);
11547
11548 // Set options
11549 var options = $.extend(true, {}, o.options);
11550 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11551 var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
11552 var direction = o.options.direction || 'both'; // Set default axis
11553 var origin = o.options.origin; // The origin of the scaling
11554 if (mode != 'effect') { // Set default origin and restore for show/hide
11555 options.origin = origin || ['middle','center'];
11556 options.restore = true;
11557 }
11558 var original = {height: el.height(), width: el.width()}; // Save original
11559 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
11560
11561 // Adjust
11562 var factor = { // Set scaling factor
11563 y: direction != 'horizontal' ? (percent / 100) : 1,
11564 x: direction != 'vertical' ? (percent / 100) : 1
11565 };
11566 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
11567
11568 if (o.options.fade) { // Fade option to support puff
11569 if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
11570 if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
11571 };
11572
11573 // Animation
11574 options.from = el.from; options.to = el.to; options.mode = mode;
11575
11576 // Animate
11577 el.effect('size', options, o.duration, o.callback);
11578 el.dequeue();
11579 });
11580
11581 };
11582
11583 $.effects.size = function(o) {
11584
11585 return this.queue(function() {
11586
11587 // Create element
11588 var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
11589 var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
11590 var props2 = ['width','height','overflow']; // Copy for children
11591 var cProps = ['fontSize'];
11592 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
11593 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
11594
11595 // Set options
11596 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11597 var restore = o.options.restore || false; // Default restore
11598 var scale = o.options.scale || 'both'; // Default scale mode
11599 var origin = o.options.origin; // The origin of the sizing
11600 var original = {height: el.height(), width: el.width()}; // Save original
11601 el.from = o.options.from || original; // Default from state
11602 el.to = o.options.to || original; // Default to state
11603 // Adjust
11604 if (origin) { // Calculate baseline shifts
11605 var baseline = $.effects.getBaseline(origin, original);
11606 el.from.top = (original.height - el.from.height) * baseline.y;
11607 el.from.left = (original.width - el.from.width) * baseline.x;
11608 el.to.top = (original.height - el.to.height) * baseline.y;
11609 el.to.left = (original.width - el.to.width) * baseline.x;
11610 };
11611 var factor = { // Set scaling factor
11612 from: {y: el.from.height / original.height, x: el.from.width / original.width},
11613 to: {y: el.to.height / original.height, x: el.to.width / original.width}
11614 };
11615 if (scale == 'box' || scale == 'both') { // Scale the css box
11616 if (factor.from.y != factor.to.y) { // Vertical props scaling
11617 props = props.concat(vProps);
11618 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
11619 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
11620 };
11621 if (factor.from.x != factor.to.x) { // Horizontal props scaling
11622 props = props.concat(hProps);
11623 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
11624 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
11625 };
11626 };
11627 if (scale == 'content' || scale == 'both') { // Scale the content
11628 if (factor.from.y != factor.to.y) { // Vertical props scaling
11629 props = props.concat(cProps);
11630 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
11631 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
11632 };
11633 };
11634 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
11635 $.effects.createWrapper(el); // Create Wrapper
11636 el.css('overflow','hidden').css(el.from); // Shift
11637
11638 // Animate
11639 if (scale == 'content' || scale == 'both') { // Scale the children
11640 vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
11641 hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
11642 props2 = props.concat(vProps).concat(hProps); // Concat
11643 el.find("*[width]").each(function(){
11644 var child = $(this);
11645 if (restore) $.effects.save(child, props2);
11646 var c_original = {height: child.height(), width: child.width()}; // Save original
11647 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
11648 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
11649 if (factor.from.y != factor.to.y) { // Vertical props scaling
11650 child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
11651 child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
11652 };
11653 if (factor.from.x != factor.to.x) { // Horizontal props scaling
11654 child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
11655 child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
11656 };
11657 child.css(child.from); // Shift children
11658 child.animate(child.to, o.duration, o.options.easing, function(){
11659 if (restore) $.effects.restore(child, props2); // Restore children
11660 }); // Animate children
11661 });
11662 };
11663
11664 // Animate
11665 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11666 if (el.to.opacity === 0) {
11667 el.css('opacity', el.from.opacity);
11668 }
11669 if(mode == 'hide') el.hide(); // Hide
11670 $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
11671 if(o.callback) o.callback.apply(this, arguments); // Callback
11672 el.dequeue();
11673 }});
11674
11675 });
11676
11677 };
11678
11679 })(jQuery);
11680 /*!
11681 * jQuery UI Effects Shake 1.8.21
11682 *
11683 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11684 * Dual licensed under the MIT or GPL Version 2 licenses.
11685 * http://jquery.org/license
11686 *
11687 * http://docs.jquery.com/UI/Effects/Shake
11688 *
11689 * Depends:
11690 * jquery.effects.core.js
11691 */
11692 (function( $, undefined ) {
11693
11694 $.effects.shake = function(o) {
11695
11696 return this.queue(function() {
11697
11698 // Create element
11699 var el = $(this), props = ['position','top','bottom','left','right'];
11700
11701 // Set options
11702 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
11703 var direction = o.options.direction || 'left'; // Default direction
11704 var distance = o.options.distance || 20; // Default distance
11705 var times = o.options.times || 3; // Default # of times
11706 var speed = o.duration || o.options.duration || 140; // Default speed per shake
11707
11708 // Adjust
11709 $.effects.save(el, props); el.show(); // Save & Show
11710 $.effects.createWrapper(el); // Create Wrapper
11711 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11712 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11713
11714 // Animation
11715 var animation = {}, animation1 = {}, animation2 = {};
11716 animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
11717 animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
11718 animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
11719
11720 // Animate
11721 el.animate(animation, speed, o.options.easing);
11722 for (var i = 1; i < times; i++) { // Shakes
11723 el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
11724 };
11725 el.animate(animation1, speed, o.options.easing).
11726 animate(animation, speed / 2, o.options.easing, function(){ // Last shake
11727 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11728 if(o.callback) o.callback.apply(this, arguments); // Callback
11729 });
11730 el.queue('fx', function() { el.dequeue(); });
11731 el.dequeue();
11732 });
11733
11734 };
11735
11736 })(jQuery);
11737 /*!
11738 * jQuery UI Effects Slide 1.8.21
11739 *
11740 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11741 * Dual licensed under the MIT or GPL Version 2 licenses.
11742 * http://jquery.org/license
11743 *
11744 * http://docs.jquery.com/UI/Effects/Slide
11745 *
11746 * Depends:
11747 * jquery.effects.core.js
11748 */
11749 (function( $, undefined ) {
11750
11751 $.effects.slide = function(o) {
11752
11753 return this.queue(function() {
11754
11755 // Create element
11756 var el = $(this), props = ['position','top','bottom','left','right'];
11757
11758 // Set options
11759 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
11760 var direction = o.options.direction || 'left'; // Default Direction
11761
11762 // Adjust
11763 $.effects.save(el, props); el.show(); // Save & Show
11764 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
11765 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
11766 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
11767 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
11768 if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
11769
11770 // Animation
11771 var animation = {};
11772 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
11773
11774 // Animate
11775 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
11776 if(mode == 'hide') el.hide(); // Hide
11777 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
11778 if(o.callback) o.callback.apply(this, arguments); // Callback
11779 el.dequeue();
11780 }});
11781
11782 });
11783
11784 };
11785
11786 })(jQuery);
11787 /*!
11788 * jQuery UI Effects Transfer 1.8.21
11789 *
11790 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11791 * Dual licensed under the MIT or GPL Version 2 licenses.
11792 * http://jquery.org/license
11793 *
11794 * http://docs.jquery.com/UI/Effects/Transfer
11795 *
11796 * Depends:
11797 * jquery.effects.core.js
11798 */
11799 (function( $, undefined ) {
11800
11801 $.effects.transfer = function(o) {
11802 return this.queue(function() {
11803 var elem = $(this),
11804 target = $(o.options.to),
11805 endPosition = target.offset(),
11806 animation = {
11807 top: endPosition.top,
11808 left: endPosition.left,
11809 height: target.innerHeight(),
11810 width: target.innerWidth()
11811 },
11812 startPosition = elem.offset(),
11813 transfer = $('<div class="ui-effects-transfer"></div>')
11814 .appendTo(document.body)
11815 .addClass(o.options.className)
11816 .css({
11817 top: startPosition.top,
11818 left: startPosition.left,
11819 height: elem.innerHeight(),
11820 width: elem.innerWidth(),
11821 position: 'absolute'
11822 })
11823 .animate(animation, o.duration, o.options.easing, function() {
11824 transfer.remove();
11825 (o.callback && o.callback.apply(elem[0], arguments));
11826 elem.dequeue();
11827 });
11828 });
11829 };
11830
11831 })(jQuery);