/[projects]/misc/horsensspejder-web/jquery/jquery-ui-1.10.3/ui/jquery-ui.js
ViewVC logotype

Annotation of /misc/horsensspejder-web/jquery/jquery-ui-1.10.3/ui/jquery-ui.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2125 - (hide annotations) (download) (as text)
Wed Mar 12 19:30:05 2014 UTC (10 years, 4 months ago) by torben
File MIME type: application/javascript
File size: 435844 byte(s)
initial import
1 torben 2125 /*! jQuery UI - v1.10.3 - 2013-05-03
2     * http://jqueryui.com
3     * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
4     * Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
5     (function( $, undefined ) {
6    
7     var uuid = 0,
8     runiqueId = /^ui-id-\d+$/;
9    
10     // $.ui might exist from components with no dependencies, e.g., $.ui.position
11     $.ui = $.ui || {};
12    
13     $.extend( $.ui, {
14     version: "1.10.3",
15    
16     keyCode: {
17     BACKSPACE: 8,
18     COMMA: 188,
19     DELETE: 46,
20     DOWN: 40,
21     END: 35,
22     ENTER: 13,
23     ESCAPE: 27,
24     HOME: 36,
25     LEFT: 37,
26     NUMPAD_ADD: 107,
27     NUMPAD_DECIMAL: 110,
28     NUMPAD_DIVIDE: 111,
29     NUMPAD_ENTER: 108,
30     NUMPAD_MULTIPLY: 106,
31     NUMPAD_SUBTRACT: 109,
32     PAGE_DOWN: 34,
33     PAGE_UP: 33,
34     PERIOD: 190,
35     RIGHT: 39,
36     SPACE: 32,
37     TAB: 9,
38     UP: 38
39     }
40     });
41    
42     // plugins
43     $.fn.extend({
44     focus: (function( orig ) {
45     return function( delay, fn ) {
46     return typeof delay === "number" ?
47     this.each(function() {
48     var elem = this;
49     setTimeout(function() {
50     $( elem ).focus();
51     if ( fn ) {
52     fn.call( elem );
53     }
54     }, delay );
55     }) :
56     orig.apply( this, arguments );
57     };
58     })( $.fn.focus ),
59    
60     scrollParent: function() {
61     var scrollParent;
62     if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
63     scrollParent = this.parents().filter(function() {
64     return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
65     }).eq(0);
66     } else {
67     scrollParent = this.parents().filter(function() {
68     return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
69     }).eq(0);
70     }
71    
72     return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
73     },
74    
75     zIndex: function( zIndex ) {
76     if ( zIndex !== undefined ) {
77     return this.css( "zIndex", zIndex );
78     }
79    
80     if ( this.length ) {
81     var elem = $( this[ 0 ] ), position, value;
82     while ( elem.length && elem[ 0 ] !== document ) {
83     // Ignore z-index if position is set to a value where z-index is ignored by the browser
84     // This makes behavior of this function consistent across browsers
85     // WebKit always returns auto if the element is positioned
86     position = elem.css( "position" );
87     if ( position === "absolute" || position === "relative" || position === "fixed" ) {
88     // IE returns 0 when zIndex is not specified
89     // other browsers return a string
90     // we ignore the case of nested elements with an explicit value of 0
91     // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
92     value = parseInt( elem.css( "zIndex" ), 10 );
93     if ( !isNaN( value ) && value !== 0 ) {
94     return value;
95     }
96     }
97     elem = elem.parent();
98     }
99     }
100    
101     return 0;
102     },
103    
104     uniqueId: function() {
105     return this.each(function() {
106     if ( !this.id ) {
107     this.id = "ui-id-" + (++uuid);
108     }
109     });
110     },
111    
112     removeUniqueId: function() {
113     return this.each(function() {
114     if ( runiqueId.test( this.id ) ) {
115     $( this ).removeAttr( "id" );
116     }
117     });
118     }
119     });
120    
121     // selectors
122     function focusable( element, isTabIndexNotNaN ) {
123     var map, mapName, img,
124     nodeName = element.nodeName.toLowerCase();
125     if ( "area" === nodeName ) {
126     map = element.parentNode;
127     mapName = map.name;
128     if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
129     return false;
130     }
131     img = $( "img[usemap=#" + mapName + "]" )[0];
132     return !!img && visible( img );
133     }
134     return ( /input|select|textarea|button|object/.test( nodeName ) ?
135     !element.disabled :
136     "a" === nodeName ?
137     element.href || isTabIndexNotNaN :
138     isTabIndexNotNaN) &&
139     // the element and all of its ancestors must be visible
140     visible( element );
141     }
142    
143     function visible( element ) {
144     return $.expr.filters.visible( element ) &&
145     !$( element ).parents().addBack().filter(function() {
146     return $.css( this, "visibility" ) === "hidden";
147     }).length;
148     }
149    
150     $.extend( $.expr[ ":" ], {
151     data: $.expr.createPseudo ?
152     $.expr.createPseudo(function( dataName ) {
153     return function( elem ) {
154     return !!$.data( elem, dataName );
155     };
156     }) :
157     // support: jQuery <1.8
158     function( elem, i, match ) {
159     return !!$.data( elem, match[ 3 ] );
160     },
161    
162     focusable: function( element ) {
163     return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
164     },
165    
166     tabbable: function( element ) {
167     var tabIndex = $.attr( element, "tabindex" ),
168     isTabIndexNaN = isNaN( tabIndex );
169     return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
170     }
171     });
172    
173     // support: jQuery <1.8
174     if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
175     $.each( [ "Width", "Height" ], function( i, name ) {
176     var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
177     type = name.toLowerCase(),
178     orig = {
179     innerWidth: $.fn.innerWidth,
180     innerHeight: $.fn.innerHeight,
181     outerWidth: $.fn.outerWidth,
182     outerHeight: $.fn.outerHeight
183     };
184    
185     function reduce( elem, size, border, margin ) {
186     $.each( side, function() {
187     size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
188     if ( border ) {
189     size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
190     }
191     if ( margin ) {
192     size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
193     }
194     });
195     return size;
196     }
197    
198     $.fn[ "inner" + name ] = function( size ) {
199     if ( size === undefined ) {
200     return orig[ "inner" + name ].call( this );
201     }
202    
203     return this.each(function() {
204     $( this ).css( type, reduce( this, size ) + "px" );
205     });
206     };
207    
208     $.fn[ "outer" + name] = function( size, margin ) {
209     if ( typeof size !== "number" ) {
210     return orig[ "outer" + name ].call( this, size );
211     }
212    
213     return this.each(function() {
214     $( this).css( type, reduce( this, size, true, margin ) + "px" );
215     });
216     };
217     });
218     }
219    
220     // support: jQuery <1.8
221     if ( !$.fn.addBack ) {
222     $.fn.addBack = function( selector ) {
223     return this.add( selector == null ?
224     this.prevObject : this.prevObject.filter( selector )
225     );
226     };
227     }
228    
229     // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
230     if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
231     $.fn.removeData = (function( removeData ) {
232     return function( key ) {
233     if ( arguments.length ) {
234     return removeData.call( this, $.camelCase( key ) );
235     } else {
236     return removeData.call( this );
237     }
238     };
239     })( $.fn.removeData );
240     }
241    
242    
243    
244    
245    
246     // deprecated
247     $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
248    
249     $.support.selectstart = "onselectstart" in document.createElement( "div" );
250     $.fn.extend({
251     disableSelection: function() {
252     return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
253     ".ui-disableSelection", function( event ) {
254     event.preventDefault();
255     });
256     },
257    
258     enableSelection: function() {
259     return this.unbind( ".ui-disableSelection" );
260     }
261     });
262    
263     $.extend( $.ui, {
264     // $.ui.plugin is deprecated. Use $.widget() extensions instead.
265     plugin: {
266     add: function( module, option, set ) {
267     var i,
268     proto = $.ui[ module ].prototype;
269     for ( i in set ) {
270     proto.plugins[ i ] = proto.plugins[ i ] || [];
271     proto.plugins[ i ].push( [ option, set[ i ] ] );
272     }
273     },
274     call: function( instance, name, args ) {
275     var i,
276     set = instance.plugins[ name ];
277     if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
278     return;
279     }
280    
281     for ( i = 0; i < set.length; i++ ) {
282     if ( instance.options[ set[ i ][ 0 ] ] ) {
283     set[ i ][ 1 ].apply( instance.element, args );
284     }
285     }
286     }
287     },
288    
289     // only used by resizable
290     hasScroll: function( el, a ) {
291    
292     //If overflow is hidden, the element might have extra content, but the user wants to hide it
293     if ( $( el ).css( "overflow" ) === "hidden") {
294     return false;
295     }
296    
297     var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
298     has = false;
299    
300     if ( el[ scroll ] > 0 ) {
301     return true;
302     }
303    
304     // TODO: determine which cases actually cause this to happen
305     // if the element doesn't have the scroll set, see if it's possible to
306     // set the scroll
307     el[ scroll ] = 1;
308     has = ( el[ scroll ] > 0 );
309     el[ scroll ] = 0;
310     return has;
311     }
312     });
313    
314     })( jQuery );
315    
316     (function( $, undefined ) {
317    
318     var uuid = 0,
319     slice = Array.prototype.slice,
320     _cleanData = $.cleanData;
321     $.cleanData = function( elems ) {
322     for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323     try {
324     $( elem ).triggerHandler( "remove" );
325     // http://bugs.jquery.com/ticket/8235
326     } catch( e ) {}
327     }
328     _cleanData( elems );
329     };
330    
331     $.widget = function( name, base, prototype ) {
332     var fullName, existingConstructor, constructor, basePrototype,
333     // proxiedPrototype allows the provided prototype to remain unmodified
334     // so that it can be used as a mixin for multiple widgets (#8876)
335     proxiedPrototype = {},
336     namespace = name.split( "." )[ 0 ];
337    
338     name = name.split( "." )[ 1 ];
339     fullName = namespace + "-" + name;
340    
341     if ( !prototype ) {
342     prototype = base;
343     base = $.Widget;
344     }
345    
346     // create selector for plugin
347     $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348     return !!$.data( elem, fullName );
349     };
350    
351     $[ namespace ] = $[ namespace ] || {};
352     existingConstructor = $[ namespace ][ name ];
353     constructor = $[ namespace ][ name ] = function( options, element ) {
354     // allow instantiation without "new" keyword
355     if ( !this._createWidget ) {
356     return new constructor( options, element );
357     }
358    
359     // allow instantiation without initializing for simple inheritance
360     // must use "new" keyword (the code above always passes args)
361     if ( arguments.length ) {
362     this._createWidget( options, element );
363     }
364     };
365     // extend with the existing constructor to carry over any static properties
366     $.extend( constructor, existingConstructor, {
367     version: prototype.version,
368     // copy the object used to create the prototype in case we need to
369     // redefine the widget later
370     _proto: $.extend( {}, prototype ),
371     // track widgets that inherit from this widget in case this widget is
372     // redefined after a widget inherits from it
373     _childConstructors: []
374     });
375    
376     basePrototype = new base();
377     // we need to make the options hash a property directly on the new instance
378     // otherwise we'll modify the options hash on the prototype that we're
379     // inheriting from
380     basePrototype.options = $.widget.extend( {}, basePrototype.options );
381     $.each( prototype, function( prop, value ) {
382     if ( !$.isFunction( value ) ) {
383     proxiedPrototype[ prop ] = value;
384     return;
385     }
386     proxiedPrototype[ prop ] = (function() {
387     var _super = function() {
388     return base.prototype[ prop ].apply( this, arguments );
389     },
390     _superApply = function( args ) {
391     return base.prototype[ prop ].apply( this, args );
392     };
393     return function() {
394     var __super = this._super,
395     __superApply = this._superApply,
396     returnValue;
397    
398     this._super = _super;
399     this._superApply = _superApply;
400    
401     returnValue = value.apply( this, arguments );
402    
403     this._super = __super;
404     this._superApply = __superApply;
405    
406     return returnValue;
407     };
408     })();
409     });
410     constructor.prototype = $.widget.extend( basePrototype, {
411     // TODO: remove support for widgetEventPrefix
412     // always use the name + a colon as the prefix, e.g., draggable:start
413     // don't prefix for widgets that aren't DOM-based
414     widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
415     }, proxiedPrototype, {
416     constructor: constructor,
417     namespace: namespace,
418     widgetName: name,
419     widgetFullName: fullName
420     });
421    
422     // If this widget is being redefined then we need to find all widgets that
423     // are inheriting from it and redefine all of them so that they inherit from
424     // the new version of this widget. We're essentially trying to replace one
425     // level in the prototype chain.
426     if ( existingConstructor ) {
427     $.each( existingConstructor._childConstructors, function( i, child ) {
428     var childPrototype = child.prototype;
429    
430     // redefine the child widget using the same prototype that was
431     // originally used, but inherit from the new version of the base
432     $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433     });
434     // remove the list of existing child constructors from the old constructor
435     // so the old child constructors can be garbage collected
436     delete existingConstructor._childConstructors;
437     } else {
438     base._childConstructors.push( constructor );
439     }
440    
441     $.widget.bridge( name, constructor );
442     };
443    
444     $.widget.extend = function( target ) {
445     var input = slice.call( arguments, 1 ),
446     inputIndex = 0,
447     inputLength = input.length,
448     key,
449     value;
450     for ( ; inputIndex < inputLength; inputIndex++ ) {
451     for ( key in input[ inputIndex ] ) {
452     value = input[ inputIndex ][ key ];
453     if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454     // Clone objects
455     if ( $.isPlainObject( value ) ) {
456     target[ key ] = $.isPlainObject( target[ key ] ) ?
457     $.widget.extend( {}, target[ key ], value ) :
458     // Don't extend strings, arrays, etc. with objects
459     $.widget.extend( {}, value );
460     // Copy everything else by reference
461     } else {
462     target[ key ] = value;
463     }
464     }
465     }
466     }
467     return target;
468     };
469    
470     $.widget.bridge = function( name, object ) {
471     var fullName = object.prototype.widgetFullName || name;
472     $.fn[ name ] = function( options ) {
473     var isMethodCall = typeof options === "string",
474     args = slice.call( arguments, 1 ),
475     returnValue = this;
476    
477     // allow multiple hashes to be passed on init
478     options = !isMethodCall && args.length ?
479     $.widget.extend.apply( null, [ options ].concat(args) ) :
480     options;
481    
482     if ( isMethodCall ) {
483     this.each(function() {
484     var methodValue,
485     instance = $.data( this, fullName );
486     if ( !instance ) {
487     return $.error( "cannot call methods on " + name + " prior to initialization; " +
488     "attempted to call method '" + options + "'" );
489     }
490     if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491     return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492     }
493     methodValue = instance[ options ].apply( instance, args );
494     if ( methodValue !== instance && methodValue !== undefined ) {
495     returnValue = methodValue && methodValue.jquery ?
496     returnValue.pushStack( methodValue.get() ) :
497     methodValue;
498     return false;
499     }
500     });
501     } else {
502     this.each(function() {
503     var instance = $.data( this, fullName );
504     if ( instance ) {
505     instance.option( options || {} )._init();
506     } else {
507     $.data( this, fullName, new object( options, this ) );
508     }
509     });
510     }
511    
512     return returnValue;
513     };
514     };
515    
516     $.Widget = function( /* options, element */ ) {};
517     $.Widget._childConstructors = [];
518    
519     $.Widget.prototype = {
520     widgetName: "widget",
521     widgetEventPrefix: "",
522     defaultElement: "<div>",
523     options: {
524     disabled: false,
525    
526     // callbacks
527     create: null
528     },
529     _createWidget: function( options, element ) {
530     element = $( element || this.defaultElement || this )[ 0 ];
531     this.element = $( element );
532     this.uuid = uuid++;
533     this.eventNamespace = "." + this.widgetName + this.uuid;
534     this.options = $.widget.extend( {},
535     this.options,
536     this._getCreateOptions(),
537     options );
538    
539     this.bindings = $();
540     this.hoverable = $();
541     this.focusable = $();
542    
543     if ( element !== this ) {
544     $.data( element, this.widgetFullName, this );
545     this._on( true, this.element, {
546     remove: function( event ) {
547     if ( event.target === element ) {
548     this.destroy();
549     }
550     }
551     });
552     this.document = $( element.style ?
553     // element within the document
554     element.ownerDocument :
555     // element is window or document
556     element.document || element );
557     this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558     }
559    
560     this._create();
561     this._trigger( "create", null, this._getCreateEventData() );
562     this._init();
563     },
564     _getCreateOptions: $.noop,
565     _getCreateEventData: $.noop,
566     _create: $.noop,
567     _init: $.noop,
568    
569     destroy: function() {
570     this._destroy();
571     // we can probably remove the unbind calls in 2.0
572     // all event bindings should go through this._on()
573     this.element
574     .unbind( this.eventNamespace )
575     // 1.9 BC for #7810
576     // TODO remove dual storage
577     .removeData( this.widgetName )
578     .removeData( this.widgetFullName )
579     // support: jquery <1.6.3
580     // http://bugs.jquery.com/ticket/9413
581     .removeData( $.camelCase( this.widgetFullName ) );
582     this.widget()
583     .unbind( this.eventNamespace )
584     .removeAttr( "aria-disabled" )
585     .removeClass(
586     this.widgetFullName + "-disabled " +
587     "ui-state-disabled" );
588    
589     // clean up events and states
590     this.bindings.unbind( this.eventNamespace );
591     this.hoverable.removeClass( "ui-state-hover" );
592     this.focusable.removeClass( "ui-state-focus" );
593     },
594     _destroy: $.noop,
595    
596     widget: function() {
597     return this.element;
598     },
599    
600     option: function( key, value ) {
601     var options = key,
602     parts,
603     curOption,
604     i;
605    
606     if ( arguments.length === 0 ) {
607     // don't return a reference to the internal hash
608     return $.widget.extend( {}, this.options );
609     }
610    
611     if ( typeof key === "string" ) {
612     // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613     options = {};
614     parts = key.split( "." );
615     key = parts.shift();
616     if ( parts.length ) {
617     curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618     for ( i = 0; i < parts.length - 1; i++ ) {
619     curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620     curOption = curOption[ parts[ i ] ];
621     }
622     key = parts.pop();
623     if ( value === undefined ) {
624     return curOption[ key ] === undefined ? null : curOption[ key ];
625     }
626     curOption[ key ] = value;
627     } else {
628     if ( value === undefined ) {
629     return this.options[ key ] === undefined ? null : this.options[ key ];
630     }
631     options[ key ] = value;
632     }
633     }
634    
635     this._setOptions( options );
636    
637     return this;
638     },
639     _setOptions: function( options ) {
640     var key;
641    
642     for ( key in options ) {
643     this._setOption( key, options[ key ] );
644     }
645    
646     return this;
647     },
648     _setOption: function( key, value ) {
649     this.options[ key ] = value;
650    
651     if ( key === "disabled" ) {
652     this.widget()
653     .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654     .attr( "aria-disabled", value );
655     this.hoverable.removeClass( "ui-state-hover" );
656     this.focusable.removeClass( "ui-state-focus" );
657     }
658    
659     return this;
660     },
661    
662     enable: function() {
663     return this._setOption( "disabled", false );
664     },
665     disable: function() {
666     return this._setOption( "disabled", true );
667     },
668    
669     _on: function( suppressDisabledCheck, element, handlers ) {
670     var delegateElement,
671     instance = this;
672    
673     // no suppressDisabledCheck flag, shuffle arguments
674     if ( typeof suppressDisabledCheck !== "boolean" ) {
675     handlers = element;
676     element = suppressDisabledCheck;
677     suppressDisabledCheck = false;
678     }
679    
680     // no element argument, shuffle and use this.element
681     if ( !handlers ) {
682     handlers = element;
683     element = this.element;
684     delegateElement = this.widget();
685     } else {
686     // accept selectors, DOM elements
687     element = delegateElement = $( element );
688     this.bindings = this.bindings.add( element );
689     }
690    
691     $.each( handlers, function( event, handler ) {
692     function handlerProxy() {
693     // allow widgets to customize the disabled handling
694     // - disabled as an array instead of boolean
695     // - disabled class as method for disabling individual parts
696     if ( !suppressDisabledCheck &&
697     ( instance.options.disabled === true ||
698     $( this ).hasClass( "ui-state-disabled" ) ) ) {
699     return;
700     }
701     return ( typeof handler === "string" ? instance[ handler ] : handler )
702     .apply( instance, arguments );
703     }
704    
705     // copy the guid so direct unbinding works
706     if ( typeof handler !== "string" ) {
707     handlerProxy.guid = handler.guid =
708     handler.guid || handlerProxy.guid || $.guid++;
709     }
710    
711     var match = event.match( /^(\w+)\s*(.*)$/ ),
712     eventName = match[1] + instance.eventNamespace,
713     selector = match[2];
714     if ( selector ) {
715     delegateElement.delegate( selector, eventName, handlerProxy );
716     } else {
717     element.bind( eventName, handlerProxy );
718     }
719     });
720     },
721    
722     _off: function( element, eventName ) {
723     eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724     element.unbind( eventName ).undelegate( eventName );
725     },
726    
727     _delay: function( handler, delay ) {
728     function handlerProxy() {
729     return ( typeof handler === "string" ? instance[ handler ] : handler )
730     .apply( instance, arguments );
731     }
732     var instance = this;
733     return setTimeout( handlerProxy, delay || 0 );
734     },
735    
736     _hoverable: function( element ) {
737     this.hoverable = this.hoverable.add( element );
738     this._on( element, {
739     mouseenter: function( event ) {
740     $( event.currentTarget ).addClass( "ui-state-hover" );
741     },
742     mouseleave: function( event ) {
743     $( event.currentTarget ).removeClass( "ui-state-hover" );
744     }
745     });
746     },
747    
748     _focusable: function( element ) {
749     this.focusable = this.focusable.add( element );
750     this._on( element, {
751     focusin: function( event ) {
752     $( event.currentTarget ).addClass( "ui-state-focus" );
753     },
754     focusout: function( event ) {
755     $( event.currentTarget ).removeClass( "ui-state-focus" );
756     }
757     });
758     },
759    
760     _trigger: function( type, event, data ) {
761     var prop, orig,
762     callback = this.options[ type ];
763    
764     data = data || {};
765     event = $.Event( event );
766     event.type = ( type === this.widgetEventPrefix ?
767     type :
768     this.widgetEventPrefix + type ).toLowerCase();
769     // the original event may come from any element
770     // so we need to reset the target on the new event
771     event.target = this.element[ 0 ];
772    
773     // copy original event properties over to the new event
774     orig = event.originalEvent;
775     if ( orig ) {
776     for ( prop in orig ) {
777     if ( !( prop in event ) ) {
778     event[ prop ] = orig[ prop ];
779     }
780     }
781     }
782    
783     this.element.trigger( event, data );
784     return !( $.isFunction( callback ) &&
785     callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786     event.isDefaultPrevented() );
787     }
788     };
789    
790     $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791     $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792     if ( typeof options === "string" ) {
793     options = { effect: options };
794     }
795     var hasOptions,
796     effectName = !options ?
797     method :
798     options === true || typeof options === "number" ?
799     defaultEffect :
800     options.effect || defaultEffect;
801     options = options || {};
802     if ( typeof options === "number" ) {
803     options = { duration: options };
804     }
805     hasOptions = !$.isEmptyObject( options );
806     options.complete = callback;
807     if ( options.delay ) {
808     element.delay( options.delay );
809     }
810     if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811     element[ method ]( options );
812     } else if ( effectName !== method && element[ effectName ] ) {
813     element[ effectName ]( options.duration, options.easing, callback );
814     } else {
815     element.queue(function( next ) {
816     $( this )[ method ]();
817     if ( callback ) {
818     callback.call( element[ 0 ] );
819     }
820     next();
821     });
822     }
823     };
824     });
825    
826     })( jQuery );
827    
828     (function( $, undefined ) {
829    
830     var mouseHandled = false;
831     $( document ).mouseup( function() {
832     mouseHandled = false;
833     });
834    
835     $.widget("ui.mouse", {
836     version: "1.10.3",
837     options: {
838     cancel: "input,textarea,button,select,option",
839     distance: 1,
840     delay: 0
841     },
842     _mouseInit: function() {
843     var that = this;
844    
845     this.element
846     .bind("mousedown."+this.widgetName, function(event) {
847     return that._mouseDown(event);
848     })
849     .bind("click."+this.widgetName, function(event) {
850     if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
851     $.removeData(event.target, that.widgetName + ".preventClickEvent");
852     event.stopImmediatePropagation();
853     return false;
854     }
855     });
856    
857     this.started = false;
858     },
859    
860     // TODO: make sure destroying one instance of mouse doesn't mess with
861     // other instances of mouse
862     _mouseDestroy: function() {
863     this.element.unbind("."+this.widgetName);
864     if ( this._mouseMoveDelegate ) {
865     $(document)
866     .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
867     .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
868     }
869     },
870    
871     _mouseDown: function(event) {
872     // don't let more than one widget handle mouseStart
873     if( mouseHandled ) { return; }
874    
875     // we may have missed mouseup (out of window)
876     (this._mouseStarted && this._mouseUp(event));
877    
878     this._mouseDownEvent = event;
879    
880     var that = this,
881     btnIsLeft = (event.which === 1),
882     // event.target.nodeName works around a bug in IE 8 with
883     // disabled inputs (#7620)
884     elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
885     if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
886     return true;
887     }
888    
889     this.mouseDelayMet = !this.options.delay;
890     if (!this.mouseDelayMet) {
891     this._mouseDelayTimer = setTimeout(function() {
892     that.mouseDelayMet = true;
893     }, this.options.delay);
894     }
895    
896     if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
897     this._mouseStarted = (this._mouseStart(event) !== false);
898     if (!this._mouseStarted) {
899     event.preventDefault();
900     return true;
901     }
902     }
903    
904     // Click event may never have fired (Gecko & Opera)
905     if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
906     $.removeData(event.target, this.widgetName + ".preventClickEvent");
907     }
908    
909     // these delegates are required to keep context
910     this._mouseMoveDelegate = function(event) {
911     return that._mouseMove(event);
912     };
913     this._mouseUpDelegate = function(event) {
914     return that._mouseUp(event);
915     };
916     $(document)
917     .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
918     .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
919    
920     event.preventDefault();
921    
922     mouseHandled = true;
923     return true;
924     },
925    
926     _mouseMove: function(event) {
927     // IE mouseup check - mouseup happened when mouse was out of window
928     if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
929     return this._mouseUp(event);
930     }
931    
932     if (this._mouseStarted) {
933     this._mouseDrag(event);
934     return event.preventDefault();
935     }
936    
937     if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
938     this._mouseStarted =
939     (this._mouseStart(this._mouseDownEvent, event) !== false);
940     (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
941     }
942    
943     return !this._mouseStarted;
944     },
945    
946     _mouseUp: function(event) {
947     $(document)
948     .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
949     .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
950    
951     if (this._mouseStarted) {
952     this._mouseStarted = false;
953    
954     if (event.target === this._mouseDownEvent.target) {
955     $.data(event.target, this.widgetName + ".preventClickEvent", true);
956     }
957    
958     this._mouseStop(event);
959     }
960    
961     return false;
962     },
963    
964     _mouseDistanceMet: function(event) {
965     return (Math.max(
966     Math.abs(this._mouseDownEvent.pageX - event.pageX),
967     Math.abs(this._mouseDownEvent.pageY - event.pageY)
968     ) >= this.options.distance
969     );
970     },
971    
972     _mouseDelayMet: function(/* event */) {
973     return this.mouseDelayMet;
974     },
975    
976     // These are placeholder methods, to be overriden by extending plugin
977     _mouseStart: function(/* event */) {},
978     _mouseDrag: function(/* event */) {},
979     _mouseStop: function(/* event */) {},
980     _mouseCapture: function(/* event */) { return true; }
981     });
982    
983     })(jQuery);
984    
985     (function( $, undefined ) {
986    
987     $.widget("ui.draggable", $.ui.mouse, {
988     version: "1.10.3",
989     widgetEventPrefix: "drag",
990     options: {
991     addClasses: true,
992     appendTo: "parent",
993     axis: false,
994     connectToSortable: false,
995     containment: false,
996     cursor: "auto",
997     cursorAt: false,
998     grid: false,
999     handle: false,
1000     helper: "original",
1001     iframeFix: false,
1002     opacity: false,
1003     refreshPositions: false,
1004     revert: false,
1005     revertDuration: 500,
1006     scope: "default",
1007     scroll: true,
1008     scrollSensitivity: 20,
1009     scrollSpeed: 20,
1010     snap: false,
1011     snapMode: "both",
1012     snapTolerance: 20,
1013     stack: false,
1014     zIndex: false,
1015    
1016     // callbacks
1017     drag: null,
1018     start: null,
1019     stop: null
1020     },
1021     _create: function() {
1022    
1023     if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1024     this.element[0].style.position = "relative";
1025     }
1026     if (this.options.addClasses){
1027     this.element.addClass("ui-draggable");
1028     }
1029     if (this.options.disabled){
1030     this.element.addClass("ui-draggable-disabled");
1031     }
1032    
1033     this._mouseInit();
1034    
1035     },
1036    
1037     _destroy: function() {
1038     this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1039     this._mouseDestroy();
1040     },
1041    
1042     _mouseCapture: function(event) {
1043    
1044     var o = this.options;
1045    
1046     // among others, prevent a drag on a resizable-handle
1047     if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1048     return false;
1049     }
1050    
1051     //Quit if we're not on a valid handle
1052     this.handle = this._getHandle(event);
1053     if (!this.handle) {
1054     return false;
1055     }
1056    
1057     $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1058     $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1059     .css({
1060     width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1061     position: "absolute", opacity: "0.001", zIndex: 1000
1062     })
1063     .css($(this).offset())
1064     .appendTo("body");
1065     });
1066    
1067     return true;
1068    
1069     },
1070    
1071     _mouseStart: function(event) {
1072    
1073     var o = this.options;
1074    
1075     //Create and append the visible helper
1076     this.helper = this._createHelper(event);
1077    
1078     this.helper.addClass("ui-draggable-dragging");
1079    
1080     //Cache the helper size
1081     this._cacheHelperProportions();
1082    
1083     //If ddmanager is used for droppables, set the global draggable
1084     if($.ui.ddmanager) {
1085     $.ui.ddmanager.current = this;
1086     }
1087    
1088     /*
1089     * - Position generation -
1090     * This block generates everything position related - it's the core of draggables.
1091     */
1092    
1093     //Cache the margins of the original element
1094     this._cacheMargins();
1095    
1096     //Store the helper's css position
1097     this.cssPosition = this.helper.css( "position" );
1098     this.scrollParent = this.helper.scrollParent();
1099     this.offsetParent = this.helper.offsetParent();
1100     this.offsetParentCssPosition = this.offsetParent.css( "position" );
1101    
1102     //The element's absolute position on the page minus margins
1103     this.offset = this.positionAbs = this.element.offset();
1104     this.offset = {
1105     top: this.offset.top - this.margins.top,
1106     left: this.offset.left - this.margins.left
1107     };
1108    
1109     //Reset scroll cache
1110     this.offset.scroll = false;
1111    
1112     $.extend(this.offset, {
1113     click: { //Where the click happened, relative to the element
1114     left: event.pageX - this.offset.left,
1115     top: event.pageY - this.offset.top
1116     },
1117     parent: this._getParentOffset(),
1118     relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1119     });
1120    
1121     //Generate the original position
1122     this.originalPosition = this.position = this._generatePosition(event);
1123     this.originalPageX = event.pageX;
1124     this.originalPageY = event.pageY;
1125    
1126     //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1127     (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1128    
1129     //Set a containment if given in the options
1130     this._setContainment();
1131    
1132     //Trigger event + callbacks
1133     if(this._trigger("start", event) === false) {
1134     this._clear();
1135     return false;
1136     }
1137    
1138     //Recache the helper size
1139     this._cacheHelperProportions();
1140    
1141     //Prepare the droppable offsets
1142     if ($.ui.ddmanager && !o.dropBehaviour) {
1143     $.ui.ddmanager.prepareOffsets(this, event);
1144     }
1145    
1146    
1147     this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1148    
1149     //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1150     if ( $.ui.ddmanager ) {
1151     $.ui.ddmanager.dragStart(this, event);
1152     }
1153    
1154     return true;
1155     },
1156    
1157     _mouseDrag: function(event, noPropagation) {
1158     // reset any necessary cached properties (see #5009)
1159     if ( this.offsetParentCssPosition === "fixed" ) {
1160     this.offset.parent = this._getParentOffset();
1161     }
1162    
1163     //Compute the helpers position
1164     this.position = this._generatePosition(event);
1165     this.positionAbs = this._convertPositionTo("absolute");
1166    
1167     //Call plugins and callbacks and use the resulting position if something is returned
1168     if (!noPropagation) {
1169     var ui = this._uiHash();
1170     if(this._trigger("drag", event, ui) === false) {
1171     this._mouseUp({});
1172     return false;
1173     }
1174     this.position = ui.position;
1175     }
1176    
1177     if(!this.options.axis || this.options.axis !== "y") {
1178     this.helper[0].style.left = this.position.left+"px";
1179     }
1180     if(!this.options.axis || this.options.axis !== "x") {
1181     this.helper[0].style.top = this.position.top+"px";
1182     }
1183     if($.ui.ddmanager) {
1184     $.ui.ddmanager.drag(this, event);
1185     }
1186    
1187     return false;
1188     },
1189    
1190     _mouseStop: function(event) {
1191    
1192     //If we are using droppables, inform the manager about the drop
1193     var that = this,
1194     dropped = false;
1195     if ($.ui.ddmanager && !this.options.dropBehaviour) {
1196     dropped = $.ui.ddmanager.drop(this, event);
1197     }
1198    
1199     //if a drop comes from outside (a sortable)
1200     if(this.dropped) {
1201     dropped = this.dropped;
1202     this.dropped = false;
1203     }
1204    
1205     //if the original element is no longer in the DOM don't bother to continue (see #8269)
1206     if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1207     return false;
1208     }
1209    
1210     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))) {
1211     $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1212     if(that._trigger("stop", event) !== false) {
1213     that._clear();
1214     }
1215     });
1216     } else {
1217     if(this._trigger("stop", event) !== false) {
1218     this._clear();
1219     }
1220     }
1221    
1222     return false;
1223     },
1224    
1225     _mouseUp: function(event) {
1226     //Remove frame helpers
1227     $("div.ui-draggable-iframeFix").each(function() {
1228     this.parentNode.removeChild(this);
1229     });
1230    
1231     //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1232     if( $.ui.ddmanager ) {
1233     $.ui.ddmanager.dragStop(this, event);
1234     }
1235    
1236     return $.ui.mouse.prototype._mouseUp.call(this, event);
1237     },
1238    
1239     cancel: function() {
1240    
1241     if(this.helper.is(".ui-draggable-dragging")) {
1242     this._mouseUp({});
1243     } else {
1244     this._clear();
1245     }
1246    
1247     return this;
1248    
1249     },
1250    
1251     _getHandle: function(event) {
1252     return this.options.handle ?
1253     !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1254     true;
1255     },
1256    
1257     _createHelper: function(event) {
1258    
1259     var o = this.options,
1260     helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1261    
1262     if(!helper.parents("body").length) {
1263     helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1264     }
1265    
1266     if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1267     helper.css("position", "absolute");
1268     }
1269    
1270     return helper;
1271    
1272     },
1273    
1274     _adjustOffsetFromHelper: function(obj) {
1275     if (typeof obj === "string") {
1276     obj = obj.split(" ");
1277     }
1278     if ($.isArray(obj)) {
1279     obj = {left: +obj[0], top: +obj[1] || 0};
1280     }
1281     if ("left" in obj) {
1282     this.offset.click.left = obj.left + this.margins.left;
1283     }
1284     if ("right" in obj) {
1285     this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1286     }
1287     if ("top" in obj) {
1288     this.offset.click.top = obj.top + this.margins.top;
1289     }
1290     if ("bottom" in obj) {
1291     this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1292     }
1293     },
1294    
1295     _getParentOffset: function() {
1296    
1297     //Get the offsetParent and cache its position
1298     var po = this.offsetParent.offset();
1299    
1300     // This is a special case where we need to modify a offset calculated on start, since the following happened:
1301     // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1302     // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1303     // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1304     if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1305     po.left += this.scrollParent.scrollLeft();
1306     po.top += this.scrollParent.scrollTop();
1307     }
1308    
1309     //This needs to be actually done for all browsers, since pageX/pageY includes this information
1310     //Ugly IE fix
1311     if((this.offsetParent[0] === document.body) ||
1312     (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1313     po = { top: 0, left: 0 };
1314     }
1315    
1316     return {
1317     top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1318     left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1319     };
1320    
1321     },
1322    
1323     _getRelativeOffset: function() {
1324    
1325     if(this.cssPosition === "relative") {
1326     var p = this.element.position();
1327     return {
1328     top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1329     left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1330     };
1331     } else {
1332     return { top: 0, left: 0 };
1333     }
1334    
1335     },
1336    
1337     _cacheMargins: function() {
1338     this.margins = {
1339     left: (parseInt(this.element.css("marginLeft"),10) || 0),
1340     top: (parseInt(this.element.css("marginTop"),10) || 0),
1341     right: (parseInt(this.element.css("marginRight"),10) || 0),
1342     bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1343     };
1344     },
1345    
1346     _cacheHelperProportions: function() {
1347     this.helperProportions = {
1348     width: this.helper.outerWidth(),
1349     height: this.helper.outerHeight()
1350     };
1351     },
1352    
1353     _setContainment: function() {
1354    
1355     var over, c, ce,
1356     o = this.options;
1357    
1358     if ( !o.containment ) {
1359     this.containment = null;
1360     return;
1361     }
1362    
1363     if ( o.containment === "window" ) {
1364     this.containment = [
1365     $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1366     $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1367     $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1368     $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1369     ];
1370     return;
1371     }
1372    
1373     if ( o.containment === "document") {
1374     this.containment = [
1375     0,
1376     0,
1377     $( document ).width() - this.helperProportions.width - this.margins.left,
1378     ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1379     ];
1380     return;
1381     }
1382    
1383     if ( o.containment.constructor === Array ) {
1384     this.containment = o.containment;
1385     return;
1386     }
1387    
1388     if ( o.containment === "parent" ) {
1389     o.containment = this.helper[ 0 ].parentNode;
1390     }
1391    
1392     c = $( o.containment );
1393     ce = c[ 0 ];
1394    
1395     if( !ce ) {
1396     return;
1397     }
1398    
1399     over = c.css( "overflow" ) !== "hidden";
1400    
1401     this.containment = [
1402     ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1403     ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1404     ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
1405     ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom
1406     ];
1407     this.relative_container = c;
1408     },
1409    
1410     _convertPositionTo: function(d, pos) {
1411    
1412     if(!pos) {
1413     pos = this.position;
1414     }
1415    
1416     var mod = d === "absolute" ? 1 : -1,
1417     scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1418    
1419     //Cache the scroll
1420     if (!this.offset.scroll) {
1421     this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1422     }
1423    
1424     return {
1425     top: (
1426     pos.top + // The absolute mouse position
1427     this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1428     this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
1429     ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1430     ),
1431     left: (
1432     pos.left + // The absolute mouse position
1433     this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1434     this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
1435     ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1436     )
1437     };
1438    
1439     },
1440    
1441     _generatePosition: function(event) {
1442    
1443     var containment, co, top, left,
1444     o = this.options,
1445     scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1446     pageX = event.pageX,
1447     pageY = event.pageY;
1448    
1449     //Cache the scroll
1450     if (!this.offset.scroll) {
1451     this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1452     }
1453    
1454     /*
1455     * - Position constraining -
1456     * Constrain the position to a mix of grid, containment.
1457     */
1458    
1459     // If we are not dragging yet, we won't check for options
1460     if ( this.originalPosition ) {
1461     if ( this.containment ) {
1462     if ( this.relative_container ){
1463     co = this.relative_container.offset();
1464     containment = [
1465     this.containment[ 0 ] + co.left,
1466     this.containment[ 1 ] + co.top,
1467     this.containment[ 2 ] + co.left,
1468     this.containment[ 3 ] + co.top
1469     ];
1470     }
1471     else {
1472     containment = this.containment;
1473     }
1474    
1475     if(event.pageX - this.offset.click.left < containment[0]) {
1476     pageX = containment[0] + this.offset.click.left;
1477     }
1478     if(event.pageY - this.offset.click.top < containment[1]) {
1479     pageY = containment[1] + this.offset.click.top;
1480     }
1481     if(event.pageX - this.offset.click.left > containment[2]) {
1482     pageX = containment[2] + this.offset.click.left;
1483     }
1484     if(event.pageY - this.offset.click.top > containment[3]) {
1485     pageY = containment[3] + this.offset.click.top;
1486     }
1487     }
1488    
1489     if(o.grid) {
1490     //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1491     top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1492     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;
1493    
1494     left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1495     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;
1496     }
1497    
1498     }
1499    
1500     return {
1501     top: (
1502     pageY - // The absolute mouse position
1503     this.offset.click.top - // Click offset (relative to the element)
1504     this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
1505     this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
1506     ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1507     ),
1508     left: (
1509     pageX - // The absolute mouse position
1510     this.offset.click.left - // Click offset (relative to the element)
1511     this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
1512     this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
1513     ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
1514     )
1515     };
1516    
1517     },
1518    
1519     _clear: function() {
1520     this.helper.removeClass("ui-draggable-dragging");
1521     if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1522     this.helper.remove();
1523     }
1524     this.helper = null;
1525     this.cancelHelperRemoval = false;
1526     },
1527    
1528     // From now on bulk stuff - mainly helpers
1529    
1530     _trigger: function(type, event, ui) {
1531     ui = ui || this._uiHash();
1532     $.ui.plugin.call(this, type, [event, ui]);
1533     //The absolute position has to be recalculated after plugins
1534     if(type === "drag") {
1535     this.positionAbs = this._convertPositionTo("absolute");
1536     }
1537     return $.Widget.prototype._trigger.call(this, type, event, ui);
1538     },
1539    
1540     plugins: {},
1541    
1542     _uiHash: function() {
1543     return {
1544     helper: this.helper,
1545     position: this.position,
1546     originalPosition: this.originalPosition,
1547     offset: this.positionAbs
1548     };
1549     }
1550    
1551     });
1552    
1553     $.ui.plugin.add("draggable", "connectToSortable", {
1554     start: function(event, ui) {
1555    
1556     var inst = $(this).data("ui-draggable"), o = inst.options,
1557     uiSortable = $.extend({}, ui, { item: inst.element });
1558     inst.sortables = [];
1559     $(o.connectToSortable).each(function() {
1560     var sortable = $.data(this, "ui-sortable");
1561     if (sortable && !sortable.options.disabled) {
1562     inst.sortables.push({
1563     instance: sortable,
1564     shouldRevert: sortable.options.revert
1565     });
1566     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).
1567     sortable._trigger("activate", event, uiSortable);
1568     }
1569     });
1570    
1571     },
1572     stop: function(event, ui) {
1573    
1574     //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1575     var inst = $(this).data("ui-draggable"),
1576     uiSortable = $.extend({}, ui, { item: inst.element });
1577    
1578     $.each(inst.sortables, function() {
1579     if(this.instance.isOver) {
1580    
1581     this.instance.isOver = 0;
1582    
1583     inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1584     this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1585    
1586     //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1587     if(this.shouldRevert) {
1588     this.instance.options.revert = this.shouldRevert;
1589     }
1590    
1591     //Trigger the stop of the sortable
1592     this.instance._mouseStop(event);
1593    
1594     this.instance.options.helper = this.instance.options._helper;
1595    
1596     //If the helper has been the original item, restore properties in the sortable
1597     if(inst.options.helper === "original") {
1598     this.instance.currentItem.css({ top: "auto", left: "auto" });
1599     }
1600    
1601     } else {
1602     this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1603     this.instance._trigger("deactivate", event, uiSortable);
1604     }
1605    
1606     });
1607    
1608     },
1609     drag: function(event, ui) {
1610    
1611     var inst = $(this).data("ui-draggable"), that = this;
1612    
1613     $.each(inst.sortables, function() {
1614    
1615     var innermostIntersecting = false,
1616     thisSortable = this;
1617    
1618     //Copy over some variables to allow calling the sortable's native _intersectsWith
1619     this.instance.positionAbs = inst.positionAbs;
1620     this.instance.helperProportions = inst.helperProportions;
1621     this.instance.offset.click = inst.offset.click;
1622    
1623     if(this.instance._intersectsWith(this.instance.containerCache)) {
1624     innermostIntersecting = true;
1625     $.each(inst.sortables, function () {
1626     this.instance.positionAbs = inst.positionAbs;
1627     this.instance.helperProportions = inst.helperProportions;
1628     this.instance.offset.click = inst.offset.click;
1629     if (this !== thisSortable &&
1630     this.instance._intersectsWith(this.instance.containerCache) &&
1631     $.contains(thisSortable.instance.element[0], this.instance.element[0])
1632     ) {
1633     innermostIntersecting = false;
1634     }
1635     return innermostIntersecting;
1636     });
1637     }
1638    
1639    
1640     if(innermostIntersecting) {
1641     //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1642     if(!this.instance.isOver) {
1643    
1644     this.instance.isOver = 1;
1645     //Now we fake the start of dragging for the sortable instance,
1646     //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1647     //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)
1648     this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1649     this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1650     this.instance.options.helper = function() { return ui.helper[0]; };
1651    
1652     event.target = this.instance.currentItem[0];
1653     this.instance._mouseCapture(event, true);
1654     this.instance._mouseStart(event, true, true);
1655    
1656     //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1657     this.instance.offset.click.top = inst.offset.click.top;
1658     this.instance.offset.click.left = inst.offset.click.left;
1659     this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1660     this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1661    
1662     inst._trigger("toSortable", event);
1663     inst.dropped = this.instance.element; //draggable revert needs that
1664     //hack so receive/update callbacks work (mostly)
1665     inst.currentItem = inst.element;
1666     this.instance.fromOutside = inst;
1667    
1668     }
1669    
1670     //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
1671     if(this.instance.currentItem) {
1672     this.instance._mouseDrag(event);
1673     }
1674    
1675     } else {
1676    
1677     //If it doesn't intersect with the sortable, and it intersected before,
1678     //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1679     if(this.instance.isOver) {
1680    
1681     this.instance.isOver = 0;
1682     this.instance.cancelHelperRemoval = true;
1683    
1684     //Prevent reverting on this forced stop
1685     this.instance.options.revert = false;
1686    
1687     // The out event needs to be triggered independently
1688     this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1689    
1690     this.instance._mouseStop(event, true);
1691     this.instance.options.helper = this.instance.options._helper;
1692    
1693     //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1694     this.instance.currentItem.remove();
1695     if(this.instance.placeholder) {
1696     this.instance.placeholder.remove();
1697     }
1698    
1699     inst._trigger("fromSortable", event);
1700     inst.dropped = false; //draggable revert needs that
1701     }
1702    
1703     }
1704    
1705     });
1706    
1707     }
1708     });
1709    
1710     $.ui.plugin.add("draggable", "cursor", {
1711     start: function() {
1712     var t = $("body"), o = $(this).data("ui-draggable").options;
1713     if (t.css("cursor")) {
1714     o._cursor = t.css("cursor");
1715     }
1716     t.css("cursor", o.cursor);
1717     },
1718     stop: function() {
1719     var o = $(this).data("ui-draggable").options;
1720     if (o._cursor) {
1721     $("body").css("cursor", o._cursor);
1722     }
1723     }
1724     });
1725    
1726     $.ui.plugin.add("draggable", "opacity", {
1727     start: function(event, ui) {
1728     var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1729     if(t.css("opacity")) {
1730     o._opacity = t.css("opacity");
1731     }
1732     t.css("opacity", o.opacity);
1733     },
1734     stop: function(event, ui) {
1735     var o = $(this).data("ui-draggable").options;
1736     if(o._opacity) {
1737     $(ui.helper).css("opacity", o._opacity);
1738     }
1739     }
1740     });
1741    
1742     $.ui.plugin.add("draggable", "scroll", {
1743     start: function() {
1744     var i = $(this).data("ui-draggable");
1745     if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1746     i.overflowOffset = i.scrollParent.offset();
1747     }
1748     },
1749     drag: function( event ) {
1750    
1751     var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1752    
1753     if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1754    
1755     if(!o.axis || o.axis !== "x") {
1756     if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1757     i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1758     } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1759     i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1760     }
1761     }
1762    
1763     if(!o.axis || o.axis !== "y") {
1764     if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1765     i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1766     } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1767     i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1768     }
1769     }
1770    
1771     } else {
1772    
1773     if(!o.axis || o.axis !== "x") {
1774     if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1775     scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1776     } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1777     scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1778     }
1779     }
1780    
1781     if(!o.axis || o.axis !== "y") {
1782     if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1783     scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1784     } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1785     scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1786     }
1787     }
1788    
1789     }
1790    
1791     if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1792     $.ui.ddmanager.prepareOffsets(i, event);
1793     }
1794    
1795     }
1796     });
1797    
1798     $.ui.plugin.add("draggable", "snap", {
1799     start: function() {
1800    
1801     var i = $(this).data("ui-draggable"),
1802     o = i.options;
1803    
1804     i.snapElements = [];
1805    
1806     $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1807     var $t = $(this),
1808     $o = $t.offset();
1809     if(this !== i.element[0]) {
1810     i.snapElements.push({
1811     item: this,
1812     width: $t.outerWidth(), height: $t.outerHeight(),
1813     top: $o.top, left: $o.left
1814     });
1815     }
1816     });
1817    
1818     },
1819     drag: function(event, ui) {
1820    
1821     var ts, bs, ls, rs, l, r, t, b, i, first,
1822     inst = $(this).data("ui-draggable"),
1823     o = inst.options,
1824     d = o.snapTolerance,
1825     x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1826     y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1827    
1828     for (i = inst.snapElements.length - 1; i >= 0; i--){
1829    
1830     l = inst.snapElements[i].left;
1831     r = l + inst.snapElements[i].width;
1832     t = inst.snapElements[i].top;
1833     b = t + inst.snapElements[i].height;
1834    
1835     if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
1836     if(inst.snapElements[i].snapping) {
1837     (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1838     }
1839     inst.snapElements[i].snapping = false;
1840     continue;
1841     }
1842    
1843     if(o.snapMode !== "inner") {
1844     ts = Math.abs(t - y2) <= d;
1845     bs = Math.abs(b - y1) <= d;
1846     ls = Math.abs(l - x2) <= d;
1847     rs = Math.abs(r - x1) <= d;
1848     if(ts) {
1849     ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1850     }
1851     if(bs) {
1852     ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1853     }
1854     if(ls) {
1855     ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1856     }
1857     if(rs) {
1858     ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1859     }
1860     }
1861    
1862     first = (ts || bs || ls || rs);
1863    
1864     if(o.snapMode !== "outer") {
1865     ts = Math.abs(t - y1) <= d;
1866     bs = Math.abs(b - y2) <= d;
1867     ls = Math.abs(l - x1) <= d;
1868     rs = Math.abs(r - x2) <= d;
1869     if(ts) {
1870     ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1871     }
1872     if(bs) {
1873     ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1874     }
1875     if(ls) {
1876     ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1877     }
1878     if(rs) {
1879     ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1880     }
1881     }
1882    
1883     if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1884     (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1885     }
1886     inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1887    
1888     }
1889    
1890     }
1891     });
1892    
1893     $.ui.plugin.add("draggable", "stack", {
1894     start: function() {
1895     var min,
1896     o = this.data("ui-draggable").options,
1897     group = $.makeArray($(o.stack)).sort(function(a,b) {
1898     return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1899     });
1900    
1901     if (!group.length) { return; }
1902    
1903     min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1904     $(group).each(function(i) {
1905     $(this).css("zIndex", min + i);
1906     });
1907     this.css("zIndex", (min + group.length));
1908     }
1909     });
1910    
1911     $.ui.plugin.add("draggable", "zIndex", {
1912     start: function(event, ui) {
1913     var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1914     if(t.css("zIndex")) {
1915     o._zIndex = t.css("zIndex");
1916     }
1917     t.css("zIndex", o.zIndex);
1918     },
1919     stop: function(event, ui) {
1920     var o = $(this).data("ui-draggable").options;
1921     if(o._zIndex) {
1922     $(ui.helper).css("zIndex", o._zIndex);
1923     }
1924     }
1925     });
1926    
1927     })(jQuery);
1928    
1929     (function( $, undefined ) {
1930    
1931     function isOverAxis( x, reference, size ) {
1932     return ( x > reference ) && ( x < ( reference + size ) );
1933     }
1934    
1935     $.widget("ui.droppable", {
1936     version: "1.10.3",
1937     widgetEventPrefix: "drop",
1938     options: {
1939     accept: "*",
1940     activeClass: false,
1941     addClasses: true,
1942     greedy: false,
1943     hoverClass: false,
1944     scope: "default",
1945     tolerance: "intersect",
1946    
1947     // callbacks
1948     activate: null,
1949     deactivate: null,
1950     drop: null,
1951     out: null,
1952     over: null
1953     },
1954     _create: function() {
1955    
1956     var o = this.options,
1957     accept = o.accept;
1958    
1959     this.isover = false;
1960     this.isout = true;
1961    
1962     this.accept = $.isFunction(accept) ? accept : function(d) {
1963     return d.is(accept);
1964     };
1965    
1966     //Store the droppable's proportions
1967     this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1968    
1969     // Add the reference and positions to the manager
1970     $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1971     $.ui.ddmanager.droppables[o.scope].push(this);
1972    
1973     (o.addClasses && this.element.addClass("ui-droppable"));
1974    
1975     },
1976    
1977     _destroy: function() {
1978     var i = 0,
1979     drop = $.ui.ddmanager.droppables[this.options.scope];
1980    
1981     for ( ; i < drop.length; i++ ) {
1982     if ( drop[i] === this ) {
1983     drop.splice(i, 1);
1984     }
1985     }
1986    
1987     this.element.removeClass("ui-droppable ui-droppable-disabled");
1988     },
1989    
1990     _setOption: function(key, value) {
1991    
1992     if(key === "accept") {
1993     this.accept = $.isFunction(value) ? value : function(d) {
1994     return d.is(value);
1995     };
1996     }
1997     $.Widget.prototype._setOption.apply(this, arguments);
1998     },
1999    
2000     _activate: function(event) {
2001     var draggable = $.ui.ddmanager.current;
2002     if(this.options.activeClass) {
2003     this.element.addClass(this.options.activeClass);
2004     }
2005     if(draggable){
2006     this._trigger("activate", event, this.ui(draggable));
2007     }
2008     },
2009    
2010     _deactivate: function(event) {
2011     var draggable = $.ui.ddmanager.current;
2012     if(this.options.activeClass) {
2013     this.element.removeClass(this.options.activeClass);
2014     }
2015     if(draggable){
2016     this._trigger("deactivate", event, this.ui(draggable));
2017     }
2018     },
2019    
2020     _over: function(event) {
2021    
2022     var draggable = $.ui.ddmanager.current;
2023    
2024     // Bail if draggable and droppable are same element
2025     if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2026     return;
2027     }
2028    
2029     if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2030     if(this.options.hoverClass) {
2031     this.element.addClass(this.options.hoverClass);
2032     }
2033     this._trigger("over", event, this.ui(draggable));
2034     }
2035    
2036     },
2037    
2038     _out: function(event) {
2039    
2040     var draggable = $.ui.ddmanager.current;
2041    
2042     // Bail if draggable and droppable are same element
2043     if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2044     return;
2045     }
2046    
2047     if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2048     if(this.options.hoverClass) {
2049     this.element.removeClass(this.options.hoverClass);
2050     }
2051     this._trigger("out", event, this.ui(draggable));
2052     }
2053    
2054     },
2055    
2056     _drop: function(event,custom) {
2057    
2058     var draggable = custom || $.ui.ddmanager.current,
2059     childrenIntersection = false;
2060    
2061     // Bail if draggable and droppable are same element
2062     if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2063     return false;
2064     }
2065    
2066     this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2067     var inst = $.data(this, "ui-droppable");
2068     if(
2069     inst.options.greedy &&
2070     !inst.options.disabled &&
2071     inst.options.scope === draggable.options.scope &&
2072     inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2073     $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2074     ) { childrenIntersection = true; return false; }
2075     });
2076     if(childrenIntersection) {
2077     return false;
2078     }
2079    
2080     if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2081     if(this.options.activeClass) {
2082     this.element.removeClass(this.options.activeClass);
2083     }
2084     if(this.options.hoverClass) {
2085     this.element.removeClass(this.options.hoverClass);
2086     }
2087     this._trigger("drop", event, this.ui(draggable));
2088     return this.element;
2089     }
2090    
2091     return false;
2092    
2093     },
2094    
2095     ui: function(c) {
2096     return {
2097     draggable: (c.currentItem || c.element),
2098     helper: c.helper,
2099     position: c.position,
2100     offset: c.positionAbs
2101     };
2102     }
2103    
2104     });
2105    
2106     $.ui.intersect = function(draggable, droppable, toleranceMode) {
2107    
2108     if (!droppable.offset) {
2109     return false;
2110     }
2111    
2112     var draggableLeft, draggableTop,
2113     x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2114     y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
2115     l = droppable.offset.left, r = l + droppable.proportions.width,
2116     t = droppable.offset.top, b = t + droppable.proportions.height;
2117    
2118     switch (toleranceMode) {
2119     case "fit":
2120     return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2121     case "intersect":
2122     return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2123     x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2124     t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2125     y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2126     case "pointer":
2127     draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2128     draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2129     return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
2130     case "touch":
2131     return (
2132     (y1 >= t && y1 <= b) || // Top edge touching
2133     (y2 >= t && y2 <= b) || // Bottom edge touching
2134     (y1 < t && y2 > b) // Surrounded vertically
2135     ) && (
2136     (x1 >= l && x1 <= r) || // Left edge touching
2137     (x2 >= l && x2 <= r) || // Right edge touching
2138     (x1 < l && x2 > r) // Surrounded horizontally
2139     );
2140     default:
2141     return false;
2142     }
2143    
2144     };
2145    
2146     /*
2147     This manager tracks offsets of draggables and droppables
2148     */
2149     $.ui.ddmanager = {
2150     current: null,
2151     droppables: { "default": [] },
2152     prepareOffsets: function(t, event) {
2153    
2154     var i, j,
2155     m = $.ui.ddmanager.droppables[t.options.scope] || [],
2156     type = event ? event.type : null, // workaround for #2317
2157     list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2158    
2159     droppablesLoop: for (i = 0; i < m.length; i++) {
2160    
2161     //No disabled and non-accepted
2162     if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2163     continue;
2164     }
2165    
2166     // Filter out elements in the current dragged item
2167     for (j=0; j < list.length; j++) {
2168     if(list[j] === m[i].element[0]) {
2169     m[i].proportions.height = 0;
2170     continue droppablesLoop;
2171     }
2172     }
2173    
2174     m[i].visible = m[i].element.css("display") !== "none";
2175     if(!m[i].visible) {
2176     continue;
2177     }
2178    
2179     //Activate the droppable if used directly from draggables
2180     if(type === "mousedown") {
2181     m[i]._activate.call(m[i], event);
2182     }
2183    
2184     m[i].offset = m[i].element.offset();
2185     m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2186    
2187     }
2188    
2189     },
2190     drop: function(draggable, event) {
2191    
2192     var dropped = false;
2193     // Create a copy of the droppables in case the list changes during the drop (#9116)
2194     $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2195    
2196     if(!this.options) {
2197     return;
2198     }
2199     if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2200     dropped = this._drop.call(this, event) || dropped;
2201     }
2202    
2203     if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2204     this.isout = true;
2205     this.isover = false;
2206     this._deactivate.call(this, event);
2207     }
2208    
2209     });
2210     return dropped;
2211    
2212     },
2213     dragStart: function( draggable, event ) {
2214     //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2215     draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2216     if( !draggable.options.refreshPositions ) {
2217     $.ui.ddmanager.prepareOffsets( draggable, event );
2218     }
2219     });
2220     },
2221     drag: function(draggable, event) {
2222    
2223     //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2224     if(draggable.options.refreshPositions) {
2225     $.ui.ddmanager.prepareOffsets(draggable, event);
2226     }
2227    
2228     //Run through all droppables and check their positions based on specific tolerance options
2229     $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2230    
2231     if(this.options.disabled || this.greedyChild || !this.visible) {
2232     return;
2233     }
2234    
2235     var parentInstance, scope, parent,
2236     intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2237     c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2238     if(!c) {
2239     return;
2240     }
2241    
2242     if (this.options.greedy) {
2243     // find droppable parents with same scope
2244     scope = this.options.scope;
2245     parent = this.element.parents(":data(ui-droppable)").filter(function () {
2246     return $.data(this, "ui-droppable").options.scope === scope;
2247     });
2248    
2249     if (parent.length) {
2250     parentInstance = $.data(parent[0], "ui-droppable");
2251     parentInstance.greedyChild = (c === "isover");
2252     }
2253     }
2254    
2255     // we just moved into a greedy child
2256     if (parentInstance && c === "isover") {
2257     parentInstance.isover = false;
2258     parentInstance.isout = true;
2259     parentInstance._out.call(parentInstance, event);
2260     }
2261    
2262     this[c] = true;
2263     this[c === "isout" ? "isover" : "isout"] = false;
2264     this[c === "isover" ? "_over" : "_out"].call(this, event);
2265    
2266     // we just moved out of a greedy child
2267     if (parentInstance && c === "isout") {
2268     parentInstance.isout = false;
2269     parentInstance.isover = true;
2270     parentInstance._over.call(parentInstance, event);
2271     }
2272     });
2273    
2274     },
2275     dragStop: function( draggable, event ) {
2276     draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2277     //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2278     if( !draggable.options.refreshPositions ) {
2279     $.ui.ddmanager.prepareOffsets( draggable, event );
2280     }
2281     }
2282     };
2283    
2284     })(jQuery);
2285    
2286     (function( $, undefined ) {
2287    
2288     function num(v) {
2289     return parseInt(v, 10) || 0;
2290     }
2291    
2292     function isNumber(value) {
2293     return !isNaN(parseInt(value, 10));
2294     }
2295    
2296     $.widget("ui.resizable", $.ui.mouse, {
2297     version: "1.10.3",
2298     widgetEventPrefix: "resize",
2299     options: {
2300     alsoResize: false,
2301     animate: false,
2302     animateDuration: "slow",
2303     animateEasing: "swing",
2304     aspectRatio: false,
2305     autoHide: false,
2306     containment: false,
2307     ghost: false,
2308     grid: false,
2309     handles: "e,s,se",
2310     helper: false,
2311     maxHeight: null,
2312     maxWidth: null,
2313     minHeight: 10,
2314     minWidth: 10,
2315     // See #7960
2316     zIndex: 90,
2317    
2318     // callbacks
2319     resize: null,
2320     start: null,
2321     stop: null
2322     },
2323     _create: function() {
2324    
2325     var n, i, handle, axis, hname,
2326     that = this,
2327     o = this.options;
2328     this.element.addClass("ui-resizable");
2329    
2330     $.extend(this, {
2331     _aspectRatio: !!(o.aspectRatio),
2332     aspectRatio: o.aspectRatio,
2333     originalElement: this.element,
2334     _proportionallyResizeElements: [],
2335     _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2336     });
2337    
2338     //Wrap the element if it cannot hold child nodes
2339     if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2340    
2341     //Create a wrapper element and set the wrapper to the new current internal element
2342     this.element.wrap(
2343     $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2344     position: this.element.css("position"),
2345     width: this.element.outerWidth(),
2346     height: this.element.outerHeight(),
2347     top: this.element.css("top"),
2348     left: this.element.css("left")
2349     })
2350     );
2351    
2352     //Overwrite the original this.element
2353     this.element = this.element.parent().data(
2354     "ui-resizable", this.element.data("ui-resizable")
2355     );
2356    
2357     this.elementIsWrapper = true;
2358    
2359     //Move margins to the wrapper
2360     this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2361     this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2362    
2363     //Prevent Safari textarea resize
2364     this.originalResizeStyle = this.originalElement.css("resize");
2365     this.originalElement.css("resize", "none");
2366    
2367     //Push the actual element to our proportionallyResize internal array
2368     this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2369    
2370     // avoid IE jump (hard set the margin)
2371     this.originalElement.css({ margin: this.originalElement.css("margin") });
2372    
2373     // fix handlers offset
2374     this._proportionallyResize();
2375    
2376     }
2377    
2378     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" });
2379     if(this.handles.constructor === String) {
2380    
2381     if ( this.handles === "all") {
2382     this.handles = "n,e,s,w,se,sw,ne,nw";
2383     }
2384    
2385     n = this.handles.split(",");
2386     this.handles = {};
2387    
2388     for(i = 0; i < n.length; i++) {
2389    
2390     handle = $.trim(n[i]);
2391     hname = "ui-resizable-"+handle;
2392     axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2393    
2394     // Apply zIndex to all handles - see #7960
2395     axis.css({ zIndex: o.zIndex });
2396    
2397     //TODO : What's going on here?
2398     if ("se" === handle) {
2399     axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2400     }
2401    
2402     //Insert into internal handles object and append to element
2403     this.handles[handle] = ".ui-resizable-"+handle;
2404     this.element.append(axis);
2405     }
2406    
2407     }
2408    
2409     this._renderAxis = function(target) {
2410    
2411     var i, axis, padPos, padWrapper;
2412    
2413     target = target || this.element;
2414    
2415     for(i in this.handles) {
2416    
2417     if(this.handles[i].constructor === String) {
2418     this.handles[i] = $(this.handles[i], this.element).show();
2419     }
2420    
2421     //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2422     if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2423    
2424     axis = $(this.handles[i], this.element);
2425    
2426     //Checking the correct pad and border
2427     padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2428    
2429     //The padding type i have to apply...
2430     padPos = [ "padding",
2431     /ne|nw|n/.test(i) ? "Top" :
2432     /se|sw|s/.test(i) ? "Bottom" :
2433     /^e$/.test(i) ? "Right" : "Left" ].join("");
2434    
2435     target.css(padPos, padWrapper);
2436    
2437     this._proportionallyResize();
2438    
2439     }
2440    
2441     //TODO: What's that good for? There's not anything to be executed left
2442     if(!$(this.handles[i]).length) {
2443     continue;
2444     }
2445     }
2446     };
2447    
2448     //TODO: make renderAxis a prototype function
2449     this._renderAxis(this.element);
2450    
2451     this._handles = $(".ui-resizable-handle", this.element)
2452     .disableSelection();
2453    
2454     //Matching axis name
2455     this._handles.mouseover(function() {
2456     if (!that.resizing) {
2457     if (this.className) {
2458     axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2459     }
2460     //Axis, default = se
2461     that.axis = axis && axis[1] ? axis[1] : "se";
2462     }
2463     });
2464    
2465     //If we want to auto hide the elements
2466     if (o.autoHide) {
2467     this._handles.hide();
2468     $(this.element)
2469     .addClass("ui-resizable-autohide")
2470     .mouseenter(function() {
2471     if (o.disabled) {
2472     return;
2473     }
2474     $(this).removeClass("ui-resizable-autohide");
2475     that._handles.show();
2476     })
2477     .mouseleave(function(){
2478     if (o.disabled) {
2479     return;
2480     }
2481     if (!that.resizing) {
2482     $(this).addClass("ui-resizable-autohide");
2483     that._handles.hide();
2484     }
2485     });
2486     }
2487    
2488     //Initialize the mouse interaction
2489     this._mouseInit();
2490    
2491     },
2492    
2493     _destroy: function() {
2494    
2495     this._mouseDestroy();
2496    
2497     var wrapper,
2498     _destroy = function(exp) {
2499     $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2500     .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2501     };
2502    
2503     //TODO: Unwrap at same DOM position
2504     if (this.elementIsWrapper) {
2505     _destroy(this.element);
2506     wrapper = this.element;
2507     this.originalElement.css({
2508     position: wrapper.css("position"),
2509     width: wrapper.outerWidth(),
2510     height: wrapper.outerHeight(),
2511     top: wrapper.css("top"),
2512     left: wrapper.css("left")
2513     }).insertAfter( wrapper );
2514     wrapper.remove();
2515     }
2516    
2517     this.originalElement.css("resize", this.originalResizeStyle);
2518     _destroy(this.originalElement);
2519    
2520     return this;
2521     },
2522    
2523     _mouseCapture: function(event) {
2524     var i, handle,
2525     capture = false;
2526    
2527     for (i in this.handles) {
2528     handle = $(this.handles[i])[0];
2529     if (handle === event.target || $.contains(handle, event.target)) {
2530     capture = true;
2531     }
2532     }
2533    
2534     return !this.options.disabled && capture;
2535     },
2536    
2537     _mouseStart: function(event) {
2538    
2539     var curleft, curtop, cursor,
2540     o = this.options,
2541     iniPos = this.element.position(),
2542     el = this.element;
2543    
2544     this.resizing = true;
2545    
2546     // bugfix for http://dev.jquery.com/ticket/1749
2547     if ( (/absolute/).test( el.css("position") ) ) {
2548     el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2549     } else if (el.is(".ui-draggable")) {
2550     el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2551     }
2552    
2553     this._renderProxy();
2554    
2555     curleft = num(this.helper.css("left"));
2556     curtop = num(this.helper.css("top"));
2557    
2558     if (o.containment) {
2559     curleft += $(o.containment).scrollLeft() || 0;
2560     curtop += $(o.containment).scrollTop() || 0;
2561     }
2562    
2563     //Store needed variables
2564     this.offset = this.helper.offset();
2565     this.position = { left: curleft, top: curtop };
2566     this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2567     this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2568     this.originalPosition = { left: curleft, top: curtop };
2569     this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2570     this.originalMousePosition = { left: event.pageX, top: event.pageY };
2571    
2572     //Aspect Ratio
2573     this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2574    
2575     cursor = $(".ui-resizable-" + this.axis).css("cursor");
2576     $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2577    
2578     el.addClass("ui-resizable-resizing");
2579     this._propagate("start", event);
2580     return true;
2581     },
2582    
2583     _mouseDrag: function(event) {
2584    
2585     //Increase performance, avoid regex
2586     var data,
2587     el = this.helper, props = {},
2588     smp = this.originalMousePosition,
2589     a = this.axis,
2590     prevTop = this.position.top,
2591     prevLeft = this.position.left,
2592     prevWidth = this.size.width,
2593     prevHeight = this.size.height,
2594     dx = (event.pageX-smp.left)||0,
2595     dy = (event.pageY-smp.top)||0,
2596     trigger = this._change[a];
2597    
2598     if (!trigger) {
2599     return false;
2600     }
2601    
2602     // Calculate the attrs that will be change
2603     data = trigger.apply(this, [event, dx, dy]);
2604    
2605     // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2606     this._updateVirtualBoundaries(event.shiftKey);
2607     if (this._aspectRatio || event.shiftKey) {
2608     data = this._updateRatio(data, event);
2609     }
2610    
2611     data = this._respectSize(data, event);
2612    
2613     this._updateCache(data);
2614    
2615     // plugins callbacks need to be called first
2616     this._propagate("resize", event);
2617    
2618     if (this.position.top !== prevTop) {
2619     props.top = this.position.top + "px";
2620     }
2621     if (this.position.left !== prevLeft) {
2622     props.left = this.position.left + "px";
2623     }
2624     if (this.size.width !== prevWidth) {
2625     props.width = this.size.width + "px";
2626     }
2627     if (this.size.height !== prevHeight) {
2628     props.height = this.size.height + "px";
2629     }
2630     el.css(props);
2631    
2632     if (!this._helper && this._proportionallyResizeElements.length) {
2633     this._proportionallyResize();
2634     }
2635    
2636     // Call the user callback if the element was resized
2637     if ( ! $.isEmptyObject(props) ) {
2638     this._trigger("resize", event, this.ui());
2639     }
2640    
2641     return false;
2642     },
2643    
2644     _mouseStop: function(event) {
2645    
2646     this.resizing = false;
2647     var pr, ista, soffseth, soffsetw, s, left, top,
2648     o = this.options, that = this;
2649    
2650     if(this._helper) {
2651    
2652     pr = this._proportionallyResizeElements;
2653     ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2654     soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2655     soffsetw = ista ? 0 : that.sizeDiff.width;
2656    
2657     s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) };
2658     left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2659     top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2660    
2661     if (!o.animate) {
2662     this.element.css($.extend(s, { top: top, left: left }));
2663     }
2664    
2665     that.helper.height(that.size.height);
2666     that.helper.width(that.size.width);
2667    
2668     if (this._helper && !o.animate) {
2669     this._proportionallyResize();
2670     }
2671     }
2672    
2673     $("body").css("cursor", "auto");
2674    
2675     this.element.removeClass("ui-resizable-resizing");
2676    
2677     this._propagate("stop", event);
2678    
2679     if (this._helper) {
2680     this.helper.remove();
2681     }
2682    
2683     return false;
2684    
2685     },
2686    
2687     _updateVirtualBoundaries: function(forceAspectRatio) {
2688     var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2689     o = this.options;
2690    
2691     b = {
2692     minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2693     maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2694     minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2695     maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2696     };
2697    
2698     if(this._aspectRatio || forceAspectRatio) {
2699     // We want to create an enclosing box whose aspect ration is the requested one
2700     // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2701     pMinWidth = b.minHeight * this.aspectRatio;
2702     pMinHeight = b.minWidth / this.aspectRatio;
2703     pMaxWidth = b.maxHeight * this.aspectRatio;
2704     pMaxHeight = b.maxWidth / this.aspectRatio;
2705    
2706     if(pMinWidth > b.minWidth) {
2707     b.minWidth = pMinWidth;
2708     }
2709     if(pMinHeight > b.minHeight) {
2710     b.minHeight = pMinHeight;
2711     }
2712     if(pMaxWidth < b.maxWidth) {
2713     b.maxWidth = pMaxWidth;
2714     }
2715     if(pMaxHeight < b.maxHeight) {
2716     b.maxHeight = pMaxHeight;
2717     }
2718     }
2719     this._vBoundaries = b;
2720     },
2721    
2722     _updateCache: function(data) {
2723     this.offset = this.helper.offset();
2724     if (isNumber(data.left)) {
2725     this.position.left = data.left;
2726     }
2727     if (isNumber(data.top)) {
2728     this.position.top = data.top;
2729     }
2730     if (isNumber(data.height)) {
2731     this.size.height = data.height;
2732     }
2733     if (isNumber(data.width)) {
2734     this.size.width = data.width;
2735     }
2736     },
2737    
2738     _updateRatio: function( data ) {
2739    
2740     var cpos = this.position,
2741     csize = this.size,
2742     a = this.axis;
2743    
2744     if (isNumber(data.height)) {
2745     data.width = (data.height * this.aspectRatio);
2746     } else if (isNumber(data.width)) {
2747     data.height = (data.width / this.aspectRatio);
2748     }
2749    
2750     if (a === "sw") {
2751     data.left = cpos.left + (csize.width - data.width);
2752     data.top = null;
2753     }
2754     if (a === "nw") {
2755     data.top = cpos.top + (csize.height - data.height);
2756     data.left = cpos.left + (csize.width - data.width);
2757     }
2758    
2759     return data;
2760     },
2761    
2762     _respectSize: function( data ) {
2763    
2764     var o = this._vBoundaries,
2765     a = this.axis,
2766     ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2767     isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2768     dw = this.originalPosition.left + this.originalSize.width,
2769     dh = this.position.top + this.size.height,
2770     cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2771     if (isminw) {
2772     data.width = o.minWidth;
2773     }
2774     if (isminh) {
2775     data.height = o.minHeight;
2776     }
2777     if (ismaxw) {
2778     data.width = o.maxWidth;
2779     }
2780     if (ismaxh) {
2781     data.height = o.maxHeight;
2782     }
2783    
2784     if (isminw && cw) {
2785     data.left = dw - o.minWidth;
2786     }
2787     if (ismaxw && cw) {
2788     data.left = dw - o.maxWidth;
2789     }
2790     if (isminh && ch) {
2791     data.top = dh - o.minHeight;
2792     }
2793     if (ismaxh && ch) {
2794     data.top = dh - o.maxHeight;
2795     }
2796    
2797     // fixing jump error on top/left - bug #2330
2798     if (!data.width && !data.height && !data.left && data.top) {
2799     data.top = null;
2800     } else if (!data.width && !data.height && !data.top && data.left) {
2801     data.left = null;
2802     }
2803    
2804     return data;
2805     },
2806    
2807     _proportionallyResize: function() {
2808    
2809     if (!this._proportionallyResizeElements.length) {
2810     return;
2811     }
2812    
2813     var i, j, borders, paddings, prel,
2814     element = this.helper || this.element;
2815    
2816     for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2817    
2818     prel = this._proportionallyResizeElements[i];
2819    
2820     if (!this.borderDif) {
2821     this.borderDif = [];
2822     borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2823     paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2824    
2825     for ( j = 0; j < borders.length; j++ ) {
2826     this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2827     }
2828     }
2829    
2830     prel.css({
2831     height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2832     width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2833     });
2834    
2835     }
2836    
2837     },
2838    
2839     _renderProxy: function() {
2840    
2841     var el = this.element, o = this.options;
2842     this.elementOffset = el.offset();
2843    
2844     if(this._helper) {
2845    
2846     this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
2847    
2848     this.helper.addClass(this._helper).css({
2849     width: this.element.outerWidth() - 1,
2850     height: this.element.outerHeight() - 1,
2851     position: "absolute",
2852     left: this.elementOffset.left +"px",
2853     top: this.elementOffset.top +"px",
2854     zIndex: ++o.zIndex //TODO: Don't modify option
2855     });
2856    
2857     this.helper
2858     .appendTo("body")
2859     .disableSelection();
2860    
2861     } else {
2862     this.helper = this.element;
2863     }
2864    
2865     },
2866    
2867     _change: {
2868     e: function(event, dx) {
2869     return { width: this.originalSize.width + dx };
2870     },
2871     w: function(event, dx) {
2872     var cs = this.originalSize, sp = this.originalPosition;
2873     return { left: sp.left + dx, width: cs.width - dx };
2874     },
2875     n: function(event, dx, dy) {
2876     var cs = this.originalSize, sp = this.originalPosition;
2877     return { top: sp.top + dy, height: cs.height - dy };
2878     },
2879     s: function(event, dx, dy) {
2880     return { height: this.originalSize.height + dy };
2881     },
2882     se: function(event, dx, dy) {
2883     return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2884     },
2885     sw: function(event, dx, dy) {
2886     return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2887     },
2888     ne: function(event, dx, dy) {
2889     return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2890     },
2891     nw: function(event, dx, dy) {
2892     return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2893     }
2894     },
2895    
2896     _propagate: function(n, event) {
2897     $.ui.plugin.call(this, n, [event, this.ui()]);
2898     (n !== "resize" && this._trigger(n, event, this.ui()));
2899     },
2900    
2901     plugins: {},
2902    
2903     ui: function() {
2904     return {
2905     originalElement: this.originalElement,
2906     element: this.element,
2907     helper: this.helper,
2908     position: this.position,
2909     size: this.size,
2910     originalSize: this.originalSize,
2911     originalPosition: this.originalPosition
2912     };
2913     }
2914    
2915     });
2916    
2917     /*
2918     * Resizable Extensions
2919     */
2920    
2921     $.ui.plugin.add("resizable", "animate", {
2922    
2923     stop: function( event ) {
2924     var that = $(this).data("ui-resizable"),
2925     o = that.options,
2926     pr = that._proportionallyResizeElements,
2927     ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2928     soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2929     soffsetw = ista ? 0 : that.sizeDiff.width,
2930     style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2931     left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2932     top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2933    
2934     that.element.animate(
2935     $.extend(style, top && left ? { top: top, left: left } : {}), {
2936     duration: o.animateDuration,
2937     easing: o.animateEasing,
2938     step: function() {
2939    
2940     var data = {
2941     width: parseInt(that.element.css("width"), 10),
2942     height: parseInt(that.element.css("height"), 10),
2943     top: parseInt(that.element.css("top"), 10),
2944     left: parseInt(that.element.css("left"), 10)
2945     };
2946    
2947     if (pr && pr.length) {
2948     $(pr[0]).css({ width: data.width, height: data.height });
2949     }
2950    
2951     // propagating resize, and updating values for each animation step
2952     that._updateCache(data);
2953     that._propagate("resize", event);
2954    
2955     }
2956     }
2957     );
2958     }
2959    
2960     });
2961    
2962     $.ui.plugin.add("resizable", "containment", {
2963    
2964     start: function() {
2965     var element, p, co, ch, cw, width, height,
2966     that = $(this).data("ui-resizable"),
2967     o = that.options,
2968     el = that.element,
2969     oc = o.containment,
2970     ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2971    
2972     if (!ce) {
2973     return;
2974     }
2975    
2976     that.containerElement = $(ce);
2977    
2978     if (/document/.test(oc) || oc === document) {
2979     that.containerOffset = { left: 0, top: 0 };
2980     that.containerPosition = { left: 0, top: 0 };
2981    
2982     that.parentData = {
2983     element: $(document), left: 0, top: 0,
2984     width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2985     };
2986     }
2987    
2988     // i'm a node, so compute top, left, right, bottom
2989     else {
2990     element = $(ce);
2991     p = [];
2992     $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2993    
2994     that.containerOffset = element.offset();
2995     that.containerPosition = element.position();
2996     that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2997    
2998     co = that.containerOffset;
2999     ch = that.containerSize.height;
3000     cw = that.containerSize.width;
3001     width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
3002     height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3003    
3004     that.parentData = {
3005     element: ce, left: co.left, top: co.top, width: width, height: height
3006     };
3007     }
3008     },
3009    
3010     resize: function( event ) {
3011     var woset, hoset, isParent, isOffsetRelative,
3012     that = $(this).data("ui-resizable"),
3013     o = that.options,
3014     co = that.containerOffset, cp = that.position,
3015     pRatio = that._aspectRatio || event.shiftKey,
3016     cop = { top:0, left:0 }, ce = that.containerElement;
3017    
3018     if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3019     cop = co;
3020     }
3021    
3022     if (cp.left < (that._helper ? co.left : 0)) {
3023     that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3024     if (pRatio) {
3025     that.size.height = that.size.width / that.aspectRatio;
3026     }
3027     that.position.left = o.helper ? co.left : 0;
3028     }
3029    
3030     if (cp.top < (that._helper ? co.top : 0)) {
3031     that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3032     if (pRatio) {
3033     that.size.width = that.size.height * that.aspectRatio;
3034     }
3035     that.position.top = that._helper ? co.top : 0;
3036     }
3037    
3038     that.offset.left = that.parentData.left+that.position.left;
3039     that.offset.top = that.parentData.top+that.position.top;
3040    
3041     woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3042     hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3043    
3044     isParent = that.containerElement.get(0) === that.element.parent().get(0);
3045     isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3046    
3047     if(isParent && isOffsetRelative) {
3048     woset -= that.parentData.left;
3049     }
3050    
3051     if (woset + that.size.width >= that.parentData.width) {
3052     that.size.width = that.parentData.width - woset;
3053     if (pRatio) {
3054     that.size.height = that.size.width / that.aspectRatio;
3055     }
3056     }
3057    
3058     if (hoset + that.size.height >= that.parentData.height) {
3059     that.size.height = that.parentData.height - hoset;
3060     if (pRatio) {
3061     that.size.width = that.size.height * that.aspectRatio;
3062     }
3063     }
3064     },
3065    
3066     stop: function(){
3067     var that = $(this).data("ui-resizable"),
3068     o = that.options,
3069     co = that.containerOffset,
3070     cop = that.containerPosition,
3071     ce = that.containerElement,
3072     helper = $(that.helper),
3073     ho = helper.offset(),
3074     w = helper.outerWidth() - that.sizeDiff.width,
3075     h = helper.outerHeight() - that.sizeDiff.height;
3076    
3077     if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3078     $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3079     }
3080    
3081     if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3082     $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3083     }
3084    
3085     }
3086     });
3087    
3088     $.ui.plugin.add("resizable", "alsoResize", {
3089    
3090     start: function () {
3091     var that = $(this).data("ui-resizable"),
3092     o = that.options,
3093     _store = function (exp) {
3094     $(exp).each(function() {
3095     var el = $(this);
3096     el.data("ui-resizable-alsoresize", {
3097     width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3098     left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3099     });
3100     });
3101     };
3102    
3103     if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3104     if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3105     else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3106     }else{
3107     _store(o.alsoResize);
3108     }
3109     },
3110    
3111     resize: function (event, ui) {
3112     var that = $(this).data("ui-resizable"),
3113     o = that.options,
3114     os = that.originalSize,
3115     op = that.originalPosition,
3116     delta = {
3117     height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3118     top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3119     },
3120    
3121     _alsoResize = function (exp, c) {
3122     $(exp).each(function() {
3123     var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3124     css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3125    
3126     $.each(css, function (i, prop) {
3127     var sum = (start[prop]||0) + (delta[prop]||0);
3128     if (sum && sum >= 0) {
3129     style[prop] = sum || null;
3130     }
3131     });
3132    
3133     el.css(style);
3134     });
3135     };
3136    
3137     if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3138     $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3139     }else{
3140     _alsoResize(o.alsoResize);
3141     }
3142     },
3143    
3144     stop: function () {
3145     $(this).removeData("resizable-alsoresize");
3146     }
3147     });
3148    
3149     $.ui.plugin.add("resizable", "ghost", {
3150    
3151     start: function() {
3152    
3153     var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3154    
3155     that.ghost = that.originalElement.clone();
3156     that.ghost
3157     .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3158     .addClass("ui-resizable-ghost")
3159     .addClass(typeof o.ghost === "string" ? o.ghost : "");
3160    
3161     that.ghost.appendTo(that.helper);
3162    
3163     },
3164    
3165     resize: function(){
3166     var that = $(this).data("ui-resizable");
3167     if (that.ghost) {
3168     that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3169     }
3170     },
3171    
3172     stop: function() {
3173     var that = $(this).data("ui-resizable");
3174     if (that.ghost && that.helper) {
3175     that.helper.get(0).removeChild(that.ghost.get(0));
3176     }
3177     }
3178    
3179     });
3180    
3181     $.ui.plugin.add("resizable", "grid", {
3182    
3183     resize: function() {
3184     var that = $(this).data("ui-resizable"),
3185     o = that.options,
3186     cs = that.size,
3187     os = that.originalSize,
3188     op = that.originalPosition,
3189     a = that.axis,
3190     grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3191     gridX = (grid[0]||1),
3192     gridY = (grid[1]||1),
3193     ox = Math.round((cs.width - os.width) / gridX) * gridX,
3194     oy = Math.round((cs.height - os.height) / gridY) * gridY,
3195     newWidth = os.width + ox,
3196     newHeight = os.height + oy,
3197     isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3198     isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3199     isMinWidth = o.minWidth && (o.minWidth > newWidth),
3200     isMinHeight = o.minHeight && (o.minHeight > newHeight);
3201    
3202     o.grid = grid;
3203    
3204     if (isMinWidth) {
3205     newWidth = newWidth + gridX;
3206     }
3207     if (isMinHeight) {
3208     newHeight = newHeight + gridY;
3209     }
3210     if (isMaxWidth) {
3211     newWidth = newWidth - gridX;
3212     }
3213     if (isMaxHeight) {
3214     newHeight = newHeight - gridY;
3215     }
3216    
3217     if (/^(se|s|e)$/.test(a)) {
3218     that.size.width = newWidth;
3219     that.size.height = newHeight;
3220     } else if (/^(ne)$/.test(a)) {
3221     that.size.width = newWidth;
3222     that.size.height = newHeight;
3223     that.position.top = op.top - oy;
3224     } else if (/^(sw)$/.test(a)) {
3225     that.size.width = newWidth;
3226     that.size.height = newHeight;
3227     that.position.left = op.left - ox;
3228     } else {
3229     that.size.width = newWidth;
3230     that.size.height = newHeight;
3231     that.position.top = op.top - oy;
3232     that.position.left = op.left - ox;
3233     }
3234     }
3235    
3236     });
3237    
3238     })(jQuery);
3239    
3240     (function( $, undefined ) {
3241    
3242     $.widget("ui.selectable", $.ui.mouse, {
3243     version: "1.10.3",
3244     options: {
3245     appendTo: "body",
3246     autoRefresh: true,
3247     distance: 0,
3248     filter: "*",
3249     tolerance: "touch",
3250    
3251     // callbacks
3252     selected: null,
3253     selecting: null,
3254     start: null,
3255     stop: null,
3256     unselected: null,
3257     unselecting: null
3258     },
3259     _create: function() {
3260     var selectees,
3261     that = this;
3262    
3263     this.element.addClass("ui-selectable");
3264    
3265     this.dragged = false;
3266    
3267     // cache selectee children based on filter
3268     this.refresh = function() {
3269     selectees = $(that.options.filter, that.element[0]);
3270     selectees.addClass("ui-selectee");
3271     selectees.each(function() {
3272     var $this = $(this),
3273     pos = $this.offset();
3274     $.data(this, "selectable-item", {
3275     element: this,
3276     $element: $this,
3277     left: pos.left,
3278     top: pos.top,
3279     right: pos.left + $this.outerWidth(),
3280     bottom: pos.top + $this.outerHeight(),
3281     startselected: false,
3282     selected: $this.hasClass("ui-selected"),
3283     selecting: $this.hasClass("ui-selecting"),
3284     unselecting: $this.hasClass("ui-unselecting")
3285     });
3286     });
3287     };
3288     this.refresh();
3289    
3290     this.selectees = selectees.addClass("ui-selectee");
3291    
3292     this._mouseInit();
3293    
3294     this.helper = $("<div class='ui-selectable-helper'></div>");
3295     },
3296    
3297     _destroy: function() {
3298     this.selectees
3299     .removeClass("ui-selectee")
3300     .removeData("selectable-item");
3301     this.element
3302     .removeClass("ui-selectable ui-selectable-disabled");
3303     this._mouseDestroy();
3304     },
3305    
3306     _mouseStart: function(event) {
3307     var that = this,
3308     options = this.options;
3309    
3310     this.opos = [event.pageX, event.pageY];
3311    
3312     if (this.options.disabled) {
3313     return;
3314     }
3315    
3316     this.selectees = $(options.filter, this.element[0]);
3317    
3318     this._trigger("start", event);
3319    
3320     $(options.appendTo).append(this.helper);
3321     // position helper (lasso)
3322     this.helper.css({
3323     "left": event.pageX,
3324     "top": event.pageY,
3325     "width": 0,
3326     "height": 0
3327     });
3328    
3329     if (options.autoRefresh) {
3330     this.refresh();
3331     }
3332    
3333     this.selectees.filter(".ui-selected").each(function() {
3334     var selectee = $.data(this, "selectable-item");
3335     selectee.startselected = true;
3336     if (!event.metaKey && !event.ctrlKey) {
3337     selectee.$element.removeClass("ui-selected");
3338     selectee.selected = false;
3339     selectee.$element.addClass("ui-unselecting");
3340     selectee.unselecting = true;
3341     // selectable UNSELECTING callback
3342     that._trigger("unselecting", event, {
3343     unselecting: selectee.element
3344     });
3345     }
3346     });
3347    
3348     $(event.target).parents().addBack().each(function() {
3349     var doSelect,
3350     selectee = $.data(this, "selectable-item");
3351     if (selectee) {
3352     doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3353     selectee.$element
3354     .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3355     .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3356     selectee.unselecting = !doSelect;
3357     selectee.selecting = doSelect;
3358     selectee.selected = doSelect;
3359     // selectable (UN)SELECTING callback
3360     if (doSelect) {
3361     that._trigger("selecting", event, {
3362     selecting: selectee.element
3363     });
3364     } else {
3365     that._trigger("unselecting", event, {
3366     unselecting: selectee.element
3367     });
3368     }
3369     return false;
3370     }
3371     });
3372    
3373     },
3374    
3375     _mouseDrag: function(event) {
3376    
3377     this.dragged = true;
3378    
3379     if (this.options.disabled) {
3380     return;
3381     }
3382    
3383     var tmp,
3384     that = this,
3385     options = this.options,
3386     x1 = this.opos[0],
3387     y1 = this.opos[1],
3388     x2 = event.pageX,
3389     y2 = event.pageY;
3390    
3391     if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3392     if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3393     this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3394    
3395     this.selectees.each(function() {
3396     var selectee = $.data(this, "selectable-item"),
3397     hit = false;
3398    
3399     //prevent helper from being selected if appendTo: selectable
3400     if (!selectee || selectee.element === that.element[0]) {
3401     return;
3402     }
3403    
3404     if (options.tolerance === "touch") {
3405     hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3406     } else if (options.tolerance === "fit") {
3407     hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3408     }
3409    
3410     if (hit) {
3411     // SELECT
3412     if (selectee.selected) {
3413     selectee.$element.removeClass("ui-selected");
3414     selectee.selected = false;
3415     }
3416     if (selectee.unselecting) {
3417     selectee.$element.removeClass("ui-unselecting");
3418     selectee.unselecting = false;
3419     }
3420     if (!selectee.selecting) {
3421     selectee.$element.addClass("ui-selecting");
3422     selectee.selecting = true;
3423     // selectable SELECTING callback
3424     that._trigger("selecting", event, {
3425     selecting: selectee.element
3426     });
3427     }
3428     } else {
3429     // UNSELECT
3430     if (selectee.selecting) {
3431     if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3432     selectee.$element.removeClass("ui-selecting");
3433     selectee.selecting = false;
3434     selectee.$element.addClass("ui-selected");
3435     selectee.selected = true;
3436     } else {
3437     selectee.$element.removeClass("ui-selecting");
3438     selectee.selecting = false;
3439     if (selectee.startselected) {
3440     selectee.$element.addClass("ui-unselecting");
3441     selectee.unselecting = true;
3442     }
3443     // selectable UNSELECTING callback
3444     that._trigger("unselecting", event, {
3445     unselecting: selectee.element
3446     });
3447     }
3448     }
3449     if (selectee.selected) {
3450     if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3451     selectee.$element.removeClass("ui-selected");
3452     selectee.selected = false;
3453    
3454     selectee.$element.addClass("ui-unselecting");
3455     selectee.unselecting = true;
3456     // selectable UNSELECTING callback
3457     that._trigger("unselecting", event, {
3458     unselecting: selectee.element
3459     });
3460     }
3461     }
3462     }
3463     });
3464    
3465     return false;
3466     },
3467    
3468     _mouseStop: function(event) {
3469     var that = this;
3470    
3471     this.dragged = false;
3472    
3473     $(".ui-unselecting", this.element[0]).each(function() {
3474     var selectee = $.data(this, "selectable-item");
3475     selectee.$element.removeClass("ui-unselecting");
3476     selectee.unselecting = false;
3477     selectee.startselected = false;
3478     that._trigger("unselected", event, {
3479     unselected: selectee.element
3480     });
3481     });
3482     $(".ui-selecting", this.element[0]).each(function() {
3483     var selectee = $.data(this, "selectable-item");
3484     selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3485     selectee.selecting = false;
3486     selectee.selected = true;
3487     selectee.startselected = true;
3488     that._trigger("selected", event, {
3489     selected: selectee.element
3490     });
3491     });
3492     this._trigger("stop", event);
3493    
3494     this.helper.remove();
3495    
3496     return false;
3497     }
3498    
3499     });
3500    
3501     })(jQuery);
3502    
3503     (function( $, undefined ) {
3504    
3505     /*jshint loopfunc: true */
3506    
3507     function isOverAxis( x, reference, size ) {
3508     return ( x > reference ) && ( x < ( reference + size ) );
3509     }
3510    
3511     function isFloating(item) {
3512     return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3513     }
3514    
3515     $.widget("ui.sortable", $.ui.mouse, {
3516     version: "1.10.3",
3517     widgetEventPrefix: "sort",
3518     ready: false,
3519     options: {
3520     appendTo: "parent",
3521     axis: false,
3522     connectWith: false,
3523     containment: false,
3524     cursor: "auto",
3525     cursorAt: false,
3526     dropOnEmpty: true,
3527     forcePlaceholderSize: false,
3528     forceHelperSize: false,
3529     grid: false,
3530     handle: false,
3531     helper: "original",
3532     items: "> *",
3533     opacity: false,
3534     placeholder: false,
3535     revert: false,
3536     scroll: true,
3537     scrollSensitivity: 20,
3538     scrollSpeed: 20,
3539     scope: "default",
3540     tolerance: "intersect",
3541     zIndex: 1000,
3542    
3543     // callbacks
3544     activate: null,
3545     beforeStop: null,
3546     change: null,
3547     deactivate: null,
3548     out: null,
3549     over: null,
3550     receive: null,
3551     remove: null,
3552     sort: null,
3553     start: null,
3554     stop: null,
3555     update: null
3556     },
3557     _create: function() {
3558    
3559     var o = this.options;
3560     this.containerCache = {};
3561     this.element.addClass("ui-sortable");
3562    
3563     //Get the items
3564     this.refresh();
3565    
3566     //Let's determine if the items are being displayed horizontally
3567     this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
3568    
3569     //Let's determine the parent's offset
3570     this.offset = this.element.offset();
3571    
3572     //Initialize mouse events for interaction
3573     this._mouseInit();
3574    
3575     //We're ready to go
3576     this.ready = true;
3577    
3578     },
3579    
3580     _destroy: function() {
3581     this.element
3582     .removeClass("ui-sortable ui-sortable-disabled");
3583     this._mouseDestroy();
3584    
3585     for ( var i = this.items.length - 1; i >= 0; i-- ) {
3586     this.items[i].item.removeData(this.widgetName + "-item");
3587     }
3588    
3589     return this;
3590     },
3591    
3592     _setOption: function(key, value){
3593     if ( key === "disabled" ) {
3594     this.options[ key ] = value;
3595    
3596     this.widget().toggleClass( "ui-sortable-disabled", !!value );
3597     } else {
3598     // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3599     $.Widget.prototype._setOption.apply(this, arguments);
3600     }
3601     },
3602    
3603     _mouseCapture: function(event, overrideHandle) {
3604     var currentItem = null,
3605     validHandle = false,
3606     that = this;
3607    
3608     if (this.reverting) {
3609     return false;
3610     }
3611    
3612     if(this.options.disabled || this.options.type === "static") {
3613     return false;
3614     }
3615    
3616     //We have to refresh the items data once first
3617     this._refreshItems(event);
3618    
3619     //Find out if the clicked node (or one of its parents) is a actual item in this.items
3620     $(event.target).parents().each(function() {
3621     if($.data(this, that.widgetName + "-item") === that) {
3622     currentItem = $(this);
3623     return false;
3624     }
3625     });
3626     if($.data(event.target, that.widgetName + "-item") === that) {
3627     currentItem = $(event.target);
3628     }
3629    
3630     if(!currentItem) {
3631     return false;
3632     }
3633     if(this.options.handle && !overrideHandle) {
3634     $(this.options.handle, currentItem).find("*").addBack().each(function() {
3635     if(this === event.target) {
3636     validHandle = true;
3637     }
3638     });
3639     if(!validHandle) {
3640     return false;
3641     }
3642     }
3643    
3644     this.currentItem = currentItem;
3645     this._removeCurrentsFromItems();
3646     return true;
3647    
3648     },
3649    
3650     _mouseStart: function(event, overrideHandle, noActivation) {
3651    
3652     var i, body,
3653     o = this.options;
3654    
3655     this.currentContainer = this;
3656    
3657     //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3658     this.refreshPositions();
3659    
3660     //Create and append the visible helper
3661     this.helper = this._createHelper(event);
3662    
3663     //Cache the helper size
3664     this._cacheHelperProportions();
3665    
3666     /*
3667     * - Position generation -
3668     * This block generates everything position related - it's the core of draggables.
3669     */
3670    
3671     //Cache the margins of the original element
3672     this._cacheMargins();
3673    
3674     //Get the next scrolling parent
3675     this.scrollParent = this.helper.scrollParent();
3676    
3677     //The element's absolute position on the page minus margins
3678     this.offset = this.currentItem.offset();
3679     this.offset = {
3680     top: this.offset.top - this.margins.top,
3681     left: this.offset.left - this.margins.left
3682     };
3683    
3684     $.extend(this.offset, {
3685     click: { //Where the click happened, relative to the element
3686     left: event.pageX - this.offset.left,
3687     top: event.pageY - this.offset.top
3688     },
3689     parent: this._getParentOffset(),
3690     relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3691     });
3692    
3693     // Only after we got the offset, we can change the helper's position to absolute
3694     // TODO: Still need to figure out a way to make relative sorting possible
3695     this.helper.css("position", "absolute");
3696     this.cssPosition = this.helper.css("position");
3697    
3698     //Generate the original position
3699     this.originalPosition = this._generatePosition(event);
3700     this.originalPageX = event.pageX;
3701     this.originalPageY = event.pageY;
3702    
3703     //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3704     (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3705    
3706     //Cache the former DOM position
3707     this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3708    
3709     //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
3710     if(this.helper[0] !== this.currentItem[0]) {
3711     this.currentItem.hide();
3712     }
3713    
3714     //Create the placeholder
3715     this._createPlaceholder();
3716    
3717     //Set a containment if given in the options
3718     if(o.containment) {
3719     this._setContainment();
3720     }
3721    
3722     if( o.cursor && o.cursor !== "auto" ) { // cursor option
3723     body = this.document.find( "body" );
3724    
3725     // support: IE
3726     this.storedCursor = body.css( "cursor" );
3727     body.css( "cursor", o.cursor );
3728    
3729     this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
3730     }
3731    
3732     if(o.opacity) { // opacity option
3733     if (this.helper.css("opacity")) {
3734     this._storedOpacity = this.helper.css("opacity");
3735     }
3736     this.helper.css("opacity", o.opacity);
3737     }
3738    
3739     if(o.zIndex) { // zIndex option
3740     if (this.helper.css("zIndex")) {
3741     this._storedZIndex = this.helper.css("zIndex");
3742     }
3743     this.helper.css("zIndex", o.zIndex);
3744     }
3745    
3746     //Prepare scrolling
3747     if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3748     this.overflowOffset = this.scrollParent.offset();
3749     }
3750    
3751     //Call callbacks
3752     this._trigger("start", event, this._uiHash());
3753    
3754     //Recache the helper size
3755     if(!this._preserveHelperProportions) {
3756     this._cacheHelperProportions();
3757     }
3758    
3759    
3760     //Post "activate" events to possible containers
3761     if( !noActivation ) {
3762     for ( i = this.containers.length - 1; i >= 0; i-- ) {
3763     this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3764     }
3765     }
3766    
3767     //Prepare possible droppables
3768     if($.ui.ddmanager) {
3769     $.ui.ddmanager.current = this;
3770     }
3771    
3772     if ($.ui.ddmanager && !o.dropBehaviour) {
3773     $.ui.ddmanager.prepareOffsets(this, event);
3774     }
3775    
3776     this.dragging = true;
3777    
3778     this.helper.addClass("ui-sortable-helper");
3779     this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3780     return true;
3781    
3782     },
3783    
3784     _mouseDrag: function(event) {
3785     var i, item, itemElement, intersection,
3786     o = this.options,
3787     scrolled = false;
3788    
3789     //Compute the helpers position
3790     this.position = this._generatePosition(event);
3791     this.positionAbs = this._convertPositionTo("absolute");
3792    
3793     if (!this.lastPositionAbs) {
3794     this.lastPositionAbs = this.positionAbs;
3795     }
3796    
3797     //Do scrolling
3798     if(this.options.scroll) {
3799     if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3800    
3801     if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3802     this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3803     } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3804     this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3805     }
3806    
3807     if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3808     this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3809     } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3810     this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3811     }
3812    
3813     } else {
3814    
3815     if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
3816     scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3817     } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
3818     scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3819     }
3820    
3821     if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
3822     scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3823     } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
3824     scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3825     }
3826    
3827     }
3828    
3829     if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3830     $.ui.ddmanager.prepareOffsets(this, event);
3831     }
3832     }
3833    
3834     //Regenerate the absolute position used for position checks
3835     this.positionAbs = this._convertPositionTo("absolute");
3836    
3837     //Set the helper position
3838     if(!this.options.axis || this.options.axis !== "y") {
3839     this.helper[0].style.left = this.position.left+"px";
3840     }
3841     if(!this.options.axis || this.options.axis !== "x") {
3842     this.helper[0].style.top = this.position.top+"px";
3843     }
3844    
3845     //Rearrange
3846     for (i = this.items.length - 1; i >= 0; i--) {
3847    
3848     //Cache variables and intersection, continue if no intersection
3849     item = this.items[i];
3850     itemElement = item.item[0];
3851     intersection = this._intersectsWithPointer(item);
3852     if (!intersection) {
3853     continue;
3854     }
3855    
3856     // Only put the placeholder inside the current Container, skip all
3857     // items form other containers. This works because when moving
3858     // an item from one container to another the
3859     // currentContainer is switched before the placeholder is moved.
3860     //
3861     // Without this moving items in "sub-sortables" can cause the placeholder to jitter
3862     // beetween the outer and inner container.
3863     if (item.instance !== this.currentContainer) {
3864     continue;
3865     }
3866    
3867     // cannot intersect with itself
3868     // no useless actions that have been done before
3869     // no action if the item moved is the parent of the item checked
3870     if (itemElement !== this.currentItem[0] &&
3871     this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3872     !$.contains(this.placeholder[0], itemElement) &&
3873     (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3874     ) {
3875    
3876     this.direction = intersection === 1 ? "down" : "up";
3877    
3878     if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3879     this._rearrange(event, item);
3880     } else {
3881     break;
3882     }
3883    
3884     this._trigger("change", event, this._uiHash());
3885     break;
3886     }
3887     }
3888    
3889     //Post events to containers
3890     this._contactContainers(event);
3891    
3892     //Interconnect with droppables
3893     if($.ui.ddmanager) {
3894     $.ui.ddmanager.drag(this, event);
3895     }
3896    
3897     //Call callbacks
3898     this._trigger("sort", event, this._uiHash());
3899    
3900     this.lastPositionAbs = this.positionAbs;
3901     return false;
3902    
3903     },
3904    
3905     _mouseStop: function(event, noPropagation) {
3906    
3907     if(!event) {
3908     return;
3909     }
3910    
3911     //If we are using droppables, inform the manager about the drop
3912     if ($.ui.ddmanager && !this.options.dropBehaviour) {
3913     $.ui.ddmanager.drop(this, event);
3914     }
3915    
3916     if(this.options.revert) {
3917     var that = this,
3918     cur = this.placeholder.offset(),
3919     axis = this.options.axis,
3920     animation = {};
3921    
3922     if ( !axis || axis === "x" ) {
3923     animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
3924     }
3925     if ( !axis || axis === "y" ) {
3926     animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
3927     }
3928     this.reverting = true;
3929     $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
3930     that._clear(event);
3931     });
3932     } else {
3933     this._clear(event, noPropagation);
3934     }
3935    
3936     return false;
3937    
3938     },
3939    
3940     cancel: function() {
3941    
3942     if(this.dragging) {
3943    
3944     this._mouseUp({ target: null });
3945    
3946     if(this.options.helper === "original") {
3947     this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3948     } else {
3949     this.currentItem.show();
3950     }
3951    
3952     //Post deactivating events to containers
3953     for (var i = this.containers.length - 1; i >= 0; i--){
3954     this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3955     if(this.containers[i].containerCache.over) {
3956     this.containers[i]._trigger("out", null, this._uiHash(this));
3957     this.containers[i].containerCache.over = 0;
3958     }
3959     }
3960    
3961     }
3962    
3963     if (this.placeholder) {
3964     //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3965     if(this.placeholder[0].parentNode) {
3966     this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3967     }
3968     if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3969     this.helper.remove();
3970     }
3971    
3972     $.extend(this, {
3973     helper: null,
3974     dragging: false,
3975     reverting: false,
3976     _noFinalSort: null
3977     });
3978    
3979     if(this.domPosition.prev) {
3980     $(this.domPosition.prev).after(this.currentItem);
3981     } else {
3982     $(this.domPosition.parent).prepend(this.currentItem);
3983     }
3984     }
3985    
3986     return this;
3987    
3988     },
3989    
3990     serialize: function(o) {
3991    
3992     var items = this._getItemsAsjQuery(o && o.connected),
3993     str = [];
3994     o = o || {};
3995    
3996     $(items).each(function() {
3997     var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
3998     if (res) {
3999     str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4000     }
4001     });
4002    
4003     if(!str.length && o.key) {
4004     str.push(o.key + "=");
4005     }
4006    
4007     return str.join("&");
4008    
4009     },
4010    
4011     toArray: function(o) {
4012    
4013     var items = this._getItemsAsjQuery(o && o.connected),
4014     ret = [];
4015    
4016     o = o || {};
4017    
4018     items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4019     return ret;
4020    
4021     },
4022    
4023     /* Be careful with the following core functions */
4024     _intersectsWith: function(item) {
4025    
4026     var x1 = this.positionAbs.left,
4027     x2 = x1 + this.helperProportions.width,
4028     y1 = this.positionAbs.top,
4029     y2 = y1 + this.helperProportions.height,
4030     l = item.left,
4031     r = l + item.width,
4032     t = item.top,
4033     b = t + item.height,
4034     dyClick = this.offset.click.top,
4035     dxClick = this.offset.click.left,
4036     isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4037     isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4038     isOverElement = isOverElementHeight && isOverElementWidth;
4039    
4040     if ( this.options.tolerance === "pointer" ||
4041     this.options.forcePointerForContainers ||
4042     (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4043     ) {
4044     return isOverElement;
4045     } else {
4046    
4047     return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4048     x2 - (this.helperProportions.width / 2) < r && // Left Half
4049     t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4050     y2 - (this.helperProportions.height / 2) < b ); // Top Half
4051    
4052     }
4053     },
4054    
4055     _intersectsWithPointer: function(item) {
4056    
4057     var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4058     isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4059     isOverElement = isOverElementHeight && isOverElementWidth,
4060     verticalDirection = this._getDragVerticalDirection(),
4061     horizontalDirection = this._getDragHorizontalDirection();
4062    
4063     if (!isOverElement) {
4064     return false;
4065     }
4066    
4067     return this.floating ?
4068     ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4069     : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4070    
4071     },
4072    
4073     _intersectsWithSides: function(item) {
4074    
4075     var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4076     isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4077     verticalDirection = this._getDragVerticalDirection(),
4078     horizontalDirection = this._getDragHorizontalDirection();
4079    
4080     if (this.floating && horizontalDirection) {
4081     return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4082     } else {
4083     return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4084     }
4085    
4086     },
4087    
4088     _getDragVerticalDirection: function() {
4089     var delta = this.positionAbs.top - this.lastPositionAbs.top;
4090     return delta !== 0 && (delta > 0 ? "down" : "up");
4091     },
4092    
4093     _getDragHorizontalDirection: function() {
4094     var delta = this.positionAbs.left - this.lastPositionAbs.left;
4095     return delta !== 0 && (delta > 0 ? "right" : "left");
4096     },
4097    
4098     refresh: function(event) {
4099     this._refreshItems(event);
4100     this.refreshPositions();
4101     return this;
4102     },
4103    
4104     _connectWith: function() {
4105     var options = this.options;
4106     return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4107     },
4108    
4109     _getItemsAsjQuery: function(connected) {
4110    
4111     var i, j, cur, inst,
4112     items = [],
4113     queries = [],
4114     connectWith = this._connectWith();
4115    
4116     if(connectWith && connected) {
4117     for (i = connectWith.length - 1; i >= 0; i--){
4118     cur = $(connectWith[i]);
4119     for ( j = cur.length - 1; j >= 0; j--){
4120     inst = $.data(cur[j], this.widgetFullName);
4121     if(inst && inst !== this && !inst.options.disabled) {
4122     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]);
4123     }
4124     }
4125     }
4126     }
4127    
4128     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]);
4129    
4130     for (i = queries.length - 1; i >= 0; i--){
4131     queries[i][0].each(function() {
4132     items.push(this);
4133     });
4134     }
4135    
4136     return $(items);
4137    
4138     },
4139    
4140     _removeCurrentsFromItems: function() {
4141    
4142     var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4143    
4144     this.items = $.grep(this.items, function (item) {
4145     for (var j=0; j < list.length; j++) {
4146     if(list[j] === item.item[0]) {
4147     return false;
4148     }
4149     }
4150     return true;
4151     });
4152    
4153     },
4154    
4155     _refreshItems: function(event) {
4156    
4157     this.items = [];
4158     this.containers = [this];
4159    
4160     var i, j, cur, inst, targetData, _queries, item, queriesLength,
4161     items = this.items,
4162     queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4163     connectWith = this._connectWith();
4164    
4165     if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4166     for (i = connectWith.length - 1; i >= 0; i--){
4167     cur = $(connectWith[i]);
4168     for (j = cur.length - 1; j >= 0; j--){
4169     inst = $.data(cur[j], this.widgetFullName);
4170     if(inst && inst !== this && !inst.options.disabled) {
4171     queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4172     this.containers.push(inst);
4173     }
4174     }
4175     }
4176     }
4177    
4178     for (i = queries.length - 1; i >= 0; i--) {
4179     targetData = queries[i][1];
4180     _queries = queries[i][0];
4181    
4182     for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4183     item = $(_queries[j]);
4184    
4185     item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4186    
4187     items.push({
4188     item: item,
4189     instance: targetData,
4190     width: 0, height: 0,
4191     left: 0, top: 0
4192     });
4193     }
4194     }
4195    
4196     },
4197    
4198     refreshPositions: function(fast) {
4199    
4200     //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4201     if(this.offsetParent && this.helper) {
4202     this.offset.parent = this._getParentOffset();
4203     }
4204    
4205     var i, item, t, p;
4206    
4207     for (i = this.items.length - 1; i >= 0; i--){
4208     item = this.items[i];
4209    
4210     //We ignore calculating positions of all connected containers when we're not over them
4211     if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4212     continue;
4213     }
4214    
4215     t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4216    
4217     if (!fast) {
4218     item.width = t.outerWidth();
4219     item.height = t.outerHeight();
4220     }
4221    
4222     p = t.offset();
4223     item.left = p.left;
4224     item.top = p.top;
4225     }
4226    
4227     if(this.options.custom && this.options.custom.refreshContainers) {
4228     this.options.custom.refreshContainers.call(this);
4229     } else {
4230     for (i = this.containers.length - 1; i >= 0; i--){
4231     p = this.containers[i].element.offset();
4232     this.containers[i].containerCache.left = p.left;
4233     this.containers[i].containerCache.top = p.top;
4234     this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
4235     this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4236     }
4237     }
4238    
4239     return this;
4240     },
4241    
4242     _createPlaceholder: function(that) {
4243     that = that || this;
4244     var className,
4245     o = that.options;
4246    
4247     if(!o.placeholder || o.placeholder.constructor === String) {
4248     className = o.placeholder;
4249     o.placeholder = {
4250     element: function() {
4251    
4252     var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4253     element = $( "<" + nodeName + ">", that.document[0] )
4254     .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4255     .removeClass("ui-sortable-helper");
4256    
4257     if ( nodeName === "tr" ) {
4258     that.currentItem.children().each(function() {
4259     $( "<td>&#160;</td>", that.document[0] )
4260     .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4261     .appendTo( element );
4262     });
4263     } else if ( nodeName === "img" ) {
4264     element.attr( "src", that.currentItem.attr( "src" ) );
4265     }
4266    
4267     if ( !className ) {
4268     element.css( "visibility", "hidden" );
4269     }
4270    
4271     return element;
4272     },
4273     update: function(container, p) {
4274    
4275     // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4276     // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4277     if(className && !o.forcePlaceholderSize) {
4278     return;
4279     }
4280    
4281     //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
4282     if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4283     if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4284     }
4285     };
4286     }
4287    
4288     //Create the placeholder
4289     that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4290    
4291     //Append it after the actual current item
4292     that.currentItem.after(that.placeholder);
4293    
4294     //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4295     o.placeholder.update(that, that.placeholder);
4296    
4297     },
4298    
4299     _contactContainers: function(event) {
4300     var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4301     innermostContainer = null,
4302     innermostIndex = null;
4303    
4304     // get innermost container that intersects with item
4305     for (i = this.containers.length - 1; i >= 0; i--) {
4306    
4307     // never consider a container that's located within the item itself
4308     if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4309     continue;
4310     }
4311    
4312     if(this._intersectsWith(this.containers[i].containerCache)) {
4313    
4314     // if we've already found a container and it's more "inner" than this, then continue
4315     if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4316     continue;
4317     }
4318    
4319     innermostContainer = this.containers[i];
4320     innermostIndex = i;
4321    
4322     } else {
4323     // container doesn't intersect. trigger "out" event if necessary
4324     if(this.containers[i].containerCache.over) {
4325     this.containers[i]._trigger("out", event, this._uiHash(this));
4326     this.containers[i].containerCache.over = 0;
4327     }
4328     }
4329    
4330     }
4331    
4332     // if no intersecting containers found, return
4333     if(!innermostContainer) {
4334     return;
4335     }
4336    
4337     // move the item into the container if it's not there already
4338     if(this.containers.length === 1) {
4339     if (!this.containers[innermostIndex].containerCache.over) {
4340     this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4341     this.containers[innermostIndex].containerCache.over = 1;
4342     }
4343     } else {
4344    
4345     //When entering a new container, we will find the item with the least distance and append our item near it
4346     dist = 10000;
4347     itemWithLeastDistance = null;
4348     floating = innermostContainer.floating || isFloating(this.currentItem);
4349     posProperty = floating ? "left" : "top";
4350     sizeProperty = floating ? "width" : "height";
4351     base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4352     for (j = this.items.length - 1; j >= 0; j--) {
4353     if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4354     continue;
4355     }
4356     if(this.items[j].item[0] === this.currentItem[0]) {
4357     continue;
4358     }
4359     if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4360     continue;
4361     }
4362     cur = this.items[j].item.offset()[posProperty];
4363     nearBottom = false;
4364     if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4365     nearBottom = true;
4366     cur += this.items[j][sizeProperty];
4367     }
4368    
4369     if(Math.abs(cur - base) < dist) {
4370     dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4371     this.direction = nearBottom ? "up": "down";
4372     }
4373     }
4374    
4375     //Check if dropOnEmpty is enabled
4376     if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4377     return;
4378     }
4379    
4380     if(this.currentContainer === this.containers[innermostIndex]) {
4381     return;
4382     }
4383    
4384     itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4385     this._trigger("change", event, this._uiHash());
4386     this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4387     this.currentContainer = this.containers[innermostIndex];
4388    
4389     //Update the placeholder
4390     this.options.placeholder.update(this.currentContainer, this.placeholder);
4391    
4392     this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4393     this.containers[innermostIndex].containerCache.over = 1;
4394     }
4395    
4396    
4397     },
4398    
4399     _createHelper: function(event) {
4400    
4401     var o = this.options,
4402     helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4403    
4404     //Add the helper to the DOM if that didn't happen already
4405     if(!helper.parents("body").length) {
4406     $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4407     }
4408    
4409     if(helper[0] === this.currentItem[0]) {
4410     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") };
4411     }
4412    
4413     if(!helper[0].style.width || o.forceHelperSize) {
4414     helper.width(this.currentItem.width());
4415     }
4416     if(!helper[0].style.height || o.forceHelperSize) {
4417     helper.height(this.currentItem.height());
4418     }
4419    
4420     return helper;
4421    
4422     },
4423    
4424     _adjustOffsetFromHelper: function(obj) {
4425     if (typeof obj === "string") {
4426     obj = obj.split(" ");
4427     }
4428     if ($.isArray(obj)) {
4429     obj = {left: +obj[0], top: +obj[1] || 0};
4430     }
4431     if ("left" in obj) {
4432     this.offset.click.left = obj.left + this.margins.left;
4433     }
4434     if ("right" in obj) {
4435     this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4436     }
4437     if ("top" in obj) {
4438     this.offset.click.top = obj.top + this.margins.top;
4439     }
4440     if ("bottom" in obj) {
4441     this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4442     }
4443     },
4444    
4445     _getParentOffset: function() {
4446    
4447    
4448     //Get the offsetParent and cache its position
4449     this.offsetParent = this.helper.offsetParent();
4450     var po = this.offsetParent.offset();
4451    
4452     // This is a special case where we need to modify a offset calculated on start, since the following happened:
4453     // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4454     // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4455     // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4456     if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4457     po.left += this.scrollParent.scrollLeft();
4458     po.top += this.scrollParent.scrollTop();
4459     }
4460    
4461     // This needs to be actually done for all browsers, since pageX/pageY includes this information
4462     // with an ugly IE fix
4463     if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4464     po = { top: 0, left: 0 };
4465     }
4466    
4467     return {
4468     top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4469     left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4470     };
4471    
4472     },
4473    
4474     _getRelativeOffset: function() {
4475    
4476     if(this.cssPosition === "relative") {
4477     var p = this.currentItem.position();
4478     return {
4479     top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4480     left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4481     };
4482     } else {
4483     return { top: 0, left: 0 };
4484     }
4485    
4486     },
4487    
4488     _cacheMargins: function() {
4489     this.margins = {
4490     left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4491     top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4492     };
4493     },
4494    
4495     _cacheHelperProportions: function() {
4496     this.helperProportions = {
4497     width: this.helper.outerWidth(),
4498     height: this.helper.outerHeight()
4499     };
4500     },
4501    
4502     _setContainment: function() {
4503    
4504     var ce, co, over,
4505     o = this.options;
4506     if(o.containment === "parent") {
4507     o.containment = this.helper[0].parentNode;
4508     }
4509     if(o.containment === "document" || o.containment === "window") {
4510     this.containment = [
4511     0 - this.offset.relative.left - this.offset.parent.left,
4512     0 - this.offset.relative.top - this.offset.parent.top,
4513     $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4514     ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4515     ];
4516     }
4517    
4518     if(!(/^(document|window|parent)$/).test(o.containment)) {
4519     ce = $(o.containment)[0];
4520     co = $(o.containment).offset();
4521     over = ($(ce).css("overflow") !== "hidden");
4522    
4523     this.containment = [
4524     co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4525     co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4526     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,
4527     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
4528     ];
4529     }
4530    
4531     },
4532    
4533     _convertPositionTo: function(d, pos) {
4534    
4535     if(!pos) {
4536     pos = this.position;
4537     }
4538     var mod = d === "absolute" ? 1 : -1,
4539     scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4540     scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4541    
4542     return {
4543     top: (
4544     pos.top + // The absolute mouse position
4545     this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
4546     this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
4547     ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4548     ),
4549     left: (
4550     pos.left + // The absolute mouse position
4551     this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
4552     this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
4553     ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4554     )
4555     };
4556    
4557     },
4558    
4559     _generatePosition: function(event) {
4560    
4561     var top, left,
4562     o = this.options,
4563     pageX = event.pageX,
4564     pageY = event.pageY,
4565     scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4566    
4567     // This is another very weird special case that only happens for relative elements:
4568     // 1. If the css position is relative
4569     // 2. and the scroll parent is the document or similar to the offset parent
4570     // we have to refresh the relative offset during the scroll so there are no jumps
4571     if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
4572     this.offset.relative = this._getRelativeOffset();
4573     }
4574    
4575     /*
4576     * - Position constraining -
4577     * Constrain the position to a mix of grid, containment.
4578     */
4579    
4580     if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4581    
4582     if(this.containment) {
4583     if(event.pageX - this.offset.click.left < this.containment[0]) {
4584     pageX = this.containment[0] + this.offset.click.left;
4585     }
4586     if(event.pageY - this.offset.click.top < this.containment[1]) {
4587     pageY = this.containment[1] + this.offset.click.top;
4588     }
4589     if(event.pageX - this.offset.click.left > this.containment[2]) {
4590     pageX = this.containment[2] + this.offset.click.left;
4591     }
4592     if(event.pageY - this.offset.click.top > this.containment[3]) {
4593     pageY = this.containment[3] + this.offset.click.top;
4594     }
4595     }
4596    
4597     if(o.grid) {
4598     top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4599     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;
4600    
4601     left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4602     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;
4603     }
4604    
4605     }
4606    
4607     return {
4608     top: (
4609     pageY - // The absolute mouse position
4610     this.offset.click.top - // Click offset (relative to the element)
4611     this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
4612     this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
4613     ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4614     ),
4615     left: (
4616     pageX - // The absolute mouse position
4617     this.offset.click.left - // Click offset (relative to the element)
4618     this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
4619     this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
4620     ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4621     )
4622     };
4623    
4624     },
4625    
4626     _rearrange: function(event, i, a, hardRefresh) {
4627    
4628     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));
4629    
4630     //Various things done here to improve the performance:
4631     // 1. we create a setTimeout, that calls refreshPositions
4632     // 2. on the instance, we have a counter variable, that get's higher after every append
4633     // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4634     // 4. this lets only the last addition to the timeout stack through
4635     this.counter = this.counter ? ++this.counter : 1;
4636     var counter = this.counter;
4637    
4638     this._delay(function() {
4639     if(counter === this.counter) {
4640     this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4641     }
4642     });
4643    
4644     },
4645    
4646     _clear: function(event, noPropagation) {
4647    
4648     this.reverting = false;
4649     // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4650     // everything else normalized again
4651     var i,
4652     delayedTriggers = [];
4653    
4654     // We first have to update the dom position of the actual currentItem
4655     // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4656     if(!this._noFinalSort && this.currentItem.parent().length) {
4657     this.placeholder.before(this.currentItem);
4658     }
4659     this._noFinalSort = null;
4660    
4661     if(this.helper[0] === this.currentItem[0]) {
4662     for(i in this._storedCSS) {
4663     if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4664     this._storedCSS[i] = "";
4665     }
4666     }
4667     this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4668     } else {
4669     this.currentItem.show();
4670     }
4671    
4672     if(this.fromOutside && !noPropagation) {
4673     delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4674     }
4675     if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4676     delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4677     }
4678    
4679     // Check if the items Container has Changed and trigger appropriate
4680     // events.
4681     if (this !== this.currentContainer) {
4682     if(!noPropagation) {
4683     delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4684     delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
4685     delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
4686     }
4687     }
4688    
4689    
4690     //Post events to containers
4691     for (i = this.containers.length - 1; i >= 0; i--){
4692     if(!noPropagation) {
4693     delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4694     }
4695     if(this.containers[i].containerCache.over) {
4696     delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
4697     this.containers[i].containerCache.over = 0;
4698     }
4699     }
4700    
4701     //Do what was originally in plugins
4702     if ( this.storedCursor ) {
4703     this.document.find( "body" ).css( "cursor", this.storedCursor );
4704     this.storedStylesheet.remove();
4705     }
4706     if(this._storedOpacity) {
4707     this.helper.css("opacity", this._storedOpacity);
4708     }
4709     if(this._storedZIndex) {
4710     this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4711     }
4712    
4713     this.dragging = false;
4714     if(this.cancelHelperRemoval) {
4715     if(!noPropagation) {
4716     this._trigger("beforeStop", event, this._uiHash());
4717     for (i=0; i < delayedTriggers.length; i++) {
4718     delayedTriggers[i].call(this, event);
4719     } //Trigger all delayed events
4720     this._trigger("stop", event, this._uiHash());
4721     }
4722    
4723     this.fromOutside = false;
4724     return false;
4725     }
4726    
4727     if(!noPropagation) {
4728     this._trigger("beforeStop", event, this._uiHash());
4729     }
4730    
4731     //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4732     this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4733    
4734     if(this.helper[0] !== this.currentItem[0]) {
4735     this.helper.remove();
4736     }
4737     this.helper = null;
4738    
4739     if(!noPropagation) {
4740     for (i=0; i < delayedTriggers.length; i++) {
4741     delayedTriggers[i].call(this, event);
4742     } //Trigger all delayed events
4743     this._trigger("stop", event, this._uiHash());
4744     }
4745    
4746     this.fromOutside = false;
4747     return true;
4748    
4749     },
4750    
4751     _trigger: function() {
4752     if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4753     this.cancel();
4754     }
4755     },
4756    
4757     _uiHash: function(_inst) {
4758     var inst = _inst || this;
4759     return {
4760     helper: inst.helper,
4761     placeholder: inst.placeholder || $([]),
4762     position: inst.position,
4763     originalPosition: inst.originalPosition,
4764     offset: inst.positionAbs,
4765     item: inst.currentItem,
4766     sender: _inst ? _inst.element : null
4767     };
4768     }
4769    
4770     });
4771    
4772     })(jQuery);
4773    
4774     (function($, undefined) {
4775    
4776     var dataSpace = "ui-effects-";
4777    
4778     $.effects = {
4779     effect: {}
4780     };
4781    
4782     /*!
4783     * jQuery Color Animations v2.1.2
4784     * https://github.com/jquery/jquery-color
4785     *
4786     * Copyright 2013 jQuery Foundation and other contributors
4787     * Released under the MIT license.
4788     * http://jquery.org/license
4789     *
4790     * Date: Wed Jan 16 08:47:09 2013 -0600
4791     */
4792     (function( jQuery, undefined ) {
4793    
4794     var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
4795    
4796     // plusequals test for += 100 -= 100
4797     rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4798     // a set of RE's that can match strings and generate color tuples.
4799     stringParsers = [{
4800     re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4801     parse: function( execResult ) {
4802     return [
4803     execResult[ 1 ],
4804     execResult[ 2 ],
4805     execResult[ 3 ],
4806     execResult[ 4 ]
4807     ];
4808     }
4809     }, {
4810     re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4811     parse: function( execResult ) {
4812     return [
4813     execResult[ 1 ] * 2.55,
4814     execResult[ 2 ] * 2.55,
4815     execResult[ 3 ] * 2.55,
4816     execResult[ 4 ]
4817     ];
4818     }
4819     }, {
4820     // this regex ignores A-F because it's compared against an already lowercased string
4821     re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4822     parse: function( execResult ) {
4823     return [
4824     parseInt( execResult[ 1 ], 16 ),
4825     parseInt( execResult[ 2 ], 16 ),
4826     parseInt( execResult[ 3 ], 16 )
4827     ];
4828     }
4829     }, {
4830     // this regex ignores A-F because it's compared against an already lowercased string
4831     re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4832     parse: function( execResult ) {
4833     return [
4834     parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4835     parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4836     parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4837     ];
4838     }
4839     }, {
4840     re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4841     space: "hsla",
4842     parse: function( execResult ) {
4843     return [
4844     execResult[ 1 ],
4845     execResult[ 2 ] / 100,
4846     execResult[ 3 ] / 100,
4847     execResult[ 4 ]
4848     ];
4849     }
4850     }],
4851    
4852     // jQuery.Color( )
4853     color = jQuery.Color = function( color, green, blue, alpha ) {
4854     return new jQuery.Color.fn.parse( color, green, blue, alpha );
4855     },
4856     spaces = {
4857     rgba: {
4858     props: {
4859     red: {
4860     idx: 0,
4861     type: "byte"
4862     },
4863     green: {
4864     idx: 1,
4865     type: "byte"
4866     },
4867     blue: {
4868     idx: 2,
4869     type: "byte"
4870     }
4871     }
4872     },
4873    
4874     hsla: {
4875     props: {
4876     hue: {
4877     idx: 0,
4878     type: "degrees"
4879     },
4880     saturation: {
4881     idx: 1,
4882     type: "percent"
4883     },
4884     lightness: {
4885     idx: 2,
4886     type: "percent"
4887     }
4888     }
4889     }
4890     },
4891     propTypes = {
4892     "byte": {
4893     floor: true,
4894     max: 255
4895     },
4896     "percent": {
4897     max: 1
4898     },
4899     "degrees": {
4900     mod: 360,
4901     floor: true
4902     }
4903     },
4904     support = color.support = {},
4905    
4906     // element for support tests
4907     supportElem = jQuery( "<p>" )[ 0 ],
4908    
4909     // colors = jQuery.Color.names
4910     colors,
4911    
4912     // local aliases of functions called often
4913     each = jQuery.each;
4914    
4915     // determine rgba support immediately
4916     supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4917     support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4918    
4919     // define cache name and alpha properties
4920     // for rgba and hsla spaces
4921     each( spaces, function( spaceName, space ) {
4922     space.cache = "_" + spaceName;
4923     space.props.alpha = {
4924     idx: 3,
4925     type: "percent",
4926     def: 1
4927     };
4928     });
4929    
4930     function clamp( value, prop, allowEmpty ) {
4931     var type = propTypes[ prop.type ] || {};
4932    
4933     if ( value == null ) {
4934     return (allowEmpty || !prop.def) ? null : prop.def;
4935     }
4936    
4937     // ~~ is an short way of doing floor for positive numbers
4938     value = type.floor ? ~~value : parseFloat( value );
4939    
4940     // IE will pass in empty strings as value for alpha,
4941     // which will hit this case
4942     if ( isNaN( value ) ) {
4943     return prop.def;
4944     }
4945    
4946     if ( type.mod ) {
4947     // we add mod before modding to make sure that negatives values
4948     // get converted properly: -10 -> 350
4949     return (value + type.mod) % type.mod;
4950     }
4951    
4952     // for now all property types without mod have min and max
4953     return 0 > value ? 0 : type.max < value ? type.max : value;
4954     }
4955    
4956     function stringParse( string ) {
4957     var inst = color(),
4958     rgba = inst._rgba = [];
4959    
4960     string = string.toLowerCase();
4961    
4962     each( stringParsers, function( i, parser ) {
4963     var parsed,
4964     match = parser.re.exec( string ),
4965     values = match && parser.parse( match ),
4966     spaceName = parser.space || "rgba";
4967    
4968     if ( values ) {
4969     parsed = inst[ spaceName ]( values );
4970    
4971     // if this was an rgba parse the assignment might happen twice
4972     // oh well....
4973     inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
4974     rgba = inst._rgba = parsed._rgba;
4975    
4976     // exit each( stringParsers ) here because we matched
4977     return false;
4978     }
4979     });
4980    
4981     // Found a stringParser that handled it
4982     if ( rgba.length ) {
4983    
4984     // if this came from a parsed string, force "transparent" when alpha is 0
4985     // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
4986     if ( rgba.join() === "0,0,0,0" ) {
4987     jQuery.extend( rgba, colors.transparent );
4988     }
4989     return inst;
4990     }
4991    
4992     // named colors
4993     return colors[ string ];
4994     }
4995    
4996     color.fn = jQuery.extend( color.prototype, {
4997     parse: function( red, green, blue, alpha ) {
4998     if ( red === undefined ) {
4999     this._rgba = [ null, null, null, null ];
5000     return this;
5001     }
5002     if ( red.jquery || red.nodeType ) {
5003     red = jQuery( red ).css( green );
5004     green = undefined;
5005     }
5006    
5007     var inst = this,
5008     type = jQuery.type( red ),
5009     rgba = this._rgba = [];
5010    
5011     // more than 1 argument specified - assume ( red, green, blue, alpha )
5012     if ( green !== undefined ) {
5013     red = [ red, green, blue, alpha ];
5014     type = "array";
5015     }
5016    
5017     if ( type === "string" ) {
5018     return this.parse( stringParse( red ) || colors._default );
5019     }
5020    
5021     if ( type === "array" ) {
5022     each( spaces.rgba.props, function( key, prop ) {
5023     rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
5024     });
5025     return this;
5026     }
5027    
5028     if ( type === "object" ) {
5029     if ( red instanceof color ) {
5030     each( spaces, function( spaceName, space ) {
5031     if ( red[ space.cache ] ) {
5032     inst[ space.cache ] = red[ space.cache ].slice();
5033     }
5034     });
5035     } else {
5036     each( spaces, function( spaceName, space ) {
5037     var cache = space.cache;
5038     each( space.props, function( key, prop ) {
5039    
5040     // if the cache doesn't exist, and we know how to convert
5041     if ( !inst[ cache ] && space.to ) {
5042    
5043     // if the value was null, we don't need to copy it
5044     // if the key was alpha, we don't need to copy it either
5045     if ( key === "alpha" || red[ key ] == null ) {
5046     return;
5047     }
5048     inst[ cache ] = space.to( inst._rgba );
5049     }
5050    
5051     // this is the only case where we allow nulls for ALL properties.
5052     // call clamp with alwaysAllowEmpty
5053     inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
5054     });
5055    
5056     // everything defined but alpha?
5057     if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
5058     // use the default of 1
5059     inst[ cache ][ 3 ] = 1;
5060     if ( space.from ) {
5061     inst._rgba = space.from( inst[ cache ] );
5062     }
5063     }
5064     });
5065     }
5066     return this;
5067     }
5068     },
5069     is: function( compare ) {
5070     var is = color( compare ),
5071     same = true,
5072     inst = this;
5073    
5074     each( spaces, function( _, space ) {
5075     var localCache,
5076     isCache = is[ space.cache ];
5077     if (isCache) {
5078     localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
5079     each( space.props, function( _, prop ) {
5080     if ( isCache[ prop.idx ] != null ) {
5081     same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
5082     return same;
5083     }
5084     });
5085     }
5086     return same;
5087     });
5088     return same;
5089     },
5090     _space: function() {
5091     var used = [],
5092     inst = this;
5093     each( spaces, function( spaceName, space ) {
5094     if ( inst[ space.cache ] ) {
5095     used.push( spaceName );
5096     }
5097     });
5098     return used.pop();
5099     },
5100     transition: function( other, distance ) {
5101     var end = color( other ),
5102     spaceName = end._space(),
5103     space = spaces[ spaceName ],
5104     startColor = this.alpha() === 0 ? color( "transparent" ) : this,
5105     start = startColor[ space.cache ] || space.to( startColor._rgba ),
5106     result = start.slice();
5107    
5108     end = end[ space.cache ];
5109     each( space.props, function( key, prop ) {
5110     var index = prop.idx,
5111     startValue = start[ index ],
5112     endValue = end[ index ],
5113     type = propTypes[ prop.type ] || {};
5114    
5115     // if null, don't override start value
5116     if ( endValue === null ) {
5117     return;
5118     }
5119     // if null - use end
5120     if ( startValue === null ) {
5121     result[ index ] = endValue;
5122     } else {
5123     if ( type.mod ) {
5124     if ( endValue - startValue > type.mod / 2 ) {
5125     startValue += type.mod;
5126     } else if ( startValue - endValue > type.mod / 2 ) {
5127     startValue -= type.mod;
5128     }
5129     }
5130     result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
5131     }
5132     });
5133     return this[ spaceName ]( result );
5134     },
5135     blend: function( opaque ) {
5136     // if we are already opaque - return ourself
5137     if ( this._rgba[ 3 ] === 1 ) {
5138     return this;
5139     }
5140    
5141     var rgb = this._rgba.slice(),
5142     a = rgb.pop(),
5143     blend = color( opaque )._rgba;
5144    
5145     return color( jQuery.map( rgb, function( v, i ) {
5146     return ( 1 - a ) * blend[ i ] + a * v;
5147     }));
5148     },
5149     toRgbaString: function() {
5150     var prefix = "rgba(",
5151     rgba = jQuery.map( this._rgba, function( v, i ) {
5152     return v == null ? ( i > 2 ? 1 : 0 ) : v;
5153     });
5154    
5155     if ( rgba[ 3 ] === 1 ) {
5156     rgba.pop();
5157     prefix = "rgb(";
5158     }
5159    
5160     return prefix + rgba.join() + ")";
5161     },
5162     toHslaString: function() {
5163     var prefix = "hsla(",
5164     hsla = jQuery.map( this.hsla(), function( v, i ) {
5165     if ( v == null ) {
5166     v = i > 2 ? 1 : 0;
5167     }
5168    
5169     // catch 1 and 2
5170     if ( i && i < 3 ) {
5171     v = Math.round( v * 100 ) + "%";
5172     }
5173     return v;
5174     });
5175    
5176     if ( hsla[ 3 ] === 1 ) {
5177     hsla.pop();
5178     prefix = "hsl(";
5179     }
5180     return prefix + hsla.join() + ")";
5181     },
5182     toHexString: function( includeAlpha ) {
5183     var rgba = this._rgba.slice(),
5184     alpha = rgba.pop();
5185    
5186     if ( includeAlpha ) {
5187     rgba.push( ~~( alpha * 255 ) );
5188     }
5189    
5190     return "#" + jQuery.map( rgba, function( v ) {
5191    
5192     // default to 0 when nulls exist
5193     v = ( v || 0 ).toString( 16 );
5194     return v.length === 1 ? "0" + v : v;
5195     }).join("");
5196     },
5197     toString: function() {
5198     return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
5199     }
5200     });
5201     color.fn.parse.prototype = color.fn;
5202    
5203     // hsla conversions adapted from:
5204     // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
5205    
5206     function hue2rgb( p, q, h ) {
5207     h = ( h + 1 ) % 1;
5208     if ( h * 6 < 1 ) {
5209     return p + (q - p) * h * 6;
5210     }
5211     if ( h * 2 < 1) {
5212     return q;
5213     }
5214     if ( h * 3 < 2 ) {
5215     return p + (q - p) * ((2/3) - h) * 6;
5216     }
5217     return p;
5218     }
5219    
5220     spaces.hsla.to = function ( rgba ) {
5221     if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
5222     return [ null, null, null, rgba[ 3 ] ];
5223     }
5224     var r = rgba[ 0 ] / 255,
5225     g = rgba[ 1 ] / 255,
5226     b = rgba[ 2 ] / 255,
5227     a = rgba[ 3 ],
5228     max = Math.max( r, g, b ),
5229     min = Math.min( r, g, b ),
5230     diff = max - min,
5231     add = max + min,
5232     l = add * 0.5,
5233     h, s;
5234    
5235     if ( min === max ) {
5236     h = 0;
5237     } else if ( r === max ) {
5238     h = ( 60 * ( g - b ) / diff ) + 360;
5239     } else if ( g === max ) {
5240     h = ( 60 * ( b - r ) / diff ) + 120;
5241     } else {
5242     h = ( 60 * ( r - g ) / diff ) + 240;
5243     }
5244    
5245     // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
5246     // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
5247     if ( diff === 0 ) {
5248     s = 0;
5249     } else if ( l <= 0.5 ) {
5250     s = diff / add;
5251     } else {
5252     s = diff / ( 2 - add );
5253     }
5254     return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
5255     };
5256    
5257     spaces.hsla.from = function ( hsla ) {
5258     if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
5259     return [ null, null, null, hsla[ 3 ] ];
5260     }
5261     var h = hsla[ 0 ] / 360,
5262     s = hsla[ 1 ],
5263     l = hsla[ 2 ],
5264     a = hsla[ 3 ],
5265     q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
5266     p = 2 * l - q;
5267    
5268     return [
5269     Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
5270     Math.round( hue2rgb( p, q, h ) * 255 ),
5271     Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
5272     a
5273     ];
5274     };
5275    
5276    
5277     each( spaces, function( spaceName, space ) {
5278     var props = space.props,
5279     cache = space.cache,
5280     to = space.to,
5281     from = space.from;
5282    
5283     // makes rgba() and hsla()
5284     color.fn[ spaceName ] = function( value ) {
5285    
5286     // generate a cache for this space if it doesn't exist
5287     if ( to && !this[ cache ] ) {
5288     this[ cache ] = to( this._rgba );
5289     }
5290     if ( value === undefined ) {
5291     return this[ cache ].slice();
5292     }
5293    
5294     var ret,
5295     type = jQuery.type( value ),
5296     arr = ( type === "array" || type === "object" ) ? value : arguments,
5297     local = this[ cache ].slice();
5298    
5299     each( props, function( key, prop ) {
5300     var val = arr[ type === "object" ? key : prop.idx ];
5301     if ( val == null ) {
5302     val = local[ prop.idx ];
5303     }
5304     local[ prop.idx ] = clamp( val, prop );
5305     });
5306    
5307     if ( from ) {
5308     ret = color( from( local ) );
5309     ret[ cache ] = local;
5310     return ret;
5311     } else {
5312     return color( local );
5313     }
5314     };
5315    
5316     // makes red() green() blue() alpha() hue() saturation() lightness()
5317     each( props, function( key, prop ) {
5318     // alpha is included in more than one space
5319     if ( color.fn[ key ] ) {
5320     return;
5321     }
5322     color.fn[ key ] = function( value ) {
5323     var vtype = jQuery.type( value ),
5324     fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
5325     local = this[ fn ](),
5326     cur = local[ prop.idx ],
5327     match;
5328    
5329     if ( vtype === "undefined" ) {
5330     return cur;
5331     }
5332    
5333     if ( vtype === "function" ) {
5334     value = value.call( this, cur );
5335     vtype = jQuery.type( value );
5336     }
5337     if ( value == null && prop.empty ) {
5338     return this;
5339     }
5340     if ( vtype === "string" ) {
5341     match = rplusequals.exec( value );
5342     if ( match ) {
5343     value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
5344     }
5345     }
5346     local[ prop.idx ] = value;
5347     return this[ fn ]( local );
5348     };
5349     });
5350     });
5351    
5352     // add cssHook and .fx.step function for each named hook.
5353     // accept a space separated string of properties
5354     color.hook = function( hook ) {
5355     var hooks = hook.split( " " );
5356     each( hooks, function( i, hook ) {
5357     jQuery.cssHooks[ hook ] = {
5358     set: function( elem, value ) {
5359     var parsed, curElem,
5360     backgroundColor = "";
5361    
5362     if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
5363     value = color( parsed || value );
5364     if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
5365     curElem = hook === "backgroundColor" ? elem.parentNode : elem;
5366     while (
5367     (backgroundColor === "" || backgroundColor === "transparent") &&
5368     curElem && curElem.style
5369     ) {
5370     try {
5371     backgroundColor = jQuery.css( curElem, "backgroundColor" );
5372     curElem = curElem.parentNode;
5373     } catch ( e ) {
5374     }
5375     }
5376    
5377     value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
5378     backgroundColor :
5379     "_default" );
5380     }
5381    
5382     value = value.toRgbaString();
5383     }
5384     try {
5385     elem.style[ hook ] = value;
5386     } catch( e ) {
5387     // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
5388     }
5389     }
5390     };
5391     jQuery.fx.step[ hook ] = function( fx ) {
5392     if ( !fx.colorInit ) {
5393     fx.start = color( fx.elem, hook );
5394     fx.end = color( fx.end );
5395     fx.colorInit = true;
5396     }
5397     jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
5398     };
5399     });
5400    
5401     };
5402    
5403     color.hook( stepHooks );
5404    
5405     jQuery.cssHooks.borderColor = {
5406     expand: function( value ) {
5407     var expanded = {};
5408    
5409     each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
5410     expanded[ "border" + part + "Color" ] = value;
5411     });
5412     return expanded;
5413     }
5414     };
5415    
5416     // Basic color names only.
5417     // Usage of any of the other color names requires adding yourself or including
5418     // jquery.color.svg-names.js.
5419     colors = jQuery.Color.names = {
5420     // 4.1. Basic color keywords
5421     aqua: "#00ffff",
5422     black: "#000000",
5423     blue: "#0000ff",
5424     fuchsia: "#ff00ff",
5425     gray: "#808080",
5426     green: "#008000",
5427     lime: "#00ff00",
5428     maroon: "#800000",
5429     navy: "#000080",
5430     olive: "#808000",
5431     purple: "#800080",
5432     red: "#ff0000",
5433     silver: "#c0c0c0",
5434     teal: "#008080",
5435     white: "#ffffff",
5436     yellow: "#ffff00",
5437    
5438     // 4.2.3. "transparent" color keyword
5439     transparent: [ null, null, null, 0 ],
5440    
5441     _default: "#ffffff"
5442     };
5443    
5444     })( jQuery );
5445    
5446    
5447     /******************************************************************************/
5448     /****************************** CLASS ANIMATIONS ******************************/
5449     /******************************************************************************/
5450     (function() {
5451    
5452     var classAnimationActions = [ "add", "remove", "toggle" ],
5453     shorthandStyles = {
5454     border: 1,
5455     borderBottom: 1,
5456     borderColor: 1,
5457     borderLeft: 1,
5458     borderRight: 1,
5459     borderTop: 1,
5460     borderWidth: 1,
5461     margin: 1,
5462     padding: 1
5463     };
5464    
5465     $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
5466     $.fx.step[ prop ] = function( fx ) {
5467     if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
5468     jQuery.style( fx.elem, prop, fx.end );
5469     fx.setAttr = true;
5470     }
5471     };
5472     });
5473    
5474     function getElementStyles( elem ) {
5475     var key, len,
5476     style = elem.ownerDocument.defaultView ?
5477     elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
5478     elem.currentStyle,
5479     styles = {};
5480    
5481     if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
5482     len = style.length;
5483     while ( len-- ) {
5484     key = style[ len ];
5485     if ( typeof style[ key ] === "string" ) {
5486     styles[ $.camelCase( key ) ] = style[ key ];
5487     }
5488     }
5489     // support: Opera, IE <9
5490     } else {
5491     for ( key in style ) {
5492     if ( typeof style[ key ] === "string" ) {
5493     styles[ key ] = style[ key ];
5494     }
5495     }
5496     }
5497    
5498     return styles;
5499     }
5500    
5501    
5502     function styleDifference( oldStyle, newStyle ) {
5503     var diff = {},
5504     name, value;
5505    
5506     for ( name in newStyle ) {
5507     value = newStyle[ name ];
5508     if ( oldStyle[ name ] !== value ) {
5509     if ( !shorthandStyles[ name ] ) {
5510     if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
5511     diff[ name ] = value;
5512     }
5513     }
5514     }
5515     }
5516    
5517     return diff;
5518     }
5519    
5520     // support: jQuery <1.8
5521     if ( !$.fn.addBack ) {
5522     $.fn.addBack = function( selector ) {
5523     return this.add( selector == null ?
5524     this.prevObject : this.prevObject.filter( selector )
5525     );
5526     };
5527     }
5528    
5529     $.effects.animateClass = function( value, duration, easing, callback ) {
5530     var o = $.speed( duration, easing, callback );
5531    
5532     return this.queue( function() {
5533     var animated = $( this ),
5534     baseClass = animated.attr( "class" ) || "",
5535     applyClassChange,
5536     allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
5537    
5538     // map the animated objects to store the original styles.
5539     allAnimations = allAnimations.map(function() {
5540     var el = $( this );
5541     return {
5542     el: el,
5543     start: getElementStyles( this )
5544     };
5545     });
5546    
5547     // apply class change
5548     applyClassChange = function() {
5549     $.each( classAnimationActions, function(i, action) {
5550     if ( value[ action ] ) {
5551     animated[ action + "Class" ]( value[ action ] );
5552     }
5553     });
5554     };
5555     applyClassChange();
5556    
5557     // map all animated objects again - calculate new styles and diff
5558     allAnimations = allAnimations.map(function() {
5559     this.end = getElementStyles( this.el[ 0 ] );
5560     this.diff = styleDifference( this.start, this.end );
5561     return this;
5562     });
5563    
5564     // apply original class
5565     animated.attr( "class", baseClass );
5566    
5567     // map all animated objects again - this time collecting a promise
5568     allAnimations = allAnimations.map(function() {
5569     var styleInfo = this,
5570     dfd = $.Deferred(),
5571     opts = $.extend({}, o, {
5572     queue: false,
5573     complete: function() {
5574     dfd.resolve( styleInfo );
5575     }
5576     });
5577    
5578     this.el.animate( this.diff, opts );
5579     return dfd.promise();
5580     });
5581    
5582     // once all animations have completed:
5583     $.when.apply( $, allAnimations.get() ).done(function() {
5584    
5585     // set the final class
5586     applyClassChange();
5587    
5588     // for each animated element,
5589     // clear all css properties that were animated
5590     $.each( arguments, function() {
5591     var el = this.el;
5592     $.each( this.diff, function(key) {
5593     el.css( key, "" );
5594     });
5595     });
5596    
5597     // this is guarnteed to be there if you use jQuery.speed()
5598     // it also handles dequeuing the next anim...
5599     o.complete.call( animated[ 0 ] );
5600     });
5601     });
5602     };
5603    
5604     $.fn.extend({
5605     addClass: (function( orig ) {
5606     return function( classNames, speed, easing, callback ) {
5607     return speed ?
5608     $.effects.animateClass.call( this,
5609     { add: classNames }, speed, easing, callback ) :
5610     orig.apply( this, arguments );
5611     };
5612     })( $.fn.addClass ),
5613    
5614     removeClass: (function( orig ) {
5615     return function( classNames, speed, easing, callback ) {
5616     return arguments.length > 1 ?
5617     $.effects.animateClass.call( this,
5618     { remove: classNames }, speed, easing, callback ) :
5619     orig.apply( this, arguments );
5620     };
5621     })( $.fn.removeClass ),
5622    
5623     toggleClass: (function( orig ) {
5624     return function( classNames, force, speed, easing, callback ) {
5625     if ( typeof force === "boolean" || force === undefined ) {
5626     if ( !speed ) {
5627     // without speed parameter
5628     return orig.apply( this, arguments );
5629     } else {
5630     return $.effects.animateClass.call( this,
5631     (force ? { add: classNames } : { remove: classNames }),
5632     speed, easing, callback );
5633     }
5634     } else {
5635     // without force parameter
5636     return $.effects.animateClass.call( this,
5637     { toggle: classNames }, force, speed, easing );
5638     }
5639     };
5640     })( $.fn.toggleClass ),
5641    
5642     switchClass: function( remove, add, speed, easing, callback) {
5643     return $.effects.animateClass.call( this, {
5644     add: add,
5645     remove: remove
5646     }, speed, easing, callback );
5647     }
5648     });
5649    
5650     })();
5651    
5652     /******************************************************************************/
5653     /*********************************** EFFECTS **********************************/
5654     /******************************************************************************/
5655    
5656     (function() {
5657    
5658     $.extend( $.effects, {
5659     version: "1.10.3",
5660    
5661     // Saves a set of properties in a data storage
5662     save: function( element, set ) {
5663     for( var i=0; i < set.length; i++ ) {
5664     if ( set[ i ] !== null ) {
5665     element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5666     }
5667     }
5668     },
5669    
5670     // Restores a set of previously saved properties from a data storage
5671     restore: function( element, set ) {
5672     var val, i;
5673     for( i=0; i < set.length; i++ ) {
5674     if ( set[ i ] !== null ) {
5675     val = element.data( dataSpace + set[ i ] );
5676     // support: jQuery 1.6.2
5677     // http://bugs.jquery.com/ticket/9917
5678     // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5679     // We can't differentiate between "" and 0 here, so we just assume
5680     // empty string since it's likely to be a more common value...
5681     if ( val === undefined ) {
5682     val = "";
5683     }
5684     element.css( set[ i ], val );
5685     }
5686     }
5687     },
5688    
5689     setMode: function( el, mode ) {
5690     if (mode === "toggle") {
5691     mode = el.is( ":hidden" ) ? "show" : "hide";
5692     }
5693     return mode;
5694     },
5695    
5696     // Translates a [top,left] array into a baseline value
5697     // this should be a little more flexible in the future to handle a string & hash
5698     getBaseline: function( origin, original ) {
5699     var y, x;
5700     switch ( origin[ 0 ] ) {
5701     case "top": y = 0; break;
5702     case "middle": y = 0.5; break;
5703     case "bottom": y = 1; break;
5704     default: y = origin[ 0 ] / original.height;
5705     }
5706     switch ( origin[ 1 ] ) {
5707     case "left": x = 0; break;
5708     case "center": x = 0.5; break;
5709     case "right": x = 1; break;
5710     default: x = origin[ 1 ] / original.width;
5711     }
5712     return {
5713     x: x,
5714     y: y
5715     };
5716     },
5717    
5718     // Wraps the element around a wrapper that copies position properties
5719     createWrapper: function( element ) {
5720    
5721     // if the element is already wrapped, return it
5722     if ( element.parent().is( ".ui-effects-wrapper" )) {
5723     return element.parent();
5724     }
5725    
5726     // wrap the element
5727     var props = {
5728     width: element.outerWidth(true),
5729     height: element.outerHeight(true),
5730     "float": element.css( "float" )
5731     },
5732     wrapper = $( "<div></div>" )
5733     .addClass( "ui-effects-wrapper" )
5734     .css({
5735     fontSize: "100%",
5736     background: "transparent",
5737     border: "none",
5738     margin: 0,
5739     padding: 0
5740     }),
5741     // Store the size in case width/height are defined in % - Fixes #5245
5742     size = {
5743     width: element.width(),
5744     height: element.height()
5745     },
5746     active = document.activeElement;
5747    
5748     // support: Firefox
5749     // Firefox incorrectly exposes anonymous content
5750     // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5751     try {
5752     active.id;
5753     } catch( e ) {
5754     active = document.body;
5755     }
5756    
5757     element.wrap( wrapper );
5758    
5759     // Fixes #7595 - Elements lose focus when wrapped.
5760     if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5761     $( active ).focus();
5762     }
5763    
5764     wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5765    
5766     // transfer positioning properties to the wrapper
5767     if ( element.css( "position" ) === "static" ) {
5768     wrapper.css({ position: "relative" });
5769     element.css({ position: "relative" });
5770     } else {
5771     $.extend( props, {
5772     position: element.css( "position" ),
5773     zIndex: element.css( "z-index" )
5774     });
5775     $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5776     props[ pos ] = element.css( pos );
5777     if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5778     props[ pos ] = "auto";
5779     }
5780     });
5781     element.css({
5782     position: "relative",
5783     top: 0,
5784     left: 0,
5785     right: "auto",
5786     bottom: "auto"
5787     });
5788     }
5789     element.css(size);
5790    
5791     return wrapper.css( props ).show();
5792     },
5793    
5794     removeWrapper: function( element ) {
5795     var active = document.activeElement;
5796    
5797     if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5798     element.parent().replaceWith( element );
5799    
5800     // Fixes #7595 - Elements lose focus when wrapped.
5801     if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5802     $( active ).focus();
5803     }
5804     }
5805    
5806    
5807     return element;
5808     },
5809    
5810     setTransition: function( element, list, factor, value ) {
5811     value = value || {};
5812     $.each( list, function( i, x ) {
5813     var unit = element.cssUnit( x );
5814     if ( unit[ 0 ] > 0 ) {
5815     value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5816     }
5817     });
5818     return value;
5819     }
5820     });
5821    
5822     // return an effect options object for the given parameters:
5823     function _normalizeArguments( effect, options, speed, callback ) {
5824    
5825     // allow passing all options as the first parameter
5826     if ( $.isPlainObject( effect ) ) {
5827     options = effect;
5828     effect = effect.effect;
5829     }
5830    
5831     // convert to an object
5832     effect = { effect: effect };
5833    
5834     // catch (effect, null, ...)
5835     if ( options == null ) {
5836     options = {};
5837     }
5838    
5839     // catch (effect, callback)
5840     if ( $.isFunction( options ) ) {
5841     callback = options;
5842     speed = null;
5843     options = {};
5844     }
5845    
5846     // catch (effect, speed, ?)
5847     if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5848     callback = speed;
5849     speed = options;
5850     options = {};
5851     }
5852    
5853     // catch (effect, options, callback)
5854     if ( $.isFunction( speed ) ) {
5855     callback = speed;
5856     speed = null;
5857     }
5858    
5859     // add options to effect
5860     if ( options ) {
5861     $.extend( effect, options );
5862     }
5863    
5864     speed = speed || options.duration;
5865     effect.duration = $.fx.off ? 0 :
5866     typeof speed === "number" ? speed :
5867     speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5868     $.fx.speeds._default;
5869    
5870     effect.complete = callback || options.complete;
5871    
5872     return effect;
5873     }
5874    
5875     function standardAnimationOption( option ) {
5876     // Valid standard speeds (nothing, number, named speed)
5877     if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
5878     return true;
5879     }
5880    
5881     // Invalid strings - treat as "normal" speed
5882     if ( typeof option === "string" && !$.effects.effect[ option ] ) {
5883     return true;
5884     }
5885    
5886     // Complete callback
5887     if ( $.isFunction( option ) ) {
5888     return true;
5889     }
5890    
5891     // Options hash (but not naming an effect)
5892     if ( typeof option === "object" && !option.effect ) {
5893     return true;
5894     }
5895    
5896     // Didn't match any standard API
5897     return false;
5898     }
5899    
5900     $.fn.extend({
5901     effect: function( /* effect, options, speed, callback */ ) {
5902     var args = _normalizeArguments.apply( this, arguments ),
5903     mode = args.mode,
5904     queue = args.queue,
5905     effectMethod = $.effects.effect[ args.effect ];
5906    
5907     if ( $.fx.off || !effectMethod ) {
5908     // delegate to the original method (e.g., .show()) if possible
5909     if ( mode ) {
5910     return this[ mode ]( args.duration, args.complete );
5911     } else {
5912     return this.each( function() {
5913     if ( args.complete ) {
5914     args.complete.call( this );
5915     }
5916     });
5917     }
5918     }
5919    
5920     function run( next ) {
5921     var elem = $( this ),
5922     complete = args.complete,
5923     mode = args.mode;
5924    
5925     function done() {
5926     if ( $.isFunction( complete ) ) {
5927     complete.call( elem[0] );
5928     }
5929     if ( $.isFunction( next ) ) {
5930     next();
5931     }
5932     }
5933    
5934     // If the element already has the correct final state, delegate to
5935     // the core methods so the internal tracking of "olddisplay" works.
5936     if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5937     elem[ mode ]();
5938     done();
5939     } else {
5940     effectMethod.call( elem[0], args, done );
5941     }
5942     }
5943    
5944     return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5945     },
5946    
5947     show: (function( orig ) {
5948     return function( option ) {
5949     if ( standardAnimationOption( option ) ) {
5950     return orig.apply( this, arguments );
5951     } else {
5952     var args = _normalizeArguments.apply( this, arguments );
5953     args.mode = "show";
5954     return this.effect.call( this, args );
5955     }
5956     };
5957     })( $.fn.show ),
5958    
5959     hide: (function( orig ) {
5960     return function( option ) {
5961     if ( standardAnimationOption( option ) ) {
5962     return orig.apply( this, arguments );
5963     } else {
5964     var args = _normalizeArguments.apply( this, arguments );
5965     args.mode = "hide";
5966     return this.effect.call( this, args );
5967     }
5968     };
5969     })( $.fn.hide ),
5970    
5971     toggle: (function( orig ) {
5972     return function( option ) {
5973     if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
5974     return orig.apply( this, arguments );
5975     } else {
5976     var args = _normalizeArguments.apply( this, arguments );
5977     args.mode = "toggle";
5978     return this.effect.call( this, args );
5979     }
5980     };
5981     })( $.fn.toggle ),
5982    
5983     // helper functions
5984     cssUnit: function(key) {
5985     var style = this.css( key ),
5986     val = [];
5987    
5988     $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
5989     if ( style.indexOf( unit ) > 0 ) {
5990     val = [ parseFloat( style ), unit ];
5991     }
5992     });
5993     return val;
5994     }
5995     });
5996    
5997     })();
5998    
5999     /******************************************************************************/
6000     /*********************************** EASING ***********************************/
6001     /******************************************************************************/
6002    
6003     (function() {
6004    
6005     // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
6006    
6007     var baseEasings = {};
6008    
6009     $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
6010     baseEasings[ name ] = function( p ) {
6011     return Math.pow( p, i + 2 );
6012     };
6013     });
6014    
6015     $.extend( baseEasings, {
6016     Sine: function ( p ) {
6017     return 1 - Math.cos( p * Math.PI / 2 );
6018     },
6019     Circ: function ( p ) {
6020     return 1 - Math.sqrt( 1 - p * p );
6021     },
6022     Elastic: function( p ) {
6023     return p === 0 || p === 1 ? p :
6024     -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
6025     },
6026     Back: function( p ) {
6027     return p * p * ( 3 * p - 2 );
6028     },
6029     Bounce: function ( p ) {
6030     var pow2,
6031     bounce = 4;
6032    
6033     while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
6034     return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
6035     }
6036     });
6037    
6038     $.each( baseEasings, function( name, easeIn ) {
6039     $.easing[ "easeIn" + name ] = easeIn;
6040     $.easing[ "easeOut" + name ] = function( p ) {
6041     return 1 - easeIn( 1 - p );
6042     };
6043     $.easing[ "easeInOut" + name ] = function( p ) {
6044     return p < 0.5 ?
6045     easeIn( p * 2 ) / 2 :
6046     1 - easeIn( p * -2 + 2 ) / 2;
6047     };
6048     });
6049    
6050     })();
6051    
6052     })(jQuery);
6053    
6054     (function( $, undefined ) {
6055    
6056     var uid = 0,
6057     hideProps = {},
6058     showProps = {};
6059    
6060     hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
6061     hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
6062     showProps.height = showProps.paddingTop = showProps.paddingBottom =
6063     showProps.borderTopWidth = showProps.borderBottomWidth = "show";
6064    
6065     $.widget( "ui.accordion", {
6066     version: "1.10.3",
6067     options: {
6068     active: 0,
6069     animate: {},
6070     collapsible: false,
6071     event: "click",
6072     header: "> li > :first-child,> :not(li):even",
6073     heightStyle: "auto",
6074     icons: {
6075     activeHeader: "ui-icon-triangle-1-s",
6076     header: "ui-icon-triangle-1-e"
6077     },
6078    
6079     // callbacks
6080     activate: null,
6081     beforeActivate: null
6082     },
6083    
6084     _create: function() {
6085     var options = this.options;
6086     this.prevShow = this.prevHide = $();
6087     this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
6088     // ARIA
6089     .attr( "role", "tablist" );
6090    
6091     // don't allow collapsible: false and active: false / null
6092     if ( !options.collapsible && (options.active === false || options.active == null) ) {
6093     options.active = 0;
6094     }
6095    
6096     this._processPanels();
6097     // handle negative values
6098     if ( options.active < 0 ) {
6099     options.active += this.headers.length;
6100     }
6101     this._refresh();
6102     },
6103    
6104     _getCreateEventData: function() {
6105     return {
6106     header: this.active,
6107     panel: !this.active.length ? $() : this.active.next(),
6108     content: !this.active.length ? $() : this.active.next()
6109     };
6110     },
6111    
6112     _createIcons: function() {
6113     var icons = this.options.icons;
6114     if ( icons ) {
6115     $( "<span>" )
6116     .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
6117     .prependTo( this.headers );
6118     this.active.children( ".ui-accordion-header-icon" )
6119     .removeClass( icons.header )
6120     .addClass( icons.activeHeader );
6121     this.headers.addClass( "ui-accordion-icons" );
6122     }
6123     },
6124    
6125     _destroyIcons: function() {
6126     this.headers
6127     .removeClass( "ui-accordion-icons" )
6128     .children( ".ui-accordion-header-icon" )
6129     .remove();
6130     },
6131    
6132     _destroy: function() {
6133     var contents;
6134    
6135     // clean up main element
6136     this.element
6137     .removeClass( "ui-accordion ui-widget ui-helper-reset" )
6138     .removeAttr( "role" );
6139    
6140     // clean up headers
6141     this.headers
6142     .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
6143     .removeAttr( "role" )
6144     .removeAttr( "aria-selected" )
6145     .removeAttr( "aria-controls" )
6146     .removeAttr( "tabIndex" )
6147     .each(function() {
6148     if ( /^ui-accordion/.test( this.id ) ) {
6149     this.removeAttribute( "id" );
6150     }
6151     });
6152     this._destroyIcons();
6153    
6154     // clean up content panels
6155     contents = this.headers.next()
6156     .css( "display", "" )
6157     .removeAttr( "role" )
6158     .removeAttr( "aria-expanded" )
6159     .removeAttr( "aria-hidden" )
6160     .removeAttr( "aria-labelledby" )
6161     .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
6162     .each(function() {
6163     if ( /^ui-accordion/.test( this.id ) ) {
6164     this.removeAttribute( "id" );
6165     }
6166     });
6167     if ( this.options.heightStyle !== "content" ) {
6168     contents.css( "height", "" );
6169     }
6170     },
6171    
6172     _setOption: function( key, value ) {
6173     if ( key === "active" ) {
6174     // _activate() will handle invalid values and update this.options
6175     this._activate( value );
6176     return;
6177     }
6178    
6179     if ( key === "event" ) {
6180     if ( this.options.event ) {
6181     this._off( this.headers, this.options.event );
6182     }
6183     this._setupEvents( value );
6184     }
6185    
6186     this._super( key, value );
6187    
6188     // setting collapsible: false while collapsed; open first panel
6189     if ( key === "collapsible" && !value && this.options.active === false ) {
6190     this._activate( 0 );
6191     }
6192    
6193     if ( key === "icons" ) {
6194     this._destroyIcons();
6195     if ( value ) {
6196     this._createIcons();
6197     }
6198     }
6199    
6200     // #5332 - opacity doesn't cascade to positioned elements in IE
6201     // so we need to add the disabled class to the headers and panels
6202     if ( key === "disabled" ) {
6203     this.headers.add( this.headers.next() )
6204     .toggleClass( "ui-state-disabled", !!value );
6205     }
6206     },
6207    
6208     _keydown: function( event ) {
6209     /*jshint maxcomplexity:15*/
6210     if ( event.altKey || event.ctrlKey ) {
6211     return;
6212     }
6213    
6214     var keyCode = $.ui.keyCode,
6215     length = this.headers.length,
6216     currentIndex = this.headers.index( event.target ),
6217     toFocus = false;
6218    
6219     switch ( event.keyCode ) {
6220     case keyCode.RIGHT:
6221     case keyCode.DOWN:
6222     toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6223     break;
6224     case keyCode.LEFT:
6225     case keyCode.UP:
6226     toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6227     break;
6228     case keyCode.SPACE:
6229     case keyCode.ENTER:
6230     this._eventHandler( event );
6231     break;
6232     case keyCode.HOME:
6233     toFocus = this.headers[ 0 ];
6234     break;
6235     case keyCode.END:
6236     toFocus = this.headers[ length - 1 ];
6237     break;
6238     }
6239    
6240     if ( toFocus ) {
6241     $( event.target ).attr( "tabIndex", -1 );
6242     $( toFocus ).attr( "tabIndex", 0 );
6243     toFocus.focus();
6244     event.preventDefault();
6245     }
6246     },
6247    
6248     _panelKeyDown : function( event ) {
6249     if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6250     $( event.currentTarget ).prev().focus();
6251     }
6252     },
6253    
6254     refresh: function() {
6255     var options = this.options;
6256     this._processPanels();
6257    
6258     // was collapsed or no panel
6259     if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6260     options.active = false;
6261     this.active = $();
6262     // active false only when collapsible is true
6263     } else if ( options.active === false ) {
6264     this._activate( 0 );
6265     // was active, but active panel is gone
6266     } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6267     // all remaining panel are disabled
6268     if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6269     options.active = false;
6270     this.active = $();
6271     // activate previous panel
6272     } else {
6273     this._activate( Math.max( 0, options.active - 1 ) );
6274     }
6275     // was active, active panel still exists
6276     } else {
6277     // make sure active index is correct
6278     options.active = this.headers.index( this.active );
6279     }
6280    
6281     this._destroyIcons();
6282    
6283     this._refresh();
6284     },
6285    
6286     _processPanels: function() {
6287     this.headers = this.element.find( this.options.header )
6288     .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
6289    
6290     this.headers.next()
6291     .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6292     .filter(":not(.ui-accordion-content-active)")
6293     .hide();
6294     },
6295    
6296     _refresh: function() {
6297     var maxHeight,
6298     options = this.options,
6299     heightStyle = options.heightStyle,
6300     parent = this.element.parent(),
6301     accordionId = this.accordionId = "ui-accordion-" +
6302     (this.element.attr( "id" ) || ++uid);
6303    
6304     this.active = this._findActive( options.active )
6305     .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6306     .removeClass( "ui-corner-all" );
6307     this.active.next()
6308     .addClass( "ui-accordion-content-active" )
6309     .show();
6310    
6311     this.headers
6312     .attr( "role", "tab" )
6313     .each(function( i ) {
6314     var header = $( this ),
6315     headerId = header.attr( "id" ),
6316     panel = header.next(),
6317     panelId = panel.attr( "id" );
6318     if ( !headerId ) {
6319     headerId = accordionId + "-header-" + i;
6320     header.attr( "id", headerId );
6321     }
6322     if ( !panelId ) {
6323     panelId = accordionId + "-panel-" + i;
6324     panel.attr( "id", panelId );
6325     }
6326     header.attr( "aria-controls", panelId );
6327     panel.attr( "aria-labelledby", headerId );
6328     })
6329     .next()
6330     .attr( "role", "tabpanel" );
6331    
6332     this.headers
6333     .not( this.active )
6334     .attr({
6335     "aria-selected": "false",
6336     tabIndex: -1
6337     })
6338     .next()
6339     .attr({
6340     "aria-expanded": "false",
6341     "aria-hidden": "true"
6342     })
6343     .hide();
6344    
6345     // make sure at least one header is in the tab order
6346     if ( !this.active.length ) {
6347     this.headers.eq( 0 ).attr( "tabIndex", 0 );
6348     } else {
6349     this.active.attr({
6350     "aria-selected": "true",
6351     tabIndex: 0
6352     })
6353     .next()
6354     .attr({
6355     "aria-expanded": "true",
6356     "aria-hidden": "false"
6357     });
6358     }
6359    
6360     this._createIcons();
6361    
6362     this._setupEvents( options.event );
6363    
6364     if ( heightStyle === "fill" ) {
6365     maxHeight = parent.height();
6366     this.element.siblings( ":visible" ).each(function() {
6367     var elem = $( this ),
6368     position = elem.css( "position" );
6369    
6370     if ( position === "absolute" || position === "fixed" ) {
6371     return;
6372     }
6373     maxHeight -= elem.outerHeight( true );
6374     });
6375    
6376     this.headers.each(function() {
6377     maxHeight -= $( this ).outerHeight( true );
6378     });
6379    
6380     this.headers.next()
6381     .each(function() {
6382     $( this ).height( Math.max( 0, maxHeight -
6383     $( this ).innerHeight() + $( this ).height() ) );
6384     })
6385     .css( "overflow", "auto" );
6386     } else if ( heightStyle === "auto" ) {
6387     maxHeight = 0;
6388     this.headers.next()
6389     .each(function() {
6390     maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6391     })
6392     .height( maxHeight );
6393     }
6394     },
6395    
6396     _activate: function( index ) {
6397     var active = this._findActive( index )[ 0 ];
6398    
6399     // trying to activate the already active panel
6400     if ( active === this.active[ 0 ] ) {
6401     return;
6402     }
6403    
6404     // trying to collapse, simulate a click on the currently active header
6405     active = active || this.active[ 0 ];
6406    
6407     this._eventHandler({
6408     target: active,
6409     currentTarget: active,
6410     preventDefault: $.noop
6411     });
6412     },
6413    
6414     _findActive: function( selector ) {
6415     return typeof selector === "number" ? this.headers.eq( selector ) : $();
6416     },
6417    
6418     _setupEvents: function( event ) {
6419     var events = {
6420     keydown: "_keydown"
6421     };
6422     if ( event ) {
6423     $.each( event.split(" "), function( index, eventName ) {
6424     events[ eventName ] = "_eventHandler";
6425     });
6426     }
6427    
6428     this._off( this.headers.add( this.headers.next() ) );
6429     this._on( this.headers, events );
6430     this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6431     this._hoverable( this.headers );
6432     this._focusable( this.headers );
6433     },
6434    
6435     _eventHandler: function( event ) {
6436     var options = this.options,
6437     active = this.active,
6438     clicked = $( event.currentTarget ),
6439     clickedIsActive = clicked[ 0 ] === active[ 0 ],
6440     collapsing = clickedIsActive && options.collapsible,
6441     toShow = collapsing ? $() : clicked.next(),
6442     toHide = active.next(),
6443     eventData = {
6444     oldHeader: active,
6445     oldPanel: toHide,
6446     newHeader: collapsing ? $() : clicked,
6447     newPanel: toShow
6448     };
6449    
6450     event.preventDefault();
6451    
6452     if (
6453     // click on active header, but not collapsible
6454     ( clickedIsActive && !options.collapsible ) ||
6455     // allow canceling activation
6456     ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6457     return;
6458     }
6459    
6460     options.active = collapsing ? false : this.headers.index( clicked );
6461    
6462     // when the call to ._toggle() comes after the class changes
6463     // it causes a very odd bug in IE 8 (see #6720)
6464     this.active = clickedIsActive ? $() : clicked;
6465     this._toggle( eventData );
6466    
6467     // switch classes
6468     // corner classes on the previously active header stay after the animation
6469     active.removeClass( "ui-accordion-header-active ui-state-active" );
6470     if ( options.icons ) {
6471     active.children( ".ui-accordion-header-icon" )
6472     .removeClass( options.icons.activeHeader )
6473     .addClass( options.icons.header );
6474     }
6475    
6476     if ( !clickedIsActive ) {
6477     clicked
6478     .removeClass( "ui-corner-all" )
6479     .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6480     if ( options.icons ) {
6481     clicked.children( ".ui-accordion-header-icon" )
6482     .removeClass( options.icons.header )
6483     .addClass( options.icons.activeHeader );
6484     }
6485    
6486     clicked
6487     .next()
6488     .addClass( "ui-accordion-content-active" );
6489     }
6490     },
6491    
6492     _toggle: function( data ) {
6493     var toShow = data.newPanel,
6494     toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6495    
6496     // handle activating a panel during the animation for another activation
6497     this.prevShow.add( this.prevHide ).stop( true, true );
6498     this.prevShow = toShow;
6499     this.prevHide = toHide;
6500    
6501     if ( this.options.animate ) {
6502     this._animate( toShow, toHide, data );
6503     } else {
6504     toHide.hide();
6505     toShow.show();
6506     this._toggleComplete( data );
6507     }
6508    
6509     toHide.attr({
6510     "aria-expanded": "false",
6511     "aria-hidden": "true"
6512     });
6513     toHide.prev().attr( "aria-selected", "false" );
6514     // if we're switching panels, remove the old header from the tab order
6515     // if we're opening from collapsed state, remove the previous header from the tab order
6516     // if we're collapsing, then keep the collapsing header in the tab order
6517     if ( toShow.length && toHide.length ) {
6518     toHide.prev().attr( "tabIndex", -1 );
6519     } else if ( toShow.length ) {
6520     this.headers.filter(function() {
6521     return $( this ).attr( "tabIndex" ) === 0;
6522     })
6523     .attr( "tabIndex", -1 );
6524     }
6525    
6526     toShow
6527     .attr({
6528     "aria-expanded": "true",
6529     "aria-hidden": "false"
6530     })
6531     .prev()
6532     .attr({
6533     "aria-selected": "true",
6534     tabIndex: 0
6535     });
6536     },
6537    
6538     _animate: function( toShow, toHide, data ) {
6539     var total, easing, duration,
6540     that = this,
6541     adjust = 0,
6542     down = toShow.length &&
6543     ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6544     animate = this.options.animate || {},
6545     options = down && animate.down || animate,
6546     complete = function() {
6547     that._toggleComplete( data );
6548     };
6549    
6550     if ( typeof options === "number" ) {
6551     duration = options;
6552     }
6553     if ( typeof options === "string" ) {
6554     easing = options;
6555     }
6556     // fall back from options to animation in case of partial down settings
6557     easing = easing || options.easing || animate.easing;
6558     duration = duration || options.duration || animate.duration;
6559    
6560     if ( !toHide.length ) {
6561     return toShow.animate( showProps, duration, easing, complete );
6562     }
6563     if ( !toShow.length ) {
6564     return toHide.animate( hideProps, duration, easing, complete );
6565     }
6566    
6567     total = toShow.show().outerHeight();
6568     toHide.animate( hideProps, {
6569     duration: duration,
6570     easing: easing,
6571     step: function( now, fx ) {
6572     fx.now = Math.round( now );
6573     }
6574     });
6575     toShow
6576     .hide()
6577     .animate( showProps, {
6578     duration: duration,
6579     easing: easing,
6580     complete: complete,
6581     step: function( now, fx ) {
6582     fx.now = Math.round( now );
6583     if ( fx.prop !== "height" ) {
6584     adjust += fx.now;
6585     } else if ( that.options.heightStyle !== "content" ) {
6586     fx.now = Math.round( total - toHide.outerHeight() - adjust );
6587     adjust = 0;
6588     }
6589     }
6590     });
6591     },
6592    
6593     _toggleComplete: function( data ) {
6594     var toHide = data.oldPanel;
6595    
6596     toHide
6597     .removeClass( "ui-accordion-content-active" )
6598     .prev()
6599     .removeClass( "ui-corner-top" )
6600     .addClass( "ui-corner-all" );
6601    
6602     // Work around for rendering bug in IE (#5421)
6603     if ( toHide.length ) {
6604     toHide.parent()[0].className = toHide.parent()[0].className;
6605     }
6606    
6607     this._trigger( "activate", null, data );
6608     }
6609     });
6610    
6611     })( jQuery );
6612    
6613     (function( $, undefined ) {
6614    
6615     // used to prevent race conditions with remote data sources
6616     var requestIndex = 0;
6617    
6618     $.widget( "ui.autocomplete", {
6619     version: "1.10.3",
6620     defaultElement: "<input>",
6621     options: {
6622     appendTo: null,
6623     autoFocus: false,
6624     delay: 300,
6625     minLength: 1,
6626     position: {
6627     my: "left top",
6628     at: "left bottom",
6629     collision: "none"
6630     },
6631     source: null,
6632    
6633     // callbacks
6634     change: null,
6635     close: null,
6636     focus: null,
6637     open: null,
6638     response: null,
6639     search: null,
6640     select: null
6641     },
6642    
6643     pending: 0,
6644    
6645     _create: function() {
6646     // Some browsers only repeat keydown events, not keypress events,
6647     // so we use the suppressKeyPress flag to determine if we've already
6648     // handled the keydown event. #7269
6649     // Unfortunately the code for & in keypress is the same as the up arrow,
6650     // so we use the suppressKeyPressRepeat flag to avoid handling keypress
6651     // events when we know the keydown event was used to modify the
6652     // search term. #7799
6653     var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
6654     nodeName = this.element[0].nodeName.toLowerCase(),
6655     isTextarea = nodeName === "textarea",
6656     isInput = nodeName === "input";
6657    
6658     this.isMultiLine =
6659     // Textareas are always multi-line
6660     isTextarea ? true :
6661     // Inputs are always single-line, even if inside a contentEditable element
6662     // IE also treats inputs as contentEditable
6663     isInput ? false :
6664     // All other element types are determined by whether or not they're contentEditable
6665     this.element.prop( "isContentEditable" );
6666    
6667     this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
6668     this.isNewMenu = true;
6669    
6670     this.element
6671     .addClass( "ui-autocomplete-input" )
6672     .attr( "autocomplete", "off" );
6673    
6674     this._on( this.element, {
6675     keydown: function( event ) {
6676     /*jshint maxcomplexity:15*/
6677     if ( this.element.prop( "readOnly" ) ) {
6678     suppressKeyPress = true;
6679     suppressInput = true;
6680     suppressKeyPressRepeat = true;
6681     return;
6682     }
6683    
6684     suppressKeyPress = false;
6685     suppressInput = false;
6686     suppressKeyPressRepeat = false;
6687     var keyCode = $.ui.keyCode;
6688     switch( event.keyCode ) {
6689     case keyCode.PAGE_UP:
6690     suppressKeyPress = true;
6691     this._move( "previousPage", event );
6692     break;
6693     case keyCode.PAGE_DOWN:
6694     suppressKeyPress = true;
6695     this._move( "nextPage", event );
6696     break;
6697     case keyCode.UP:
6698     suppressKeyPress = true;
6699     this._keyEvent( "previous", event );
6700     break;
6701     case keyCode.DOWN:
6702     suppressKeyPress = true;
6703     this._keyEvent( "next", event );
6704     break;
6705     case keyCode.ENTER:
6706     case keyCode.NUMPAD_ENTER:
6707     // when menu is open and has focus
6708     if ( this.menu.active ) {
6709     // #6055 - Opera still allows the keypress to occur
6710     // which causes forms to submit
6711     suppressKeyPress = true;
6712     event.preventDefault();
6713     this.menu.select( event );
6714     }
6715     break;
6716     case keyCode.TAB:
6717     if ( this.menu.active ) {
6718     this.menu.select( event );
6719     }
6720     break;
6721     case keyCode.ESCAPE:
6722     if ( this.menu.element.is( ":visible" ) ) {
6723     this._value( this.term );
6724     this.close( event );
6725     // Different browsers have different default behavior for escape
6726     // Single press can mean undo or clear
6727     // Double press in IE means clear the whole form
6728     event.preventDefault();
6729     }
6730     break;
6731     default:
6732     suppressKeyPressRepeat = true;
6733     // search timeout should be triggered before the input value is changed
6734     this._searchTimeout( event );
6735     break;
6736     }
6737     },
6738     keypress: function( event ) {
6739     if ( suppressKeyPress ) {
6740     suppressKeyPress = false;
6741     if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6742     event.preventDefault();
6743     }
6744     return;
6745     }
6746     if ( suppressKeyPressRepeat ) {
6747     return;
6748     }
6749    
6750     // replicate some key handlers to allow them to repeat in Firefox and Opera
6751     var keyCode = $.ui.keyCode;
6752     switch( event.keyCode ) {
6753     case keyCode.PAGE_UP:
6754     this._move( "previousPage", event );
6755     break;
6756     case keyCode.PAGE_DOWN:
6757     this._move( "nextPage", event );
6758     break;
6759     case keyCode.UP:
6760     this._keyEvent( "previous", event );
6761     break;
6762     case keyCode.DOWN:
6763     this._keyEvent( "next", event );
6764     break;
6765     }
6766     },
6767     input: function( event ) {
6768     if ( suppressInput ) {
6769     suppressInput = false;
6770     event.preventDefault();
6771     return;
6772     }
6773     this._searchTimeout( event );
6774     },
6775     focus: function() {
6776     this.selectedItem = null;
6777     this.previous = this._value();
6778     },
6779     blur: function( event ) {
6780     if ( this.cancelBlur ) {
6781     delete this.cancelBlur;
6782     return;
6783     }
6784    
6785     clearTimeout( this.searching );
6786     this.close( event );
6787     this._change( event );
6788     }
6789     });
6790    
6791     this._initSource();
6792     this.menu = $( "<ul>" )
6793     .addClass( "ui-autocomplete ui-front" )
6794     .appendTo( this._appendTo() )
6795     .menu({
6796     // disable ARIA support, the live region takes care of that
6797     role: null
6798     })
6799     .hide()
6800     .data( "ui-menu" );
6801    
6802     this._on( this.menu.element, {
6803     mousedown: function( event ) {
6804     // prevent moving focus out of the text field
6805     event.preventDefault();
6806    
6807     // IE doesn't prevent moving focus even with event.preventDefault()
6808     // so we set a flag to know when we should ignore the blur event
6809     this.cancelBlur = true;
6810     this._delay(function() {
6811     delete this.cancelBlur;
6812     });
6813    
6814     // clicking on the scrollbar causes focus to shift to the body
6815     // but we can't detect a mouseup or a click immediately afterward
6816     // so we have to track the next mousedown and close the menu if
6817     // the user clicks somewhere outside of the autocomplete
6818     var menuElement = this.menu.element[ 0 ];
6819     if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6820     this._delay(function() {
6821     var that = this;
6822     this.document.one( "mousedown", function( event ) {
6823     if ( event.target !== that.element[ 0 ] &&
6824     event.target !== menuElement &&
6825     !$.contains( menuElement, event.target ) ) {
6826     that.close();
6827     }
6828     });
6829     });
6830     }
6831     },
6832     menufocus: function( event, ui ) {
6833     // support: Firefox
6834     // Prevent accidental activation of menu items in Firefox (#7024 #9118)
6835     if ( this.isNewMenu ) {
6836     this.isNewMenu = false;
6837     if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6838     this.menu.blur();
6839    
6840     this.document.one( "mousemove", function() {
6841     $( event.target ).trigger( event.originalEvent );
6842     });
6843    
6844     return;
6845     }
6846     }
6847    
6848     var item = ui.item.data( "ui-autocomplete-item" );
6849     if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6850     // use value to match what will end up in the input, if it was a key event
6851     if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6852     this._value( item.value );
6853     }
6854     } else {
6855     // Normally the input is populated with the item's value as the
6856     // menu is navigated, causing screen readers to notice a change and
6857     // announce the item. Since the focus event was canceled, this doesn't
6858     // happen, so we update the live region so that screen readers can
6859     // still notice the change and announce it.
6860     this.liveRegion.text( item.value );
6861     }
6862     },
6863     menuselect: function( event, ui ) {
6864     var item = ui.item.data( "ui-autocomplete-item" ),
6865     previous = this.previous;
6866    
6867     // only trigger when focus was lost (click on menu)
6868     if ( this.element[0] !== this.document[0].activeElement ) {
6869     this.element.focus();
6870     this.previous = previous;
6871     // #6109 - IE triggers two focus events and the second
6872     // is asynchronous, so we need to reset the previous
6873     // term synchronously and asynchronously :-(
6874     this._delay(function() {
6875     this.previous = previous;
6876     this.selectedItem = item;
6877     });
6878     }
6879    
6880     if ( false !== this._trigger( "select", event, { item: item } ) ) {
6881     this._value( item.value );
6882     }
6883     // reset the term after the select event
6884     // this allows custom select handling to work properly
6885     this.term = this._value();
6886    
6887     this.close( event );
6888     this.selectedItem = item;
6889     }
6890     });
6891    
6892     this.liveRegion = $( "<span>", {
6893     role: "status",
6894     "aria-live": "polite"
6895     })
6896     .addClass( "ui-helper-hidden-accessible" )
6897     .insertBefore( this.element );
6898    
6899     // turning off autocomplete prevents the browser from remembering the
6900     // value when navigating through history, so we re-enable autocomplete
6901     // if the page is unloaded before the widget is destroyed. #7790
6902     this._on( this.window, {
6903     beforeunload: function() {
6904     this.element.removeAttr( "autocomplete" );
6905     }
6906     });
6907     },
6908    
6909     _destroy: function() {
6910     clearTimeout( this.searching );
6911     this.element
6912     .removeClass( "ui-autocomplete-input" )
6913     .removeAttr( "autocomplete" );
6914     this.menu.element.remove();
6915     this.liveRegion.remove();
6916     },
6917    
6918     _setOption: function( key, value ) {
6919     this._super( key, value );
6920     if ( key === "source" ) {
6921     this._initSource();
6922     }
6923     if ( key === "appendTo" ) {
6924     this.menu.element.appendTo( this._appendTo() );
6925     }
6926     if ( key === "disabled" && value && this.xhr ) {
6927     this.xhr.abort();
6928     }
6929     },
6930    
6931     _appendTo: function() {
6932     var element = this.options.appendTo;
6933    
6934     if ( element ) {
6935     element = element.jquery || element.nodeType ?
6936     $( element ) :
6937     this.document.find( element ).eq( 0 );
6938     }
6939    
6940     if ( !element ) {
6941     element = this.element.closest( ".ui-front" );
6942     }
6943    
6944     if ( !element.length ) {
6945     element = this.document[0].body;
6946     }
6947    
6948     return element;
6949     },
6950    
6951     _initSource: function() {
6952     var array, url,
6953     that = this;
6954     if ( $.isArray(this.options.source) ) {
6955     array = this.options.source;
6956     this.source = function( request, response ) {
6957     response( $.ui.autocomplete.filter( array, request.term ) );
6958     };
6959     } else if ( typeof this.options.source === "string" ) {
6960     url = this.options.source;
6961     this.source = function( request, response ) {
6962     if ( that.xhr ) {
6963     that.xhr.abort();
6964     }
6965     that.xhr = $.ajax({
6966     url: url,
6967     data: request,
6968     dataType: "json",
6969     success: function( data ) {
6970     response( data );
6971     },
6972     error: function() {
6973     response( [] );
6974     }
6975     });
6976     };
6977     } else {
6978     this.source = this.options.source;
6979     }
6980     },
6981    
6982     _searchTimeout: function( event ) {
6983     clearTimeout( this.searching );
6984     this.searching = this._delay(function() {
6985     // only search if the value has changed
6986     if ( this.term !== this._value() ) {
6987     this.selectedItem = null;
6988     this.search( null, event );
6989     }
6990     }, this.options.delay );
6991     },
6992    
6993     search: function( value, event ) {
6994     value = value != null ? value : this._value();
6995    
6996     // always save the actual value, not the one passed as an argument
6997     this.term = this._value();
6998    
6999     if ( value.length < this.options.minLength ) {
7000     return this.close( event );
7001     }
7002    
7003     if ( this._trigger( "search", event ) === false ) {
7004     return;
7005     }
7006    
7007     return this._search( value );
7008     },
7009    
7010     _search: function( value ) {
7011     this.pending++;
7012     this.element.addClass( "ui-autocomplete-loading" );
7013     this.cancelSearch = false;
7014    
7015     this.source( { term: value }, this._response() );
7016     },
7017    
7018     _response: function() {
7019     var that = this,
7020     index = ++requestIndex;
7021    
7022     return function( content ) {
7023     if ( index === requestIndex ) {
7024     that.__response( content );
7025     }
7026    
7027     that.pending--;
7028     if ( !that.pending ) {
7029     that.element.removeClass( "ui-autocomplete-loading" );
7030     }
7031     };
7032     },
7033    
7034     __response: function( content ) {
7035     if ( content ) {
7036     content = this._normalize( content );
7037     }
7038     this._trigger( "response", null, { content: content } );
7039     if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7040     this._suggest( content );
7041     this._trigger( "open" );
7042     } else {
7043     // use ._close() instead of .close() so we don't cancel future searches
7044     this._close();
7045     }
7046     },
7047    
7048     close: function( event ) {
7049     this.cancelSearch = true;
7050     this._close( event );
7051     },
7052    
7053     _close: function( event ) {
7054     if ( this.menu.element.is( ":visible" ) ) {
7055     this.menu.element.hide();
7056     this.menu.blur();
7057     this.isNewMenu = true;
7058     this._trigger( "close", event );
7059     }
7060     },
7061    
7062     _change: function( event ) {
7063     if ( this.previous !== this._value() ) {
7064     this._trigger( "change", event, { item: this.selectedItem } );
7065     }
7066     },
7067    
7068     _normalize: function( items ) {
7069     // assume all items have the right format when the first item is complete
7070     if ( items.length && items[0].label && items[0].value ) {
7071     return items;
7072     }
7073     return $.map( items, function( item ) {
7074     if ( typeof item === "string" ) {
7075     return {
7076     label: item,
7077     value: item
7078     };
7079     }
7080     return $.extend({
7081     label: item.label || item.value,
7082     value: item.value || item.label
7083     }, item );
7084     });
7085     },
7086    
7087     _suggest: function( items ) {
7088     var ul = this.menu.element.empty();
7089     this._renderMenu( ul, items );
7090     this.isNewMenu = true;
7091     this.menu.refresh();
7092    
7093     // size and position menu
7094     ul.show();
7095     this._resizeMenu();
7096     ul.position( $.extend({
7097     of: this.element
7098     }, this.options.position ));
7099    
7100     if ( this.options.autoFocus ) {
7101     this.menu.next();
7102     }
7103     },
7104    
7105     _resizeMenu: function() {
7106     var ul = this.menu.element;
7107     ul.outerWidth( Math.max(
7108     // Firefox wraps long text (possibly a rounding bug)
7109     // so we add 1px to avoid the wrapping (#7513)
7110     ul.width( "" ).outerWidth() + 1,
7111     this.element.outerWidth()
7112     ) );
7113     },
7114    
7115     _renderMenu: function( ul, items ) {
7116     var that = this;
7117     $.each( items, function( index, item ) {
7118     that._renderItemData( ul, item );
7119     });
7120     },
7121    
7122     _renderItemData: function( ul, item ) {
7123     return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7124     },
7125    
7126     _renderItem: function( ul, item ) {
7127     return $( "<li>" )
7128     .append( $( "<a>" ).text( item.label ) )
7129     .appendTo( ul );
7130     },
7131    
7132     _move: function( direction, event ) {
7133     if ( !this.menu.element.is( ":visible" ) ) {
7134     this.search( null, event );
7135     return;
7136     }
7137     if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7138     this.menu.isLastItem() && /^next/.test( direction ) ) {
7139     this._value( this.term );
7140     this.menu.blur();
7141     return;
7142     }
7143     this.menu[ direction ]( event );
7144     },
7145    
7146     widget: function() {
7147     return this.menu.element;
7148     },
7149    
7150     _value: function() {
7151     return this.valueMethod.apply( this.element, arguments );
7152     },
7153    
7154     _keyEvent: function( keyEvent, event ) {
7155     if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7156     this._move( keyEvent, event );
7157    
7158     // prevents moving cursor to beginning/end of the text field in some browsers
7159     event.preventDefault();
7160     }
7161     }
7162     });
7163    
7164     $.extend( $.ui.autocomplete, {
7165     escapeRegex: function( value ) {
7166     return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
7167     },
7168     filter: function(array, term) {
7169     var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
7170     return $.grep( array, function(value) {
7171     return matcher.test( value.label || value.value || value );
7172     });
7173     }
7174     });
7175    
7176    
7177     // live region extension, adding a `messages` option
7178     // NOTE: This is an experimental API. We are still investigating
7179     // a full solution for string manipulation and internationalization.
7180     $.widget( "ui.autocomplete", $.ui.autocomplete, {
7181     options: {
7182     messages: {
7183     noResults: "No search results.",
7184     results: function( amount ) {
7185     return amount + ( amount > 1 ? " results are" : " result is" ) +
7186     " available, use up and down arrow keys to navigate.";
7187     }
7188     }
7189     },
7190    
7191     __response: function( content ) {
7192     var message;
7193     this._superApply( arguments );
7194     if ( this.options.disabled || this.cancelSearch ) {
7195     return;
7196     }
7197     if ( content && content.length ) {
7198     message = this.options.messages.results( content.length );
7199     } else {
7200     message = this.options.messages.noResults;
7201     }
7202     this.liveRegion.text( message );
7203     }
7204     });
7205    
7206     }( jQuery ));
7207    
7208     (function( $, undefined ) {
7209    
7210     var lastActive, startXPos, startYPos, clickDragged,
7211     baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7212     stateClasses = "ui-state-hover ui-state-active ",
7213     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",
7214     formResetHandler = function() {
7215     var form = $( this );
7216     setTimeout(function() {
7217     form.find( ":ui-button" ).button( "refresh" );
7218     }, 1 );
7219     },
7220     radioGroup = function( radio ) {
7221     var name = radio.name,
7222     form = radio.form,
7223     radios = $( [] );
7224     if ( name ) {
7225     name = name.replace( /'/g, "\\'" );
7226     if ( form ) {
7227     radios = $( form ).find( "[name='" + name + "']" );
7228     } else {
7229     radios = $( "[name='" + name + "']", radio.ownerDocument )
7230     .filter(function() {
7231     return !this.form;
7232     });
7233     }
7234     }
7235     return radios;
7236     };
7237    
7238     $.widget( "ui.button", {
7239     version: "1.10.3",
7240     defaultElement: "<button>",
7241     options: {
7242     disabled: null,
7243     text: true,
7244     label: null,
7245     icons: {
7246     primary: null,
7247     secondary: null
7248     }
7249     },
7250     _create: function() {
7251     this.element.closest( "form" )
7252     .unbind( "reset" + this.eventNamespace )
7253     .bind( "reset" + this.eventNamespace, formResetHandler );
7254    
7255     if ( typeof this.options.disabled !== "boolean" ) {
7256     this.options.disabled = !!this.element.prop( "disabled" );
7257     } else {
7258     this.element.prop( "disabled", this.options.disabled );
7259     }
7260    
7261     this._determineButtonType();
7262     this.hasTitle = !!this.buttonElement.attr( "title" );
7263    
7264     var that = this,
7265     options = this.options,
7266     toggleButton = this.type === "checkbox" || this.type === "radio",
7267     activeClass = !toggleButton ? "ui-state-active" : "",
7268     focusClass = "ui-state-focus";
7269    
7270     if ( options.label === null ) {
7271     options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7272     }
7273    
7274     this._hoverable( this.buttonElement );
7275    
7276     this.buttonElement
7277     .addClass( baseClasses )
7278     .attr( "role", "button" )
7279     .bind( "mouseenter" + this.eventNamespace, function() {
7280     if ( options.disabled ) {
7281     return;
7282     }
7283     if ( this === lastActive ) {
7284     $( this ).addClass( "ui-state-active" );
7285     }
7286     })
7287     .bind( "mouseleave" + this.eventNamespace, function() {
7288     if ( options.disabled ) {
7289     return;
7290     }
7291     $( this ).removeClass( activeClass );
7292     })
7293     .bind( "click" + this.eventNamespace, function( event ) {
7294     if ( options.disabled ) {
7295     event.preventDefault();
7296     event.stopImmediatePropagation();
7297     }
7298     });
7299    
7300     this.element
7301     .bind( "focus" + this.eventNamespace, function() {
7302     // no need to check disabled, focus won't be triggered anyway
7303     that.buttonElement.addClass( focusClass );
7304     })
7305     .bind( "blur" + this.eventNamespace, function() {
7306     that.buttonElement.removeClass( focusClass );
7307     });
7308    
7309     if ( toggleButton ) {
7310     this.element.bind( "change" + this.eventNamespace, function() {
7311     if ( clickDragged ) {
7312     return;
7313     }
7314     that.refresh();
7315     });
7316     // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
7317     // prevents issue where button state changes but checkbox/radio checked state
7318     // does not in Firefox (see ticket #6970)
7319     this.buttonElement
7320     .bind( "mousedown" + this.eventNamespace, function( event ) {
7321     if ( options.disabled ) {
7322     return;
7323     }
7324     clickDragged = false;
7325     startXPos = event.pageX;
7326     startYPos = event.pageY;
7327     })
7328     .bind( "mouseup" + this.eventNamespace, function( event ) {
7329     if ( options.disabled ) {
7330     return;
7331     }
7332     if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
7333     clickDragged = true;
7334     }
7335     });
7336     }
7337    
7338     if ( this.type === "checkbox" ) {
7339     this.buttonElement.bind( "click" + this.eventNamespace, function() {
7340     if ( options.disabled || clickDragged ) {
7341     return false;
7342     }
7343     });
7344     } else if ( this.type === "radio" ) {
7345     this.buttonElement.bind( "click" + this.eventNamespace, function() {
7346     if ( options.disabled || clickDragged ) {
7347     return false;
7348     }
7349     $( this ).addClass( "ui-state-active" );
7350     that.buttonElement.attr( "aria-pressed", "true" );
7351    
7352     var radio = that.element[ 0 ];
7353     radioGroup( radio )
7354     .not( radio )
7355     .map(function() {
7356     return $( this ).button( "widget" )[ 0 ];
7357     })
7358     .removeClass( "ui-state-active" )
7359     .attr( "aria-pressed", "false" );
7360     });
7361     } else {
7362     this.buttonElement
7363     .bind( "mousedown" + this.eventNamespace, function() {
7364     if ( options.disabled ) {
7365     return false;
7366     }
7367     $( this ).addClass( "ui-state-active" );
7368     lastActive = this;
7369     that.document.one( "mouseup", function() {
7370     lastActive = null;
7371     });
7372     })
7373     .bind( "mouseup" + this.eventNamespace, function() {
7374     if ( options.disabled ) {
7375     return false;
7376     }
7377     $( this ).removeClass( "ui-state-active" );
7378     })
7379     .bind( "keydown" + this.eventNamespace, function(event) {
7380     if ( options.disabled ) {
7381     return false;
7382     }
7383     if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7384     $( this ).addClass( "ui-state-active" );
7385     }
7386     })
7387     // see #8559, we bind to blur here in case the button element loses
7388     // focus between keydown and keyup, it would be left in an "active" state
7389     .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7390     $( this ).removeClass( "ui-state-active" );
7391     });
7392    
7393     if ( this.buttonElement.is("a") ) {
7394     this.buttonElement.keyup(function(event) {
7395     if ( event.keyCode === $.ui.keyCode.SPACE ) {
7396     // TODO pass through original event correctly (just as 2nd argument doesn't work)
7397     $( this ).click();
7398     }
7399     });
7400     }
7401     }
7402    
7403     // TODO: pull out $.Widget's handling for the disabled option into
7404     // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7405     // be overridden by individual plugins
7406     this._setOption( "disabled", options.disabled );
7407     this._resetButton();
7408     },
7409    
7410     _determineButtonType: function() {
7411     var ancestor, labelSelector, checked;
7412    
7413     if ( this.element.is("[type=checkbox]") ) {
7414     this.type = "checkbox";
7415     } else if ( this.element.is("[type=radio]") ) {
7416     this.type = "radio";
7417     } else if ( this.element.is("input") ) {
7418     this.type = "input";
7419     } else {
7420     this.type = "button";
7421     }
7422    
7423     if ( this.type === "checkbox" || this.type === "radio" ) {
7424     // we don't search against the document in case the element
7425     // is disconnected from the DOM
7426     ancestor = this.element.parents().last();
7427     labelSelector = "label[for='" + this.element.attr("id") + "']";
7428     this.buttonElement = ancestor.find( labelSelector );
7429     if ( !this.buttonElement.length ) {
7430     ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7431     this.buttonElement = ancestor.filter( labelSelector );
7432     if ( !this.buttonElement.length ) {
7433     this.buttonElement = ancestor.find( labelSelector );
7434     }
7435     }
7436     this.element.addClass( "ui-helper-hidden-accessible" );
7437    
7438     checked = this.element.is( ":checked" );
7439     if ( checked ) {
7440     this.buttonElement.addClass( "ui-state-active" );
7441     }
7442     this.buttonElement.prop( "aria-pressed", checked );
7443     } else {
7444     this.buttonElement = this.element;
7445     }
7446     },
7447    
7448     widget: function() {
7449     return this.buttonElement;
7450     },
7451    
7452     _destroy: function() {
7453     this.element
7454     .removeClass( "ui-helper-hidden-accessible" );
7455     this.buttonElement
7456     .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7457     .removeAttr( "role" )
7458     .removeAttr( "aria-pressed" )
7459     .html( this.buttonElement.find(".ui-button-text").html() );
7460    
7461     if ( !this.hasTitle ) {
7462     this.buttonElement.removeAttr( "title" );
7463     }
7464     },
7465    
7466     _setOption: function( key, value ) {
7467     this._super( key, value );
7468     if ( key === "disabled" ) {
7469     if ( value ) {
7470     this.element.prop( "disabled", true );
7471     } else {
7472     this.element.prop( "disabled", false );
7473     }
7474     return;
7475     }
7476     this._resetButton();
7477     },
7478    
7479     refresh: function() {
7480     //See #8237 & #8828
7481     var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7482    
7483     if ( isDisabled !== this.options.disabled ) {
7484     this._setOption( "disabled", isDisabled );
7485     }
7486     if ( this.type === "radio" ) {
7487     radioGroup( this.element[0] ).each(function() {
7488     if ( $( this ).is( ":checked" ) ) {
7489     $( this ).button( "widget" )
7490     .addClass( "ui-state-active" )
7491     .attr( "aria-pressed", "true" );
7492     } else {
7493     $( this ).button( "widget" )
7494     .removeClass( "ui-state-active" )
7495     .attr( "aria-pressed", "false" );
7496     }
7497     });
7498     } else if ( this.type === "checkbox" ) {
7499     if ( this.element.is( ":checked" ) ) {
7500     this.buttonElement
7501     .addClass( "ui-state-active" )
7502     .attr( "aria-pressed", "true" );
7503     } else {
7504     this.buttonElement
7505     .removeClass( "ui-state-active" )
7506     .attr( "aria-pressed", "false" );
7507     }
7508     }
7509     },
7510    
7511     _resetButton: function() {
7512     if ( this.type === "input" ) {
7513     if ( this.options.label ) {
7514     this.element.val( this.options.label );
7515     }
7516     return;
7517     }
7518     var buttonElement = this.buttonElement.removeClass( typeClasses ),
7519     buttonText = $( "<span></span>", this.document[0] )
7520     .addClass( "ui-button-text" )
7521     .html( this.options.label )
7522     .appendTo( buttonElement.empty() )
7523     .text(),
7524     icons = this.options.icons,
7525     multipleIcons = icons.primary && icons.secondary,
7526     buttonClasses = [];
7527    
7528     if ( icons.primary || icons.secondary ) {
7529     if ( this.options.text ) {
7530     buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7531     }
7532    
7533     if ( icons.primary ) {
7534     buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7535     }
7536    
7537     if ( icons.secondary ) {
7538     buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7539     }
7540    
7541     if ( !this.options.text ) {
7542     buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7543    
7544     if ( !this.hasTitle ) {
7545     buttonElement.attr( "title", $.trim( buttonText ) );
7546     }
7547     }
7548     } else {
7549     buttonClasses.push( "ui-button-text-only" );
7550     }
7551     buttonElement.addClass( buttonClasses.join( " " ) );
7552     }
7553     });
7554    
7555     $.widget( "ui.buttonset", {
7556     version: "1.10.3",
7557     options: {
7558     items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7559     },
7560    
7561     _create: function() {
7562     this.element.addClass( "ui-buttonset" );
7563     },
7564    
7565     _init: function() {
7566     this.refresh();
7567     },
7568    
7569     _setOption: function( key, value ) {
7570     if ( key === "disabled" ) {
7571     this.buttons.button( "option", key, value );
7572     }
7573    
7574     this._super( key, value );
7575     },
7576    
7577     refresh: function() {
7578     var rtl = this.element.css( "direction" ) === "rtl";
7579    
7580     this.buttons = this.element.find( this.options.items )
7581     .filter( ":ui-button" )
7582     .button( "refresh" )
7583     .end()
7584     .not( ":ui-button" )
7585     .button()
7586     .end()
7587     .map(function() {
7588     return $( this ).button( "widget" )[ 0 ];
7589     })
7590     .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7591     .filter( ":first" )
7592     .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7593     .end()
7594     .filter( ":last" )
7595     .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7596     .end()
7597     .end();
7598     },
7599    
7600     _destroy: function() {
7601     this.element.removeClass( "ui-buttonset" );
7602     this.buttons
7603     .map(function() {
7604     return $( this ).button( "widget" )[ 0 ];
7605     })
7606     .removeClass( "ui-corner-left ui-corner-right" )
7607     .end()
7608     .button( "destroy" );
7609     }
7610     });
7611    
7612     }( jQuery ) );
7613    
7614     (function( $, undefined ) {
7615    
7616     $.extend($.ui, { datepicker: { version: "1.10.3" } });
7617    
7618     var PROP_NAME = "datepicker",
7619     instActive;
7620    
7621     /* Date picker manager.
7622     Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7623     Settings for (groups of) date pickers are maintained in an instance object,
7624     allowing multiple different settings on the same page. */
7625    
7626     function Datepicker() {
7627     this._curInst = null; // The current instance in use
7628     this._keyEvent = false; // If the last event was a key event
7629     this._disabledInputs = []; // List of date picker inputs that have been disabled
7630     this._datepickerShowing = false; // True if the popup picker is showing , false if not
7631     this._inDialog = false; // True if showing within a "dialog", false if not
7632     this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7633     this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7634     this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7635     this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7636     this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7637     this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7638     this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7639     this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7640     this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7641     this.regional = []; // Available regional settings, indexed by language code
7642     this.regional[""] = { // Default regional settings
7643     closeText: "Done", // Display text for close link
7644     prevText: "Prev", // Display text for previous month link
7645     nextText: "Next", // Display text for next month link
7646     currentText: "Today", // Display text for current month link
7647     monthNames: ["January","February","March","April","May","June",
7648     "July","August","September","October","November","December"], // Names of months for drop-down and formatting
7649     monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
7650     dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
7651     dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
7652     dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
7653     weekHeader: "Wk", // Column header for week of the year
7654     dateFormat: "mm/dd/yy", // See format options on parseDate
7655     firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7656     isRTL: false, // True if right-to-left language, false if left-to-right
7657     showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7658     yearSuffix: "" // Additional text to append to the year in the month headers
7659     };
7660     this._defaults = { // Global defaults for all the date picker instances
7661     showOn: "focus", // "focus" for popup on focus,
7662     // "button" for trigger button, or "both" for either
7663     showAnim: "fadeIn", // Name of jQuery animation for popup
7664     showOptions: {}, // Options for enhanced animations
7665     defaultDate: null, // Used when field is blank: actual date,
7666     // +/-number for offset from today, null for today
7667     appendText: "", // Display text following the input box, e.g. showing the format
7668     buttonText: "...", // Text for trigger button
7669     buttonImage: "", // URL for trigger button image
7670     buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7671     hideIfNoPrevNext: false, // True to hide next/previous month links
7672     // if not applicable, false to just disable them
7673     navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7674     gotoCurrent: false, // True if today link goes back to current selection instead
7675     changeMonth: false, // True if month can be selected directly, false if only prev/next
7676     changeYear: false, // True if year can be selected directly, false if only prev/next
7677     yearRange: "c-10:c+10", // Range of years to display in drop-down,
7678     // either relative to today's year (-nn:+nn), relative to currently displayed year
7679     // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7680     showOtherMonths: false, // True to show dates in other months, false to leave blank
7681     selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7682     showWeek: false, // True to show week of the year, false to not show it
7683     calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7684     // takes a Date and returns the number of the week for it
7685     shortYearCutoff: "+10", // Short year values < this are in the current century,
7686     // > this are in the previous century,
7687     // string value starting with "+" for current year + value
7688     minDate: null, // The earliest selectable date, or null for no limit
7689     maxDate: null, // The latest selectable date, or null for no limit
7690     duration: "fast", // Duration of display/closure
7691     beforeShowDay: null, // Function that takes a date and returns an array with
7692     // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7693     // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7694     beforeShow: null, // Function that takes an input field and
7695     // returns a set of custom settings for the date picker
7696     onSelect: null, // Define a callback function when a date is selected
7697     onChangeMonthYear: null, // Define a callback function when the month or year is changed
7698     onClose: null, // Define a callback function when the datepicker is closed
7699     numberOfMonths: 1, // Number of months to show at a time
7700     showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7701     stepMonths: 1, // Number of months to step back/forward
7702     stepBigMonths: 12, // Number of months to step back/forward for the big links
7703     altField: "", // Selector for an alternate field to store selected dates into
7704     altFormat: "", // The date format to use for the alternate field
7705     constrainInput: true, // The input is constrained by the current date format
7706     showButtonPanel: false, // True to show button panel, false to not show it
7707     autoSize: false, // True to size the input for the date format, false to leave as is
7708     disabled: false // The initial disabled state
7709     };
7710     $.extend(this._defaults, this.regional[""]);
7711     this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
7712     }
7713    
7714     $.extend(Datepicker.prototype, {
7715     /* Class name added to elements to indicate already configured with a date picker. */
7716     markerClassName: "hasDatepicker",
7717    
7718     //Keep track of the maximum number of rows displayed (see #7043)
7719     maxRows: 4,
7720    
7721     // TODO rename to "widget" when switching to widget factory
7722     _widgetDatepicker: function() {
7723     return this.dpDiv;
7724     },
7725    
7726     /* Override the default settings for all instances of the date picker.
7727     * @param settings object - the new settings to use as defaults (anonymous object)
7728     * @return the manager object
7729     */
7730     setDefaults: function(settings) {
7731     extendRemove(this._defaults, settings || {});
7732     return this;
7733     },
7734    
7735     /* Attach the date picker to a jQuery selection.
7736     * @param target element - the target input field or division or span
7737     * @param settings object - the new settings to use for this date picker instance (anonymous)
7738     */
7739     _attachDatepicker: function(target, settings) {
7740     var nodeName, inline, inst;
7741     nodeName = target.nodeName.toLowerCase();
7742     inline = (nodeName === "div" || nodeName === "span");
7743     if (!target.id) {
7744     this.uuid += 1;
7745     target.id = "dp" + this.uuid;
7746     }
7747     inst = this._newInst($(target), inline);
7748     inst.settings = $.extend({}, settings || {});
7749     if (nodeName === "input") {
7750     this._connectDatepicker(target, inst);
7751     } else if (inline) {
7752     this._inlineDatepicker(target, inst);
7753     }
7754     },
7755    
7756     /* Create a new instance object. */
7757     _newInst: function(target, inline) {
7758     var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
7759     return {id: id, input: target, // associated target
7760     selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7761     drawMonth: 0, drawYear: 0, // month being drawn
7762     inline: inline, // is datepicker inline or not
7763     dpDiv: (!inline ? this.dpDiv : // presentation div
7764     bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
7765     },
7766    
7767     /* Attach the date picker to an input field. */
7768     _connectDatepicker: function(target, inst) {
7769     var input = $(target);
7770     inst.append = $([]);
7771     inst.trigger = $([]);
7772     if (input.hasClass(this.markerClassName)) {
7773     return;
7774     }
7775     this._attachments(input, inst);
7776     input.addClass(this.markerClassName).keydown(this._doKeyDown).
7777     keypress(this._doKeyPress).keyup(this._doKeyUp);
7778     this._autoSize(inst);
7779     $.data(target, PROP_NAME, inst);
7780     //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7781     if( inst.settings.disabled ) {
7782     this._disableDatepicker( target );
7783     }
7784     },
7785    
7786     /* Make attachments based on settings. */
7787     _attachments: function(input, inst) {
7788     var showOn, buttonText, buttonImage,
7789     appendText = this._get(inst, "appendText"),
7790     isRTL = this._get(inst, "isRTL");
7791    
7792     if (inst.append) {
7793     inst.append.remove();
7794     }
7795     if (appendText) {
7796     inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
7797     input[isRTL ? "before" : "after"](inst.append);
7798     }
7799    
7800     input.unbind("focus", this._showDatepicker);
7801    
7802     if (inst.trigger) {
7803     inst.trigger.remove();
7804     }
7805    
7806     showOn = this._get(inst, "showOn");
7807     if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7808     input.focus(this._showDatepicker);
7809     }
7810     if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7811     buttonText = this._get(inst, "buttonText");
7812     buttonImage = this._get(inst, "buttonImage");
7813     inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7814     $("<img/>").addClass(this._triggerClass).
7815     attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7816     $("<button type='button'></button>").addClass(this._triggerClass).
7817     html(!buttonImage ? buttonText : $("<img/>").attr(
7818     { src:buttonImage, alt:buttonText, title:buttonText })));
7819     input[isRTL ? "before" : "after"](inst.trigger);
7820     inst.trigger.click(function() {
7821     if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7822     $.datepicker._hideDatepicker();
7823     } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7824     $.datepicker._hideDatepicker();
7825     $.datepicker._showDatepicker(input[0]);
7826     } else {
7827     $.datepicker._showDatepicker(input[0]);
7828     }
7829     return false;
7830     });
7831     }
7832     },
7833    
7834     /* Apply the maximum length for the date format. */
7835     _autoSize: function(inst) {
7836     if (this._get(inst, "autoSize") && !inst.inline) {
7837     var findMax, max, maxI, i,
7838     date = new Date(2009, 12 - 1, 20), // Ensure double digits
7839     dateFormat = this._get(inst, "dateFormat");
7840    
7841     if (dateFormat.match(/[DM]/)) {
7842     findMax = function(names) {
7843     max = 0;
7844     maxI = 0;
7845     for (i = 0; i < names.length; i++) {
7846     if (names[i].length > max) {
7847     max = names[i].length;
7848     maxI = i;
7849     }
7850     }
7851     return maxI;
7852     };
7853     date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7854     "monthNames" : "monthNamesShort"))));
7855     date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7856     "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7857     }
7858     inst.input.attr("size", this._formatDate(inst, date).length);
7859     }
7860     },
7861    
7862     /* Attach an inline date picker to a div. */
7863     _inlineDatepicker: function(target, inst) {
7864     var divSpan = $(target);
7865     if (divSpan.hasClass(this.markerClassName)) {
7866     return;
7867     }
7868     divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7869     $.data(target, PROP_NAME, inst);
7870     this._setDate(inst, this._getDefaultDate(inst), true);
7871     this._updateDatepicker(inst);
7872     this._updateAlternate(inst);
7873     //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7874     if( inst.settings.disabled ) {
7875     this._disableDatepicker( target );
7876     }
7877     // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7878     // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7879     inst.dpDiv.css( "display", "block" );
7880     },
7881    
7882     /* Pop-up the date picker in a "dialog" box.
7883     * @param input element - ignored
7884     * @param date string or Date - the initial date to display
7885     * @param onSelect function - the function to call when a date is selected
7886     * @param settings object - update the dialog date picker instance's settings (anonymous object)
7887     * @param pos int[2] - coordinates for the dialog's position within the screen or
7888     * event - with x/y coordinates or
7889     * leave empty for default (screen centre)
7890     * @return the manager object
7891     */
7892     _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7893     var id, browserWidth, browserHeight, scrollX, scrollY,
7894     inst = this._dialogInst; // internal instance
7895    
7896     if (!inst) {
7897     this.uuid += 1;
7898     id = "dp" + this.uuid;
7899     this._dialogInput = $("<input type='text' id='" + id +
7900     "' style='position: absolute; top: -100px; width: 0px;'/>");
7901     this._dialogInput.keydown(this._doKeyDown);
7902     $("body").append(this._dialogInput);
7903     inst = this._dialogInst = this._newInst(this._dialogInput, false);
7904     inst.settings = {};
7905     $.data(this._dialogInput[0], PROP_NAME, inst);
7906     }
7907     extendRemove(inst.settings, settings || {});
7908     date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7909     this._dialogInput.val(date);
7910    
7911     this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7912     if (!this._pos) {
7913     browserWidth = document.documentElement.clientWidth;
7914     browserHeight = document.documentElement.clientHeight;
7915     scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7916     scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7917     this._pos = // should use actual width/height below
7918     [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7919     }
7920    
7921     // move input on screen for focus, but hidden behind dialog
7922     this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7923     inst.settings.onSelect = onSelect;
7924     this._inDialog = true;
7925     this.dpDiv.addClass(this._dialogClass);
7926     this._showDatepicker(this._dialogInput[0]);
7927     if ($.blockUI) {
7928     $.blockUI(this.dpDiv);
7929     }
7930     $.data(this._dialogInput[0], PROP_NAME, inst);
7931     return this;
7932     },
7933    
7934     /* Detach a datepicker from its control.
7935     * @param target element - the target input field or division or span
7936     */
7937     _destroyDatepicker: function(target) {
7938     var nodeName,
7939     $target = $(target),
7940     inst = $.data(target, PROP_NAME);
7941    
7942     if (!$target.hasClass(this.markerClassName)) {
7943     return;
7944     }
7945    
7946     nodeName = target.nodeName.toLowerCase();
7947     $.removeData(target, PROP_NAME);
7948     if (nodeName === "input") {
7949     inst.append.remove();
7950     inst.trigger.remove();
7951     $target.removeClass(this.markerClassName).
7952     unbind("focus", this._showDatepicker).
7953     unbind("keydown", this._doKeyDown).
7954     unbind("keypress", this._doKeyPress).
7955     unbind("keyup", this._doKeyUp);
7956     } else if (nodeName === "div" || nodeName === "span") {
7957     $target.removeClass(this.markerClassName).empty();
7958     }
7959     },
7960    
7961     /* Enable the date picker to a jQuery selection.
7962     * @param target element - the target input field or division or span
7963     */
7964     _enableDatepicker: function(target) {
7965     var nodeName, inline,
7966     $target = $(target),
7967     inst = $.data(target, PROP_NAME);
7968    
7969     if (!$target.hasClass(this.markerClassName)) {
7970     return;
7971     }
7972    
7973     nodeName = target.nodeName.toLowerCase();
7974     if (nodeName === "input") {
7975     target.disabled = false;
7976     inst.trigger.filter("button").
7977     each(function() { this.disabled = false; }).end().
7978     filter("img").css({opacity: "1.0", cursor: ""});
7979     } else if (nodeName === "div" || nodeName === "span") {
7980     inline = $target.children("." + this._inlineClass);
7981     inline.children().removeClass("ui-state-disabled");
7982     inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7983     prop("disabled", false);
7984     }
7985     this._disabledInputs = $.map(this._disabledInputs,
7986     function(value) { return (value === target ? null : value); }); // delete entry
7987     },
7988    
7989     /* Disable the date picker to a jQuery selection.
7990     * @param target element - the target input field or division or span
7991     */
7992     _disableDatepicker: function(target) {
7993     var nodeName, inline,
7994     $target = $(target),
7995     inst = $.data(target, PROP_NAME);
7996    
7997     if (!$target.hasClass(this.markerClassName)) {
7998     return;
7999     }
8000    
8001     nodeName = target.nodeName.toLowerCase();
8002     if (nodeName === "input") {
8003     target.disabled = true;
8004     inst.trigger.filter("button").
8005     each(function() { this.disabled = true; }).end().
8006     filter("img").css({opacity: "0.5", cursor: "default"});
8007     } else if (nodeName === "div" || nodeName === "span") {
8008     inline = $target.children("." + this._inlineClass);
8009     inline.children().addClass("ui-state-disabled");
8010     inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8011     prop("disabled", true);
8012     }
8013     this._disabledInputs = $.map(this._disabledInputs,
8014     function(value) { return (value === target ? null : value); }); // delete entry
8015     this._disabledInputs[this._disabledInputs.length] = target;
8016     },
8017    
8018     /* Is the first field in a jQuery collection disabled as a datepicker?
8019     * @param target element - the target input field or division or span
8020     * @return boolean - true if disabled, false if enabled
8021     */
8022     _isDisabledDatepicker: function(target) {
8023     if (!target) {
8024     return false;
8025     }
8026     for (var i = 0; i < this._disabledInputs.length; i++) {
8027     if (this._disabledInputs[i] === target) {
8028     return true;
8029     }
8030     }
8031     return false;
8032     },
8033    
8034     /* Retrieve the instance data for the target control.
8035     * @param target element - the target input field or division or span
8036     * @return object - the associated instance data
8037     * @throws error if a jQuery problem getting data
8038     */
8039     _getInst: function(target) {
8040     try {
8041     return $.data(target, PROP_NAME);
8042     }
8043     catch (err) {
8044     throw "Missing instance data for this datepicker";
8045     }
8046     },
8047    
8048     /* Update or retrieve the settings for a date picker attached to an input field or division.
8049     * @param target element - the target input field or division or span
8050     * @param name object - the new settings to update or
8051     * string - the name of the setting to change or retrieve,
8052     * when retrieving also "all" for all instance settings or
8053     * "defaults" for all global defaults
8054     * @param value any - the new value for the setting
8055     * (omit if above is an object or to retrieve a value)
8056     */
8057     _optionDatepicker: function(target, name, value) {
8058     var settings, date, minDate, maxDate,
8059     inst = this._getInst(target);
8060    
8061     if (arguments.length === 2 && typeof name === "string") {
8062     return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8063     (inst ? (name === "all" ? $.extend({}, inst.settings) :
8064     this._get(inst, name)) : null));
8065     }
8066    
8067     settings = name || {};
8068     if (typeof name === "string") {
8069     settings = {};
8070     settings[name] = value;
8071     }
8072    
8073     if (inst) {
8074     if (this._curInst === inst) {
8075     this._hideDatepicker();
8076     }
8077    
8078     date = this._getDateDatepicker(target, true);
8079     minDate = this._getMinMaxDate(inst, "min");
8080     maxDate = this._getMinMaxDate(inst, "max");
8081     extendRemove(inst.settings, settings);
8082     // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8083     if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8084     inst.settings.minDate = this._formatDate(inst, minDate);
8085     }
8086     if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8087     inst.settings.maxDate = this._formatDate(inst, maxDate);
8088     }
8089     if ( "disabled" in settings ) {
8090     if ( settings.disabled ) {
8091     this._disableDatepicker(target);
8092     } else {
8093     this._enableDatepicker(target);
8094     }
8095     }
8096     this._attachments($(target), inst);
8097     this._autoSize(inst);
8098     this._setDate(inst, date);
8099     this._updateAlternate(inst);
8100     this._updateDatepicker(inst);
8101     }
8102     },
8103    
8104     // change method deprecated
8105     _changeDatepicker: function(target, name, value) {
8106     this._optionDatepicker(target, name, value);
8107     },
8108    
8109     /* Redraw the date picker attached to an input field or division.
8110     * @param target element - the target input field or division or span
8111     */
8112     _refreshDatepicker: function(target) {
8113     var inst = this._getInst(target);
8114     if (inst) {
8115     this._updateDatepicker(inst);
8116     }
8117     },
8118    
8119     /* Set the dates for a jQuery selection.
8120     * @param target element - the target input field or division or span
8121     * @param date Date - the new date
8122     */
8123     _setDateDatepicker: function(target, date) {
8124     var inst = this._getInst(target);
8125     if (inst) {
8126     this._setDate(inst, date);
8127     this._updateDatepicker(inst);
8128     this._updateAlternate(inst);
8129     }
8130     },
8131    
8132     /* Get the date(s) for the first entry in a jQuery selection.
8133     * @param target element - the target input field or division or span
8134     * @param noDefault boolean - true if no default date is to be used
8135     * @return Date - the current date
8136     */
8137     _getDateDatepicker: function(target, noDefault) {
8138     var inst = this._getInst(target);
8139     if (inst && !inst.inline) {
8140     this._setDateFromField(inst, noDefault);
8141     }
8142     return (inst ? this._getDate(inst) : null);
8143     },
8144    
8145     /* Handle keystrokes. */
8146     _doKeyDown: function(event) {
8147     var onSelect, dateStr, sel,
8148     inst = $.datepicker._getInst(event.target),
8149     handled = true,
8150     isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8151    
8152     inst._keyEvent = true;
8153     if ($.datepicker._datepickerShowing) {
8154     switch (event.keyCode) {
8155     case 9: $.datepicker._hideDatepicker();
8156     handled = false;
8157     break; // hide on tab out
8158     case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8159     $.datepicker._currentClass + ")", inst.dpDiv);
8160     if (sel[0]) {
8161     $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8162     }
8163    
8164     onSelect = $.datepicker._get(inst, "onSelect");
8165     if (onSelect) {
8166     dateStr = $.datepicker._formatDate(inst);
8167    
8168     // trigger custom callback
8169     onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8170     } else {
8171     $.datepicker._hideDatepicker();
8172     }
8173    
8174     return false; // don't submit the form
8175     case 27: $.datepicker._hideDatepicker();
8176     break; // hide on escape
8177     case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8178     -$.datepicker._get(inst, "stepBigMonths") :
8179     -$.datepicker._get(inst, "stepMonths")), "M");
8180     break; // previous month/year on page up/+ ctrl
8181     case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8182     +$.datepicker._get(inst, "stepBigMonths") :
8183     +$.datepicker._get(inst, "stepMonths")), "M");
8184     break; // next month/year on page down/+ ctrl
8185     case 35: if (event.ctrlKey || event.metaKey) {
8186     $.datepicker._clearDate(event.target);
8187     }
8188     handled = event.ctrlKey || event.metaKey;
8189     break; // clear on ctrl or command +end
8190     case 36: if (event.ctrlKey || event.metaKey) {
8191     $.datepicker._gotoToday(event.target);
8192     }
8193     handled = event.ctrlKey || event.metaKey;
8194     break; // current on ctrl or command +home
8195     case 37: if (event.ctrlKey || event.metaKey) {
8196     $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8197     }
8198     handled = event.ctrlKey || event.metaKey;
8199     // -1 day on ctrl or command +left
8200     if (event.originalEvent.altKey) {
8201     $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8202     -$.datepicker._get(inst, "stepBigMonths") :
8203     -$.datepicker._get(inst, "stepMonths")), "M");
8204     }
8205     // next month/year on alt +left on Mac
8206     break;
8207     case 38: if (event.ctrlKey || event.metaKey) {
8208     $.datepicker._adjustDate(event.target, -7, "D");
8209     }
8210     handled = event.ctrlKey || event.metaKey;
8211     break; // -1 week on ctrl or command +up
8212     case 39: if (event.ctrlKey || event.metaKey) {
8213     $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8214     }
8215     handled = event.ctrlKey || event.metaKey;
8216     // +1 day on ctrl or command +right
8217     if (event.originalEvent.altKey) {
8218     $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8219     +$.datepicker._get(inst, "stepBigMonths") :
8220     +$.datepicker._get(inst, "stepMonths")), "M");
8221     }
8222     // next month/year on alt +right
8223     break;
8224     case 40: if (event.ctrlKey || event.metaKey) {
8225     $.datepicker._adjustDate(event.target, +7, "D");
8226     }
8227     handled = event.ctrlKey || event.metaKey;
8228     break; // +1 week on ctrl or command +down
8229     default: handled = false;
8230     }
8231     } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8232     $.datepicker._showDatepicker(this);
8233     } else {
8234     handled = false;
8235     }
8236    
8237     if (handled) {
8238     event.preventDefault();
8239     event.stopPropagation();
8240     }
8241     },
8242    
8243     /* Filter entered characters - based on date format. */
8244     _doKeyPress: function(event) {
8245     var chars, chr,
8246     inst = $.datepicker._getInst(event.target);
8247    
8248     if ($.datepicker._get(inst, "constrainInput")) {
8249     chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8250     chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8251     return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8252     }
8253     },
8254    
8255     /* Synchronise manual entry and field/alternate field. */
8256     _doKeyUp: function(event) {
8257     var date,
8258     inst = $.datepicker._getInst(event.target);
8259    
8260     if (inst.input.val() !== inst.lastVal) {
8261     try {
8262     date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8263     (inst.input ? inst.input.val() : null),
8264     $.datepicker._getFormatConfig(inst));
8265    
8266     if (date) { // only if valid
8267     $.datepicker._setDateFromField(inst);
8268     $.datepicker._updateAlternate(inst);
8269     $.datepicker._updateDatepicker(inst);
8270     }
8271     }
8272     catch (err) {
8273     }
8274     }
8275     return true;
8276     },
8277    
8278     /* Pop-up the date picker for a given input field.
8279     * If false returned from beforeShow event handler do not show.
8280     * @param input element - the input field attached to the date picker or
8281     * event - if triggered by focus
8282     */
8283     _showDatepicker: function(input) {
8284     input = input.target || input;
8285     if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8286     input = $("input", input.parentNode)[0];
8287     }
8288    
8289     if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8290     return;
8291     }
8292    
8293     var inst, beforeShow, beforeShowSettings, isFixed,
8294     offset, showAnim, duration;
8295    
8296     inst = $.datepicker._getInst(input);
8297     if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8298     $.datepicker._curInst.dpDiv.stop(true, true);
8299     if ( inst && $.datepicker._datepickerShowing ) {
8300     $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8301     }
8302     }
8303    
8304     beforeShow = $.datepicker._get(inst, "beforeShow");
8305     beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8306     if(beforeShowSettings === false){
8307     return;
8308     }
8309     extendRemove(inst.settings, beforeShowSettings);
8310    
8311     inst.lastVal = null;
8312     $.datepicker._lastInput = input;
8313     $.datepicker._setDateFromField(inst);
8314    
8315     if ($.datepicker._inDialog) { // hide cursor
8316     input.value = "";
8317     }
8318     if (!$.datepicker._pos) { // position below input
8319     $.datepicker._pos = $.datepicker._findPos(input);
8320     $.datepicker._pos[1] += input.offsetHeight; // add the height
8321     }
8322    
8323     isFixed = false;
8324     $(input).parents().each(function() {
8325     isFixed |= $(this).css("position") === "fixed";
8326     return !isFixed;
8327     });
8328    
8329     offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8330     $.datepicker._pos = null;
8331     //to avoid flashes on Firefox
8332     inst.dpDiv.empty();
8333     // determine sizing offscreen
8334     inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8335     $.datepicker._updateDatepicker(inst);
8336     // fix width for dynamic number of date pickers
8337     // and adjust position before showing
8338     offset = $.datepicker._checkOffset(inst, offset, isFixed);
8339     inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8340     "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8341     left: offset.left + "px", top: offset.top + "px"});
8342    
8343     if (!inst.inline) {
8344     showAnim = $.datepicker._get(inst, "showAnim");
8345     duration = $.datepicker._get(inst, "duration");
8346     inst.dpDiv.zIndex($(input).zIndex()+1);
8347     $.datepicker._datepickerShowing = true;
8348    
8349     if ( $.effects && $.effects.effect[ showAnim ] ) {
8350     inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8351     } else {
8352     inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8353     }
8354    
8355     if ( $.datepicker._shouldFocusInput( inst ) ) {
8356     inst.input.focus();
8357     }
8358    
8359     $.datepicker._curInst = inst;
8360     }
8361     },
8362    
8363     /* Generate the date picker content. */
8364     _updateDatepicker: function(inst) {
8365     this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8366     instActive = inst; // for delegate hover events
8367     inst.dpDiv.empty().append(this._generateHTML(inst));
8368     this._attachHandlers(inst);
8369     inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
8370    
8371     var origyearshtml,
8372     numMonths = this._getNumberOfMonths(inst),
8373     cols = numMonths[1],
8374     width = 17;
8375    
8376     inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8377     if (cols > 1) {
8378     inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8379     }
8380     inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8381     "Class"]("ui-datepicker-multi");
8382     inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8383     "Class"]("ui-datepicker-rtl");
8384    
8385     if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8386     inst.input.focus();
8387     }
8388    
8389     // deffered render of the years select (to avoid flashes on Firefox)
8390     if( inst.yearshtml ){
8391     origyearshtml = inst.yearshtml;
8392     setTimeout(function(){
8393     //assure that inst.yearshtml didn't change.
8394     if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8395     inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8396     }
8397     origyearshtml = inst.yearshtml = null;
8398     }, 0);
8399     }
8400     },
8401    
8402     // #6694 - don't focus the input if it's already focused
8403     // this breaks the change event in IE
8404     // Support: IE and jQuery <1.9
8405     _shouldFocusInput: function( inst ) {
8406     return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8407     },
8408    
8409     /* Check positioning to remain on screen. */
8410     _checkOffset: function(inst, offset, isFixed) {
8411     var dpWidth = inst.dpDiv.outerWidth(),
8412     dpHeight = inst.dpDiv.outerHeight(),
8413     inputWidth = inst.input ? inst.input.outerWidth() : 0,
8414     inputHeight = inst.input ? inst.input.outerHeight() : 0,
8415     viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8416     viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8417    
8418     offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8419     offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8420     offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8421    
8422     // now check if datepicker is showing outside window viewport - move to a better place if so.
8423     offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8424     Math.abs(offset.left + dpWidth - viewWidth) : 0);
8425     offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8426     Math.abs(dpHeight + inputHeight) : 0);
8427    
8428     return offset;
8429     },
8430    
8431     /* Find an object's position on the screen. */
8432     _findPos: function(obj) {
8433     var position,
8434     inst = this._getInst(obj),
8435     isRTL = this._get(inst, "isRTL");
8436    
8437     while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8438     obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8439     }
8440    
8441     position = $(obj).offset();
8442     return [position.left, position.top];
8443     },
8444    
8445     /* Hide the date picker from view.
8446     * @param input element - the input field attached to the date picker
8447     */
8448     _hideDatepicker: function(input) {
8449     var showAnim, duration, postProcess, onClose,
8450     inst = this._curInst;
8451    
8452     if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
8453     return;
8454     }
8455    
8456     if (this._datepickerShowing) {
8457     showAnim = this._get(inst, "showAnim");
8458     duration = this._get(inst, "duration");
8459     postProcess = function() {
8460     $.datepicker._tidyDialog(inst);
8461     };
8462    
8463     // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8464     if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8465     inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8466     } else {
8467     inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8468     (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8469     }
8470    
8471     if (!showAnim) {
8472     postProcess();
8473     }
8474     this._datepickerShowing = false;
8475    
8476     onClose = this._get(inst, "onClose");
8477     if (onClose) {
8478     onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8479     }
8480    
8481     this._lastInput = null;
8482     if (this._inDialog) {
8483     this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8484     if ($.blockUI) {
8485     $.unblockUI();
8486     $("body").append(this.dpDiv);
8487     }
8488     }
8489     this._inDialog = false;
8490     }
8491     },
8492    
8493     /* Tidy up after a dialog display. */
8494     _tidyDialog: function(inst) {
8495     inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8496     },
8497    
8498     /* Close date picker if clicked elsewhere. */
8499     _checkExternalClick: function(event) {
8500     if (!$.datepicker._curInst) {
8501     return;
8502     }
8503    
8504     var $target = $(event.target),
8505     inst = $.datepicker._getInst($target[0]);
8506    
8507     if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8508     $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8509     !$target.hasClass($.datepicker.markerClassName) &&
8510     !$target.closest("." + $.datepicker._triggerClass).length &&
8511     $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8512     ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8513     $.datepicker._hideDatepicker();
8514     }
8515     },
8516    
8517     /* Adjust one of the date sub-fields. */
8518     _adjustDate: function(id, offset, period) {
8519     var target = $(id),
8520     inst = this._getInst(target[0]);
8521    
8522     if (this._isDisabledDatepicker(target[0])) {
8523     return;
8524     }
8525     this._adjustInstDate(inst, offset +
8526     (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8527     period);
8528     this._updateDatepicker(inst);
8529     },
8530    
8531     /* Action for current link. */
8532     _gotoToday: function(id) {
8533     var date,
8534     target = $(id),
8535     inst = this._getInst(target[0]);
8536    
8537     if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8538     inst.selectedDay = inst.currentDay;
8539     inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8540     inst.drawYear = inst.selectedYear = inst.currentYear;
8541     } else {
8542     date = new Date();
8543     inst.selectedDay = date.getDate();
8544     inst.drawMonth = inst.selectedMonth = date.getMonth();
8545     inst.drawYear = inst.selectedYear = date.getFullYear();
8546     }
8547     this._notifyChange(inst);
8548     this._adjustDate(target);
8549     },
8550    
8551     /* Action for selecting a new month/year. */
8552     _selectMonthYear: function(id, select, period) {
8553     var target = $(id),
8554     inst = this._getInst(target[0]);
8555    
8556     inst["selected" + (period === "M" ? "Month" : "Year")] =
8557     inst["draw" + (period === "M" ? "Month" : "Year")] =
8558     parseInt(select.options[select.selectedIndex].value,10);
8559    
8560     this._notifyChange(inst);
8561     this._adjustDate(target);
8562     },
8563    
8564     /* Action for selecting a day. */
8565     _selectDay: function(id, month, year, td) {
8566     var inst,
8567     target = $(id);
8568    
8569     if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8570     return;
8571     }
8572    
8573     inst = this._getInst(target[0]);
8574     inst.selectedDay = inst.currentDay = $("a", td).html();
8575     inst.selectedMonth = inst.currentMonth = month;
8576     inst.selectedYear = inst.currentYear = year;
8577     this._selectDate(id, this._formatDate(inst,
8578     inst.currentDay, inst.currentMonth, inst.currentYear));
8579     },
8580    
8581     /* Erase the input field and hide the date picker. */
8582     _clearDate: function(id) {
8583     var target = $(id);
8584     this._selectDate(target, "");
8585     },
8586    
8587     /* Update the input field with the selected date. */
8588     _selectDate: function(id, dateStr) {
8589     var onSelect,
8590     target = $(id),
8591     inst = this._getInst(target[0]);
8592    
8593     dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8594     if (inst.input) {
8595     inst.input.val(dateStr);
8596     }
8597     this._updateAlternate(inst);
8598    
8599     onSelect = this._get(inst, "onSelect");
8600     if (onSelect) {
8601     onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
8602     } else if (inst.input) {
8603     inst.input.trigger("change"); // fire the change event
8604     }
8605    
8606     if (inst.inline){
8607     this._updateDatepicker(inst);
8608     } else {
8609     this._hideDatepicker();
8610     this._lastInput = inst.input[0];
8611     if (typeof(inst.input[0]) !== "object") {
8612     inst.input.focus(); // restore focus
8613     }
8614     this._lastInput = null;
8615     }
8616     },
8617    
8618     /* Update any alternate field to synchronise with the main field. */
8619     _updateAlternate: function(inst) {
8620     var altFormat, date, dateStr,
8621     altField = this._get(inst, "altField");
8622    
8623     if (altField) { // update alternate field too
8624     altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8625     date = this._getDate(inst);
8626     dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8627     $(altField).each(function() { $(this).val(dateStr); });
8628     }
8629     },
8630    
8631     /* Set as beforeShowDay function to prevent selection of weekends.
8632     * @param date Date - the date to customise
8633     * @return [boolean, string] - is this date selectable?, what is its CSS class?
8634     */
8635     noWeekends: function(date) {
8636     var day = date.getDay();
8637     return [(day > 0 && day < 6), ""];
8638     },
8639    
8640     /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8641     * @param date Date - the date to get the week for
8642     * @return number - the number of the week within the year that contains this date
8643     */
8644     iso8601Week: function(date) {
8645     var time,
8646     checkDate = new Date(date.getTime());
8647    
8648     // Find Thursday of this week starting on Monday
8649     checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8650    
8651     time = checkDate.getTime();
8652     checkDate.setMonth(0); // Compare with Jan 1
8653     checkDate.setDate(1);
8654     return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8655     },
8656    
8657     /* Parse a string value into a date object.
8658     * See formatDate below for the possible formats.
8659     *
8660     * @param format string - the expected format of the date
8661     * @param value string - the date in the above format
8662     * @param settings Object - attributes include:
8663     * shortYearCutoff number - the cutoff year for determining the century (optional)
8664     * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8665     * dayNames string[7] - names of the days from Sunday (optional)
8666     * monthNamesShort string[12] - abbreviated names of the months (optional)
8667     * monthNames string[12] - names of the months (optional)
8668     * @return Date - the extracted date value or null if value is blank
8669     */
8670     parseDate: function (format, value, settings) {
8671     if (format == null || value == null) {
8672     throw "Invalid arguments";
8673     }
8674    
8675     value = (typeof value === "object" ? value.toString() : value + "");
8676     if (value === "") {
8677     return null;
8678     }
8679    
8680     var iFormat, dim, extra,
8681     iValue = 0,
8682     shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8683     shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8684     new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8685     dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8686     dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8687     monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8688     monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8689     year = -1,
8690     month = -1,
8691     day = -1,
8692     doy = -1,
8693     literal = false,
8694     date,
8695     // Check whether a format character is doubled
8696     lookAhead = function(match) {
8697     var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8698     if (matches) {
8699     iFormat++;
8700     }
8701     return matches;
8702     },
8703     // Extract a number from the string value
8704     getNumber = function(match) {
8705     var isDoubled = lookAhead(match),
8706     size = (match === "@" ? 14 : (match === "!" ? 20 :
8707     (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8708     digits = new RegExp("^\\d{1," + size + "}"),
8709     num = value.substring(iValue).match(digits);
8710     if (!num) {
8711     throw "Missing number at position " + iValue;
8712     }
8713     iValue += num[0].length;
8714     return parseInt(num[0], 10);
8715     },
8716     // Extract a name from the string value and convert to an index
8717     getName = function(match, shortNames, longNames) {
8718     var index = -1,
8719     names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8720     return [ [k, v] ];
8721     }).sort(function (a, b) {
8722     return -(a[1].length - b[1].length);
8723     });
8724    
8725     $.each(names, function (i, pair) {
8726     var name = pair[1];
8727     if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8728     index = pair[0];
8729     iValue += name.length;
8730     return false;
8731     }
8732     });
8733     if (index !== -1) {
8734     return index + 1;
8735     } else {
8736     throw "Unknown name at position " + iValue;
8737     }
8738     },
8739     // Confirm that a literal character matches the string value
8740     checkLiteral = function() {
8741     if (value.charAt(iValue) !== format.charAt(iFormat)) {
8742     throw "Unexpected literal at position " + iValue;
8743     }
8744     iValue++;
8745     };
8746    
8747     for (iFormat = 0; iFormat < format.length; iFormat++) {
8748     if (literal) {
8749     if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8750     literal = false;
8751     } else {
8752     checkLiteral();
8753     }
8754     } else {
8755     switch (format.charAt(iFormat)) {
8756     case "d":
8757     day = getNumber("d");
8758     break;
8759     case "D":
8760     getName("D", dayNamesShort, dayNames);
8761     break;
8762     case "o":
8763     doy = getNumber("o");
8764     break;
8765     case "m":
8766     month = getNumber("m");
8767     break;
8768     case "M":
8769     month = getName("M", monthNamesShort, monthNames);
8770     break;
8771     case "y":
8772     year = getNumber("y");
8773     break;
8774     case "@":
8775     date = new Date(getNumber("@"));
8776     year = date.getFullYear();
8777     month = date.getMonth() + 1;
8778     day = date.getDate();
8779     break;
8780     case "!":
8781     date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8782     year = date.getFullYear();
8783     month = date.getMonth() + 1;
8784     day = date.getDate();
8785     break;
8786     case "'":
8787     if (lookAhead("'")){
8788     checkLiteral();
8789     } else {
8790     literal = true;
8791     }
8792     break;
8793     default:
8794     checkLiteral();
8795     }
8796     }
8797     }
8798    
8799     if (iValue < value.length){
8800     extra = value.substr(iValue);
8801     if (!/^\s+/.test(extra)) {
8802     throw "Extra/unparsed characters found in date: " + extra;
8803     }
8804     }
8805    
8806     if (year === -1) {
8807     year = new Date().getFullYear();
8808     } else if (year < 100) {
8809     year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8810     (year <= shortYearCutoff ? 0 : -100);
8811     }
8812    
8813     if (doy > -1) {
8814     month = 1;
8815     day = doy;
8816     do {
8817     dim = this._getDaysInMonth(year, month - 1);
8818     if (day <= dim) {
8819     break;
8820     }
8821     month++;
8822     day -= dim;
8823     } while (true);
8824     }
8825    
8826     date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8827     if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8828     throw "Invalid date"; // E.g. 31/02/00
8829     }
8830     return date;
8831     },
8832    
8833     /* Standard date formats. */
8834     ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8835     COOKIE: "D, dd M yy",
8836     ISO_8601: "yy-mm-dd",
8837     RFC_822: "D, d M y",
8838     RFC_850: "DD, dd-M-y",
8839     RFC_1036: "D, d M y",
8840     RFC_1123: "D, d M yy",
8841     RFC_2822: "D, d M yy",
8842     RSS: "D, d M y", // RFC 822
8843     TICKS: "!",
8844     TIMESTAMP: "@",
8845     W3C: "yy-mm-dd", // ISO 8601
8846    
8847     _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8848     Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8849    
8850     /* Format a date object into a string value.
8851     * The format can be combinations of the following:
8852     * d - day of month (no leading zero)
8853     * dd - day of month (two digit)
8854     * o - day of year (no leading zeros)
8855     * oo - day of year (three digit)
8856     * D - day name short
8857     * DD - day name long
8858     * m - month of year (no leading zero)
8859     * mm - month of year (two digit)
8860     * M - month name short
8861     * MM - month name long
8862     * y - year (two digit)
8863     * yy - year (four digit)
8864     * @ - Unix timestamp (ms since 01/01/1970)
8865     * ! - Windows ticks (100ns since 01/01/0001)
8866     * "..." - literal text
8867     * '' - single quote
8868     *
8869     * @param format string - the desired format of the date
8870     * @param date Date - the date value to format
8871     * @param settings Object - attributes include:
8872     * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8873     * dayNames string[7] - names of the days from Sunday (optional)
8874     * monthNamesShort string[12] - abbreviated names of the months (optional)
8875     * monthNames string[12] - names of the months (optional)
8876     * @return string - the date in the above format
8877     */
8878     formatDate: function (format, date, settings) {
8879     if (!date) {
8880     return "";
8881     }
8882    
8883     var iFormat,
8884     dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8885     dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8886     monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8887     monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8888     // Check whether a format character is doubled
8889     lookAhead = function(match) {
8890     var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8891     if (matches) {
8892     iFormat++;
8893     }
8894     return matches;
8895     },
8896     // Format a number, with leading zero if necessary
8897     formatNumber = function(match, value, len) {
8898     var num = "" + value;
8899     if (lookAhead(match)) {
8900     while (num.length < len) {
8901     num = "0" + num;
8902     }
8903     }
8904     return num;
8905     },
8906     // Format a name, short or long as requested
8907     formatName = function(match, value, shortNames, longNames) {
8908     return (lookAhead(match) ? longNames[value] : shortNames[value]);
8909     },
8910     output = "",
8911     literal = false;
8912    
8913     if (date) {
8914     for (iFormat = 0; iFormat < format.length; iFormat++) {
8915     if (literal) {
8916     if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8917     literal = false;
8918     } else {
8919     output += format.charAt(iFormat);
8920     }
8921     } else {
8922     switch (format.charAt(iFormat)) {
8923     case "d":
8924     output += formatNumber("d", date.getDate(), 2);
8925     break;
8926     case "D":
8927     output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8928     break;
8929     case "o":
8930     output += formatNumber("o",
8931     Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8932     break;
8933     case "m":
8934     output += formatNumber("m", date.getMonth() + 1, 2);
8935     break;
8936     case "M":
8937     output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8938     break;
8939     case "y":
8940     output += (lookAhead("y") ? date.getFullYear() :
8941     (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8942     break;
8943     case "@":
8944     output += date.getTime();
8945     break;
8946     case "!":
8947     output += date.getTime() * 10000 + this._ticksTo1970;
8948     break;
8949     case "'":
8950     if (lookAhead("'")) {
8951     output += "'";
8952     } else {
8953     literal = true;
8954     }
8955     break;
8956     default:
8957     output += format.charAt(iFormat);
8958     }
8959     }
8960     }
8961     }
8962     return output;
8963     },
8964    
8965     /* Extract all possible characters from the date format. */
8966     _possibleChars: function (format) {
8967     var iFormat,
8968     chars = "",
8969     literal = false,
8970     // Check whether a format character is doubled
8971     lookAhead = function(match) {
8972     var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8973     if (matches) {
8974     iFormat++;
8975     }
8976     return matches;
8977     };
8978    
8979     for (iFormat = 0; iFormat < format.length; iFormat++) {
8980     if (literal) {
8981     if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8982     literal = false;
8983     } else {
8984     chars += format.charAt(iFormat);
8985     }
8986     } else {
8987     switch (format.charAt(iFormat)) {
8988     case "d": case "m": case "y": case "@":
8989     chars += "0123456789";
8990     break;
8991     case "D": case "M":
8992     return null; // Accept anything
8993     case "'":
8994     if (lookAhead("'")) {
8995     chars += "'";
8996     } else {
8997     literal = true;
8998     }
8999     break;
9000     default:
9001     chars += format.charAt(iFormat);
9002     }
9003     }
9004     }
9005     return chars;
9006     },
9007    
9008     /* Get a setting value, defaulting if necessary. */
9009     _get: function(inst, name) {
9010     return inst.settings[name] !== undefined ?
9011     inst.settings[name] : this._defaults[name];
9012     },
9013    
9014     /* Parse existing date and initialise date picker. */
9015     _setDateFromField: function(inst, noDefault) {
9016     if (inst.input.val() === inst.lastVal) {
9017     return;
9018     }
9019    
9020     var dateFormat = this._get(inst, "dateFormat"),
9021     dates = inst.lastVal = inst.input ? inst.input.val() : null,
9022     defaultDate = this._getDefaultDate(inst),
9023     date = defaultDate,
9024     settings = this._getFormatConfig(inst);
9025    
9026     try {
9027     date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9028     } catch (event) {
9029     dates = (noDefault ? "" : dates);
9030     }
9031     inst.selectedDay = date.getDate();
9032     inst.drawMonth = inst.selectedMonth = date.getMonth();
9033     inst.drawYear = inst.selectedYear = date.getFullYear();
9034     inst.currentDay = (dates ? date.getDate() : 0);
9035     inst.currentMonth = (dates ? date.getMonth() : 0);
9036     inst.currentYear = (dates ? date.getFullYear() : 0);
9037     this._adjustInstDate(inst);
9038     },
9039    
9040     /* Retrieve the default date shown on opening. */
9041     _getDefaultDate: function(inst) {
9042     return this._restrictMinMax(inst,
9043     this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9044     },
9045    
9046     /* A date may be specified as an exact value or a relative one. */
9047     _determineDate: function(inst, date, defaultDate) {
9048     var offsetNumeric = function(offset) {
9049     var date = new Date();
9050     date.setDate(date.getDate() + offset);
9051     return date;
9052     },
9053     offsetString = function(offset) {
9054     try {
9055     return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9056     offset, $.datepicker._getFormatConfig(inst));
9057     }
9058     catch (e) {
9059     // Ignore
9060     }
9061    
9062     var date = (offset.toLowerCase().match(/^c/) ?
9063     $.datepicker._getDate(inst) : null) || new Date(),
9064     year = date.getFullYear(),
9065     month = date.getMonth(),
9066     day = date.getDate(),
9067     pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9068     matches = pattern.exec(offset);
9069    
9070     while (matches) {
9071     switch (matches[2] || "d") {
9072     case "d" : case "D" :
9073     day += parseInt(matches[1],10); break;
9074     case "w" : case "W" :
9075     day += parseInt(matches[1],10) * 7; break;
9076     case "m" : case "M" :
9077     month += parseInt(matches[1],10);
9078     day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9079     break;
9080     case "y": case "Y" :
9081     year += parseInt(matches[1],10);
9082     day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9083     break;
9084     }
9085     matches = pattern.exec(offset);
9086     }
9087     return new Date(year, month, day);
9088     },
9089     newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9090     (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9091    
9092     newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9093     if (newDate) {
9094     newDate.setHours(0);
9095     newDate.setMinutes(0);
9096     newDate.setSeconds(0);
9097     newDate.setMilliseconds(0);
9098     }
9099     return this._daylightSavingAdjust(newDate);
9100     },
9101    
9102     /* Handle switch to/from daylight saving.
9103     * Hours may be non-zero on daylight saving cut-over:
9104     * > 12 when midnight changeover, but then cannot generate
9105     * midnight datetime, so jump to 1AM, otherwise reset.
9106     * @param date (Date) the date to check
9107     * @return (Date) the corrected date
9108     */
9109     _daylightSavingAdjust: function(date) {
9110     if (!date) {
9111     return null;
9112     }
9113     date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9114     return date;
9115     },
9116    
9117     /* Set the date(s) directly. */
9118     _setDate: function(inst, date, noChange) {
9119     var clear = !date,
9120     origMonth = inst.selectedMonth,
9121     origYear = inst.selectedYear,
9122     newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9123    
9124     inst.selectedDay = inst.currentDay = newDate.getDate();
9125     inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9126     inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9127     if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9128     this._notifyChange(inst);
9129     }
9130     this._adjustInstDate(inst);
9131     if (inst.input) {
9132     inst.input.val(clear ? "" : this._formatDate(inst));
9133     }
9134     },
9135    
9136     /* Retrieve the date(s) directly. */
9137     _getDate: function(inst) {
9138     var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9139     this._daylightSavingAdjust(new Date(
9140     inst.currentYear, inst.currentMonth, inst.currentDay)));
9141     return startDate;
9142     },
9143    
9144     /* Attach the onxxx handlers. These are declared statically so
9145     * they work with static code transformers like Caja.
9146     */
9147     _attachHandlers: function(inst) {
9148     var stepMonths = this._get(inst, "stepMonths"),
9149     id = "#" + inst.id.replace( /\\\\/g, "\\" );
9150     inst.dpDiv.find("[data-handler]").map(function () {
9151     var handler = {
9152     prev: function () {
9153     $.datepicker._adjustDate(id, -stepMonths, "M");
9154     },
9155     next: function () {
9156     $.datepicker._adjustDate(id, +stepMonths, "M");
9157     },
9158     hide: function () {
9159     $.datepicker._hideDatepicker();
9160     },
9161     today: function () {
9162     $.datepicker._gotoToday(id);
9163     },
9164     selectDay: function () {
9165     $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9166     return false;
9167     },
9168     selectMonth: function () {
9169     $.datepicker._selectMonthYear(id, this, "M");
9170     return false;
9171     },
9172     selectYear: function () {
9173     $.datepicker._selectMonthYear(id, this, "Y");
9174     return false;
9175     }
9176     };
9177     $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9178     });
9179     },
9180    
9181     /* Generate the HTML for the current state of the date picker. */
9182     _generateHTML: function(inst) {
9183     var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9184     controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9185     monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9186     selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9187     cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9188     printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9189     tempDate = new Date(),
9190     today = this._daylightSavingAdjust(
9191     new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9192     isRTL = this._get(inst, "isRTL"),
9193     showButtonPanel = this._get(inst, "showButtonPanel"),
9194     hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9195     navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9196     numMonths = this._getNumberOfMonths(inst),
9197     showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9198     stepMonths = this._get(inst, "stepMonths"),
9199     isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9200     currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9201     new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9202     minDate = this._getMinMaxDate(inst, "min"),
9203     maxDate = this._getMinMaxDate(inst, "max"),
9204     drawMonth = inst.drawMonth - showCurrentAtPos,
9205     drawYear = inst.drawYear;
9206    
9207     if (drawMonth < 0) {
9208     drawMonth += 12;
9209     drawYear--;
9210     }
9211     if (maxDate) {
9212     maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9213     maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9214     maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9215     while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9216     drawMonth--;
9217     if (drawMonth < 0) {
9218     drawMonth = 11;
9219     drawYear--;
9220     }
9221     }
9222     }
9223     inst.drawMonth = drawMonth;
9224     inst.drawYear = drawYear;
9225    
9226     prevText = this._get(inst, "prevText");
9227     prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9228     this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9229     this._getFormatConfig(inst)));
9230    
9231     prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9232     "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9233     " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9234     (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>"));
9235    
9236     nextText = this._get(inst, "nextText");
9237     nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9238     this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9239     this._getFormatConfig(inst)));
9240    
9241     next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9242     "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9243     " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9244     (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>"));
9245    
9246     currentText = this._get(inst, "currentText");
9247     gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9248     currentText = (!navigationAsDateFormat ? currentText :
9249     this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9250    
9251     controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
9252     this._get(inst, "closeText") + "</button>" : "");
9253    
9254     buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9255     (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
9256     ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9257    
9258     firstDay = parseInt(this._get(inst, "firstDay"),10);
9259     firstDay = (isNaN(firstDay) ? 0 : firstDay);
9260    
9261     showWeek = this._get(inst, "showWeek");
9262     dayNames = this._get(inst, "dayNames");
9263     dayNamesMin = this._get(inst, "dayNamesMin");
9264     monthNames = this._get(inst, "monthNames");
9265     monthNamesShort = this._get(inst, "monthNamesShort");
9266     beforeShowDay = this._get(inst, "beforeShowDay");
9267     showOtherMonths = this._get(inst, "showOtherMonths");
9268     selectOtherMonths = this._get(inst, "selectOtherMonths");
9269     defaultDate = this._getDefaultDate(inst);
9270     html = "";
9271     dow;
9272     for (row = 0; row < numMonths[0]; row++) {
9273     group = "";
9274     this.maxRows = 4;
9275     for (col = 0; col < numMonths[1]; col++) {
9276     selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9277     cornerClass = " ui-corner-all";
9278     calender = "";
9279     if (isMultiMonth) {
9280     calender += "<div class='ui-datepicker-group";
9281     if (numMonths[1] > 1) {
9282     switch (col) {
9283     case 0: calender += " ui-datepicker-group-first";
9284     cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9285     case numMonths[1]-1: calender += " ui-datepicker-group-last";
9286     cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9287     default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9288     }
9289     }
9290     calender += "'>";
9291     }
9292     calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9293     (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9294     (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9295     this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9296     row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9297     "</div><table class='ui-datepicker-calendar'><thead>" +
9298     "<tr>";
9299     thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9300     for (dow = 0; dow < 7; dow++) { // days of the week
9301     day = (dow + firstDay) % 7;
9302     thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9303     "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9304     }
9305     calender += thead + "</tr></thead><tbody>";
9306     daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9307     if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9308     inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9309     }
9310     leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9311     curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9312     numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9313     this.maxRows = numRows;
9314     printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9315     for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9316     calender += "<tr>";
9317     tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9318     this._get(inst, "calculateWeek")(printDate) + "</td>");
9319     for (dow = 0; dow < 7; dow++) { // create date picker days
9320     daySettings = (beforeShowDay ?
9321     beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9322     otherMonth = (printDate.getMonth() !== drawMonth);
9323     unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9324     (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9325     tbody += "<td class='" +
9326     ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9327     (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9328     ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9329     (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9330     // or defaultDate is current printedDate and defaultDate is selectedDate
9331     " " + this._dayOverClass : "") + // highlight selected day
9332     (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days
9333     (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9334     (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9335     (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9336     ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9337     (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9338     (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9339     (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9340     (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9341     (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9342     (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9343     "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9344     printDate.setDate(printDate.getDate() + 1);
9345     printDate = this._daylightSavingAdjust(printDate);
9346     }
9347     calender += tbody + "</tr>";
9348     }
9349     drawMonth++;
9350     if (drawMonth > 11) {
9351     drawMonth = 0;
9352     drawYear++;
9353     }
9354     calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9355     ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9356     group += calender;
9357     }
9358     html += group;
9359     }
9360     html += buttonPanel;
9361     inst._keyEvent = false;
9362     return html;
9363     },
9364    
9365     /* Generate the month and year header. */
9366     _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9367     secondary, monthNames, monthNamesShort) {
9368    
9369     var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9370     changeMonth = this._get(inst, "changeMonth"),
9371     changeYear = this._get(inst, "changeYear"),
9372     showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9373     html = "<div class='ui-datepicker-title'>",
9374     monthHtml = "";
9375    
9376     // month selection
9377     if (secondary || !changeMonth) {
9378     monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9379     } else {
9380     inMinYear = (minDate && minDate.getFullYear() === drawYear);
9381     inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9382     monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9383     for ( month = 0; month < 12; month++) {
9384     if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9385     monthHtml += "<option value='" + month + "'" +
9386     (month === drawMonth ? " selected='selected'" : "") +
9387     ">" + monthNamesShort[month] + "</option>";
9388     }
9389     }
9390     monthHtml += "</select>";
9391     }
9392    
9393     if (!showMonthAfterYear) {
9394     html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9395     }
9396    
9397     // year selection
9398     if ( !inst.yearshtml ) {
9399     inst.yearshtml = "";
9400     if (secondary || !changeYear) {
9401     html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9402     } else {
9403     // determine range of years to display
9404     years = this._get(inst, "yearRange").split(":");
9405     thisYear = new Date().getFullYear();
9406     determineYear = function(value) {
9407     var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9408     (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9409     parseInt(value, 10)));
9410     return (isNaN(year) ? thisYear : year);
9411     };
9412     year = determineYear(years[0]);
9413     endYear = Math.max(year, determineYear(years[1] || ""));
9414     year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9415     endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9416     inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9417     for (; year <= endYear; year++) {
9418     inst.yearshtml += "<option value='" + year + "'" +
9419     (year === drawYear ? " selected='selected'" : "") +
9420     ">" + year + "</option>";
9421     }
9422     inst.yearshtml += "</select>";
9423    
9424     html += inst.yearshtml;
9425     inst.yearshtml = null;
9426     }
9427     }
9428    
9429     html += this._get(inst, "yearSuffix");
9430     if (showMonthAfterYear) {
9431     html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9432     }
9433     html += "</div>"; // Close datepicker_header
9434     return html;
9435     },
9436    
9437     /* Adjust one of the date sub-fields. */
9438     _adjustInstDate: function(inst, offset, period) {
9439     var year = inst.drawYear + (period === "Y" ? offset : 0),
9440     month = inst.drawMonth + (period === "M" ? offset : 0),
9441     day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9442     date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9443    
9444     inst.selectedDay = date.getDate();
9445     inst.drawMonth = inst.selectedMonth = date.getMonth();
9446     inst.drawYear = inst.selectedYear = date.getFullYear();
9447     if (period === "M" || period === "Y") {
9448     this._notifyChange(inst);
9449     }
9450     },
9451    
9452     /* Ensure a date is within any min/max bounds. */
9453     _restrictMinMax: function(inst, date) {
9454     var minDate = this._getMinMaxDate(inst, "min"),
9455     maxDate = this._getMinMaxDate(inst, "max"),
9456     newDate = (minDate && date < minDate ? minDate : date);
9457     return (maxDate && newDate > maxDate ? maxDate : newDate);
9458     },
9459    
9460     /* Notify change of month/year. */
9461     _notifyChange: function(inst) {
9462     var onChange = this._get(inst, "onChangeMonthYear");
9463     if (onChange) {
9464     onChange.apply((inst.input ? inst.input[0] : null),
9465     [inst.selectedYear, inst.selectedMonth + 1, inst]);
9466     }
9467     },
9468    
9469     /* Determine the number of months to show. */
9470     _getNumberOfMonths: function(inst) {
9471     var numMonths = this._get(inst, "numberOfMonths");
9472     return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9473     },
9474    
9475     /* Determine the current maximum date - ensure no time components are set. */
9476     _getMinMaxDate: function(inst, minMax) {
9477     return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9478     },
9479    
9480     /* Find the number of days in a given month. */
9481     _getDaysInMonth: function(year, month) {
9482     return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9483     },
9484    
9485     /* Find the day of the week of the first of a month. */
9486     _getFirstDayOfMonth: function(year, month) {
9487     return new Date(year, month, 1).getDay();
9488     },
9489    
9490     /* Determines if we should allow a "next/prev" month display change. */
9491     _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9492     var numMonths = this._getNumberOfMonths(inst),
9493     date = this._daylightSavingAdjust(new Date(curYear,
9494     curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9495    
9496     if (offset < 0) {
9497     date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9498     }
9499     return this._isInRange(inst, date);
9500     },
9501    
9502     /* Is the given date in the accepted range? */
9503     _isInRange: function(inst, date) {
9504     var yearSplit, currentYear,
9505     minDate = this._getMinMaxDate(inst, "min"),
9506     maxDate = this._getMinMaxDate(inst, "max"),
9507     minYear = null,
9508     maxYear = null,
9509     years = this._get(inst, "yearRange");
9510     if (years){
9511     yearSplit = years.split(":");
9512     currentYear = new Date().getFullYear();
9513     minYear = parseInt(yearSplit[0], 10);
9514     maxYear = parseInt(yearSplit[1], 10);
9515     if ( yearSplit[0].match(/[+\-].*/) ) {
9516     minYear += currentYear;
9517     }
9518     if ( yearSplit[1].match(/[+\-].*/) ) {
9519     maxYear += currentYear;
9520     }
9521     }
9522    
9523     return ((!minDate || date.getTime() >= minDate.getTime()) &&
9524     (!maxDate || date.getTime() <= maxDate.getTime()) &&
9525     (!minYear || date.getFullYear() >= minYear) &&
9526     (!maxYear || date.getFullYear() <= maxYear));
9527     },
9528    
9529     /* Provide the configuration settings for formatting/parsing. */
9530     _getFormatConfig: function(inst) {
9531     var shortYearCutoff = this._get(inst, "shortYearCutoff");
9532     shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9533     new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9534     return {shortYearCutoff: shortYearCutoff,
9535     dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9536     monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9537     },
9538    
9539     /* Format the given date for display. */
9540     _formatDate: function(inst, day, month, year) {
9541     if (!day) {
9542     inst.currentDay = inst.selectedDay;
9543     inst.currentMonth = inst.selectedMonth;
9544     inst.currentYear = inst.selectedYear;
9545     }
9546     var date = (day ? (typeof day === "object" ? day :
9547     this._daylightSavingAdjust(new Date(year, month, day))) :
9548     this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9549     return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9550     }
9551     });
9552    
9553     /*
9554     * Bind hover events for datepicker elements.
9555     * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9556     * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9557     */
9558     function bindHover(dpDiv) {
9559     var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9560     return dpDiv.delegate(selector, "mouseout", function() {
9561     $(this).removeClass("ui-state-hover");
9562     if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9563     $(this).removeClass("ui-datepicker-prev-hover");
9564     }
9565     if (this.className.indexOf("ui-datepicker-next") !== -1) {
9566     $(this).removeClass("ui-datepicker-next-hover");
9567     }
9568     })
9569     .delegate(selector, "mouseover", function(){
9570     if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
9571     $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9572     $(this).addClass("ui-state-hover");
9573     if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9574     $(this).addClass("ui-datepicker-prev-hover");
9575     }
9576     if (this.className.indexOf("ui-datepicker-next") !== -1) {
9577     $(this).addClass("ui-datepicker-next-hover");
9578     }
9579     }
9580     });
9581     }
9582    
9583     /* jQuery extend now ignores nulls! */
9584     function extendRemove(target, props) {
9585     $.extend(target, props);
9586     for (var name in props) {
9587     if (props[name] == null) {
9588     target[name] = props[name];
9589     }
9590     }
9591     return target;
9592     }
9593    
9594     /* Invoke the datepicker functionality.
9595     @param options string - a command, optionally followed by additional parameters or
9596     Object - settings for attaching new datepicker functionality
9597     @return jQuery object */
9598     $.fn.datepicker = function(options){
9599    
9600     /* Verify an empty collection wasn't passed - Fixes #6976 */
9601     if ( !this.length ) {
9602     return this;
9603     }
9604    
9605     /* Initialise the date picker. */
9606     if (!$.datepicker.initialized) {
9607     $(document).mousedown($.datepicker._checkExternalClick);
9608     $.datepicker.initialized = true;
9609     }
9610    
9611     /* Append datepicker main container to body if not exist. */
9612     if ($("#"+$.datepicker._mainDivId).length === 0) {
9613     $("body").append($.datepicker.dpDiv);
9614     }
9615    
9616     var otherArgs = Array.prototype.slice.call(arguments, 1);
9617     if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9618     return $.datepicker["_" + options + "Datepicker"].
9619     apply($.datepicker, [this[0]].concat(otherArgs));
9620     }
9621     if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9622     return $.datepicker["_" + options + "Datepicker"].
9623     apply($.datepicker, [this[0]].concat(otherArgs));
9624     }
9625     return this.each(function() {
9626     typeof options === "string" ?
9627     $.datepicker["_" + options + "Datepicker"].
9628     apply($.datepicker, [this].concat(otherArgs)) :
9629     $.datepicker._attachDatepicker(this, options);
9630     });
9631     };
9632    
9633     $.datepicker = new Datepicker(); // singleton instance
9634     $.datepicker.initialized = false;
9635     $.datepicker.uuid = new Date().getTime();
9636     $.datepicker.version = "1.10.3";
9637    
9638     })(jQuery);
9639    
9640     (function( $, undefined ) {
9641    
9642     var sizeRelatedOptions = {
9643     buttons: true,
9644     height: true,
9645     maxHeight: true,
9646     maxWidth: true,
9647     minHeight: true,
9648     minWidth: true,
9649     width: true
9650     },
9651     resizableRelatedOptions = {
9652     maxHeight: true,
9653     maxWidth: true,
9654     minHeight: true,
9655     minWidth: true
9656     };
9657    
9658     $.widget( "ui.dialog", {
9659     version: "1.10.3",
9660     options: {
9661     appendTo: "body",
9662     autoOpen: true,
9663     buttons: [],
9664     closeOnEscape: true,
9665     closeText: "close",
9666     dialogClass: "",
9667     draggable: true,
9668     hide: null,
9669     height: "auto",
9670     maxHeight: null,
9671     maxWidth: null,
9672     minHeight: 150,
9673     minWidth: 150,
9674     modal: false,
9675     position: {
9676     my: "center",
9677     at: "center",
9678     of: window,
9679     collision: "fit",
9680     // Ensure the titlebar is always visible
9681     using: function( pos ) {
9682     var topOffset = $( this ).css( pos ).offset().top;
9683     if ( topOffset < 0 ) {
9684     $( this ).css( "top", pos.top - topOffset );
9685     }
9686     }
9687     },
9688     resizable: true,
9689     show: null,
9690     title: null,
9691     width: 300,
9692    
9693     // callbacks
9694     beforeClose: null,
9695     close: null,
9696     drag: null,
9697     dragStart: null,
9698     dragStop: null,
9699     focus: null,
9700     open: null,
9701     resize: null,
9702     resizeStart: null,
9703     resizeStop: null
9704     },
9705    
9706     _create: function() {
9707     this.originalCss = {
9708     display: this.element[0].style.display,
9709     width: this.element[0].style.width,
9710     minHeight: this.element[0].style.minHeight,
9711     maxHeight: this.element[0].style.maxHeight,
9712     height: this.element[0].style.height
9713     };
9714     this.originalPosition = {
9715     parent: this.element.parent(),
9716     index: this.element.parent().children().index( this.element )
9717     };
9718     this.originalTitle = this.element.attr("title");
9719     this.options.title = this.options.title || this.originalTitle;
9720    
9721     this._createWrapper();
9722    
9723     this.element
9724     .show()
9725     .removeAttr("title")
9726     .addClass("ui-dialog-content ui-widget-content")
9727     .appendTo( this.uiDialog );
9728    
9729     this._createTitlebar();
9730     this._createButtonPane();
9731    
9732     if ( this.options.draggable && $.fn.draggable ) {
9733     this._makeDraggable();
9734     }
9735     if ( this.options.resizable && $.fn.resizable ) {
9736     this._makeResizable();
9737     }
9738    
9739     this._isOpen = false;
9740     },
9741    
9742     _init: function() {
9743     if ( this.options.autoOpen ) {
9744     this.open();
9745     }
9746     },
9747    
9748     _appendTo: function() {
9749     var element = this.options.appendTo;
9750     if ( element && (element.jquery || element.nodeType) ) {
9751     return $( element );
9752     }
9753     return this.document.find( element || "body" ).eq( 0 );
9754     },
9755    
9756     _destroy: function() {
9757     var next,
9758     originalPosition = this.originalPosition;
9759    
9760     this._destroyOverlay();
9761    
9762     this.element
9763     .removeUniqueId()
9764     .removeClass("ui-dialog-content ui-widget-content")
9765     .css( this.originalCss )
9766     // Without detaching first, the following becomes really slow
9767     .detach();
9768    
9769     this.uiDialog.stop( true, true ).remove();
9770    
9771     if ( this.originalTitle ) {
9772     this.element.attr( "title", this.originalTitle );
9773     }
9774    
9775     next = originalPosition.parent.children().eq( originalPosition.index );
9776     // Don't try to place the dialog next to itself (#8613)
9777     if ( next.length && next[0] !== this.element[0] ) {
9778     next.before( this.element );
9779     } else {
9780     originalPosition.parent.append( this.element );
9781     }
9782     },
9783    
9784     widget: function() {
9785     return this.uiDialog;
9786     },
9787    
9788     disable: $.noop,
9789     enable: $.noop,
9790    
9791     close: function( event ) {
9792     var that = this;
9793    
9794     if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
9795     return;
9796     }
9797    
9798     this._isOpen = false;
9799     this._destroyOverlay();
9800    
9801     if ( !this.opener.filter(":focusable").focus().length ) {
9802     // Hiding a focused element doesn't trigger blur in WebKit
9803     // so in case we have nothing to focus on, explicitly blur the active element
9804     // https://bugs.webkit.org/show_bug.cgi?id=47182
9805     $( this.document[0].activeElement ).blur();
9806     }
9807    
9808     this._hide( this.uiDialog, this.options.hide, function() {
9809     that._trigger( "close", event );
9810     });
9811     },
9812    
9813     isOpen: function() {
9814     return this._isOpen;
9815     },
9816    
9817     moveToTop: function() {
9818     this._moveToTop();
9819     },
9820    
9821     _moveToTop: function( event, silent ) {
9822     var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9823     if ( moved && !silent ) {
9824     this._trigger( "focus", event );
9825     }
9826     return moved;
9827     },
9828    
9829     open: function() {
9830     var that = this;
9831     if ( this._isOpen ) {
9832     if ( this._moveToTop() ) {
9833     this._focusTabbable();
9834     }
9835     return;
9836     }
9837    
9838     this._isOpen = true;
9839     this.opener = $( this.document[0].activeElement );
9840    
9841     this._size();
9842     this._position();
9843     this._createOverlay();
9844     this._moveToTop( null, true );
9845     this._show( this.uiDialog, this.options.show, function() {
9846     that._focusTabbable();
9847     that._trigger("focus");
9848     });
9849    
9850     this._trigger("open");
9851     },
9852    
9853     _focusTabbable: function() {
9854     // Set focus to the first match:
9855     // 1. First element inside the dialog matching [autofocus]
9856     // 2. Tabbable element inside the content element
9857     // 3. Tabbable element inside the buttonpane
9858     // 4. The close button
9859     // 5. The dialog itself
9860     var hasFocus = this.element.find("[autofocus]");
9861     if ( !hasFocus.length ) {
9862     hasFocus = this.element.find(":tabbable");
9863     }
9864     if ( !hasFocus.length ) {
9865     hasFocus = this.uiDialogButtonPane.find(":tabbable");
9866     }
9867     if ( !hasFocus.length ) {
9868     hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9869     }
9870     if ( !hasFocus.length ) {
9871     hasFocus = this.uiDialog;
9872     }
9873     hasFocus.eq( 0 ).focus();
9874     },
9875    
9876     _keepFocus: function( event ) {
9877     function checkFocus() {
9878     var activeElement = this.document[0].activeElement,
9879     isActive = this.uiDialog[0] === activeElement ||
9880     $.contains( this.uiDialog[0], activeElement );
9881     if ( !isActive ) {
9882     this._focusTabbable();
9883     }
9884     }
9885     event.preventDefault();
9886     checkFocus.call( this );
9887     // support: IE
9888     // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9889     // so we check again later
9890     this._delay( checkFocus );
9891     },
9892    
9893     _createWrapper: function() {
9894     this.uiDialog = $("<div>")
9895     .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9896     this.options.dialogClass )
9897     .hide()
9898     .attr({
9899     // Setting tabIndex makes the div focusable
9900     tabIndex: -1,
9901     role: "dialog"
9902     })
9903     .appendTo( this._appendTo() );
9904    
9905     this._on( this.uiDialog, {
9906     keydown: function( event ) {
9907     if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9908     event.keyCode === $.ui.keyCode.ESCAPE ) {
9909     event.preventDefault();
9910     this.close( event );
9911     return;
9912     }
9913    
9914     // prevent tabbing out of dialogs
9915     if ( event.keyCode !== $.ui.keyCode.TAB ) {
9916     return;
9917     }
9918     var tabbables = this.uiDialog.find(":tabbable"),
9919     first = tabbables.filter(":first"),
9920     last = tabbables.filter(":last");
9921    
9922     if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9923     first.focus( 1 );
9924     event.preventDefault();
9925     } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9926     last.focus( 1 );
9927     event.preventDefault();
9928     }
9929     },
9930     mousedown: function( event ) {
9931     if ( this._moveToTop( event ) ) {
9932     this._focusTabbable();
9933     }
9934     }
9935     });
9936    
9937     // We assume that any existing aria-describedby attribute means
9938     // that the dialog content is marked up properly
9939     // otherwise we brute force the content as the description
9940     if ( !this.element.find("[aria-describedby]").length ) {
9941     this.uiDialog.attr({
9942     "aria-describedby": this.element.uniqueId().attr("id")
9943     });
9944     }
9945     },
9946    
9947     _createTitlebar: function() {
9948     var uiDialogTitle;
9949    
9950     this.uiDialogTitlebar = $("<div>")
9951     .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9952     .prependTo( this.uiDialog );
9953     this._on( this.uiDialogTitlebar, {
9954     mousedown: function( event ) {
9955     // Don't prevent click on close button (#8838)
9956     // Focusing a dialog that is partially scrolled out of view
9957     // causes the browser to scroll it into view, preventing the click event
9958     if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9959     // Dialog isn't getting focus when dragging (#8063)
9960     this.uiDialog.focus();
9961     }
9962     }
9963     });
9964    
9965     this.uiDialogTitlebarClose = $("<button></button>")
9966     .button({
9967     label: this.options.closeText,
9968     icons: {
9969     primary: "ui-icon-closethick"
9970     },
9971     text: false
9972     })
9973     .addClass("ui-dialog-titlebar-close")
9974     .appendTo( this.uiDialogTitlebar );
9975     this._on( this.uiDialogTitlebarClose, {
9976     click: function( event ) {
9977     event.preventDefault();
9978     this.close( event );
9979     }
9980     });
9981    
9982     uiDialogTitle = $("<span>")
9983     .uniqueId()
9984     .addClass("ui-dialog-title")
9985     .prependTo( this.uiDialogTitlebar );
9986     this._title( uiDialogTitle );
9987    
9988     this.uiDialog.attr({
9989     "aria-labelledby": uiDialogTitle.attr("id")
9990     });
9991     },
9992    
9993     _title: function( title ) {
9994     if ( !this.options.title ) {
9995     title.html("&#160;");
9996     }
9997     title.text( this.options.title );
9998     },
9999    
10000     _createButtonPane: function() {
10001     this.uiDialogButtonPane = $("<div>")
10002     .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
10003    
10004     this.uiButtonSet = $("<div>")
10005     .addClass("ui-dialog-buttonset")
10006     .appendTo( this.uiDialogButtonPane );
10007    
10008     this._createButtons();
10009     },
10010    
10011     _createButtons: function() {
10012     var that = this,
10013     buttons = this.options.buttons;
10014    
10015     // if we already have a button pane, remove it
10016     this.uiDialogButtonPane.remove();
10017     this.uiButtonSet.empty();
10018    
10019     if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10020     this.uiDialog.removeClass("ui-dialog-buttons");
10021     return;
10022     }
10023    
10024     $.each( buttons, function( name, props ) {
10025     var click, buttonOptions;
10026     props = $.isFunction( props ) ?
10027     { click: props, text: name } :
10028     props;
10029     // Default to a non-submitting button
10030     props = $.extend( { type: "button" }, props );
10031     // Change the context for the click callback to be the main element
10032     click = props.click;
10033     props.click = function() {
10034     click.apply( that.element[0], arguments );
10035     };
10036     buttonOptions = {
10037     icons: props.icons,
10038     text: props.showText
10039     };
10040     delete props.icons;
10041     delete props.showText;
10042     $( "<button></button>", props )
10043     .button( buttonOptions )
10044     .appendTo( that.uiButtonSet );
10045     });
10046     this.uiDialog.addClass("ui-dialog-buttons");
10047     this.uiDialogButtonPane.appendTo( this.uiDialog );
10048     },
10049    
10050     _makeDraggable: function() {
10051     var that = this,
10052     options = this.options;
10053    
10054     function filteredUi( ui ) {
10055     return {
10056     position: ui.position,
10057     offset: ui.offset
10058     };
10059     }
10060    
10061     this.uiDialog.draggable({
10062     cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10063     handle: ".ui-dialog-titlebar",
10064     containment: "document",
10065     start: function( event, ui ) {
10066     $( this ).addClass("ui-dialog-dragging");
10067     that._blockFrames();
10068     that._trigger( "dragStart", event, filteredUi( ui ) );
10069     },
10070     drag: function( event, ui ) {
10071     that._trigger( "drag", event, filteredUi( ui ) );
10072     },
10073     stop: function( event, ui ) {
10074     options.position = [
10075     ui.position.left - that.document.scrollLeft(),
10076     ui.position.top - that.document.scrollTop()
10077     ];
10078     $( this ).removeClass("ui-dialog-dragging");
10079     that._unblockFrames();
10080     that._trigger( "dragStop", event, filteredUi( ui ) );
10081     }
10082     });
10083     },
10084    
10085     _makeResizable: function() {
10086     var that = this,
10087     options = this.options,
10088     handles = options.resizable,
10089     // .ui-resizable has position: relative defined in the stylesheet
10090     // but dialogs have to use absolute or fixed positioning
10091     position = this.uiDialog.css("position"),
10092     resizeHandles = typeof handles === "string" ?
10093     handles :
10094     "n,e,s,w,se,sw,ne,nw";
10095    
10096     function filteredUi( ui ) {
10097     return {
10098     originalPosition: ui.originalPosition,
10099     originalSize: ui.originalSize,
10100     position: ui.position,
10101     size: ui.size
10102     };
10103     }
10104    
10105     this.uiDialog.resizable({
10106     cancel: ".ui-dialog-content",
10107     containment: "document",
10108     alsoResize: this.element,
10109     maxWidth: options.maxWidth,
10110     maxHeight: options.maxHeight,
10111     minWidth: options.minWidth,
10112     minHeight: this._minHeight(),
10113     handles: resizeHandles,
10114     start: function( event, ui ) {
10115     $( this ).addClass("ui-dialog-resizing");
10116     that._blockFrames();
10117     that._trigger( "resizeStart", event, filteredUi( ui ) );
10118     },
10119     resize: function( event, ui ) {
10120     that._trigger( "resize", event, filteredUi( ui ) );
10121     },
10122     stop: function( event, ui ) {
10123     options.height = $( this ).height();
10124     options.width = $( this ).width();
10125     $( this ).removeClass("ui-dialog-resizing");
10126     that._unblockFrames();
10127     that._trigger( "resizeStop", event, filteredUi( ui ) );
10128     }
10129     })
10130     .css( "position", position );
10131     },
10132    
10133     _minHeight: function() {
10134     var options = this.options;
10135    
10136     return options.height === "auto" ?
10137     options.minHeight :
10138     Math.min( options.minHeight, options.height );
10139     },
10140    
10141     _position: function() {
10142     // Need to show the dialog to get the actual offset in the position plugin
10143     var isVisible = this.uiDialog.is(":visible");
10144     if ( !isVisible ) {
10145     this.uiDialog.show();
10146     }
10147     this.uiDialog.position( this.options.position );
10148     if ( !isVisible ) {
10149     this.uiDialog.hide();
10150     }
10151     },
10152    
10153     _setOptions: function( options ) {
10154     var that = this,
10155     resize = false,
10156     resizableOptions = {};
10157    
10158     $.each( options, function( key, value ) {
10159     that._setOption( key, value );
10160    
10161     if ( key in sizeRelatedOptions ) {
10162     resize = true;
10163     }
10164     if ( key in resizableRelatedOptions ) {
10165     resizableOptions[ key ] = value;
10166     }
10167     });
10168    
10169     if ( resize ) {
10170     this._size();
10171     this._position();
10172     }
10173     if ( this.uiDialog.is(":data(ui-resizable)") ) {
10174     this.uiDialog.resizable( "option", resizableOptions );
10175     }
10176     },
10177    
10178     _setOption: function( key, value ) {
10179     /*jshint maxcomplexity:15*/
10180     var isDraggable, isResizable,
10181     uiDialog = this.uiDialog;
10182    
10183     if ( key === "dialogClass" ) {
10184     uiDialog
10185     .removeClass( this.options.dialogClass )
10186     .addClass( value );
10187     }
10188    
10189     if ( key === "disabled" ) {
10190     return;
10191     }
10192    
10193     this._super( key, value );
10194    
10195     if ( key === "appendTo" ) {
10196     this.uiDialog.appendTo( this._appendTo() );
10197     }
10198    
10199     if ( key === "buttons" ) {
10200     this._createButtons();
10201     }
10202    
10203     if ( key === "closeText" ) {
10204     this.uiDialogTitlebarClose.button({
10205     // Ensure that we always pass a string
10206     label: "" + value
10207     });
10208     }
10209    
10210     if ( key === "draggable" ) {
10211     isDraggable = uiDialog.is(":data(ui-draggable)");
10212     if ( isDraggable && !value ) {
10213     uiDialog.draggable("destroy");
10214     }
10215    
10216     if ( !isDraggable && value ) {
10217     this._makeDraggable();
10218     }
10219     }
10220    
10221     if ( key === "position" ) {
10222     this._position();
10223     }
10224    
10225     if ( key === "resizable" ) {
10226     // currently resizable, becoming non-resizable
10227     isResizable = uiDialog.is(":data(ui-resizable)");
10228     if ( isResizable && !value ) {
10229     uiDialog.resizable("destroy");
10230     }
10231    
10232     // currently resizable, changing handles
10233     if ( isResizable && typeof value === "string" ) {
10234     uiDialog.resizable( "option", "handles", value );
10235     }
10236    
10237     // currently non-resizable, becoming resizable
10238     if ( !isResizable && value !== false ) {
10239     this._makeResizable();
10240     }
10241     }
10242    
10243     if ( key === "title" ) {
10244     this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
10245     }
10246     },
10247    
10248     _size: function() {
10249     // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10250     // divs will both have width and height set, so we need to reset them
10251     var nonContentHeight, minContentHeight, maxContentHeight,
10252     options = this.options;
10253    
10254     // Reset content sizing
10255     this.element.show().css({
10256     width: "auto",
10257     minHeight: 0,
10258     maxHeight: "none",
10259     height: 0
10260     });
10261    
10262     if ( options.minWidth > options.width ) {
10263     options.width = options.minWidth;
10264     }
10265    
10266     // reset wrapper sizing
10267     // determine the height of all the non-content elements
10268     nonContentHeight = this.uiDialog.css({
10269     height: "auto",
10270     width: options.width
10271     })
10272     .outerHeight();
10273     minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10274     maxContentHeight = typeof options.maxHeight === "number" ?
10275     Math.max( 0, options.maxHeight - nonContentHeight ) :
10276     "none";
10277    
10278     if ( options.height === "auto" ) {
10279     this.element.css({
10280     minHeight: minContentHeight,
10281     maxHeight: maxContentHeight,
10282     height: "auto"
10283     });
10284     } else {
10285     this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10286     }
10287    
10288     if (this.uiDialog.is(":data(ui-resizable)") ) {
10289     this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10290     }
10291     },
10292    
10293     _blockFrames: function() {
10294     this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10295     var iframe = $( this );
10296    
10297     return $( "<div>" )
10298     .css({
10299     position: "absolute",
10300     width: iframe.outerWidth(),
10301     height: iframe.outerHeight()
10302     })
10303     .appendTo( iframe.parent() )
10304     .offset( iframe.offset() )[0];
10305     });
10306     },
10307    
10308     _unblockFrames: function() {
10309     if ( this.iframeBlocks ) {
10310     this.iframeBlocks.remove();
10311     delete this.iframeBlocks;
10312     }
10313     },
10314    
10315     _allowInteraction: function( event ) {
10316     if ( $( event.target ).closest(".ui-dialog").length ) {
10317     return true;
10318     }
10319    
10320     // TODO: Remove hack when datepicker implements
10321     // the .ui-front logic (#8989)
10322     return !!$( event.target ).closest(".ui-datepicker").length;
10323     },
10324    
10325     _createOverlay: function() {
10326     if ( !this.options.modal ) {
10327     return;
10328     }
10329    
10330     var that = this,
10331     widgetFullName = this.widgetFullName;
10332     if ( !$.ui.dialog.overlayInstances ) {
10333     // Prevent use of anchors and inputs.
10334     // We use a delay in case the overlay is created from an
10335     // event that we're going to be cancelling. (#2804)
10336     this._delay(function() {
10337     // Handle .dialog().dialog("close") (#4065)
10338     if ( $.ui.dialog.overlayInstances ) {
10339     this.document.bind( "focusin.dialog", function( event ) {
10340     if ( !that._allowInteraction( event ) ) {
10341     event.preventDefault();
10342     $(".ui-dialog:visible:last .ui-dialog-content")
10343     .data( widgetFullName )._focusTabbable();
10344     }
10345     });
10346     }
10347     });
10348     }
10349    
10350     this.overlay = $("<div>")
10351     .addClass("ui-widget-overlay ui-front")
10352     .appendTo( this._appendTo() );
10353     this._on( this.overlay, {
10354     mousedown: "_keepFocus"
10355     });
10356     $.ui.dialog.overlayInstances++;
10357     },
10358    
10359     _destroyOverlay: function() {
10360     if ( !this.options.modal ) {
10361     return;
10362     }
10363    
10364     if ( this.overlay ) {
10365     $.ui.dialog.overlayInstances--;
10366    
10367     if ( !$.ui.dialog.overlayInstances ) {
10368     this.document.unbind( "focusin.dialog" );
10369     }
10370     this.overlay.remove();
10371     this.overlay = null;
10372     }
10373     }
10374     });
10375    
10376     $.ui.dialog.overlayInstances = 0;
10377    
10378     // DEPRECATED
10379     if ( $.uiBackCompat !== false ) {
10380     // position option with array notation
10381     // just override with old implementation
10382     $.widget( "ui.dialog", $.ui.dialog, {
10383     _position: function() {
10384     var position = this.options.position,
10385     myAt = [],
10386     offset = [ 0, 0 ],
10387     isVisible;
10388    
10389     if ( position ) {
10390     if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
10391     myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
10392     if ( myAt.length === 1 ) {
10393     myAt[1] = myAt[0];
10394     }
10395    
10396     $.each( [ "left", "top" ], function( i, offsetPosition ) {
10397     if ( +myAt[ i ] === myAt[ i ] ) {
10398     offset[ i ] = myAt[ i ];
10399     myAt[ i ] = offsetPosition;
10400     }
10401     });
10402    
10403     position = {
10404     my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
10405     myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
10406     at: myAt.join(" ")
10407     };
10408     }
10409    
10410     position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
10411     } else {
10412     position = $.ui.dialog.prototype.options.position;
10413     }
10414    
10415     // need to show the dialog to get the actual offset in the position plugin
10416     isVisible = this.uiDialog.is(":visible");
10417     if ( !isVisible ) {
10418     this.uiDialog.show();
10419     }
10420     this.uiDialog.position( position );
10421     if ( !isVisible ) {
10422     this.uiDialog.hide();
10423     }
10424     }
10425     });
10426     }
10427    
10428     }( jQuery ) );
10429    
10430     (function( $, undefined ) {
10431    
10432     var rvertical = /up|down|vertical/,
10433     rpositivemotion = /up|left|vertical|horizontal/;
10434    
10435     $.effects.effect.blind = function( o, done ) {
10436     // Create element
10437     var el = $( this ),
10438     props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10439     mode = $.effects.setMode( el, o.mode || "hide" ),
10440     direction = o.direction || "up",
10441     vertical = rvertical.test( direction ),
10442     ref = vertical ? "height" : "width",
10443     ref2 = vertical ? "top" : "left",
10444     motion = rpositivemotion.test( direction ),
10445     animation = {},
10446     show = mode === "show",
10447     wrapper, distance, margin;
10448    
10449     // if already wrapped, the wrapper's properties are my property. #6245
10450     if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10451     $.effects.save( el.parent(), props );
10452     } else {
10453     $.effects.save( el, props );
10454     }
10455     el.show();
10456     wrapper = $.effects.createWrapper( el ).css({
10457     overflow: "hidden"
10458     });
10459    
10460     distance = wrapper[ ref ]();
10461     margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10462    
10463     animation[ ref ] = show ? distance : 0;
10464     if ( !motion ) {
10465     el
10466     .css( vertical ? "bottom" : "right", 0 )
10467     .css( vertical ? "top" : "left", "auto" )
10468     .css({ position: "absolute" });
10469    
10470     animation[ ref2 ] = show ? margin : distance + margin;
10471     }
10472    
10473     // start at 0 if we are showing
10474     if ( show ) {
10475     wrapper.css( ref, 0 );
10476     if ( ! motion ) {
10477     wrapper.css( ref2, margin + distance );
10478     }
10479     }
10480    
10481     // Animate
10482     wrapper.animate( animation, {
10483     duration: o.duration,
10484     easing: o.easing,
10485     queue: false,
10486     complete: function() {
10487     if ( mode === "hide" ) {
10488     el.hide();
10489     }
10490     $.effects.restore( el, props );
10491     $.effects.removeWrapper( el );
10492     done();
10493     }
10494     });
10495    
10496     };
10497    
10498     })(jQuery);
10499    
10500     (function( $, undefined ) {
10501    
10502     $.effects.effect.bounce = function( o, done ) {
10503     var el = $( this ),
10504     props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10505    
10506     // defaults:
10507     mode = $.effects.setMode( el, o.mode || "effect" ),
10508     hide = mode === "hide",
10509     show = mode === "show",
10510     direction = o.direction || "up",
10511     distance = o.distance,
10512     times = o.times || 5,
10513    
10514     // number of internal animations
10515     anims = times * 2 + ( show || hide ? 1 : 0 ),
10516     speed = o.duration / anims,
10517     easing = o.easing,
10518    
10519     // utility:
10520     ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10521     motion = ( direction === "up" || direction === "left" ),
10522     i,
10523     upAnim,
10524     downAnim,
10525    
10526     // we will need to re-assemble the queue to stack our animations in place
10527     queue = el.queue(),
10528     queuelen = queue.length;
10529    
10530     // Avoid touching opacity to prevent clearType and PNG issues in IE
10531     if ( show || hide ) {
10532     props.push( "opacity" );
10533     }
10534    
10535     $.effects.save( el, props );
10536     el.show();
10537     $.effects.createWrapper( el ); // Create Wrapper
10538    
10539     // default distance for the BIGGEST bounce is the outer Distance / 3
10540     if ( !distance ) {
10541     distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10542     }
10543    
10544     if ( show ) {
10545     downAnim = { opacity: 1 };
10546     downAnim[ ref ] = 0;
10547    
10548     // if we are showing, force opacity 0 and set the initial position
10549     // then do the "first" animation
10550     el.css( "opacity", 0 )
10551     .css( ref, motion ? -distance * 2 : distance * 2 )
10552     .animate( downAnim, speed, easing );
10553     }
10554    
10555     // start at the smallest distance if we are hiding
10556     if ( hide ) {
10557     distance = distance / Math.pow( 2, times - 1 );
10558     }
10559    
10560     downAnim = {};
10561     downAnim[ ref ] = 0;
10562     // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10563     for ( i = 0; i < times; i++ ) {
10564     upAnim = {};
10565     upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10566    
10567     el.animate( upAnim, speed, easing )
10568     .animate( downAnim, speed, easing );
10569    
10570     distance = hide ? distance * 2 : distance / 2;
10571     }
10572    
10573     // Last Bounce when Hiding
10574     if ( hide ) {
10575     upAnim = { opacity: 0 };
10576     upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10577    
10578     el.animate( upAnim, speed, easing );
10579     }
10580    
10581     el.queue(function() {
10582     if ( hide ) {
10583     el.hide();
10584     }
10585     $.effects.restore( el, props );
10586     $.effects.removeWrapper( el );
10587     done();
10588     });
10589    
10590     // inject all the animations we just queued to be first in line (after "inprogress")
10591     if ( queuelen > 1) {
10592     queue.splice.apply( queue,
10593     [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10594     }
10595     el.dequeue();
10596    
10597     };
10598    
10599     })(jQuery);
10600    
10601     (function( $, undefined ) {
10602    
10603     $.effects.effect.clip = function( o, done ) {
10604     // Create element
10605     var el = $( this ),
10606     props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10607     mode = $.effects.setMode( el, o.mode || "hide" ),
10608     show = mode === "show",
10609     direction = o.direction || "vertical",
10610     vert = direction === "vertical",
10611     size = vert ? "height" : "width",
10612     position = vert ? "top" : "left",
10613     animation = {},
10614     wrapper, animate, distance;
10615    
10616     // Save & Show
10617     $.effects.save( el, props );
10618     el.show();
10619    
10620     // Create Wrapper
10621     wrapper = $.effects.createWrapper( el ).css({
10622     overflow: "hidden"
10623     });
10624     animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10625     distance = animate[ size ]();
10626    
10627     // Shift
10628     if ( show ) {
10629     animate.css( size, 0 );
10630     animate.css( position, distance / 2 );
10631     }
10632    
10633     // Create Animation Object:
10634     animation[ size ] = show ? distance : 0;
10635     animation[ position ] = show ? 0 : distance / 2;
10636    
10637     // Animate
10638     animate.animate( animation, {
10639     queue: false,
10640     duration: o.duration,
10641     easing: o.easing,
10642     complete: function() {
10643     if ( !show ) {
10644     el.hide();
10645     }
10646     $.effects.restore( el, props );
10647     $.effects.removeWrapper( el );
10648     done();
10649     }
10650     });
10651    
10652     };
10653    
10654     })(jQuery);
10655    
10656     (function( $, undefined ) {
10657    
10658     $.effects.effect.drop = function( o, done ) {
10659    
10660     var el = $( this ),
10661     props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10662     mode = $.effects.setMode( el, o.mode || "hide" ),
10663     show = mode === "show",
10664     direction = o.direction || "left",
10665     ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10666     motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10667     animation = {
10668     opacity: show ? 1 : 0
10669     },
10670     distance;
10671    
10672     // Adjust
10673     $.effects.save( el, props );
10674     el.show();
10675     $.effects.createWrapper( el );
10676    
10677     distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10678    
10679     if ( show ) {
10680     el
10681     .css( "opacity", 0 )
10682     .css( ref, motion === "pos" ? -distance : distance );
10683     }
10684    
10685     // Animation
10686     animation[ ref ] = ( show ?
10687     ( motion === "pos" ? "+=" : "-=" ) :
10688     ( motion === "pos" ? "-=" : "+=" ) ) +
10689     distance;
10690    
10691     // Animate
10692     el.animate( animation, {
10693     queue: false,
10694     duration: o.duration,
10695     easing: o.easing,
10696     complete: function() {
10697     if ( mode === "hide" ) {
10698     el.hide();
10699     }
10700     $.effects.restore( el, props );
10701     $.effects.removeWrapper( el );
10702     done();
10703     }
10704     });
10705     };
10706    
10707     })(jQuery);
10708    
10709     (function( $, undefined ) {
10710    
10711     $.effects.effect.explode = function( o, done ) {
10712    
10713     var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10714     cells = rows,
10715     el = $( this ),
10716     mode = $.effects.setMode( el, o.mode || "hide" ),
10717     show = mode === "show",
10718    
10719     // show and then visibility:hidden the element before calculating offset
10720     offset = el.show().css( "visibility", "hidden" ).offset(),
10721    
10722     // width and height of a piece
10723     width = Math.ceil( el.outerWidth() / cells ),
10724     height = Math.ceil( el.outerHeight() / rows ),
10725     pieces = [],
10726    
10727     // loop
10728     i, j, left, top, mx, my;
10729    
10730     // children animate complete:
10731     function childComplete() {
10732     pieces.push( this );
10733     if ( pieces.length === rows * cells ) {
10734     animComplete();
10735     }
10736     }
10737    
10738     // clone the element for each row and cell.
10739     for( i = 0; i < rows ; i++ ) { // ===>
10740     top = offset.top + i * height;
10741     my = i - ( rows - 1 ) / 2 ;
10742    
10743     for( j = 0; j < cells ; j++ ) { // |||
10744     left = offset.left + j * width;
10745     mx = j - ( cells - 1 ) / 2 ;
10746    
10747     // Create a clone of the now hidden main element that will be absolute positioned
10748     // within a wrapper div off the -left and -top equal to size of our pieces
10749     el
10750     .clone()
10751     .appendTo( "body" )
10752     .wrap( "<div></div>" )
10753     .css({
10754     position: "absolute",
10755     visibility: "visible",
10756     left: -j * width,
10757     top: -i * height
10758     })
10759    
10760     // select the wrapper - make it overflow: hidden and absolute positioned based on
10761     // where the original was located +left and +top equal to the size of pieces
10762     .parent()
10763     .addClass( "ui-effects-explode" )
10764     .css({
10765     position: "absolute",
10766     overflow: "hidden",
10767     width: width,
10768     height: height,
10769     left: left + ( show ? mx * width : 0 ),
10770     top: top + ( show ? my * height : 0 ),
10771     opacity: show ? 0 : 1
10772     }).animate({
10773     left: left + ( show ? 0 : mx * width ),
10774     top: top + ( show ? 0 : my * height ),
10775     opacity: show ? 1 : 0
10776     }, o.duration || 500, o.easing, childComplete );
10777     }
10778     }
10779    
10780     function animComplete() {
10781     el.css({
10782     visibility: "visible"
10783     });
10784     $( pieces ).remove();
10785     if ( !show ) {
10786     el.hide();
10787     }
10788     done();
10789     }
10790     };
10791    
10792     })(jQuery);
10793    
10794     (function( $, undefined ) {
10795    
10796     $.effects.effect.fade = function( o, done ) {
10797     var el = $( this ),
10798     mode = $.effects.setMode( el, o.mode || "toggle" );
10799    
10800     el.animate({
10801     opacity: mode
10802     }, {
10803     queue: false,
10804     duration: o.duration,
10805     easing: o.easing,
10806     complete: done
10807     });
10808     };
10809    
10810     })( jQuery );
10811    
10812     (function( $, undefined ) {
10813    
10814     $.effects.effect.fold = function( o, done ) {
10815    
10816     // Create element
10817     var el = $( this ),
10818     props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10819     mode = $.effects.setMode( el, o.mode || "hide" ),
10820     show = mode === "show",
10821     hide = mode === "hide",
10822     size = o.size || 15,
10823     percent = /([0-9]+)%/.exec( size ),
10824     horizFirst = !!o.horizFirst,
10825     widthFirst = show !== horizFirst,
10826     ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10827     duration = o.duration / 2,
10828     wrapper, distance,
10829     animation1 = {},
10830     animation2 = {};
10831    
10832     $.effects.save( el, props );
10833     el.show();
10834    
10835     // Create Wrapper
10836     wrapper = $.effects.createWrapper( el ).css({
10837     overflow: "hidden"
10838     });
10839     distance = widthFirst ?
10840     [ wrapper.width(), wrapper.height() ] :
10841     [ wrapper.height(), wrapper.width() ];
10842    
10843     if ( percent ) {
10844     size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10845     }
10846     if ( show ) {
10847     wrapper.css( horizFirst ? {
10848     height: 0,
10849     width: size
10850     } : {
10851     height: size,
10852     width: 0
10853     });
10854     }
10855    
10856     // Animation
10857     animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10858     animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10859    
10860     // Animate
10861     wrapper
10862     .animate( animation1, duration, o.easing )
10863     .animate( animation2, duration, o.easing, function() {
10864     if ( hide ) {
10865     el.hide();
10866     }
10867     $.effects.restore( el, props );
10868     $.effects.removeWrapper( el );
10869     done();
10870     });
10871    
10872     };
10873    
10874     })(jQuery);
10875    
10876     (function( $, undefined ) {
10877    
10878     $.effects.effect.highlight = function( o, done ) {
10879     var elem = $( this ),
10880     props = [ "backgroundImage", "backgroundColor", "opacity" ],
10881     mode = $.effects.setMode( elem, o.mode || "show" ),
10882     animation = {
10883     backgroundColor: elem.css( "backgroundColor" )
10884     };
10885    
10886     if (mode === "hide") {
10887     animation.opacity = 0;
10888     }
10889    
10890     $.effects.save( elem, props );
10891    
10892     elem
10893     .show()
10894     .css({
10895     backgroundImage: "none",
10896     backgroundColor: o.color || "#ffff99"
10897     })
10898     .animate( animation, {
10899     queue: false,
10900     duration: o.duration,
10901     easing: o.easing,
10902     complete: function() {
10903     if ( mode === "hide" ) {
10904     elem.hide();
10905     }
10906     $.effects.restore( elem, props );
10907     done();
10908     }
10909     });
10910     };
10911    
10912     })(jQuery);
10913    
10914     (function( $, undefined ) {
10915    
10916     $.effects.effect.pulsate = function( o, done ) {
10917     var elem = $( this ),
10918     mode = $.effects.setMode( elem, o.mode || "show" ),
10919     show = mode === "show",
10920     hide = mode === "hide",
10921     showhide = ( show || mode === "hide" ),
10922    
10923     // showing or hiding leaves of the "last" animation
10924     anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10925     duration = o.duration / anims,
10926     animateTo = 0,
10927     queue = elem.queue(),
10928     queuelen = queue.length,
10929     i;
10930    
10931     if ( show || !elem.is(":visible")) {
10932     elem.css( "opacity", 0 ).show();
10933     animateTo = 1;
10934     }
10935    
10936     // anims - 1 opacity "toggles"
10937     for ( i = 1; i < anims; i++ ) {
10938     elem.animate({
10939     opacity: animateTo
10940     }, duration, o.easing );
10941     animateTo = 1 - animateTo;
10942     }
10943    
10944     elem.animate({
10945     opacity: animateTo
10946     }, duration, o.easing);
10947    
10948     elem.queue(function() {
10949     if ( hide ) {
10950     elem.hide();
10951     }
10952     done();
10953     });
10954    
10955     // We just queued up "anims" animations, we need to put them next in the queue
10956     if ( queuelen > 1 ) {
10957     queue.splice.apply( queue,
10958     [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10959     }
10960     elem.dequeue();
10961     };
10962    
10963     })(jQuery);
10964    
10965     (function( $, undefined ) {
10966    
10967     $.effects.effect.puff = function( o, done ) {
10968     var elem = $( this ),
10969     mode = $.effects.setMode( elem, o.mode || "hide" ),
10970     hide = mode === "hide",
10971     percent = parseInt( o.percent, 10 ) || 150,
10972     factor = percent / 100,
10973     original = {
10974     height: elem.height(),
10975     width: elem.width(),
10976     outerHeight: elem.outerHeight(),
10977     outerWidth: elem.outerWidth()
10978     };
10979    
10980     $.extend( o, {
10981     effect: "scale",
10982     queue: false,
10983     fade: true,
10984     mode: mode,
10985     complete: done,
10986     percent: hide ? percent : 100,
10987     from: hide ?
10988     original :
10989     {
10990     height: original.height * factor,
10991     width: original.width * factor,
10992     outerHeight: original.outerHeight * factor,
10993     outerWidth: original.outerWidth * factor
10994     }
10995     });
10996    
10997     elem.effect( o );
10998     };
10999    
11000     $.effects.effect.scale = function( o, done ) {
11001    
11002     // Create element
11003     var el = $( this ),
11004     options = $.extend( true, {}, o ),
11005     mode = $.effects.setMode( el, o.mode || "effect" ),
11006     percent = parseInt( o.percent, 10 ) ||
11007     ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11008     direction = o.direction || "both",
11009     origin = o.origin,
11010     original = {
11011     height: el.height(),
11012     width: el.width(),
11013     outerHeight: el.outerHeight(),
11014     outerWidth: el.outerWidth()
11015     },
11016     factor = {
11017     y: direction !== "horizontal" ? (percent / 100) : 1,
11018     x: direction !== "vertical" ? (percent / 100) : 1
11019     };
11020    
11021     // We are going to pass this effect to the size effect:
11022     options.effect = "size";
11023     options.queue = false;
11024     options.complete = done;
11025    
11026     // Set default origin and restore for show/hide
11027     if ( mode !== "effect" ) {
11028     options.origin = origin || ["middle","center"];
11029     options.restore = true;
11030     }
11031    
11032     options.from = o.from || ( mode === "show" ? {
11033     height: 0,
11034     width: 0,
11035     outerHeight: 0,
11036     outerWidth: 0
11037     } : original );
11038     options.to = {
11039     height: original.height * factor.y,
11040     width: original.width * factor.x,
11041     outerHeight: original.outerHeight * factor.y,
11042     outerWidth: original.outerWidth * factor.x
11043     };
11044    
11045     // Fade option to support puff
11046     if ( options.fade ) {
11047     if ( mode === "show" ) {
11048     options.from.opacity = 0;
11049     options.to.opacity = 1;
11050     }
11051     if ( mode === "hide" ) {
11052     options.from.opacity = 1;
11053     options.to.opacity = 0;
11054     }
11055     }
11056    
11057     // Animate
11058     el.effect( options );
11059    
11060     };
11061    
11062     $.effects.effect.size = function( o, done ) {
11063    
11064     // Create element
11065     var original, baseline, factor,
11066     el = $( this ),
11067     props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11068    
11069     // Always restore
11070     props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11071    
11072     // Copy for children
11073     props2 = [ "width", "height", "overflow" ],
11074     cProps = [ "fontSize" ],
11075     vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11076     hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11077    
11078     // Set options
11079     mode = $.effects.setMode( el, o.mode || "effect" ),
11080     restore = o.restore || mode !== "effect",
11081     scale = o.scale || "both",
11082     origin = o.origin || [ "middle", "center" ],
11083     position = el.css( "position" ),
11084     props = restore ? props0 : props1,
11085     zero = {
11086     height: 0,
11087     width: 0,
11088     outerHeight: 0,
11089     outerWidth: 0
11090     };
11091    
11092     if ( mode === "show" ) {
11093     el.show();
11094     }
11095     original = {
11096     height: el.height(),
11097     width: el.width(),
11098     outerHeight: el.outerHeight(),
11099     outerWidth: el.outerWidth()
11100     };
11101    
11102     if ( o.mode === "toggle" && mode === "show" ) {
11103     el.from = o.to || zero;
11104     el.to = o.from || original;
11105     } else {
11106     el.from = o.from || ( mode === "show" ? zero : original );
11107     el.to = o.to || ( mode === "hide" ? zero : original );
11108     }
11109    
11110     // Set scaling factor
11111     factor = {
11112     from: {
11113     y: el.from.height / original.height,
11114     x: el.from.width / original.width
11115     },
11116     to: {
11117     y: el.to.height / original.height,
11118     x: el.to.width / original.width
11119     }
11120     };
11121    
11122     // Scale the css box
11123     if ( scale === "box" || scale === "both" ) {
11124    
11125     // Vertical props scaling
11126     if ( factor.from.y !== factor.to.y ) {
11127     props = props.concat( vProps );
11128     el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11129     el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11130     }
11131    
11132     // Horizontal props scaling
11133     if ( factor.from.x !== factor.to.x ) {
11134     props = props.concat( hProps );
11135     el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11136     el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11137     }
11138     }
11139    
11140     // Scale the content
11141     if ( scale === "content" || scale === "both" ) {
11142    
11143     // Vertical props scaling
11144     if ( factor.from.y !== factor.to.y ) {
11145     props = props.concat( cProps ).concat( props2 );
11146     el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11147     el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11148     }
11149     }
11150    
11151     $.effects.save( el, props );
11152     el.show();
11153     $.effects.createWrapper( el );
11154     el.css( "overflow", "hidden" ).css( el.from );
11155    
11156     // Adjust
11157     if (origin) { // Calculate baseline shifts
11158     baseline = $.effects.getBaseline( origin, original );
11159     el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11160     el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11161     el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11162     el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11163     }
11164     el.css( el.from ); // set top & left
11165    
11166     // Animate
11167     if ( scale === "content" || scale === "both" ) { // Scale the children
11168    
11169     // Add margins/font-size
11170     vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11171     hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11172     props2 = props0.concat(vProps).concat(hProps);
11173    
11174     el.find( "*[width]" ).each( function(){
11175     var child = $( this ),
11176     c_original = {
11177     height: child.height(),
11178     width: child.width(),
11179     outerHeight: child.outerHeight(),
11180     outerWidth: child.outerWidth()
11181     };
11182     if (restore) {
11183     $.effects.save(child, props2);
11184     }
11185    
11186     child.from = {
11187     height: c_original.height * factor.from.y,
11188     width: c_original.width * factor.from.x,
11189     outerHeight: c_original.outerHeight * factor.from.y,
11190     outerWidth: c_original.outerWidth * factor.from.x
11191     };
11192     child.to = {
11193     height: c_original.height * factor.to.y,
11194     width: c_original.width * factor.to.x,
11195     outerHeight: c_original.height * factor.to.y,
11196     outerWidth: c_original.width * factor.to.x
11197     };
11198    
11199     // Vertical props scaling
11200     if ( factor.from.y !== factor.to.y ) {
11201     child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11202     child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11203     }
11204    
11205     // Horizontal props scaling
11206     if ( factor.from.x !== factor.to.x ) {
11207     child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11208     child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11209     }
11210    
11211     // Animate children
11212     child.css( child.from );
11213     child.animate( child.to, o.duration, o.easing, function() {
11214    
11215     // Restore children
11216     if ( restore ) {
11217     $.effects.restore( child, props2 );
11218     }
11219     });
11220     });
11221     }
11222    
11223     // Animate
11224     el.animate( el.to, {
11225     queue: false,
11226     duration: o.duration,
11227     easing: o.easing,
11228     complete: function() {
11229     if ( el.to.opacity === 0 ) {
11230     el.css( "opacity", el.from.opacity );
11231     }
11232     if( mode === "hide" ) {
11233     el.hide();
11234     }
11235     $.effects.restore( el, props );
11236     if ( !restore ) {
11237    
11238     // we need to calculate our new positioning based on the scaling
11239     if ( position === "static" ) {
11240     el.css({
11241     position: "relative",
11242     top: el.to.top,
11243     left: el.to.left
11244     });
11245     } else {
11246     $.each([ "top", "left" ], function( idx, pos ) {
11247     el.css( pos, function( _, str ) {
11248     var val = parseInt( str, 10 ),
11249     toRef = idx ? el.to.left : el.to.top;
11250    
11251     // if original was "auto", recalculate the new value from wrapper
11252     if ( str === "auto" ) {
11253     return toRef + "px";
11254     }
11255    
11256     return val + toRef + "px";
11257     });
11258     });
11259     }
11260     }
11261    
11262     $.effects.removeWrapper( el );
11263     done();
11264     }
11265     });
11266    
11267     };
11268    
11269     })(jQuery);
11270    
11271     (function( $, undefined ) {
11272    
11273     $.effects.effect.shake = function( o, done ) {
11274    
11275     var el = $( this ),
11276     props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11277     mode = $.effects.setMode( el, o.mode || "effect" ),
11278     direction = o.direction || "left",
11279     distance = o.distance || 20,
11280     times = o.times || 3,
11281     anims = times * 2 + 1,
11282     speed = Math.round(o.duration/anims),
11283     ref = (direction === "up" || direction === "down") ? "top" : "left",
11284     positiveMotion = (direction === "up" || direction === "left"),
11285     animation = {},
11286     animation1 = {},
11287     animation2 = {},
11288     i,
11289    
11290     // we will need to re-assemble the queue to stack our animations in place
11291     queue = el.queue(),
11292     queuelen = queue.length;
11293    
11294     $.effects.save( el, props );
11295     el.show();
11296     $.effects.createWrapper( el );
11297    
11298     // Animation
11299     animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11300     animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11301     animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11302    
11303     // Animate
11304     el.animate( animation, speed, o.easing );
11305    
11306     // Shakes
11307     for ( i = 1; i < times; i++ ) {
11308     el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11309     }
11310     el
11311     .animate( animation1, speed, o.easing )
11312     .animate( animation, speed / 2, o.easing )
11313     .queue(function() {
11314     if ( mode === "hide" ) {
11315     el.hide();
11316     }
11317     $.effects.restore( el, props );
11318     $.effects.removeWrapper( el );
11319     done();
11320     });
11321    
11322     // inject all the animations we just queued to be first in line (after "inprogress")
11323     if ( queuelen > 1) {
11324     queue.splice.apply( queue,
11325     [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11326     }
11327     el.dequeue();
11328    
11329     };
11330    
11331     })(jQuery);
11332    
11333     (function( $, undefined ) {
11334    
11335     $.effects.effect.slide = function( o, done ) {
11336    
11337     // Create element
11338     var el = $( this ),
11339     props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11340     mode = $.effects.setMode( el, o.mode || "show" ),
11341     show = mode === "show",
11342     direction = o.direction || "left",
11343     ref = (direction === "up" || direction === "down") ? "top" : "left",
11344     positiveMotion = (direction === "up" || direction === "left"),
11345     distance,
11346     animation = {};
11347    
11348     // Adjust
11349     $.effects.save( el, props );
11350     el.show();
11351     distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11352    
11353     $.effects.createWrapper( el ).css({
11354     overflow: "hidden"
11355     });
11356    
11357     if ( show ) {
11358     el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11359     }
11360    
11361     // Animation
11362     animation[ ref ] = ( show ?
11363     ( positiveMotion ? "+=" : "-=") :
11364     ( positiveMotion ? "-=" : "+=")) +
11365     distance;
11366    
11367     // Animate
11368     el.animate( animation, {
11369     queue: false,
11370     duration: o.duration,
11371     easing: o.easing,
11372     complete: function() {
11373     if ( mode === "hide" ) {
11374     el.hide();
11375     }
11376     $.effects.restore( el, props );
11377     $.effects.removeWrapper( el );
11378     done();
11379     }
11380     });
11381     };
11382    
11383     })(jQuery);
11384    
11385     (function( $, undefined ) {
11386    
11387     $.effects.effect.transfer = function( o, done ) {
11388     var elem = $( this ),
11389     target = $( o.to ),
11390     targetFixed = target.css( "position" ) === "fixed",
11391     body = $("body"),
11392     fixTop = targetFixed ? body.scrollTop() : 0,
11393     fixLeft = targetFixed ? body.scrollLeft() : 0,
11394     endPosition = target.offset(),
11395     animation = {
11396     top: endPosition.top - fixTop ,
11397     left: endPosition.left - fixLeft ,
11398     height: target.innerHeight(),
11399     width: target.innerWidth()
11400     },
11401     startPosition = elem.offset(),
11402     transfer = $( "<div class='ui-effects-transfer'></div>" )
11403     .appendTo( document.body )
11404     .addClass( o.className )
11405     .css({
11406     top: startPosition.top - fixTop ,
11407     left: startPosition.left - fixLeft ,
11408     height: elem.innerHeight(),
11409     width: elem.innerWidth(),
11410     position: targetFixed ? "fixed" : "absolute"
11411     })
11412     .animate( animation, o.duration, o.easing, function() {
11413     transfer.remove();
11414     done();
11415     });
11416     };
11417    
11418     })(jQuery);
11419    
11420     (function( $, undefined ) {
11421    
11422     $.widget( "ui.menu", {
11423     version: "1.10.3",
11424     defaultElement: "<ul>",
11425     delay: 300,
11426     options: {
11427     icons: {
11428     submenu: "ui-icon-carat-1-e"
11429     },
11430     menus: "ul",
11431     position: {
11432     my: "left top",
11433     at: "right top"
11434     },
11435     role: "menu",
11436    
11437     // callbacks
11438     blur: null,
11439     focus: null,
11440     select: null
11441     },
11442    
11443     _create: function() {
11444     this.activeMenu = this.element;
11445     // flag used to prevent firing of the click handler
11446     // as the event bubbles up through nested menus
11447     this.mouseHandled = false;
11448     this.element
11449     .uniqueId()
11450     .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11451     .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
11452     .attr({
11453     role: this.options.role,
11454     tabIndex: 0
11455     })
11456     // need to catch all clicks on disabled menu
11457     // not possible through _on
11458     .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
11459     if ( this.options.disabled ) {
11460     event.preventDefault();
11461     }
11462     }, this ));
11463    
11464     if ( this.options.disabled ) {
11465     this.element
11466     .addClass( "ui-state-disabled" )
11467     .attr( "aria-disabled", "true" );
11468     }
11469    
11470     this._on({
11471     // Prevent focus from sticking to links inside menu after clicking
11472     // them (focus should always stay on UL during navigation).
11473     "mousedown .ui-menu-item > a": function( event ) {
11474     event.preventDefault();
11475     },
11476     "click .ui-state-disabled > a": function( event ) {
11477     event.preventDefault();
11478     },
11479     "click .ui-menu-item:has(a)": function( event ) {
11480     var target = $( event.target ).closest( ".ui-menu-item" );
11481     if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
11482     this.mouseHandled = true;
11483    
11484     this.select( event );
11485     // Open submenu on click
11486     if ( target.has( ".ui-menu" ).length ) {
11487     this.expand( event );
11488     } else if ( !this.element.is( ":focus" ) ) {
11489     // Redirect focus to the menu
11490     this.element.trigger( "focus", [ true ] );
11491    
11492     // If the active item is on the top level, let it stay active.
11493     // Otherwise, blur the active item since it is no longer visible.
11494     if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
11495     clearTimeout( this.timer );
11496     }
11497     }
11498     }
11499     },
11500     "mouseenter .ui-menu-item": function( event ) {
11501     var target = $( event.currentTarget );
11502     // Remove ui-state-active class from siblings of the newly focused menu item
11503     // to avoid a jump caused by adjacent elements both having a class with a border
11504     target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
11505     this.focus( event, target );
11506     },
11507     mouseleave: "collapseAll",
11508     "mouseleave .ui-menu": "collapseAll",
11509     focus: function( event, keepActiveItem ) {
11510     // If there's already an active item, keep it active
11511     // If not, activate the first item
11512     var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
11513    
11514     if ( !keepActiveItem ) {
11515     this.focus( event, item );
11516     }
11517     },
11518     blur: function( event ) {
11519     this._delay(function() {
11520     if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
11521     this.collapseAll( event );
11522     }
11523     });
11524     },
11525     keydown: "_keydown"
11526     });
11527    
11528     this.refresh();
11529    
11530     // Clicks outside of a menu collapse any open menus
11531     this._on( this.document, {
11532     click: function( event ) {
11533     if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11534     this.collapseAll( event );
11535     }
11536    
11537     // Reset the mouseHandled flag
11538     this.mouseHandled = false;
11539     }
11540     });
11541     },
11542    
11543     _destroy: function() {
11544     // Destroy (sub)menus
11545     this.element
11546     .removeAttr( "aria-activedescendant" )
11547     .find( ".ui-menu" ).addBack()
11548     .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11549     .removeAttr( "role" )
11550     .removeAttr( "tabIndex" )
11551     .removeAttr( "aria-labelledby" )
11552     .removeAttr( "aria-expanded" )
11553     .removeAttr( "aria-hidden" )
11554     .removeAttr( "aria-disabled" )
11555     .removeUniqueId()
11556     .show();
11557    
11558     // Destroy menu items
11559     this.element.find( ".ui-menu-item" )
11560     .removeClass( "ui-menu-item" )
11561     .removeAttr( "role" )
11562     .removeAttr( "aria-disabled" )
11563     .children( "a" )
11564     .removeUniqueId()
11565     .removeClass( "ui-corner-all ui-state-hover" )
11566     .removeAttr( "tabIndex" )
11567     .removeAttr( "role" )
11568     .removeAttr( "aria-haspopup" )
11569     .children().each( function() {
11570     var elem = $( this );
11571     if ( elem.data( "ui-menu-submenu-carat" ) ) {
11572     elem.remove();
11573     }
11574     });
11575    
11576     // Destroy menu dividers
11577     this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11578     },
11579    
11580     _keydown: function( event ) {
11581     /*jshint maxcomplexity:20*/
11582     var match, prev, character, skip, regex,
11583     preventDefault = true;
11584    
11585     function escape( value ) {
11586     return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11587     }
11588    
11589     switch ( event.keyCode ) {
11590     case $.ui.keyCode.PAGE_UP:
11591     this.previousPage( event );
11592     break;
11593     case $.ui.keyCode.PAGE_DOWN:
11594     this.nextPage( event );
11595     break;
11596     case $.ui.keyCode.HOME:
11597     this._move( "first", "first", event );
11598     break;
11599     case $.ui.keyCode.END:
11600     this._move( "last", "last", event );
11601     break;
11602     case $.ui.keyCode.UP:
11603     this.previous( event );
11604     break;
11605     case $.ui.keyCode.DOWN:
11606     this.next( event );
11607     break;
11608     case $.ui.keyCode.LEFT:
11609     this.collapse( event );
11610     break;
11611     case $.ui.keyCode.RIGHT:
11612     if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11613     this.expand( event );
11614     }
11615     break;
11616     case $.ui.keyCode.ENTER:
11617     case $.ui.keyCode.SPACE:
11618     this._activate( event );
11619     break;
11620     case $.ui.keyCode.ESCAPE:
11621     this.collapse( event );
11622     break;
11623     default:
11624     preventDefault = false;
11625     prev = this.previousFilter || "";
11626     character = String.fromCharCode( event.keyCode );
11627     skip = false;
11628    
11629     clearTimeout( this.filterTimer );
11630    
11631     if ( character === prev ) {
11632     skip = true;
11633     } else {
11634     character = prev + character;
11635     }
11636    
11637     regex = new RegExp( "^" + escape( character ), "i" );
11638     match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11639     return regex.test( $( this ).children( "a" ).text() );
11640     });
11641     match = skip && match.index( this.active.next() ) !== -1 ?
11642     this.active.nextAll( ".ui-menu-item" ) :
11643     match;
11644    
11645     // If no matches on the current filter, reset to the last character pressed
11646     // to move down the menu to the first item that starts with that character
11647     if ( !match.length ) {
11648     character = String.fromCharCode( event.keyCode );
11649     regex = new RegExp( "^" + escape( character ), "i" );
11650     match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11651     return regex.test( $( this ).children( "a" ).text() );
11652     });
11653     }
11654    
11655     if ( match.length ) {
11656     this.focus( event, match );
11657     if ( match.length > 1 ) {
11658     this.previousFilter = character;
11659     this.filterTimer = this._delay(function() {
11660     delete this.previousFilter;
11661     }, 1000 );
11662     } else {
11663     delete this.previousFilter;
11664     }
11665     } else {
11666     delete this.previousFilter;
11667     }
11668     }
11669    
11670     if ( preventDefault ) {
11671     event.preventDefault();
11672     }
11673     },
11674    
11675     _activate: function( event ) {
11676     if ( !this.active.is( ".ui-state-disabled" ) ) {
11677     if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11678     this.expand( event );
11679     } else {
11680     this.select( event );
11681     }
11682     }
11683     },
11684    
11685     refresh: function() {
11686     var menus,
11687     icon = this.options.icons.submenu,
11688     submenus = this.element.find( this.options.menus );
11689    
11690     // Initialize nested menus
11691     submenus.filter( ":not(.ui-menu)" )
11692     .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11693     .hide()
11694     .attr({
11695     role: this.options.role,
11696     "aria-hidden": "true",
11697     "aria-expanded": "false"
11698     })
11699     .each(function() {
11700     var menu = $( this ),
11701     item = menu.prev( "a" ),
11702     submenuCarat = $( "<span>" )
11703     .addClass( "ui-menu-icon ui-icon " + icon )
11704     .data( "ui-menu-submenu-carat", true );
11705    
11706     item
11707     .attr( "aria-haspopup", "true" )
11708     .prepend( submenuCarat );
11709     menu.attr( "aria-labelledby", item.attr( "id" ) );
11710     });
11711    
11712     menus = submenus.add( this.element );
11713    
11714     // Don't refresh list items that are already adapted
11715     menus.children( ":not(.ui-menu-item):has(a)" )
11716     .addClass( "ui-menu-item" )
11717     .attr( "role", "presentation" )
11718     .children( "a" )
11719     .uniqueId()
11720     .addClass( "ui-corner-all" )
11721     .attr({
11722     tabIndex: -1,
11723     role: this._itemRole()
11724     });
11725    
11726     // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11727     menus.children( ":not(.ui-menu-item)" ).each(function() {
11728     var item = $( this );
11729     // hyphen, em dash, en dash
11730     if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
11731     item.addClass( "ui-widget-content ui-menu-divider" );
11732     }
11733     });
11734    
11735     // Add aria-disabled attribute to any disabled menu item
11736     menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11737    
11738     // If the active item has been removed, blur the menu
11739     if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11740     this.blur();
11741     }
11742     },
11743    
11744     _itemRole: function() {
11745     return {
11746     menu: "menuitem",
11747     listbox: "option"
11748     }[ this.options.role ];
11749     },
11750    
11751     _setOption: function( key, value ) {
11752     if ( key === "icons" ) {
11753     this.element.find( ".ui-menu-icon" )
11754     .removeClass( this.options.icons.submenu )
11755     .addClass( value.submenu );
11756     }
11757     this._super( key, value );
11758     },
11759    
11760     focus: function( event, item ) {
11761     var nested, focused;
11762     this.blur( event, event && event.type === "focus" );
11763    
11764     this._scrollIntoView( item );
11765    
11766     this.active = item.first();
11767     focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11768     // Only update aria-activedescendant if there's a role
11769     // otherwise we assume focus is managed elsewhere
11770     if ( this.options.role ) {
11771     this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11772     }
11773    
11774     // Highlight active parent menu item, if any
11775     this.active
11776     .parent()
11777     .closest( ".ui-menu-item" )
11778     .children( "a:first" )
11779     .addClass( "ui-state-active" );
11780    
11781     if ( event && event.type === "keydown" ) {
11782     this._close();
11783     } else {
11784     this.timer = this._delay(function() {
11785     this._close();
11786     }, this.delay );
11787     }
11788    
11789     nested = item.children( ".ui-menu" );
11790     if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
11791     this._startOpening(nested);
11792     }
11793     this.activeMenu = item.parent();
11794    
11795     this._trigger( "focus", event, { item: item } );
11796     },
11797    
11798     _scrollIntoView: function( item ) {
11799     var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11800     if ( this._hasScroll() ) {
11801     borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11802     paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11803     offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11804     scroll = this.activeMenu.scrollTop();
11805     elementHeight = this.activeMenu.height();
11806     itemHeight = item.height();
11807    
11808     if ( offset < 0 ) {
11809     this.activeMenu.scrollTop( scroll + offset );
11810     } else if ( offset + itemHeight > elementHeight ) {
11811     this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11812     }
11813     }
11814     },
11815    
11816     blur: function( event, fromFocus ) {
11817     if ( !fromFocus ) {
11818     clearTimeout( this.timer );
11819     }
11820    
11821     if ( !this.active ) {
11822     return;
11823     }
11824    
11825     this.active.children( "a" ).removeClass( "ui-state-focus" );
11826     this.active = null;
11827    
11828     this._trigger( "blur", event, { item: this.active } );
11829     },
11830    
11831     _startOpening: function( submenu ) {
11832     clearTimeout( this.timer );
11833    
11834     // Don't open if already open fixes a Firefox bug that caused a .5 pixel
11835     // shift in the submenu position when mousing over the carat icon
11836     if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11837     return;
11838     }
11839    
11840     this.timer = this._delay(function() {
11841     this._close();
11842     this._open( submenu );
11843     }, this.delay );
11844     },
11845    
11846     _open: function( submenu ) {
11847     var position = $.extend({
11848     of: this.active
11849     }, this.options.position );
11850    
11851     clearTimeout( this.timer );
11852     this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11853     .hide()
11854     .attr( "aria-hidden", "true" );
11855    
11856     submenu
11857     .show()
11858     .removeAttr( "aria-hidden" )
11859     .attr( "aria-expanded", "true" )
11860     .position( position );
11861     },
11862    
11863     collapseAll: function( event, all ) {
11864     clearTimeout( this.timer );
11865     this.timer = this._delay(function() {
11866     // If we were passed an event, look for the submenu that contains the event
11867     var currentMenu = all ? this.element :
11868     $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11869    
11870     // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11871     if ( !currentMenu.length ) {
11872     currentMenu = this.element;
11873     }
11874    
11875     this._close( currentMenu );
11876    
11877     this.blur( event );
11878     this.activeMenu = currentMenu;
11879     }, this.delay );
11880     },
11881    
11882     // With no arguments, closes the currently active menu - if nothing is active
11883     // it closes all menus. If passed an argument, it will search for menus BELOW
11884     _close: function( startMenu ) {
11885     if ( !startMenu ) {
11886     startMenu = this.active ? this.active.parent() : this.element;
11887     }
11888    
11889     startMenu
11890     .find( ".ui-menu" )
11891     .hide()
11892     .attr( "aria-hidden", "true" )
11893     .attr( "aria-expanded", "false" )
11894     .end()
11895     .find( "a.ui-state-active" )
11896     .removeClass( "ui-state-active" );
11897     },
11898    
11899     collapse: function( event ) {
11900     var newItem = this.active &&
11901     this.active.parent().closest( ".ui-menu-item", this.element );
11902     if ( newItem && newItem.length ) {
11903     this._close();
11904     this.focus( event, newItem );
11905     }
11906     },
11907    
11908     expand: function( event ) {
11909     var newItem = this.active &&
11910     this.active
11911     .children( ".ui-menu " )
11912     .children( ".ui-menu-item" )
11913     .first();
11914    
11915     if ( newItem && newItem.length ) {
11916     this._open( newItem.parent() );
11917    
11918     // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11919     this._delay(function() {
11920     this.focus( event, newItem );
11921     });
11922     }
11923     },
11924    
11925     next: function( event ) {
11926     this._move( "next", "first", event );
11927     },
11928    
11929     previous: function( event ) {
11930     this._move( "prev", "last", event );
11931     },
11932    
11933     isFirstItem: function() {
11934     return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11935     },
11936    
11937     isLastItem: function() {
11938     return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11939     },
11940    
11941     _move: function( direction, filter, event ) {
11942     var next;
11943     if ( this.active ) {
11944     if ( direction === "first" || direction === "last" ) {
11945     next = this.active
11946     [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11947     .eq( -1 );
11948     } else {
11949     next = this.active
11950     [ direction + "All" ]( ".ui-menu-item" )
11951     .eq( 0 );
11952     }
11953     }
11954     if ( !next || !next.length || !this.active ) {
11955     next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11956     }
11957    
11958     this.focus( event, next );
11959     },
11960    
11961     nextPage: function( event ) {
11962     var item, base, height;
11963    
11964     if ( !this.active ) {
11965     this.next( event );
11966     return;
11967     }
11968     if ( this.isLastItem() ) {
11969     return;
11970     }
11971     if ( this._hasScroll() ) {
11972     base = this.active.offset().top;
11973     height = this.element.height();
11974     this.active.nextAll( ".ui-menu-item" ).each(function() {
11975     item = $( this );
11976     return item.offset().top - base - height < 0;
11977     });
11978    
11979     this.focus( event, item );
11980     } else {
11981     this.focus( event, this.activeMenu.children( ".ui-menu-item" )
11982     [ !this.active ? "first" : "last" ]() );
11983     }
11984     },
11985    
11986     previousPage: function( event ) {
11987     var item, base, height;
11988     if ( !this.active ) {
11989     this.next( event );
11990     return;
11991     }
11992     if ( this.isFirstItem() ) {
11993     return;
11994     }
11995     if ( this._hasScroll() ) {
11996     base = this.active.offset().top;
11997     height = this.element.height();
11998     this.active.prevAll( ".ui-menu-item" ).each(function() {
11999     item = $( this );
12000     return item.offset().top - base + height > 0;
12001     });
12002    
12003     this.focus( event, item );
12004     } else {
12005     this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
12006     }
12007     },
12008    
12009     _hasScroll: function() {
12010     return this.element.outerHeight() < this.element.prop( "scrollHeight" );
12011     },
12012    
12013     select: function( event ) {
12014     // TODO: It should never be possible to not have an active item at this
12015     // point, but the tests don't trigger mouseenter before click.
12016     this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
12017     var ui = { item: this.active };
12018     if ( !this.active.has( ".ui-menu" ).length ) {
12019     this.collapseAll( event, true );
12020     }
12021     this._trigger( "select", event, ui );
12022     }
12023     });
12024    
12025     }( jQuery ));
12026    
12027     (function( $, undefined ) {
12028    
12029     $.ui = $.ui || {};
12030    
12031     var cachedScrollbarWidth,
12032     max = Math.max,
12033     abs = Math.abs,
12034     round = Math.round,
12035     rhorizontal = /left|center|right/,
12036     rvertical = /top|center|bottom/,
12037     roffset = /[\+\-]\d+(\.[\d]+)?%?/,
12038     rposition = /^\w+/,
12039     rpercent = /%$/,
12040     _position = $.fn.position;
12041    
12042     function getOffsets( offsets, width, height ) {
12043     return [
12044     parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
12045     parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
12046     ];
12047     }
12048    
12049     function parseCss( element, property ) {
12050     return parseInt( $.css( element, property ), 10 ) || 0;
12051     }
12052    
12053     function getDimensions( elem ) {
12054     var raw = elem[0];
12055     if ( raw.nodeType === 9 ) {
12056     return {
12057     width: elem.width(),
12058     height: elem.height(),
12059     offset: { top: 0, left: 0 }
12060     };
12061     }
12062     if ( $.isWindow( raw ) ) {
12063     return {
12064     width: elem.width(),
12065     height: elem.height(),
12066     offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
12067     };
12068     }
12069     if ( raw.preventDefault ) {
12070     return {
12071     width: 0,
12072     height: 0,
12073     offset: { top: raw.pageY, left: raw.pageX }
12074     };
12075     }
12076     return {
12077     width: elem.outerWidth(),
12078     height: elem.outerHeight(),
12079     offset: elem.offset()
12080     };
12081     }
12082    
12083     $.position = {
12084     scrollbarWidth: function() {
12085     if ( cachedScrollbarWidth !== undefined ) {
12086     return cachedScrollbarWidth;
12087     }
12088     var w1, w2,
12089     div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
12090     innerDiv = div.children()[0];
12091    
12092     $( "body" ).append( div );
12093     w1 = innerDiv.offsetWidth;
12094     div.css( "overflow", "scroll" );
12095    
12096     w2 = innerDiv.offsetWidth;
12097    
12098     if ( w1 === w2 ) {
12099     w2 = div[0].clientWidth;
12100     }
12101    
12102     div.remove();
12103    
12104     return (cachedScrollbarWidth = w1 - w2);
12105     },
12106     getScrollInfo: function( within ) {
12107     var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
12108     overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
12109     hasOverflowX = overflowX === "scroll" ||
12110     ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
12111     hasOverflowY = overflowY === "scroll" ||
12112     ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
12113     return {
12114     width: hasOverflowY ? $.position.scrollbarWidth() : 0,
12115     height: hasOverflowX ? $.position.scrollbarWidth() : 0
12116     };
12117     },
12118     getWithinInfo: function( element ) {
12119     var withinElement = $( element || window ),
12120     isWindow = $.isWindow( withinElement[0] );
12121     return {
12122     element: withinElement,
12123     isWindow: isWindow,
12124     offset: withinElement.offset() || { left: 0, top: 0 },
12125     scrollLeft: withinElement.scrollLeft(),
12126     scrollTop: withinElement.scrollTop(),
12127     width: isWindow ? withinElement.width() : withinElement.outerWidth(),
12128     height: isWindow ? withinElement.height() : withinElement.outerHeight()
12129     };
12130     }
12131     };
12132    
12133     $.fn.position = function( options ) {
12134     if ( !options || !options.of ) {
12135     return _position.apply( this, arguments );
12136     }
12137    
12138     // make a copy, we don't want to modify arguments
12139     options = $.extend( {}, options );
12140    
12141     var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
12142     target = $( options.of ),
12143     within = $.position.getWithinInfo( options.within ),
12144     scrollInfo = $.position.getScrollInfo( within ),
12145     collision = ( options.collision || "flip" ).split( " " ),
12146     offsets = {};
12147    
12148     dimensions = getDimensions( target );
12149     if ( target[0].preventDefault ) {
12150     // force left top to allow flipping
12151     options.at = "left top";
12152     }
12153     targetWidth = dimensions.width;
12154     targetHeight = dimensions.height;
12155     targetOffset = dimensions.offset;
12156     // clone to reuse original targetOffset later
12157     basePosition = $.extend( {}, targetOffset );
12158    
12159     // force my and at to have valid horizontal and vertical positions
12160     // if a value is missing or invalid, it will be converted to center
12161     $.each( [ "my", "at" ], function() {
12162     var pos = ( options[ this ] || "" ).split( " " ),
12163     horizontalOffset,
12164     verticalOffset;
12165    
12166     if ( pos.length === 1) {
12167     pos = rhorizontal.test( pos[ 0 ] ) ?
12168     pos.concat( [ "center" ] ) :
12169     rvertical.test( pos[ 0 ] ) ?
12170     [ "center" ].concat( pos ) :
12171     [ "center", "center" ];
12172     }
12173     pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
12174     pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
12175    
12176     // calculate offsets
12177     horizontalOffset = roffset.exec( pos[ 0 ] );
12178     verticalOffset = roffset.exec( pos[ 1 ] );
12179     offsets[ this ] = [
12180     horizontalOffset ? horizontalOffset[ 0 ] : 0,
12181     verticalOffset ? verticalOffset[ 0 ] : 0
12182     ];
12183    
12184     // reduce to just the positions without the offsets
12185     options[ this ] = [
12186     rposition.exec( pos[ 0 ] )[ 0 ],
12187     rposition.exec( pos[ 1 ] )[ 0 ]
12188     ];
12189     });
12190    
12191     // normalize collision option
12192     if ( collision.length === 1 ) {
12193     collision[ 1 ] = collision[ 0 ];
12194     }
12195    
12196     if ( options.at[ 0 ] === "right" ) {
12197     basePosition.left += targetWidth;
12198     } else if ( options.at[ 0 ] === "center" ) {
12199     basePosition.left += targetWidth / 2;
12200     }
12201    
12202     if ( options.at[ 1 ] === "bottom" ) {
12203     basePosition.top += targetHeight;
12204     } else if ( options.at[ 1 ] === "center" ) {
12205     basePosition.top += targetHeight / 2;
12206     }
12207    
12208     atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
12209     basePosition.left += atOffset[ 0 ];
12210     basePosition.top += atOffset[ 1 ];
12211    
12212     return this.each(function() {
12213     var collisionPosition, using,
12214     elem = $( this ),
12215     elemWidth = elem.outerWidth(),
12216     elemHeight = elem.outerHeight(),
12217     marginLeft = parseCss( this, "marginLeft" ),
12218     marginTop = parseCss( this, "marginTop" ),
12219     collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
12220     collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
12221     position = $.extend( {}, basePosition ),
12222     myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
12223    
12224     if ( options.my[ 0 ] === "right" ) {
12225     position.left -= elemWidth;
12226     } else if ( options.my[ 0 ] === "center" ) {
12227     position.left -= elemWidth / 2;
12228     }
12229    
12230     if ( options.my[ 1 ] === "bottom" ) {
12231     position.top -= elemHeight;
12232     } else if ( options.my[ 1 ] === "center" ) {
12233     position.top -= elemHeight / 2;
12234     }
12235    
12236     position.left += myOffset[ 0 ];
12237     position.top += myOffset[ 1 ];
12238    
12239     // if the browser doesn't support fractions, then round for consistent results
12240     if ( !$.support.offsetFractions ) {
12241     position.left = round( position.left );
12242     position.top = round( position.top );
12243     }
12244    
12245     collisionPosition = {
12246     marginLeft: marginLeft,
12247     marginTop: marginTop
12248     };
12249    
12250     $.each( [ "left", "top" ], function( i, dir ) {
12251     if ( $.ui.position[ collision[ i ] ] ) {
12252     $.ui.position[ collision[ i ] ][ dir ]( position, {
12253     targetWidth: targetWidth,
12254     targetHeight: targetHeight,
12255     elemWidth: elemWidth,
12256     elemHeight: elemHeight,
12257     collisionPosition: collisionPosition,
12258     collisionWidth: collisionWidth,
12259     collisionHeight: collisionHeight,
12260     offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
12261     my: options.my,
12262     at: options.at,
12263     within: within,
12264     elem : elem
12265     });
12266     }
12267     });
12268    
12269     if ( options.using ) {
12270     // adds feedback as second argument to using callback, if present
12271     using = function( props ) {
12272     var left = targetOffset.left - position.left,
12273     right = left + targetWidth - elemWidth,
12274     top = targetOffset.top - position.top,
12275     bottom = top + targetHeight - elemHeight,
12276     feedback = {
12277     target: {
12278     element: target,
12279     left: targetOffset.left,
12280     top: targetOffset.top,
12281     width: targetWidth,
12282     height: targetHeight
12283     },
12284     element: {
12285     element: elem,
12286     left: position.left,
12287     top: position.top,
12288     width: elemWidth,
12289     height: elemHeight
12290     },
12291     horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
12292     vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
12293     };
12294     if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
12295     feedback.horizontal = "center";
12296     }
12297     if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
12298     feedback.vertical = "middle";
12299     }
12300     if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
12301     feedback.important = "horizontal";
12302     } else {
12303     feedback.important = "vertical";
12304     }
12305     options.using.call( this, props, feedback );
12306     };
12307     }
12308    
12309     elem.offset( $.extend( position, { using: using } ) );
12310     });
12311     };
12312    
12313     $.ui.position = {
12314     fit: {
12315     left: function( position, data ) {
12316     var within = data.within,
12317     withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
12318     outerWidth = within.width,
12319     collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12320     overLeft = withinOffset - collisionPosLeft,
12321     overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
12322     newOverRight;
12323    
12324     // element is wider than within
12325     if ( data.collisionWidth > outerWidth ) {
12326     // element is initially over the left side of within
12327     if ( overLeft > 0 && overRight <= 0 ) {
12328     newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
12329     position.left += overLeft - newOverRight;
12330     // element is initially over right side of within
12331     } else if ( overRight > 0 && overLeft <= 0 ) {
12332     position.left = withinOffset;
12333     // element is initially over both left and right sides of within
12334     } else {
12335     if ( overLeft > overRight ) {
12336     position.left = withinOffset + outerWidth - data.collisionWidth;
12337     } else {
12338     position.left = withinOffset;
12339     }
12340     }
12341     // too far left -> align with left edge
12342     } else if ( overLeft > 0 ) {
12343     position.left += overLeft;
12344     // too far right -> align with right edge
12345     } else if ( overRight > 0 ) {
12346     position.left -= overRight;
12347     // adjust based on position and margin
12348     } else {
12349     position.left = max( position.left - collisionPosLeft, position.left );
12350     }
12351     },
12352     top: function( position, data ) {
12353     var within = data.within,
12354     withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
12355     outerHeight = data.within.height,
12356     collisionPosTop = position.top - data.collisionPosition.marginTop,
12357     overTop = withinOffset - collisionPosTop,
12358     overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
12359     newOverBottom;
12360    
12361     // element is taller than within
12362     if ( data.collisionHeight > outerHeight ) {
12363     // element is initially over the top of within
12364     if ( overTop > 0 && overBottom <= 0 ) {
12365     newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
12366     position.top += overTop - newOverBottom;
12367     // element is initially over bottom of within
12368     } else if ( overBottom > 0 && overTop <= 0 ) {
12369     position.top = withinOffset;
12370     // element is initially over both top and bottom of within
12371     } else {
12372     if ( overTop > overBottom ) {
12373     position.top = withinOffset + outerHeight - data.collisionHeight;
12374     } else {
12375     position.top = withinOffset;
12376     }
12377     }
12378     // too far up -> align with top
12379     } else if ( overTop > 0 ) {
12380     position.top += overTop;
12381     // too far down -> align with bottom edge
12382     } else if ( overBottom > 0 ) {
12383     position.top -= overBottom;
12384     // adjust based on position and margin
12385     } else {
12386     position.top = max( position.top - collisionPosTop, position.top );
12387     }
12388     }
12389     },
12390     flip: {
12391     left: function( position, data ) {
12392     var within = data.within,
12393     withinOffset = within.offset.left + within.scrollLeft,
12394     outerWidth = within.width,
12395     offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
12396     collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12397     overLeft = collisionPosLeft - offsetLeft,
12398     overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
12399     myOffset = data.my[ 0 ] === "left" ?
12400     -data.elemWidth :
12401     data.my[ 0 ] === "right" ?
12402     data.elemWidth :
12403     0,
12404     atOffset = data.at[ 0 ] === "left" ?
12405     data.targetWidth :
12406     data.at[ 0 ] === "right" ?
12407     -data.targetWidth :
12408     0,
12409     offset = -2 * data.offset[ 0 ],
12410     newOverRight,
12411     newOverLeft;
12412    
12413     if ( overLeft < 0 ) {
12414     newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
12415     if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
12416     position.left += myOffset + atOffset + offset;
12417     }
12418     }
12419     else if ( overRight > 0 ) {
12420     newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
12421     if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
12422     position.left += myOffset + atOffset + offset;
12423     }
12424     }
12425     },
12426     top: function( position, data ) {
12427     var within = data.within,
12428     withinOffset = within.offset.top + within.scrollTop,
12429     outerHeight = within.height,
12430     offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
12431     collisionPosTop = position.top - data.collisionPosition.marginTop,
12432     overTop = collisionPosTop - offsetTop,
12433     overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
12434     top = data.my[ 1 ] === "top",
12435     myOffset = top ?
12436     -data.elemHeight :
12437     data.my[ 1 ] === "bottom" ?
12438     data.elemHeight :
12439     0,
12440     atOffset = data.at[ 1 ] === "top" ?
12441     data.targetHeight :
12442     data.at[ 1 ] === "bottom" ?
12443     -data.targetHeight :
12444     0,
12445     offset = -2 * data.offset[ 1 ],
12446     newOverTop,
12447     newOverBottom;
12448     if ( overTop < 0 ) {
12449     newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
12450     if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
12451     position.top += myOffset + atOffset + offset;
12452     }
12453     }
12454     else if ( overBottom > 0 ) {
12455     newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
12456     if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
12457     position.top += myOffset + atOffset + offset;
12458     }
12459     }
12460     }
12461     },
12462     flipfit: {
12463     left: function() {
12464     $.ui.position.flip.left.apply( this, arguments );
12465     $.ui.position.fit.left.apply( this, arguments );
12466     },
12467     top: function() {
12468     $.ui.position.flip.top.apply( this, arguments );
12469     $.ui.position.fit.top.apply( this, arguments );
12470     }
12471     }
12472     };
12473    
12474     // fraction support test
12475     (function () {
12476     var testElement, testElementParent, testElementStyle, offsetLeft, i,
12477     body = document.getElementsByTagName( "body" )[ 0 ],
12478     div = document.createElement( "div" );
12479    
12480     //Create a "fake body" for testing based on method used in jQuery.support
12481     testElement = document.createElement( body ? "div" : "body" );
12482     testElementStyle = {
12483     visibility: "hidden",
12484     width: 0,
12485     height: 0,
12486     border: 0,
12487     margin: 0,
12488     background: "none"
12489     };
12490     if ( body ) {
12491     $.extend( testElementStyle, {
12492     position: "absolute",
12493     left: "-1000px",
12494     top: "-1000px"
12495     });
12496     }
12497     for ( i in testElementStyle ) {
12498     testElement.style[ i ] = testElementStyle[ i ];
12499     }
12500     testElement.appendChild( div );
12501     testElementParent = body || document.documentElement;
12502     testElementParent.insertBefore( testElement, testElementParent.firstChild );
12503    
12504     div.style.cssText = "position: absolute; left: 10.7432222px;";
12505    
12506     offsetLeft = $( div ).offset().left;
12507     $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
12508    
12509     testElement.innerHTML = "";
12510     testElementParent.removeChild( testElement );
12511     })();
12512    
12513     }( jQuery ) );
12514    
12515     (function( $, undefined ) {
12516    
12517     $.widget( "ui.progressbar", {
12518     version: "1.10.3",
12519     options: {
12520     max: 100,
12521     value: 0,
12522    
12523     change: null,
12524     complete: null
12525     },
12526    
12527     min: 0,
12528    
12529     _create: function() {
12530     // Constrain initial value
12531     this.oldValue = this.options.value = this._constrainedValue();
12532    
12533     this.element
12534     .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12535     .attr({
12536     // Only set static values, aria-valuenow and aria-valuemax are
12537     // set inside _refreshValue()
12538     role: "progressbar",
12539     "aria-valuemin": this.min
12540     });
12541    
12542     this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12543     .appendTo( this.element );
12544    
12545     this._refreshValue();
12546     },
12547    
12548     _destroy: function() {
12549     this.element
12550     .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12551     .removeAttr( "role" )
12552     .removeAttr( "aria-valuemin" )
12553     .removeAttr( "aria-valuemax" )
12554     .removeAttr( "aria-valuenow" );
12555    
12556     this.valueDiv.remove();
12557     },
12558    
12559     value: function( newValue ) {
12560     if ( newValue === undefined ) {
12561     return this.options.value;
12562     }
12563    
12564     this.options.value = this._constrainedValue( newValue );
12565     this._refreshValue();
12566     },
12567    
12568     _constrainedValue: function( newValue ) {
12569     if ( newValue === undefined ) {
12570     newValue = this.options.value;
12571     }
12572    
12573     this.indeterminate = newValue === false;
12574    
12575     // sanitize value
12576     if ( typeof newValue !== "number" ) {
12577     newValue = 0;
12578     }
12579    
12580     return this.indeterminate ? false :
12581     Math.min( this.options.max, Math.max( this.min, newValue ) );
12582     },
12583    
12584     _setOptions: function( options ) {
12585     // Ensure "value" option is set after other values (like max)
12586     var value = options.value;
12587     delete options.value;
12588    
12589     this._super( options );
12590    
12591     this.options.value = this._constrainedValue( value );
12592     this._refreshValue();
12593     },
12594    
12595     _setOption: function( key, value ) {
12596     if ( key === "max" ) {
12597     // Don't allow a max less than min
12598     value = Math.max( this.min, value );
12599     }
12600    
12601     this._super( key, value );
12602     },
12603    
12604     _percentage: function() {
12605     return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12606     },
12607    
12608     _refreshValue: function() {
12609     var value = this.options.value,
12610     percentage = this._percentage();
12611    
12612     this.valueDiv
12613     .toggle( this.indeterminate || value > this.min )
12614     .toggleClass( "ui-corner-right", value === this.options.max )
12615     .width( percentage.toFixed(0) + "%" );
12616    
12617     this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
12618    
12619     if ( this.indeterminate ) {
12620     this.element.removeAttr( "aria-valuenow" );
12621     if ( !this.overlayDiv ) {
12622     this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
12623     }
12624     } else {
12625     this.element.attr({
12626     "aria-valuemax": this.options.max,
12627     "aria-valuenow": value
12628     });
12629     if ( this.overlayDiv ) {
12630     this.overlayDiv.remove();
12631     this.overlayDiv = null;
12632     }
12633     }
12634    
12635     if ( this.oldValue !== value ) {
12636     this.oldValue = value;
12637     this._trigger( "change" );
12638     }
12639     if ( value === this.options.max ) {
12640     this._trigger( "complete" );
12641     }
12642     }
12643     });
12644    
12645     })( jQuery );
12646    
12647     (function( $, undefined ) {
12648    
12649     // number of pages in a slider
12650     // (how many times can you page up/down to go through the whole range)
12651     var numPages = 5;
12652    
12653     $.widget( "ui.slider", $.ui.mouse, {
12654     version: "1.10.3",
12655     widgetEventPrefix: "slide",
12656    
12657     options: {
12658     animate: false,
12659     distance: 0,
12660     max: 100,
12661     min: 0,
12662     orientation: "horizontal",
12663     range: false,
12664     step: 1,
12665     value: 0,
12666     values: null,
12667    
12668     // callbacks
12669     change: null,
12670     slide: null,
12671     start: null,
12672     stop: null
12673     },
12674    
12675     _create: function() {
12676     this._keySliding = false;
12677     this._mouseSliding = false;
12678     this._animateOff = true;
12679     this._handleIndex = null;
12680     this._detectOrientation();
12681     this._mouseInit();
12682    
12683     this.element
12684     .addClass( "ui-slider" +
12685     " ui-slider-" + this.orientation +
12686     " ui-widget" +
12687     " ui-widget-content" +
12688     " ui-corner-all");
12689    
12690     this._refresh();
12691     this._setOption( "disabled", this.options.disabled );
12692    
12693     this._animateOff = false;
12694     },
12695    
12696     _refresh: function() {
12697     this._createRange();
12698     this._createHandles();
12699     this._setupEvents();
12700     this._refreshValue();
12701     },
12702    
12703     _createHandles: function() {
12704     var i, handleCount,
12705     options = this.options,
12706     existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12707     handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12708     handles = [];
12709    
12710     handleCount = ( options.values && options.values.length ) || 1;
12711    
12712     if ( existingHandles.length > handleCount ) {
12713     existingHandles.slice( handleCount ).remove();
12714     existingHandles = existingHandles.slice( 0, handleCount );
12715     }
12716    
12717     for ( i = existingHandles.length; i < handleCount; i++ ) {
12718     handles.push( handle );
12719     }
12720    
12721     this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12722    
12723     this.handle = this.handles.eq( 0 );
12724    
12725     this.handles.each(function( i ) {
12726     $( this ).data( "ui-slider-handle-index", i );
12727     });
12728     },
12729    
12730     _createRange: function() {
12731     var options = this.options,
12732     classes = "";
12733    
12734     if ( options.range ) {
12735     if ( options.range === true ) {
12736     if ( !options.values ) {
12737     options.values = [ this._valueMin(), this._valueMin() ];
12738     } else if ( options.values.length && options.values.length !== 2 ) {
12739     options.values = [ options.values[0], options.values[0] ];
12740     } else if ( $.isArray( options.values ) ) {
12741     options.values = options.values.slice(0);
12742     }
12743     }
12744    
12745     if ( !this.range || !this.range.length ) {
12746     this.range = $( "<div></div>" )
12747     .appendTo( this.element );
12748    
12749     classes = "ui-slider-range" +
12750     // note: this isn't the most fittingly semantic framework class for this element,
12751     // but worked best visually with a variety of themes
12752     " ui-widget-header ui-corner-all";
12753     } else {
12754     this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12755     // Handle range switching from true to min/max
12756     .css({
12757     "left": "",
12758     "bottom": ""
12759     });
12760     }
12761    
12762     this.range.addClass( classes +
12763     ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12764     } else {
12765     this.range = $([]);
12766     }
12767     },
12768    
12769     _setupEvents: function() {
12770     var elements = this.handles.add( this.range ).filter( "a" );
12771     this._off( elements );
12772     this._on( elements, this._handleEvents );
12773     this._hoverable( elements );
12774     this._focusable( elements );
12775     },
12776    
12777     _destroy: function() {
12778     this.handles.remove();
12779     this.range.remove();
12780    
12781     this.element
12782     .removeClass( "ui-slider" +
12783     " ui-slider-horizontal" +
12784     " ui-slider-vertical" +
12785     " ui-widget" +
12786     " ui-widget-content" +
12787     " ui-corner-all" );
12788    
12789     this._mouseDestroy();
12790     },
12791    
12792     _mouseCapture: function( event ) {
12793     var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12794     that = this,
12795     o = this.options;
12796    
12797     if ( o.disabled ) {
12798     return false;
12799     }
12800    
12801     this.elementSize = {
12802     width: this.element.outerWidth(),
12803     height: this.element.outerHeight()
12804     };
12805     this.elementOffset = this.element.offset();
12806    
12807     position = { x: event.pageX, y: event.pageY };
12808     normValue = this._normValueFromMouse( position );
12809     distance = this._valueMax() - this._valueMin() + 1;
12810     this.handles.each(function( i ) {
12811     var thisDistance = Math.abs( normValue - that.values(i) );
12812     if (( distance > thisDistance ) ||
12813     ( distance === thisDistance &&
12814     (i === that._lastChangedValue || that.values(i) === o.min ))) {
12815     distance = thisDistance;
12816     closestHandle = $( this );
12817     index = i;
12818     }
12819     });
12820    
12821     allowed = this._start( event, index );
12822     if ( allowed === false ) {
12823     return false;
12824     }
12825     this._mouseSliding = true;
12826    
12827     this._handleIndex = index;
12828    
12829     closestHandle
12830     .addClass( "ui-state-active" )
12831     .focus();
12832    
12833     offset = closestHandle.offset();
12834     mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12835     this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12836     left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12837     top: event.pageY - offset.top -
12838     ( closestHandle.height() / 2 ) -
12839     ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12840     ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12841     ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12842     };
12843    
12844     if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12845     this._slide( event, index, normValue );
12846     }
12847     this._animateOff = true;
12848     return true;
12849     },
12850    
12851     _mouseStart: function() {
12852     return true;
12853     },
12854    
12855     _mouseDrag: function( event ) {
12856     var position = { x: event.pageX, y: event.pageY },
12857     normValue = this._normValueFromMouse( position );
12858    
12859     this._slide( event, this._handleIndex, normValue );
12860    
12861     return false;
12862     },
12863    
12864     _mouseStop: function( event ) {
12865     this.handles.removeClass( "ui-state-active" );
12866     this._mouseSliding = false;
12867    
12868     this._stop( event, this._handleIndex );
12869     this._change( event, this._handleIndex );
12870    
12871     this._handleIndex = null;
12872     this._clickOffset = null;
12873     this._animateOff = false;
12874    
12875     return false;
12876     },
12877    
12878     _detectOrientation: function() {
12879     this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12880     },
12881    
12882     _normValueFromMouse: function( position ) {
12883     var pixelTotal,
12884     pixelMouse,
12885     percentMouse,
12886     valueTotal,
12887     valueMouse;
12888    
12889     if ( this.orientation === "horizontal" ) {
12890     pixelTotal = this.elementSize.width;
12891     pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12892     } else {
12893     pixelTotal = this.elementSize.height;
12894     pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12895     }
12896    
12897     percentMouse = ( pixelMouse / pixelTotal );
12898     if ( percentMouse > 1 ) {
12899     percentMouse = 1;
12900     }
12901     if ( percentMouse < 0 ) {
12902     percentMouse = 0;
12903     }
12904     if ( this.orientation === "vertical" ) {
12905     percentMouse = 1 - percentMouse;
12906     }
12907    
12908     valueTotal = this._valueMax() - this._valueMin();
12909     valueMouse = this._valueMin() + percentMouse * valueTotal;
12910    
12911     return this._trimAlignValue( valueMouse );
12912     },
12913    
12914     _start: function( event, index ) {
12915     var uiHash = {
12916     handle: this.handles[ index ],
12917     value: this.value()
12918     };
12919     if ( this.options.values && this.options.values.length ) {
12920     uiHash.value = this.values( index );
12921     uiHash.values = this.values();
12922     }
12923     return this._trigger( "start", event, uiHash );
12924     },
12925    
12926     _slide: function( event, index, newVal ) {
12927     var otherVal,
12928     newValues,
12929     allowed;
12930    
12931     if ( this.options.values && this.options.values.length ) {
12932     otherVal = this.values( index ? 0 : 1 );
12933    
12934     if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12935     ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12936     ) {
12937     newVal = otherVal;
12938     }
12939    
12940     if ( newVal !== this.values( index ) ) {
12941     newValues = this.values();
12942     newValues[ index ] = newVal;
12943     // A slide can be canceled by returning false from the slide callback
12944     allowed = this._trigger( "slide", event, {
12945     handle: this.handles[ index ],
12946     value: newVal,
12947     values: newValues
12948     } );
12949     otherVal = this.values( index ? 0 : 1 );
12950     if ( allowed !== false ) {
12951     this.values( index, newVal, true );
12952     }
12953     }
12954     } else {
12955     if ( newVal !== this.value() ) {
12956     // A slide can be canceled by returning false from the slide callback
12957     allowed = this._trigger( "slide", event, {
12958     handle: this.handles[ index ],
12959     value: newVal
12960     } );
12961     if ( allowed !== false ) {
12962     this.value( newVal );
12963     }
12964     }
12965     }
12966     },
12967    
12968     _stop: function( event, index ) {
12969     var uiHash = {
12970     handle: this.handles[ index ],
12971     value: this.value()
12972     };
12973     if ( this.options.values && this.options.values.length ) {
12974     uiHash.value = this.values( index );
12975     uiHash.values = this.values();
12976     }
12977    
12978     this._trigger( "stop", event, uiHash );
12979     },
12980    
12981     _change: function( event, index ) {
12982     if ( !this._keySliding && !this._mouseSliding ) {
12983     var uiHash = {
12984     handle: this.handles[ index ],
12985     value: this.value()
12986     };
12987     if ( this.options.values && this.options.values.length ) {
12988     uiHash.value = this.values( index );
12989     uiHash.values = this.values();
12990     }
12991    
12992     //store the last changed value index for reference when handles overlap
12993     this._lastChangedValue = index;
12994    
12995     this._trigger( "change", event, uiHash );
12996     }
12997     },
12998    
12999     value: function( newValue ) {
13000     if ( arguments.length ) {
13001     this.options.value = this._trimAlignValue( newValue );
13002     this._refreshValue();
13003     this._change( null, 0 );
13004     return;
13005     }
13006    
13007     return this._value();
13008     },
13009    
13010     values: function( index, newValue ) {
13011     var vals,
13012     newValues,
13013     i;
13014    
13015     if ( arguments.length > 1 ) {
13016     this.options.values[ index ] = this._trimAlignValue( newValue );
13017     this._refreshValue();
13018     this._change( null, index );
13019     return;
13020     }
13021    
13022     if ( arguments.length ) {
13023     if ( $.isArray( arguments[ 0 ] ) ) {
13024     vals = this.options.values;
13025     newValues = arguments[ 0 ];
13026     for ( i = 0; i < vals.length; i += 1 ) {
13027     vals[ i ] = this._trimAlignValue( newValues[ i ] );
13028     this._change( null, i );
13029     }
13030     this._refreshValue();
13031     } else {
13032     if ( this.options.values && this.options.values.length ) {
13033     return this._values( index );
13034     } else {
13035     return this.value();
13036     }
13037     }
13038     } else {
13039     return this._values();
13040     }
13041     },
13042    
13043     _setOption: function( key, value ) {
13044     var i,
13045     valsLength = 0;
13046    
13047     if ( key === "range" && this.options.range === true ) {
13048     if ( value === "min" ) {
13049     this.options.value = this._values( 0 );
13050     this.options.values = null;
13051     } else if ( value === "max" ) {
13052     this.options.value = this._values( this.options.values.length-1 );
13053     this.options.values = null;
13054     }
13055     }
13056    
13057     if ( $.isArray( this.options.values ) ) {
13058     valsLength = this.options.values.length;
13059     }
13060    
13061     $.Widget.prototype._setOption.apply( this, arguments );
13062    
13063     switch ( key ) {
13064     case "orientation":
13065     this._detectOrientation();
13066     this.element
13067     .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13068     .addClass( "ui-slider-" + this.orientation );
13069     this._refreshValue();
13070     break;
13071     case "value":
13072     this._animateOff = true;
13073     this._refreshValue();
13074     this._change( null, 0 );
13075     this._animateOff = false;
13076     break;
13077     case "values":
13078     this._animateOff = true;
13079     this._refreshValue();
13080     for ( i = 0; i < valsLength; i += 1 ) {
13081     this._change( null, i );
13082     }
13083     this._animateOff = false;
13084     break;
13085     case "min":
13086     case "max":
13087     this._animateOff = true;
13088     this._refreshValue();
13089     this._animateOff = false;
13090     break;
13091     case "range":
13092     this._animateOff = true;
13093     this._refresh();
13094     this._animateOff = false;
13095     break;
13096     }
13097     },
13098    
13099     //internal value getter
13100     // _value() returns value trimmed by min and max, aligned by step
13101     _value: function() {
13102     var val = this.options.value;
13103     val = this._trimAlignValue( val );
13104    
13105     return val;
13106     },
13107    
13108     //internal values getter
13109     // _values() returns array of values trimmed by min and max, aligned by step
13110     // _values( index ) returns single value trimmed by min and max, aligned by step
13111     _values: function( index ) {
13112     var val,
13113     vals,
13114     i;
13115    
13116     if ( arguments.length ) {
13117     val = this.options.values[ index ];
13118     val = this._trimAlignValue( val );
13119    
13120     return val;
13121     } else if ( this.options.values && this.options.values.length ) {
13122     // .slice() creates a copy of the array
13123     // this copy gets trimmed by min and max and then returned
13124     vals = this.options.values.slice();
13125     for ( i = 0; i < vals.length; i+= 1) {
13126     vals[ i ] = this._trimAlignValue( vals[ i ] );
13127     }
13128    
13129     return vals;
13130     } else {
13131     return [];
13132     }
13133     },
13134    
13135     // returns the step-aligned value that val is closest to, between (inclusive) min and max
13136     _trimAlignValue: function( val ) {
13137     if ( val <= this._valueMin() ) {
13138     return this._valueMin();
13139     }
13140     if ( val >= this._valueMax() ) {
13141     return this._valueMax();
13142     }
13143     var step = ( this.options.step > 0 ) ? this.options.step : 1,
13144     valModStep = (val - this._valueMin()) % step,
13145     alignValue = val - valModStep;
13146    
13147     if ( Math.abs(valModStep) * 2 >= step ) {
13148     alignValue += ( valModStep > 0 ) ? step : ( -step );
13149     }
13150    
13151     // Since JavaScript has problems with large floats, round
13152     // the final value to 5 digits after the decimal point (see #4124)
13153     return parseFloat( alignValue.toFixed(5) );
13154     },
13155    
13156     _valueMin: function() {
13157     return this.options.min;
13158     },
13159    
13160     _valueMax: function() {
13161     return this.options.max;
13162     },
13163    
13164     _refreshValue: function() {
13165     var lastValPercent, valPercent, value, valueMin, valueMax,
13166     oRange = this.options.range,
13167     o = this.options,
13168     that = this,
13169     animate = ( !this._animateOff ) ? o.animate : false,
13170     _set = {};
13171    
13172     if ( this.options.values && this.options.values.length ) {
13173     this.handles.each(function( i ) {
13174     valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13175     _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13176     $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13177     if ( that.options.range === true ) {
13178     if ( that.orientation === "horizontal" ) {
13179     if ( i === 0 ) {
13180     that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13181     }
13182     if ( i === 1 ) {
13183     that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13184     }
13185     } else {
13186     if ( i === 0 ) {
13187     that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13188     }
13189     if ( i === 1 ) {
13190     that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13191     }
13192     }
13193     }
13194     lastValPercent = valPercent;
13195     });
13196     } else {
13197     value = this.value();
13198     valueMin = this._valueMin();
13199     valueMax = this._valueMax();
13200     valPercent = ( valueMax !== valueMin ) ?
13201     ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13202     0;
13203     _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13204     this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13205    
13206     if ( oRange === "min" && this.orientation === "horizontal" ) {
13207     this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13208     }
13209     if ( oRange === "max" && this.orientation === "horizontal" ) {
13210     this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13211     }
13212     if ( oRange === "min" && this.orientation === "vertical" ) {
13213     this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13214     }
13215     if ( oRange === "max" && this.orientation === "vertical" ) {
13216     this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13217     }
13218     }
13219     },
13220    
13221     _handleEvents: {
13222     keydown: function( event ) {
13223     /*jshint maxcomplexity:25*/
13224     var allowed, curVal, newVal, step,
13225     index = $( event.target ).data( "ui-slider-handle-index" );
13226    
13227     switch ( event.keyCode ) {
13228     case $.ui.keyCode.HOME:
13229     case $.ui.keyCode.END:
13230     case $.ui.keyCode.PAGE_UP:
13231     case $.ui.keyCode.PAGE_DOWN:
13232     case $.ui.keyCode.UP:
13233     case $.ui.keyCode.RIGHT:
13234     case $.ui.keyCode.DOWN:
13235     case $.ui.keyCode.LEFT:
13236     event.preventDefault();
13237     if ( !this._keySliding ) {
13238     this._keySliding = true;
13239     $( event.target ).addClass( "ui-state-active" );
13240     allowed = this._start( event, index );
13241     if ( allowed === false ) {
13242     return;
13243     }
13244     }
13245     break;
13246     }
13247    
13248     step = this.options.step;
13249     if ( this.options.values && this.options.values.length ) {
13250     curVal = newVal = this.values( index );
13251     } else {
13252     curVal = newVal = this.value();
13253     }
13254    
13255     switch ( event.keyCode ) {
13256     case $.ui.keyCode.HOME:
13257     newVal = this._valueMin();
13258     break;
13259     case $.ui.keyCode.END:
13260     newVal = this._valueMax();
13261     break;
13262     case $.ui.keyCode.PAGE_UP:
13263     newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13264     break;
13265     case $.ui.keyCode.PAGE_DOWN:
13266     newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13267     break;
13268     case $.ui.keyCode.UP:
13269     case $.ui.keyCode.RIGHT:
13270     if ( curVal === this._valueMax() ) {
13271     return;
13272     }
13273     newVal = this._trimAlignValue( curVal + step );
13274     break;
13275     case $.ui.keyCode.DOWN:
13276     case $.ui.keyCode.LEFT:
13277     if ( curVal === this._valueMin() ) {
13278     return;
13279     }
13280     newVal = this._trimAlignValue( curVal - step );
13281     break;
13282     }
13283    
13284     this._slide( event, index, newVal );
13285     },
13286     click: function( event ) {
13287     event.preventDefault();
13288     },
13289     keyup: function( event ) {
13290     var index = $( event.target ).data( "ui-slider-handle-index" );
13291    
13292     if ( this._keySliding ) {
13293     this._keySliding = false;
13294     this._stop( event, index );
13295     this._change( event, index );
13296     $( event.target ).removeClass( "ui-state-active" );
13297     }
13298     }
13299     }
13300    
13301     });
13302    
13303     }(jQuery));
13304    
13305     (function( $ ) {
13306    
13307     function modifier( fn ) {
13308     return function() {
13309     var previous = this.element.val();
13310     fn.apply( this, arguments );
13311     this._refresh();
13312     if ( previous !== this.element.val() ) {
13313     this._trigger( "change" );
13314     }
13315     };
13316     }
13317    
13318     $.widget( "ui.spinner", {
13319     version: "1.10.3",
13320     defaultElement: "<input>",
13321     widgetEventPrefix: "spin",
13322     options: {
13323     culture: null,
13324     icons: {
13325     down: "ui-icon-triangle-1-s",
13326     up: "ui-icon-triangle-1-n"
13327     },
13328     incremental: true,
13329     max: null,
13330     min: null,
13331     numberFormat: null,
13332     page: 10,
13333     step: 1,
13334    
13335     change: null,
13336     spin: null,
13337     start: null,
13338     stop: null
13339     },
13340    
13341     _create: function() {
13342     // handle string values that need to be parsed
13343     this._setOption( "max", this.options.max );
13344     this._setOption( "min", this.options.min );
13345     this._setOption( "step", this.options.step );
13346    
13347     // format the value, but don't constrain
13348     this._value( this.element.val(), true );
13349    
13350     this._draw();
13351     this._on( this._events );
13352     this._refresh();
13353    
13354     // turning off autocomplete prevents the browser from remembering the
13355     // value when navigating through history, so we re-enable autocomplete
13356     // if the page is unloaded before the widget is destroyed. #7790
13357     this._on( this.window, {
13358     beforeunload: function() {
13359     this.element.removeAttr( "autocomplete" );
13360     }
13361     });
13362     },
13363    
13364     _getCreateOptions: function() {
13365     var options = {},
13366     element = this.element;
13367    
13368     $.each( [ "min", "max", "step" ], function( i, option ) {
13369     var value = element.attr( option );
13370     if ( value !== undefined && value.length ) {
13371     options[ option ] = value;
13372     }
13373     });
13374    
13375     return options;
13376     },
13377    
13378     _events: {
13379     keydown: function( event ) {
13380     if ( this._start( event ) && this._keydown( event ) ) {
13381     event.preventDefault();
13382     }
13383     },
13384     keyup: "_stop",
13385     focus: function() {
13386     this.previous = this.element.val();
13387     },
13388     blur: function( event ) {
13389     if ( this.cancelBlur ) {
13390     delete this.cancelBlur;
13391     return;
13392     }
13393    
13394     this._stop();
13395     this._refresh();
13396     if ( this.previous !== this.element.val() ) {
13397     this._trigger( "change", event );
13398     }
13399     },
13400     mousewheel: function( event, delta ) {
13401     if ( !delta ) {
13402     return;
13403     }
13404     if ( !this.spinning && !this._start( event ) ) {
13405     return false;
13406     }
13407    
13408     this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
13409     clearTimeout( this.mousewheelTimer );
13410     this.mousewheelTimer = this._delay(function() {
13411     if ( this.spinning ) {
13412     this._stop( event );
13413     }
13414     }, 100 );
13415     event.preventDefault();
13416     },
13417     "mousedown .ui-spinner-button": function( event ) {
13418     var previous;
13419    
13420     // We never want the buttons to have focus; whenever the user is
13421     // interacting with the spinner, the focus should be on the input.
13422     // If the input is focused then this.previous is properly set from
13423     // when the input first received focus. If the input is not focused
13424     // then we need to set this.previous based on the value before spinning.
13425     previous = this.element[0] === this.document[0].activeElement ?
13426     this.previous : this.element.val();
13427     function checkFocus() {
13428     var isActive = this.element[0] === this.document[0].activeElement;
13429     if ( !isActive ) {
13430     this.element.focus();
13431     this.previous = previous;
13432     // support: IE
13433     // IE sets focus asynchronously, so we need to check if focus
13434     // moved off of the input because the user clicked on the button.
13435     this._delay(function() {
13436     this.previous = previous;
13437     });
13438     }
13439     }
13440    
13441     // ensure focus is on (or stays on) the text field
13442     event.preventDefault();
13443     checkFocus.call( this );
13444    
13445     // support: IE
13446     // IE doesn't prevent moving focus even with event.preventDefault()
13447     // so we set a flag to know when we should ignore the blur event
13448     // and check (again) if focus moved off of the input.
13449     this.cancelBlur = true;
13450     this._delay(function() {
13451     delete this.cancelBlur;
13452     checkFocus.call( this );
13453     });
13454    
13455     if ( this._start( event ) === false ) {
13456     return;
13457     }
13458    
13459     this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13460     },
13461     "mouseup .ui-spinner-button": "_stop",
13462     "mouseenter .ui-spinner-button": function( event ) {
13463     // button will add ui-state-active if mouse was down while mouseleave and kept down
13464     if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13465     return;
13466     }
13467    
13468     if ( this._start( event ) === false ) {
13469     return false;
13470     }
13471     this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13472     },
13473     // TODO: do we really want to consider this a stop?
13474     // shouldn't we just stop the repeater and wait until mouseup before
13475     // we trigger the stop event?
13476     "mouseleave .ui-spinner-button": "_stop"
13477     },
13478    
13479     _draw: function() {
13480     var uiSpinner = this.uiSpinner = this.element
13481     .addClass( "ui-spinner-input" )
13482     .attr( "autocomplete", "off" )
13483     .wrap( this._uiSpinnerHtml() )
13484     .parent()
13485     // add buttons
13486     .append( this._buttonHtml() );
13487    
13488     this.element.attr( "role", "spinbutton" );
13489    
13490     // button bindings
13491     this.buttons = uiSpinner.find( ".ui-spinner-button" )
13492     .attr( "tabIndex", -1 )
13493     .button()
13494     .removeClass( "ui-corner-all" );
13495    
13496     // IE 6 doesn't understand height: 50% for the buttons
13497     // unless the wrapper has an explicit height
13498     if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
13499     uiSpinner.height() > 0 ) {
13500     uiSpinner.height( uiSpinner.height() );
13501     }
13502    
13503     // disable spinner if element was already disabled
13504     if ( this.options.disabled ) {
13505     this.disable();
13506     }
13507     },
13508    
13509     _keydown: function( event ) {
13510     var options = this.options,
13511     keyCode = $.ui.keyCode;
13512    
13513     switch ( event.keyCode ) {
13514     case keyCode.UP:
13515     this._repeat( null, 1, event );
13516     return true;
13517     case keyCode.DOWN:
13518     this._repeat( null, -1, event );
13519     return true;
13520     case keyCode.PAGE_UP:
13521     this._repeat( null, options.page, event );
13522     return true;
13523     case keyCode.PAGE_DOWN:
13524     this._repeat( null, -options.page, event );
13525     return true;
13526     }
13527    
13528     return false;
13529     },
13530    
13531     _uiSpinnerHtml: function() {
13532     return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
13533     },
13534    
13535     _buttonHtml: function() {
13536     return "" +
13537     "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
13538     "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
13539     "</a>" +
13540     "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
13541     "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
13542     "</a>";
13543     },
13544    
13545     _start: function( event ) {
13546     if ( !this.spinning && this._trigger( "start", event ) === false ) {
13547     return false;
13548     }
13549    
13550     if ( !this.counter ) {
13551     this.counter = 1;
13552     }
13553     this.spinning = true;
13554     return true;
13555     },
13556    
13557     _repeat: function( i, steps, event ) {
13558     i = i || 500;
13559    
13560     clearTimeout( this.timer );
13561     this.timer = this._delay(function() {
13562     this._repeat( 40, steps, event );
13563     }, i );
13564    
13565     this._spin( steps * this.options.step, event );
13566     },
13567    
13568     _spin: function( step, event ) {
13569     var value = this.value() || 0;
13570    
13571     if ( !this.counter ) {
13572     this.counter = 1;
13573     }
13574    
13575     value = this._adjustValue( value + step * this._increment( this.counter ) );
13576    
13577     if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
13578     this._value( value );
13579     this.counter++;
13580     }
13581     },
13582    
13583     _increment: function( i ) {
13584     var incremental = this.options.incremental;
13585    
13586     if ( incremental ) {
13587     return $.isFunction( incremental ) ?
13588     incremental( i ) :
13589     Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
13590     }
13591    
13592     return 1;
13593     },
13594    
13595     _precision: function() {
13596     var precision = this._precisionOf( this.options.step );
13597     if ( this.options.min !== null ) {
13598     precision = Math.max( precision, this._precisionOf( this.options.min ) );
13599     }
13600     return precision;
13601     },
13602    
13603     _precisionOf: function( num ) {
13604     var str = num.toString(),
13605     decimal = str.indexOf( "." );
13606     return decimal === -1 ? 0 : str.length - decimal - 1;
13607     },
13608    
13609     _adjustValue: function( value ) {
13610     var base, aboveMin,
13611     options = this.options;
13612    
13613     // make sure we're at a valid step
13614     // - find out where we are relative to the base (min or 0)
13615     base = options.min !== null ? options.min : 0;
13616     aboveMin = value - base;
13617     // - round to the nearest step
13618     aboveMin = Math.round(aboveMin / options.step) * options.step;
13619     // - rounding is based on 0, so adjust back to our base
13620     value = base + aboveMin;
13621    
13622     // fix precision from bad JS floating point math
13623     value = parseFloat( value.toFixed( this._precision() ) );
13624    
13625     // clamp the value
13626     if ( options.max !== null && value > options.max) {
13627     return options.max;
13628     }
13629     if ( options.min !== null && value < options.min ) {
13630     return options.min;
13631     }
13632    
13633     return value;
13634     },
13635    
13636     _stop: function( event ) {
13637     if ( !this.spinning ) {
13638     return;
13639     }
13640    
13641     clearTimeout( this.timer );
13642     clearTimeout( this.mousewheelTimer );
13643     this.counter = 0;
13644     this.spinning = false;
13645     this._trigger( "stop", event );
13646     },
13647    
13648     _setOption: function( key, value ) {
13649     if ( key === "culture" || key === "numberFormat" ) {
13650     var prevValue = this._parse( this.element.val() );
13651     this.options[ key ] = value;
13652     this.element.val( this._format( prevValue ) );
13653     return;
13654     }
13655    
13656     if ( key === "max" || key === "min" || key === "step" ) {
13657     if ( typeof value === "string" ) {
13658     value = this._parse( value );
13659     }
13660     }
13661     if ( key === "icons" ) {
13662     this.buttons.first().find( ".ui-icon" )
13663     .removeClass( this.options.icons.up )
13664     .addClass( value.up );
13665     this.buttons.last().find( ".ui-icon" )
13666     .removeClass( this.options.icons.down )
13667     .addClass( value.down );
13668     }
13669    
13670     this._super( key, value );
13671    
13672     if ( key === "disabled" ) {
13673     if ( value ) {
13674     this.element.prop( "disabled", true );
13675     this.buttons.button( "disable" );
13676     } else {
13677     this.element.prop( "disabled", false );
13678     this.buttons.button( "enable" );
13679     }
13680     }
13681     },
13682    
13683     _setOptions: modifier(function( options ) {
13684     this._super( options );
13685     this._value( this.element.val() );
13686     }),
13687    
13688     _parse: function( val ) {
13689     if ( typeof val === "string" && val !== "" ) {
13690     val = window.Globalize && this.options.numberFormat ?
13691     Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13692     }
13693     return val === "" || isNaN( val ) ? null : val;
13694     },
13695    
13696     _format: function( value ) {
13697     if ( value === "" ) {
13698     return "";
13699     }
13700     return window.Globalize && this.options.numberFormat ?
13701     Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13702     value;
13703     },
13704    
13705     _refresh: function() {
13706     this.element.attr({
13707     "aria-valuemin": this.options.min,
13708     "aria-valuemax": this.options.max,
13709     // TODO: what should we do with values that can't be parsed?
13710     "aria-valuenow": this._parse( this.element.val() )
13711     });
13712     },
13713    
13714     // update the value without triggering change
13715     _value: function( value, allowAny ) {
13716     var parsed;
13717     if ( value !== "" ) {
13718     parsed = this._parse( value );
13719     if ( parsed !== null ) {
13720     if ( !allowAny ) {
13721     parsed = this._adjustValue( parsed );
13722     }
13723     value = this._format( parsed );
13724     }
13725     }
13726     this.element.val( value );
13727     this._refresh();
13728     },
13729    
13730     _destroy: function() {
13731     this.element
13732     .removeClass( "ui-spinner-input" )
13733     .prop( "disabled", false )
13734     .removeAttr( "autocomplete" )
13735     .removeAttr( "role" )
13736     .removeAttr( "aria-valuemin" )
13737     .removeAttr( "aria-valuemax" )
13738     .removeAttr( "aria-valuenow" );
13739     this.uiSpinner.replaceWith( this.element );
13740     },
13741    
13742     stepUp: modifier(function( steps ) {
13743     this._stepUp( steps );
13744     }),
13745     _stepUp: function( steps ) {
13746     if ( this._start() ) {
13747     this._spin( (steps || 1) * this.options.step );
13748     this._stop();
13749     }
13750     },
13751    
13752     stepDown: modifier(function( steps ) {
13753     this._stepDown( steps );
13754     }),
13755     _stepDown: function( steps ) {
13756     if ( this._start() ) {
13757     this._spin( (steps || 1) * -this.options.step );
13758     this._stop();
13759     }
13760     },
13761    
13762     pageUp: modifier(function( pages ) {
13763     this._stepUp( (pages || 1) * this.options.page );
13764     }),
13765    
13766     pageDown: modifier(function( pages ) {
13767     this._stepDown( (pages || 1) * this.options.page );
13768     }),
13769    
13770     value: function( newVal ) {
13771     if ( !arguments.length ) {
13772     return this._parse( this.element.val() );
13773     }
13774     modifier( this._value ).call( this, newVal );
13775     },
13776    
13777     widget: function() {
13778     return this.uiSpinner;
13779     }
13780     });
13781    
13782     }( jQuery ) );
13783    
13784     (function( $, undefined ) {
13785    
13786     var tabId = 0,
13787     rhash = /#.*$/;
13788    
13789     function getNextTabId() {
13790     return ++tabId;
13791     }
13792    
13793     function isLocal( anchor ) {
13794     return anchor.hash.length > 1 &&
13795     decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
13796     decodeURIComponent( location.href.replace( rhash, "" ) );
13797     }
13798    
13799     $.widget( "ui.tabs", {
13800     version: "1.10.3",
13801     delay: 300,
13802     options: {
13803     active: null,
13804     collapsible: false,
13805     event: "click",
13806     heightStyle: "content",
13807     hide: null,
13808     show: null,
13809    
13810     // callbacks
13811     activate: null,
13812     beforeActivate: null,
13813     beforeLoad: null,
13814     load: null
13815     },
13816    
13817     _create: function() {
13818     var that = this,
13819     options = this.options;
13820    
13821     this.running = false;
13822    
13823     this.element
13824     .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13825     .toggleClass( "ui-tabs-collapsible", options.collapsible )
13826     // Prevent users from focusing disabled tabs via click
13827     .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13828     if ( $( this ).is( ".ui-state-disabled" ) ) {
13829     event.preventDefault();
13830     }
13831     })
13832     // support: IE <9
13833     // Preventing the default action in mousedown doesn't prevent IE
13834     // from focusing the element, so if the anchor gets focused, blur.
13835     // We don't have to worry about focusing the previously focused
13836     // element since clicking on a non-focusable element should focus
13837     // the body anyway.
13838     .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13839     if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13840     this.blur();
13841     }
13842     });
13843    
13844     this._processTabs();
13845     options.active = this._initialActive();
13846    
13847     // Take disabling tabs via class attribute from HTML
13848     // into account and update option properly.
13849     if ( $.isArray( options.disabled ) ) {
13850     options.disabled = $.unique( options.disabled.concat(
13851     $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13852     return that.tabs.index( li );
13853     })
13854     ) ).sort();
13855     }
13856    
13857     // check for length avoids error when initializing empty list
13858     if ( this.options.active !== false && this.anchors.length ) {
13859     this.active = this._findActive( options.active );
13860     } else {
13861     this.active = $();
13862     }
13863    
13864     this._refresh();
13865    
13866     if ( this.active.length ) {
13867     this.load( options.active );
13868     }
13869     },
13870    
13871     _initialActive: function() {
13872     var active = this.options.active,
13873     collapsible = this.options.collapsible,
13874     locationHash = location.hash.substring( 1 );
13875    
13876     if ( active === null ) {
13877     // check the fragment identifier in the URL
13878     if ( locationHash ) {
13879     this.tabs.each(function( i, tab ) {
13880     if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13881     active = i;
13882     return false;
13883     }
13884     });
13885     }
13886    
13887     // check for a tab marked active via a class
13888     if ( active === null ) {
13889     active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13890     }
13891    
13892     // no active tab, set to false
13893     if ( active === null || active === -1 ) {
13894     active = this.tabs.length ? 0 : false;
13895     }
13896     }
13897    
13898     // handle numbers: negative, out of range
13899     if ( active !== false ) {
13900     active = this.tabs.index( this.tabs.eq( active ) );
13901     if ( active === -1 ) {
13902     active = collapsible ? false : 0;
13903     }
13904     }
13905    
13906     // don't allow collapsible: false and active: false
13907     if ( !collapsible && active === false && this.anchors.length ) {
13908     active = 0;
13909     }
13910    
13911     return active;
13912     },
13913    
13914     _getCreateEventData: function() {
13915     return {
13916     tab: this.active,
13917     panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13918     };
13919     },
13920    
13921     _tabKeydown: function( event ) {
13922     /*jshint maxcomplexity:15*/
13923     var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13924     selectedIndex = this.tabs.index( focusedTab ),
13925     goingForward = true;
13926    
13927     if ( this._handlePageNav( event ) ) {
13928     return;
13929     }
13930    
13931     switch ( event.keyCode ) {
13932     case $.ui.keyCode.RIGHT:
13933     case $.ui.keyCode.DOWN:
13934     selectedIndex++;
13935     break;
13936     case $.ui.keyCode.UP:
13937     case $.ui.keyCode.LEFT:
13938     goingForward = false;
13939     selectedIndex--;
13940     break;
13941     case $.ui.keyCode.END:
13942     selectedIndex = this.anchors.length - 1;
13943     break;
13944     case $.ui.keyCode.HOME:
13945     selectedIndex = 0;
13946     break;
13947     case $.ui.keyCode.SPACE:
13948     // Activate only, no collapsing
13949     event.preventDefault();
13950     clearTimeout( this.activating );
13951     this._activate( selectedIndex );
13952     return;
13953     case $.ui.keyCode.ENTER:
13954     // Toggle (cancel delayed activation, allow collapsing)
13955     event.preventDefault();
13956     clearTimeout( this.activating );
13957     // Determine if we should collapse or activate
13958     this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13959     return;
13960     default:
13961     return;
13962     }
13963    
13964     // Focus the appropriate tab, based on which key was pressed
13965     event.preventDefault();
13966     clearTimeout( this.activating );
13967     selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13968    
13969     // Navigating with control key will prevent automatic activation
13970     if ( !event.ctrlKey ) {
13971     // Update aria-selected immediately so that AT think the tab is already selected.
13972     // Otherwise AT may confuse the user by stating that they need to activate the tab,
13973     // but the tab will already be activated by the time the announcement finishes.
13974     focusedTab.attr( "aria-selected", "false" );
13975     this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13976    
13977     this.activating = this._delay(function() {
13978     this.option( "active", selectedIndex );
13979     }, this.delay );
13980     }
13981     },
13982    
13983     _panelKeydown: function( event ) {
13984     if ( this._handlePageNav( event ) ) {
13985     return;
13986     }
13987    
13988     // Ctrl+up moves focus to the current tab
13989     if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13990     event.preventDefault();
13991     this.active.focus();
13992     }
13993     },
13994    
13995     // Alt+page up/down moves focus to the previous/next tab (and activates)
13996     _handlePageNav: function( event ) {
13997     if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13998     this._activate( this._focusNextTab( this.options.active - 1, false ) );
13999     return true;
14000     }
14001     if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14002     this._activate( this._focusNextTab( this.options.active + 1, true ) );
14003     return true;
14004     }
14005     },
14006    
14007     _findNextTab: function( index, goingForward ) {
14008     var lastTabIndex = this.tabs.length - 1;
14009    
14010     function constrain() {
14011     if ( index > lastTabIndex ) {
14012     index = 0;
14013     }
14014     if ( index < 0 ) {
14015     index = lastTabIndex;
14016     }
14017     return index;
14018     }
14019    
14020     while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14021     index = goingForward ? index + 1 : index - 1;
14022     }
14023    
14024     return index;
14025     },
14026    
14027     _focusNextTab: function( index, goingForward ) {
14028     index = this._findNextTab( index, goingForward );
14029     this.tabs.eq( index ).focus();
14030     return index;
14031     },
14032    
14033     _setOption: function( key, value ) {
14034     if ( key === "active" ) {
14035     // _activate() will handle invalid values and update this.options
14036     this._activate( value );
14037     return;
14038     }
14039    
14040     if ( key === "disabled" ) {
14041     // don't use the widget factory's disabled handling
14042     this._setupDisabled( value );
14043     return;
14044     }
14045    
14046     this._super( key, value);
14047    
14048     if ( key === "collapsible" ) {
14049     this.element.toggleClass( "ui-tabs-collapsible", value );
14050     // Setting collapsible: false while collapsed; open first panel
14051     if ( !value && this.options.active === false ) {
14052     this._activate( 0 );
14053     }
14054     }
14055    
14056     if ( key === "event" ) {
14057     this._setupEvents( value );
14058     }
14059    
14060     if ( key === "heightStyle" ) {
14061     this._setupHeightStyle( value );
14062     }
14063     },
14064    
14065     _tabId: function( tab ) {
14066     return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
14067     },
14068    
14069     _sanitizeSelector: function( hash ) {
14070     return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14071     },
14072    
14073     refresh: function() {
14074     var options = this.options,
14075     lis = this.tablist.children( ":has(a[href])" );
14076    
14077     // get disabled tabs from class attribute from HTML
14078     // this will get converted to a boolean if needed in _refresh()
14079     options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14080     return lis.index( tab );
14081     });
14082    
14083     this._processTabs();
14084    
14085     // was collapsed or no tabs
14086     if ( options.active === false || !this.anchors.length ) {
14087     options.active = false;
14088     this.active = $();
14089     // was active, but active tab is gone
14090     } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14091     // all remaining tabs are disabled
14092     if ( this.tabs.length === options.disabled.length ) {
14093     options.active = false;
14094     this.active = $();
14095     // activate previous tab
14096     } else {
14097     this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14098     }
14099     // was active, active tab still exists
14100     } else {
14101     // make sure active index is correct
14102     options.active = this.tabs.index( this.active );
14103     }
14104    
14105     this._refresh();
14106     },
14107    
14108     _refresh: function() {
14109     this._setupDisabled( this.options.disabled );
14110     this._setupEvents( this.options.event );
14111     this._setupHeightStyle( this.options.heightStyle );
14112    
14113     this.tabs.not( this.active ).attr({
14114     "aria-selected": "false",
14115     tabIndex: -1
14116     });
14117     this.panels.not( this._getPanelForTab( this.active ) )
14118     .hide()
14119     .attr({
14120     "aria-expanded": "false",
14121     "aria-hidden": "true"
14122     });
14123    
14124     // Make sure one tab is in the tab order
14125     if ( !this.active.length ) {
14126     this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14127     } else {
14128     this.active
14129     .addClass( "ui-tabs-active ui-state-active" )
14130     .attr({
14131     "aria-selected": "true",
14132     tabIndex: 0
14133     });
14134     this._getPanelForTab( this.active )
14135     .show()
14136     .attr({
14137     "aria-expanded": "true",
14138     "aria-hidden": "false"
14139     });
14140     }
14141     },
14142    
14143     _processTabs: function() {
14144     var that = this;
14145    
14146     this.tablist = this._getList()
14147     .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14148     .attr( "role", "tablist" );
14149    
14150     this.tabs = this.tablist.find( "> li:has(a[href])" )
14151     .addClass( "ui-state-default ui-corner-top" )
14152     .attr({
14153     role: "tab",
14154     tabIndex: -1
14155     });
14156    
14157     this.anchors = this.tabs.map(function() {
14158     return $( "a", this )[ 0 ];
14159     })
14160     .addClass( "ui-tabs-anchor" )
14161     .attr({
14162     role: "presentation",
14163     tabIndex: -1
14164     });
14165    
14166     this.panels = $();
14167    
14168     this.anchors.each(function( i, anchor ) {
14169     var selector, panel, panelId,
14170     anchorId = $( anchor ).uniqueId().attr( "id" ),
14171     tab = $( anchor ).closest( "li" ),
14172     originalAriaControls = tab.attr( "aria-controls" );
14173    
14174     // inline tab
14175     if ( isLocal( anchor ) ) {
14176     selector = anchor.hash;
14177     panel = that.element.find( that._sanitizeSelector( selector ) );
14178     // remote tab
14179     } else {
14180     panelId = that._tabId( tab );
14181     selector = "#" + panelId;
14182     panel = that.element.find( selector );
14183     if ( !panel.length ) {
14184     panel = that._createPanel( panelId );
14185     panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14186     }
14187     panel.attr( "aria-live", "polite" );
14188     }
14189    
14190     if ( panel.length) {
14191     that.panels = that.panels.add( panel );
14192     }
14193     if ( originalAriaControls ) {
14194     tab.data( "ui-tabs-aria-controls", originalAriaControls );
14195     }
14196     tab.attr({
14197     "aria-controls": selector.substring( 1 ),
14198     "aria-labelledby": anchorId
14199     });
14200     panel.attr( "aria-labelledby", anchorId );
14201     });
14202    
14203     this.panels
14204     .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14205     .attr( "role", "tabpanel" );
14206     },
14207    
14208     // allow overriding how to find the list for rare usage scenarios (#7715)
14209     _getList: function() {
14210     return this.element.find( "ol,ul" ).eq( 0 );
14211     },
14212    
14213     _createPanel: function( id ) {
14214     return $( "<div>" )
14215     .attr( "id", id )
14216     .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14217     .data( "ui-tabs-destroy", true );
14218     },
14219    
14220     _setupDisabled: function( disabled ) {
14221     if ( $.isArray( disabled ) ) {
14222     if ( !disabled.length ) {
14223     disabled = false;
14224     } else if ( disabled.length === this.anchors.length ) {
14225     disabled = true;
14226     }
14227     }
14228    
14229     // disable tabs
14230     for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
14231     if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14232     $( li )
14233     .addClass( "ui-state-disabled" )
14234     .attr( "aria-disabled", "true" );
14235     } else {
14236     $( li )
14237     .removeClass( "ui-state-disabled" )
14238     .removeAttr( "aria-disabled" );
14239     }
14240     }
14241    
14242     this.options.disabled = disabled;
14243     },
14244    
14245     _setupEvents: function( event ) {
14246     var events = {
14247     click: function( event ) {
14248     event.preventDefault();
14249     }
14250     };
14251     if ( event ) {
14252     $.each( event.split(" "), function( index, eventName ) {
14253     events[ eventName ] = "_eventHandler";
14254     });
14255     }
14256    
14257     this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14258     this._on( this.anchors, events );
14259     this._on( this.tabs, { keydown: "_tabKeydown" } );
14260     this._on( this.panels, { keydown: "_panelKeydown" } );
14261    
14262     this._focusable( this.tabs );
14263     this._hoverable( this.tabs );
14264     },
14265    
14266     _setupHeightStyle: function( heightStyle ) {
14267     var maxHeight,
14268     parent = this.element.parent();
14269    
14270     if ( heightStyle === "fill" ) {
14271     maxHeight = parent.height();
14272     maxHeight -= this.element.outerHeight() - this.element.height();
14273    
14274     this.element.siblings( ":visible" ).each(function() {
14275     var elem = $( this ),
14276     position = elem.css( "position" );
14277    
14278     if ( position === "absolute" || position === "fixed" ) {
14279     return;
14280     }
14281     maxHeight -= elem.outerHeight( true );
14282     });
14283    
14284     this.element.children().not( this.panels ).each(function() {
14285     maxHeight -= $( this ).outerHeight( true );
14286     });
14287    
14288     this.panels.each(function() {
14289     $( this ).height( Math.max( 0, maxHeight -
14290     $( this ).innerHeight() + $( this ).height() ) );
14291     })
14292     .css( "overflow", "auto" );
14293     } else if ( heightStyle === "auto" ) {
14294     maxHeight = 0;
14295     this.panels.each(function() {
14296     maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14297     }).height( maxHeight );
14298     }
14299     },
14300    
14301     _eventHandler: function( event ) {
14302     var options = this.options,
14303     active = this.active,
14304     anchor = $( event.currentTarget ),
14305     tab = anchor.closest( "li" ),
14306     clickedIsActive = tab[ 0 ] === active[ 0 ],
14307     collapsing = clickedIsActive && options.collapsible,
14308     toShow = collapsing ? $() : this._getPanelForTab( tab ),
14309     toHide = !active.length ? $() : this._getPanelForTab( active ),
14310     eventData = {
14311     oldTab: active,
14312     oldPanel: toHide,
14313     newTab: collapsing ? $() : tab,
14314     newPanel: toShow
14315     };
14316    
14317     event.preventDefault();
14318    
14319     if ( tab.hasClass( "ui-state-disabled" ) ||
14320     // tab is already loading
14321     tab.hasClass( "ui-tabs-loading" ) ||
14322     // can't switch durning an animation
14323     this.running ||
14324     // click on active header, but not collapsible
14325     ( clickedIsActive && !options.collapsible ) ||
14326     // allow canceling activation
14327     ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14328     return;
14329     }
14330    
14331     options.active = collapsing ? false : this.tabs.index( tab );
14332    
14333     this.active = clickedIsActive ? $() : tab;
14334     if ( this.xhr ) {
14335     this.xhr.abort();
14336     }
14337    
14338     if ( !toHide.length && !toShow.length ) {
14339     $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14340     }
14341    
14342     if ( toShow.length ) {
14343     this.load( this.tabs.index( tab ), event );
14344     }
14345     this._toggle( event, eventData );
14346     },
14347    
14348     // handles show/hide for selecting tabs
14349     _toggle: function( event, eventData ) {
14350     var that = this,
14351     toShow = eventData.newPanel,
14352     toHide = eventData.oldPanel;
14353    
14354     this.running = true;
14355    
14356     function complete() {
14357     that.running = false;
14358     that._trigger( "activate", event, eventData );
14359     }
14360    
14361     function show() {
14362     eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14363    
14364     if ( toShow.length && that.options.show ) {
14365     that._show( toShow, that.options.show, complete );
14366     } else {
14367     toShow.show();
14368     complete();
14369     }
14370     }
14371    
14372     // start out by hiding, then showing, then completing
14373     if ( toHide.length && this.options.hide ) {
14374     this._hide( toHide, this.options.hide, function() {
14375     eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14376     show();
14377     });
14378     } else {
14379     eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14380     toHide.hide();
14381     show();
14382     }
14383    
14384     toHide.attr({
14385     "aria-expanded": "false",
14386     "aria-hidden": "true"
14387     });
14388     eventData.oldTab.attr( "aria-selected", "false" );
14389     // If we're switching tabs, remove the old tab from the tab order.
14390     // If we're opening from collapsed state, remove the previous tab from the tab order.
14391     // If we're collapsing, then keep the collapsing tab in the tab order.
14392     if ( toShow.length && toHide.length ) {
14393     eventData.oldTab.attr( "tabIndex", -1 );
14394     } else if ( toShow.length ) {
14395     this.tabs.filter(function() {
14396     return $( this ).attr( "tabIndex" ) === 0;
14397     })
14398     .attr( "tabIndex", -1 );
14399     }
14400    
14401     toShow.attr({
14402     "aria-expanded": "true",
14403     "aria-hidden": "false"
14404     });
14405     eventData.newTab.attr({
14406     "aria-selected": "true",
14407     tabIndex: 0
14408     });
14409     },
14410    
14411     _activate: function( index ) {
14412     var anchor,
14413     active = this._findActive( index );
14414    
14415     // trying to activate the already active panel
14416     if ( active[ 0 ] === this.active[ 0 ] ) {
14417     return;
14418     }
14419    
14420     // trying to collapse, simulate a click on the current active header
14421     if ( !active.length ) {
14422     active = this.active;
14423     }
14424    
14425     anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14426     this._eventHandler({
14427     target: anchor,
14428     currentTarget: anchor,
14429     preventDefault: $.noop
14430     });
14431     },
14432    
14433     _findActive: function( index ) {
14434     return index === false ? $() : this.tabs.eq( index );
14435     },
14436    
14437     _getIndex: function( index ) {
14438     // meta-function to give users option to provide a href string instead of a numerical index.
14439     if ( typeof index === "string" ) {
14440     index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
14441     }
14442    
14443     return index;
14444     },
14445    
14446     _destroy: function() {
14447     if ( this.xhr ) {
14448     this.xhr.abort();
14449     }
14450    
14451     this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
14452    
14453     this.tablist
14454     .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14455     .removeAttr( "role" );
14456    
14457     this.anchors
14458     .removeClass( "ui-tabs-anchor" )
14459     .removeAttr( "role" )
14460     .removeAttr( "tabIndex" )
14461     .removeUniqueId();
14462    
14463     this.tabs.add( this.panels ).each(function() {
14464     if ( $.data( this, "ui-tabs-destroy" ) ) {
14465     $( this ).remove();
14466     } else {
14467     $( this )
14468     .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
14469     "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
14470     .removeAttr( "tabIndex" )
14471     .removeAttr( "aria-live" )
14472     .removeAttr( "aria-busy" )
14473     .removeAttr( "aria-selected" )
14474     .removeAttr( "aria-labelledby" )
14475     .removeAttr( "aria-hidden" )
14476     .removeAttr( "aria-expanded" )
14477     .removeAttr( "role" );
14478     }
14479     });
14480    
14481     this.tabs.each(function() {
14482     var li = $( this ),
14483     prev = li.data( "ui-tabs-aria-controls" );
14484     if ( prev ) {
14485     li
14486     .attr( "aria-controls", prev )
14487     .removeData( "ui-tabs-aria-controls" );
14488     } else {
14489     li.removeAttr( "aria-controls" );
14490     }
14491     });
14492    
14493     this.panels.show();
14494    
14495     if ( this.options.heightStyle !== "content" ) {
14496     this.panels.css( "height", "" );
14497     }
14498     },
14499    
14500     enable: function( index ) {
14501     var disabled = this.options.disabled;
14502     if ( disabled === false ) {
14503     return;
14504     }
14505    
14506     if ( index === undefined ) {
14507     disabled = false;
14508     } else {
14509     index = this._getIndex( index );
14510     if ( $.isArray( disabled ) ) {
14511     disabled = $.map( disabled, function( num ) {
14512     return num !== index ? num : null;
14513     });
14514     } else {
14515     disabled = $.map( this.tabs, function( li, num ) {
14516     return num !== index ? num : null;
14517     });
14518     }
14519     }
14520     this._setupDisabled( disabled );
14521     },
14522    
14523     disable: function( index ) {
14524     var disabled = this.options.disabled;
14525     if ( disabled === true ) {
14526     return;
14527     }
14528    
14529     if ( index === undefined ) {
14530     disabled = true;
14531     } else {
14532     index = this._getIndex( index );
14533     if ( $.inArray( index, disabled ) !== -1 ) {
14534     return;
14535     }
14536     if ( $.isArray( disabled ) ) {
14537     disabled = $.merge( [ index ], disabled ).sort();
14538     } else {
14539     disabled = [ index ];
14540     }
14541     }
14542     this._setupDisabled( disabled );
14543     },
14544    
14545     load: function( index, event ) {
14546     index = this._getIndex( index );
14547     var that = this,
14548     tab = this.tabs.eq( index ),
14549     anchor = tab.find( ".ui-tabs-anchor" ),
14550     panel = this._getPanelForTab( tab ),
14551     eventData = {
14552     tab: tab,
14553     panel: panel
14554     };
14555    
14556     // not remote
14557     if ( isLocal( anchor[ 0 ] ) ) {
14558     return;
14559     }
14560    
14561     this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14562    
14563     // support: jQuery <1.8
14564     // jQuery <1.8 returns false if the request is canceled in beforeSend,
14565     // but as of 1.8, $.ajax() always returns a jqXHR object.
14566     if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14567     tab.addClass( "ui-tabs-loading" );
14568     panel.attr( "aria-busy", "true" );
14569    
14570     this.xhr
14571     .success(function( response ) {
14572     // support: jQuery <1.8
14573     // http://bugs.jquery.com/ticket/11778
14574     setTimeout(function() {
14575     panel.html( response );
14576     that._trigger( "load", event, eventData );
14577     }, 1 );
14578     })
14579     .complete(function( jqXHR, status ) {
14580     // support: jQuery <1.8
14581     // http://bugs.jquery.com/ticket/11778
14582     setTimeout(function() {
14583     if ( status === "abort" ) {
14584     that.panels.stop( false, true );
14585     }
14586    
14587     tab.removeClass( "ui-tabs-loading" );
14588     panel.removeAttr( "aria-busy" );
14589    
14590     if ( jqXHR === that.xhr ) {
14591     delete that.xhr;
14592     }
14593     }, 1 );
14594     });
14595     }
14596     },
14597    
14598     _ajaxSettings: function( anchor, event, eventData ) {
14599     var that = this;
14600     return {
14601     url: anchor.attr( "href" ),
14602     beforeSend: function( jqXHR, settings ) {
14603     return that._trigger( "beforeLoad", event,
14604     $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14605     }
14606     };
14607     },
14608    
14609     _getPanelForTab: function( tab ) {
14610     var id = $( tab ).attr( "aria-controls" );
14611     return this.element.find( this._sanitizeSelector( "#" + id ) );
14612     }
14613     });
14614    
14615     })( jQuery );
14616    
14617     (function( $ ) {
14618    
14619     var increments = 0;
14620    
14621     function addDescribedBy( elem, id ) {
14622     var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14623     describedby.push( id );
14624     elem
14625     .data( "ui-tooltip-id", id )
14626     .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14627     }
14628    
14629     function removeDescribedBy( elem ) {
14630     var id = elem.data( "ui-tooltip-id" ),
14631     describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14632     index = $.inArray( id, describedby );
14633     if ( index !== -1 ) {
14634     describedby.splice( index, 1 );
14635     }
14636    
14637     elem.removeData( "ui-tooltip-id" );
14638     describedby = $.trim( describedby.join( " " ) );
14639     if ( describedby ) {
14640     elem.attr( "aria-describedby", describedby );
14641     } else {
14642     elem.removeAttr( "aria-describedby" );
14643     }
14644     }
14645    
14646     $.widget( "ui.tooltip", {
14647     version: "1.10.3",
14648     options: {
14649     content: function() {
14650     // support: IE<9, Opera in jQuery <1.7
14651     // .text() can't accept undefined, so coerce to a string
14652     var title = $( this ).attr( "title" ) || "";
14653     // Escape title, since we're going from an attribute to raw HTML
14654     return $( "<a>" ).text( title ).html();
14655     },
14656     hide: true,
14657     // Disabled elements have inconsistent behavior across browsers (#8661)
14658     items: "[title]:not([disabled])",
14659     position: {
14660     my: "left top+15",
14661     at: "left bottom",
14662     collision: "flipfit flip"
14663     },
14664     show: true,
14665     tooltipClass: null,
14666     track: false,
14667    
14668     // callbacks
14669     close: null,
14670     open: null
14671     },
14672    
14673     _create: function() {
14674     this._on({
14675     mouseover: "open",
14676     focusin: "open"
14677     });
14678    
14679     // IDs of generated tooltips, needed for destroy
14680     this.tooltips = {};
14681     // IDs of parent tooltips where we removed the title attribute
14682     this.parents = {};
14683    
14684     if ( this.options.disabled ) {
14685     this._disable();
14686     }
14687     },
14688    
14689     _setOption: function( key, value ) {
14690     var that = this;
14691    
14692     if ( key === "disabled" ) {
14693     this[ value ? "_disable" : "_enable" ]();
14694     this.options[ key ] = value;
14695     // disable element style changes
14696     return;
14697     }
14698    
14699     this._super( key, value );
14700    
14701     if ( key === "content" ) {
14702     $.each( this.tooltips, function( id, element ) {
14703     that._updateContent( element );
14704     });
14705     }
14706     },
14707    
14708     _disable: function() {
14709     var that = this;
14710    
14711     // close open tooltips
14712     $.each( this.tooltips, function( id, element ) {
14713     var event = $.Event( "blur" );
14714     event.target = event.currentTarget = element[0];
14715     that.close( event, true );
14716     });
14717    
14718     // remove title attributes to prevent native tooltips
14719     this.element.find( this.options.items ).addBack().each(function() {
14720     var element = $( this );
14721     if ( element.is( "[title]" ) ) {
14722     element
14723     .data( "ui-tooltip-title", element.attr( "title" ) )
14724     .attr( "title", "" );
14725     }
14726     });
14727     },
14728    
14729     _enable: function() {
14730     // restore title attributes
14731     this.element.find( this.options.items ).addBack().each(function() {
14732     var element = $( this );
14733     if ( element.data( "ui-tooltip-title" ) ) {
14734     element.attr( "title", element.data( "ui-tooltip-title" ) );
14735     }
14736     });
14737     },
14738    
14739     open: function( event ) {
14740     var that = this,
14741     target = $( event ? event.target : this.element )
14742     // we need closest here due to mouseover bubbling,
14743     // but always pointing at the same event target
14744     .closest( this.options.items );
14745    
14746     // No element to show a tooltip for or the tooltip is already open
14747     if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14748     return;
14749     }
14750    
14751     if ( target.attr( "title" ) ) {
14752     target.data( "ui-tooltip-title", target.attr( "title" ) );
14753     }
14754    
14755     target.data( "ui-tooltip-open", true );
14756    
14757     // kill parent tooltips, custom or native, for hover
14758     if ( event && event.type === "mouseover" ) {
14759     target.parents().each(function() {
14760     var parent = $( this ),
14761     blurEvent;
14762     if ( parent.data( "ui-tooltip-open" ) ) {
14763     blurEvent = $.Event( "blur" );
14764     blurEvent.target = blurEvent.currentTarget = this;
14765     that.close( blurEvent, true );
14766     }
14767     if ( parent.attr( "title" ) ) {
14768     parent.uniqueId();
14769     that.parents[ this.id ] = {
14770     element: this,
14771     title: parent.attr( "title" )
14772     };
14773     parent.attr( "title", "" );
14774     }
14775     });
14776     }
14777    
14778     this._updateContent( target, event );
14779     },
14780    
14781     _updateContent: function( target, event ) {
14782     var content,
14783     contentOption = this.options.content,
14784     that = this,
14785     eventType = event ? event.type : null;
14786    
14787     if ( typeof contentOption === "string" ) {
14788     return this._open( event, target, contentOption );
14789     }
14790    
14791     content = contentOption.call( target[0], function( response ) {
14792     // ignore async response if tooltip was closed already
14793     if ( !target.data( "ui-tooltip-open" ) ) {
14794     return;
14795     }
14796     // IE may instantly serve a cached response for ajax requests
14797     // delay this call to _open so the other call to _open runs first
14798     that._delay(function() {
14799     // jQuery creates a special event for focusin when it doesn't
14800     // exist natively. To improve performance, the native event
14801     // object is reused and the type is changed. Therefore, we can't
14802     // rely on the type being correct after the event finished
14803     // bubbling, so we set it back to the previous value. (#8740)
14804     if ( event ) {
14805     event.type = eventType;
14806     }
14807     this._open( event, target, response );
14808     });
14809     });
14810     if ( content ) {
14811     this._open( event, target, content );
14812     }
14813     },
14814    
14815     _open: function( event, target, content ) {
14816     var tooltip, events, delayedShow,
14817     positionOption = $.extend( {}, this.options.position );
14818    
14819     if ( !content ) {
14820     return;
14821     }
14822    
14823     // Content can be updated multiple times. If the tooltip already
14824     // exists, then just update the content and bail.
14825     tooltip = this._find( target );
14826     if ( tooltip.length ) {
14827     tooltip.find( ".ui-tooltip-content" ).html( content );
14828     return;
14829     }
14830    
14831     // if we have a title, clear it to prevent the native tooltip
14832     // we have to check first to avoid defining a title if none exists
14833     // (we don't want to cause an element to start matching [title])
14834     //
14835     // We use removeAttr only for key events, to allow IE to export the correct
14836     // accessible attributes. For mouse events, set to empty string to avoid
14837     // native tooltip showing up (happens only when removing inside mouseover).
14838     if ( target.is( "[title]" ) ) {
14839     if ( event && event.type === "mouseover" ) {
14840     target.attr( "title", "" );
14841     } else {
14842     target.removeAttr( "title" );
14843     }
14844     }
14845    
14846     tooltip = this._tooltip( target );
14847     addDescribedBy( target, tooltip.attr( "id" ) );
14848     tooltip.find( ".ui-tooltip-content" ).html( content );
14849    
14850     function position( event ) {
14851     positionOption.of = event;
14852     if ( tooltip.is( ":hidden" ) ) {
14853     return;
14854     }
14855     tooltip.position( positionOption );
14856     }
14857     if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14858     this._on( this.document, {
14859     mousemove: position
14860     });
14861     // trigger once to override element-relative positioning
14862     position( event );
14863     } else {
14864     tooltip.position( $.extend({
14865     of: target
14866     }, this.options.position ) );
14867     }
14868    
14869     tooltip.hide();
14870    
14871     this._show( tooltip, this.options.show );
14872     // Handle tracking tooltips that are shown with a delay (#8644). As soon
14873     // as the tooltip is visible, position the tooltip using the most recent
14874     // event.
14875     if ( this.options.show && this.options.show.delay ) {
14876     delayedShow = this.delayedShow = setInterval(function() {
14877     if ( tooltip.is( ":visible" ) ) {
14878     position( positionOption.of );
14879     clearInterval( delayedShow );
14880     }
14881     }, $.fx.interval );
14882     }
14883    
14884     this._trigger( "open", event, { tooltip: tooltip } );
14885    
14886     events = {
14887     keyup: function( event ) {
14888     if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14889     var fakeEvent = $.Event(event);
14890     fakeEvent.currentTarget = target[0];
14891     this.close( fakeEvent, true );
14892     }
14893     },
14894     remove: function() {
14895     this._removeTooltip( tooltip );
14896     }
14897     };
14898     if ( !event || event.type === "mouseover" ) {
14899     events.mouseleave = "close";
14900     }
14901     if ( !event || event.type === "focusin" ) {
14902     events.focusout = "close";
14903     }
14904     this._on( true, target, events );
14905     },
14906    
14907     close: function( event ) {
14908     var that = this,
14909     target = $( event ? event.currentTarget : this.element ),
14910     tooltip = this._find( target );
14911    
14912     // disabling closes the tooltip, so we need to track when we're closing
14913     // to avoid an infinite loop in case the tooltip becomes disabled on close
14914     if ( this.closing ) {
14915     return;
14916     }
14917    
14918     // Clear the interval for delayed tracking tooltips
14919     clearInterval( this.delayedShow );
14920    
14921     // only set title if we had one before (see comment in _open())
14922     if ( target.data( "ui-tooltip-title" ) ) {
14923     target.attr( "title", target.data( "ui-tooltip-title" ) );
14924     }
14925    
14926     removeDescribedBy( target );
14927    
14928     tooltip.stop( true );
14929     this._hide( tooltip, this.options.hide, function() {
14930     that._removeTooltip( $( this ) );
14931     });
14932    
14933     target.removeData( "ui-tooltip-open" );
14934     this._off( target, "mouseleave focusout keyup" );
14935     // Remove 'remove' binding only on delegated targets
14936     if ( target[0] !== this.element[0] ) {
14937     this._off( target, "remove" );
14938     }
14939     this._off( this.document, "mousemove" );
14940    
14941     if ( event && event.type === "mouseleave" ) {
14942     $.each( this.parents, function( id, parent ) {
14943     $( parent.element ).attr( "title", parent.title );
14944     delete that.parents[ id ];
14945     });
14946     }
14947    
14948     this.closing = true;
14949     this._trigger( "close", event, { tooltip: tooltip } );
14950     this.closing = false;
14951     },
14952    
14953     _tooltip: function( element ) {
14954     var id = "ui-tooltip-" + increments++,
14955     tooltip = $( "<div>" )
14956     .attr({
14957     id: id,
14958     role: "tooltip"
14959     })
14960     .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14961     ( this.options.tooltipClass || "" ) );
14962     $( "<div>" )
14963     .addClass( "ui-tooltip-content" )
14964     .appendTo( tooltip );
14965     tooltip.appendTo( this.document[0].body );
14966     this.tooltips[ id ] = element;
14967     return tooltip;
14968     },
14969    
14970     _find: function( target ) {
14971     var id = target.data( "ui-tooltip-id" );
14972     return id ? $( "#" + id ) : $();
14973     },
14974    
14975     _removeTooltip: function( tooltip ) {
14976     tooltip.remove();
14977     delete this.tooltips[ tooltip.attr( "id" ) ];
14978     },
14979    
14980     _destroy: function() {
14981     var that = this;
14982    
14983     // close open tooltips
14984     $.each( this.tooltips, function( id, element ) {
14985     // Delegate to close method to handle common cleanup
14986     var event = $.Event( "blur" );
14987     event.target = event.currentTarget = element[0];
14988     that.close( event, true );
14989    
14990     // Remove immediately; destroying an open tooltip doesn't use the
14991     // hide animation
14992     $( "#" + id ).remove();
14993    
14994     // Restore the title
14995     if ( element.data( "ui-tooltip-title" ) ) {
14996     element.attr( "title", element.data( "ui-tooltip-title" ) );
14997     element.removeData( "ui-tooltip-title" );
14998     }
14999     });
15000     }
15001     });
15002    
15003     }( jQuery ) );

  ViewVC Help
Powered by ViewVC 1.1.20