PageSourceSearch

https://iea-wind.org/wp-content/plugins/tree-website-map/lib/horizontal-tree/js/jquery-ui.js?ver=7.0.6

js iea-wind.org collected 2026-09-24 09:28:20 UTC 434,373 bytes, 14,936 lines download raw bytes

1/*! jQuery UI - v1.10.1 - 2013-02-15
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
6(function( $, undefined ) {
7
8var uuid = 0,
9	runiqueId = /^ui-id-\d+$/;
10
11// prevent duplicate loading
12// this is only a problem because we proxy existing functions
13// and we don't want to double proxy them
14$.ui = $.ui || {};
15if ( $.ui.version ) {
16	return;
17}
18
19$.extend( $.ui, {
20	version: "1.10.1",
21
22	keyCode: {
23		BACKSPACE: 8,
24		COMMA: 188,
25		DELETE: 46,
26		DOWN: 40,
27		END: 35,
28		ENTER: 13,
29		ESCAPE: 27,
30		HOME: 36,
31		LEFT: 37,
32		NUMPAD_ADD: 107,
33		NUMPAD_DECIMAL: 110,
34		NUMPAD_DIVIDE: 111,
35		NUMPAD_ENTER: 108,
36		NUMPAD_MULTIPLY: 106,
37		NUMPAD_SUBTRACT: 109,
38		PAGE_DOWN: 34,
39		PAGE_UP: 33,
40		PERIOD: 190,
41		RIGHT: 39,
42		SPACE: 32,
43		TAB: 9,
44		UP: 38
45	}
46});
47
48// plugins
49$.fn.extend({
50	_focus: $.fn.focus,
51	focus: function( delay, fn ) {
52		return typeof delay === "number" ?
53			this.each(function() {
54				var elem = this;
55				setTimeout(function() {
56					$( elem ).focus();
57					if ( fn ) {
58						fn.call( elem );
59					}
60				}, delay );
61			}) :
62			this._focus.apply( this, arguments );
63	},
64
65	scrollParent: function() {
66		var scrollParent;
67		if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
68			scrollParent = this.parents().filter(function() {
69				return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70			}).eq(0);
71		} else {
72			scrollParent = this.parents().filter(function() {
73				return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
74			}).eq(0);
75		}
76
77		return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
78	},
79
80	zIndex: function( zIndex ) {
81		if ( zIndex !== undefined ) {
82			return this.css( "zIndex", zIndex );
83		}
84
85		if ( this.length ) {
86			var elem = $( this[ 0 ] ), position, value;
87			while ( elem.length && elem[ 0 ] !== document ) {
88				// Ignore z-index if position is set to a value where z-index is ignored by the browser
89				// This makes behavior of this function consistent across browsers
90				// WebKit always returns auto if the element is positioned
91				position = elem.css( "position" );
92				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
93					// IE returns 0 when zIndex is not specified
94					// other browsers return a string
95					// we ignore the case of nested elements with an explicit value of 0
96					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
97					value = parseInt( elem.css( "zIndex" ), 10 );
98					if ( !isNaN( value ) && value !== 0 ) {
99						return value;
100					}
101				}
102				elem = elem.parent();
103			}
104		}
105
106		return 0;
107	},
108
109	uniqueId: function() {
110		return this.each(function() {
111			if ( !this.id ) {
112				this.id = "ui-id-" + (++uuid);
113			}
114		});
115	},
116
117	removeUniqueId: function() {
118		return this.each(function() {
119			if ( runiqueId.test( this.id ) ) {
120				$( this ).removeAttr( "id" );
121			}
122		});
123	}
124});
125
126// selectors
127function focusable( element, isTabIndexNotNaN ) {
128	var map, mapName, img,
129		nodeName = element.nodeName.toLowerCase();
130	if ( "area" === nodeName ) {
131		map = element.parentNode;
132		mapName = map.name;
133		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
134			return false;
vendor: 33,404 bytes, lines 135-1334
135		}
136		img = $( "img[usemap=#" + mapName + "]" )[0];
137		return !!img && visible( img );
138	}
139	return ( /input|select|textarea|button|object/.test( nodeName ) ?
140		!element.disabled :
141		"a" === nodeName ?
142			element.href || isTabIndexNotNaN :
143			isTabIndexNotNaN) &&
144		// the element and all of its ancestors must be visible
145		visible( element );
146}
147
148function visible( element ) {
149	return $.expr.filters.visible( element ) &&
150		!$( element ).parents().addBack().filter(function() {
151			return $.css( this, "visibility" ) === "hidden";
152		}).length;
153}
154
155$.extend( $.expr[ ":" ], {
156	data: $.expr.createPseudo ?
157		$.expr.createPseudo(function( dataName ) {
158			return function( elem ) {
159				return !!$.data( elem, dataName );
160			};
161		}) :
162		// support: jQuery <1.8
163		function( elem, i, match ) {
164			return !!$.data( elem, match[ 3 ] );
165		},
166
167	focusable: function( element ) {
168		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
169	},
170
171	tabbable: function( element ) {
172		var tabIndex = $.attr( element, "tabindex" ),
173			isTabIndexNaN = isNaN( tabIndex );
174		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
175	}
176});
177
178// support: jQuery <1.8
179if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
180	$.each( [ "Width", "Height" ], function( i, name ) {
181		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
182			type = name.toLowerCase(),
183			orig = {
184				innerWidth: $.fn.innerWidth,
185				innerHeight: $.fn.innerHeight,
186				outerWidth: $.fn.outerWidth,
187				outerHeight: $.fn.outerHeight
188			};
189
190		function reduce( elem, size, border, margin ) {
191			$.each( side, function() {
192				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
193				if ( border ) {
194					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
195				}
196				if ( margin ) {
197					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
198				}
199			});
200			return size;
201		}
202
203		$.fn[ "inner" + name ] = function( size ) {
204			if ( size === undefined ) {
205				return orig[ "inner" + name ].call( this );
206			}
207
208			return this.each(function() {
209				$( this ).css( type, reduce( this, size ) + "px" );
210			});
211		};
212
213		$.fn[ "outer" + name] = function( size, margin ) {
214			if ( typeof size !== "number" ) {
215				return orig[ "outer" + name ].call( this, size );
216			}
217
218			return this.each(function() {
219				$( this).css( type, reduce( this, size, true, margin ) + "px" );
220			});
221		};
222	});
223}
224
225// support: jQuery <1.8
226if ( !$.fn.addBack ) {
227	$.fn.addBack = function( selector ) {
228		return this.add( selector == null ?
229			this.prevObject : this.prevObject.filter( selector )
230		);
231	};
232}
233
234// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
235if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
236	$.fn.removeData = (function( removeData ) {
237		return function( key ) {
238			if ( arguments.length ) {
239				return removeData.call( this, $.camelCase( key ) );
240			} else {
241				return removeData.call( this );
242			}
243		};
244	})( $.fn.removeData );
245}
246
247
248
249
250
251// deprecated
252$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
253
254$.support.selectstart = "onselectstart" in document.createElement( "div" );
255$.fn.extend({
256	disableSelection: function() {
257		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
258			".ui-disableSelection", function( event ) {
259				event.preventDefault();
260			});
261	},
262
263	enableSelection: function() {
264		return this.unbind( ".ui-disableSelection" );
265	}
266});
267
268$.extend( $.ui, {
269	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
270	plugin: {
271		add: function( module, option, set ) {
272			var i,
273				proto = $.ui[ module ].prototype;
274			for ( i in set ) {
275				proto.plugins[ i ] = proto.plugins[ i ] || [];
276				proto.plugins[ i ].push( [ option, set[ i ] ] );
277			}
278		},
279		call: function( instance, name, args ) {
280			var i,
281				set = instance.plugins[ name ];
282			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
283				return;
284			}
285
286			for ( i = 0; i < set.length; i++ ) {
287				if ( instance.options[ set[ i ][ 0 ] ] ) {
288					set[ i ][ 1 ].apply( instance.element, args );
289				}
290			}
291		}
292	},
293
294	// only used by resizable
295	hasScroll: function( el, a ) {
296
297		//If overflow is hidden, the element might have extra content, but the user wants to hide it
298		if ( $( el ).css( "overflow" ) === "hidden") {
299			return false;
300		}
301
302		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
303			has = false;
304
305		if ( el[ scroll ] > 0 ) {
306			return true;
307		}
308
309		// TODO: determine which cases actually cause this to happen
310		// if the element doesn't have the scroll set, see if it's possible to
311		// set the scroll
312		el[ scroll ] = 1;
313		has = ( el[ scroll ] > 0 );
314		el[ scroll ] = 0;
315		return has;
316	}
317});
318
319})( jQuery );
320
321(function( $, undefined ) {
322
323var uuid = 0,
324	slice = Array.prototype.slice,
325	_cleanData = $.cleanData;
326$.cleanData = function( elems ) {
327	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
328		try {
329			$( elem ).triggerHandler( "remove" );
330		// http://bugs.jquery.com/ticket/8235
331		} catch( e ) {}
332	}
333	_cleanData( elems );
334};
335
336$.widget = function( name, base, prototype ) {
337	var fullName, existingConstructor, constructor, basePrototype,
338		// proxiedPrototype allows the provided prototype to remain unmodified
339		// so that it can be used as a mixin for multiple widgets (#8876)
340		proxiedPrototype = {},
341		namespace = name.split( "." )[ 0 ];
342
343	name = name.split( "." )[ 1 ];
344	fullName = namespace + "-" + name;
345
346	if ( !prototype ) {
347		prototype = base;
348		base = $.Widget;
349	}
350
351	// create selector for plugin
352	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
353		return !!$.data( elem, fullName );
354	};
355
356	$[ namespace ] = $[ namespace ] || {};
357	existingConstructor = $[ namespace ][ name ];
358	constructor = $[ namespace ][ name ] = function( options, element ) {
359		// allow instantiation without "new" keyword
360		if ( !this._createWidget ) {
361			return new constructor( options, element );
362		}
363
364		// allow instantiation without initializing for simple inheritance
365		// must use "new" keyword (the code above always passes args)
366		if ( arguments.length ) {
367			this._createWidget( options, element );
368		}
369	};
370	// extend with the existing constructor to carry over any static properties
371	$.extend( constructor, existingConstructor, {
372		version: prototype.version,
373		// copy the object used to create the prototype in case we need to
374		// redefine the widget later
375		_proto: $.extend( {}, prototype ),
376		// track widgets that inherit from this widget in case this widget is
377		// redefined after a widget inherits from it
378		_childConstructors: []
379	});
380
381	basePrototype = new base();
382	// we need to make the options hash a property directly on the new instance
383	// otherwise we'll modify the options hash on the prototype that we're
384	// inheriting from
385	basePrototype.options = $.widget.extend( {}, basePrototype.options );
386	$.each( prototype, function( prop, value ) {
387		if ( !$.isFunction( value ) ) {
388			proxiedPrototype[ prop ] = value;
389			return;
390		}
391		proxiedPrototype[ prop ] = (function() {
392			var _super = function() {
393					return base.prototype[ prop ].apply( this, arguments );
394				},
395				_superApply = function( args ) {
396					return base.prototype[ prop ].apply( this, args );
397				};
398			return function() {
399				var __super = this._super,
400					__superApply = this._superApply,
401					returnValue;
402
403				this._super = _super;
404				this._superApply = _superApply;
405
406				returnValue = value.apply( this, arguments );
407
408				this._super = __super;
409				this._superApply = __superApply;
410
411				return returnValue;
412			};
413		})();
414	});
415	constructor.prototype = $.widget.extend( basePrototype, {
416		// TODO: remove support for widgetEventPrefix
417		// always use the name + a colon as the prefix, e.g., draggable:start
418		// don't prefix for widgets that aren't DOM-based
419		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
420	}, proxiedPrototype, {
421		constructor: constructor,
422		namespace: namespace,
423		widgetName: name,
424		widgetFullName: fullName
425	});
426
427	// If this widget is being redefined then we need to find all widgets that
428	// are inheriting from it and redefine all of them so that they inherit from
429	// the new version of this widget. We're essentially trying to replace one
430	// level in the prototype chain.
431	if ( existingConstructor ) {
432		$.each( existingConstructor._childConstructors, function( i, child ) {
433			var childPrototype = child.prototype;
434
435			// redefine the child widget using the same prototype that was
436			// originally used, but inherit from the new version of the base
437			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
438		});
439		// remove the list of existing child constructors from the old constructor
440		// so the old child constructors can be garbage collected
441		delete existingConstructor._childConstructors;
442	} else {
443		base._childConstructors.push( constructor );
444	}
445
446	$.widget.bridge( name, constructor );
447};
448
449$.widget.extend = function( target ) {
450	var input = slice.call( arguments, 1 ),
451		inputIndex = 0,
452		inputLength = input.length,
453		key,
454		value;
455	for ( ; inputIndex < inputLength; inputIndex++ ) {
456		for ( key in input[ inputIndex ] ) {
457			value = input[ inputIndex ][ key ];
458			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
459				// Clone objects
460				if ( $.isPlainObject( value ) ) {
461					target[ key ] = $.isPlainObject( target[ key ] ) ?
462						$.widget.extend( {}, target[ key ], value ) :
463						// Don't extend strings, arrays, etc. with objects
464						$.widget.extend( {}, value );
465				// Copy everything else by reference
466				} else {
467					target[ key ] = value;
468				}
469			}
470		}
471	}
472	return target;
473};
474
475$.widget.bridge = function( name, object ) {
476	var fullName = object.prototype.widgetFullName || name;
477	$.fn[ name ] = function( options ) {
478		var isMethodCall = typeof options === "string",
479			args = slice.call( arguments, 1 ),
480			returnValue = this;
481
482		// allow multiple hashes to be passed on init
483		options = !isMethodCall && args.length ?
484			$.widget.extend.apply( null, [ options ].concat(args) ) :
485			options;
486
487		if ( isMethodCall ) {
488			this.each(function() {
489				var methodValue,
490					instance = $.data( this, fullName );
491				if ( !instance ) {
492					return $.error( "cannot call methods on " + name + " prior to initialization; " +
493						"attempted to call method '" + options + "'" );
494				}
495				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
496					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
497				}
498				methodValue = instance[ options ].apply( instance, args );
499				if ( methodValue !== instance && methodValue !== undefined ) {
500					returnValue = methodValue && methodValue.jquery ?
501						returnValue.pushStack( methodValue.get() ) :
502						methodValue;
503					return false;
504				}
505			});
506		} else {
507			this.each(function() {
508				var instance = $.data( this, fullName );
509				if ( instance ) {
510					instance.option( options || {} )._init();
511				} else {
512					$.data( this, fullName, new object( options, this ) );
513				}
514			});
515		}
516
517		return returnValue;
518	};
519};
520
521$.Widget = function( /* options, element */ ) {};
522$.Widget._childConstructors = [];
523
524$.Widget.prototype = {
525	widgetName: "widget",
526	widgetEventPrefix: "",
527	defaultElement: "<div>",
528	options: {
529		disabled: false,
530
531		// callbacks
532		create: null
533	},
534	_createWidget: function( options, element ) {
535		element = $( element || this.defaultElement || this )[ 0 ];
536		this.element = $( element );
537		this.uuid = uuid++;
538		this.eventNamespace = "." + this.widgetName + this.uuid;
539		this.options = $.widget.extend( {},
540			this.options,
541			this._getCreateOptions(),
542			options );
543
544		this.bindings = $();
545		this.hoverable = $();
546		this.focusable = $();
547
548		if ( element !== this ) {
549			$.data( element, this.widgetFullName, this );
550			this._on( true, this.element, {
551				remove: function( event ) {
552					if ( event.target === element ) {
553						this.destroy();
554					}
555				}
556			});
557			this.document = $( element.style ?
558				// element within the document
559				element.ownerDocument :
560				// element is window or document
561				element.document || element );
562			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
563		}
564
565		this._create();
566		this._trigger( "create", null, this._getCreateEventData() );
567		this._init();
568	},
569	_getCreateOptions: $.noop,
570	_getCreateEventData: $.noop,
571	_create: $.noop,
572	_init: $.noop,
573
574	destroy: function() {
575		this._destroy();
576		// we can probably remove the unbind calls in 2.0
577		// all event bindings should go through this._on()
578		this.element
579			.unbind( this.eventNamespace )
580			// 1.9 BC for #7810
581			// TODO remove dual storage
582			.removeData( this.widgetName )
583			.removeData( this.widgetFullName )
584			// support: jquery <1.6.3
585			// http://bugs.jquery.com/ticket/9413
586			.removeData( $.camelCase( this.widgetFullName ) );
587		this.widget()
588			.unbind( this.eventNamespace )
589			.removeAttr( "aria-disabled" )
590			.removeClass(
591				this.widgetFullName + "-disabled " +
592				"ui-state-disabled" );
593
594		// clean up events and states
595		this.bindings.unbind( this.eventNamespace );
596		this.hoverable.removeClass( "ui-state-hover" );
597		this.focusable.removeClass( "ui-state-focus" );
598	},
599	_destroy: $.noop,
600
601	widget: function() {
602		return this.element;
603	},
604
605	option: function( key, value ) {
606		var options = key,
607			parts,
608			curOption,
609			i;
610
611		if ( arguments.length === 0 ) {
612			// don't return a reference to the internal hash
613			return $.widget.extend( {}, this.options );
614		}
615
616		if ( typeof key === "string" ) {
617			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
618			options = {};
619			parts = key.split( "." );
620			key = parts.shift();
621			if ( parts.length ) {
622				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
623				for ( i = 0; i < parts.length - 1; i++ ) {
624					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
625					curOption = curOption[ parts[ i ] ];
626				}
627				key = parts.pop();
628				if ( value === undefined ) {
629					return curOption[ key ] === undefined ? null : curOption[ key ];
630				}
631				curOption[ key ] = value;
632			} else {
633				if ( value === undefined ) {
634					return this.options[ key ] === undefined ? null : this.options[ key ];
635				}
636				options[ key ] = value;
637			}
638		}
639
640		this._setOptions( options );
641
642		return this;
643	},
644	_setOptions: function( options ) {
645		var key;
646
647		for ( key in options ) {
648			this._setOption( key, options[ key ] );
649		}
650
651		return this;
652	},
653	_setOption: function( key, value ) {
654		this.options[ key ] = value;
655
656		if ( key === "disabled" ) {
657			this.widget()
658				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
659				.attr( "aria-disabled", value );
660			this.hoverable.removeClass( "ui-state-hover" );
661			this.focusable.removeClass( "ui-state-focus" );
662		}
663
664		return this;
665	},
666
667	enable: function() {
668		return this._setOption( "disabled", false );
669	},
670	disable: function() {
671		return this._setOption( "disabled", true );
672	},
673
674	_on: function( suppressDisabledCheck, element, handlers ) {
675		var delegateElement,
676			instance = this;
677
678		// no suppressDisabledCheck flag, shuffle arguments
679		if ( typeof suppressDisabledCheck !== "boolean" ) {
680			handlers = element;
681			element = suppressDisabledCheck;
682			suppressDisabledCheck = false;
683		}
684
685		// no element argument, shuffle and use this.element
686		if ( !handlers ) {
687			handlers = element;
688			element = this.element;
689			delegateElement = this.widget();
690		} else {
691			// accept selectors, DOM elements
692			element = delegateElement = $( element );
693			this.bindings = this.bindings.add( element );
694		}
695
696		$.each( handlers, function( event, handler ) {
697			function handlerProxy() {
698				// allow widgets to customize the disabled handling
699				// - disabled as an array instead of boolean
700				// - disabled class as method for disabling individual parts
701				if ( !suppressDisabledCheck &&
702						( instance.options.disabled === true ||
703							$( this ).hasClass( "ui-state-disabled" ) ) ) {
704					return;
705				}
706				return ( typeof handler === "string" ? instance[ handler ] : handler )
707					.apply( instance, arguments );
708			}
709
710			// copy the guid so direct unbinding works
711			if ( typeof handler !== "string" ) {
712				handlerProxy.guid = handler.guid =
713					handler.guid || handlerProxy.guid || $.guid++;
714			}
715
716			var match = event.match( /^(\w+)\s*(.*)$/ ),
717				eventName = match[1] + instance.eventNamespace,
718				selector = match[2];
719			if ( selector ) {
720				delegateElement.delegate( selector, eventName, handlerProxy );
721			} else {
722				element.bind( eventName, handlerProxy );
723			}
724		});
725	},
726
727	_off: function( element, eventName ) {
728		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
729		element.unbind( eventName ).undelegate( eventName );
730	},
731
732	_delay: function( handler, delay ) {
733		function handlerProxy() {
734			return ( typeof handler === "string" ? instance[ handler ] : handler )
735				.apply( instance, arguments );
736		}
737		var instance = this;
738		return setTimeout( handlerProxy, delay || 0 );
739	},
740
741	_hoverable: function( element ) {
742		this.hoverable = this.hoverable.add( element );
743		this._on( element, {
744			mouseenter: function( event ) {
745				$( event.currentTarget ).addClass( "ui-state-hover" );
746			},
747			mouseleave: function( event ) {
748				$( event.currentTarget ).removeClass( "ui-state-hover" );
749			}
750		});
751	},
752
753	_focusable: function( element ) {
754		this.focusable = this.focusable.add( element );
755		this._on( element, {
756			focusin: function( event ) {
757				$( event.currentTarget ).addClass( "ui-state-focus" );
758			},
759			focusout: function( event ) {
760				$( event.currentTarget ).removeClass( "ui-state-focus" );
761			}
762		});
763	},
764
765	_trigger: function( type, event, data ) {
766		var prop, orig,
767			callback = this.options[ type ];
768
769		data = data || {};
770		event = $.Event( event );
771		event.type = ( type === this.widgetEventPrefix ?
772			type :
773			this.widgetEventPrefix + type ).toLowerCase();
774		// the original event may come from any element
775		// so we need to reset the target on the new event
776		event.target = this.element[ 0 ];
777
778		// copy original event properties over to the new event
779		orig = event.originalEvent;
780		if ( orig ) {
781			for ( prop in orig ) {
782				if ( !( prop in event ) ) {
783					event[ prop ] = orig[ prop ];
784				}
785			}
786		}
787
788		this.element.trigger( event, data );
789		return !( $.isFunction( callback ) &&
790			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
791			event.isDefaultPrevented() );
792	}
793};
794
795$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
796	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
797		if ( typeof options === "string" ) {
798			options = { effect: options };
799		}
800		var hasOptions,
801			effectName = !options ?
802				method :
803				options === true || typeof options === "number" ?
804					defaultEffect :
805					options.effect || defaultEffect;
806		options = options || {};
807		if ( typeof options === "number" ) {
808			options = { duration: options };
809		}
810		hasOptions = !$.isEmptyObject( options );
811		options.complete = callback;
812		if ( options.delay ) {
813			element.delay( options.delay );
814		}
815		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
816			element[ method ]( options );
817		} else if ( effectName !== method && element[ effectName ] ) {
818			element[ effectName ]( options.duration, options.easing, callback );
819		} else {
820			element.queue(function( next ) {
821				$( this )[ method ]();
822				if ( callback ) {
823					callback.call( element[ 0 ] );
824				}
825				next();
826			});
827		}
828	};
829});
830
831})( jQuery );
832
833(function( $, undefined ) {
834
835var mouseHandled = false;
836$( document ).mouseup( function() {
837	mouseHandled = false;
838});
839
840$.widget("ui.mouse", {
841	version: "1.10.1",
842	options: {
843		cancel: "input,textarea,button,select,option",
844		distance: 1,
845		delay: 0
846	},
847	_mouseInit: function() {
848		var that = this;
849
850		this.element
851			.bind("mousedown."+this.widgetName, function(event) {
852				return that._mouseDown(event);
853			})
854			.bind("click."+this.widgetName, function(event) {
855				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
856					$.removeData(event.target, that.widgetName + ".preventClickEvent");
857					event.stopImmediatePropagation();
858					return false;
859				}
860			});
861
862		this.started = false;
863	},
864
865	// TODO: make sure destroying one instance of mouse doesn't mess with
866	// other instances of mouse
867	_mouseDestroy: function() {
868		this.element.unbind("."+this.widgetName);
869		if ( this._mouseMoveDelegate ) {
870			$(document)
871				.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
872				.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
873		}
874	},
875
876	_mouseDown: function(event) {
877		// don't let more than one widget handle mouseStart
878		if( mouseHandled ) { return; }
879
880		// we may have missed mouseup (out of window)
881		(this._mouseStarted && this._mouseUp(event));
882
883		this._mouseDownEvent = event;
884
885		var that = this,
886			btnIsLeft = (event.which === 1),
887			// event.target.nodeName works around a bug in IE 8 with
888			// disabled inputs (#7620)
889			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
890		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
891			return true;
892		}
893
894		this.mouseDelayMet = !this.options.delay;
895		if (!this.mouseDelayMet) {
896			this._mouseDelayTimer = setTimeout(function() {
897				that.mouseDelayMet = true;
898			}, this.options.delay);
899		}
900
901		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
902			this._mouseStarted = (this._mouseStart(event) !== false);
903			if (!this._mouseStarted) {
904				event.preventDefault();
905				return true;
906			}
907		}
908
909		// Click event may never have fired (Gecko & Opera)
910		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
911			$.removeData(event.target, this.widgetName + ".preventClickEvent");
912		}
913
914		// these delegates are required to keep context
915		this._mouseMoveDelegate = function(event) {
916			return that._mouseMove(event);
917		};
918		this._mouseUpDelegate = function(event) {
919			return that._mouseUp(event);
920		};
921		$(document)
922			.bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
923			.bind("mouseup."+this.widgetName, this._mouseUpDelegate);
924
925		event.preventDefault();
926
927		mouseHandled = true;
928		return true;
929	},
930
931	_mouseMove: function(event) {
932		// IE mouseup check - mouseup happened when mouse was out of window
933		if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
934			return this._mouseUp(event);
935		}
936
937		if (this._mouseStarted) {
938			this._mouseDrag(event);
939			return event.preventDefault();
940		}
941
942		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
943			this._mouseStarted =
944				(this._mouseStart(this._mouseDownEvent, event) !== false);
945			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
946		}
947
948		return !this._mouseStarted;
949	},
950
951	_mouseUp: function(event) {
952		$(document)
953			.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
954			.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
955
956		if (this._mouseStarted) {
957			this._mouseStarted = false;
958
959			if (event.target === this._mouseDownEvent.target) {
960				$.data(event.target, this.widgetName + ".preventClickEvent", true);
961			}
962
963			this._mouseStop(event);
964		}
965
966		return false;
967	},
968
969	_mouseDistanceMet: function(event) {
970		return (Math.max(
971				Math.abs(this._mouseDownEvent.pageX - event.pageX),
972				Math.abs(this._mouseDownEvent.pageY - event.pageY)
973			) >= this.options.distance
974		);
975	},
976
977	_mouseDelayMet: function(/* event */) {
978		return this.mouseDelayMet;
979	},
980
981	// These are placeholder methods, to be overriden by extending plugin
982	_mouseStart: function(/* event */) {},
983	_mouseDrag: function(/* event */) {},
984	_mouseStop: function(/* event */) {},
985	_mouseCapture: function(/* event */) { return true; }
986});
987
988})(jQuery);
989
990(function( $, undefined ) {
991
992$.widget("ui.draggable", $.ui.mouse, {
993	version: "1.10.1",
994	widgetEventPrefix: "drag",
995	options: {
996		addClasses: true,
997		appendTo: "parent",
998		axis: false,
999		connectToSortable: false,
1000		containment: false,
1001		cursor: "auto",
1002		cursorAt: false,
1003		grid: false,
1004		handle: false,
1005		helper: "original",
1006		iframeFix: false,
1007		opacity: false,
1008		refreshPositions: false,
1009		revert: false,
1010		revertDuration: 500,
1011		scope: "default",
1012		scroll: true,
1013		scrollSensitivity: 20,
1014		scrollSpeed: 20,
1015		snap: false,
1016		snapMode: "both",
1017		snapTolerance: 20,
1018		stack: false,
1019		zIndex: false,
1020
1021		// callbacks
1022		drag: null,
1023		start: null,
1024		stop: null
1025	},
1026	_create: function() {
1027
1028		if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1029			this.element[0].style.position = "relative";
1030		}
1031		if (this.options.addClasses){
1032			this.element.addClass("ui-draggable");
1033		}
1034		if (this.options.disabled){
1035			this.element.addClass("ui-draggable-disabled");
1036		}
1037
1038		this._mouseInit();
1039
1040	},
1041
1042	_destroy: function() {
1043		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1044		this._mouseDestroy();
1045	},
1046
1047	_mouseCapture: function(event) {
1048
1049		var o = this.options;
1050
1051		// among others, prevent a drag on a resizable-handle
1052		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1053			return false;
1054		}
1055
1056		//Quit if we're not on a valid handle
1057		this.handle = this._getHandle(event);
1058		if (!this.handle) {
1059			return false;
1060		}
1061
1062		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1063			$("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1064			.css({
1065				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1066				position: "absolute", opacity: "0.001", zIndex: 1000
1067			})
1068			.css($(this).offset())
1069			.appendTo("body");
1070		});
1071
1072		return true;
1073
1074	},
1075
1076	_mouseStart: function(event) {
1077
1078		var o = this.options;
1079
1080		//Create and append the visible helper
1081		this.helper = this._createHelper(event);
1082
1083		this.helper.addClass("ui-draggable-dragging");
1084
1085		//Cache the helper size
1086		this._cacheHelperProportions();
1087
1088		//If ddmanager is used for droppables, set the global draggable
1089		if($.ui.ddmanager) {
1090			$.ui.ddmanager.current = this;
1091		}
1092
1093		/*
1094		 * - Position generation -
1095		 * This block generates everything position related - it's the core of draggables.
1096		 */
1097
1098		//Cache the margins of the original element
1099		this._cacheMargins();
1100
1101		//Store the helper's css position
1102		this.cssPosition = this.helper.css("position");
1103		this.scrollParent = this.helper.scrollParent();
1104
1105		//The element's absolute position on the page minus margins
1106		this.offset = this.positionAbs = this.element.offset();
1107		this.offset = {
1108			top: this.offset.top - this.margins.top,
1109			left: this.offset.left - this.margins.left
1110		};
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		if(o.containment) {
1131			this._setContainment();
1132		}
1133
1134		//Trigger event + callbacks
1135		if(this._trigger("start", event) === false) {
1136			this._clear();
1137			return false;
1138		}
1139
1140		//Recache the helper size
1141		this._cacheHelperProportions();
1142
1143		//Prepare the droppable offsets
1144		if ($.ui.ddmanager && !o.dropBehaviour) {
1145			$.ui.ddmanager.prepareOffsets(this, event);
1146		}
1147
1148
1149		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1150
1151		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1152		if ( $.ui.ddmanager ) {
1153			$.ui.ddmanager.dragStart(this, event);
1154		}
1155
1156		return true;
1157	},
1158
1159	_mouseDrag: function(event, noPropagation) {
1160
1161		//Compute the helpers position
1162		this.position = this._generatePosition(event);
1163		this.positionAbs = this._convertPositionTo("absolute");
1164
1165		//Call plugins and callbacks and use the resulting position if something is returned
1166		if (!noPropagation) {
1167			var ui = this._uiHash();
1168			if(this._trigger("drag", event, ui) === false) {
1169				this._mouseUp({});
1170				return false;
1171			}
1172			this.position = ui.position;
1173		}
1174
1175		if(!this.options.axis || this.options.axis !== "y") {
1176			this.helper[0].style.left = this.position.left+"px";
1177		}
1178		if(!this.options.axis || this.options.axis !== "x") {
1179			this.helper[0].style.top = this.position.top+"px";
1180		}
1181		if($.ui.ddmanager) {
1182			$.ui.ddmanager.drag(this, event);
1183		}
1184
1185		return false;
1186	},
1187
1188	_mouseStop: function(event) {
1189
1190		//If we are using droppables, inform the manager about the drop
1191		var element,
1192			that = this,
1193			elementInDom = false,
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		element = this.element[0];
1207		while ( element && (element = element.parentNode) ) {
1208			if (element === document ) {
1209				elementInDom = true;
1210			}
1211		}
1212		if ( !elementInDom && this.options.helper === "original" ) {
1213			return false;
1214		}
1215
1216		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))) {
1217			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1218				if(that._trigger("stop", event) !== false) {
1219					that._clear();
1220				}
1221			});
1222		} else {
1223			if(this._trigger("stop", event) !== false) {
1224				this._clear();
1225			}
1226		}
1227
1228		return false;
1229	},
1230
1231	_mouseUp: function(event) {
1232		//Remove frame helpers
1233		$("div.ui-draggable-iframeFix").each(function() {
1234			this.parentNode.removeChild(this);
1235		});
1236
1237		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1238		if( $.ui.ddmanager ) {
1239			$.ui.ddmanager.dragStop(this, event);
1240		}
1241
1242		return $.ui.mouse.prototype._mouseUp.call(this, event);
1243	},
1244
1245	cancel: function() {
1246
1247		if(this.helper.is(".ui-draggable-dragging")) {
1248			this._mouseUp({});
1249		} else {
1250			this._clear();
1251		}
1252
1253		return this;
1254
1255	},
1256
1257	_getHandle: function(event) {
1258
1259		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1260		$(this.options.handle, this.element)
1261			.find("*")
1262			.addBack()
1263			.each(function() {
1264				if(this === event.target) {
1265					handle = true;
1266				}
1267			});
1268
1269		return handle;
1270
1271	},
1272
1273	_createHelper: function(event) {
1274
1275		var o = this.options,
1276			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1277
1278		if(!helper.parents("body").length) {
1279			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1280		}
1281
1282		if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1283			helper.css("position", "absolute");
1284		}
1285
1286		return helper;
1287
1288	},
1289
1290	_adjustOffsetFromHelper: function(obj) {
1291		if (typeof obj === "string") {
1292			obj = obj.split(" ");
1293		}
1294		if ($.isArray(obj)) {
1295			obj = {left: +obj[0], top: +obj[1] || 0};
1296		}
1297		if ("left" in obj) {
1298			this.offset.click.left = obj.left + this.margins.left;
1299		}
1300		if ("right" in obj) {
1301			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1302		}
1303		if ("top" in obj) {
1304			this.offset.click.top = obj.top + this.margins.top;
1305		}
1306		if ("bottom" in obj) {
1307			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1308		}
1309	},
1310
1311	_getParentOffset: function() {
1312
1313		//Get the offsetParent and cache its position
1314		this.offsetParent = this.helper.offsetParent();
1315		var po = this.offsetParent.offset();
1316
1317		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1318		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1319		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1320		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1321		if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1322			po.left += this.scrollParent.scrollLeft();
1323			po.top += this.scrollParent.scrollTop();
1324		}
1325
1326		//This needs to be actually done for all browsers, since pageX/pageY includes this information
1327		//Ugly IE fix
1328		if((this.offsetParent[0] === document.body) ||
1329			(this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1330			po = { top: 0, left: 0 };
1331		}
1332
1333		return {
1334			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
vendor: 1,408 bytes, lines 1334-1381
133410) || 0),
1335			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1336		};
1337
1338	},
1339
1340	_getRelativeOffset: function() {
1341
1342		if(this.cssPosition === "relative") {
1343			var p = this.element.position();
1344			return {
1345				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1346				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1347			};
1348		} else {
1349			return { top: 0, left: 0 };
1350		}
1351
1352	},
1353
1354	_cacheMargins: function() {
1355		this.margins = {
1356			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1357			top: (parseInt(this.element.css("marginTop"),10) || 0),
1358			right: (parseInt(this.element.css("marginRight"),10) || 0),
1359			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1360		};
1361	},
1362
1363	_cacheHelperProportions: function() {
1364		this.helperProportions = {
1365			width: this.helper.outerWidth(),
1366			height: this.helper.outerHeight()
1367		};
1368	},
1369
1370	_setContainment: function() {
1371
1372		var over, c, ce,
1373			o = this.options;
1374
1375		if(o.containment === "parent") {
1376			o.containment = this.helper[0].parentNode;
1377		}
1378		if(o.containment === "document" || o.containment === "window") {
1379			this.containment = [
1380				o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1381				o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
vendor: 6,288 bytes, lines 1382-1514
1382				(o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
1383				(o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1384			];
1385		}
1386
1387		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) {
1388			c = $(o.containment);
1389			ce = c[0];
1390
1391			if(!ce) {
1392				return;
1393			}
1394
1395			over = ($(ce).css("overflow") !== "hidden");
1396
1397			this.containment = [
1398				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1399				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1400				(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1401				(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1402			];
1403			this.relative_container = c;
1404
1405		} else if(o.containment.constructor === Array) {
1406			this.containment = o.containment;
1407		}
1408
1409	},
1410
1411	_convertPositionTo: function(d, pos) {
1412
1413		if(!pos) {
1414			pos = this.position;
1415		}
1416
1417		var mod = d === "absolute" ? 1 : -1,
1418			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);
1419
1420		return {
1421			top: (
1422				pos.top	+																// The absolute mouse position
1423				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
1424				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
1425				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1426			),
1427			left: (
1428				pos.left +																// The absolute mouse position
1429				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
1430				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
1431				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1432			)
1433		};
1434
1435	},
1436
1437	_generatePosition: function(event) {
1438
1439		var containment, co, top, left,
1440			o = this.options,
1441			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
1442			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName),
1443			pageX = event.pageX,
1444			pageY = event.pageY;
1445
1446		/*
1447		 * - Position constraining -
1448		 * Constrain the position to a mix of grid, containment.
1449		 */
1450
1451		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1452			if(this.containment) {
1453			if (this.relative_container){
1454				co = this.relative_container.offset();
1455				containment = [ this.containment[0] + co.left,
1456					this.containment[1] + co.top,
1457					this.containment[2] + co.left,
1458					this.containment[3] + co.top ];
1459			}
1460			else {
1461				containment = this.containment;
1462			}
1463
1464				if(event.pageX - this.offset.click.left < containment[0]) {
1465					pageX = containment[0] + this.offset.click.left;
1466				}
1467				if(event.pageY - this.offset.click.top < containment[1]) {
1468					pageY = containment[1] + this.offset.click.top;
1469				}
1470				if(event.pageX - this.offset.click.left > containment[2]) {
1471					pageX = containment[2] + this.offset.click.left;
1472				}
1473				if(event.pageY - this.offset.click.top > containment[3]) {
1474					pageY = containment[3] + this.offset.click.top;
1475				}
1476			}
1477
1478			if(o.grid) {
1479				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1480				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1481				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;
1482
1483				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1484				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;
1485			}
1486
1487		}
1488
1489		return {
1490			top: (
1491				pageY -																	// The absolute mouse position
1492				this.offset.click.top	-												// Click offset (relative to the element)
1493				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
1494				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
1495				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1496			),
1497			left: (
1498				pageX -																	// The absolute mouse position
1499				this.offset.click.left -												// Click offset (relative to the element)
1500				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
1501				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
1502				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1503			)
1504		};
1505
1506	},
1507
1508	_clear: function() {
1509		this.helper.removeClass("ui-draggable-dragging");
1510		if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1511			this.helper.remove();
1512		}
1513		this.helper = null;
1514		this.cancelHelperRemoval = false;
1515	},
1516
1517	// From now on bulk stuff - mainly helpers
1518
1519	_trigger: function(type, event, ui) {
1520		ui = ui || this._uiHash();
1521		$.ui.plugin.call(this, type, [event, ui]);
1522		//The absolute position has to be recalculated after plugins
1523		if(type === "drag") {
1524			this.positionAbs = this._convertPositionTo("absolute");
1525		}
1526		return $.Widget.prototype._trigger.call(this, type, event, ui);
1527	},
1528
1529	plugins: {},
1530
1531	_uiHash: function() {
1532		return {
1533			helper: this.helper,
1534			position: this.position,
1535			originalPosition: this.originalPosition,
1536			offset: this.positionAbs
1537		};
1538	}
1539
1540});
1541
1542$.ui.plugin.add("draggable", "connectToSortable", {
1543	start: function(event, ui) {
1544
1545		var inst = $(this).data("ui-draggable"), o = inst.options,
1546			uiSortable = $.extend({}, ui, { item: inst.element });
1547		inst.sortables = [];
1548		$(o.connectToSortable).each(function() {
1549			var sortable = $.data(this, "ui-sortable");
1550			if (sortable && !sortable.options.disabled) {
1551				inst.sortables.push({
1552					instance: sortable,
1553					shouldRevert: sortable.options.revert
1554				});
1555				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).
1556				sortable._trigger("activate", event, uiSortable);
1557			}
1558		});
1559
1560	},
1561	stop: function(event, ui) {
1562
1563		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1564		var inst = $(this).data("ui-draggable"),
1565			uiSortable = $.extend({}, ui, { item: inst.element });
1566
1567		$.each(inst.sortables, function() {
1568			if(this.instance.isOver) {
1569
1570				this.instance.isOver = 0;
1571
1572				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1573				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1574
1575				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1576				if(this.shouldRevert) {
1577					this.instance.options.revert = true;
1578				}
1579
1580				//Trigger the stop of the sortable
1581				this.instance._mouseStop(event);
1582
1583				this.instance.options.helper = this.instance.options._helper;
1584
1585				//If the helper has been the original item, restore properties in the sortable
1586				if(inst.options.helper === "original") {
1587					this.instance.currentItem.css({ top: "auto", left: "auto" });
1588				}
1589
1590			} else {
1591				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1592				this.instance._trigger("deactivate", event, uiSortable);
1593			}
1594
1595		});
1596
1597	},
1598	drag: function(event, ui) {
1599
1600		var inst = $(this).data("ui-draggable"), that = this;
1601
1602		$.each(inst.sortables, function() {
1603
1604			var innermostIntersecting = false,
1605				thisSortable = this;
1606
1607			//Copy over some variables to allow calling the sortable's native _intersectsWith
1608			this.instance.positionAbs = inst.positionAbs;
1609			this.instance.helperProportions = inst.helperProportions;
1610			this.instance.offset.click = inst.offset.click;
1611
1612			if(this.instance._intersectsWith(this.instance.containerCache)) {
1613				innermostIntersecting = true;
1614				$.each(inst.sortables, function () {
1615					this.instance.positionAbs = inst.positionAbs;
1616					this.instance.helperProportions = inst.helperProportions;
1617					this.instance.offset.click = inst.offset.click;
1618					if (this !== thisSortable &&
1619						this.instance._intersectsWith(this.instance.containerCache) &&
1620						$.contains(thisSortable.instance.element[0], this.instance.element[0])
1621					) {
1622						innermostIntersecting = false;
1623					}
1624					return innermostIntersecting;
1625				});
1626			}
1627
1628
1629			if(innermostIntersecting) {
1630				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1631				if(!this.instance.isOver) {
1632
1633					this.instance.isOver = 1;
1634					//Now we fake the start of dragging for the sortable instance,
1635					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1636					//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)
1637					this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1638					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1639					this.instance.options.helper = function() { return ui.helper[0]; };
1640
1641					event.target = this.instance.currentItem[0];
1642					this.instance._mouseCapture(event, true);
1643					this.instance._mouseStart(event, true, true);
1644
1645					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1646					this.instance.offset.click.top = inst.offset.click.top;
1647					this.instance.offset.click.left = inst.offset.click.left;
1648					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1649					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1650
1651					inst._trigger("toSortable", event);
1652					inst.dropped = this.instance.element; //draggable revert needs that
1653					//hack so receive/update callbacks work (mostly)
1654					inst.currentItem = inst.element;
1655					this.instance.fromOutside = inst;
1656
1657				}
1658
1659				//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
1660				if(this.instance.currentItem) {
1661					this.instance._mouseDrag(event);
1662				}
1663
1664			} else {
1665
1666				//If it doesn't intersect with the sortable, and it intersected before,
1667				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1668				if(this.instance.isOver) {
1669
1670					this.instance.isOver = 0;
1671					this.instance.cancelHelperRemoval = true;
1672
1673					//Prevent reverting on this forced stop
1674					this.instance.options.revert = false;
1675
1676					// The out event needs to be triggered independently
1677					this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1678
1679					this.instance._mouseStop(event, true);
1680					this.instance.options.helper = this.instance.options._helper;
1681
1682					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1683					this.instance.currentItem.remove();
1684					if(this.instance.placeholder) {
1685						this.instance.placeholder.remove();
1686					}
1687
1688					inst._trigger("fromSortable", event);
1689					inst.dropped = false; //draggable revert needs that
1690				}
1691
1692			}
1693
1694		});
1695
1696	}
1697});
1698
1699$.ui.plugin.add("draggable", "cursor", {
1700	start: function() {
1701		var t = $("body"), o = $(this).data("ui-draggable").options;
1702		if (t.css("cursor")) {
1703			o._cursor = t.css("cursor");
1704		}
1705		t.css("cursor", o.cursor);
1706	},
1707	stop: function() {
1708		var o = $(this).data("ui-draggable").options;
1709		if (o._cursor) {
1710			$("body").css("cursor", o._cursor);
1711		}
1712	}
1713});
1714
1715$.ui.plugin.add("draggable", "opacity", {
1716	start: function(event, ui) {
1717		var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1718		if(t.css("opacity")) {
1719			o._opacity = t.css("opacity");
1720		}
1721		t.css("opacity", o.opacity);
1722	},
1723	stop: function(event, ui) {
1724		var o = $(this).data("ui-draggable").options;
1725		if(o._opacity) {
1726			$(ui.helper).css("opacity", o._opacity);
1727		}
1728	}
1729});
1730
1731$.ui.plugin.add("draggable", "scroll", {
1732	start: function() {
1733		var i = $(this).data("ui-draggable");
1734		if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1735			i.overflowOffset = i.scrollParent.offset();
1736		}
1737	},
1738	drag: function( event ) {
1739
1740		var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1741
1742		if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1743
1744			if(!o.axis || o.axis !== "x") {
1745				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1746					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1747				} else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1748					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1749				}
1750			}
1751
1752			if(!o.axis || o.axis !== "y") {
1753				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1754					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1755				} else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1756					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1757				}
1758			}
1759
1760		} else {
1761
1762			if(!o.axis || o.axis !== "x") {
1763				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1764					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1765				} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1766					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1767				}
1768			}
1769
1770			if(!o.axis || o.axis !== "y") {
1771				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1772					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1773				} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1774					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1775				}
1776			}
1777
1778		}
1779
1780		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1781			$.ui.ddmanager.prepareOffsets(i, event);
1782		}
1783
1784	}
1785});
1786
1787$.ui.plugin.add("draggable", "snap", {
1788	start: function() {
1789
1790		var i = $(this).data("ui-draggable"),
1791			o = i.options;
1792
1793		i.snapElements = [];
1794
1795		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1796			var $t = $(this),
1797				$o = $t.offset();
1798			if(this !== i.element[0]) {
1799				i.snapElements.push({
1800					item: this,
1801					width: $t.outerWidth(), height: $t.outerHeight(),
1802					top: $o.top, left: $o.left
1803				});
1804			}
1805		});
1806
1807	},
1808	drag: function(event, ui) {
1809
1810		var ts, bs, ls, rs, l, r, t, b, i, first,
1811			inst = $(this).data("ui-draggable"),
1812			o = inst.options,
1813			d = o.snapTolerance,
1814			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1815			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1816
1817		for (i = inst.snapElements.length - 1; i >= 0; i--){
1818
1819			l = inst.snapElements[i].left;
1820			r = l + inst.snapElements[i].width;
1821			t = inst.snapElements[i].top;
1822			b = t + inst.snapElements[i].height;
1823
1824			//Yes, I know, this is insane ;)
1825			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1826				if(inst.snapElements[i].snapping) {
1827					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1828				}
1829				inst.snapElements[i].snapping = false;
vendor: 32,428 bytes, lines 1830-2971
1830				continue;
1831			}
1832
1833			if(o.snapMode !== "inner") {
1834				ts = Math.abs(t - y2) <= d;
1835				bs = Math.abs(b - y1) <= d;
1836				ls = Math.abs(l - x2) <= d;
1837				rs = Math.abs(r - x1) <= d;
1838				if(ts) {
1839					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1840				}
1841				if(bs) {
1842					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1843				}
1844				if(ls) {
1845					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1846				}
1847				if(rs) {
1848					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1849				}
1850			}
1851
1852			first = (ts || bs || ls || rs);
1853
1854			if(o.snapMode !== "outer") {
1855				ts = Math.abs(t - y1) <= d;
1856				bs = Math.abs(b - y2) <= d;
1857				ls = Math.abs(l - x1) <= d;
1858				rs = Math.abs(r - x2) <= d;
1859				if(ts) {
1860					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1861				}
1862				if(bs) {
1863					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1864				}
1865				if(ls) {
1866					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1867				}
1868				if(rs) {
1869					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1870				}
1871			}
1872
1873			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1874				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1875			}
1876			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1877
1878		}
1879
1880	}
1881});
1882
1883$.ui.plugin.add("draggable", "stack", {
1884	start: function() {
1885		var min,
1886			o = this.data("ui-draggable").options,
1887			group = $.makeArray($(o.stack)).sort(function(a,b) {
1888				return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1889			});
1890
1891		if (!group.length) { return; }
1892
1893		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1894		$(group).each(function(i) {
1895			$(this).css("zIndex", min + i);
1896		});
1897		this.css("zIndex", (min + group.length));
1898	}
1899});
1900
1901$.ui.plugin.add("draggable", "zIndex", {
1902	start: function(event, ui) {
1903		var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1904		if(t.css("zIndex")) {
1905			o._zIndex = t.css("zIndex");
1906		}
1907		t.css("zIndex", o.zIndex);
1908	},
1909	stop: function(event, ui) {
1910		var o = $(this).data("ui-draggable").options;
1911		if(o._zIndex) {
1912			$(ui.helper).css("zIndex", o._zIndex);
1913		}
1914	}
1915});
1916
1917})(jQuery);
1918
1919(function( $, undefined ) {
1920
1921function isOverAxis( x, reference, size ) {
1922	return ( x > reference ) && ( x < ( reference + size ) );
1923}
1924
1925$.widget("ui.droppable", {
1926	version: "1.10.1",
1927	widgetEventPrefix: "drop",
1928	options: {
1929		accept: "*",
1930		activeClass: false,
1931		addClasses: true,
1932		greedy: false,
1933		hoverClass: false,
1934		scope: "default",
1935		tolerance: "intersect",
1936
1937		// callbacks
1938		activate: null,
1939		deactivate: null,
1940		drop: null,
1941		out: null,
1942		over: null
1943	},
1944	_create: function() {
1945
1946		var o = this.options,
1947			accept = o.accept;
1948
1949		this.isover = false;
1950		this.isout = true;
1951
1952		this.accept = $.isFunction(accept) ? accept : function(d) {
1953			return d.is(accept);
1954		};
1955
1956		//Store the droppable's proportions
1957		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1958
1959		// Add the reference and positions to the manager
1960		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1961		$.ui.ddmanager.droppables[o.scope].push(this);
1962
1963		(o.addClasses && this.element.addClass("ui-droppable"));
1964
1965	},
1966
1967	_destroy: function() {
1968		var i = 0,
1969			drop = $.ui.ddmanager.droppables[this.options.scope];
1970
1971		for ( ; i < drop.length; i++ ) {
1972			if ( drop[i] === this ) {
1973				drop.splice(i, 1);
1974			}
1975		}
1976
1977		this.element.removeClass("ui-droppable ui-droppable-disabled");
1978	},
1979
1980	_setOption: function(key, value) {
1981
1982		if(key === "accept") {
1983			this.accept = $.isFunction(value) ? value : function(d) {
1984				return d.is(value);
1985			};
1986		}
1987		$.Widget.prototype._setOption.apply(this, arguments);
1988	},
1989
1990	_activate: function(event) {
1991		var draggable = $.ui.ddmanager.current;
1992		if(this.options.activeClass) {
1993			this.element.addClass(this.options.activeClass);
1994		}
1995		if(draggable){
1996			this._trigger("activate", event, this.ui(draggable));
1997		}
1998	},
1999
2000	_deactivate: function(event) {
2001		var draggable = $.ui.ddmanager.current;
2002		if(this.options.activeClass) {
2003			this.element.removeClass(this.options.activeClass);
2004		}
2005		if(draggable){
2006			this._trigger("deactivate", event, this.ui(draggable));
2007		}
2008	},
2009
2010	_over: function(event) {
2011
2012		var draggable = $.ui.ddmanager.current;
2013
2014		// Bail if draggable and droppable are same element
2015		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2016			return;
2017		}
2018
2019		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2020			if(this.options.hoverClass) {
2021				this.element.addClass(this.options.hoverClass);
2022			}
2023			this._trigger("over", event, this.ui(draggable));
2024		}
2025
2026	},
2027
2028	_out: function(event) {
2029
2030		var draggable = $.ui.ddmanager.current;
2031
2032		// Bail if draggable and droppable are same element
2033		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2034			return;
2035		}
2036
2037		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2038			if(this.options.hoverClass) {
2039				this.element.removeClass(this.options.hoverClass);
2040			}
2041			this._trigger("out", event, this.ui(draggable));
2042		}
2043
2044	},
2045
2046	_drop: function(event,custom) {
2047
2048		var draggable = custom || $.ui.ddmanager.current,
2049			childrenIntersection = false;
2050
2051		// Bail if draggable and droppable are same element
2052		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2053			return false;
2054		}
2055
2056		this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2057			var inst = $.data(this, "ui-droppable");
2058			if(
2059				inst.options.greedy &&
2060				!inst.options.disabled &&
2061				inst.options.scope === draggable.options.scope &&
2062				inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2063				$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2064			) { childrenIntersection = true; return false; }
2065		});
2066		if(childrenIntersection) {
2067			return false;
2068		}
2069
2070		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2071			if(this.options.activeClass) {
2072				this.element.removeClass(this.options.activeClass);
2073			}
2074			if(this.options.hoverClass) {
2075				this.element.removeClass(this.options.hoverClass);
2076			}
2077			this._trigger("drop", event, this.ui(draggable));
2078			return this.element;
2079		}
2080
2081		return false;
2082
2083	},
2084
2085	ui: function(c) {
2086		return {
2087			draggable: (c.currentItem || c.element),
2088			helper: c.helper,
2089			position: c.position,
2090			offset: c.positionAbs
2091		};
2092	}
2093
2094});
2095
2096$.ui.intersect = function(draggable, droppable, toleranceMode) {
2097
2098	if (!droppable.offset) {
2099		return false;
2100	}
2101
2102	var draggableLeft, draggableTop,
2103		x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2104		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
2105		l = droppable.offset.left, r = l + droppable.proportions.width,
2106		t = droppable.offset.top, b = t + droppable.proportions.height;
2107
2108	switch (toleranceMode) {
2109		case "fit":
2110			return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2111		case "intersect":
2112			return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2113				x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2114				t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2115				y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2116		case "pointer":
2117			draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2118			draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2119			return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
2120		case "touch":
2121			return (
2122				(y1 >= t && y1 <= b) ||	// Top edge touching
2123				(y2 >= t && y2 <= b) ||	// Bottom edge touching
2124				(y1 < t && y2 > b)		// Surrounded vertically
2125			) && (
2126				(x1 >= l && x1 <= r) ||	// Left edge touching
2127				(x2 >= l && x2 <= r) ||	// Right edge touching
2128				(x1 < l && x2 > r)		// Surrounded horizontally
2129			);
2130		default:
2131			return false;
2132		}
2133
2134};
2135
2136/*
2137	This manager tracks offsets of draggables and droppables
2138*/
2139$.ui.ddmanager = {
2140	current: null,
2141	droppables: { "default": [] },
2142	prepareOffsets: function(t, event) {
2143
2144		var i, j,
2145			m = $.ui.ddmanager.droppables[t.options.scope] || [],
2146			type = event ? event.type : null, // workaround for #2317
2147			list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2148
2149		droppablesLoop: for (i = 0; i < m.length; i++) {
2150
2151			//No disabled and non-accepted
2152			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2153				continue;
2154			}
2155
2156			// Filter out elements in the current dragged item
2157			for (j=0; j < list.length; j++) {
2158				if(list[j] === m[i].element[0]) {
2159					m[i].proportions.height = 0;
2160					continue droppablesLoop;
2161				}
2162			}
2163
2164			m[i].visible = m[i].element.css("display") !== "none";
2165			if(!m[i].visible) {
2166				continue;
2167			}
2168
2169			//Activate the droppable if used directly from draggables
2170			if(type === "mousedown") {
2171				m[i]._activate.call(m[i], event);
2172			}
2173
2174			m[i].offset = m[i].element.offset();
2175			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2176
2177		}
2178
2179	},
2180	drop: function(draggable, event) {
2181
2182		var dropped = false;
2183		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2184
2185			if(!this.options) {
2186				return;
2187			}
2188			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2189				dropped = this._drop.call(this, event) || dropped;
2190			}
2191
2192			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2193				this.isout = true;
2194				this.isover = false;
2195				this._deactivate.call(this, event);
2196			}
2197
2198		});
2199		return dropped;
2200
2201	},
2202	dragStart: function( draggable, event ) {
2203		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2204		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2205			if( !draggable.options.refreshPositions ) {
2206				$.ui.ddmanager.prepareOffsets( draggable, event );
2207			}
2208		});
2209	},
2210	drag: function(draggable, event) {
2211
2212		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2213		if(draggable.options.refreshPositions) {
2214			$.ui.ddmanager.prepareOffsets(draggable, event);
2215		}
2216
2217		//Run through all droppables and check their positions based on specific tolerance options
2218		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2219
2220			if(this.options.disabled || this.greedyChild || !this.visible) {
2221				return;
2222			}
2223
2224			var parentInstance, scope, parent,
2225				intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2226				c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2227			if(!c) {
2228				return;
2229			}
2230
2231			if (this.options.greedy) {
2232				// find droppable parents with same scope
2233				scope = this.options.scope;
2234				parent = this.element.parents(":data(ui-droppable)").filter(function () {
2235					return $.data(this, "ui-droppable").options.scope === scope;
2236				});
2237
2238				if (parent.length) {
2239					parentInstance = $.data(parent[0], "ui-droppable");
2240					parentInstance.greedyChild = (c === "isover");
2241				}
2242			}
2243
2244			// we just moved into a greedy child
2245			if (parentInstance && c === "isover") {
2246				parentInstance.isover = false;
2247				parentInstance.isout = true;
2248				parentInstance._out.call(parentInstance, event);
2249			}
2250
2251			this[c] = true;
2252			this[c === "isout" ? "isover" : "isout"] = false;
2253			this[c === "isover" ? "_over" : "_out"].call(this, event);
2254
2255			// we just moved out of a greedy child
2256			if (parentInstance && c === "isout") {
2257				parentInstance.isout = false;
2258				parentInstance.isover = true;
2259				parentInstance._over.call(parentInstance, event);
2260			}
2261		});
2262
2263	},
2264	dragStop: function( draggable, event ) {
2265		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2266		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2267		if( !draggable.options.refreshPositions ) {
2268			$.ui.ddmanager.prepareOffsets( draggable, event );
2269		}
2270	}
2271};
2272
2273})(jQuery);
2274
2275(function( $, undefined ) {
2276
2277function num(v) {
2278	return parseInt(v, 10) || 0;
2279}
2280
2281function isNumber(value) {
2282	return !isNaN(parseInt(value, 10));
2283}
2284
2285$.widget("ui.resizable", $.ui.mouse, {
2286	version: "1.10.1",
2287	widgetEventPrefix: "resize",
2288	options: {
2289		alsoResize: false,
2290		animate: false,
2291		animateDuration: "slow",
2292		animateEasing: "swing",
2293		aspectRatio: false,
2294		autoHide: false,
2295		containment: false,
2296		ghost: false,
2297		grid: false,
2298		handles: "e,s,se",
2299		helper: false,
2300		maxHeight: null,
2301		maxWidth: null,
2302		minHeight: 10,
2303		minWidth: 10,
2304		// See #7960
2305		zIndex: 90,
2306
2307		// callbacks
2308		resize: null,
2309		start: null,
2310		stop: null
2311	},
2312	_create: function() {
2313
2314		var n, i, handle, axis, hname,
2315			that = this,
2316			o = this.options;
2317		this.element.addClass("ui-resizable");
2318
2319		$.extend(this, {
2320			_aspectRatio: !!(o.aspectRatio),
2321			aspectRatio: o.aspectRatio,
2322			originalElement: this.element,
2323			_proportionallyResizeElements: [],
2324			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2325		});
2326
2327		//Wrap the element if it cannot hold child nodes
2328		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2329
2330			//Create a wrapper element and set the wrapper to the new current internal element
2331			this.element.wrap(
2332				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2333					position: this.element.css("position"),
2334					width: this.element.outerWidth(),
2335					height: this.element.outerHeight(),
2336					top: this.element.css("top"),
2337					left: this.element.css("left")
2338				})
2339			);
2340
2341			//Overwrite the original this.element
2342			this.element = this.element.parent().data(
2343				"ui-resizable", this.element.data("ui-resizable")
2344			);
2345
2346			this.elementIsWrapper = true;
2347
2348			//Move margins to the wrapper
2349			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2350			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2351
2352			//Prevent Safari textarea resize
2353			this.originalResizeStyle = this.originalElement.css("resize");
2354			this.originalElement.css("resize", "none");
2355
2356			//Push the actual element to our proportionallyResize internal array
2357			this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2358
2359			// avoid IE jump (hard set the margin)
2360			this.originalElement.css({ margin: this.originalElement.css("margin") });
2361
2362			// fix handlers offset
2363			this._proportionallyResize();
2364
2365		}
2366
2367		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" });
2368		if(this.handles.constructor === String) {
2369
2370			if ( this.handles === "all") {
2371				this.handles = "n,e,s,w,se,sw,ne,nw";
2372			}
2373
2374			n = this.handles.split(",");
2375			this.handles = {};
2376
2377			for(i = 0; i < n.length; i++) {
2378
2379				handle = $.trim(n[i]);
2380				hname = "ui-resizable-"+handle;
2381				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2382
2383				// Apply zIndex to all handles - see #7960
2384				axis.css({ zIndex: o.zIndex });
2385
2386				//TODO : What's going on here?
2387				if ("se" === handle) {
2388					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2389				}
2390
2391				//Insert into internal handles object and append to element
2392				this.handles[handle] = ".ui-resizable-"+handle;
2393				this.element.append(axis);
2394			}
2395
2396		}
2397
2398		this._renderAxis = function(target) {
2399
2400			var i, axis, padPos, padWrapper;
2401
2402			target = target || this.element;
2403
2404			for(i in this.handles) {
2405
2406				if(this.handles[i].constructor === String) {
2407					this.handles[i] = $(this.handles[i], this.element).show();
2408				}
2409
2410				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2411				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2412
2413					axis = $(this.handles[i], this.element);
2414
2415					//Checking the correct pad and border
2416					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2417
2418					//The padding type i have to apply...
2419					padPos = [ "padding",
2420						/ne|nw|n/.test(i) ? "Top" :
2421						/se|sw|s/.test(i) ? "Bottom" :
2422						/^e$/.test(i) ? "Right" : "Left" ].join("");
2423
2424					target.css(padPos, padWrapper);
2425
2426					this._proportionallyResize();
2427
2428				}
2429
2430				//TODO: What's that good for? There's not anything to be executed left
2431				if(!$(this.handles[i]).length) {
2432					continue;
2433				}
2434			}
2435		};
2436
2437		//TODO: make renderAxis a prototype function
2438		this._renderAxis(this.element);
2439
2440		this._handles = $(".ui-resizable-handle", this.element)
2441			.disableSelection();
2442
2443		//Matching axis name
2444		this._handles.mouseover(function() {
2445			if (!that.resizing) {
2446				if (this.className) {
2447					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2448				}
2449				//Axis, default = se
2450				that.axis = axis && axis[1] ? axis[1] : "se";
2451			}
2452		});
2453
2454		//If we want to auto hide the elements
2455		if (o.autoHide) {
2456			this._handles.hide();
2457			$(this.element)
2458				.addClass("ui-resizable-autohide")
2459				.mouseenter(function() {
2460					if (o.disabled) {
2461						return;
2462					}
2463					$(this).removeClass("ui-resizable-autohide");
2464					that._handles.show();
2465				})
2466				.mouseleave(function(){
2467					if (o.disabled) {
2468						return;
2469					}
2470					if (!that.resizing) {
2471						$(this).addClass("ui-resizable-autohide");
2472						that._handles.hide();
2473					}
2474				});
2475		}
2476
2477		//Initialize the mouse interaction
2478		this._mouseInit();
2479
2480	},
2481
2482	_destroy: function() {
2483
2484		this._mouseDestroy();
2485
2486		var wrapper,
2487			_destroy = function(exp) {
2488				$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2489					.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2490			};
2491
2492		//TODO: Unwrap at same DOM position
2493		if (this.elementIsWrapper) {
2494			_destroy(this.element);
2495			wrapper = this.element;
2496			this.originalElement.css({
2497				position: wrapper.css("position"),
2498				width: wrapper.outerWidth(),
2499				height: wrapper.outerHeight(),
2500				top: wrapper.css("top"),
2501				left: wrapper.css("left")
2502			}).insertAfter( wrapper );
2503			wrapper.remove();
2504		}
2505
2506		this.originalElement.css("resize", this.originalResizeStyle);
2507		_destroy(this.originalElement);
2508
2509		return this;
2510	},
2511
2512	_mouseCapture: function(event) {
2513		var i, handle,
2514			capture = false;
2515
2516		for (i in this.handles) {
2517			handle = $(this.handles[i])[0];
2518			if (handle === event.target || $.contains(handle, event.target)) {
2519				capture = true;
2520			}
2521		}
2522
2523		return !this.options.disabled && capture;
2524	},
2525
2526	_mouseStart: function(event) {
2527
2528		var curleft, curtop, cursor,
2529			o = this.options,
2530			iniPos = this.element.position(),
2531			el = this.element;
2532
2533		this.resizing = true;
2534
2535		// bugfix for http://dev.jquery.com/ticket/1749
2536		if ( (/absolute/).test( el.css("position") ) ) {
2537			el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2538		} else if (el.is(".ui-draggable")) {
2539			el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2540		}
2541
2542		this._renderProxy();
2543
2544		curleft = num(this.helper.css("left"));
2545		curtop = num(this.helper.css("top"));
2546
2547		if (o.containment) {
2548			curleft += $(o.containment).scrollLeft() || 0;
2549			curtop += $(o.containment).scrollTop() || 0;
2550		}
2551
2552		//Store needed variables
2553		this.offset = this.helper.offset();
2554		this.position = { left: curleft, top: curtop };
2555		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2556		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2557		this.originalPosition = { left: curleft, top: curtop };
2558		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2559		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2560
2561		//Aspect Ratio
2562		this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2563
2564		cursor = $(".ui-resizable-" + this.axis).css("cursor");
2565		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2566
2567		el.addClass("ui-resizable-resizing");
2568		this._propagate("start", event);
2569		return true;
2570	},
2571
2572	_mouseDrag: function(event) {
2573
2574		//Increase performance, avoid regex
2575		var data,
2576			el = this.helper, props = {},
2577			smp = this.originalMousePosition,
2578			a = this.axis,
2579			prevTop = this.position.top,
2580			prevLeft = this.position.left,
2581			prevWidth = this.size.width,
2582			prevHeight = this.size.height,
2583			dx = (event.pageX-smp.left)||0,
2584			dy = (event.pageY-smp.top)||0,
2585			trigger = this._change[a];
2586
2587		if (!trigger) {
2588			return false;
2589		}
2590
2591		// Calculate the attrs that will be change
2592		data = trigger.apply(this, [event, dx, dy]);
2593
2594		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2595		this._updateVirtualBoundaries(event.shiftKey);
2596		if (this._aspectRatio || event.shiftKey) {
2597			data = this._updateRatio(data, event);
2598		}
2599
2600		data = this._respectSize(data, event);
2601
2602		this._updateCache(data);
2603
2604		// plugins callbacks need to be called first
2605		this._propagate("resize", event);
2606
2607		if (this.position.top !== prevTop) {
2608			props.top = this.position.top + "px";
2609		}
2610		if (this.position.left !== prevLeft) {
2611			props.left = this.position.left + "px";
2612		}
2613		if (this.size.width !== prevWidth) {
2614			props.width = this.size.width + "px";
2615		}
2616		if (this.size.height !== prevHeight) {
2617			props.height = this.size.height + "px";
2618		}
2619		el.css(props);
2620
2621		if (!this._helper && this._proportionallyResizeElements.length) {
2622			this._proportionallyResize();
2623		}
2624
2625		// Call the user callback if the element was resized
2626		if ( ! $.isEmptyObject(props) ) {
2627			this._trigger("resize", event, this.ui());
2628		}
2629
2630		return false;
2631	},
2632
2633	_mouseStop: function(event) {
2634
2635		this.resizing = false;
2636		var pr, ista, soffseth, soffsetw, s, left, top,
2637			o = this.options, that = this;
2638
2639		if(this._helper) {
2640
2641			pr = this._proportionallyResizeElements;
2642			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2643			soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2644			soffsetw = ista ? 0 : that.sizeDiff.width;
2645
2646			s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
2647			left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2648			top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2649
2650			if (!o.animate) {
2651				this.element.css($.extend(s, { top: top, left: left }));
2652			}
2653
2654			that.helper.height(that.size.height);
2655			that.helper.width(that.size.width);
2656
2657			if (this._helper && !o.animate) {
2658				this._proportionallyResize();
2659			}
2660		}
2661
2662		$("body").css("cursor", "auto");
2663
2664		this.element.removeClass("ui-resizable-resizing");
2665
2666		this._propagate("stop", event);
2667
2668		if (this._helper) {
2669			this.helper.remove();
2670		}
2671
2672		return false;
2673
2674	},
2675
2676	_updateVirtualBoundaries: function(forceAspectRatio) {
2677		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2678			o = this.options;
2679
2680		b = {
2681			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2682			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2683			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2684			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2685		};
2686
2687		if(this._aspectRatio || forceAspectRatio) {
2688			// We want to create an enclosing box whose aspect ration is the requested one
2689			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2690			pMinWidth = b.minHeight * this.aspectRatio;
2691			pMinHeight = b.minWidth / this.aspectRatio;
2692			pMaxWidth = b.maxHeight * this.aspectRatio;
2693			pMaxHeight = b.maxWidth / this.aspectRatio;
2694
2695			if(pMinWidth > b.minWidth) {
2696				b.minWidth = pMinWidth;
2697			}
2698			if(pMinHeight > b.minHeight) {
2699				b.minHeight = pMinHeight;
2700			}
2701			if(pMaxWidth < b.maxWidth) {
2702				b.maxWidth = pMaxWidth;
2703			}
2704			if(pMaxHeight < b.maxHeight) {
2705				b.maxHeight = pMaxHeight;
2706			}
2707		}
2708		this._vBoundaries = b;
2709	},
2710
2711	_updateCache: function(data) {
2712		this.offset = this.helper.offset();
2713		if (isNumber(data.left)) {
2714			this.position.left = data.left;
2715		}
2716		if (isNumber(data.top)) {
2717			this.position.top = data.top;
2718		}
2719		if (isNumber(data.height)) {
2720			this.size.height = data.height;
2721		}
2722		if (isNumber(data.width)) {
2723			this.size.width = data.width;
2724		}
2725	},
2726
2727	_updateRatio: function( data ) {
2728
2729		var cpos = this.position,
2730			csize = this.size,
2731			a = this.axis;
2732
2733		if (isNumber(data.height)) {
2734			data.width = (data.height * this.aspectRatio);
2735		} else if (isNumber(data.width)) {
2736			data.height = (data.width / this.aspectRatio);
2737		}
2738
2739		if (a === "sw") {
2740			data.left = cpos.left + (csize.width - data.width);
2741			data.top = null;
2742		}
2743		if (a === "nw") {
2744			data.top = cpos.top + (csize.height - data.height);
2745			data.left = cpos.left + (csize.width - data.width);
2746		}
2747
2748		return data;
2749	},
2750
2751	_respectSize: function( data ) {
2752
2753		var o = this._vBoundaries,
2754			a = this.axis,
2755			ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2756			isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2757			dw = this.originalPosition.left + this.originalSize.width,
2758			dh = this.position.top + this.size.height,
2759			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2760		if (isminw) {
2761			data.width = o.minWidth;
2762		}
2763		if (isminh) {
2764			data.height = o.minHeight;
2765		}
2766		if (ismaxw) {
2767			data.width = o.maxWidth;
2768		}
2769		if (ismaxh) {
2770			data.height = o.maxHeight;
2771		}
2772
2773		if (isminw && cw) {
2774			data.left = dw - o.minWidth;
2775		}
2776		if (ismaxw && cw) {
2777			data.left = dw - o.maxWidth;
2778		}
2779		if (isminh && ch) {
2780			data.top = dh - o.minHeight;
2781		}
2782		if (ismaxh && ch) {
2783			data.top = dh - o.maxHeight;
2784		}
2785
2786		// fixing jump error on top/left - bug #2330
2787		if (!data.width && !data.height && !data.left && data.top) {
2788			data.top = null;
2789		} else if (!data.width && !data.height && !data.top && data.left) {
2790			data.left = null;
2791		}
2792
2793		return data;
2794	},
2795
2796	_proportionallyResize: function() {
2797
2798		if (!this._proportionallyResizeElements.length) {
2799			return;
2800		}
2801
2802		var i, j, borders, paddings, prel,
2803			element = this.helper || this.element;
2804
2805		for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2806
2807			prel = this._proportionallyResizeElements[i];
2808
2809			if (!this.borderDif) {
2810				this.borderDif = [];
2811				borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2812				paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2813
2814				for ( j = 0; j < borders.length; j++ ) {
2815					this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2816				}
2817			}
2818
2819			prel.css({
2820				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2821				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2822			});
2823
2824		}
2825
2826	},
2827
2828	_renderProxy: function() {
2829
2830		var el = this.element, o = this.options;
2831		this.elementOffset = el.offset();
2832
2833		if(this._helper) {
2834
2835			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
2836
2837			this.helper.addClass(this._helper).css({
2838				width: this.element.outerWidth() - 1,
2839				height: this.element.outerHeight() - 1,
2840				position: "absolute",
2841				left: this.elementOffset.left +"px",
2842				top: this.elementOffset.top +"px",
2843				zIndex: ++o.zIndex //TODO: Don't modify option
2844			});
2845
2846			this.helper
2847				.appendTo("body")
2848				.disableSelection();
2849
2850		} else {
2851			this.helper = this.element;
2852		}
2853
2854	},
2855
2856	_change: {
2857		e: function(event, dx) {
2858			return { width: this.originalSize.width + dx };
2859		},
2860		w: function(event, dx) {
2861			var cs = this.originalSize, sp = this.originalPosition;
2862			return { left: sp.left + dx, width: cs.width - dx };
2863		},
2864		n: function(event, dx, dy) {
2865			var cs = this.originalSize, sp = this.originalPosition;
2866			return { top: sp.top + dy, height: cs.height - dy };
2867		},
2868		s: function(event, dx, dy) {
2869			return { height: this.originalSize.height + dy };
2870		},
2871		se: function(event, dx, dy) {
2872			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2873		},
2874		sw: function(event, dx, dy) {
2875			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2876		},
2877		ne: function(event, dx, dy) {
2878			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2879		},
2880		nw: function(event, dx, dy) {
2881			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2882		}
2883	},
2884
2885	_propagate: function(n, event) {
2886		$.ui.plugin.call(this, n, [event, this.ui()]);
2887		(n !== "resize" && this._trigger(n, event, this.ui()));
2888	},
2889
2890	plugins: {},
2891
2892	ui: function() {
2893		return {
2894			originalElement: this.originalElement,
2895			element: this.element,
2896			helper: this.helper,
2897			position: this.position,
2898			size: this.size,
2899			originalSize: this.originalSize,
2900			originalPosition: this.originalPosition
2901		};
2902	}
2903
2904});
2905
2906/*
2907 * Resizable Extensions
2908 */
2909
2910$.ui.plugin.add("resizable", "animate", {
2911
2912	stop: function( event ) {
2913		var that = $(this).data("ui-resizable"),
2914			o = that.options,
2915			pr = that._proportionallyResizeElements,
2916			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2917			soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2918			soffsetw = ista ? 0 : that.sizeDiff.width,
2919			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2920			left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2921			top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2922
2923		that.element.animate(
2924			$.extend(style, top && left ? { top: top, left: left } : {}), {
2925				duration: o.animateDuration,
2926				easing: o.animateEasing,
2927				step: function() {
2928
2929					var data = {
2930						width: parseInt(that.element.css("width"), 10),
2931						height: parseInt(that.element.css("height"), 10),
2932						top: parseInt(that.element.css("top"), 10),
2933						left: parseInt(that.element.css("left"), 10)
2934					};
2935
2936					if (pr && pr.length) {
2937						$(pr[0]).css({ width: data.width, height: data.height });
2938					}
2939
2940					// propagating resize, and updating values for each animation step
2941					that._updateCache(data);
2942					that._propagate("resize", event);
2943
2944				}
2945			}
2946		);
2947	}
2948
2949});
2950
2951$.ui.plugin.add("resizable", "containment", {
2952
2953	start: function() {
2954		var element, p, co, ch, cw, width, height,
2955			that = $(this).data("ui-resizable"),
2956			o = that.options,
2957			el = that.element,
2958			oc = o.containment,
2959			ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2960
2961		if (!ce) {
2962			return;
2963		}
2964
2965		that.containerElement = $(ce);
2966
2967		if (/document/.test(oc) || oc === document) {
2968			that.containerOffset = { left: 0, top: 0 };
2969			that.containerPosition = { left: 0, top: 0 };
2970
2971			that.parentData = {
2972				element: $(document), left: 0, top: 0,
2973				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2974			};
2975		}
2976
2977		// i'm a node, so compute top, left, right, bottom
2978		else {
2979			element = $(ce);
2980			p = [];
2981			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2982
2983			that.containerOffset = element.offset();
2984			that.containerPosition = element.position();
2985			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2986
2987			co = that.containerOffset;
2988			ch = that.containerSize.height;
2989			cw = that.containerSize.width;
2990			width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
2991			height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2992
2993			that.parentData = {
2994				element: ce, left: co.left, top: co.top, width: width, height: height
2995			};
2996		}
2997	},
2998
2999	resize: function( event ) {
3000		var woset, hoset, isParent, isOffsetRelative,
3001			that = $(this).data("ui-resizable"),
3002			o = that.options,
3003			co = that.containerOffset, cp = that.position,
3004			pRatio = that._aspectRatio || event.shiftKey,
3005			cop = { top:0, left:0 }, ce = that.containerElement;
3006
3007		if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3008			cop = co;
3009		}
3010
3011		if (cp.left < (that._helper ? co.left : 0)) {
3012			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3013			if (pRatio) {
3014				that.size.height = that.size.width / that.aspectRatio;
3015			}
3016			that.position.left = o.helper ? co.left : 0;
3017		}
3018
3019		if (cp.top < (that._helper ? co.top : 0)) {
3020			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3021			if (pRatio) {
3022				that.size.width = that.size.height * that.aspectRatio;
3023			}
3024			that.position.top = that._helper ? co.top : 0;
3025		}
3026
3027		that.offset.left = that.parentData.left+that.position.left;
3028		that.offset.top = that.parentData.top+that.position.top;
3029
3030		woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3031		hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3032
3033		isParent = that.containerElement.get(0) === that.element.parent().get(0);
3034		isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3035
3036		if(isParent && isOffsetRelative) {
3037			woset -= that.parentData.left;
3038		}
3039
3040		if (woset + that.size.width >= that.parentData.width) {
3041			that.size.width = that.parentData.width - woset;
3042			if (pRatio) {
3043				that.size.height = that.size.width / that.aspectRatio;
3044			}
3045		}
3046
3047		if (hoset + that.size.height >= that.parentData.height) {
3048			that.size.height = that.parentData.height - hoset;
3049			if (pRatio) {
3050				that.size.width = that.size.height * that.aspectRatio;
3051			}
3052		}
3053	},
3054
3055	stop: function(){
3056		var that = $(this).data("ui-resizable"),
3057			o = that.options,
3058			co = that.containerOffset,
3059			cop = that.containerPosition,
3060			ce = that.containerElement,
3061			helper = $(that.helper),
3062			ho = helper.offset(),
3063			w = helper.outerWidth() - that.sizeDiff.width,
3064			h = helper.outerHeight() - that.sizeDiff.height;
3065
3066		if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3067			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3068		}
3069
3070		if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3071			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3072		}
3073
3074	}
3075});
3076
3077$.ui.plugin.add("resizable", "alsoResize", {
3078
3079	start: function () {
3080		var that = $(this).data("ui-resizable"),
3081			o = that.options,
3082			_store = function (exp) {
3083				$(exp).each(function() {
3084					var el = $(this);
3085					el.data("ui-resizable-alsoresize", {
3086						width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3087						left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3088					});
3089				});
3090			};
3091
3092		if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3093			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3094			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3095		}else{
3096			_store(o.alsoResize);
3097		}
3098	},
3099
3100	resize: function (event, ui) {
3101		var that = $(this).data("ui-resizable"),
3102			o = that.options,
3103			os = that.originalSize,
3104			op = that.originalPosition,
3105			delta = {
3106				height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3107				top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3108			},
3109
3110			_alsoResize = function (exp, c) {
3111				$(exp).each(function() {
3112					var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3113						css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3114
vendor: 36,306 bytes, lines 3115-4365
3115					$.each(css, function (i, prop) {
3116						var sum = (start[prop]||0) + (delta[prop]||0);
3117						if (sum && sum >= 0) {
3118							style[prop] = sum || null;
3119						}
3120					});
3121
3122					el.css(style);
3123				});
3124			};
3125
3126		if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3127			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3128		}else{
3129			_alsoResize(o.alsoResize);
3130		}
3131	},
3132
3133	stop: function () {
3134		$(this).removeData("resizable-alsoresize");
3135	}
3136});
3137
3138$.ui.plugin.add("resizable", "ghost", {
3139
3140	start: function() {
3141
3142		var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3143
3144		that.ghost = that.originalElement.clone();
3145		that.ghost
3146			.css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3147			.addClass("ui-resizable-ghost")
3148			.addClass(typeof o.ghost === "string" ? o.ghost : "");
3149
3150		that.ghost.appendTo(that.helper);
3151
3152	},
3153
3154	resize: function(){
3155		var that = $(this).data("ui-resizable");
3156		if (that.ghost) {
3157			that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3158		}
3159	},
3160
3161	stop: function() {
3162		var that = $(this).data("ui-resizable");
3163		if (that.ghost && that.helper) {
3164			that.helper.get(0).removeChild(that.ghost.get(0));
3165		}
3166	}
3167
3168});
3169
3170$.ui.plugin.add("resizable", "grid", {
3171
3172	resize: function() {
3173		var that = $(this).data("ui-resizable"),
3174			o = that.options,
3175			cs = that.size,
3176			os = that.originalSize,
3177			op = that.originalPosition,
3178			a = that.axis,
3179			grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3180			gridX = (grid[0]||1),
3181			gridY = (grid[1]||1),
3182			ox = Math.round((cs.width - os.width) / gridX) * gridX,
3183			oy = Math.round((cs.height - os.height) / gridY) * gridY,
3184			newWidth = os.width + ox,
3185			newHeight = os.height + oy,
3186			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3187			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3188			isMinWidth = o.minWidth && (o.minWidth > newWidth),
3189			isMinHeight = o.minHeight && (o.minHeight > newHeight);
3190
3191		o.grid = grid;
3192
3193		if (isMinWidth) {
3194			newWidth = newWidth + gridX;
3195		}
3196		if (isMinHeight) {
3197			newHeight = newHeight + gridY;
3198		}
3199		if (isMaxWidth) {
3200			newWidth = newWidth - gridX;
3201		}
3202		if (isMaxHeight) {
3203			newHeight = newHeight - gridY;
3204		}
3205
3206		if (/^(se|s|e)$/.test(a)) {
3207			that.size.width = newWidth;
3208			that.size.height = newHeight;
3209		} else if (/^(ne)$/.test(a)) {
3210			that.size.width = newWidth;
3211			that.size.height = newHeight;
3212			that.position.top = op.top - oy;
3213		} else if (/^(sw)$/.test(a)) {
3214			that.size.width = newWidth;
3215			that.size.height = newHeight;
3216			that.position.left = op.left - ox;
3217		} else {
3218			that.size.width = newWidth;
3219			that.size.height = newHeight;
3220			that.position.top = op.top - oy;
3221			that.position.left = op.left - ox;
3222		}
3223	}
3224
3225});
3226
3227})(jQuery);
3228
3229(function( $, undefined ) {
3230
3231$.widget("ui.selectable", $.ui.mouse, {
3232	version: "1.10.1",
3233	options: {
3234		appendTo: "body",
3235		autoRefresh: true,
3236		distance: 0,
3237		filter: "*",
3238		tolerance: "touch",
3239
3240		// callbacks
3241		selected: null,
3242		selecting: null,
3243		start: null,
3244		stop: null,
3245		unselected: null,
3246		unselecting: null
3247	},
3248	_create: function() {
3249		var selectees,
3250			that = this;
3251
3252		this.element.addClass("ui-selectable");
3253
3254		this.dragged = false;
3255
3256		// cache selectee children based on filter
3257		this.refresh = function() {
3258			selectees = $(that.options.filter, that.element[0]);
3259			selectees.addClass("ui-selectee");
3260			selectees.each(function() {
3261				var $this = $(this),
3262					pos = $this.offset();
3263				$.data(this, "selectable-item", {
3264					element: this,
3265					$element: $this,
3266					left: pos.left,
3267					top: pos.top,
3268					right: pos.left + $this.outerWidth(),
3269					bottom: pos.top + $this.outerHeight(),
3270					startselected: false,
3271					selected: $this.hasClass("ui-selected"),
3272					selecting: $this.hasClass("ui-selecting"),
3273					unselecting: $this.hasClass("ui-unselecting")
3274				});
3275			});
3276		};
3277		this.refresh();
3278
3279		this.selectees = selectees.addClass("ui-selectee");
3280
3281		this._mouseInit();
3282
3283		this.helper = $("<div class='ui-selectable-helper'></div>");
3284	},
3285
3286	_destroy: function() {
3287		this.selectees
3288			.removeClass("ui-selectee")
3289			.removeData("selectable-item");
3290		this.element
3291			.removeClass("ui-selectable ui-selectable-disabled");
3292		this._mouseDestroy();
3293	},
3294
3295	_mouseStart: function(event) {
3296		var that = this,
3297			options = this.options;
3298
3299		this.opos = [event.pageX, event.pageY];
3300
3301		if (this.options.disabled) {
3302			return;
3303		}
3304
3305		this.selectees = $(options.filter, this.element[0]);
3306
3307		this._trigger("start", event);
3308
3309		$(options.appendTo).append(this.helper);
3310		// position helper (lasso)
3311		this.helper.css({
3312			"left": event.pageX,
3313			"top": event.pageY,
3314			"width": 0,
3315			"height": 0
3316		});
3317
3318		if (options.autoRefresh) {
3319			this.refresh();
3320		}
3321
3322		this.selectees.filter(".ui-selected").each(function() {
3323			var selectee = $.data(this, "selectable-item");
3324			selectee.startselected = true;
3325			if (!event.metaKey && !event.ctrlKey) {
3326				selectee.$element.removeClass("ui-selected");
3327				selectee.selected = false;
3328				selectee.$element.addClass("ui-unselecting");
3329				selectee.unselecting = true;
3330				// selectable UNSELECTING callback
3331				that._trigger("unselecting", event, {
3332					unselecting: selectee.element
3333				});
3334			}
3335		});
3336
3337		$(event.target).parents().addBack().each(function() {
3338			var doSelect,
3339				selectee = $.data(this, "selectable-item");
3340			if (selectee) {
3341				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3342				selectee.$element
3343					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3344					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3345				selectee.unselecting = !doSelect;
3346				selectee.selecting = doSelect;
3347				selectee.selected = doSelect;
3348				// selectable (UN)SELECTING callback
3349				if (doSelect) {
3350					that._trigger("selecting", event, {
3351						selecting: selectee.element
3352					});
3353				} else {
3354					that._trigger("unselecting", event, {
3355						unselecting: selectee.element
3356					});
3357				}
3358				return false;
3359			}
3360		});
3361
3362	},
3363
3364	_mouseDrag: function(event) {
3365
3366		this.dragged = true;
3367
3368		if (this.options.disabled) {
3369			return;
3370		}
3371
3372		var tmp,
3373			that = this,
3374			options = this.options,
3375			x1 = this.opos[0],
3376			y1 = this.opos[1],
3377			x2 = event.pageX,
3378			y2 = event.pageY;
3379
3380		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3381		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3382		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3383
3384		this.selectees.each(function() {
3385			var selectee = $.data(this, "selectable-item"),
3386				hit = false;
3387
3388			//prevent helper from being selected if appendTo: selectable
3389			if (!selectee || selectee.element === that.element[0]) {
3390				return;
3391			}
3392
3393			if (options.tolerance === "touch") {
3394				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3395			} else if (options.tolerance === "fit") {
3396				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3397			}
3398
3399			if (hit) {
3400				// SELECT
3401				if (selectee.selected) {
3402					selectee.$element.removeClass("ui-selected");
3403					selectee.selected = false;
3404				}
3405				if (selectee.unselecting) {
3406					selectee.$element.removeClass("ui-unselecting");
3407					selectee.unselecting = false;
3408				}
3409				if (!selectee.selecting) {
3410					selectee.$element.addClass("ui-selecting");
3411					selectee.selecting = true;
3412					// selectable SELECTING callback
3413					that._trigger("selecting", event, {
3414						selecting: selectee.element
3415					});
3416				}
3417			} else {
3418				// UNSELECT
3419				if (selectee.selecting) {
3420					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3421						selectee.$element.removeClass("ui-selecting");
3422						selectee.selecting = false;
3423						selectee.$element.addClass("ui-selected");
3424						selectee.selected = true;
3425					} else {
3426						selectee.$element.removeClass("ui-selecting");
3427						selectee.selecting = false;
3428						if (selectee.startselected) {
3429							selectee.$element.addClass("ui-unselecting");
3430							selectee.unselecting = true;
3431						}
3432						// selectable UNSELECTING callback
3433						that._trigger("unselecting", event, {
3434							unselecting: selectee.element
3435						});
3436					}
3437				}
3438				if (selectee.selected) {
3439					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3440						selectee.$element.removeClass("ui-selected");
3441						selectee.selected = false;
3442
3443						selectee.$element.addClass("ui-unselecting");
3444						selectee.unselecting = true;
3445						// selectable UNSELECTING callback
3446						that._trigger("unselecting", event, {
3447							unselecting: selectee.element
3448						});
3449					}
3450				}
3451			}
3452		});
3453
3454		return false;
3455	},
3456
3457	_mouseStop: function(event) {
3458		var that = this;
3459
3460		this.dragged = false;
3461
3462		$(".ui-unselecting", this.element[0]).each(function() {
3463			var selectee = $.data(this, "selectable-item");
3464			selectee.$element.removeClass("ui-unselecting");
3465			selectee.unselecting = false;
3466			selectee.startselected = false;
3467			that._trigger("unselected", event, {
3468				unselected: selectee.element
3469			});
3470		});
3471		$(".ui-selecting", this.element[0]).each(function() {
3472			var selectee = $.data(this, "selectable-item");
3473			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3474			selectee.selecting = false;
3475			selectee.selected = true;
3476			selectee.startselected = true;
3477			that._trigger("selected", event, {
3478				selected: selectee.element
3479			});
3480		});
3481		this._trigger("stop", event);
3482
3483		this.helper.remove();
3484
3485		return false;
3486	}
3487
3488});
3489
3490})(jQuery);
3491
3492(function( $, undefined ) {
3493
3494/*jshint loopfunc: true */
3495
3496function isOverAxis( x, reference, size ) {
3497	return ( x > reference ) && ( x < ( reference + size ) );
3498}
3499
3500$.widget("ui.sortable", $.ui.mouse, {
3501	version: "1.10.1",
3502	widgetEventPrefix: "sort",
3503	ready: false,
3504	options: {
3505		appendTo: "parent",
3506		axis: false,
3507		connectWith: false,
3508		containment: false,
3509		cursor: "auto",
3510		cursorAt: false,
3511		dropOnEmpty: true,
3512		forcePlaceholderSize: false,
3513		forceHelperSize: false,
3514		grid: false,
3515		handle: false,
3516		helper: "original",
3517		items: "> *",
3518		opacity: false,
3519		placeholder: false,
3520		revert: false,
3521		scroll: true,
3522		scrollSensitivity: 20,
3523		scrollSpeed: 20,
3524		scope: "default",
3525		tolerance: "intersect",
3526		zIndex: 1000,
3527
3528		// callbacks
3529		activate: null,
3530		beforeStop: null,
3531		change: null,
3532		deactivate: null,
3533		out: null,
3534		over: null,
3535		receive: null,
3536		remove: null,
3537		sort: null,
3538		start: null,
3539		stop: null,
3540		update: null
3541	},
3542	_create: function() {
3543
3544		var o = this.options;
3545		this.containerCache = {};
3546		this.element.addClass("ui-sortable");
3547
3548		//Get the items
3549		this.refresh();
3550
3551		//Let's determine if the items are being displayed horizontally
3552		this.floating = this.items.length ? o.axis === "x" || (/left|right/).test(this.items[0].item.css("float")) || (/inline|table-cell/).test(this.items[0].item.css("display")) : false;
3553
3554		//Let's determine the parent's offset
3555		this.offset = this.element.offset();
3556
3557		//Initialize mouse events for interaction
3558		this._mouseInit();
3559
3560		//We're ready to go
3561		this.ready = true;
3562
3563	},
3564
3565	_destroy: function() {
3566		this.element
3567			.removeClass("ui-sortable ui-sortable-disabled");
3568		this._mouseDestroy();
3569
3570		for ( var i = this.items.length - 1; i >= 0; i-- ) {
3571			this.items[i].item.removeData(this.widgetName + "-item");
3572		}
3573
3574		return this;
3575	},
3576
3577	_setOption: function(key, value){
3578		if ( key === "disabled" ) {
3579			this.options[ key ] = value;
3580
3581			this.widget().toggleClass( "ui-sortable-disabled", !!value );
3582		} else {
3583			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3584			$.Widget.prototype._setOption.apply(this, arguments);
3585		}
3586	},
3587
3588	_mouseCapture: function(event, overrideHandle) {
3589		var currentItem = null,
3590			validHandle = false,
3591			that = this;
3592
3593		if (this.reverting) {
3594			return false;
3595		}
3596
3597		if(this.options.disabled || this.options.type === "static") {
3598			return false;
3599		}
3600
3601		//We have to refresh the items data once first
3602		this._refreshItems(event);
3603
3604		//Find out if the clicked node (or one of its parents) is a actual item in this.items
3605		$(event.target).parents().each(function() {
3606			if($.data(this, that.widgetName + "-item") === that) {
3607				currentItem = $(this);
3608				return false;
3609			}
3610		});
3611		if($.data(event.target, that.widgetName + "-item") === that) {
3612			currentItem = $(event.target);
3613		}
3614
3615		if(!currentItem) {
3616			return false;
3617		}
3618		if(this.options.handle && !overrideHandle) {
3619			$(this.options.handle, currentItem).find("*").addBack().each(function() {
3620				if(this === event.target) {
3621					validHandle = true;
3622				}
3623			});
3624			if(!validHandle) {
3625				return false;
3626			}
3627		}
3628
3629		this.currentItem = currentItem;
3630		this._removeCurrentsFromItems();
3631		return true;
3632
3633	},
3634
3635	_mouseStart: function(event, overrideHandle, noActivation) {
3636
3637		var i,
3638			o = this.options;
3639
3640		this.currentContainer = this;
3641
3642		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3643		this.refreshPositions();
3644
3645		//Create and append the visible helper
3646		this.helper = this._createHelper(event);
3647
3648		//Cache the helper size
3649		this._cacheHelperProportions();
3650
3651		/*
3652		 * - Position generation -
3653		 * This block generates everything position related - it's the core of draggables.
3654		 */
3655
3656		//Cache the margins of the original element
3657		this._cacheMargins();
3658
3659		//Get the next scrolling parent
3660		this.scrollParent = this.helper.scrollParent();
3661
3662		//The element's absolute position on the page minus margins
3663		this.offset = this.currentItem.offset();
3664		this.offset = {
3665			top: this.offset.top - this.margins.top,
3666			left: this.offset.left - this.margins.left
3667		};
3668
3669		$.extend(this.offset, {
3670			click: { //Where the click happened, relative to the element
3671				left: event.pageX - this.offset.left,
3672				top: event.pageY - this.offset.top
3673			},
3674			parent: this._getParentOffset(),
3675			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3676		});
3677
3678		// Only after we got the offset, we can change the helper's position to absolute
3679		// TODO: Still need to figure out a way to make relative sorting possible
3680		this.helper.css("position", "absolute");
3681		this.cssPosition = this.helper.css("position");
3682
3683		//Generate the original position
3684		this.originalPosition = this._generatePosition(event);
3685		this.originalPageX = event.pageX;
3686		this.originalPageY = event.pageY;
3687
3688		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3689		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3690
3691		//Cache the former DOM position
3692		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3693
3694		//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
3695		if(this.helper[0] !== this.currentItem[0]) {
3696			this.currentItem.hide();
3697		}
3698
3699		//Create the placeholder
3700		this._createPlaceholder();
3701
3702		//Set a containment if given in the options
3703		if(o.containment) {
3704			this._setContainment();
3705		}
3706
3707		if(o.cursor) { // cursor option
3708			if ($("body").css("cursor")) {
3709				this._storedCursor = $("body").css("cursor");
3710			}
3711			$("body").css("cursor", o.cursor);
3712		}
3713
3714		if(o.opacity) { // opacity option
3715			if (this.helper.css("opacity")) {
3716				this._storedOpacity = this.helper.css("opacity");
3717			}
3718			this.helper.css("opacity", o.opacity);
3719		}
3720
3721		if(o.zIndex) { // zIndex option
3722			if (this.helper.css("zIndex")) {
3723				this._storedZIndex = this.helper.css("zIndex");
3724			}
3725			this.helper.css("zIndex", o.zIndex);
3726		}
3727
3728		//Prepare scrolling
3729		if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3730			this.overflowOffset = this.scrollParent.offset();
3731		}
3732
3733		//Call callbacks
3734		this._trigger("start", event, this._uiHash());
3735
3736		//Recache the helper size
3737		if(!this._preserveHelperProportions) {
3738			this._cacheHelperProportions();
3739		}
3740
3741
3742		//Post "activate" events to possible containers
3743		if( !noActivation ) {
3744			for ( i = this.containers.length - 1; i >= 0; i-- ) {
3745				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3746			}
3747		}
3748
3749		//Prepare possible droppables
3750		if($.ui.ddmanager) {
3751			$.ui.ddmanager.current = this;
3752		}
3753
3754		if ($.ui.ddmanager && !o.dropBehaviour) {
3755			$.ui.ddmanager.prepareOffsets(this, event);
3756		}
3757
3758		this.dragging = true;
3759
3760		this.helper.addClass("ui-sortable-helper");
3761		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3762		return true;
3763
3764	},
3765
3766	_mouseDrag: function(event) {
3767		var i, item, itemElement, intersection,
3768			o = this.options,
3769			scrolled = false;
3770
3771		//Compute the helpers position
3772		this.position = this._generatePosition(event);
3773		this.positionAbs = this._convertPositionTo("absolute");
3774
3775		if (!this.lastPositionAbs) {
3776			this.lastPositionAbs = this.positionAbs;
3777		}
3778
3779		//Do scrolling
3780		if(this.options.scroll) {
3781			if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3782
3783				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3784					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3785				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3786					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3787				}
3788
3789				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3790					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3791				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3792					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3793				}
3794
3795			} else {
3796
3797				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
3798					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3799				} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
3800					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3801				}
3802
3803				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
3804					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3805				} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
3806					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3807				}
3808
3809			}
3810
3811			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3812				$.ui.ddmanager.prepareOffsets(this, event);
3813			}
3814		}
3815
3816		//Regenerate the absolute position used for position checks
3817		this.positionAbs = this._convertPositionTo("absolute");
3818
3819		//Set the helper position
3820		if(!this.options.axis || this.options.axis !== "y") {
3821			this.helper[0].style.left = this.position.left+"px";
3822		}
3823		if(!this.options.axis || this.options.axis !== "x") {
3824			this.helper[0].style.top = this.position.top+"px";
3825		}
3826
3827		//Rearrange
3828		for (i = this.items.length - 1; i >= 0; i--) {
3829
3830			//Cache variables and intersection, continue if no intersection
3831			item = this.items[i];
3832			itemElement = item.item[0];
3833			intersection = this._intersectsWithPointer(item);
3834			if (!intersection) {
3835				continue;
3836			}
3837
3838			// Only put the placeholder inside the current Container, skip all
3839			// items form other containers. This works because when moving
3840			// an item from one container to another the
3841			// currentContainer is switched before the placeholder is moved.
3842			//
3843			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
3844			// beetween the outer and inner container.
3845			if (item.instance !== this.currentContainer) {
3846				continue;
3847			}
3848
3849			// cannot intersect with itself
3850			// no useless actions that have been done before
3851			// no action if the item moved is the parent of the item checked
3852			if (itemElement !== this.currentItem[0] &&
3853				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3854				!$.contains(this.placeholder[0], itemElement) &&
3855				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3856			) {
3857
3858				this.direction = intersection === 1 ? "down" : "up";
3859
3860				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3861					this._rearrange(event, item);
3862				} else {
3863					break;
3864				}
3865
3866				this._trigger("change", event, this._uiHash());
3867				break;
3868			}
3869		}
3870
3871		//Post events to containers
3872		this._contactContainers(event);
3873
3874		//Interconnect with droppables
3875		if($.ui.ddmanager) {
3876			$.ui.ddmanager.drag(this, event);
3877		}
3878
3879		//Call callbacks
3880		this._trigger("sort", event, this._uiHash());
3881
3882		this.lastPositionAbs = this.positionAbs;
3883		return false;
3884
3885	},
3886
3887	_mouseStop: function(event, noPropagation) {
3888
3889		if(!event) {
3890			return;
3891		}
3892
3893		//If we are using droppables, inform the manager about the drop
3894		if ($.ui.ddmanager && !this.options.dropBehaviour) {
3895			$.ui.ddmanager.drop(this, event);
3896		}
3897
3898		if(this.options.revert) {
3899			var that = this,
3900				cur = this.placeholder.offset();
3901
3902			this.reverting = true;
3903
3904			$(this.helper).animate({
3905				left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft),
3906				top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop)
3907			}, parseInt(this.options.revert, 10) || 500, function() {
3908				that._clear(event);
3909			});
3910		} else {
3911			this._clear(event, noPropagation);
3912		}
3913
3914		return false;
3915
3916	},
3917
3918	cancel: function() {
3919
3920		if(this.dragging) {
3921
3922			this._mouseUp({ target: null });
3923
3924			if(this.options.helper === "original") {
3925				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3926			} else {
3927				this.currentItem.show();
3928			}
3929
3930			//Post deactivating events to containers
3931			for (var i = this.containers.length - 1; i >= 0; i--){
3932				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3933				if(this.containers[i].containerCache.over) {
3934					this.containers[i]._trigger("out", null, this._uiHash(this));
3935					this.containers[i].containerCache.over = 0;
3936				}
3937			}
3938
3939		}
3940
3941		if (this.placeholder) {
3942			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3943			if(this.placeholder[0].parentNode) {
3944				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3945			}
3946			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3947				this.helper.remove();
3948			}
3949
3950			$.extend(this, {
3951				helper: null,
3952				dragging: false,
3953				reverting: false,
3954				_noFinalSort: null
3955			});
3956
3957			if(this.domPosition.prev) {
3958				$(this.domPosition.prev).after(this.currentItem);
3959			} else {
3960				$(this.domPosition.parent).prepend(this.currentItem);
3961			}
3962		}
3963
3964		return this;
3965
3966	},
3967
3968	serialize: function(o) {
3969
3970		var items = this._getItemsAsjQuery(o && o.connected),
3971			str = [];
3972		o = o || {};
3973
3974		$(items).each(function() {
3975			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
3976			if (res) {
3977				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
3978			}
3979		});
3980
3981		if(!str.length && o.key) {
3982			str.push(o.key + "=");
3983		}
3984
3985		return str.join("&");
3986
3987	},
3988
3989	toArray: function(o) {
3990
3991		var items = this._getItemsAsjQuery(o && o.connected),
3992			ret = [];
3993
3994		o = o || {};
3995
3996		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
3997		return ret;
3998
3999	},
4000
4001	/* Be careful with the following core functions */
4002	_intersectsWith: function(item) {
4003
4004		var x1 = this.positionAbs.left,
4005			x2 = x1 + this.helperProportions.width,
4006			y1 = this.positionAbs.top,
4007			y2 = y1 + this.helperProportions.height,
4008			l = item.left,
4009			r = l + item.width,
4010			t = item.top,
4011			b = t + item.height,
4012			dyClick = this.offset.click.top,
4013			dxClick = this.offset.click.left,
4014			isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
4015
4016		if ( this.options.tolerance === "pointer" ||
4017			this.options.forcePointerForContainers ||
4018			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4019		) {
4020			return isOverElement;
4021		} else {
4022
4023			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4024				x2 - (this.helperProportions.width / 2) < r && // Left Half
4025				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4026				y2 - (this.helperProportions.height / 2) < b ); // Top Half
4027
4028		}
4029	},
4030
4031	_intersectsWithPointer: function(item) {
4032
4033		var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4034			isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4035			isOverElement = isOverElementHeight && isOverElementWidth,
4036			verticalDirection = this._getDragVerticalDirection(),
4037			horizontalDirection = this._getDragHorizontalDirection();
4038
4039		if (!isOverElement) {
4040			return false;
4041		}
4042
4043		return this.floating ?
4044			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4045			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4046
4047	},
4048
4049	_intersectsWithSides: function(item) {
4050
4051		var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4052			isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4053			verticalDirection = this._getDragVerticalDirection(),
4054			horizontalDirection = this._getDragHorizontalDirection();
4055
4056		if (this.floating && horizontalDirection) {
4057			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4058		} else {
4059			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4060		}
4061
4062	},
4063
4064	_getDragVerticalDirection: function() {
4065		var delta = this.positionAbs.top - this.lastPositionAbs.top;
4066		return delta !== 0 && (delta > 0 ? "down" : "up");
4067	},
4068
4069	_getDragHorizontalDirection: function() {
4070		var delta = this.positionAbs.left - this.lastPositionAbs.left;
4071		return delta !== 0 && (delta > 0 ? "right" : "left");
4072	},
4073
4074	refresh: function(event) {
4075		this._refreshItems(event);
4076		this.refreshPositions();
4077		return this;
4078	},
4079
4080	_connectWith: function() {
4081		var options = this.options;
4082		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4083	},
4084
4085	_getItemsAsjQuery: function(connected) {
4086
4087		var i, j, cur, inst,
4088			items = [],
4089			queries = [],
4090			connectWith = this._connectWith();
4091
4092		if(connectWith && connected) {
4093			for (i = connectWith.length - 1; i >= 0; i--){
4094				cur = $(connectWith[i]);
4095				for ( j = cur.length - 1; j >= 0; j--){
4096					inst = $.data(cur[j], this.widgetFullName);
4097					if(inst && inst !== this && !inst.options.disabled) {
4098						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]);
4099					}
4100				}
4101			}
4102		}
4103
4104		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]);
4105
4106		for (i = queries.length - 1; i >= 0; i--){
4107			queries[i][0].each(function() {
4108				items.push(this);
4109			});
4110		}
4111
4112		return $(items);
4113
4114	},
4115
4116	_removeCurrentsFromItems: function() {
4117
4118		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4119
4120		this.items = $.grep(this.items, function (item) {
4121			for (var j=0; j < list.length; j++) {
4122				if(list[j] === item.item[0]) {
4123					return false;
4124				}
4125			}
4126			return true;
4127		});
4128
4129	},
4130
4131	_refreshItems: function(event) {
4132
4133		this.items = [];
4134		this.containers = [this];
4135
4136		var i, j, cur, inst, targetData, _queries, item, queriesLength,
4137			items = this.items,
4138			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4139			connectWith = this._connectWith();
4140
4141		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4142			for (i = connectWith.length - 1; i >= 0; i--){
4143				cur = $(connectWith[i]);
4144				for (j = cur.length - 1; j >= 0; j--){
4145					inst = $.data(cur[j], this.widgetFullName);
4146					if(inst && inst !== this && !inst.options.disabled) {
4147						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4148						this.containers.push(inst);
4149					}
4150				}
4151			}
4152		}
4153
4154		for (i = queries.length - 1; i >= 0; i--) {
4155			targetData = queries[i][1];
4156			_queries = queries[i][0];
4157
4158			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4159				item = $(_queries[j]);
4160
4161				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4162
4163				items.push({
4164					item: item,
4165					instance: targetData,
4166					width: 0, height: 0,
4167					left: 0, top: 0
4168				});
4169			}
4170		}
4171
4172	},
4173
4174	refreshPositions: function(fast) {
4175
4176		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4177		if(this.offsetParent && this.helper) {
4178			this.offset.parent = this._getParentOffset();
4179		}
4180
4181		var i, item, t, p;
4182
4183		for (i = this.items.length - 1; i >= 0; i--){
4184			item = this.items[i];
4185
4186			//We ignore calculating positions of all connected containers when we're not over them
4187			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4188				continue;
4189			}
4190
4191			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4192
4193			if (!fast) {
4194				item.width = t.outerWidth();
4195				item.height = t.outerHeight();
4196			}
4197
4198			p = t.offset();
4199			item.left = p.left;
4200			item.top = p.top;
4201		}
4202
4203		if(this.options.custom && this.options.custom.refreshContainers) {
4204			this.options.custom.refreshContainers.call(this);
4205		} else {
4206			for (i = this.containers.length - 1; i >= 0; i--){
4207				p = this.containers[i].element.offset();
4208				this.containers[i].containerCache.left = p.left;
4209				this.containers[i].containerCache.top = p.top;
4210				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
4211				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4212			}
4213		}
4214
4215		return this;
4216	},
4217
4218	_createPlaceholder: function(that) {
4219		that = that || this;
4220		var className,
4221			o = that.options;
4222
4223		if(!o.placeholder || o.placeholder.constructor === String) {
4224			className = o.placeholder;
4225			o.placeholder = {
4226				element: function() {
4227
4228					var el = $(document.createElement(that.currentItem[0].nodeName))
4229						.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4230						.removeClass("ui-sortable-helper")[0];
4231
4232					if(!className) {
4233						el.style.visibility = "hidden";
4234					}
4235
4236					return el;
4237				},
4238				update: function(container, p) {
4239
4240					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4241					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4242					if(className && !o.forcePlaceholderSize) {
4243						return;
4244					}
4245
4246					//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
4247					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4248					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4249				}
4250			};
4251		}
4252
4253		//Create the placeholder
4254		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4255
4256		//Append it after the actual current item
4257		that.currentItem.after(that.placeholder);
4258
4259		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4260		o.placeholder.update(that, that.placeholder);
4261
4262	},
4263
4264	_contactContainers: function(event) {
4265		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom,
4266			innermostContainer = null,
4267			innermostIndex = null;
4268
4269		// get innermost container that intersects with item
4270		for (i = this.containers.length - 1; i >= 0; i--) {
4271
4272			// never consider a container that's located within the item itself
4273			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4274				continue;
4275			}
4276
4277			if(this._intersectsWith(this.containers[i].containerCache)) {
4278
4279				// if we've already found a container and it's more "inner" than this, then continue
4280				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4281					continue;
4282				}
4283
4284				innermostContainer = this.containers[i];
4285				innermostIndex = i;
4286
4287			} else {
4288				// container doesn't intersect. trigger "out" event if necessary
4289				if(this.containers[i].containerCache.over) {
4290					this.containers[i]._trigger("out", event, this._uiHash(this));
4291					this.containers[i].containerCache.over = 0;
4292				}
4293			}
4294
4295		}
4296
4297		// if no intersecting containers found, return
4298		if(!innermostContainer) {
4299			return;
4300		}
4301
4302		// move the item into the container if it's not there already
4303		if(this.containers.length === 1) {
4304			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4305			this.containers[innermostIndex].containerCache.over = 1;
4306		} else {
4307
4308			//When entering a new container, we will find the item with the least distance and append our item near it
4309			dist = 10000;
4310			itemWithLeastDistance = null;
4311			posProperty = this.containers[innermostIndex].floating ? "left" : "top";
4312			sizeProperty = this.containers[innermostIndex].floating ? "width" : "height";
4313			base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4314			for (j = this.items.length - 1; j >= 0; j--) {
4315				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4316					continue;
4317				}
4318				if(this.items[j].item[0] === this.currentItem[0]) {
4319					continue;
4320				}
4321				cur = this.items[j].item.offset()[posProperty];
4322				nearBottom = false;
4323				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4324					nearBottom = true;
4325					cur += this.items[j][sizeProperty];
4326				}
4327
4328				if(Math.abs(cur - base) < dist) {
4329					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4330					this.direction = nearBottom ? "up": "down";
4331				}
4332			}
4333
4334			//Check if dropOnEmpty is enabled
4335			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4336				return;
4337			}
4338
4339			this.currentContainer = this.containers[innermostIndex];
4340			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4341			this._trigger("change", event, this._uiHash());
4342			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4343
4344			//Update the placeholder
4345			this.options.placeholder.update(this.currentContainer, this.placeholder);
4346
4347			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4348			this.containers[innermostIndex].containerCache.over = 1;
4349		}
4350
4351
4352	},
4353
4354	_createHelper: function(event) {
4355
4356		var o = this.options,
4357			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4358
4359		//Add the helper to the DOM if that didn't happen already
4360		if(!helper.parents("body").length) {
4361			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4362		}
4363
4364		if(helper[0] === this.currentItem[0]) {
4365			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
vendor: 4,379 bytes, lines 4365-4482
4365: this.currentItem.css("left") };
4366		}
4367
4368		if(!helper[0].style.width || o.forceHelperSize) {
4369			helper.width(this.currentItem.width());
4370		}
4371		if(!helper[0].style.height || o.forceHelperSize) {
4372			helper.height(this.currentItem.height());
4373		}
4374
4375		return helper;
4376
4377	},
4378
4379	_adjustOffsetFromHelper: function(obj) {
4380		if (typeof obj === "string") {
4381			obj = obj.split(" ");
4382		}
4383		if ($.isArray(obj)) {
4384			obj = {left: +obj[0], top: +obj[1] || 0};
4385		}
4386		if ("left" in obj) {
4387			this.offset.click.left = obj.left + this.margins.left;
4388		}
4389		if ("right" in obj) {
4390			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4391		}
4392		if ("top" in obj) {
4393			this.offset.click.top = obj.top + this.margins.top;
4394		}
4395		if ("bottom" in obj) {
4396			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4397		}
4398	},
4399
4400	_getParentOffset: function() {
4401
4402
4403		//Get the offsetParent and cache its position
4404		this.offsetParent = this.helper.offsetParent();
4405		var po = this.offsetParent.offset();
4406
4407		// This is a special case where we need to modify a offset calculated on start, since the following happened:
4408		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4409		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4410		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4411		if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4412			po.left += this.scrollParent.scrollLeft();
4413			po.top += this.scrollParent.scrollTop();
4414		}
4415
4416		// This needs to be actually done for all browsers, since pageX/pageY includes this information
4417		// with an ugly IE fix
4418		if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4419			po = { top: 0, left: 0 };
4420		}
4421
4422		return {
4423			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4424			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4425		};
4426
4427	},
4428
4429	_getRelativeOffset: function() {
4430
4431		if(this.cssPosition === "relative") {
4432			var p = this.currentItem.position();
4433			return {
4434				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4435				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4436			};
4437		} else {
4438			return { top: 0, left: 0 };
4439		}
4440
4441	},
4442
4443	_cacheMargins: function() {
4444		this.margins = {
4445			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4446			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4447		};
4448	},
4449
4450	_cacheHelperProportions: function() {
4451		this.helperProportions = {
4452			width: this.helper.outerWidth(),
4453			height: this.helper.outerHeight()
4454		};
4455	},
4456
4457	_setContainment: function() {
4458
4459		var ce, co, over,
4460			o = this.options;
4461		if(o.containment === "parent") {
4462			o.containment = this.helper[0].parentNode;
4463		}
4464		if(o.containment === "document" || o.containment === "window") {
4465			this.containment = [
4466				0 - this.offset.relative.left - this.offset.parent.left,
4467				0 - this.offset.relative.top - this.offset.parent.top,
4468				$(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4469				($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4470			];
4471		}
4472
4473		if(!(/^(document|window|parent)$/).test(o.containment)) {
4474			ce = $(o.containment)[0];
4475			co = $(o.containment).offset();
4476			over = ($(ce).css("overflow") !== "hidden");
4477
4478			this.containment = [
4479				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4480				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4481				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,
4482				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
vendor: 5,508 bytes, lines 4482-4594
448210) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4483			];
4484		}
4485
4486	},
4487
4488	_convertPositionTo: function(d, pos) {
4489
4490		if(!pos) {
4491			pos = this.position;
4492		}
4493		var mod = d === "absolute" ? 1 : -1,
4494			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4495			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4496
4497		return {
4498			top: (
4499				pos.top	+																// The absolute mouse position
4500				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
4501				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
4502				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4503			),
4504			left: (
4505				pos.left +																// The absolute mouse position
4506				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
4507				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
4508				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4509			)
4510		};
4511
4512	},
4513
4514	_generatePosition: function(event) {
4515
4516		var top, left,
4517			o = this.options,
4518			pageX = event.pageX,
4519			pageY = event.pageY,
4520			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);
4521
4522		// This is another very weird special case that only happens for relative elements:
4523		// 1. If the css position is relative
4524		// 2. and the scroll parent is the document or similar to the offset parent
4525		// we have to refresh the relative offset during the scroll so there are no jumps
4526		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
4527			this.offset.relative = this._getRelativeOffset();
4528		}
4529
4530		/*
4531		 * - Position constraining -
4532		 * Constrain the position to a mix of grid, containment.
4533		 */
4534
4535		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4536
4537			if(this.containment) {
4538				if(event.pageX - this.offset.click.left < this.containment[0]) {
4539					pageX = this.containment[0] + this.offset.click.left;
4540				}
4541				if(event.pageY - this.offset.click.top < this.containment[1]) {
4542					pageY = this.containment[1] + this.offset.click.top;
4543				}
4544				if(event.pageX - this.offset.click.left > this.containment[2]) {
4545					pageX = this.containment[2] + this.offset.click.left;
4546				}
4547				if(event.pageY - this.offset.click.top > this.containment[3]) {
4548					pageY = this.containment[3] + this.offset.click.top;
4549				}
4550			}
4551
4552			if(o.grid) {
4553				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4554				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;
4555
4556				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4557				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;
4558			}
4559
4560		}
4561
4562		return {
4563			top: (
4564				pageY -																// The absolute mouse position
4565				this.offset.click.top -													// Click offset (relative to the element)
4566				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
4567				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
4568				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4569			),
4570			left: (
4571				pageX -																// The absolute mouse position
4572				this.offset.click.left -												// Click offset (relative to the element)
4573				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
4574				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
4575				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4576			)
4577		};
4578
4579	},
4580
4581	_rearrange: function(event, i, a, hardRefresh) {
4582
4583		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));
4584
4585		//Various things done here to improve the performance:
4586		// 1. we create a setTimeout, that calls refreshPositions
4587		// 2. on the instance, we have a counter variable, that get's higher after every append
4588		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4589		// 4. this lets only the last addition to the timeout stack through
4590		this.counter = this.counter ? ++this.counter : 1;
4591		var counter = this.counter;
4592
4593		this._delay(function() {
4594			if(counter === this.counter) {
vendor: 3,274 bytes, lines 4595-4677
4595				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4596			}
4597		});
4598
4599	},
4600
4601	_clear: function(event, noPropagation) {
4602
4603		this.reverting = false;
4604		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
4605		// everything else normalized again
4606		var i,
4607			delayedTriggers = [];
4608
4609		// We first have to update the dom position of the actual currentItem
4610		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4611		if(!this._noFinalSort && this.currentItem.parent().length) {
4612			this.placeholder.before(this.currentItem);
4613		}
4614		this._noFinalSort = null;
4615
4616		if(this.helper[0] === this.currentItem[0]) {
4617			for(i in this._storedCSS) {
4618				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4619					this._storedCSS[i] = "";
4620				}
4621			}
4622			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4623		} else {
4624			this.currentItem.show();
4625		}
4626
4627		if(this.fromOutside && !noPropagation) {
4628			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4629		}
4630		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4631			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4632		}
4633
4634		// Check if the items Container has Changed and trigger appropriate
4635		// events.
4636		if (this !== this.currentContainer) {
4637			if(!noPropagation) {
4638				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4639				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4640				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4641			}
4642		}
4643
4644
4645		//Post events to containers
4646		for (i = this.containers.length - 1; i >= 0; i--){
4647			if(!noPropagation) {
4648				delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4649			}
4650			if(this.containers[i].containerCache.over) {
4651				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4652				this.containers[i].containerCache.over = 0;
4653			}
4654		}
4655
4656		//Do what was originally in plugins
4657		if(this._storedCursor) {
4658			$("body").css("cursor", this._storedCursor);
4659		}
4660		if(this._storedOpacity) {
4661			this.helper.css("opacity", this._storedOpacity);
4662		}
4663		if(this._storedZIndex) {
4664			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4665		}
4666
4667		this.dragging = false;
4668		if(this.cancelHelperRemoval) {
4669			if(!noPropagation) {
4670				this._trigger("beforeStop", event, this._uiHash());
4671				for (i=0; i < delayedTriggers.length; i++) {
4672					delayedTriggers[i].call(this, event);
4673				} //Trigger all delayed events
4674				this._trigger("stop", event, this._uiHash());
4675			}
4676
4677			this.fromOutside = false;
vendor: 77,299 bytes, lines 4678-7594
4678			return false;
4679		}
4680
4681		if(!noPropagation) {
4682			this._trigger("beforeStop", event, this._uiHash());
4683		}
4684
4685		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4686		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4687
4688		if(this.helper[0] !== this.currentItem[0]) {
4689			this.helper.remove();
4690		}
4691		this.helper = null;
4692
4693		if(!noPropagation) {
4694			for (i=0; i < delayedTriggers.length; i++) {
4695				delayedTriggers[i].call(this, event);
4696			} //Trigger all delayed events
4697			this._trigger("stop", event, this._uiHash());
4698		}
4699
4700		this.fromOutside = false;
4701		return true;
4702
4703	},
4704
4705	_trigger: function() {
4706		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4707			this.cancel();
4708		}
4709	},
4710
4711	_uiHash: function(_inst) {
4712		var inst = _inst || this;
4713		return {
4714			helper: inst.helper,
4715			placeholder: inst.placeholder || $([]),
4716			position: inst.position,
4717			originalPosition: inst.originalPosition,
4718			offset: inst.positionAbs,
4719			item: inst.currentItem,
4720			sender: _inst ? _inst.element : null
4721		};
4722	}
4723
4724});
4725
4726})(jQuery);
4727
4728;(jQuery.effects || (function($, undefined) {
4729
4730var dataSpace = "ui-effects-";
4731
4732$.effects = {
4733	effect: {}
4734};
4735
4736/*!
4737 * jQuery Color Animations v2.1.2
4738 * https://github.com/jquery/jquery-color
4739 *
4740 * Copyright 2013 jQuery Foundation and other contributors
4741 * Released under the MIT license.
4742 * http://jquery.org/license
4743 *
4744 * Date: Wed Jan 16 08:47:09 2013 -0600
4745 */
4746(function( jQuery, undefined ) {
4747
4748	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
4749
4750	// plusequals test for += 100 -= 100
4751	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4752	// a set of RE's that can match strings and generate color tuples.
4753	stringParsers = [{
4754			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4755			parse: function( execResult ) {
4756				return [
4757					execResult[ 1 ],
4758					execResult[ 2 ],
4759					execResult[ 3 ],
4760					execResult[ 4 ]
4761				];
4762			}
4763		}, {
4764			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4765			parse: function( execResult ) {
4766				return [
4767					execResult[ 1 ] * 2.55,
4768					execResult[ 2 ] * 2.55,
4769					execResult[ 3 ] * 2.55,
4770					execResult[ 4 ]
4771				];
4772			}
4773		}, {
4774			// this regex ignores A-F because it's compared against an already lowercased string
4775			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4776			parse: function( execResult ) {
4777				return [
4778					parseInt( execResult[ 1 ], 16 ),
4779					parseInt( execResult[ 2 ], 16 ),
4780					parseInt( execResult[ 3 ], 16 )
4781				];
4782			}
4783		}, {
4784			// this regex ignores A-F because it's compared against an already lowercased string
4785			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4786			parse: function( execResult ) {
4787				return [
4788					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4789					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4790					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4791				];
4792			}
4793		}, {
4794			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4795			space: "hsla",
4796			parse: function( execResult ) {
4797				return [
4798					execResult[ 1 ],
4799					execResult[ 2 ] / 100,
4800					execResult[ 3 ] / 100,
4801					execResult[ 4 ]
4802				];
4803			}
4804		}],
4805
4806	// jQuery.Color( )
4807	color = jQuery.Color = function( color, green, blue, alpha ) {
4808		return new jQuery.Color.fn.parse( color, green, blue, alpha );
4809	},
4810	spaces = {
4811		rgba: {
4812			props: {
4813				red: {
4814					idx: 0,
4815					type: "byte"
4816				},
4817				green: {
4818					idx: 1,
4819					type: "byte"
4820				},
4821				blue: {
4822					idx: 2,
4823					type: "byte"
4824				}
4825			}
4826		},
4827
4828		hsla: {
4829			props: {
4830				hue: {
4831					idx: 0,
4832					type: "degrees"
4833				},
4834				saturation: {
4835					idx: 1,
4836					type: "percent"
4837				},
4838				lightness: {
4839					idx: 2,
4840					type: "percent"
4841				}
4842			}
4843		}
4844	},
4845	propTypes = {
4846		"byte": {
4847			floor: true,
4848			max: 255
4849		},
4850		"percent": {
4851			max: 1
4852		},
4853		"degrees": {
4854			mod: 360,
4855			floor: true
4856		}
4857	},
4858	support = color.support = {},
4859
4860	// element for support tests
4861	supportElem = jQuery( "<p>" )[ 0 ],
4862
4863	// colors = jQuery.Color.names
4864	colors,
4865
4866	// local aliases of functions called often
4867	each = jQuery.each;
4868
4869// determine rgba support immediately
4870supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4871support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4872
4873// define cache name and alpha properties
4874// for rgba and hsla spaces
4875each( spaces, function( spaceName, space ) {
4876	space.cache = "_" + spaceName;
4877	space.props.alpha = {
4878		idx: 3,
4879		type: "percent",
4880		def: 1
4881	};
4882});
4883
4884function clamp( value, prop, allowEmpty ) {
4885	var type = propTypes[ prop.type ] || {};
4886
4887	if ( value == null ) {
4888		return (allowEmpty || !prop.def) ? null : prop.def;
4889	}
4890
4891	// ~~ is an short way of doing floor for positive numbers
4892	value = type.floor ? ~~value : parseFloat( value );
4893
4894	// IE will pass in empty strings as value for alpha,
4895	// which will hit this case
4896	if ( isNaN( value ) ) {
4897		return prop.def;
4898	}
4899
4900	if ( type.mod ) {
4901		// we add mod before modding to make sure that negatives values
4902		// get converted properly: -10 -> 350
4903		return (value + type.mod) % type.mod;
4904	}
4905
4906	// for now all property types without mod have min and max
4907	return 0 > value ? 0 : type.max < value ? type.max : value;
4908}
4909
4910function stringParse( string ) {
4911	var inst = color(),
4912		rgba = inst._rgba = [];
4913
4914	string = string.toLowerCase();
4915
4916	each( stringParsers, function( i, parser ) {
4917		var parsed,
4918			match = parser.re.exec( string ),
4919			values = match && parser.parse( match ),
4920			spaceName = parser.space || "rgba";
4921
4922		if ( values ) {
4923			parsed = inst[ spaceName ]( values );
4924
4925			// if this was an rgba parse the assignment might happen twice
4926			// oh well....
4927			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
4928			rgba = inst._rgba = parsed._rgba;
4929
4930			// exit each( stringParsers ) here because we matched
4931			return false;
4932		}
4933	});
4934
4935	// Found a stringParser that handled it
4936	if ( rgba.length ) {
4937
4938		// if this came from a parsed string, force "transparent" when alpha is 0
4939		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
4940		if ( rgba.join() === "0,0,0,0" ) {
4941			jQuery.extend( rgba, colors.transparent );
4942		}
4943		return inst;
4944	}
4945
4946	// named colors
4947	return colors[ string ];
4948}
4949
4950color.fn = jQuery.extend( color.prototype, {
4951	parse: function( red, green, blue, alpha ) {
4952		if ( red === undefined ) {
4953			this._rgba = [ null, null, null, null ];
4954			return this;
4955		}
4956		if ( red.jquery || red.nodeType ) {
4957			red = jQuery( red ).css( green );
4958			green = undefined;
4959		}
4960
4961		var inst = this,
4962			type = jQuery.type( red ),
4963			rgba = this._rgba = [];
4964
4965		// more than 1 argument specified - assume ( red, green, blue, alpha )
4966		if ( green !== undefined ) {
4967			red = [ red, green, blue, alpha ];
4968			type = "array";
4969		}
4970
4971		if ( type === "string" ) {
4972			return this.parse( stringParse( red ) || colors._default );
4973		}
4974
4975		if ( type === "array" ) {
4976			each( spaces.rgba.props, function( key, prop ) {
4977				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
4978			});
4979			return this;
4980		}
4981
4982		if ( type === "object" ) {
4983			if ( red instanceof color ) {
4984				each( spaces, function( spaceName, space ) {
4985					if ( red[ space.cache ] ) {
4986						inst[ space.cache ] = red[ space.cache ].slice();
4987					}
4988				});
4989			} else {
4990				each( spaces, function( spaceName, space ) {
4991					var cache = space.cache;
4992					each( space.props, function( key, prop ) {
4993
4994						// if the cache doesn't exist, and we know how to convert
4995						if ( !inst[ cache ] && space.to ) {
4996
4997							// if the value was null, we don't need to copy it
4998							// if the key was alpha, we don't need to copy it either
4999							if ( key === "alpha" || red[ key ] == null ) {
5000								return;
5001							}
5002							inst[ cache ] = space.to( inst._rgba );
5003						}
5004
5005						// this is the only case where we allow nulls for ALL properties.
5006						// call clamp with alwaysAllowEmpty
5007						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
5008					});
5009
5010					// everything defined but alpha?
5011					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
5012						// use the default of 1
5013						inst[ cache ][ 3 ] = 1;
5014						if ( space.from ) {
5015							inst._rgba = space.from( inst[ cache ] );
5016						}
5017					}
5018				});
5019			}
5020			return this;
5021		}
5022	},
5023	is: function( compare ) {
5024		var is = color( compare ),
5025			same = true,
5026			inst = this;
5027
5028		each( spaces, function( _, space ) {
5029			var localCache,
5030				isCache = is[ space.cache ];
5031			if (isCache) {
5032				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
5033				each( space.props, function( _, prop ) {
5034					if ( isCache[ prop.idx ] != null ) {
5035						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
5036						return same;
5037					}
5038				});
5039			}
5040			return same;
5041		});
5042		return same;
5043	},
5044	_space: function() {
5045		var used = [],
5046			inst = this;
5047		each( spaces, function( spaceName, space ) {
5048			if ( inst[ space.cache ] ) {
5049				used.push( spaceName );
5050			}
5051		});
5052		return used.pop();
5053	},
5054	transition: function( other, distance ) {
5055		var end = color( other ),
5056			spaceName = end._space(),
5057			space = spaces[ spaceName ],
5058			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
5059			start = startColor[ space.cache ] || space.to( startColor._rgba ),
5060			result = start.slice();
5061
5062		end = end[ space.cache ];
5063		each( space.props, function( key, prop ) {
5064			var index = prop.idx,
5065				startValue = start[ index ],
5066				endValue = end[ index ],
5067				type = propTypes[ prop.type ] || {};
5068
5069			// if null, don't override start value
5070			if ( endValue === null ) {
5071				return;
5072			}
5073			// if null - use end
5074			if ( startValue === null ) {
5075				result[ index ] = endValue;
5076			} else {
5077				if ( type.mod ) {
5078					if ( endValue - startValue > type.mod / 2 ) {
5079						startValue += type.mod;
5080					} else if ( startValue - endValue > type.mod / 2 ) {
5081						startValue -= type.mod;
5082					}
5083				}
5084				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
5085			}
5086		});
5087		return this[ spaceName ]( result );
5088	},
5089	blend: function( opaque ) {
5090		// if we are already opaque - return ourself
5091		if ( this._rgba[ 3 ] === 1 ) {
5092			return this;
5093		}
5094
5095		var rgb = this._rgba.slice(),
5096			a = rgb.pop(),
5097			blend = color( opaque )._rgba;
5098
5099		return color( jQuery.map( rgb, function( v, i ) {
5100			return ( 1 - a ) * blend[ i ] + a * v;
5101		}));
5102	},
5103	toRgbaString: function() {
5104		var prefix = "rgba(",
5105			rgba = jQuery.map( this._rgba, function( v, i ) {
5106				return v == null ? ( i > 2 ? 1 : 0 ) : v;
5107			});
5108
5109		if ( rgba[ 3 ] === 1 ) {
5110			rgba.pop();
5111			prefix = "rgb(";
5112		}
5113
5114		return prefix + rgba.join() + ")";
5115	},
5116	toHslaString: function() {
5117		var prefix = "hsla(",
5118			hsla = jQuery.map( this.hsla(), function( v, i ) {
5119				if ( v == null ) {
5120					v = i > 2 ? 1 : 0;
5121				}
5122
5123				// catch 1 and 2
5124				if ( i && i < 3 ) {
5125					v = Math.round( v * 100 ) + "%";
5126				}
5127				return v;
5128			});
5129
5130		if ( hsla[ 3 ] === 1 ) {
5131			hsla.pop();
5132			prefix = "hsl(";
5133		}
5134		return prefix + hsla.join() + ")";
5135	},
5136	toHexString: function( includeAlpha ) {
5137		var rgba = this._rgba.slice(),
5138			alpha = rgba.pop();
5139
5140		if ( includeAlpha ) {
5141			rgba.push( ~~( alpha * 255 ) );
5142		}
5143
5144		return "#" + jQuery.map( rgba, function( v ) {
5145
5146			// default to 0 when nulls exist
5147			v = ( v || 0 ).toString( 16 );
5148			return v.length === 1 ? "0" + v : v;
5149		}).join("");
5150	},
5151	toString: function() {
5152		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
5153	}
5154});
5155color.fn.parse.prototype = color.fn;
5156
5157// hsla conversions adapted from:
5158// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
5159
5160function hue2rgb( p, q, h ) {
5161	h = ( h + 1 ) % 1;
5162	if ( h * 6 < 1 ) {
5163		return p + (q - p) * h * 6;
5164	}
5165	if ( h * 2 < 1) {
5166		return q;
5167	}
5168	if ( h * 3 < 2 ) {
5169		return p + (q - p) * ((2/3) - h) * 6;
5170	}
5171	return p;
5172}
5173
5174spaces.hsla.to = function ( rgba ) {
5175	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
5176		return [ null, null, null, rgba[ 3 ] ];
5177	}
5178	var r = rgba[ 0 ] / 255,
5179		g = rgba[ 1 ] / 255,
5180		b = rgba[ 2 ] / 255,
5181		a = rgba[ 3 ],
5182		max = Math.max( r, g, b ),
5183		min = Math.min( r, g, b ),
5184		diff = max - min,
5185		add = max + min,
5186		l = add * 0.5,
5187		h, s;
5188
5189	if ( min === max ) {
5190		h = 0;
5191	} else if ( r === max ) {
5192		h = ( 60 * ( g - b ) / diff ) + 360;
5193	} else if ( g === max ) {
5194		h = ( 60 * ( b - r ) / diff ) + 120;
5195	} else {
5196		h = ( 60 * ( r - g ) / diff ) + 240;
5197	}
5198
5199	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
5200	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
5201	if ( diff === 0 ) {
5202		s = 0;
5203	} else if ( l <= 0.5 ) {
5204		s = diff / add;
5205	} else {
5206		s = diff / ( 2 - add );
5207	}
5208	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
5209};
5210
5211spaces.hsla.from = function ( hsla ) {
5212	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
5213		return [ null, null, null, hsla[ 3 ] ];
5214	}
5215	var h = hsla[ 0 ] / 360,
5216		s = hsla[ 1 ],
5217		l = hsla[ 2 ],
5218		a = hsla[ 3 ],
5219		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
5220		p = 2 * l - q;
5221
5222	return [
5223		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
5224		Math.round( hue2rgb( p, q, h ) * 255 ),
5225		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
5226		a
5227	];
5228};
5229
5230
5231each( spaces, function( spaceName, space ) {
5232	var props = space.props,
5233		cache = space.cache,
5234		to = space.to,
5235		from = space.from;
5236
5237	// makes rgba() and hsla()
5238	color.fn[ spaceName ] = function( value ) {
5239
5240		// generate a cache for this space if it doesn't exist
5241		if ( to && !this[ cache ] ) {
5242			this[ cache ] = to( this._rgba );
5243		}
5244		if ( value === undefined ) {
5245			return this[ cache ].slice();
5246		}
5247
5248		var ret,
5249			type = jQuery.type( value ),
5250			arr = ( type === "array" || type === "object" ) ? value : arguments,
5251			local = this[ cache ].slice();
5252
5253		each( props, function( key, prop ) {
5254			var val = arr[ type === "object" ? key : prop.idx ];
5255			if ( val == null ) {
5256				val = local[ prop.idx ];
5257			}
5258			local[ prop.idx ] = clamp( val, prop );
5259		});
5260
5261		if ( from ) {
5262			ret = color( from( local ) );
5263			ret[ cache ] = local;
5264			return ret;
5265		} else {
5266			return color( local );
5267		}
5268	};
5269
5270	// makes red() green() blue() alpha() hue() saturation() lightness()
5271	each( props, function( key, prop ) {
5272		// alpha is included in more than one space
5273		if ( color.fn[ key ] ) {
5274			return;
5275		}
5276		color.fn[ key ] = function( value ) {
5277			var vtype = jQuery.type( value ),
5278				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
5279				local = this[ fn ](),
5280				cur = local[ prop.idx ],
5281				match;
5282
5283			if ( vtype === "undefined" ) {
5284				return cur;
5285			}
5286
5287			if ( vtype === "function" ) {
5288				value = value.call( this, cur );
5289				vtype = jQuery.type( value );
5290			}
5291			if ( value == null && prop.empty ) {
5292				return this;
5293			}
5294			if ( vtype === "string" ) {
5295				match = rplusequals.exec( value );
5296				if ( match ) {
5297					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
5298				}
5299			}
5300			local[ prop.idx ] = value;
5301			return this[ fn ]( local );
5302		};
5303	});
5304});
5305
5306// add cssHook and .fx.step function for each named hook.
5307// accept a space separated string of properties
5308color.hook = function( hook ) {
5309	var hooks = hook.split( " " );
5310	each( hooks, function( i, hook ) {
5311		jQuery.cssHooks[ hook ] = {
5312			set: function( elem, value ) {
5313				var parsed, curElem,
5314					backgroundColor = "";
5315
5316				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
5317					value = color( parsed || value );
5318					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
5319						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
5320						while (
5321							(backgroundColor === "" || backgroundColor === "transparent") &&
5322							curElem && curElem.style
5323						) {
5324							try {
5325								backgroundColor = jQuery.css( curElem, "backgroundColor" );
5326								curElem = curElem.parentNode;
5327							} catch ( e ) {
5328							}
5329						}
5330
5331						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
5332							backgroundColor :
5333							"_default" );
5334					}
5335
5336					value = value.toRgbaString();
5337				}
5338				try {
5339					elem.style[ hook ] = value;
5340				} catch( e ) {
5341					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
5342				}
5343			}
5344		};
5345		jQuery.fx.step[ hook ] = function( fx ) {
5346			if ( !fx.colorInit ) {
5347				fx.start = color( fx.elem, hook );
5348				fx.end = color( fx.end );
5349				fx.colorInit = true;
5350			}
5351			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
5352		};
5353	});
5354
5355};
5356
5357color.hook( stepHooks );
5358
5359jQuery.cssHooks.borderColor = {
5360	expand: function( value ) {
5361		var expanded = {};
5362
5363		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
5364			expanded[ "border" + part + "Color" ] = value;
5365		});
5366		return expanded;
5367	}
5368};
5369
5370// Basic color names only.
5371// Usage of any of the other color names requires adding yourself or including
5372// jquery.color.svg-names.js.
5373colors = jQuery.Color.names = {
5374	// 4.1. Basic color keywords
5375	aqua: "#00ffff",
5376	black: "#000000",
5377	blue: "#0000ff",
5378	fuchsia: "#ff00ff",
5379	gray: "#808080",
5380	green: "#008000",
5381	lime: "#00ff00",
5382	maroon: "#800000",
5383	navy: "#000080",
5384	olive: "#808000",
5385	purple: "#800080",
5386	red: "#ff0000",
5387	silver: "#c0c0c0",
5388	teal: "#008080",
5389	white: "#ffffff",
5390	yellow: "#ffff00",
5391
5392	// 4.2.3. "transparent" color keyword
5393	transparent: [ null, null, null, 0 ],
5394
5395	_default: "#ffffff"
5396};
5397
5398})( jQuery );
5399
5400
5401/******************************************************************************/
5402/****************************** CLASS ANIMATIONS ******************************/
5403/******************************************************************************/
5404(function() {
5405
5406var classAnimationActions = [ "add", "remove", "toggle" ],
5407	shorthandStyles = {
5408		border: 1,
5409		borderBottom: 1,
5410		borderColor: 1,
5411		borderLeft: 1,
5412		borderRight: 1,
5413		borderTop: 1,
5414		borderWidth: 1,
5415		margin: 1,
5416		padding: 1
5417	};
5418
5419$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
5420	$.fx.step[ prop ] = function( fx ) {
5421		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
5422			jQuery.style( fx.elem, prop, fx.end );
5423			fx.setAttr = true;
5424		}
5425	};
5426});
5427
5428function getElementStyles( elem ) {
5429	var key, len,
5430		style = elem.ownerDocument.defaultView ?
5431			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
5432			elem.currentStyle,
5433		styles = {};
5434
5435	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
5436		len = style.length;
5437		while ( len-- ) {
5438			key = style[ len ];
5439			if ( typeof style[ key ] === "string" ) {
5440				styles[ $.camelCase( key ) ] = style[ key ];
5441			}
5442		}
5443	// support: Opera, IE <9
5444	} else {
5445		for ( key in style ) {
5446			if ( typeof style[ key ] === "string" ) {
5447				styles[ key ] = style[ key ];
5448			}
5449		}
5450	}
5451
5452	return styles;
5453}
5454
5455
5456function styleDifference( oldStyle, newStyle ) {
5457	var diff = {},
5458		name, value;
5459
5460	for ( name in newStyle ) {
5461		value = newStyle[ name ];
5462		if ( oldStyle[ name ] !== value ) {
5463			if ( !shorthandStyles[ name ] ) {
5464				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
5465					diff[ name ] = value;
5466				}
5467			}
5468		}
5469	}
5470
5471	return diff;
5472}
5473
5474// support: jQuery <1.8
5475if ( !$.fn.addBack ) {
5476	$.fn.addBack = function( selector ) {
5477		return this.add( selector == null ?
5478			this.prevObject : this.prevObject.filter( selector )
5479		);
5480	};
5481}
5482
5483$.effects.animateClass = function( value, duration, easing, callback ) {
5484	var o = $.speed( duration, easing, callback );
5485
5486	return this.queue( function() {
5487		var animated = $( this ),
5488			baseClass = animated.attr( "class" ) || "",
5489			applyClassChange,
5490			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
5491
5492		// map the animated objects to store the original styles.
5493		allAnimations = allAnimations.map(function() {
5494			var el = $( this );
5495			return {
5496				el: el,
5497				start: getElementStyles( this )
5498			};
5499		});
5500
5501		// apply class change
5502		applyClassChange = function() {
5503			$.each( classAnimationActions, function(i, action) {
5504				if ( value[ action ] ) {
5505					animated[ action + "Class" ]( value[ action ] );
5506				}
5507			});
5508		};
5509		applyClassChange();
5510
5511		// map all animated objects again - calculate new styles and diff
5512		allAnimations = allAnimations.map(function() {
5513			this.end = getElementStyles( this.el[ 0 ] );
5514			this.diff = styleDifference( this.start, this.end );
5515			return this;
5516		});
5517
5518		// apply original class
5519		animated.attr( "class", baseClass );
5520
5521		// map all animated objects again - this time collecting a promise
5522		allAnimations = allAnimations.map(function() {
5523			var styleInfo = this,
5524				dfd = $.Deferred(),
5525				opts = $.extend({}, o, {
5526					queue: false,
5527					complete: function() {
5528						dfd.resolve( styleInfo );
5529					}
5530				});
5531
5532			this.el.animate( this.diff, opts );
5533			return dfd.promise();
5534		});
5535
5536		// once all animations have completed:
5537		$.when.apply( $, allAnimations.get() ).done(function() {
5538
5539			// set the final class
5540			applyClassChange();
5541
5542			// for each animated element,
5543			// clear all css properties that were animated
5544			$.each( arguments, function() {
5545				var el = this.el;
5546				$.each( this.diff, function(key) {
5547					el.css( key, "" );
5548				});
5549			});
5550
5551			// this is guarnteed to be there if you use jQuery.speed()
5552			// it also handles dequeuing the next anim...
5553			o.complete.call( animated[ 0 ] );
5554		});
5555	});
5556};
5557
5558$.fn.extend({
5559	_addClass: $.fn.addClass,
5560	addClass: function( classNames, speed, easing, callback ) {
5561		return speed ?
5562			$.effects.animateClass.call( this,
5563				{ add: classNames }, speed, easing, callback ) :
5564			this._addClass( classNames );
5565	},
5566
5567	_removeClass: $.fn.removeClass,
5568	removeClass: function( classNames, speed, easing, callback ) {
5569		return arguments.length > 1 ?
5570			$.effects.animateClass.call( this,
5571				{ remove: classNames }, speed, easing, callback ) :
5572			this._removeClass.apply( this, arguments );
5573	},
5574
5575	_toggleClass: $.fn.toggleClass,
5576	toggleClass: function( classNames, force, speed, easing, callback ) {
5577		if ( typeof force === "boolean" || force === undefined ) {
5578			if ( !speed ) {
5579				// without speed parameter
5580				return this._toggleClass( classNames, force );
5581			} else {
5582				return $.effects.animateClass.call( this,
5583					(force ? { add: classNames } : { remove: classNames }),
5584					speed, easing, callback );
5585			}
5586		} else {
5587			// without force parameter
5588			return $.effects.animateClass.call( this,
5589				{ toggle: classNames }, force, speed, easing );
5590		}
5591	},
5592
5593	switchClass: function( remove, add, speed, easing, callback) {
5594		return $.effects.animateClass.call( this, {
5595			add: add,
5596			remove: remove
5597		}, speed, easing, callback );
5598	}
5599});
5600
5601})();
5602
5603/******************************************************************************/
5604/*********************************** EFFECTS **********************************/
5605/******************************************************************************/
5606
5607(function() {
5608
5609$.extend( $.effects, {
5610	version: "1.10.1",
5611
5612	// Saves a set of properties in a data storage
5613	save: function( element, set ) {
5614		for( var i=0; i < set.length; i++ ) {
5615			if ( set[ i ] !== null ) {
5616				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5617			}
5618		}
5619	},
5620
5621	// Restores a set of previously saved properties from a data storage
5622	restore: function( element, set ) {
5623		var val, i;
5624		for( i=0; i < set.length; i++ ) {
5625			if ( set[ i ] !== null ) {
5626				val = element.data( dataSpace + set[ i ] );
5627				// support: jQuery 1.6.2
5628				// http://bugs.jquery.com/ticket/9917
5629				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5630				// We can't differentiate between "" and 0 here, so we just assume
5631				// empty string since it's likely to be a more common value...
5632				if ( val === undefined ) {
5633					val = "";
5634				}
5635				element.css( set[ i ], val );
5636			}
5637		}
5638	},
5639
5640	setMode: function( el, mode ) {
5641		if (mode === "toggle") {
5642			mode = el.is( ":hidden" ) ? "show" : "hide";
5643		}
5644		return mode;
5645	},
5646
5647	// Translates a [top,left] array into a baseline value
5648	// this should be a little more flexible in the future to handle a string & hash
5649	getBaseline: function( origin, original ) {
5650		var y, x;
5651		switch ( origin[ 0 ] ) {
5652			case "top": y = 0; break;
5653			case "middle": y = 0.5; break;
5654			case "bottom": y = 1; break;
5655			default: y = origin[ 0 ] / original.height;
5656		}
5657		switch ( origin[ 1 ] ) {
5658			case "left": x = 0; break;
5659			case "center": x = 0.5; break;
5660			case "right": x = 1; break;
5661			default: x = origin[ 1 ] / original.width;
5662		}
5663		return {
5664			x: x,
5665			y: y
5666		};
5667	},
5668
5669	// Wraps the element around a wrapper that copies position properties
5670	createWrapper: function( element ) {
5671
5672		// if the element is already wrapped, return it
5673		if ( element.parent().is( ".ui-effects-wrapper" )) {
5674			return element.parent();
5675		}
5676
5677		// wrap the element
5678		var props = {
5679				width: element.outerWidth(true),
5680				height: element.outerHeight(true),
5681				"float": element.css( "float" )
5682			},
5683			wrapper = $( "<div></div>" )
5684				.addClass( "ui-effects-wrapper" )
5685				.css({
5686					fontSize: "100%",
5687					background: "transparent",
5688					border: "none",
5689					margin: 0,
5690					padding: 0
5691				}),
5692			// Store the size in case width/height are defined in % - Fixes #5245
5693			size = {
5694				width: element.width(),
5695				height: element.height()
5696			},
5697			active = document.activeElement;
5698
5699		// support: Firefox
5700		// Firefox incorrectly exposes anonymous content
5701		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5702		try {
5703			active.id;
5704		} catch( e ) {
5705			active = document.body;
5706		}
5707
5708		element.wrap( wrapper );
5709
5710		// Fixes #7595 - Elements lose focus when wrapped.
5711		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5712			$( active ).focus();
5713		}
5714
5715		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5716
5717		// transfer positioning properties to the wrapper
5718		if ( element.css( "position" ) === "static" ) {
5719			wrapper.css({ position: "relative" });
5720			element.css({ position: "relative" });
5721		} else {
5722			$.extend( props, {
5723				position: element.css( "position" ),
5724				zIndex: element.css( "z-index" )
5725			});
5726			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5727				props[ pos ] = element.css( pos );
5728				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5729					props[ pos ] = "auto";
5730				}
5731			});
5732			element.css({
5733				position: "relative",
5734				top: 0,
5735				left: 0,
5736				right: "auto",
5737				bottom: "auto"
5738			});
5739		}
5740		element.css(size);
5741
5742		return wrapper.css( props ).show();
5743	},
5744
5745	removeWrapper: function( element ) {
5746		var active = document.activeElement;
5747
5748		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5749			element.parent().replaceWith( element );
5750
5751			// Fixes #7595 - Elements lose focus when wrapped.
5752			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5753				$( active ).focus();
5754			}
5755		}
5756
5757
5758		return element;
5759	},
5760
5761	setTransition: function( element, list, factor, value ) {
5762		value = value || {};
5763		$.each( list, function( i, x ) {
5764			var unit = element.cssUnit( x );
5765			if ( unit[ 0 ] > 0 ) {
5766				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5767			}
5768		});
5769		return value;
5770	}
5771});
5772
5773// return an effect options object for the given parameters:
5774function _normalizeArguments( effect, options, speed, callback ) {
5775
5776	// allow passing all options as the first parameter
5777	if ( $.isPlainObject( effect ) ) {
5778		options = effect;
5779		effect = effect.effect;
5780	}
5781
5782	// convert to an object
5783	effect = { effect: effect };
5784
5785	// catch (effect, null, ...)
5786	if ( options == null ) {
5787		options = {};
5788	}
5789
5790	// catch (effect, callback)
5791	if ( $.isFunction( options ) ) {
5792		callback = options;
5793		speed = null;
5794		options = {};
5795	}
5796
5797	// catch (effect, speed, ?)
5798	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5799		callback = speed;
5800		speed = options;
5801		options = {};
5802	}
5803
5804	// catch (effect, options, callback)
5805	if ( $.isFunction( speed ) ) {
5806		callback = speed;
5807		speed = null;
5808	}
5809
5810	// add options to effect
5811	if ( options ) {
5812		$.extend( effect, options );
5813	}
5814
5815	speed = speed || options.duration;
5816	effect.duration = $.fx.off ? 0 :
5817		typeof speed === "number" ? speed :
5818		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5819		$.fx.speeds._default;
5820
5821	effect.complete = callback || options.complete;
5822
5823	return effect;
5824}
5825
5826function standardSpeed( speed ) {
5827	// valid standard speeds
5828	if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
5829		return true;
5830	}
5831
5832	// invalid strings - treat as "normal" speed
5833	return typeof speed === "string" && !$.effects.effect[ speed ];
5834}
5835
5836$.fn.extend({
5837	effect: function( /* effect, options, speed, callback */ ) {
5838		var args = _normalizeArguments.apply( this, arguments ),
5839			mode = args.mode,
5840			queue = args.queue,
5841			effectMethod = $.effects.effect[ args.effect ];
5842
5843		if ( $.fx.off || !effectMethod ) {
5844			// delegate to the original method (e.g., .show()) if possible
5845			if ( mode ) {
5846				return this[ mode ]( args.duration, args.complete );
5847			} else {
5848				return this.each( function() {
5849					if ( args.complete ) {
5850						args.complete.call( this );
5851					}
5852				});
5853			}
5854		}
5855
5856		function run( next ) {
5857			var elem = $( this ),
5858				complete = args.complete,
5859				mode = args.mode;
5860
5861			function done() {
5862				if ( $.isFunction( complete ) ) {
5863					complete.call( elem[0] );
5864				}
5865				if ( $.isFunction( next ) ) {
5866					next();
5867				}
5868			}
5869
5870			// if the element is hiddden and mode is hide,
5871			// or element is visible and mode is show
5872			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5873				done();
5874			} else {
5875				effectMethod.call( elem[0], args, done );
5876			}
5877		}
5878
5879		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5880	},
5881
5882	_show: $.fn.show,
5883	show: function( speed ) {
5884		if ( standardSpeed( speed ) ) {
5885			return this._show.apply( this, arguments );
5886		} else {
5887			var args = _normalizeArguments.apply( this, arguments );
5888			args.mode = "show";
5889			return this.effect.call( this, args );
5890		}
5891	},
5892
5893	_hide: $.fn.hide,
5894	hide: function( speed ) {
5895		if ( standardSpeed( speed ) ) {
5896			return this._hide.apply( this, arguments );
5897		} else {
5898			var args = _normalizeArguments.apply( this, arguments );
5899			args.mode = "hide";
5900			return this.effect.call( this, args );
5901		}
5902	},
5903
5904	// jQuery core overloads toggle and creates _toggle
5905	__toggle: $.fn.toggle,
5906	toggle: function( speed ) {
5907		if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
5908			return this.__toggle.apply( this, arguments );
5909		} else {
5910			var args = _normalizeArguments.apply( this, arguments );
5911			args.mode = "toggle";
5912			return this.effect.call( this, args );
5913		}
5914	},
5915
5916	// helper functions
5917	cssUnit: function(key) {
5918		var style = this.css( key ),
5919			val = [];
5920
5921		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
5922			if ( style.indexOf( unit ) > 0 ) {
5923				val = [ parseFloat( style ), unit ];
5924			}
5925		});
5926		return val;
5927	}
5928});
5929
5930})();
5931
5932/******************************************************************************/
5933/*********************************** EASING ***********************************/
5934/******************************************************************************/
5935
5936(function() {
5937
5938// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
5939
5940var baseEasings = {};
5941
5942$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
5943	baseEasings[ name ] = function( p ) {
5944		return Math.pow( p, i + 2 );
5945	};
5946});
5947
5948$.extend( baseEasings, {
5949	Sine: function ( p ) {
5950		return 1 - Math.cos( p * Math.PI / 2 );
5951	},
5952	Circ: function ( p ) {
5953		return 1 - Math.sqrt( 1 - p * p );
5954	},
5955	Elastic: function( p ) {
5956		return p === 0 || p === 1 ? p :
5957			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
5958	},
5959	Back: function( p ) {
5960		return p * p * ( 3 * p - 2 );
5961	},
5962	Bounce: function ( p ) {
5963		var pow2,
5964			bounce = 4;
5965
5966		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
5967		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
5968	}
5969});
5970
5971$.each( baseEasings, function( name, easeIn ) {
5972	$.easing[ "easeIn" + name ] = easeIn;
5973	$.easing[ "easeOut" + name ] = function( p ) {
5974		return 1 - easeIn( 1 - p );
5975	};
5976	$.easing[ "easeInOut" + name ] = function( p ) {
5977		return p < 0.5 ?
5978			easeIn( p * 2 ) / 2 :
5979			1 - easeIn( p * -2 + 2 ) / 2;
5980	};
5981});
5982
5983})();
5984
5985})(jQuery));
5986
5987(function( $, undefined ) {
5988
5989var uid = 0,
5990	hideProps = {},
5991	showProps = {};
5992
5993hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
5994	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
5995showProps.height = showProps.paddingTop = showProps.paddingBottom =
5996	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
5997
5998$.widget( "ui.accordion", {
5999	version: "1.10.1",
6000	options: {
6001		active: 0,
6002		animate: {},
6003		collapsible: false,
6004		event: "click",
6005		header: "> li > :first-child,> :not(li):even",
6006		heightStyle: "auto",
6007		icons: {
6008			activeHeader: "ui-icon-triangle-1-s",
6009			header: "ui-icon-triangle-1-e"
6010		},
6011
6012		// callbacks
6013		activate: null,
6014		beforeActivate: null
6015	},
6016
6017	_create: function() {
6018		var options = this.options;
6019		this.prevShow = this.prevHide = $();
6020		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
6021			// ARIA
6022			.attr( "role", "tablist" );
6023
6024		// don't allow collapsible: false and active: false / null
6025		if ( !options.collapsible && (options.active === false || options.active == null) ) {
6026			options.active = 0;
6027		}
6028
6029		this._processPanels();
6030		// handle negative values
6031		if ( options.active < 0 ) {
6032			options.active += this.headers.length;
6033		}
6034		this._refresh();
6035	},
6036
6037	_getCreateEventData: function() {
6038		return {
6039			header: this.active,
6040			panel: !this.active.length ? $() : this.active.next(),
6041			content: !this.active.length ? $() : this.active.next()
6042		};
6043	},
6044
6045	_createIcons: function() {
6046		var icons = this.options.icons;
6047		if ( icons ) {
6048			$( "<span>" )
6049				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
6050				.prependTo( this.headers );
6051			this.active.children( ".ui-accordion-header-icon" )
6052				.removeClass( icons.header )
6053				.addClass( icons.activeHeader );
6054			this.headers.addClass( "ui-accordion-icons" );
6055		}
6056	},
6057
6058	_destroyIcons: function() {
6059		this.headers
6060			.removeClass( "ui-accordion-icons" )
6061			.children( ".ui-accordion-header-icon" )
6062				.remove();
6063	},
6064
6065	_destroy: function() {
6066		var contents;
6067
6068		// clean up main element
6069		this.element
6070			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
6071			.removeAttr( "role" );
6072
6073		// clean up headers
6074		this.headers
6075			.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" )
6076			.removeAttr( "role" )
6077			.removeAttr( "aria-selected" )
6078			.removeAttr( "aria-controls" )
6079			.removeAttr( "tabIndex" )
6080			.each(function() {
6081				if ( /^ui-accordion/.test( this.id ) ) {
6082					this.removeAttribute( "id" );
6083				}
6084			});
6085		this._destroyIcons();
6086
6087		// clean up content panels
6088		contents = this.headers.next()
6089			.css( "display", "" )
6090			.removeAttr( "role" )
6091			.removeAttr( "aria-expanded" )
6092			.removeAttr( "aria-hidden" )
6093			.removeAttr( "aria-labelledby" )
6094			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
6095			.each(function() {
6096				if ( /^ui-accordion/.test( this.id ) ) {
6097					this.removeAttribute( "id" );
6098				}
6099			});
6100		if ( this.options.heightStyle !== "content" ) {
6101			contents.css( "height", "" );
6102		}
6103	},
6104
6105	_setOption: function( key, value ) {
6106		if ( key === "active" ) {
6107			// _activate() will handle invalid values and update this.options
6108			this._activate( value );
6109			return;
6110		}
6111
6112		if ( key === "event" ) {
6113			if ( this.options.event ) {
6114				this._off( this.headers, this.options.event );
6115			}
6116			this._setupEvents( value );
6117		}
6118
6119		this._super( key, value );
6120
6121		// setting collapsible: false while collapsed; open first panel
6122		if ( key === "collapsible" && !value && this.options.active === false ) {
6123			this._activate( 0 );
6124		}
6125
6126		if ( key === "icons" ) {
6127			this._destroyIcons();
6128			if ( value ) {
6129				this._createIcons();
6130			}
6131		}
6132
6133		// #5332 - opacity doesn't cascade to positioned elements in IE
6134		// so we need to add the disabled class to the headers and panels
6135		if ( key === "disabled" ) {
6136			this.headers.add( this.headers.next() )
6137				.toggleClass( "ui-state-disabled", !!value );
6138		}
6139	},
6140
6141	_keydown: function( event ) {
6142		/*jshint maxcomplexity:15*/
6143		if ( event.altKey || event.ctrlKey ) {
6144			return;
6145		}
6146
6147		var keyCode = $.ui.keyCode,
6148			length = this.headers.length,
6149			currentIndex = this.headers.index( event.target ),
6150			toFocus = false;
6151
6152		switch ( event.keyCode ) {
6153			case keyCode.RIGHT:
6154			case keyCode.DOWN:
6155				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6156				break;
6157			case keyCode.LEFT:
6158			case keyCode.UP:
6159				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6160				break;
6161			case keyCode.SPACE:
6162			case keyCode.ENTER:
6163				this._eventHandler( event );
6164				break;
6165			case keyCode.HOME:
6166				toFocus = this.headers[ 0 ];
6167				break;
6168			case keyCode.END:
6169				toFocus = this.headers[ length - 1 ];
6170				break;
6171		}
6172
6173		if ( toFocus ) {
6174			$( event.target ).attr( "tabIndex", -1 );
6175			$( toFocus ).attr( "tabIndex", 0 );
6176			toFocus.focus();
6177			event.preventDefault();
6178		}
6179	},
6180
6181	_panelKeyDown : function( event ) {
6182		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6183			$( event.currentTarget ).prev().focus();
6184		}
6185	},
6186
6187	refresh: function() {
6188		var options = this.options;
6189		this._processPanels();
6190
6191		// was collapsed or no panel
6192		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6193			options.active = false;
6194			this.active = $();
6195		// active false only when collapsible is true
6196		} if ( options.active === false ) {
6197			this._activate( 0 );
6198		// was active, but active panel is gone
6199		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6200			// all remaining panel are disabled
6201			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6202				options.active = false;
6203				this.active = $();
6204			// activate previous panel
6205			} else {
6206				this._activate( Math.max( 0, options.active - 1 ) );
6207			}
6208		// was active, active panel still exists
6209		} else {
6210			// make sure active index is correct
6211			options.active = this.headers.index( this.active );
6212		}
6213
6214		this._destroyIcons();
6215
6216		this._refresh();
6217	},
6218
6219	_processPanels: function() {
6220		this.headers = this.element.find( this.options.header )
6221			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
6222
6223		this.headers.next()
6224			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6225			.filter(":not(.ui-accordion-content-active)")
6226			.hide();
6227	},
6228
6229	_refresh: function() {
6230		var maxHeight,
6231			options = this.options,
6232			heightStyle = options.heightStyle,
6233			parent = this.element.parent(),
6234			accordionId = this.accordionId = "ui-accordion-" +
6235				(this.element.attr( "id" ) || ++uid);
6236
6237		this.active = this._findActive( options.active )
6238			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6239			.removeClass( "ui-corner-all" );
6240		this.active.next()
6241			.addClass( "ui-accordion-content-active" )
6242			.show();
6243
6244		this.headers
6245			.attr( "role", "tab" )
6246			.each(function( i ) {
6247				var header = $( this ),
6248					headerId = header.attr( "id" ),
6249					panel = header.next(),
6250					panelId = panel.attr( "id" );
6251				if ( !headerId ) {
6252					headerId = accordionId + "-header-" + i;
6253					header.attr( "id", headerId );
6254				}
6255				if ( !panelId ) {
6256					panelId = accordionId + "-panel-" + i;
6257					panel.attr( "id", panelId );
6258				}
6259				header.attr( "aria-controls", panelId );
6260				panel.attr( "aria-labelledby", headerId );
6261			})
6262			.next()
6263				.attr( "role", "tabpanel" );
6264
6265		this.headers
6266			.not( this.active )
6267			.attr({
6268				"aria-selected": "false",
6269				tabIndex: -1
6270			})
6271			.next()
6272				.attr({
6273					"aria-expanded": "false",
6274					"aria-hidden": "true"
6275				})
6276				.hide();
6277
6278		// make sure at least one header is in the tab order
6279		if ( !this.active.length ) {
6280			this.headers.eq( 0 ).attr( "tabIndex", 0 );
6281		} else {
6282			this.active.attr({
6283				"aria-selected": "true",
6284				tabIndex: 0
6285			})
6286			.next()
6287				.attr({
6288					"aria-expanded": "true",
6289					"aria-hidden": "false"
6290				});
6291		}
6292
6293		this._createIcons();
6294
6295		this._setupEvents( options.event );
6296
6297		if ( heightStyle === "fill" ) {
6298			maxHeight = parent.height();
6299			this.element.siblings( ":visible" ).each(function() {
6300				var elem = $( this ),
6301					position = elem.css( "position" );
6302
6303				if ( position === "absolute" || position === "fixed" ) {
6304					return;
6305				}
6306				maxHeight -= elem.outerHeight( true );
6307			});
6308
6309			this.headers.each(function() {
6310				maxHeight -= $( this ).outerHeight( true );
6311			});
6312
6313			this.headers.next()
6314				.each(function() {
6315					$( this ).height( Math.max( 0, maxHeight -
6316						$( this ).innerHeight() + $( this ).height() ) );
6317				})
6318				.css( "overflow", "auto" );
6319		} else if ( heightStyle === "auto" ) {
6320			maxHeight = 0;
6321			this.headers.next()
6322				.each(function() {
6323					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6324				})
6325				.height( maxHeight );
6326		}
6327	},
6328
6329	_activate: function( index ) {
6330		var active = this._findActive( index )[ 0 ];
6331
6332		// trying to activate the already active panel
6333		if ( active === this.active[ 0 ] ) {
6334			return;
6335		}
6336
6337		// trying to collapse, simulate a click on the currently active header
6338		active = active || this.active[ 0 ];
6339
6340		this._eventHandler({
6341			target: active,
6342			currentTarget: active,
6343			preventDefault: $.noop
6344		});
6345	},
6346
6347	_findActive: function( selector ) {
6348		return typeof selector === "number" ? this.headers.eq( selector ) : $();
6349	},
6350
6351	_setupEvents: function( event ) {
6352		var events = {
6353			keydown: "_keydown"
6354		};
6355		if ( event ) {
6356			$.each( event.split(" "), function( index, eventName ) {
6357				events[ eventName ] = "_eventHandler";
6358			});
6359		}
6360
6361		this._off( this.headers.add( this.headers.next() ) );
6362		this._on( this.headers, events );
6363		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6364		this._hoverable( this.headers );
6365		this._focusable( this.headers );
6366	},
6367
6368	_eventHandler: function( event ) {
6369		var options = this.options,
6370			active = this.active,
6371			clicked = $( event.currentTarget ),
6372			clickedIsActive = clicked[ 0 ] === active[ 0 ],
6373			collapsing = clickedIsActive && options.collapsible,
6374			toShow = collapsing ? $() : clicked.next(),
6375			toHide = active.next(),
6376			eventData = {
6377				oldHeader: active,
6378				oldPanel: toHide,
6379				newHeader: collapsing ? $() : clicked,
6380				newPanel: toShow
6381			};
6382
6383		event.preventDefault();
6384
6385		if (
6386				// click on active header, but not collapsible
6387				( clickedIsActive && !options.collapsible ) ||
6388				// allow canceling activation
6389				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6390			return;
6391		}
6392
6393		options.active = collapsing ? false : this.headers.index( clicked );
6394
6395		// when the call to ._toggle() comes after the class changes
6396		// it causes a very odd bug in IE 8 (see #6720)
6397		this.active = clickedIsActive ? $() : clicked;
6398		this._toggle( eventData );
6399
6400		// switch classes
6401		// corner classes on the previously active header stay after the animation
6402		active.removeClass( "ui-accordion-header-active ui-state-active" );
6403		if ( options.icons ) {
6404			active.children( ".ui-accordion-header-icon" )
6405				.removeClass( options.icons.activeHeader )
6406				.addClass( options.icons.header );
6407		}
6408
6409		if ( !clickedIsActive ) {
6410			clicked
6411				.removeClass( "ui-corner-all" )
6412				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6413			if ( options.icons ) {
6414				clicked.children( ".ui-accordion-header-icon" )
6415					.removeClass( options.icons.header )
6416					.addClass( options.icons.activeHeader );
6417			}
6418
6419			clicked
6420				.next()
6421				.addClass( "ui-accordion-content-active" );
6422		}
6423	},
6424
6425	_toggle: function( data ) {
6426		var toShow = data.newPanel,
6427			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6428
6429		// handle activating a panel during the animation for another activation
6430		this.prevShow.add( this.prevHide ).stop( true, true );
6431		this.prevShow = toShow;
6432		this.prevHide = toHide;
6433
6434		if ( this.options.animate ) {
6435			this._animate( toShow, toHide, data );
6436		} else {
6437			toHide.hide();
6438			toShow.show();
6439			this._toggleComplete( data );
6440		}
6441
6442		toHide.attr({
6443			"aria-expanded": "false",
6444			"aria-hidden": "true"
6445		});
6446		toHide.prev().attr( "aria-selected", "false" );
6447		// if we're switching panels, remove the old header from the tab order
6448		// if we're opening from collapsed state, remove the previous header from the tab order
6449		// if we're collapsing, then keep the collapsing header in the tab order
6450		if ( toShow.length && toHide.length ) {
6451			toHide.prev().attr( "tabIndex", -1 );
6452		} else if ( toShow.length ) {
6453			this.headers.filter(function() {
6454				return $( this ).attr( "tabIndex" ) === 0;
6455			})
6456			.attr( "tabIndex", -1 );
6457		}
6458
6459		toShow
6460			.attr({
6461				"aria-expanded": "true",
6462				"aria-hidden": "false"
6463			})
6464			.prev()
6465				.attr({
6466					"aria-selected": "true",
6467					tabIndex: 0
6468				});
6469	},
6470
6471	_animate: function( toShow, toHide, data ) {
6472		var total, easing, duration,
6473			that = this,
6474			adjust = 0,
6475			down = toShow.length &&
6476				( !toHide.length || ( toShow.index() < toHide.index() ) ),
6477			animate = this.options.animate || {},
6478			options = down && animate.down || animate,
6479			complete = function() {
6480				that._toggleComplete( data );
6481			};
6482
6483		if ( typeof options === "number" ) {
6484			duration = options;
6485		}
6486		if ( typeof options === "string" ) {
6487			easing = options;
6488		}
6489		// fall back from options to animation in case of partial down settings
6490		easing = easing || options.easing || animate.easing;
6491		duration = duration || options.duration || animate.duration;
6492
6493		if ( !toHide.length ) {
6494			return toShow.animate( showProps, duration, easing, complete );
6495		}
6496		if ( !toShow.length ) {
6497			return toHide.animate( hideProps, duration, easing, complete );
6498		}
6499
6500		total = toShow.show().outerHeight();
6501		toHide.animate( hideProps, {
6502			duration: duration,
6503			easing: easing,
6504			step: function( now, fx ) {
6505				fx.now = Math.round( now );
6506			}
6507		});
6508		toShow
6509			.hide()
6510			.animate( showProps, {
6511				duration: duration,
6512				easing: easing,
6513				complete: complete,
6514				step: function( now, fx ) {
6515					fx.now = Math.round( now );
6516					if ( fx.prop !== "height" ) {
6517						adjust += fx.now;
6518					} else if ( that.options.heightStyle !== "content" ) {
6519						fx.now = Math.round( total - toHide.outerHeight() - adjust );
6520						adjust = 0;
6521					}
6522				}
6523			});
6524	},
6525
6526	_toggleComplete: function( data ) {
6527		var toHide = data.oldPanel;
6528
6529		toHide
6530			.removeClass( "ui-accordion-content-active" )
6531			.prev()
6532				.removeClass( "ui-corner-top" )
6533				.addClass( "ui-corner-all" );
6534
6535		// Work around for rendering bug in IE (#5421)
6536		if ( toHide.length ) {
6537			toHide.parent()[0].className = toHide.parent()[0].className;
6538		}
6539
6540		this._trigger( "activate", null, data );
6541	}
6542});
6543
6544})( jQuery );
6545
6546(function( $, undefined ) {
6547
6548// used to prevent race conditions with remote data sources
6549var requestIndex = 0;
6550
6551$.widget( "ui.autocomplete", {
6552	version: "1.10.1",
6553	defaultElement: "<input>",
6554	options: {
6555		appendTo: null,
6556		autoFocus: false,
6557		delay: 300,
6558		minLength: 1,
6559		position: {
6560			my: "left top",
6561			at: "left bottom",
6562			collision: "none"
6563		},
6564		source: null,
6565
6566		// callbacks
6567		change: null,
6568		close: null,
6569		focus: null,
6570		open: null,
6571		response: null,
6572		search: null,
6573		select: null
6574	},
6575
6576	pending: 0,
6577
6578	_create: function() {
6579		// Some browsers only repeat keydown events, not keypress events,
6580		// so we use the suppressKeyPress flag to determine if we've already
6581		// handled the keydown event. #7269
6582		// Unfortunately the code for & in keypress is the same as the up arrow,
6583		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
6584		// events when we know the keydown event was used to modify the
6585		// search term. #7799
6586		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
6587			nodeName = this.element[0].nodeName.toLowerCase(),
6588			isTextarea = nodeName === "textarea",
6589			isInput = nodeName === "input";
6590
6591		this.isMultiLine =
6592			// Textareas are always multi-line
6593			isTextarea ? true :
6594			// Inputs are always single-line, even if inside a contentEditable element
6595			// IE also treats inputs as contentEditable
6596			isInput ? false :
6597			// All other element types are determined by whether or not they're contentEditable
6598			this.element.prop( "isContentEditable" );
6599
6600		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
6601		this.isNewMenu = true;
6602
6603		this.element
6604			.addClass( "ui-autocomplete-input" )
6605			.attr( "autocomplete", "off" );
6606
6607		this._on( this.element, {
6608			keydown: function( event ) {
6609				/*jshint maxcomplexity:15*/
6610				if ( this.element.prop( "readOnly" ) ) {
6611					suppressKeyPress = true;
6612					suppressInput = true;
6613					suppressKeyPressRepeat = true;
6614					return;
6615				}
6616
6617				suppressKeyPress = false;
6618				suppressInput = false;
6619				suppressKeyPressRepeat = false;
6620				var keyCode = $.ui.keyCode;
6621				switch( event.keyCode ) {
6622				case keyCode.PAGE_UP:
6623					suppressKeyPress = true;
6624					this._move( "previousPage", event );
6625					break;
6626				case keyCode.PAGE_DOWN:
6627					suppressKeyPress = true;
6628					this._move( "nextPage", event );
6629					break;
6630				case keyCode.UP:
6631					suppressKeyPress = true;
6632					this._keyEvent( "previous", event );
6633					break;
6634				case keyCode.DOWN:
6635					suppressKeyPress = true;
6636					this._keyEvent( "next", event );
6637					break;
6638				case keyCode.ENTER:
6639				case keyCode.NUMPAD_ENTER:
6640					// when menu is open and has focus
6641					if ( this.menu.active ) {
6642						// #6055 - Opera still allows the keypress to occur
6643						// which causes forms to submit
6644						suppressKeyPress = true;
6645						event.preventDefault();
6646						this.menu.select( event );
6647					}
6648					break;
6649				case keyCode.TAB:
6650					if ( this.menu.active ) {
6651						this.menu.select( event );
6652					}
6653					break;
6654				case keyCode.ESCAPE:
6655					if ( this.menu.element.is( ":visible" ) ) {
6656						this._value( this.term );
6657						this.close( event );
6658						// Different browsers have different default behavior for escape
6659						// Single press can mean undo or clear
6660						// Double press in IE means clear the whole form
6661						event.preventDefault();
6662					}
6663					break;
6664				default:
6665					suppressKeyPressRepeat = true;
6666					// search timeout should be triggered before the input value is changed
6667					this._searchTimeout( event );
6668					break;
6669				}
6670			},
6671			keypress: function( event ) {
6672				if ( suppressKeyPress ) {
6673					suppressKeyPress = false;
6674					event.preventDefault();
6675					return;
6676				}
6677				if ( suppressKeyPressRepeat ) {
6678					return;
6679				}
6680
6681				// replicate some key handlers to allow them to repeat in Firefox and Opera
6682				var keyCode = $.ui.keyCode;
6683				switch( event.keyCode ) {
6684				case keyCode.PAGE_UP:
6685					this._move( "previousPage", event );
6686					break;
6687				case keyCode.PAGE_DOWN:
6688					this._move( "nextPage", event );
6689					break;
6690				case keyCode.UP:
6691					this._keyEvent( "previous", event );
6692					break;
6693				case keyCode.DOWN:
6694					this._keyEvent( "next", event );
6695					break;
6696				}
6697			},
6698			input: function( event ) {
6699				if ( suppressInput ) {
6700					suppressInput = false;
6701					event.preventDefault();
6702					return;
6703				}
6704				this._searchTimeout( event );
6705			},
6706			focus: function() {
6707				this.selectedItem = null;
6708				this.previous = this._value();
6709			},
6710			blur: function( event ) {
6711				if ( this.cancelBlur ) {
6712					delete this.cancelBlur;
6713					return;
6714				}
6715
6716				clearTimeout( this.searching );
6717				this.close( event );
6718				this._change( event );
6719			}
6720		});
6721
6722		this._initSource();
6723		this.menu = $( "<ul>" )
6724			.addClass( "ui-autocomplete ui-front" )
6725			.appendTo( this._appendTo() )
6726			.menu({
6727				// custom key handling for now
6728				input: $(),
6729				// disable ARIA support, the live region takes care of that
6730				role: null
6731			})
6732			.hide()
6733			.data( "ui-menu" );
6734
6735		this._on( this.menu.element, {
6736			mousedown: function( event ) {
6737				// prevent moving focus out of the text field
6738				event.preventDefault();
6739
6740				// IE doesn't prevent moving focus even with event.preventDefault()
6741				// so we set a flag to know when we should ignore the blur event
6742				this.cancelBlur = true;
6743				this._delay(function() {
6744					delete this.cancelBlur;
6745				});
6746
6747				// clicking on the scrollbar causes focus to shift to the body
6748				// but we can't detect a mouseup or a click immediately afterward
6749				// so we have to track the next mousedown and close the menu if
6750				// the user clicks somewhere outside of the autocomplete
6751				var menuElement = this.menu.element[ 0 ];
6752				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6753					this._delay(function() {
6754						var that = this;
6755						this.document.one( "mousedown", function( event ) {
6756							if ( event.target !== that.element[ 0 ] &&
6757									event.target !== menuElement &&
6758									!$.contains( menuElement, event.target ) ) {
6759								that.close();
6760							}
6761						});
6762					});
6763				}
6764			},
6765			menufocus: function( event, ui ) {
6766				// #7024 - Prevent accidental activation of menu items in Firefox
6767				if ( this.isNewMenu ) {
6768					this.isNewMenu = false;
6769					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6770						this.menu.blur();
6771
6772						this.document.one( "mousemove", function() {
6773							$( event.target ).trigger( event.originalEvent );
6774						});
6775
6776						return;
6777					}
6778				}
6779
6780				var item = ui.item.data( "ui-autocomplete-item" );
6781				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6782					// use value to match what will end up in the input, if it was a key event
6783					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6784						this._value( item.value );
6785					}
6786				} else {
6787					// Normally the input is populated with the item's value as the
6788					// menu is navigated, causing screen readers to notice a change and
6789					// announce the item. Since the focus event was canceled, this doesn't
6790					// happen, so we update the live region so that screen readers can
6791					// still notice the change and announce it.
6792					this.liveRegion.text( item.value );
6793				}
6794			},
6795			menuselect: function( event, ui ) {
6796				var item = ui.item.data( "ui-autocomplete-item" ),
6797					previous = this.previous;
6798
6799				// only trigger when focus was lost (click on menu)
6800				if ( this.element[0] !== this.document[0].activeElement ) {
6801					this.element.focus();
6802					this.previous = previous;
6803					// #6109 - IE triggers two focus events and the second
6804					// is asynchronous, so we need to reset the previous
6805					// term synchronously and asynchronously :-(
6806					this._delay(function() {
6807						this.previous = previous;
6808						this.selectedItem = item;
6809					});
6810				}
6811
6812				if ( false !== this._trigger( "select", event, { item: item } ) ) {
6813					this._value( item.value );
6814				}
6815				// reset the term after the select event
6816				// this allows custom select handling to work properly
6817				this.term = this._value();
6818
6819				this.close( event );
6820				this.selectedItem = item;
6821			}
6822		});
6823
6824		this.liveRegion = $( "<span>", {
6825				role: "status",
6826				"aria-live": "polite"
6827			})
6828			.addClass( "ui-helper-hidden-accessible" )
6829			.insertAfter( this.element );
6830
6831		// turning off autocomplete prevents the browser from remembering the
6832		// value when navigating through history, so we re-enable autocomplete
6833		// if the page is unloaded before the widget is destroyed. #7790
6834		this._on( this.window, {
6835			beforeunload: function() {
6836				this.element.removeAttr( "autocomplete" );
6837			}
6838		});
6839	},
6840
6841	_destroy: function() {
6842		clearTimeout( this.searching );
6843		this.element
6844			.removeClass( "ui-autocomplete-input" )
6845			.removeAttr( "autocomplete" );
6846		this.menu.element.remove();
6847		this.liveRegion.remove();
6848	},
6849
6850	_setOption: function( key, value ) {
6851		this._super( key, value );
6852		if ( key === "source" ) {
6853			this._initSource();
6854		}
6855		if ( key === "appendTo" ) {
6856			this.menu.element.appendTo( this._appendTo() );
6857		}
6858		if ( key === "disabled" && value && this.xhr ) {
6859			this.xhr.abort();
6860		}
6861	},
6862
6863	_appendTo: function() {
6864		var element = this.options.appendTo;
6865
6866		if ( element ) {
6867			element = element.jquery || element.nodeType ?
6868				$( element ) :
6869				this.document.find( element ).eq( 0 );
6870		}
6871
6872		if ( !element ) {
6873			element = this.element.closest( ".ui-front" );
6874		}
6875
6876		if ( !element.length ) {
6877			element = this.document[0].body;
6878		}
6879
6880		return element;
6881	},
6882
6883	_initSource: function() {
6884		var array, url,
6885			that = this;
6886		if ( $.isArray(this.options.source) ) {
6887			array = this.options.source;
6888			this.source = function( request, response ) {
6889				response( $.ui.autocomplete.filter( array, request.term ) );
6890			};
6891		} else if ( typeof this.options.source === "string" ) {
6892			url = this.options.source;
6893			this.source = function( request, response ) {
6894				if ( that.xhr ) {
6895					that.xhr.abort();
6896				}
6897				that.xhr = $.ajax({
6898					url: url,
6899					data: request,
6900					dataType: "json",
6901					success: function( data ) {
6902						response( data );
6903					},
6904					error: function() {
6905						response( [] );
6906					}
6907				});
6908			};
6909		} else {
6910			this.source = this.options.source;
6911		}
6912	},
6913
6914	_searchTimeout: function( event ) {
6915		clearTimeout( this.searching );
6916		this.searching = this._delay(function() {
6917			// only search if the value has changed
6918			if ( this.term !== this._value() ) {
6919				this.selectedItem = null;
6920				this.search( null, event );
6921			}
6922		}, this.options.delay );
6923	},
6924
6925	search: function( value, event ) {
6926		value = value != null ? value : this._value();
6927
6928		// always save the actual value, not the one passed as an argument
6929		this.term = this._value();
6930
6931		if ( value.length < this.options.minLength ) {
6932			return this.close( event );
6933		}
6934
6935		if ( this._trigger( "search", event ) === false ) {
6936			return;
6937		}
6938
6939		return this._search( value );
6940	},
6941
6942	_search: function( value ) {
6943		this.pending++;
6944		this.element.addClass( "ui-autocomplete-loading" );
6945		this.cancelSearch = false;
6946
6947		this.source( { term: value }, this._response() );
6948	},
6949
6950	_response: function() {
6951		var that = this,
6952			index = ++requestIndex;
6953
6954		return function( content ) {
6955			if ( index === requestIndex ) {
6956				that.__response( content );
6957			}
6958
6959			that.pending--;
6960			if ( !that.pending ) {
6961				that.element.removeClass( "ui-autocomplete-loading" );
6962			}
6963		};
6964	},
6965
6966	__response: function( content ) {
6967		if ( content ) {
6968			content = this._normalize( content );
6969		}
6970		this._trigger( "response", null, { content: content } );
6971		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6972			this._suggest( content );
6973			this._trigger( "open" );
6974		} else {
6975			// use ._close() instead of .close() so we don't cancel future searches
6976			this._close();
6977		}
6978	},
6979
6980	close: function( event ) {
6981		this.cancelSearch = true;
6982		this._close( event );
6983	},
6984
6985	_close: function( event ) {
6986		if ( this.menu.element.is( ":visible" ) ) {
6987			this.menu.element.hide();
6988			this.menu.blur();
6989			this.isNewMenu = true;
6990			this._trigger( "close", event );
6991		}
6992	},
6993
6994	_change: function( event ) {
6995		if ( this.previous !== this._value() ) {
6996			this._trigger( "change", event, { item: this.selectedItem } );
6997		}
6998	},
6999
7000	_normalize: function( items ) {
7001		// assume all items have the right format when the first item is complete
7002		if ( items.length && items[0].label && items[0].value ) {
7003			return items;
7004		}
7005		return $.map( items, function( item ) {
7006			if ( typeof item === "string" ) {
7007				return {
7008					label: item,
7009					value: item
7010				};
7011			}
7012			return $.extend({
7013				label: item.label || item.value,
7014				value: item.value || item.label
7015			}, item );
7016		});
7017	},
7018
7019	_suggest: function( items ) {
7020		var ul = this.menu.element.empty();
7021		this._renderMenu( ul, items );
7022		this.menu.refresh();
7023
7024		// size and position menu
7025		ul.show();
7026		this._resizeMenu();
7027		ul.position( $.extend({
7028			of: this.element
7029		}, this.options.position ));
7030
7031		if ( this.options.autoFocus ) {
7032			this.menu.next();
7033		}
7034	},
7035
7036	_resizeMenu: function() {
7037		var ul = this.menu.element;
7038		ul.outerWidth( Math.max(
7039			// Firefox wraps long text (possibly a rounding bug)
7040			// so we add 1px to avoid the wrapping (#7513)
7041			ul.width( "" ).outerWidth() + 1,
7042			this.element.outerWidth()
7043		) );
7044	},
7045
7046	_renderMenu: function( ul, items ) {
7047		var that = this;
7048		$.each( items, function( index, item ) {
7049			that._renderItemData( ul, item );
7050		});
7051	},
7052
7053	_renderItemData: function( ul, item ) {
7054		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7055	},
7056
7057	_renderItem: function( ul, item ) {
7058		return $( "<li>" )
7059			.append( $( "<a>" ).text( item.label ) )
7060			.appendTo( ul );
7061	},
7062
7063	_move: function( direction, event ) {
7064		if ( !this.menu.element.is( ":visible" ) ) {
7065			this.search( null, event );
7066			return;
7067		}
7068		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7069				this.menu.isLastItem() && /^next/.test( direction ) ) {
7070			this._value( this.term );
7071			this.menu.blur();
7072			return;
7073		}
7074		this.menu[ direction ]( event );
7075	},
7076
7077	widget: function() {
7078		return this.menu.element;
7079	},
7080
7081	_value: function() {
7082		return this.valueMethod.apply( this.element, arguments );
7083	},
7084
7085	_keyEvent: function( keyEvent, event ) {
7086		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7087			this._move( keyEvent, event );
7088
7089			// prevents moving cursor to beginning/end of the text field in some browsers
7090			event.preventDefault();
7091		}
7092	}
7093});
7094
7095$.extend( $.ui.autocomplete, {
7096	escapeRegex: function( value ) {
7097		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
7098	},
7099	filter: function(array, term) {
7100		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
7101		return $.grep( array, function(value) {
7102			return matcher.test( value.label || value.value || value );
7103		});
7104	}
7105});
7106
7107
7108// live region extension, adding a `messages` option
7109// NOTE: This is an experimental API. We are still investigating
7110// a full solution for string manipulation and internationalization.
7111$.widget( "ui.autocomplete", $.ui.autocomplete, {
7112	options: {
7113		messages: {
7114			noResults: "No search results.",
7115			results: function( amount ) {
7116				return amount + ( amount > 1 ? " results are" : " result is" ) +
7117					" available, use up and down arrow keys to navigate.";
7118			}
7119		}
7120	},
7121
7122	__response: function( content ) {
7123		var message;
7124		this._superApply( arguments );
7125		if ( this.options.disabled || this.cancelSearch ) {
7126			return;
7127		}
7128		if ( content && content.length ) {
7129			message = this.options.messages.results( content.length );
7130		} else {
7131			message = this.options.messages.noResults;
7132		}
7133		this.liveRegion.text( message );
7134	}
7135});
7136
7137}( jQuery ));
7138
7139(function( $, undefined ) {
7140
7141var lastActive, startXPos, startYPos, clickDragged,
7142	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7143	stateClasses = "ui-state-hover ui-state-active ",
7144	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",
7145	formResetHandler = function() {
7146		var buttons = $( this ).find( ":ui-button" );
7147		setTimeout(function() {
7148			buttons.button( "refresh" );
7149		}, 1 );
7150	},
7151	radioGroup = function( radio ) {
7152		var name = radio.name,
7153			form = radio.form,
7154			radios = $( [] );
7155		if ( name ) {
7156			name = name.replace( /'/g, "\\'" );
7157			if ( form ) {
7158				radios = $( form ).find( "[name='" + name + "']" );
7159			} else {
7160				radios = $( "[name='" + name + "']", radio.ownerDocument )
7161					.filter(function() {
7162						return !this.form;
7163					});
7164			}
7165		}
7166		return radios;
7167	};
7168
7169$.widget( "ui.button", {
7170	version: "1.10.1",
7171	defaultElement: "<button>",
7172	options: {
7173		disabled: null,
7174		text: true,
7175		label: null,
7176		icons: {
7177			primary: null,
7178			secondary: null
7179		}
7180	},
7181	_create: function() {
7182		this.element.closest( "form" )
7183			.unbind( "reset" + this.eventNamespace )
7184			.bind( "reset" + this.eventNamespace, formResetHandler );
7185
7186		if ( typeof this.options.disabled !== "boolean" ) {
7187			this.options.disabled = !!this.element.prop( "disabled" );
7188		} else {
7189			this.element.prop( "disabled", this.options.disabled );
7190		}
7191
7192		this._determineButtonType();
7193		this.hasTitle = !!this.buttonElement.attr( "title" );
7194
7195		var that = this,
7196			options = this.options,
7197			toggleButton = this.type === "checkbox" || this.type === "radio",
7198			activeClass = !toggleButton ? "ui-state-active" : "",
7199			focusClass = "ui-state-focus";
7200
7201		if ( options.label === null ) {
7202			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7203		}
7204
7205		this._hoverable( this.buttonElement );
7206
7207		this.buttonElement
7208			.addClass( baseClasses )
7209			.attr( "role", "button" )
7210			.bind( "mouseenter" + this.eventNamespace, function() {
7211				if ( options.disabled ) {
7212					return;
7213				}
7214				if ( this === lastActive ) {
7215					$( this ).addClass( "ui-state-active" );
7216				}
7217			})
7218			.bind( "mouseleave" + this.eventNamespace, function() {
7219				if ( options.disabled ) {
7220					return;
7221				}
7222				$( this ).removeClass( activeClass );
7223			})
7224			.bind( "click" + this.eventNamespace, function( event ) {
7225				if ( options.disabled ) {
7226					event.preventDefault();
7227					event.stopImmediatePropagation();
7228				}
7229			});
7230
7231		this.element
7232			.bind( "focus" + this.eventNamespace, function() {
7233				// no need to check disabled, focus won't be triggered anyway
7234				that.buttonElement.addClass( focusClass );
7235			})
7236			.bind( "blur" + this.eventNamespace, function() {
7237				that.buttonElement.removeClass( focusClass );
7238			});
7239
7240		if ( toggleButton ) {
7241			this.element.bind( "change" + this.eventNamespace, function() {
7242				if ( clickDragged ) {
7243					return;
7244				}
7245				that.refresh();
7246			});
7247			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
7248			// prevents issue where button state changes but checkbox/radio checked state
7249			// does not in Firefox (see ticket #6970)
7250			this.buttonElement
7251				.bind( "mousedown" + this.eventNamespace, function( event ) {
7252					if ( options.disabled ) {
7253						return;
7254					}
7255					clickDragged = false;
7256					startXPos = event.pageX;
7257					startYPos = event.pageY;
7258				})
7259				.bind( "mouseup" + this.eventNamespace, function( event ) {
7260					if ( options.disabled ) {
7261						return;
7262					}
7263					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
7264						clickDragged = true;
7265					}
7266			});
7267		}
7268
7269		if ( this.type === "checkbox" ) {
7270			this.buttonElement.bind( "click" + this.eventNamespace, function() {
7271				if ( options.disabled || clickDragged ) {
7272					return false;
7273				}
7274			});
7275		} else if ( this.type === "radio" ) {
7276			this.buttonElement.bind( "click" + this.eventNamespace, function() {
7277				if ( options.disabled || clickDragged ) {
7278					return false;
7279				}
7280				$( this ).addClass( "ui-state-active" );
7281				that.buttonElement.attr( "aria-pressed", "true" );
7282
7283				var radio = that.element[ 0 ];
7284				radioGroup( radio )
7285					.not( radio )
7286					.map(function() {
7287						return $( this ).button( "widget" )[ 0 ];
7288					})
7289					.removeClass( "ui-state-active" )
7290					.attr( "aria-pressed", "false" );
7291			});
7292		} else {
7293			this.buttonElement
7294				.bind( "mousedown" + this.eventNamespace, function() {
7295					if ( options.disabled ) {
7296						return false;
7297					}
7298					$( this ).addClass( "ui-state-active" );
7299					lastActive = this;
7300					that.document.one( "mouseup", function() {
7301						lastActive = null;
7302					});
7303				})
7304				.bind( "mouseup" + this.eventNamespace, function() {
7305					if ( options.disabled ) {
7306						return false;
7307					}
7308					$( this ).removeClass( "ui-state-active" );
7309				})
7310				.bind( "keydown" + this.eventNamespace, function(event) {
7311					if ( options.disabled ) {
7312						return false;
7313					}
7314					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7315						$( this ).addClass( "ui-state-active" );
7316					}
7317				})
7318				// see #8559, we bind to blur here in case the button element loses
7319				// focus between keydown and keyup, it would be left in an "active" state
7320				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7321					$( this ).removeClass( "ui-state-active" );
7322				});
7323
7324			if ( this.buttonElement.is("a") ) {
7325				this.buttonElement.keyup(function(event) {
7326					if ( event.keyCode === $.ui.keyCode.SPACE ) {
7327						// TODO pass through original event correctly (just as 2nd argument doesn't work)
7328						$( this ).click();
7329					}
7330				});
7331			}
7332		}
7333
7334		// TODO: pull out $.Widget's handling for the disabled option into
7335		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7336		// be overridden by individual plugins
7337		this._setOption( "disabled", options.disabled );
7338		this._resetButton();
7339	},
7340
7341	_determineButtonType: function() {
7342		var ancestor, labelSelector, checked;
7343
7344		if ( this.element.is("[type=checkbox]") ) {
7345			this.type = "checkbox";
7346		} else if ( this.element.is("[type=radio]") ) {
7347			this.type = "radio";
7348		} else if ( this.element.is("input") ) {
7349			this.type = "input";
7350		} else {
7351			this.type = "button";
7352		}
7353
7354		if ( this.type === "checkbox" || this.type === "radio" ) {
7355			// we don't search against the document in case the element
7356			// is disconnected from the DOM
7357			ancestor = this.element.parents().last();
7358			labelSelector = "label[for='" + this.element.attr("id") + "']";
7359			this.buttonElement = ancestor.find( labelSelector );
7360			if ( !this.buttonElement.length ) {
7361				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7362				this.buttonElement = ancestor.filter( labelSelector );
7363				if ( !this.buttonElement.length ) {
7364					this.buttonElement = ancestor.find( labelSelector );
7365				}
7366			}
7367			this.element.addClass( "ui-helper-hidden-accessible" );
7368
7369			checked = this.element.is( ":checked" );
7370			if ( checked ) {
7371				this.buttonElement.addClass( "ui-state-active" );
7372			}
7373			this.buttonElement.prop( "aria-pressed", checked );
7374		} else {
7375			this.buttonElement = this.element;
7376		}
7377	},
7378
7379	widget: function() {
7380		return this.buttonElement;
7381	},
7382
7383	_destroy: function() {
7384		this.element
7385			.removeClass( "ui-helper-hidden-accessible" );
7386		this.buttonElement
7387			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7388			.removeAttr( "role" )
7389			.removeAttr( "aria-pressed" )
7390			.html( this.buttonElement.find(".ui-button-text").html() );
7391
7392		if ( !this.hasTitle ) {
7393			this.buttonElement.removeAttr( "title" );
7394		}
7395	},
7396
7397	_setOption: function( key, value ) {
7398		this._super( key, value );
7399		if ( key === "disabled" ) {
7400			if ( value ) {
7401				this.element.prop( "disabled", true );
7402			} else {
7403				this.element.prop( "disabled", false );
7404			}
7405			return;
7406		}
7407		this._resetButton();
7408	},
7409
7410	refresh: function() {
7411		//See #8237 & #8828
7412		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7413
7414		if ( isDisabled !== this.options.disabled ) {
7415			this._setOption( "disabled", isDisabled );
7416		}
7417		if ( this.type === "radio" ) {
7418			radioGroup( this.element[0] ).each(function() {
7419				if ( $( this ).is( ":checked" ) ) {
7420					$( this ).button( "widget" )
7421						.addClass( "ui-state-active" )
7422						.attr( "aria-pressed", "true" );
7423				} else {
7424					$( this ).button( "widget" )
7425						.removeClass( "ui-state-active" )
7426						.attr( "aria-pressed", "false" );
7427				}
7428			});
7429		} else if ( this.type === "checkbox" ) {
7430			if ( this.element.is( ":checked" ) ) {
7431				this.buttonElement
7432					.addClass( "ui-state-active" )
7433					.attr( "aria-pressed", "true" );
7434			} else {
7435				this.buttonElement
7436					.removeClass( "ui-state-active" )
7437					.attr( "aria-pressed", "false" );
7438			}
7439		}
7440	},
7441
7442	_resetButton: function() {
7443		if ( this.type === "input" ) {
7444			if ( this.options.label ) {
7445				this.element.val( this.options.label );
7446			}
7447			return;
7448		}
7449		var buttonElement = this.buttonElement.removeClass( typeClasses ),
7450			buttonText = $( "<span></span>", this.document[0] )
7451				.addClass( "ui-button-text" )
7452				.html( this.options.label )
7453				.appendTo( buttonElement.empty() )
7454				.text(),
7455			icons = this.options.icons,
7456			multipleIcons = icons.primary && icons.secondary,
7457			buttonClasses = [];
7458
7459		if ( icons.primary || icons.secondary ) {
7460			if ( this.options.text ) {
7461				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7462			}
7463
7464			if ( icons.primary ) {
7465				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7466			}
7467
7468			if ( icons.secondary ) {
7469				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7470			}
7471
7472			if ( !this.options.text ) {
7473				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7474
7475				if ( !this.hasTitle ) {
7476					buttonElement.attr( "title", $.trim( buttonText ) );
7477				}
7478			}
7479		} else {
7480			buttonClasses.push( "ui-button-text-only" );
7481		}
7482		buttonElement.addClass( buttonClasses.join( " " ) );
7483	}
7484});
7485
7486$.widget( "ui.buttonset", {
7487	version: "1.10.1",
7488	options: {
7489		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7490	},
7491
7492	_create: function() {
7493		this.element.addClass( "ui-buttonset" );
7494	},
7495
7496	_init: function() {
7497		this.refresh();
7498	},
7499
7500	_setOption: function( key, value ) {
7501		if ( key === "disabled" ) {
7502			this.buttons.button( "option", key, value );
7503		}
7504
7505		this._super( key, value );
7506	},
7507
7508	refresh: function() {
7509		var rtl = this.element.css( "direction" ) === "rtl";
7510
7511		this.buttons = this.element.find( this.options.items )
7512			.filter( ":ui-button" )
7513				.button( "refresh" )
7514			.end()
7515			.not( ":ui-button" )
7516				.button()
7517			.end()
7518			.map(function() {
7519				return $( this ).button( "widget" )[ 0 ];
7520			})
7521				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7522				.filter( ":first" )
7523					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7524				.end()
7525				.filter( ":last" )
7526					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7527				.end()
7528			.end();
7529	},
7530
7531	_destroy: function() {
7532		this.element.removeClass( "ui-buttonset" );
7533		this.buttons
7534			.map(function() {
7535				return $( this ).button( "widget" )[ 0 ];
7536			})
7537				.removeClass( "ui-corner-left ui-corner-right" )
7538			.end()
7539			.button( "destroy" );
7540	}
7541});
7542
7543}( jQuery ) );
7544
7545(function( $, undefined ) {
7546
7547$.extend($.ui, { datepicker: { version: "1.10.1" } });
7548
7549var PROP_NAME = "datepicker",
7550	dpuuid = new Date().getTime(),
7551	instActive;
7552
7553/* Date picker manager.
7554   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7555   Settings for (groups of) date pickers are maintained in an instance object,
7556   allowing multiple different settings on the same page. */
7557
7558function Datepicker() {
7559	this._curInst = null; // The current instance in use
7560	this._keyEvent = false; // If the last event was a key event
7561	this._disabledInputs = []; // List of date picker inputs that have been disabled
7562	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7563	this._inDialog = false; // True if showing within a "dialog", false if not
7564	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7565	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7566	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7567	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7568	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7569	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7570	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7571	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7572	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7573	this.regional = []; // Available regional settings, indexed by language code
7574	this.regional[""] = { // Default regional settings
7575		closeText: "Done", // Display text for close link
7576		prevText: "Prev", // Display text for previous month link
7577		nextText: "Next", // Display text for next month link
7578		currentText: "Today", // Display text for current month link
7579		monthNames: ["January","February","March","April","May","June",
7580			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
7581		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
7582		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
7583		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
7584		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
7585		weekHeader: "Wk", // Column header for week of the year
7586		dateFormat: "mm/dd/yy", // See format options on parseDate
7587		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7588		isRTL: false, // True if right-to-left language, false if left-to-right
7589		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7590		yearSuffix: "" // Additional text to append to the year in the month headers
7591	};
7592	this._defaults = { // Global defaults for all the date picker instances
7593		showOn: "focus", // "focus" for popup on focus,
7594			// "button" for trigger button, or "both" for either
vendor: 6,360 bytes, lines 7595-7724
7595		showAnim: "fadeIn", // Name of jQuery animation for popup
7596		showOptions: {}, // Options for enhanced animations
7597		defaultDate: null, // Used when field is blank: actual date,
7598			// +/-number for offset from today, null for today
7599		appendText: "", // Display text following the input box, e.g. showing the format
7600		buttonText: "...", // Text for trigger button
7601		buttonImage: "", // URL for trigger button image
7602		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7603		hideIfNoPrevNext: false, // True to hide next/previous month links
7604			// if not applicable, false to just disable them
7605		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7606		gotoCurrent: false, // True if today link goes back to current selection instead
7607		changeMonth: false, // True if month can be selected directly, false if only prev/next
7608		changeYear: false, // True if year can be selected directly, false if only prev/next
7609		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7610			// either relative to today's year (-nn:+nn), relative to currently displayed year
7611			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7612		showOtherMonths: false, // True to show dates in other months, false to leave blank
7613		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7614		showWeek: false, // True to show week of the year, false to not show it
7615		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7616			// takes a Date and returns the number of the week for it
7617		shortYearCutoff: "+10", // Short year values < this are in the current century,
7618			// > this are in the previous century,
7619			// string value starting with "+" for current year + value
7620		minDate: null, // The earliest selectable date, or null for no limit
7621		maxDate: null, // The latest selectable date, or null for no limit
7622		duration: "fast", // Duration of display/closure
7623		beforeShowDay: null, // Function that takes a date and returns an array with
7624			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7625			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7626		beforeShow: null, // Function that takes an input field and
7627			// returns a set of custom settings for the date picker
7628		onSelect: null, // Define a callback function when a date is selected
7629		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7630		onClose: null, // Define a callback function when the datepicker is closed
7631		numberOfMonths: 1, // Number of months to show at a time
7632		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7633		stepMonths: 1, // Number of months to step back/forward
7634		stepBigMonths: 12, // Number of months to step back/forward for the big links
7635		altField: "", // Selector for an alternate field to store selected dates into
7636		altFormat: "", // The date format to use for the alternate field
7637		constrainInput: true, // The input is constrained by the current date format
7638		showButtonPanel: false, // True to show button panel, false to not show it
7639		autoSize: false, // True to size the input for the date format, false to leave as is
7640		disabled: false // The initial disabled state
7641	};
7642	$.extend(this._defaults, this.regional[""]);
7643	this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
7644}
7645
7646$.extend(Datepicker.prototype, {
7647	/* Class name added to elements to indicate already configured with a date picker. */
7648	markerClassName: "hasDatepicker",
7649
7650	//Keep track of the maximum number of rows displayed (see #7043)
7651	maxRows: 4,
7652
7653	// TODO rename to "widget" when switching to widget factory
7654	_widgetDatepicker: function() {
7655		return this.dpDiv;
7656	},
7657
7658	/* Override the default settings for all instances of the date picker.
7659	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7660	 * @return the manager object
7661	 */
7662	setDefaults: function(settings) {
7663		extendRemove(this._defaults, settings || {});
7664		return this;
7665	},
7666
7667	/* Attach the date picker to a jQuery selection.
7668	 * @param  target	element - the target input field or division or span
7669	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7670	 */
7671	_attachDatepicker: function(target, settings) {
7672		var nodeName, inline, inst;
7673		nodeName = target.nodeName.toLowerCase();
7674		inline = (nodeName === "div" || nodeName === "span");
7675		if (!target.id) {
7676			this.uuid += 1;
7677			target.id = "dp" + this.uuid;
7678		}
7679		inst = this._newInst($(target), inline);
7680		inst.settings = $.extend({}, settings || {});
7681		if (nodeName === "input") {
7682			this._connectDatepicker(target, inst);
7683		} else if (inline) {
7684			this._inlineDatepicker(target, inst);
7685		}
7686	},
7687
7688	/* Create a new instance object. */
7689	_newInst: function(target, inline) {
7690		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
7691		return {id: id, input: target, // associated target
7692			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7693			drawMonth: 0, drawYear: 0, // month being drawn
7694			inline: inline, // is datepicker inline or not
7695			dpDiv: (!inline ? this.dpDiv : // presentation div
7696			bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
7697	},
7698
7699	/* Attach the date picker to an input field. */
7700	_connectDatepicker: function(target, inst) {
7701		var input = $(target);
7702		inst.append = $([]);
7703		inst.trigger = $([]);
7704		if (input.hasClass(this.markerClassName)) {
7705			return;
7706		}
7707		this._attachments(input, inst);
7708		input.addClass(this.markerClassName).keydown(this._doKeyDown).
7709			keypress(this._doKeyPress).keyup(this._doKeyUp);
7710		this._autoSize(inst);
7711		$.data(target, PROP_NAME, inst);
7712		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7713		if( inst.settings.disabled ) {
7714			this._disableDatepicker( target );
7715		}
7716	},
7717
7718	/* Make attachments based on settings. */
7719	_attachments: function(input, inst) {
7720		var showOn, buttonText, buttonImage,
7721			appendText = this._get(inst, "appendText"),
7722			isRTL = this._get(inst, "isRTL");
7723
7724		if (inst.append) {
vendor: 5,777 bytes, lines 7725-7880
7725			inst.append.remove();
7726		}
7727		if (appendText) {
7728			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
7729			input[isRTL ? "before" : "after"](inst.append);
7730		}
7731
7732		input.unbind("focus", this._showDatepicker);
7733
7734		if (inst.trigger) {
7735			inst.trigger.remove();
7736		}
7737
7738		showOn = this._get(inst, "showOn");
7739		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7740			input.focus(this._showDatepicker);
7741		}
7742		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7743			buttonText = this._get(inst, "buttonText");
7744			buttonImage = this._get(inst, "buttonImage");
7745			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7746				$("<img/>").addClass(this._triggerClass).
7747					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7748				$("<button type='button'></button>").addClass(this._triggerClass).
7749					html(!buttonImage ? buttonText : $("<img/>").attr(
7750					{ src:buttonImage, alt:buttonText, title:buttonText })));
7751			input[isRTL ? "before" : "after"](inst.trigger);
7752			inst.trigger.click(function() {
7753				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7754					$.datepicker._hideDatepicker();
7755				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7756					$.datepicker._hideDatepicker();
7757					$.datepicker._showDatepicker(input[0]);
7758				} else {
7759					$.datepicker._showDatepicker(input[0]);
7760				}
7761				return false;
7762			});
7763		}
7764	},
7765
7766	/* Apply the maximum length for the date format. */
7767	_autoSize: function(inst) {
7768		if (this._get(inst, "autoSize") && !inst.inline) {
7769			var findMax, max, maxI, i,
7770				date = new Date(2009, 12 - 1, 20), // Ensure double digits
7771				dateFormat = this._get(inst, "dateFormat");
7772
7773			if (dateFormat.match(/[DM]/)) {
7774				findMax = function(names) {
7775					max = 0;
7776					maxI = 0;
7777					for (i = 0; i < names.length; i++) {
7778						if (names[i].length > max) {
7779							max = names[i].length;
7780							maxI = i;
7781						}
7782					}
7783					return maxI;
7784				};
7785				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7786					"monthNames" : "monthNamesShort"))));
7787				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7788					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7789			}
7790			inst.input.attr("size", this._formatDate(inst, date).length);
7791		}
7792	},
7793
7794	/* Attach an inline date picker to a div. */
7795	_inlineDatepicker: function(target, inst) {
7796		var divSpan = $(target);
7797		if (divSpan.hasClass(this.markerClassName)) {
7798			return;
7799		}
7800		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7801		$.data(target, PROP_NAME, inst);
7802		this._setDate(inst, this._getDefaultDate(inst), true);
7803		this._updateDatepicker(inst);
7804		this._updateAlternate(inst);
7805		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7806		if( inst.settings.disabled ) {
7807			this._disableDatepicker( target );
7808		}
7809		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7810		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7811		inst.dpDiv.css( "display", "block" );
7812	},
7813
7814	/* Pop-up the date picker in a "dialog" box.
7815	 * @param  input element - ignored
7816	 * @param  date	string or Date - the initial date to display
7817	 * @param  onSelect  function - the function to call when a date is selected
7818	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7819	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7820	 *					event - with x/y coordinates or
7821	 *					leave empty for default (screen centre)
7822	 * @return the manager object
7823	 */
7824	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
7825		var id, browserWidth, browserHeight, scrollX, scrollY,
7826			inst = this._dialogInst; // internal instance
7827
7828		if (!inst) {
7829			this.uuid += 1;
7830			id = "dp" + this.uuid;
7831			this._dialogInput = $("<input type='text' id='" + id +
7832				"' style='position: absolute; top: -100px; width: 0px;'/>");
7833			this._dialogInput.keydown(this._doKeyDown);
7834			$("body").append(this._dialogInput);
7835			inst = this._dialogInst = this._newInst(this._dialogInput, false);
7836			inst.settings = {};
7837			$.data(this._dialogInput[0], PROP_NAME, inst);
7838		}
7839		extendRemove(inst.settings, settings || {});
7840		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7841		this._dialogInput.val(date);
7842
7843		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7844		if (!this._pos) {
7845			browserWidth = document.documentElement.clientWidth;
7846			browserHeight = document.documentElement.clientHeight;
7847			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7848			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7849			this._pos = // should use actual width/height below
7850				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7851		}
7852
7853		// move input on screen for focus, but hidden behind dialog
7854		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7855		inst.settings.onSelect = onSelect;
7856		this._inDialog = true;
7857		this.dpDiv.addClass(this._dialogClass);
7858		this._showDatepicker(this._dialogInput[0]);
7859		if ($.blockUI) {
7860			$.blockUI(this.dpDiv);
7861		}
7862		$.data(this._dialogInput[0], PROP_NAME, inst);
7863		return this;
7864	},
7865
7866	/* Detach a datepicker from its control.
7867	 * @param  target	element - the target input field or division or span
7868	 */
7869	_destroyDatepicker: function(target) {
7870		var nodeName,
7871			$target = $(target),
7872			inst = $.data(target, PROP_NAME);
7873
7874		if (!$target.hasClass(this.markerClassName)) {
7875			return;
7876		}
7877
7878		nodeName = target.nodeName.toLowerCase();
7879		$.removeData(target, PROP_NAME);
7880		if (nodeName === "input") {
vendor: 4,434 bytes, lines 7881-8013
7881			inst.append.remove();
7882			inst.trigger.remove();
7883			$target.removeClass(this.markerClassName).
7884				unbind("focus", this._showDatepicker).
7885				unbind("keydown", this._doKeyDown).
7886				unbind("keypress", this._doKeyPress).
7887				unbind("keyup", this._doKeyUp);
7888		} else if (nodeName === "div" || nodeName === "span") {
7889			$target.removeClass(this.markerClassName).empty();
7890		}
7891	},
7892
7893	/* Enable the date picker to a jQuery selection.
7894	 * @param  target	element - the target input field or division or span
7895	 */
7896	_enableDatepicker: function(target) {
7897		var nodeName, inline,
7898			$target = $(target),
7899			inst = $.data(target, PROP_NAME);
7900
7901		if (!$target.hasClass(this.markerClassName)) {
7902			return;
7903		}
7904
7905		nodeName = target.nodeName.toLowerCase();
7906		if (nodeName === "input") {
7907			target.disabled = false;
7908			inst.trigger.filter("button").
7909				each(function() { this.disabled = false; }).end().
7910				filter("img").css({opacity: "1.0", cursor: ""});
7911		} else if (nodeName === "div" || nodeName === "span") {
7912			inline = $target.children("." + this._inlineClass);
7913			inline.children().removeClass("ui-state-disabled");
7914			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7915				prop("disabled", false);
7916		}
7917		this._disabledInputs = $.map(this._disabledInputs,
7918			function(value) { return (value === target ? null : value); }); // delete entry
7919	},
7920
7921	/* Disable the date picker to a jQuery selection.
7922	 * @param  target	element - the target input field or division or span
7923	 */
7924	_disableDatepicker: function(target) {
7925		var nodeName, inline,
7926			$target = $(target),
7927			inst = $.data(target, PROP_NAME);
7928
7929		if (!$target.hasClass(this.markerClassName)) {
7930			return;
7931		}
7932
7933		nodeName = target.nodeName.toLowerCase();
7934		if (nodeName === "input") {
7935			target.disabled = true;
7936			inst.trigger.filter("button").
7937				each(function() { this.disabled = true; }).end().
7938				filter("img").css({opacity: "0.5", cursor: "default"});
7939		} else if (nodeName === "div" || nodeName === "span") {
7940			inline = $target.children("." + this._inlineClass);
7941			inline.children().addClass("ui-state-disabled");
7942			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7943				prop("disabled", true);
7944		}
7945		this._disabledInputs = $.map(this._disabledInputs,
7946			function(value) { return (value === target ? null : value); }); // delete entry
7947		this._disabledInputs[this._disabledInputs.length] = target;
7948	},
7949
7950	/* Is the first field in a jQuery collection disabled as a datepicker?
7951	 * @param  target	element - the target input field or division or span
7952	 * @return boolean - true if disabled, false if enabled
7953	 */
7954	_isDisabledDatepicker: function(target) {
7955		if (!target) {
7956			return false;
7957		}
7958		for (var i = 0; i < this._disabledInputs.length; i++) {
7959			if (this._disabledInputs[i] === target) {
7960				return true;
7961			}
7962		}
7963		return false;
7964	},
7965
7966	/* Retrieve the instance data for the target control.
7967	 * @param  target  element - the target input field or division or span
7968	 * @return  object - the associated instance data
7969	 * @throws  error if a jQuery problem getting data
7970	 */
7971	_getInst: function(target) {
7972		try {
7973			return $.data(target, PROP_NAME);
7974		}
7975		catch (err) {
7976			throw "Missing instance data for this datepicker";
7977		}
7978	},
7979
7980	/* Update or retrieve the settings for a date picker attached to an input field or division.
7981	 * @param  target  element - the target input field or division or span
7982	 * @param  name	object - the new settings to update or
7983	 *				string - the name of the setting to change or retrieve,
7984	 *				when retrieving also "all" for all instance settings or
7985	 *				"defaults" for all global defaults
7986	 * @param  value   any - the new value for the setting
7987	 *				(omit if above is an object or to retrieve a value)
7988	 */
7989	_optionDatepicker: function(target, name, value) {
7990		var settings, date, minDate, maxDate,
7991			inst = this._getInst(target);
7992
7993		if (arguments.length === 2 && typeof name === "string") {
7994			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
7995				(inst ? (name === "all" ? $.extend({}, inst.settings) :
7996				this._get(inst, name)) : null));
7997		}
7998
7999		settings = name || {};
8000		if (typeof name === "string") {
8001			settings = {};
8002			settings[name] = value;
8003		}
8004
8005		if (inst) {
8006			if (this._curInst === inst) {
8007				this._hideDatepicker();
8008			}
8009
8010			date = this._getDateDatepicker(target, true);
8011			minDate = this._getMinMaxDate(inst, "min");
8012			maxDate = this._getMinMaxDate(inst, "max");
8013			
vendor: 7,816 bytes, lines 8013-8241
8013extendRemove(inst.settings, settings);
8014			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8015			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8016				inst.settings.minDate = this._formatDate(inst, minDate);
8017			}
8018			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8019				inst.settings.maxDate = this._formatDate(inst, maxDate);
8020			}
8021			if ( "disabled" in settings ) {
8022				if ( settings.disabled ) {
8023					this._disableDatepicker(target);
8024				} else {
8025					this._enableDatepicker(target);
8026				}
8027			}
8028			this._attachments($(target), inst);
8029			this._autoSize(inst);
8030			this._setDate(inst, date);
8031			this._updateAlternate(inst);
8032			this._updateDatepicker(inst);
8033		}
8034	},
8035
8036	// change method deprecated
8037	_changeDatepicker: function(target, name, value) {
8038		this._optionDatepicker(target, name, value);
8039	},
8040
8041	/* Redraw the date picker attached to an input field or division.
8042	 * @param  target  element - the target input field or division or span
8043	 */
8044	_refreshDatepicker: function(target) {
8045		var inst = this._getInst(target);
8046		if (inst) {
8047			this._updateDatepicker(inst);
8048		}
8049	},
8050
8051	/* Set the dates for a jQuery selection.
8052	 * @param  target element - the target input field or division or span
8053	 * @param  date	Date - the new date
8054	 */
8055	_setDateDatepicker: function(target, date) {
8056		var inst = this._getInst(target);
8057		if (inst) {
8058			this._setDate(inst, date);
8059			this._updateDatepicker(inst);
8060			this._updateAlternate(inst);
8061		}
8062	},
8063
8064	/* Get the date(s) for the first entry in a jQuery selection.
8065	 * @param  target element - the target input field or division or span
8066	 * @param  noDefault boolean - true if no default date is to be used
8067	 * @return Date - the current date
8068	 */
8069	_getDateDatepicker: function(target, noDefault) {
8070		var inst = this._getInst(target);
8071		if (inst && !inst.inline) {
8072			this._setDateFromField(inst, noDefault);
8073		}
8074		return (inst ? this._getDate(inst) : null);
8075	},
8076
8077	/* Handle keystrokes. */
8078	_doKeyDown: function(event) {
8079		var onSelect, dateStr, sel,
8080			inst = $.datepicker._getInst(event.target),
8081			handled = true,
8082			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8083
8084		inst._keyEvent = true;
8085		if ($.datepicker._datepickerShowing) {
8086			switch (event.keyCode) {
8087				case 9: $.datepicker._hideDatepicker();
8088						handled = false;
8089						break; // hide on tab out
8090				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8091									$.datepicker._currentClass + ")", inst.dpDiv);
8092						if (sel[0]) {
8093							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8094						}
8095
8096						onSelect = $.datepicker._get(inst, "onSelect");
8097						if (onSelect) {
8098							dateStr = $.datepicker._formatDate(inst);
8099
8100							// trigger custom callback
8101							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8102						} else {
8103							$.datepicker._hideDatepicker();
8104						}
8105
8106						return false; // don't submit the form
8107				case 27: $.datepicker._hideDatepicker();
8108						break; // hide on escape
8109				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8110							-$.datepicker._get(inst, "stepBigMonths") :
8111							-$.datepicker._get(inst, "stepMonths")), "M");
8112						break; // previous month/year on page up/+ ctrl
8113				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8114							+$.datepicker._get(inst, "stepBigMonths") :
8115							+$.datepicker._get(inst, "stepMonths")), "M");
8116						break; // next month/year on page down/+ ctrl
8117				case 35: if (event.ctrlKey || event.metaKey) {
8118							$.datepicker._clearDate(event.target);
8119						}
8120						handled = event.ctrlKey || event.metaKey;
8121						break; // clear on ctrl or command +end
8122				case 36: if (event.ctrlKey || event.metaKey) {
8123							$.datepicker._gotoToday(event.target);
8124						}
8125						handled = event.ctrlKey || event.metaKey;
8126						break; // current on ctrl or command +home
8127				case 37: if (event.ctrlKey || event.metaKey) {
8128							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8129						}
8130						handled = event.ctrlKey || event.metaKey;
8131						// -1 day on ctrl or command +left
8132						if (event.originalEvent.altKey) {
8133							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
8134								-$.datepicker._get(inst, "stepBigMonths") :
8135								-$.datepicker._get(inst, "stepMonths")), "M");
8136						}
8137						// next month/year on alt +left on Mac
8138						break;
8139				case 38: if (event.ctrlKey || event.metaKey) {
8140							$.datepicker._adjustDate(event.target, -7, "D");
8141						}
8142						handled = event.ctrlKey || event.metaKey;
8143						break; // -1 week on ctrl or command +up
8144				case 39: if (event.ctrlKey || event.metaKey) {
8145							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8146						}
8147						handled = event.ctrlKey || event.metaKey;
8148						// +1 day on ctrl or command +right
8149						if (event.originalEvent.altKey) {
8150							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
8151								+$.datepicker._get(inst, "stepBigMonths") :
8152								+$.datepicker._get(inst, "stepMonths")), "M");
8153						}
8154						// next month/year on alt +right
8155						break;
8156				case 40: if (event.ctrlKey || event.metaKey) {
8157							$.datepicker._adjustDate(event.target, +7, "D");
8158						}
8159						handled = event.ctrlKey || event.metaKey;
8160						break; // +1 week on ctrl or command +down
8161				default: handled = false;
8162			}
8163		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8164			$.datepicker._showDatepicker(this);
8165		} else {
8166			handled = false;
8167		}
8168
8169		if (handled) {
8170			event.preventDefault();
8171			event.stopPropagation();
8172		}
8173	},
8174
8175	/* Filter entered characters - based on date format. */
8176	_doKeyPress: function(event) {
8177		var chars, chr,
8178			inst = $.datepicker._getInst(event.target);
8179
8180		if ($.datepicker._get(inst, "constrainInput")) {
8181			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8182			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8183			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8184		}
8185	},
8186
8187	/* Synchronise manual entry and field/alternate field. */
8188	_doKeyUp: function(event) {
8189		var date,
8190			inst = $.datepicker._getInst(event.target);
8191
8192		if (inst.input.val() !== inst.lastVal) {
8193			try {
8194				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8195					(inst.input ? inst.input.val() : null),
8196					$.datepicker._getFormatConfig(inst));
8197
8198				if (date) { // only if valid
8199					$.datepicker._setDateFromField(inst);
8200					$.datepicker._updateAlternate(inst);
8201					$.datepicker._updateDatepicker(inst);
8202				}
8203			}
8204			catch (err) {
8205			}
8206		}
8207		return true;
8208	},
8209
8210	/* Pop-up the date picker for a given input field.
8211	 * If false returned from beforeShow event handler do not show.
8212	 * @param  input  element - the input field attached to the date picker or
8213	 *					event - if triggered by focus
8214	 */
8215	_showDatepicker: function(input) {
8216		input = input.target || input;
8217		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8218			input = $("input", input.parentNode)[0];
8219		}
8220
8221		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8222			return;
8223		}
8224
8225		var inst, beforeShow, beforeShowSettings, isFixed,
8226			offset, showAnim, duration;
8227
8228		inst = $.datepicker._getInst(input);
8229		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8230			$.datepicker._curInst.dpDiv.stop(true, true);
8231			if ( inst && $.datepicker._datepickerShowing ) {
8232				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8233			}
8234		}
8235
8236		beforeShow = $.datepicker._get(inst, "beforeShow");
8237		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8238		if(beforeShowSettings === false){
8239			return;
8240		}
8241		
vendor: 5,662 bytes, lines 8241-8391
8241extendRemove(inst.settings, beforeShowSettings);
8242
8243		inst.lastVal = null;
8244		$.datepicker._lastInput = input;
8245		$.datepicker._setDateFromField(inst);
8246
8247		if ($.datepicker._inDialog) { // hide cursor
8248			input.value = "";
8249		}
8250		if (!$.datepicker._pos) { // position below input
8251			$.datepicker._pos = $.datepicker._findPos(input);
8252			$.datepicker._pos[1] += input.offsetHeight; // add the height
8253		}
8254
8255		isFixed = false;
8256		$(input).parents().each(function() {
8257			isFixed |= $(this).css("position") === "fixed";
8258			return !isFixed;
8259		});
8260
8261		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8262		$.datepicker._pos = null;
8263		//to avoid flashes on Firefox
8264		inst.dpDiv.empty();
8265		// determine sizing offscreen
8266		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8267		$.datepicker._updateDatepicker(inst);
8268		// fix width for dynamic number of date pickers
8269		// and adjust position before showing
8270		offset = $.datepicker._checkOffset(inst, offset, isFixed);
8271		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8272			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
8273			left: offset.left + "px", top: offset.top + "px"});
8274
8275		if (!inst.inline) {
8276			showAnim = $.datepicker._get(inst, "showAnim");
8277			duration = $.datepicker._get(inst, "duration");
8278			inst.dpDiv.zIndex($(input).zIndex()+1);
8279			$.datepicker._datepickerShowing = true;
8280
8281			if ( $.effects && $.effects.effect[ showAnim ] ) {
8282				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8283			} else {
8284				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8285			}
8286
8287			if (inst.input.is(":visible") && !inst.input.is(":disabled")) {
8288				inst.input.focus();
8289			}
8290			$.datepicker._curInst = inst;
8291		}
8292	},
8293
8294	/* Generate the date picker content. */
8295	_updateDatepicker: function(inst) {
8296		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8297		instActive = inst; // for delegate hover events
8298		inst.dpDiv.empty().append(this._generateHTML(inst));
8299		this._attachHandlers(inst);
8300		inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
8301
8302		var origyearshtml,
8303			numMonths = this._getNumberOfMonths(inst),
8304			cols = numMonths[1],
8305			width = 17;
8306
8307		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8308		if (cols > 1) {
8309			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8310		}
8311		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8312			"Class"]("ui-datepicker-multi");
8313		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8314			"Class"]("ui-datepicker-rtl");
8315
8316		// #6694 - don't focus the input if it's already focused
8317		// this breaks the change event in IE
8318		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
8319			inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) {
8320			inst.input.focus();
8321		}
8322
8323		// deffered render of the years select (to avoid flashes on Firefox)
8324		if( inst.yearshtml ){
8325			origyearshtml = inst.yearshtml;
8326			setTimeout(function(){
8327				//assure that inst.yearshtml didn't change.
8328				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8329					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8330				}
8331				origyearshtml = inst.yearshtml = null;
8332			}, 0);
8333		}
8334	},
8335
8336	/* Retrieve the size of left and top borders for an element.
8337	 * @param  elem  (jQuery object) the element of interest
8338	 * @return  (number[2]) the left and top borders
8339	 */
8340	_getBorders: function(elem) {
8341		var convert = function(value) {
8342			return {thin: 1, medium: 2, thick: 3}[value] || value;
8343		};
8344		return [parseFloat(convert(elem.css("border-left-width"))),
8345			parseFloat(convert(elem.css("border-top-width")))];
8346	},
8347
8348	/* Check positioning to remain on screen. */
8349	_checkOffset: function(inst, offset, isFixed) {
8350		var dpWidth = inst.dpDiv.outerWidth(),
8351			dpHeight = inst.dpDiv.outerHeight(),
8352			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8353			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8354			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8355			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8356
8357		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8358		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8359		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8360
8361		// now check if datepicker is showing outside window viewport - move to a better place if so.
8362		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8363			Math.abs(offset.left + dpWidth - viewWidth) : 0);
8364		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8365			Math.abs(dpHeight + inputHeight) : 0);
8366
8367		return offset;
8368	},
8369
8370	/* Find an object's position on the screen. */
8371	_findPos: function(obj) {
8372		var position,
8373			inst = this._getInst(obj),
8374			isRTL = this._get(inst, "isRTL");
8375
8376		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8377			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8378		}
8379
8380		position = $(obj).offset();
8381		return [position.left, position.top];
8382	},
8383
8384	/* Hide the date picker from view.
8385	 * @param  input  element - the input field attached to the date picker
8386	 */
8387	_hideDatepicker: function(input) {
8388		var showAnim, duration, postProcess, onClose,
8389			inst = this._curInst;
8390
8391		if (!inst || (input && inst !== $.data(input, PROP_NAME
vendor: 8,428 bytes, lines 8391-8647
8391))) {
8392			return;
8393		}
8394
8395		if (this._datepickerShowing) {
8396			showAnim = this._get(inst, "showAnim");
8397			duration = this._get(inst, "duration");
8398			postProcess = function() {
8399				$.datepicker._tidyDialog(inst);
8400			};
8401
8402			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8403			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8404				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8405			} else {
8406				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8407					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8408			}
8409
8410			if (!showAnim) {
8411				postProcess();
8412			}
8413			this._datepickerShowing = false;
8414
8415			onClose = this._get(inst, "onClose");
8416			if (onClose) {
8417				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8418			}
8419
8420			this._lastInput = null;
8421			if (this._inDialog) {
8422				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8423				if ($.blockUI) {
8424					$.unblockUI();
8425					$("body").append(this.dpDiv);
8426				}
8427			}
8428			this._inDialog = false;
8429		}
8430	},
8431
8432	/* Tidy up after a dialog display. */
8433	_tidyDialog: function(inst) {
8434		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8435	},
8436
8437	/* Close date picker if clicked elsewhere. */
8438	_checkExternalClick: function(event) {
8439		if (!$.datepicker._curInst) {
8440			return;
8441		}
8442
8443		var $target = $(event.target),
8444			inst = $.datepicker._getInst($target[0]);
8445
8446		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8447				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8448				!$target.hasClass($.datepicker.markerClassName) &&
8449				!$target.closest("." + $.datepicker._triggerClass).length &&
8450				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8451			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8452				$.datepicker._hideDatepicker();
8453		}
8454	},
8455
8456	/* Adjust one of the date sub-fields. */
8457	_adjustDate: function(id, offset, period) {
8458		var target = $(id),
8459			inst = this._getInst(target[0]);
8460
8461		if (this._isDisabledDatepicker(target[0])) {
8462			return;
8463		}
8464		this._adjustInstDate(inst, offset +
8465			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8466			period);
8467		this._updateDatepicker(inst);
8468	},
8469
8470	/* Action for current link. */
8471	_gotoToday: function(id) {
8472		var date,
8473			target = $(id),
8474			inst = this._getInst(target[0]);
8475
8476		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8477			inst.selectedDay = inst.currentDay;
8478			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8479			inst.drawYear = inst.selectedYear = inst.currentYear;
8480		} else {
8481			date = new Date();
8482			inst.selectedDay = date.getDate();
8483			inst.drawMonth = inst.selectedMonth = date.getMonth();
8484			inst.drawYear = inst.selectedYear = date.getFullYear();
8485		}
8486		this._notifyChange(inst);
8487		this._adjustDate(target);
8488	},
8489
8490	/* Action for selecting a new month/year. */
8491	_selectMonthYear: function(id, select, period) {
8492		var target = $(id),
8493			inst = this._getInst(target[0]);
8494
8495		inst["selected" + (period === "M" ? "Month" : "Year")] =
8496		inst["draw" + (period === "M" ? "Month" : "Year")] =
8497			parseInt(select.options[select.selectedIndex].value,10);
8498
8499		this._notifyChange(inst);
8500		this._adjustDate(target);
8501	},
8502
8503	/* Action for selecting a day. */
8504	_selectDay: function(id, month, year, td) {
8505		var inst,
8506			target = $(id);
8507
8508		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8509			return;
8510		}
8511
8512		inst = this._getInst(target[0]);
8513		inst.selectedDay = inst.currentDay = $("a", td).html();
8514		inst.selectedMonth = inst.currentMonth = month;
8515		inst.selectedYear = inst.currentYear = year;
8516		this._selectDate(id, this._formatDate(inst,
8517			inst.currentDay, inst.currentMonth, inst.currentYear));
8518	},
8519
8520	/* Erase the input field and hide the date picker. */
8521	_clearDate: function(id) {
8522		var target = $(id);
8523		this._selectDate(target, "");
8524	},
8525
8526	/* Update the input field with the selected date. */
8527	_selectDate: function(id, dateStr) {
8528		var onSelect,
8529			target = $(id),
8530			inst = this._getInst(target[0]);
8531
8532		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8533		if (inst.input) {
8534			inst.input.val(dateStr);
8535		}
8536		this._updateAlternate(inst);
8537
8538		onSelect = this._get(inst, "onSelect");
8539		if (onSelect) {
8540			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8541		} else if (inst.input) {
8542			inst.input.trigger("change"); // fire the change event
8543		}
8544
8545		if (inst.inline){
8546			this._updateDatepicker(inst);
8547		} else {
8548			this._hideDatepicker();
8549			this._lastInput = inst.input[0];
8550			if (typeof(inst.input[0]) !== "object") {
8551				inst.input.focus(); // restore focus
8552			}
8553			this._lastInput = null;
8554		}
8555	},
8556
8557	/* Update any alternate field to synchronise with the main field. */
8558	_updateAlternate: function(inst) {
8559		var altFormat, date, dateStr,
8560			altField = this._get(inst, "altField");
8561
8562		if (altField) { // update alternate field too
8563			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8564			date = this._getDate(inst);
8565			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8566			$(altField).each(function() { $(this).val(dateStr); });
8567		}
8568	},
8569
8570	/* Set as beforeShowDay function to prevent selection of weekends.
8571	 * @param  date  Date - the date to customise
8572	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8573	 */
8574	noWeekends: function(date) {
8575		var day = date.getDay();
8576		return [(day > 0 && day < 6), ""];
8577	},
8578
8579	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8580	 * @param  date  Date - the date to get the week for
8581	 * @return  number - the number of the week within the year that contains this date
8582	 */
8583	iso8601Week: function(date) {
8584		var time,
8585			checkDate = new Date(date.getTime());
8586
8587		// Find Thursday of this week starting on Monday
8588		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8589
8590		time = checkDate.getTime();
8591		checkDate.setMonth(0); // Compare with Jan 1
8592		checkDate.setDate(1);
8593		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8594	},
8595
8596	/* Parse a string value into a date object.
8597	 * See formatDate below for the possible formats.
8598	 *
8599	 * @param  format string - the expected format of the date
8600	 * @param  value string - the date in the above format
8601	 * @param  settings Object - attributes include:
8602	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8603	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8604	 *					dayNames		string[7] - names of the days from Sunday (optional)
8605	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8606	 *					monthNames		string[12] - names of the months (optional)
8607	 * @return  Date - the extracted date value or null if value is blank
8608	 */
8609	parseDate: function (format, value, settings) {
8610		if (format == null || value == null) {
8611			throw "Invalid arguments";
8612		}
8613
8614		value = (typeof value === "object" ? value.toString() : value + "");
8615		if (value === "") {
8616			return null;
8617		}
8618
8619		var iFormat, dim, extra,
8620			iValue = 0,
8621			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8622			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8623				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8624			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8625			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8626			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8627			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8628			year = -1,
8629			month = -1,
8630			day = -1,
8631			doy = -1,
8632			literal = false,
8633			date,
8634			// Check whether a format character is doubled
8635			lookAhead = function(match) {
8636				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8637				if (matches) {
8638					iFormat++;
8639				}
8640				return matches;
8641			},
8642			// Extract a number from the string value
8643			getNumber = function(match) {
8644				var isDoubled = lookAhead(match),
8645					size = (match === "@" ? 14 : (match === "!" ? 20 :
8646					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8647					
8647digits = new RegExp("^\\d{1
vendor: 13,244 bytes, lines 8647-9092
8647," + size + "}"),
8648					num = value.substring(iValue).match(digits);
8649				if (!num) {
8650					throw "Missing number at position " + iValue;
8651				}
8652				iValue += num[0].length;
8653				return parseInt(num[0], 10);
8654			},
8655			// Extract a name from the string value and convert to an index
8656			getName = function(match, shortNames, longNames) {
8657				var index = -1,
8658					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8659						return [ [k, v] ];
8660					}).sort(function (a, b) {
8661						return -(a[1].length - b[1].length);
8662					});
8663
8664				$.each(names, function (i, pair) {
8665					var name = pair[1];
8666					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8667						index = pair[0];
8668						iValue += name.length;
8669						return false;
8670					}
8671				});
8672				if (index !== -1) {
8673					return index + 1;
8674				} else {
8675					throw "Unknown name at position " + iValue;
8676				}
8677			},
8678			// Confirm that a literal character matches the string value
8679			checkLiteral = function() {
8680				if (value.charAt(iValue) !== format.charAt(iFormat)) {
8681					throw "Unexpected literal at position " + iValue;
8682				}
8683				iValue++;
8684			};
8685
8686		for (iFormat = 0; iFormat < format.length; iFormat++) {
8687			if (literal) {
8688				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8689					literal = false;
8690				} else {
8691					checkLiteral();
8692				}
8693			} else {
8694				switch (format.charAt(iFormat)) {
8695					case "d":
8696						day = getNumber("d");
8697						break;
8698					case "D":
8699						getName("D", dayNamesShort, dayNames);
8700						break;
8701					case "o":
8702						doy = getNumber("o");
8703						break;
8704					case "m":
8705						month = getNumber("m");
8706						break;
8707					case "M":
8708						month = getName("M", monthNamesShort, monthNames);
8709						break;
8710					case "y":
8711						year = getNumber("y");
8712						break;
8713					case "@":
8714						date = new Date(getNumber("@"));
8715						year = date.getFullYear();
8716						month = date.getMonth() + 1;
8717						day = date.getDate();
8718						break;
8719					case "!":
8720						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8721						year = date.getFullYear();
8722						month = date.getMonth() + 1;
8723						day = date.getDate();
8724						break;
8725					case "'":
8726						if (lookAhead("'")){
8727							checkLiteral();
8728						} else {
8729							literal = true;
8730						}
8731						break;
8732					default:
8733						checkLiteral();
8734				}
8735			}
8736		}
8737
8738		if (iValue < value.length){
8739			extra = value.substr(iValue);
8740			if (!/^\s+/.test(extra)) {
8741				throw "Extra/unparsed characters found in date: " + extra;
8742			}
8743		}
8744
8745		if (year === -1) {
8746			year = new Date().getFullYear();
8747		} else if (year < 100) {
8748			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8749				(year <= shortYearCutoff ? 0 : -100);
8750		}
8751
8752		if (doy > -1) {
8753			month = 1;
8754			day = doy;
8755			do {
8756				dim = this._getDaysInMonth(year, month - 1);
8757				if (day <= dim) {
8758					break;
8759				}
8760				month++;
8761				day -= dim;
8762			} while (true);
8763		}
8764
8765		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8766		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8767			throw "Invalid date"; // E.g. 31/02/00
8768		}
8769		return date;
8770	},
8771
8772	/* Standard date formats. */
8773	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8774	COOKIE: "D, dd M yy",
8775	ISO_8601: "yy-mm-dd",
8776	RFC_822: "D, d M y",
8777	RFC_850: "DD, dd-M-y",
8778	RFC_1036: "D, d M y",
8779	RFC_1123: "D, d M yy",
8780	RFC_2822: "D, d M yy",
8781	RSS: "D, d M y", // RFC 822
8782	TICKS: "!",
8783	TIMESTAMP: "@",
8784	W3C: "yy-mm-dd", // ISO 8601
8785
8786	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8787		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8788
8789	/* Format a date object into a string value.
8790	 * The format can be combinations of the following:
8791	 * d  - day of month (no leading zero)
8792	 * dd - day of month (two digit)
8793	 * o  - day of year (no leading zeros)
8794	 * oo - day of year (three digit)
8795	 * D  - day name short
8796	 * DD - day name long
8797	 * m  - month of year (no leading zero)
8798	 * mm - month of year (two digit)
8799	 * M  - month name short
8800	 * MM - month name long
8801	 * y  - year (two digit)
8802	 * yy - year (four digit)
8803	 * @ - Unix timestamp (ms since 01/01/1970)
8804	 * ! - Windows ticks (100ns since 01/01/0001)
8805	 * "..." - literal text
8806	 * '' - single quote
8807	 *
8808	 * @param  format string - the desired format of the date
8809	 * @param  date Date - the date value to format
8810	 * @param  settings Object - attributes include:
8811	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8812	 *					dayNames		string[7] - names of the days from Sunday (optional)
8813	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8814	 *					monthNames		string[12] - names of the months (optional)
8815	 * @return  string - the date in the above format
8816	 */
8817	formatDate: function (format, date, settings) {
8818		if (!date) {
8819			return "";
8820		}
8821
8822		var iFormat,
8823			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8824			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8825			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8826			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8827			// Check whether a format character is doubled
8828			lookAhead = function(match) {
8829				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8830				if (matches) {
8831					iFormat++;
8832				}
8833				return matches;
8834			},
8835			// Format a number, with leading zero if necessary
8836			formatNumber = function(match, value, len) {
8837				var num = "" + value;
8838				if (lookAhead(match)) {
8839					while (num.length < len) {
8840						num = "0" + num;
8841					}
8842				}
8843				return num;
8844			},
8845			// Format a name, short or long as requested
8846			formatName = function(match, value, shortNames, longNames) {
8847				return (lookAhead(match) ? longNames[value] : shortNames[value]);
8848			},
8849			output = "",
8850			literal = false;
8851
8852		if (date) {
8853			for (iFormat = 0; iFormat < format.length; iFormat++) {
8854				if (literal) {
8855					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8856						literal = false;
8857					} else {
8858						output += format.charAt(iFormat);
8859					}
8860				} else {
8861					switch (format.charAt(iFormat)) {
8862						case "d":
8863							output += formatNumber("d", date.getDate(), 2);
8864							break;
8865						case "D":
8866							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8867							break;
8868						case "o":
8869							output += formatNumber("o",
8870								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8871							break;
8872						case "m":
8873							output += formatNumber("m", date.getMonth() + 1, 2);
8874							break;
8875						case "M":
8876							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8877							break;
8878						case "y":
8879							output += (lookAhead("y") ? date.getFullYear() :
8880								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8881							break;
8882						case "@":
8883							output += date.getTime();
8884							break;
8885						case "!":
8886							output += date.getTime() * 10000 + this._ticksTo1970;
8887							break;
8888						case "'":
8889							if (lookAhead("'")) {
8890								output += "'";
8891							} else {
8892								literal = true;
8893							}
8894							break;
8895						default:
8896							output += format.charAt(iFormat);
8897					}
8898				}
8899			}
8900		}
8901		return output;
8902	},
8903
8904	/* Extract all possible characters from the date format. */
8905	_possibleChars: function (format) {
8906		var iFormat,
8907			chars = "",
8908			literal = false,
8909			// Check whether a format character is doubled
8910			lookAhead = function(match) {
8911				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8912				if (matches) {
8913					iFormat++;
8914				}
8915				return matches;
8916			};
8917
8918		for (iFormat = 0; iFormat < format.length; iFormat++) {
8919			if (literal) {
8920				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8921					literal = false;
8922				} else {
8923					chars += format.charAt(iFormat);
8924				}
8925			} else {
8926				switch (format.charAt(iFormat)) {
8927					case "d": case "m": case "y": case "@":
8928						chars += "0123456789";
8929						break;
8930					case "D": case "M":
8931						return null; // Accept anything
8932					case "'":
8933						if (lookAhead("'")) {
8934							chars += "'";
8935						} else {
8936							literal = true;
8937						}
8938						break;
8939					default:
8940						chars += format.charAt(iFormat);
8941				}
8942			}
8943		}
8944		return chars;
8945	},
8946
8947	/* Get a setting value, defaulting if necessary. */
8948	_get: function(inst, name) {
8949		return inst.settings[name] !== undefined ?
8950			inst.settings[name] : this._defaults[name];
8951	},
8952
8953	/* Parse existing date and initialise date picker. */
8954	_setDateFromField: function(inst, noDefault) {
8955		if (inst.input.val() === inst.lastVal) {
8956			return;
8957		}
8958
8959		var dateFormat = this._get(inst, "dateFormat"),
8960			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8961			defaultDate = this._getDefaultDate(inst),
8962			date = defaultDate,
8963			settings = this._getFormatConfig(inst);
8964
8965		try {
8966			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8967		} catch (event) {
8968			dates = (noDefault ? "" : dates);
8969		}
8970		inst.selectedDay = date.getDate();
8971		inst.drawMonth = inst.selectedMonth = date.getMonth();
8972		inst.drawYear = inst.selectedYear = date.getFullYear();
8973		inst.currentDay = (dates ? date.getDate() : 0);
8974		inst.currentMonth = (dates ? date.getMonth() : 0);
8975		inst.currentYear = (dates ? date.getFullYear() : 0);
8976		this._adjustInstDate(inst);
8977	},
8978
8979	/* Retrieve the default date shown on opening. */
8980	_getDefaultDate: function(inst) {
8981		return this._restrictMinMax(inst,
8982			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
8983	},
8984
8985	/* A date may be specified as an exact value or a relative one. */
8986	_determineDate: function(inst, date, defaultDate) {
8987		var offsetNumeric = function(offset) {
8988				var date = new Date();
8989				date.setDate(date.getDate() + offset);
8990				return date;
8991			},
8992			offsetString = function(offset) {
8993				try {
8994					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8995						offset, $.datepicker._getFormatConfig(inst));
8996				}
8997				catch (e) {
8998					// Ignore
8999				}
9000
9001				var date = (offset.toLowerCase().match(/^c/) ?
9002					$.datepicker._getDate(inst) : null) || new Date(),
9003					year = date.getFullYear(),
9004					month = date.getMonth(),
9005					day = date.getDate(),
9006					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9007					matches = pattern.exec(offset);
9008
9009				while (matches) {
9010					switch (matches[2] || "d") {
9011						case "d" : case "D" :
9012							day += parseInt(matches[1],10); break;
9013						case "w" : case "W" :
9014							day += parseInt(matches[1],10) * 7; break;
9015						case "m" : case "M" :
9016							month += parseInt(matches[1],10);
9017							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9018							break;
9019						case "y": case "Y" :
9020							year += parseInt(matches[1],10);
9021							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9022							break;
9023					}
9024					matches = pattern.exec(offset);
9025				}
9026				return new Date(year, month, day);
9027			},
9028			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9029				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9030
9031		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9032		if (newDate) {
9033			newDate.setHours(0);
9034			newDate.setMinutes(0);
9035			newDate.setSeconds(0);
9036			newDate.setMilliseconds(0);
9037		}
9038		return this._daylightSavingAdjust(newDate);
9039	},
9040
9041	/* Handle switch to/from daylight saving.
9042	 * Hours may be non-zero on daylight saving cut-over:
9043	 * > 12 when midnight changeover, but then cannot generate
9044	 * midnight datetime, so jump to 1AM, otherwise reset.
9045	 * @param  date  (Date) the date to check
9046	 * @return  (Date) the corrected date
9047	 */
9048	_daylightSavingAdjust: function(date) {
9049		if (!date) {
9050			return null;
9051		}
9052		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9053		return date;
9054	},
9055
9056	/* Set the date(s) directly. */
9057	_setDate: function(inst, date, noChange) {
9058		var clear = !date,
9059			origMonth = inst.selectedMonth,
9060			origYear = inst.selectedYear,
9061			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9062
9063		inst.selectedDay = inst.currentDay = newDate.getDate();
9064		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9065		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9066		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9067			this._notifyChange(inst);
9068		}
9069		this._adjustInstDate(inst);
9070		if (inst.input) {
9071			inst.input.val(clear ? "" : this._formatDate(inst));
9072		}
9073	},
9074
9075	/* Retrieve the date(s) directly. */
9076	_getDate: function(inst) {
9077		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9078			this._daylightSavingAdjust(new Date(
9079			inst.currentYear, inst.currentMonth, inst.currentDay)));
9080			return startDate;
9081	},
9082
9083	/* Attach the onxxx handlers.  These are declared statically so
9084	 * they work with static code transformers like Caja.
9085	 */
9086	_attachHandlers: function(inst) {
9087		var stepMonths = this._get(inst, "stepMonths"),
9088			id = "#" + inst.id.replace( /\\\\/g, "\\" );
9089		inst.dpDiv.find("[data-handler]").map(function () {
9090			var handler = {
9091				prev: function () {
9092					
vendor: 2,282 bytes, lines 9092-9141
9092window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, -stepMonths, "M");
9093				},
9094				next: function () {
9095					window["DP_jQuery_" + dpuuid].datepicker._adjustDate(id, +stepMonths, "M");
9096				},
9097				hide: function () {
9098					window["DP_jQuery_" + dpuuid].datepicker._hideDatepicker();
9099				},
9100				today: function () {
9101					window["DP_jQuery_" + dpuuid].datepicker._gotoToday(id);
9102				},
9103				selectDay: function () {
9104					window["DP_jQuery_" + dpuuid].datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9105					return false;
9106				},
9107				selectMonth: function () {
9108					window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "M");
9109					return false;
9110				},
9111				selectYear: function () {
9112					window["DP_jQuery_" + dpuuid].datepicker._selectMonthYear(id, this, "Y");
9113					return false;
9114				}
9115			};
9116			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9117		});
9118	},
9119
9120	/* Generate the HTML for the current state of the date picker. */
9121	_generateHTML: function(inst) {
9122		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9123			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9124			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9125			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9126			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9127			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9128			tempDate = new Date(),
9129			today = this._daylightSavingAdjust(
9130				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9131			isRTL = this._get(inst, "isRTL"),
9132			showButtonPanel = this._get(inst, "showButtonPanel"),
9133			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9134			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9135			numMonths = this._getNumberOfMonths(inst),
9136			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9137			stepMonths = this._get(inst, "stepMonths"),
9138			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9139			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9140				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9141			minDate = this._getMinMaxDate(inst, "min"),
vendor: 5,135 bytes, lines 9142-9241
9142			maxDate = this._getMinMaxDate(inst, "max"),
9143			drawMonth = inst.drawMonth - showCurrentAtPos,
9144			drawYear = inst.drawYear;
9145
9146		if (drawMonth < 0) {
9147			drawMonth += 12;
9148			drawYear--;
9149		}
9150		if (maxDate) {
9151			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9152				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9153			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9154			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9155				drawMonth--;
9156				if (drawMonth < 0) {
9157					drawMonth = 11;
9158					drawYear--;
9159				}
9160			}
9161		}
9162		inst.drawMonth = drawMonth;
9163		inst.drawYear = drawYear;
9164
9165		prevText = this._get(inst, "prevText");
9166		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9167			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9168			this._getFormatConfig(inst)));
9169
9170		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9171			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9172			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9173			(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>"));
9174
9175		nextText = this._get(inst, "nextText");
9176		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9177			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9178			this._getFormatConfig(inst)));
9179
9180		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9181			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9182			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9183			(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>"));
9184
9185		currentText = this._get(inst, "currentText");
9186		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9187		currentText = (!navigationAsDateFormat ? currentText :
9188			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9189
9190		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'>" +
9191			this._get(inst, "closeText") + "</button>" : "");
9192
9193		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9194			(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'" +
9195			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9196
9197		firstDay = parseInt(this._get(inst, "firstDay"),10);
9198		firstDay = (isNaN(firstDay) ? 0 : firstDay);
9199
9200		showWeek = this._get(inst, "showWeek");
9201		dayNames = this._get(inst, "dayNames");
9202		dayNamesMin = this._get(inst, "dayNamesMin");
9203		monthNames = this._get(inst, "monthNames");
9204		monthNamesShort = this._get(inst, "monthNamesShort");
9205		beforeShowDay = this._get(inst, "beforeShowDay");
9206		showOtherMonths = this._get(inst, "showOtherMonths");
9207		selectOtherMonths = this._get(inst, "selectOtherMonths");
9208		defaultDate = this._getDefaultDate(inst);
9209		html = "";
9210		dow;
9211		for (row = 0; row < numMonths[0]; row++) {
9212			group = "";
9213			this.maxRows = 4;
9214			for (col = 0; col < numMonths[1]; col++) {
9215				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9216				cornerClass = " ui-corner-all";
9217				calender = "";
9218				if (isMultiMonth) {
9219					calender += "<div class='ui-datepicker-group";
9220					if (numMonths[1] > 1) {
9221						switch (col) {
9222							case 0: calender += " ui-datepicker-group-first";
9223								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9224							case numMonths[1]-1: calender += " ui-datepicker-group-last";
9225								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9226							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9227						}
9228					}
9229					calender += "'>";
9230				}
9231				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9232					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9233					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9234					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9235					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9236					"</div><table class='ui-datepicker-calendar'><thead>" +
9237					"<tr>";
9238				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9239				for (dow = 0; dow < 7; dow++) { // days of the week
9240					day = (dow + firstDay) % 7;
9241					thead += "<th
vendor: 11,347 bytes, lines 9241-9495
9241" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9242						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9243				}
9244				calender += thead + "</tr></thead><tbody>";
9245				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9246				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9247					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9248				}
9249				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9250				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9251				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9252				this.maxRows = numRows;
9253				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9254				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9255					calender += "<tr>";
9256					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9257						this._get(inst, "calculateWeek")(printDate) + "</td>");
9258					for (dow = 0; dow < 7; dow++) { // create date picker days
9259						daySettings = (beforeShowDay ?
9260							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9261						otherMonth = (printDate.getMonth() !== drawMonth);
9262						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9263							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9264						tbody += "<td class='" +
9265							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9266							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9267							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9268							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9269							// or defaultDate is current printedDate and defaultDate is selectedDate
9270							" " + this._dayOverClass : "") + // highlight selected day
9271							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
9272							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9273							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9274							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9275							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9276							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9277							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9278							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9279							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9280							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9281							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9282							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9283						printDate.setDate(printDate.getDate() + 1);
9284						printDate = this._daylightSavingAdjust(printDate);
9285					}
9286					calender += tbody + "</tr>";
9287				}
9288				drawMonth++;
9289				if (drawMonth > 11) {
9290					drawMonth = 0;
9291					drawYear++;
9292				}
9293				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9294							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9295				group += calender;
9296			}
9297			html += group;
9298		}
9299		html += buttonPanel;
9300		inst._keyEvent = false;
9301		return html;
9302	},
9303
9304	/* Generate the month and year header. */
9305	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9306			secondary, monthNames, monthNamesShort) {
9307
9308		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9309			changeMonth = this._get(inst, "changeMonth"),
9310			changeYear = this._get(inst, "changeYear"),
9311			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9312			html = "<div class='ui-datepicker-title'>",
9313			monthHtml = "";
9314
9315		// month selection
9316		if (secondary || !changeMonth) {
9317			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9318		} else {
9319			inMinYear = (minDate && minDate.getFullYear() === drawYear);
9320			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9321			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9322			for ( month = 0; month < 12; month++) {
9323				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9324					monthHtml += "<option value='" + month + "'" +
9325						(month === drawMonth ? " selected='selected'" : "") +
9326						">" + monthNamesShort[month] + "</option>";
9327				}
9328			}
9329			monthHtml += "</select>";
9330		}
9331
9332		if (!showMonthAfterYear) {
9333			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9334		}
9335
9336		// year selection
9337		if ( !inst.yearshtml ) {
9338			inst.yearshtml = "";
9339			if (secondary || !changeYear) {
9340				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9341			} else {
9342				// determine range of years to display
9343				years = this._get(inst, "yearRange").split(":");
9344				thisYear = new Date().getFullYear();
9345				determineYear = function(value) {
9346					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9347						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9348						parseInt(value, 10)));
9349					return (isNaN(year) ? thisYear : year);
9350				};
9351				year = determineYear(years[0]);
9352				endYear = Math.max(year, determineYear(years[1] || ""));
9353				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9354				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9355				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9356				for (; year <= endYear; year++) {
9357					inst.yearshtml += "<option value='" + year + "'" +
9358						(year === drawYear ? " selected='selected'" : "") +
9359						">" + year + "</option>";
9360				}
9361				inst.yearshtml += "</select>";
9362
9363				html += inst.yearshtml;
9364				inst.yearshtml = null;
9365			}
9366		}
9367
9368		html += this._get(inst, "yearSuffix");
9369		if (showMonthAfterYear) {
9370			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9371		}
9372		html += "</div>"; // Close datepicker_header
9373		return html;
9374	},
9375
9376	/* Adjust one of the date sub-fields. */
9377	_adjustInstDate: function(inst, offset, period) {
9378		var year = inst.drawYear + (period === "Y" ? offset : 0),
9379			month = inst.drawMonth + (period === "M" ? offset : 0),
9380			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9381			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9382
9383		inst.selectedDay = date.getDate();
9384		inst.drawMonth = inst.selectedMonth = date.getMonth();
9385		inst.drawYear = inst.selectedYear = date.getFullYear();
9386		if (period === "M" || period === "Y") {
9387			this._notifyChange(inst);
9388		}
9389	},
9390
9391	/* Ensure a date is within any min/max bounds. */
9392	_restrictMinMax: function(inst, date) {
9393		var minDate = this._getMinMaxDate(inst, "min"),
9394			maxDate = this._getMinMaxDate(inst, "max"),
9395			newDate = (minDate && date < minDate ? minDate : date);
9396		return (maxDate && newDate > maxDate ? maxDate : newDate);
9397	},
9398
9399	/* Notify change of month/year. */
9400	_notifyChange: function(inst) {
9401		var onChange = this._get(inst, "onChangeMonthYear");
9402		if (onChange) {
9403			onChange.apply((inst.input ? inst.input[0] : null),
9404				[inst.selectedYear, inst.selectedMonth + 1, inst]);
9405		}
9406	},
9407
9408	/* Determine the number of months to show. */
9409	_getNumberOfMonths: function(inst) {
9410		var numMonths = this._get(inst, "numberOfMonths");
9411		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9412	},
9413
9414	/* Determine the current maximum date - ensure no time components are set. */
9415	_getMinMaxDate: function(inst, minMax) {
9416		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9417	},
9418
9419	/* Find the number of days in a given month. */
9420	_getDaysInMonth: function(year, month) {
9421		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9422	},
9423
9424	/* Find the day of the week of the first of a month. */
9425	_getFirstDayOfMonth: function(year, month) {
9426		return new Date(year, month, 1).getDay();
9427	},
9428
9429	/* Determines if we should allow a "next/prev" month display change. */
9430	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
9431		var numMonths = this._getNumberOfMonths(inst),
9432			date = this._daylightSavingAdjust(new Date(curYear,
9433			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9434
9435		if (offset < 0) {
9436			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9437		}
9438		return this._isInRange(inst, date);
9439	},
9440
9441	/* Is the given date in the accepted range? */
9442	_isInRange: function(inst, date) {
9443		var yearSplit, currentYear,
9444			minDate = this._getMinMaxDate(inst, "min"),
9445			maxDate = this._getMinMaxDate(inst, "max"),
9446			minYear = null,
9447			maxYear = null,
9448			years = this._get(inst, "yearRange");
9449			if (years){
9450				yearSplit = years.split(":");
9451				currentYear = new Date().getFullYear();
9452				minYear = parseInt(yearSplit[0], 10);
9453				maxYear = parseInt(yearSplit[1], 10);
9454				if ( yearSplit[0].match(/[+\-].*/) ) {
9455					minYear += currentYear;
9456				}
9457				if ( yearSplit[1].match(/[+\-].*/) ) {
9458					maxYear += currentYear;
9459				}
9460			}
9461
9462		return ((!minDate || date.getTime() >= minDate.getTime()) &&
9463			(!maxDate || date.getTime() <= maxDate.getTime()) &&
9464			(!minYear || date.getFullYear() >= minYear) &&
9465			(!maxYear || date.getFullYear() <= maxYear));
9466	},
9467
9468	/* Provide the configuration settings for formatting/parsing. */
9469	_getFormatConfig: function(inst) {
9470		var shortYearCutoff = this._get(inst, "shortYearCutoff");
9471		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9472			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9473		return {shortYearCutoff: shortYearCutoff,
9474			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9475			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9476	},
9477
9478	/* Format the given date for display. */
9479	_formatDate: function(inst, day, month, year) {
9480		if (!day) {
9481			inst.currentDay = inst.selectedDay;
9482			inst.currentMonth = inst.selectedMonth;
9483			inst.currentYear = inst.selectedYear;
9484		}
9485		var date = (day ? (typeof day === "object" ? day :
9486			this._daylightSavingAdjust(new Date(year, month, day))) :
9487			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9488		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9489	}
9490});
9491
9492/*
9493 * Bind hover events for datepicker elements.
9494 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9495 * Global 
vendor: 143,406 bytes, lines 9495-14936
9495instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9496 */
9497function bindHover(dpDiv) {
9498	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9499	return dpDiv.delegate(selector, "mouseout", function() {
9500			$(this).removeClass("ui-state-hover");
9501			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9502				$(this).removeClass("ui-datepicker-prev-hover");
9503			}
9504			if (this.className.indexOf("ui-datepicker-next") !== -1) {
9505				$(this).removeClass("ui-datepicker-next-hover");
9506			}
9507		})
9508		.delegate(selector, "mouseover", function(){
9509			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
9510				$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9511				$(this).addClass("ui-state-hover");
9512				if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9513					$(this).addClass("ui-datepicker-prev-hover");
9514				}
9515				if (this.className.indexOf("ui-datepicker-next") !== -1) {
9516					$(this).addClass("ui-datepicker-next-hover");
9517				}
9518			}
9519		});
9520}
9521
9522/* jQuery extend now ignores nulls! */
9523function extendRemove(target, props) {
9524	$.extend(target, props);
9525	for (var name in props) {
9526		if (props[name] == null) {
9527			target[name] = props[name];
9528		}
9529	}
9530	return target;
9531}
9532
9533/* Invoke the datepicker functionality.
9534   @param  options  string - a command, optionally followed by additional parameters or
9535					Object - settings for attaching new datepicker functionality
9536   @return  jQuery object */
9537$.fn.datepicker = function(options){
9538
9539	/* Verify an empty collection wasn't passed - Fixes #6976 */
9540	if ( !this.length ) {
9541		return this;
9542	}
9543
9544	/* Initialise the date picker. */
9545	if (!$.datepicker.initialized) {
9546		$(document).mousedown($.datepicker._checkExternalClick);
9547		$.datepicker.initialized = true;
9548	}
9549
9550	/* Append datepicker main container to body if not exist. */
9551	if ($("#"+$.datepicker._mainDivId).length === 0) {
9552		$("body").append($.datepicker.dpDiv);
9553	}
9554
9555	var otherArgs = Array.prototype.slice.call(arguments, 1);
9556	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9557		return $.datepicker["_" + options + "Datepicker"].
9558			apply($.datepicker, [this[0]].concat(otherArgs));
9559	}
9560	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9561		return $.datepicker["_" + options + "Datepicker"].
9562			apply($.datepicker, [this[0]].concat(otherArgs));
9563	}
9564	return this.each(function() {
9565		typeof options === "string" ?
9566			$.datepicker["_" + options + "Datepicker"].
9567				apply($.datepicker, [this].concat(otherArgs)) :
9568			$.datepicker._attachDatepicker(this, options);
9569	});
9570};
9571
9572$.datepicker = new Datepicker(); // singleton instance
9573$.datepicker.initialized = false;
9574$.datepicker.uuid = new Date().getTime();
9575$.datepicker.version = "1.10.1";
9576
9577// Workaround for #4055
9578// Add another global to avoid noConflict issues with inline event handlers
9579window["DP_jQuery_" + dpuuid] = $;
9580
9581})(jQuery);
9582
9583(function( $, undefined ) {
9584
9585var sizeRelatedOptions = {
9586		buttons: true,
9587		height: true,
9588		maxHeight: true,
9589		maxWidth: true,
9590		minHeight: true,
9591		minWidth: true,
9592		width: true
9593	},
9594	resizableRelatedOptions = {
9595		maxHeight: true,
9596		maxWidth: true,
9597		minHeight: true,
9598		minWidth: true
9599	};
9600
9601$.widget( "ui.dialog", {
9602	version: "1.10.1",
9603	options: {
9604		appendTo: "body",
9605		autoOpen: true,
9606		buttons: [],
9607		closeOnEscape: true,
9608		closeText: "close",
9609		dialogClass: "",
9610		draggable: true,
9611		hide: null,
9612		height: "auto",
9613		maxHeight: null,
9614		maxWidth: null,
9615		minHeight: 150,
9616		minWidth: 150,
9617		modal: false,
9618		position: {
9619			my: "center",
9620			at: "center",
9621			of: window,
9622			collision: "fit",
9623			// Ensure the titlebar is always visible
9624			using: function( pos ) {
9625				var topOffset = $( this ).css( pos ).offset().top;
9626				if ( topOffset < 0 ) {
9627					$( this ).css( "top", pos.top - topOffset );
9628				}
9629			}
9630		},
9631		resizable: true,
9632		show: null,
9633		title: null,
9634		width: 300,
9635
9636		// callbacks
9637		beforeClose: null,
9638		close: null,
9639		drag: null,
9640		dragStart: null,
9641		dragStop: null,
9642		focus: null,
9643		open: null,
9644		resize: null,
9645		resizeStart: null,
9646		resizeStop: null
9647	},
9648
9649	_create: function() {
9650		this.originalCss = {
9651			display: this.element[0].style.display,
9652			width: this.element[0].style.width,
9653			minHeight: this.element[0].style.minHeight,
9654			maxHeight: this.element[0].style.maxHeight,
9655			height: this.element[0].style.height
9656		};
9657		this.originalPosition = {
9658			parent: this.element.parent(),
9659			index: this.element.parent().children().index( this.element )
9660		};
9661		this.originalTitle = this.element.attr("title");
9662		this.options.title = this.options.title || this.originalTitle;
9663
9664		this._createWrapper();
9665
9666		this.element
9667			.show()
9668			.removeAttr("title")
9669			.addClass("ui-dialog-content ui-widget-content")
9670			.appendTo( this.uiDialog );
9671
9672		this._createTitlebar();
9673		this._createButtonPane();
9674
9675		if ( this.options.draggable && $.fn.draggable ) {
9676			this._makeDraggable();
9677		}
9678		if ( this.options.resizable && $.fn.resizable ) {
9679			this._makeResizable();
9680		}
9681
9682		this._isOpen = false;
9683	},
9684
9685	_init: function() {
9686		if ( this.options.autoOpen ) {
9687			this.open();
9688		}
9689	},
9690
9691	_appendTo: function() {
9692		var element = this.options.appendTo;
9693		if ( element && (element.jquery || element.nodeType) ) {
9694			return $( element );
9695		}
9696		return this.document.find( element || "body" ).eq( 0 );
9697	},
9698
9699	_destroy: function() {
9700		var next,
9701			originalPosition = this.originalPosition;
9702
9703		this._destroyOverlay();
9704
9705		this.element
9706			.removeUniqueId()
9707			.removeClass("ui-dialog-content ui-widget-content")
9708			.css( this.originalCss )
9709			// Without detaching first, the following becomes really slow
9710			.detach();
9711
9712		this.uiDialog.stop( true, true ).remove();
9713
9714		if ( this.originalTitle ) {
9715			this.element.attr( "title", this.originalTitle );
9716		}
9717
9718		next = originalPosition.parent.children().eq( originalPosition.index );
9719		// Don't try to place the dialog next to itself (#8613)
9720		if ( next.length && next[0] !== this.element[0] ) {
9721			next.before( this.element );
9722		} else {
9723			originalPosition.parent.append( this.element );
9724		}
9725	},
9726
9727	widget: function() {
9728		return this.uiDialog;
9729	},
9730
9731	disable: $.noop,
9732	enable: $.noop,
9733
9734	close: function( event ) {
9735		var that = this;
9736
9737		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
9738			return;
9739		}
9740
9741		this._isOpen = false;
9742		this._destroyOverlay();
9743
9744		if ( !this.opener.filter(":focusable").focus().length ) {
9745			// Hiding a focused element doesn't trigger blur in WebKit
9746			// so in case we have nothing to focus on, explicitly blur the active element
9747			// https://bugs.webkit.org/show_bug.cgi?id=47182
9748			$( this.document[0].activeElement ).blur();
9749		}
9750
9751		this._hide( this.uiDialog, this.options.hide, function() {
9752			that._trigger( "close", event );
9753		});
9754	},
9755
9756	isOpen: function() {
9757		return this._isOpen;
9758	},
9759
9760	moveToTop: function() {
9761		this._moveToTop();
9762	},
9763
9764	_moveToTop: function( event, silent ) {
9765		var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9766		if ( moved && !silent ) {
9767			this._trigger( "focus", event );
9768		}
9769		return moved;
9770	},
9771
9772	open: function() {
9773		var that = this;
9774		if ( this._isOpen ) {
9775			if ( this._moveToTop() ) {
9776				this._focusTabbable();
9777			}
9778			return;
9779		}
9780
9781		this._isOpen = true;
9782		this.opener = $( this.document[0].activeElement );
9783
9784		this._size();
9785		this._position();
9786		this._createOverlay();
9787		this._moveToTop( null, true );
9788		this._show( this.uiDialog, this.options.show, function() {
9789			that._focusTabbable();
9790			that._trigger("focus");
9791		});
9792
9793		this._trigger("open");
9794	},
9795
9796	_focusTabbable: function() {
9797		// Set focus to the first match:
9798		// 1. First element inside the dialog matching [autofocus]
9799		// 2. Tabbable element inside the content element
9800		// 3. Tabbable element inside the buttonpane
9801		// 4. The close button
9802		// 5. The dialog itself
9803		var hasFocus = this.element.find("[autofocus]");
9804		if ( !hasFocus.length ) {
9805			hasFocus = this.element.find(":tabbable");
9806		}
9807		if ( !hasFocus.length ) {
9808			hasFocus = this.uiDialogButtonPane.find(":tabbable");
9809		}
9810		if ( !hasFocus.length ) {
9811			hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9812		}
9813		if ( !hasFocus.length ) {
9814			hasFocus = this.uiDialog;
9815		}
9816		hasFocus.eq( 0 ).focus();
9817	},
9818
9819	_keepFocus: function( event ) {
9820		function checkFocus() {
9821			var activeElement = this.document[0].activeElement,
9822				isActive = this.uiDialog[0] === activeElement ||
9823					$.contains( this.uiDialog[0], activeElement );
9824			if ( !isActive ) {
9825				this._focusTabbable();
9826			}
9827		}
9828		event.preventDefault();
9829		checkFocus.call( this );
9830		// support: IE
9831		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9832		// so we check again later
9833		this._delay( checkFocus );
9834	},
9835
9836	_createWrapper: function() {
9837		this.uiDialog = $("<div>")
9838			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9839				this.options.dialogClass )
9840			.hide()
9841			.attr({
9842				// Setting tabIndex makes the div focusable
9843				tabIndex: -1,
9844				role: "dialog"
9845			})
9846			.appendTo( this._appendTo() );
9847
9848		this._on( this.uiDialog, {
9849			keydown: function( event ) {
9850				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9851						event.keyCode === $.ui.keyCode.ESCAPE ) {
9852					event.preventDefault();
9853					this.close( event );
9854					return;
9855				}
9856
9857				// prevent tabbing out of dialogs
9858				if ( event.keyCode !== $.ui.keyCode.TAB ) {
9859					return;
9860				}
9861				var tabbables = this.uiDialog.find(":tabbable"),
9862					first = tabbables.filter(":first"),
9863					last  = tabbables.filter(":last");
9864
9865				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9866					first.focus( 1 );
9867					event.preventDefault();
9868				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9869					last.focus( 1 );
9870					event.preventDefault();
9871				}
9872			},
9873			mousedown: function( event ) {
9874				if ( this._moveToTop( event ) ) {
9875					this._focusTabbable();
9876				}
9877			}
9878		});
9879
9880		// We assume that any existing aria-describedby attribute means
9881		// that the dialog content is marked up properly
9882		// otherwise we brute force the content as the description
9883		if ( !this.element.find("[aria-describedby]").length ) {
9884			this.uiDialog.attr({
9885				"aria-describedby": this.element.uniqueId().attr("id")
9886			});
9887		}
9888	},
9889
9890	_createTitlebar: function() {
9891		var uiDialogTitle;
9892
9893		this.uiDialogTitlebar = $("<div>")
9894			.addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9895			.prependTo( this.uiDialog );
9896		this._on( this.uiDialogTitlebar, {
9897			mousedown: function( event ) {
9898				// Don't prevent click on close button (#8838)
9899				// Focusing a dialog that is partially scrolled out of view
9900				// causes the browser to scroll it into view, preventing the click event
9901				if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9902					// Dialog isn't getting focus when dragging (#8063)
9903					this.uiDialog.focus();
9904				}
9905			}
9906		});
9907
9908		this.uiDialogTitlebarClose = $("<button></button>")
9909			.button({
9910				label: this.options.closeText,
9911				icons: {
9912					primary: "ui-icon-closethick"
9913				},
9914				text: false
9915			})
9916			.addClass("ui-dialog-titlebar-close")
9917			.appendTo( this.uiDialogTitlebar );
9918		this._on( this.uiDialogTitlebarClose, {
9919			click: function( event ) {
9920				event.preventDefault();
9921				this.close( event );
9922			}
9923		});
9924
9925		uiDialogTitle = $("<span>")
9926			.uniqueId()
9927			.addClass("ui-dialog-title")
9928			.prependTo( this.uiDialogTitlebar );
9929		this._title( uiDialogTitle );
9930
9931		this.uiDialog.attr({
9932			"aria-labelledby": uiDialogTitle.attr("id")
9933		});
9934	},
9935
9936	_title: function( title ) {
9937		if ( !this.options.title ) {
9938			title.html("&#160;");
9939		}
9940		title.text( this.options.title );
9941	},
9942
9943	_createButtonPane: function() {
9944		this.uiDialogButtonPane = $("<div>")
9945			.addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
9946
9947		this.uiButtonSet = $("<div>")
9948			.addClass("ui-dialog-buttonset")
9949			.appendTo( this.uiDialogButtonPane );
9950
9951		this._createButtons();
9952	},
9953
9954	_createButtons: function() {
9955		var that = this,
9956			buttons = this.options.buttons;
9957
9958		// if we already have a button pane, remove it
9959		this.uiDialogButtonPane.remove();
9960		this.uiButtonSet.empty();
9961
9962		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
9963			this.uiDialog.removeClass("ui-dialog-buttons");
9964			return;
9965		}
9966
9967		$.each( buttons, function( name, props ) {
9968			var click, buttonOptions;
9969			props = $.isFunction( props ) ?
9970				{ click: props, text: name } :
9971				props;
9972			// Default to a non-submitting button
9973			props = $.extend( { type: "button" }, props );
9974			// Change the context for the click callback to be the main element
9975			click = props.click;
9976			props.click = function() {
9977				click.apply( that.element[0], arguments );
9978			};
9979			buttonOptions = {
9980				icons: props.icons,
9981				text: props.showText
9982			};
9983			delete props.icons;
9984			delete props.showText;
9985			$( "<button></button>", props )
9986				.button( buttonOptions )
9987				.appendTo( that.uiButtonSet );
9988		});
9989		this.uiDialog.addClass("ui-dialog-buttons");
9990		this.uiDialogButtonPane.appendTo( this.uiDialog );
9991	},
9992
9993	_makeDraggable: function() {
9994		var that = this,
9995			options = this.options;
9996
9997		function filteredUi( ui ) {
9998			return {
9999				position: ui.position,
10000				offset: ui.offset
10001			};
10002		}
10003
10004		this.uiDialog.draggable({
10005			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10006			handle: ".ui-dialog-titlebar",
10007			containment: "document",
10008			start: function( event, ui ) {
10009				$( this ).addClass("ui-dialog-dragging");
10010				that._blockFrames();
10011				that._trigger( "dragStart", event, filteredUi( ui ) );
10012			},
10013			drag: function( event, ui ) {
10014				that._trigger( "drag", event, filteredUi( ui ) );
10015			},
10016			stop: function( event, ui ) {
10017				options.position = [
10018					ui.position.left - that.document.scrollLeft(),
10019					ui.position.top - that.document.scrollTop()
10020				];
10021				$( this ).removeClass("ui-dialog-dragging");
10022				that._unblockFrames();
10023				that._trigger( "dragStop", event, filteredUi( ui ) );
10024			}
10025		});
10026	},
10027
10028	_makeResizable: function() {
10029		var that = this,
10030			options = this.options,
10031			handles = options.resizable,
10032			// .ui-resizable has position: relative defined in the stylesheet
10033			// but dialogs have to use absolute or fixed positioning
10034			position = this.uiDialog.css("position"),
10035			resizeHandles = typeof handles === "string" ?
10036				handles	:
10037				"n,e,s,w,se,sw,ne,nw";
10038
10039		function filteredUi( ui ) {
10040			return {
10041				originalPosition: ui.originalPosition,
10042				originalSize: ui.originalSize,
10043				position: ui.position,
10044				size: ui.size
10045			};
10046		}
10047
10048		this.uiDialog.resizable({
10049			cancel: ".ui-dialog-content",
10050			containment: "document",
10051			alsoResize: this.element,
10052			maxWidth: options.maxWidth,
10053			maxHeight: options.maxHeight,
10054			minWidth: options.minWidth,
10055			minHeight: this._minHeight(),
10056			handles: resizeHandles,
10057			start: function( event, ui ) {
10058				$( this ).addClass("ui-dialog-resizing");
10059				that._blockFrames();
10060				that._trigger( "resizeStart", event, filteredUi( ui ) );
10061			},
10062			resize: function( event, ui ) {
10063				that._trigger( "resize", event, filteredUi( ui ) );
10064			},
10065			stop: function( event, ui ) {
10066				options.height = $( this ).height();
10067				options.width = $( this ).width();
10068				$( this ).removeClass("ui-dialog-resizing");
10069				that._unblockFrames();
10070				that._trigger( "resizeStop", event, filteredUi( ui ) );
10071			}
10072		})
10073		.css( "position", position );
10074	},
10075
10076	_minHeight: function() {
10077		var options = this.options;
10078
10079		return options.height === "auto" ?
10080			options.minHeight :
10081			Math.min( options.minHeight, options.height );
10082	},
10083
10084	_position: function() {
10085		// Need to show the dialog to get the actual offset in the position plugin
10086		var isVisible = this.uiDialog.is(":visible");
10087		if ( !isVisible ) {
10088			this.uiDialog.show();
10089		}
10090		this.uiDialog.position( this.options.position );
10091		if ( !isVisible ) {
10092			this.uiDialog.hide();
10093		}
10094	},
10095
10096	_setOptions: function( options ) {
10097		var that = this,
10098			resize = false,
10099			resizableOptions = {};
10100
10101		$.each( options, function( key, value ) {
10102			that._setOption( key, value );
10103
10104			if ( key in sizeRelatedOptions ) {
10105				resize = true;
10106			}
10107			if ( key in resizableRelatedOptions ) {
10108				resizableOptions[ key ] = value;
10109			}
10110		});
10111
10112		if ( resize ) {
10113			this._size();
10114			this._position();
10115		}
10116		if ( this.uiDialog.is(":data(ui-resizable)") ) {
10117			this.uiDialog.resizable( "option", resizableOptions );
10118		}
10119	},
10120
10121	_setOption: function( key, value ) {
10122		/*jshint maxcomplexity:15*/
10123		var isDraggable, isResizable,
10124			uiDialog = this.uiDialog;
10125
10126		if ( key === "dialogClass" ) {
10127			uiDialog
10128				.removeClass( this.options.dialogClass )
10129				.addClass( value );
10130		}
10131
10132		if ( key === "disabled" ) {
10133			return;
10134		}
10135
10136		this._super( key, value );
10137
10138		if ( key === "appendTo" ) {
10139			this.uiDialog.appendTo( this._appendTo() );
10140		}
10141
10142		if ( key === "buttons" ) {
10143			this._createButtons();
10144		}
10145
10146		if ( key === "closeText" ) {
10147			this.uiDialogTitlebarClose.button({
10148				// Ensure that we always pass a string
10149				label: "" + value
10150			});
10151		}
10152
10153		if ( key === "draggable" ) {
10154			isDraggable = uiDialog.is(":data(ui-draggable)");
10155			if ( isDraggable && !value ) {
10156				uiDialog.draggable("destroy");
10157			}
10158
10159			if ( !isDraggable && value ) {
10160				this._makeDraggable();
10161			}
10162		}
10163
10164		if ( key === "position" ) {
10165			this._position();
10166		}
10167
10168		if ( key === "resizable" ) {
10169			// currently resizable, becoming non-resizable
10170			isResizable = uiDialog.is(":data(ui-resizable)");
10171			if ( isResizable && !value ) {
10172				uiDialog.resizable("destroy");
10173			}
10174
10175			// currently resizable, changing handles
10176			if ( isResizable && typeof value === "string" ) {
10177				uiDialog.resizable( "option", "handles", value );
10178			}
10179
10180			// currently non-resizable, becoming resizable
10181			if ( !isResizable && value !== false ) {
10182				this._makeResizable();
10183			}
10184		}
10185
10186		if ( key === "title" ) {
10187			this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
10188		}
10189	},
10190
10191	_size: function() {
10192		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10193		// divs will both have width and height set, so we need to reset them
10194		var nonContentHeight, minContentHeight, maxContentHeight,
10195			options = this.options;
10196
10197		// Reset content sizing
10198		this.element.show().css({
10199			width: "auto",
10200			minHeight: 0,
10201			maxHeight: "none",
10202			height: 0
10203		});
10204
10205		if ( options.minWidth > options.width ) {
10206			options.width = options.minWidth;
10207		}
10208
10209		// reset wrapper sizing
10210		// determine the height of all the non-content elements
10211		nonContentHeight = this.uiDialog.css({
10212				height: "auto",
10213				width: options.width
10214			})
10215			.outerHeight();
10216		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10217		maxContentHeight = typeof options.maxHeight === "number" ?
10218			Math.max( 0, options.maxHeight - nonContentHeight ) :
10219			"none";
10220
10221		if ( options.height === "auto" ) {
10222			this.element.css({
10223				minHeight: minContentHeight,
10224				maxHeight: maxContentHeight,
10225				height: "auto"
10226			});
10227		} else {
10228			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10229		}
10230
10231		if (this.uiDialog.is(":data(ui-resizable)") ) {
10232			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10233		}
10234	},
10235
10236	_blockFrames: function() {
10237		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10238			var iframe = $( this );
10239
10240			return $( "<div>" )
10241				.css({
10242					position: "absolute",
10243					width: iframe.outerWidth(),
10244					height: iframe.outerHeight()
10245				})
10246				.appendTo( iframe.parent() )
10247				.offset( iframe.offset() )[0];
10248		});
10249	},
10250
10251	_unblockFrames: function() {
10252		if ( this.iframeBlocks ) {
10253			this.iframeBlocks.remove();
10254			delete this.iframeBlocks;
10255		}
10256	},
10257
10258	_createOverlay: function() {
10259		if ( !this.options.modal ) {
10260			return;
10261		}
10262
10263		if ( !$.ui.dialog.overlayInstances ) {
10264			// Prevent use of anchors and inputs.
10265			// We use a delay in case the overlay is created from an
10266			// event that we're going to be cancelling. (#2804)
10267			this._delay(function() {
10268				// Handle .dialog().dialog("close") (#4065)
10269				if ( $.ui.dialog.overlayInstances ) {
10270					this.document.bind( "focusin.dialog", function( event ) {
10271						if ( !$( event.target ).closest(".ui-dialog").length &&
10272								// TODO: Remove hack when datepicker implements
10273								// the .ui-front logic (#8989)
10274								!$( event.target ).closest(".ui-datepicker").length ) {
10275							event.preventDefault();
10276							$(".ui-dialog:visible:last .ui-dialog-content")
10277								.data("ui-dialog")._focusTabbable();
10278						}
10279					});
10280				}
10281			});
10282		}
10283
10284		this.overlay = $("<div>")
10285			.addClass("ui-widget-overlay ui-front")
10286			.appendTo( this._appendTo() );
10287		this._on( this.overlay, {
10288			mousedown: "_keepFocus"
10289		});
10290		$.ui.dialog.overlayInstances++;
10291	},
10292
10293	_destroyOverlay: function() {
10294		if ( !this.options.modal ) {
10295			return;
10296		}
10297
10298		if ( this.overlay ) {
10299			$.ui.dialog.overlayInstances--;
10300
10301			if ( !$.ui.dialog.overlayInstances ) {
10302				this.document.unbind( "focusin.dialog" );
10303			}
10304			this.overlay.remove();
10305			this.overlay = null;
10306		}
10307	}
10308});
10309
10310$.ui.dialog.overlayInstances = 0;
10311
10312// DEPRECATED
10313if ( $.uiBackCompat !== false ) {
10314	// position option with array notation
10315	// just override with old implementation
10316	$.widget( "ui.dialog", $.ui.dialog, {
10317		_position: function() {
10318			var position = this.options.position,
10319				myAt = [],
10320				offset = [ 0, 0 ],
10321				isVisible;
10322
10323			if ( position ) {
10324				if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
10325					myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
10326					if ( myAt.length === 1 ) {
10327						myAt[1] = myAt[0];
10328					}
10329
10330					$.each( [ "left", "top" ], function( i, offsetPosition ) {
10331						if ( +myAt[ i ] === myAt[ i ] ) {
10332							offset[ i ] = myAt[ i ];
10333							myAt[ i ] = offsetPosition;
10334						}
10335					});
10336
10337					position = {
10338						my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
10339							myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
10340						at: myAt.join(" ")
10341					};
10342				}
10343
10344				position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
10345			} else {
10346				position = $.ui.dialog.prototype.options.position;
10347			}
10348
10349			// need to show the dialog to get the actual offset in the position plugin
10350			isVisible = this.uiDialog.is(":visible");
10351			if ( !isVisible ) {
10352				this.uiDialog.show();
10353			}
10354			this.uiDialog.position( position );
10355			if ( !isVisible ) {
10356				this.uiDialog.hide();
10357			}
10358		}
10359	});
10360}
10361
10362}( jQuery ) );
10363
10364(function( $, undefined ) {
10365
10366var rvertical = /up|down|vertical/,
10367	rpositivemotion = /up|left|vertical|horizontal/;
10368
10369$.effects.effect.blind = function( o, done ) {
10370	// Create element
10371	var el = $( this ),
10372		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10373		mode = $.effects.setMode( el, o.mode || "hide" ),
10374		direction = o.direction || "up",
10375		vertical = rvertical.test( direction ),
10376		ref = vertical ? "height" : "width",
10377		ref2 = vertical ? "top" : "left",
10378		motion = rpositivemotion.test( direction ),
10379		animation = {},
10380		show = mode === "show",
10381		wrapper, distance, margin;
10382
10383	// if already wrapped, the wrapper's properties are my property. #6245
10384	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10385		$.effects.save( el.parent(), props );
10386	} else {
10387		$.effects.save( el, props );
10388	}
10389	el.show();
10390	wrapper = $.effects.createWrapper( el ).css({
10391		overflow: "hidden"
10392	});
10393
10394	distance = wrapper[ ref ]();
10395	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10396
10397	animation[ ref ] = show ? distance : 0;
10398	if ( !motion ) {
10399		el
10400			.css( vertical ? "bottom" : "right", 0 )
10401			.css( vertical ? "top" : "left", "auto" )
10402			.css({ position: "absolute" });
10403
10404		animation[ ref2 ] = show ? margin : distance + margin;
10405	}
10406
10407	// start at 0 if we are showing
10408	if ( show ) {
10409		wrapper.css( ref, 0 );
10410		if ( ! motion ) {
10411			wrapper.css( ref2, margin + distance );
10412		}
10413	}
10414
10415	// Animate
10416	wrapper.animate( animation, {
10417		duration: o.duration,
10418		easing: o.easing,
10419		queue: false,
10420		complete: function() {
10421			if ( mode === "hide" ) {
10422				el.hide();
10423			}
10424			$.effects.restore( el, props );
10425			$.effects.removeWrapper( el );
10426			done();
10427		}
10428	});
10429
10430};
10431
10432})(jQuery);
10433
10434(function( $, undefined ) {
10435
10436$.effects.effect.bounce = function( o, done ) {
10437	var el = $( this ),
10438		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10439
10440		// defaults:
10441		mode = $.effects.setMode( el, o.mode || "effect" ),
10442		hide = mode === "hide",
10443		show = mode === "show",
10444		direction = o.direction || "up",
10445		distance = o.distance,
10446		times = o.times || 5,
10447
10448		// number of internal animations
10449		anims = times * 2 + ( show || hide ? 1 : 0 ),
10450		speed = o.duration / anims,
10451		easing = o.easing,
10452
10453		// utility:
10454		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10455		motion = ( direction === "up" || direction === "left" ),
10456		i,
10457		upAnim,
10458		downAnim,
10459
10460		// we will need to re-assemble the queue to stack our animations in place
10461		queue = el.queue(),
10462		queuelen = queue.length;
10463
10464	// Avoid touching opacity to prevent clearType and PNG issues in IE
10465	if ( show || hide ) {
10466		props.push( "opacity" );
10467	}
10468
10469	$.effects.save( el, props );
10470	el.show();
10471	$.effects.createWrapper( el ); // Create Wrapper
10472
10473	// default distance for the BIGGEST bounce is the outer Distance / 3
10474	if ( !distance ) {
10475		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10476	}
10477
10478	if ( show ) {
10479		downAnim = { opacity: 1 };
10480		downAnim[ ref ] = 0;
10481
10482		// if we are showing, force opacity 0 and set the initial position
10483		// then do the "first" animation
10484		el.css( "opacity", 0 )
10485			.css( ref, motion ? -distance * 2 : distance * 2 )
10486			.animate( downAnim, speed, easing );
10487	}
10488
10489	// start at the smallest distance if we are hiding
10490	if ( hide ) {
10491		distance = distance / Math.pow( 2, times - 1 );
10492	}
10493
10494	downAnim = {};
10495	downAnim[ ref ] = 0;
10496	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10497	for ( i = 0; i < times; i++ ) {
10498		upAnim = {};
10499		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10500
10501		el.animate( upAnim, speed, easing )
10502			.animate( downAnim, speed, easing );
10503
10504		distance = hide ? distance * 2 : distance / 2;
10505	}
10506
10507	// Last Bounce when Hiding
10508	if ( hide ) {
10509		upAnim = { opacity: 0 };
10510		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10511
10512		el.animate( upAnim, speed, easing );
10513	}
10514
10515	el.queue(function() {
10516		if ( hide ) {
10517			el.hide();
10518		}
10519		$.effects.restore( el, props );
10520		$.effects.removeWrapper( el );
10521		done();
10522	});
10523
10524	// inject all the animations we just queued to be first in line (after "inprogress")
10525	if ( queuelen > 1) {
10526		queue.splice.apply( queue,
10527			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10528	}
10529	el.dequeue();
10530
10531};
10532
10533})(jQuery);
10534
10535(function( $, undefined ) {
10536
10537$.effects.effect.clip = function( o, done ) {
10538	// Create element
10539	var el = $( this ),
10540		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10541		mode = $.effects.setMode( el, o.mode || "hide" ),
10542		show = mode === "show",
10543		direction = o.direction || "vertical",
10544		vert = direction === "vertical",
10545		size = vert ? "height" : "width",
10546		position = vert ? "top" : "left",
10547		animation = {},
10548		wrapper, animate, distance;
10549
10550	// Save & Show
10551	$.effects.save( el, props );
10552	el.show();
10553
10554	// Create Wrapper
10555	wrapper = $.effects.createWrapper( el ).css({
10556		overflow: "hidden"
10557	});
10558	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10559	distance = animate[ size ]();
10560
10561	// Shift
10562	if ( show ) {
10563		animate.css( size, 0 );
10564		animate.css( position, distance / 2 );
10565	}
10566
10567	// Create Animation Object:
10568	animation[ size ] = show ? distance : 0;
10569	animation[ position ] = show ? 0 : distance / 2;
10570
10571	// Animate
10572	animate.animate( animation, {
10573		queue: false,
10574		duration: o.duration,
10575		easing: o.easing,
10576		complete: function() {
10577			if ( !show ) {
10578				el.hide();
10579			}
10580			$.effects.restore( el, props );
10581			$.effects.removeWrapper( el );
10582			done();
10583		}
10584	});
10585
10586};
10587
10588})(jQuery);
10589
10590(function( $, undefined ) {
10591
10592$.effects.effect.drop = function( o, done ) {
10593
10594	var el = $( this ),
10595		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10596		mode = $.effects.setMode( el, o.mode || "hide" ),
10597		show = mode === "show",
10598		direction = o.direction || "left",
10599		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10600		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10601		animation = {
10602			opacity: show ? 1 : 0
10603		},
10604		distance;
10605
10606	// Adjust
10607	$.effects.save( el, props );
10608	el.show();
10609	$.effects.createWrapper( el );
10610
10611	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10612
10613	if ( show ) {
10614		el
10615			.css( "opacity", 0 )
10616			.css( ref, motion === "pos" ? -distance : distance );
10617	}
10618
10619	// Animation
10620	animation[ ref ] = ( show ?
10621		( motion === "pos" ? "+=" : "-=" ) :
10622		( motion === "pos" ? "-=" : "+=" ) ) +
10623		distance;
10624
10625	// Animate
10626	el.animate( animation, {
10627		queue: false,
10628		duration: o.duration,
10629		easing: o.easing,
10630		complete: function() {
10631			if ( mode === "hide" ) {
10632				el.hide();
10633			}
10634			$.effects.restore( el, props );
10635			$.effects.removeWrapper( el );
10636			done();
10637		}
10638	});
10639};
10640
10641})(jQuery);
10642
10643(function( $, undefined ) {
10644
10645$.effects.effect.explode = function( o, done ) {
10646
10647	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10648		cells = rows,
10649		el = $( this ),
10650		mode = $.effects.setMode( el, o.mode || "hide" ),
10651		show = mode === "show",
10652
10653		// show and then visibility:hidden the element before calculating offset
10654		offset = el.show().css( "visibility", "hidden" ).offset(),
10655
10656		// width and height of a piece
10657		width = Math.ceil( el.outerWidth() / cells ),
10658		height = Math.ceil( el.outerHeight() / rows ),
10659		pieces = [],
10660
10661		// loop
10662		i, j, left, top, mx, my;
10663
10664	// children animate complete:
10665	function childComplete() {
10666		pieces.push( this );
10667		if ( pieces.length === rows * cells ) {
10668			animComplete();
10669		}
10670	}
10671
10672	// clone the element for each row and cell.
10673	for( i = 0; i < rows ; i++ ) { // ===>
10674		top = offset.top + i * height;
10675		my = i - ( rows - 1 ) / 2 ;
10676
10677		for( j = 0; j < cells ; j++ ) { // |||
10678			left = offset.left + j * width;
10679			mx = j - ( cells - 1 ) / 2 ;
10680
10681			// Create a clone of the now hidden main element that will be absolute positioned
10682			// within a wrapper div off the -left and -top equal to size of our pieces
10683			el
10684				.clone()
10685				.appendTo( "body" )
10686				.wrap( "<div></div>" )
10687				.css({
10688					position: "absolute",
10689					visibility: "visible",
10690					left: -j * width,
10691					top: -i * height
10692				})
10693
10694			// select the wrapper - make it overflow: hidden and absolute positioned based on
10695			// where the original was located +left and +top equal to the size of pieces
10696				.parent()
10697				.addClass( "ui-effects-explode" )
10698				.css({
10699					position: "absolute",
10700					overflow: "hidden",
10701					width: width,
10702					height: height,
10703					left: left + ( show ? mx * width : 0 ),
10704					top: top + ( show ? my * height : 0 ),
10705					opacity: show ? 0 : 1
10706				}).animate({
10707					left: left + ( show ? 0 : mx * width ),
10708					top: top + ( show ? 0 : my * height ),
10709					opacity: show ? 1 : 0
10710				}, o.duration || 500, o.easing, childComplete );
10711		}
10712	}
10713
10714	function animComplete() {
10715		el.css({
10716			visibility: "visible"
10717		});
10718		$( pieces ).remove();
10719		if ( !show ) {
10720			el.hide();
10721		}
10722		done();
10723	}
10724};
10725
10726})(jQuery);
10727
10728(function( $, undefined ) {
10729
10730$.effects.effect.fade = function( o, done ) {
10731	var el = $( this ),
10732		mode = $.effects.setMode( el, o.mode || "toggle" );
10733
10734	el.animate({
10735		opacity: mode
10736	}, {
10737		queue: false,
10738		duration: o.duration,
10739		easing: o.easing,
10740		complete: done
10741	});
10742};
10743
10744})( jQuery );
10745
10746(function( $, undefined ) {
10747
10748$.effects.effect.fold = function( o, done ) {
10749
10750	// Create element
10751	var el = $( this ),
10752		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10753		mode = $.effects.setMode( el, o.mode || "hide" ),
10754		show = mode === "show",
10755		hide = mode === "hide",
10756		size = o.size || 15,
10757		percent = /([0-9]+)%/.exec( size ),
10758		horizFirst = !!o.horizFirst,
10759		widthFirst = show !== horizFirst,
10760		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10761		duration = o.duration / 2,
10762		wrapper, distance,
10763		animation1 = {},
10764		animation2 = {};
10765
10766	$.effects.save( el, props );
10767	el.show();
10768
10769	// Create Wrapper
10770	wrapper = $.effects.createWrapper( el ).css({
10771		overflow: "hidden"
10772	});
10773	distance = widthFirst ?
10774		[ wrapper.width(), wrapper.height() ] :
10775		[ wrapper.height(), wrapper.width() ];
10776
10777	if ( percent ) {
10778		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10779	}
10780	if ( show ) {
10781		wrapper.css( horizFirst ? {
10782			height: 0,
10783			width: size
10784		} : {
10785			height: size,
10786			width: 0
10787		});
10788	}
10789
10790	// Animation
10791	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10792	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10793
10794	// Animate
10795	wrapper
10796		.animate( animation1, duration, o.easing )
10797		.animate( animation2, duration, o.easing, function() {
10798			if ( hide ) {
10799				el.hide();
10800			}
10801			$.effects.restore( el, props );
10802			$.effects.removeWrapper( el );
10803			done();
10804		});
10805
10806};
10807
10808})(jQuery);
10809
10810(function( $, undefined ) {
10811
10812$.effects.effect.highlight = function( o, done ) {
10813	var elem = $( this ),
10814		props = [ "backgroundImage", "backgroundColor", "opacity" ],
10815		mode = $.effects.setMode( elem, o.mode || "show" ),
10816		animation = {
10817			backgroundColor: elem.css( "backgroundColor" )
10818		};
10819
10820	if (mode === "hide") {
10821		animation.opacity = 0;
10822	}
10823
10824	$.effects.save( elem, props );
10825
10826	elem
10827		.show()
10828		.css({
10829			backgroundImage: "none",
10830			backgroundColor: o.color || "#ffff99"
10831		})
10832		.animate( animation, {
10833			queue: false,
10834			duration: o.duration,
10835			easing: o.easing,
10836			complete: function() {
10837				if ( mode === "hide" ) {
10838					elem.hide();
10839				}
10840				$.effects.restore( elem, props );
10841				done();
10842			}
10843		});
10844};
10845
10846})(jQuery);
10847
10848(function( $, undefined ) {
10849
10850$.effects.effect.pulsate = function( o, done ) {
10851	var elem = $( this ),
10852		mode = $.effects.setMode( elem, o.mode || "show" ),
10853		show = mode === "show",
10854		hide = mode === "hide",
10855		showhide = ( show || mode === "hide" ),
10856
10857		// showing or hiding leaves of the "last" animation
10858		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10859		duration = o.duration / anims,
10860		animateTo = 0,
10861		queue = elem.queue(),
10862		queuelen = queue.length,
10863		i;
10864
10865	if ( show || !elem.is(":visible")) {
10866		elem.css( "opacity", 0 ).show();
10867		animateTo = 1;
10868	}
10869
10870	// anims - 1 opacity "toggles"
10871	for ( i = 1; i < anims; i++ ) {
10872		elem.animate({
10873			opacity: animateTo
10874		}, duration, o.easing );
10875		animateTo = 1 - animateTo;
10876	}
10877
10878	elem.animate({
10879		opacity: animateTo
10880	}, duration, o.easing);
10881
10882	elem.queue(function() {
10883		if ( hide ) {
10884			elem.hide();
10885		}
10886		done();
10887	});
10888
10889	// We just queued up "anims" animations, we need to put them next in the queue
10890	if ( queuelen > 1 ) {
10891		queue.splice.apply( queue,
10892			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10893	}
10894	elem.dequeue();
10895};
10896
10897})(jQuery);
10898
10899(function( $, undefined ) {
10900
10901$.effects.effect.puff = function( o, done ) {
10902	var elem = $( this ),
10903		mode = $.effects.setMode( elem, o.mode || "hide" ),
10904		hide = mode === "hide",
10905		percent = parseInt( o.percent, 10 ) || 150,
10906		factor = percent / 100,
10907		original = {
10908			height: elem.height(),
10909			width: elem.width(),
10910			outerHeight: elem.outerHeight(),
10911			outerWidth: elem.outerWidth()
10912		};
10913
10914	$.extend( o, {
10915		effect: "scale",
10916		queue: false,
10917		fade: true,
10918		mode: mode,
10919		complete: done,
10920		percent: hide ? percent : 100,
10921		from: hide ?
10922			original :
10923			{
10924				height: original.height * factor,
10925				width: original.width * factor,
10926				outerHeight: original.outerHeight * factor,
10927				outerWidth: original.outerWidth * factor
10928			}
10929	});
10930
10931	elem.effect( o );
10932};
10933
10934$.effects.effect.scale = function( o, done ) {
10935
10936	// Create element
10937	var el = $( this ),
10938		options = $.extend( true, {}, o ),
10939		mode = $.effects.setMode( el, o.mode || "effect" ),
10940		percent = parseInt( o.percent, 10 ) ||
10941			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
10942		direction = o.direction || "both",
10943		origin = o.origin,
10944		original = {
10945			height: el.height(),
10946			width: el.width(),
10947			outerHeight: el.outerHeight(),
10948			outerWidth: el.outerWidth()
10949		},
10950		factor = {
10951			y: direction !== "horizontal" ? (percent / 100) : 1,
10952			x: direction !== "vertical" ? (percent / 100) : 1
10953		};
10954
10955	// We are going to pass this effect to the size effect:
10956	options.effect = "size";
10957	options.queue = false;
10958	options.complete = done;
10959
10960	// Set default origin and restore for show/hide
10961	if ( mode !== "effect" ) {
10962		options.origin = origin || ["middle","center"];
10963		options.restore = true;
10964	}
10965
10966	options.from = o.from || ( mode === "show" ? {
10967		height: 0,
10968		width: 0,
10969		outerHeight: 0,
10970		outerWidth: 0
10971	} : original );
10972	options.to = {
10973		height: original.height * factor.y,
10974		width: original.width * factor.x,
10975		outerHeight: original.outerHeight * factor.y,
10976		outerWidth: original.outerWidth * factor.x
10977	};
10978
10979	// Fade option to support puff
10980	if ( options.fade ) {
10981		if ( mode === "show" ) {
10982			options.from.opacity = 0;
10983			options.to.opacity = 1;
10984		}
10985		if ( mode === "hide" ) {
10986			options.from.opacity = 1;
10987			options.to.opacity = 0;
10988		}
10989	}
10990
10991	// Animate
10992	el.effect( options );
10993
10994};
10995
10996$.effects.effect.size = function( o, done ) {
10997
10998	// Create element
10999	var original, baseline, factor,
11000		el = $( this ),
11001		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11002
11003		// Always restore
11004		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11005
11006		// Copy for children
11007		props2 = [ "width", "height", "overflow" ],
11008		cProps = [ "fontSize" ],
11009		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11010		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11011
11012		// Set options
11013		mode = $.effects.setMode( el, o.mode || "effect" ),
11014		restore = o.restore || mode !== "effect",
11015		scale = o.scale || "both",
11016		origin = o.origin || [ "middle", "center" ],
11017		position = el.css( "position" ),
11018		props = restore ? props0 : props1,
11019		zero = {
11020			height: 0,
11021			width: 0,
11022			outerHeight: 0,
11023			outerWidth: 0
11024		};
11025
11026	if ( mode === "show" ) {
11027		el.show();
11028	}
11029	original = {
11030		height: el.height(),
11031		width: el.width(),
11032		outerHeight: el.outerHeight(),
11033		outerWidth: el.outerWidth()
11034	};
11035
11036	if ( o.mode === "toggle" && mode === "show" ) {
11037		el.from = o.to || zero;
11038		el.to = o.from || original;
11039	} else {
11040		el.from = o.from || ( mode === "show" ? zero : original );
11041		el.to = o.to || ( mode === "hide" ? zero : original );
11042	}
11043
11044	// Set scaling factor
11045	factor = {
11046		from: {
11047			y: el.from.height / original.height,
11048			x: el.from.width / original.width
11049		},
11050		to: {
11051			y: el.to.height / original.height,
11052			x: el.to.width / original.width
11053		}
11054	};
11055
11056	// Scale the css box
11057	if ( scale === "box" || scale === "both" ) {
11058
11059		// Vertical props scaling
11060		if ( factor.from.y !== factor.to.y ) {
11061			props = props.concat( vProps );
11062			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11063			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11064		}
11065
11066		// Horizontal props scaling
11067		if ( factor.from.x !== factor.to.x ) {
11068			props = props.concat( hProps );
11069			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11070			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11071		}
11072	}
11073
11074	// Scale the content
11075	if ( scale === "content" || scale === "both" ) {
11076
11077		// Vertical props scaling
11078		if ( factor.from.y !== factor.to.y ) {
11079			props = props.concat( cProps ).concat( props2 );
11080			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11081			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11082		}
11083	}
11084
11085	$.effects.save( el, props );
11086	el.show();
11087	$.effects.createWrapper( el );
11088	el.css( "overflow", "hidden" ).css( el.from );
11089
11090	// Adjust
11091	if (origin) { // Calculate baseline shifts
11092		baseline = $.effects.getBaseline( origin, original );
11093		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11094		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11095		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11096		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11097	}
11098	el.css( el.from ); // set top & left
11099
11100	// Animate
11101	if ( scale === "content" || scale === "both" ) { // Scale the children
11102
11103		// Add margins/font-size
11104		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11105		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11106		props2 = props0.concat(vProps).concat(hProps);
11107
11108		el.find( "*[width]" ).each( function(){
11109			var child = $( this ),
11110				c_original = {
11111					height: child.height(),
11112					width: child.width(),
11113					outerHeight: child.outerHeight(),
11114					outerWidth: child.outerWidth()
11115				};
11116			if (restore) {
11117				$.effects.save(child, props2);
11118			}
11119
11120			child.from = {
11121				height: c_original.height * factor.from.y,
11122				width: c_original.width * factor.from.x,
11123				outerHeight: c_original.outerHeight * factor.from.y,
11124				outerWidth: c_original.outerWidth * factor.from.x
11125			};
11126			child.to = {
11127				height: c_original.height * factor.to.y,
11128				width: c_original.width * factor.to.x,
11129				outerHeight: c_original.height * factor.to.y,
11130				outerWidth: c_original.width * factor.to.x
11131			};
11132
11133			// Vertical props scaling
11134			if ( factor.from.y !== factor.to.y ) {
11135				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11136				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11137			}
11138
11139			// Horizontal props scaling
11140			if ( factor.from.x !== factor.to.x ) {
11141				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11142				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11143			}
11144
11145			// Animate children
11146			child.css( child.from );
11147			child.animate( child.to, o.duration, o.easing, function() {
11148
11149				// Restore children
11150				if ( restore ) {
11151					$.effects.restore( child, props2 );
11152				}
11153			});
11154		});
11155	}
11156
11157	// Animate
11158	el.animate( el.to, {
11159		queue: false,
11160		duration: o.duration,
11161		easing: o.easing,
11162		complete: function() {
11163			if ( el.to.opacity === 0 ) {
11164				el.css( "opacity", el.from.opacity );
11165			}
11166			if( mode === "hide" ) {
11167				el.hide();
11168			}
11169			$.effects.restore( el, props );
11170			if ( !restore ) {
11171
11172				// we need to calculate our new positioning based on the scaling
11173				if ( position === "static" ) {
11174					el.css({
11175						position: "relative",
11176						top: el.to.top,
11177						left: el.to.left
11178					});
11179				} else {
11180					$.each([ "top", "left" ], function( idx, pos ) {
11181						el.css( pos, function( _, str ) {
11182							var val = parseInt( str, 10 ),
11183								toRef = idx ? el.to.left : el.to.top;
11184
11185							// if original was "auto", recalculate the new value from wrapper
11186							if ( str === "auto" ) {
11187								return toRef + "px";
11188							}
11189
11190							return val + toRef + "px";
11191						});
11192					});
11193				}
11194			}
11195
11196			$.effects.removeWrapper( el );
11197			done();
11198		}
11199	});
11200
11201};
11202
11203})(jQuery);
11204
11205(function( $, undefined ) {
11206
11207$.effects.effect.shake = function( o, done ) {
11208
11209	var el = $( this ),
11210		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11211		mode = $.effects.setMode( el, o.mode || "effect" ),
11212		direction = o.direction || "left",
11213		distance = o.distance || 20,
11214		times = o.times || 3,
11215		anims = times * 2 + 1,
11216		speed = Math.round(o.duration/anims),
11217		ref = (direction === "up" || direction === "down") ? "top" : "left",
11218		positiveMotion = (direction === "up" || direction === "left"),
11219		animation = {},
11220		animation1 = {},
11221		animation2 = {},
11222		i,
11223
11224		// we will need to re-assemble the queue to stack our animations in place
11225		queue = el.queue(),
11226		queuelen = queue.length;
11227
11228	$.effects.save( el, props );
11229	el.show();
11230	$.effects.createWrapper( el );
11231
11232	// Animation
11233	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11234	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11235	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11236
11237	// Animate
11238	el.animate( animation, speed, o.easing );
11239
11240	// Shakes
11241	for ( i = 1; i < times; i++ ) {
11242		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11243	}
11244	el
11245		.animate( animation1, speed, o.easing )
11246		.animate( animation, speed / 2, o.easing )
11247		.queue(function() {
11248			if ( mode === "hide" ) {
11249				el.hide();
11250			}
11251			$.effects.restore( el, props );
11252			$.effects.removeWrapper( el );
11253			done();
11254		});
11255
11256	// inject all the animations we just queued to be first in line (after "inprogress")
11257	if ( queuelen > 1) {
11258		queue.splice.apply( queue,
11259			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11260	}
11261	el.dequeue();
11262
11263};
11264
11265})(jQuery);
11266
11267(function( $, undefined ) {
11268
11269$.effects.effect.slide = function( o, done ) {
11270
11271	// Create element
11272	var el = $( this ),
11273		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11274		mode = $.effects.setMode( el, o.mode || "show" ),
11275		show = mode === "show",
11276		direction = o.direction || "left",
11277		ref = (direction === "up" || direction === "down") ? "top" : "left",
11278		positiveMotion = (direction === "up" || direction === "left"),
11279		distance,
11280		animation = {};
11281
11282	// Adjust
11283	$.effects.save( el, props );
11284	el.show();
11285	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11286
11287	$.effects.createWrapper( el ).css({
11288		overflow: "hidden"
11289	});
11290
11291	if ( show ) {
11292		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11293	}
11294
11295	// Animation
11296	animation[ ref ] = ( show ?
11297		( positiveMotion ? "+=" : "-=") :
11298		( positiveMotion ? "-=" : "+=")) +
11299		distance;
11300
11301	// Animate
11302	el.animate( animation, {
11303		queue: false,
11304		duration: o.duration,
11305		easing: o.easing,
11306		complete: function() {
11307			if ( mode === "hide" ) {
11308				el.hide();
11309			}
11310			$.effects.restore( el, props );
11311			$.effects.removeWrapper( el );
11312			done();
11313		}
11314	});
11315};
11316
11317})(jQuery);
11318
11319(function( $, undefined ) {
11320
11321$.effects.effect.transfer = function( o, done ) {
11322	var elem = $( this ),
11323		target = $( o.to ),
11324		targetFixed = target.css( "position" ) === "fixed",
11325		body = $("body"),
11326		fixTop = targetFixed ? body.scrollTop() : 0,
11327		fixLeft = targetFixed ? body.scrollLeft() : 0,
11328		endPosition = target.offset(),
11329		animation = {
11330			top: endPosition.top - fixTop ,
11331			left: endPosition.left - fixLeft ,
11332			height: target.innerHeight(),
11333			width: target.innerWidth()
11334		},
11335		startPosition = elem.offset(),
11336		transfer = $( "<div class='ui-effects-transfer'></div>" )
11337			.appendTo( document.body )
11338			.addClass( o.className )
11339			.css({
11340				top: startPosition.top - fixTop ,
11341				left: startPosition.left - fixLeft ,
11342				height: elem.innerHeight(),
11343				width: elem.innerWidth(),
11344				position: targetFixed ? "fixed" : "absolute"
11345			})
11346			.animate( animation, o.duration, o.easing, function() {
11347				transfer.remove();
11348				done();
11349			});
11350};
11351
11352})(jQuery);
11353
11354(function( $, undefined ) {
11355
11356$.widget( "ui.menu", {
11357	version: "1.10.1",
11358	defaultElement: "<ul>",
11359	delay: 300,
11360	options: {
11361		icons: {
11362			submenu: "ui-icon-carat-1-e"
11363		},
11364		menus: "ul",
11365		position: {
11366			my: "left top",
11367			at: "right top"
11368		},
11369		role: "menu",
11370
11371		// callbacks
11372		blur: null,
11373		focus: null,
11374		select: null
11375	},
11376
11377	_create: function() {
11378		this.activeMenu = this.element;
11379		// flag used to prevent firing of the click handler
11380		// as the event bubbles up through nested menus
11381		this.mouseHandled = false;
11382		this.element
11383			.uniqueId()
11384			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11385			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
11386			.attr({
11387				role: this.options.role,
11388				tabIndex: 0
11389			})
11390			// need to catch all clicks on disabled menu
11391			// not possible through _on
11392			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
11393				if ( this.options.disabled ) {
11394					event.preventDefault();
11395				}
11396			}, this ));
11397
11398		if ( this.options.disabled ) {
11399			this.element
11400				.addClass( "ui-state-disabled" )
11401				.attr( "aria-disabled", "true" );
11402		}
11403
11404		this._on({
11405			// Prevent focus from sticking to links inside menu after clicking
11406			// them (focus should always stay on UL during navigation).
11407			"mousedown .ui-menu-item > a": function( event ) {
11408				event.preventDefault();
11409			},
11410			"click .ui-state-disabled > a": function( event ) {
11411				event.preventDefault();
11412			},
11413			"click .ui-menu-item:has(a)": function( event ) {
11414				var target = $( event.target ).closest( ".ui-menu-item" );
11415				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
11416					this.mouseHandled = true;
11417
11418					this.select( event );
11419					// Open submenu on click
11420					if ( target.has( ".ui-menu" ).length ) {
11421						this.expand( event );
11422					} else if ( !this.element.is( ":focus" ) ) {
11423						// Redirect focus to the menu
11424						this.element.trigger( "focus", [ true ] );
11425
11426						// If the active item is on the top level, let it stay active.
11427						// Otherwise, blur the active item since it is no longer visible.
11428						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
11429							clearTimeout( this.timer );
11430						}
11431					}
11432				}
11433			},
11434			"mouseenter .ui-menu-item": function( event ) {
11435				var target = $( event.currentTarget );
11436				// Remove ui-state-active class from siblings of the newly focused menu item
11437				// to avoid a jump caused by adjacent elements both having a class with a border
11438				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
11439				this.focus( event, target );
11440			},
11441			mouseleave: "collapseAll",
11442			"mouseleave .ui-menu": "collapseAll",
11443			focus: function( event, keepActiveItem ) {
11444				// If there's already an active item, keep it active
11445				// If not, activate the first item
11446				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
11447
11448				if ( !keepActiveItem ) {
11449					this.focus( event, item );
11450				}
11451			},
11452			blur: function( event ) {
11453				this._delay(function() {
11454					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
11455						this.collapseAll( event );
11456					}
11457				});
11458			},
11459			keydown: "_keydown"
11460		});
11461
11462		this.refresh();
11463
11464		// Clicks outside of a menu collapse any open menus
11465		this._on( this.document, {
11466			click: function( event ) {
11467				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11468					this.collapseAll( event );
11469				}
11470
11471				// Reset the mouseHandled flag
11472				this.mouseHandled = false;
11473			}
11474		});
11475	},
11476
11477	_destroy: function() {
11478		// Destroy (sub)menus
11479		this.element
11480			.removeAttr( "aria-activedescendant" )
11481			.find( ".ui-menu" ).addBack()
11482				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11483				.removeAttr( "role" )
11484				.removeAttr( "tabIndex" )
11485				.removeAttr( "aria-labelledby" )
11486				.removeAttr( "aria-expanded" )
11487				.removeAttr( "aria-hidden" )
11488				.removeAttr( "aria-disabled" )
11489				.removeUniqueId()
11490				.show();
11491
11492		// Destroy menu items
11493		this.element.find( ".ui-menu-item" )
11494			.removeClass( "ui-menu-item" )
11495			.removeAttr( "role" )
11496			.removeAttr( "aria-disabled" )
11497			.children( "a" )
11498				.removeUniqueId()
11499				.removeClass( "ui-corner-all ui-state-hover" )
11500				.removeAttr( "tabIndex" )
11501				.removeAttr( "role" )
11502				.removeAttr( "aria-haspopup" )
11503				.children().each( function() {
11504					var elem = $( this );
11505					if ( elem.data( "ui-menu-submenu-carat" ) ) {
11506						elem.remove();
11507					}
11508				});
11509
11510		// Destroy menu dividers
11511		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11512	},
11513
11514	_keydown: function( event ) {
11515		/*jshint maxcomplexity:20*/
11516		var match, prev, character, skip, regex,
11517			preventDefault = true;
11518
11519		function escape( value ) {
11520			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11521		}
11522
11523		switch ( event.keyCode ) {
11524		case $.ui.keyCode.PAGE_UP:
11525			this.previousPage( event );
11526			break;
11527		case $.ui.keyCode.PAGE_DOWN:
11528			this.nextPage( event );
11529			break;
11530		case $.ui.keyCode.HOME:
11531			this._move( "first", "first", event );
11532			break;
11533		case $.ui.keyCode.END:
11534			this._move( "last", "last", event );
11535			break;
11536		case $.ui.keyCode.UP:
11537			this.previous( event );
11538			break;
11539		case $.ui.keyCode.DOWN:
11540			this.next( event );
11541			break;
11542		case $.ui.keyCode.LEFT:
11543			this.collapse( event );
11544			break;
11545		case $.ui.keyCode.RIGHT:
11546			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11547				this.expand( event );
11548			}
11549			break;
11550		case $.ui.keyCode.ENTER:
11551		case $.ui.keyCode.SPACE:
11552			this._activate( event );
11553			break;
11554		case $.ui.keyCode.ESCAPE:
11555			this.collapse( event );
11556			break;
11557		default:
11558			preventDefault = false;
11559			prev = this.previousFilter || "";
11560			character = String.fromCharCode( event.keyCode );
11561			skip = false;
11562
11563			clearTimeout( this.filterTimer );
11564
11565			if ( character === prev ) {
11566				skip = true;
11567			} else {
11568				character = prev + character;
11569			}
11570
11571			regex = new RegExp( "^" + escape( character ), "i" );
11572			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11573				return regex.test( $( this ).children( "a" ).text() );
11574			});
11575			match = skip && match.index( this.active.next() ) !== -1 ?
11576				this.active.nextAll( ".ui-menu-item" ) :
11577				match;
11578
11579			// If no matches on the current filter, reset to the last character pressed
11580			// to move down the menu to the first item that starts with that character
11581			if ( !match.length ) {
11582				character = String.fromCharCode( event.keyCode );
11583				regex = new RegExp( "^" + escape( character ), "i" );
11584				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11585					return regex.test( $( this ).children( "a" ).text() );
11586				});
11587			}
11588
11589			if ( match.length ) {
11590				this.focus( event, match );
11591				if ( match.length > 1 ) {
11592					this.previousFilter = character;
11593					this.filterTimer = this._delay(function() {
11594						delete this.previousFilter;
11595					}, 1000 );
11596				} else {
11597					delete this.previousFilter;
11598				}
11599			} else {
11600				delete this.previousFilter;
11601			}
11602		}
11603
11604		if ( preventDefault ) {
11605			event.preventDefault();
11606		}
11607	},
11608
11609	_activate: function( event ) {
11610		if ( !this.active.is( ".ui-state-disabled" ) ) {
11611			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11612				this.expand( event );
11613			} else {
11614				this.select( event );
11615			}
11616		}
11617	},
11618
11619	refresh: function() {
11620		var menus,
11621			icon = this.options.icons.submenu,
11622			submenus = this.element.find( this.options.menus );
11623
11624		// Initialize nested menus
11625		submenus.filter( ":not(.ui-menu)" )
11626			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11627			.hide()
11628			.attr({
11629				role: this.options.role,
11630				"aria-hidden": "true",
11631				"aria-expanded": "false"
11632			})
11633			.each(function() {
11634				var menu = $( this ),
11635					item = menu.prev( "a" ),
11636					submenuCarat = $( "<span>" )
11637						.addClass( "ui-menu-icon ui-icon " + icon )
11638						.data( "ui-menu-submenu-carat", true );
11639
11640				item
11641					.attr( "aria-haspopup", "true" )
11642					.prepend( submenuCarat );
11643				menu.attr( "aria-labelledby", item.attr( "id" ) );
11644			});
11645
11646		menus = submenus.add( this.element );
11647
11648		// Don't refresh list items that are already adapted
11649		menus.children( ":not(.ui-menu-item):has(a)" )
11650			.addClass( "ui-menu-item" )
11651			.attr( "role", "presentation" )
11652			.children( "a" )
11653				.uniqueId()
11654				.addClass( "ui-corner-all" )
11655				.attr({
11656					tabIndex: -1,
11657					role: this._itemRole()
11658				});
11659
11660		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11661		menus.children( ":not(.ui-menu-item)" ).each(function() {
11662			var item = $( this );
11663			// hyphen, em dash, en dash
11664			if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
11665				item.addClass( "ui-widget-content ui-menu-divider" );
11666			}
11667		});
11668
11669		// Add aria-disabled attribute to any disabled menu item
11670		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11671
11672		// If the active item has been removed, blur the menu
11673		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11674			this.blur();
11675		}
11676	},
11677
11678	_itemRole: function() {
11679		return {
11680			menu: "menuitem",
11681			listbox: "option"
11682		}[ this.options.role ];
11683	},
11684
11685	_setOption: function( key, value ) {
11686		if ( key === "icons" ) {
11687			this.element.find( ".ui-menu-icon" )
11688				.removeClass( this.options.icons.submenu )
11689				.addClass( value.submenu );
11690		}
11691		this._super( key, value );
11692	},
11693
11694	focus: function( event, item ) {
11695		var nested, focused;
11696		this.blur( event, event && event.type === "focus" );
11697
11698		this._scrollIntoView( item );
11699
11700		this.active = item.first();
11701		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11702		// Only update aria-activedescendant if there's a role
11703		// otherwise we assume focus is managed elsewhere
11704		if ( this.options.role ) {
11705			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11706		}
11707
11708		// Highlight active parent menu item, if any
11709		this.active
11710			.parent()
11711			.closest( ".ui-menu-item" )
11712			.children( "a:first" )
11713			.addClass( "ui-state-active" );
11714
11715		if ( event && event.type === "keydown" ) {
11716			this._close();
11717		} else {
11718			this.timer = this._delay(function() {
11719				this._close();
11720			}, this.delay );
11721		}
11722
11723		nested = item.children( ".ui-menu" );
11724		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
11725			this._startOpening(nested);
11726		}
11727		this.activeMenu = item.parent();
11728
11729		this._trigger( "focus", event, { item: item } );
11730	},
11731
11732	_scrollIntoView: function( item ) {
11733		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11734		if ( this._hasScroll() ) {
11735			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11736			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11737			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11738			scroll = this.activeMenu.scrollTop();
11739			elementHeight = this.activeMenu.height();
11740			itemHeight = item.height();
11741
11742			if ( offset < 0 ) {
11743				this.activeMenu.scrollTop( scroll + offset );
11744			} else if ( offset + itemHeight > elementHeight ) {
11745				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11746			}
11747		}
11748	},
11749
11750	blur: function( event, fromFocus ) {
11751		if ( !fromFocus ) {
11752			clearTimeout( this.timer );
11753		}
11754
11755		if ( !this.active ) {
11756			return;
11757		}
11758
11759		this.active.children( "a" ).removeClass( "ui-state-focus" );
11760		this.active = null;
11761
11762		this._trigger( "blur", event, { item: this.active } );
11763	},
11764
11765	_startOpening: function( submenu ) {
11766		clearTimeout( this.timer );
11767
11768		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
11769		// shift in the submenu position when mousing over the carat icon
11770		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11771			return;
11772		}
11773
11774		this.timer = this._delay(function() {
11775			this._close();
11776			this._open( submenu );
11777		}, this.delay );
11778	},
11779
11780	_open: function( submenu ) {
11781		var position = $.extend({
11782			of: this.active
11783		}, this.options.position );
11784
11785		clearTimeout( this.timer );
11786		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11787			.hide()
11788			.attr( "aria-hidden", "true" );
11789
11790		submenu
11791			.show()
11792			.removeAttr( "aria-hidden" )
11793			.attr( "aria-expanded", "true" )
11794			.position( position );
11795	},
11796
11797	collapseAll: function( event, all ) {
11798		clearTimeout( this.timer );
11799		this.timer = this._delay(function() {
11800			// If we were passed an event, look for the submenu that contains the event
11801			var currentMenu = all ? this.element :
11802				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11803
11804			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11805			if ( !currentMenu.length ) {
11806				currentMenu = this.element;
11807			}
11808
11809			this._close( currentMenu );
11810
11811			this.blur( event );
11812			this.activeMenu = currentMenu;
11813		}, this.delay );
11814	},
11815
11816	// With no arguments, closes the currently active menu - if nothing is active
11817	// it closes all menus.  If passed an argument, it will search for menus BELOW
11818	_close: function( startMenu ) {
11819		if ( !startMenu ) {
11820			startMenu = this.active ? this.active.parent() : this.element;
11821		}
11822
11823		startMenu
11824			.find( ".ui-menu" )
11825				.hide()
11826				.attr( "aria-hidden", "true" )
11827				.attr( "aria-expanded", "false" )
11828			.end()
11829			.find( "a.ui-state-active" )
11830				.removeClass( "ui-state-active" );
11831	},
11832
11833	collapse: function( event ) {
11834		var newItem = this.active &&
11835			this.active.parent().closest( ".ui-menu-item", this.element );
11836		if ( newItem && newItem.length ) {
11837			this._close();
11838			this.focus( event, newItem );
11839		}
11840	},
11841
11842	expand: function( event ) {
11843		var newItem = this.active &&
11844			this.active
11845				.children( ".ui-menu " )
11846				.children( ".ui-menu-item" )
11847				.first();
11848
11849		if ( newItem && newItem.length ) {
11850			this._open( newItem.parent() );
11851
11852			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11853			this._delay(function() {
11854				this.focus( event, newItem );
11855			});
11856		}
11857	},
11858
11859	next: function( event ) {
11860		this._move( "next", "first", event );
11861	},
11862
11863	previous: function( event ) {
11864		this._move( "prev", "last", event );
11865	},
11866
11867	isFirstItem: function() {
11868		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11869	},
11870
11871	isLastItem: function() {
11872		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11873	},
11874
11875	_move: function( direction, filter, event ) {
11876		var next;
11877		if ( this.active ) {
11878			if ( direction === "first" || direction === "last" ) {
11879				next = this.active
11880					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11881					.eq( -1 );
11882			} else {
11883				next = this.active
11884					[ direction + "All" ]( ".ui-menu-item" )
11885					.eq( 0 );
11886			}
11887		}
11888		if ( !next || !next.length || !this.active ) {
11889			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11890		}
11891
11892		this.focus( event, next );
11893	},
11894
11895	nextPage: function( event ) {
11896		var item, base, height;
11897
11898		if ( !this.active ) {
11899			this.next( event );
11900			return;
11901		}
11902		if ( this.isLastItem() ) {
11903			return;
11904		}
11905		if ( this._hasScroll() ) {
11906			base = this.active.offset().top;
11907			height = this.element.height();
11908			this.active.nextAll( ".ui-menu-item" ).each(function() {
11909				item = $( this );
11910				return item.offset().top - base - height < 0;
11911			});
11912
11913			this.focus( event, item );
11914		} else {
11915			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
11916				[ !this.active ? "first" : "last" ]() );
11917		}
11918	},
11919
11920	previousPage: function( event ) {
11921		var item, base, height;
11922		if ( !this.active ) {
11923			this.next( event );
11924			return;
11925		}
11926		if ( this.isFirstItem() ) {
11927			return;
11928		}
11929		if ( this._hasScroll() ) {
11930			base = this.active.offset().top;
11931			height = this.element.height();
11932			this.active.prevAll( ".ui-menu-item" ).each(function() {
11933				item = $( this );
11934				return item.offset().top - base + height > 0;
11935			});
11936
11937			this.focus( event, item );
11938		} else {
11939			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
11940		}
11941	},
11942
11943	_hasScroll: function() {
11944		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
11945	},
11946
11947	select: function( event ) {
11948		// TODO: It should never be possible to not have an active item at this
11949		// point, but the tests don't trigger mouseenter before click.
11950		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
11951		var ui = { item: this.active };
11952		if ( !this.active.has( ".ui-menu" ).length ) {
11953			this.collapseAll( event, true );
11954		}
11955		this._trigger( "select", event, ui );
11956	}
11957});
11958
11959}( jQuery ));
11960
11961(function( $, undefined ) {
11962
11963$.ui = $.ui || {};
11964
11965var cachedScrollbarWidth,
11966	max = Math.max,
11967	abs = Math.abs,
11968	round = Math.round,
11969	rhorizontal = /left|center|right/,
11970	rvertical = /top|center|bottom/,
11971	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
11972	rposition = /^\w+/,
11973	rpercent = /%$/,
11974	_position = $.fn.position;
11975
11976function getOffsets( offsets, width, height ) {
11977	return [
11978		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
11979		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
11980	];
11981}
11982
11983function parseCss( element, property ) {
11984	return parseInt( $.css( element, property ), 10 ) || 0;
11985}
11986
11987function getDimensions( elem ) {
11988	var raw = elem[0];
11989	if ( raw.nodeType === 9 ) {
11990		return {
11991			width: elem.width(),
11992			height: elem.height(),
11993			offset: { top: 0, left: 0 }
11994		};
11995	}
11996	if ( $.isWindow( raw ) ) {
11997		return {
11998			width: elem.width(),
11999			height: elem.height(),
12000			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
12001		};
12002	}
12003	if ( raw.preventDefault ) {
12004		return {
12005			width: 0,
12006			height: 0,
12007			offset: { top: raw.pageY, left: raw.pageX }
12008		};
12009	}
12010	return {
12011		width: elem.outerWidth(),
12012		height: elem.outerHeight(),
12013		offset: elem.offset()
12014	};
12015}
12016
12017$.position = {
12018	scrollbarWidth: function() {
12019		if ( cachedScrollbarWidth !== undefined ) {
12020			return cachedScrollbarWidth;
12021		}
12022		var w1, w2,
12023			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
12024			innerDiv = div.children()[0];
12025
12026		$( "body" ).append( div );
12027		w1 = innerDiv.offsetWidth;
12028		div.css( "overflow", "scroll" );
12029
12030		w2 = innerDiv.offsetWidth;
12031
12032		if ( w1 === w2 ) {
12033			w2 = div[0].clientWidth;
12034		}
12035
12036		div.remove();
12037
12038		return (cachedScrollbarWidth = w1 - w2);
12039	},
12040	getScrollInfo: function( within ) {
12041		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
12042			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
12043			hasOverflowX = overflowX === "scroll" ||
12044				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
12045			hasOverflowY = overflowY === "scroll" ||
12046				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
12047		return {
12048			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
12049			height: hasOverflowY ? $.position.scrollbarWidth() : 0
12050		};
12051	},
12052	getWithinInfo: function( element ) {
12053		var withinElement = $( element || window ),
12054			isWindow = $.isWindow( withinElement[0] );
12055		return {
12056			element: withinElement,
12057			isWindow: isWindow,
12058			offset: withinElement.offset() || { left: 0, top: 0 },
12059			scrollLeft: withinElement.scrollLeft(),
12060			scrollTop: withinElement.scrollTop(),
12061			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
12062			height: isWindow ? withinElement.height() : withinElement.outerHeight()
12063		};
12064	}
12065};
12066
12067$.fn.position = function( options ) {
12068	if ( !options || !options.of ) {
12069		return _position.apply( this, arguments );
12070	}
12071
12072	// make a copy, we don't want to modify arguments
12073	options = $.extend( {}, options );
12074
12075	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
12076		target = $( options.of ),
12077		within = $.position.getWithinInfo( options.within ),
12078		scrollInfo = $.position.getScrollInfo( within ),
12079		collision = ( options.collision || "flip" ).split( " " ),
12080		offsets = {};
12081
12082	dimensions = getDimensions( target );
12083	if ( target[0].preventDefault ) {
12084		// force left top to allow flipping
12085		options.at = "left top";
12086	}
12087	targetWidth = dimensions.width;
12088	targetHeight = dimensions.height;
12089	targetOffset = dimensions.offset;
12090	// clone to reuse original targetOffset later
12091	basePosition = $.extend( {}, targetOffset );
12092
12093	// force my and at to have valid horizontal and vertical positions
12094	// if a value is missing or invalid, it will be converted to center
12095	$.each( [ "my", "at" ], function() {
12096		var pos = ( options[ this ] || "" ).split( " " ),
12097			horizontalOffset,
12098			verticalOffset;
12099
12100		if ( pos.length === 1) {
12101			pos = rhorizontal.test( pos[ 0 ] ) ?
12102				pos.concat( [ "center" ] ) :
12103				rvertical.test( pos[ 0 ] ) ?
12104					[ "center" ].concat( pos ) :
12105					[ "center", "center" ];
12106		}
12107		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
12108		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
12109
12110		// calculate offsets
12111		horizontalOffset = roffset.exec( pos[ 0 ] );
12112		verticalOffset = roffset.exec( pos[ 1 ] );
12113		offsets[ this ] = [
12114			horizontalOffset ? horizontalOffset[ 0 ] : 0,
12115			verticalOffset ? verticalOffset[ 0 ] : 0
12116		];
12117
12118		// reduce to just the positions without the offsets
12119		options[ this ] = [
12120			rposition.exec( pos[ 0 ] )[ 0 ],
12121			rposition.exec( pos[ 1 ] )[ 0 ]
12122		];
12123	});
12124
12125	// normalize collision option
12126	if ( collision.length === 1 ) {
12127		collision[ 1 ] = collision[ 0 ];
12128	}
12129
12130	if ( options.at[ 0 ] === "right" ) {
12131		basePosition.left += targetWidth;
12132	} else if ( options.at[ 0 ] === "center" ) {
12133		basePosition.left += targetWidth / 2;
12134	}
12135
12136	if ( options.at[ 1 ] === "bottom" ) {
12137		basePosition.top += targetHeight;
12138	} else if ( options.at[ 1 ] === "center" ) {
12139		basePosition.top += targetHeight / 2;
12140	}
12141
12142	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
12143	basePosition.left += atOffset[ 0 ];
12144	basePosition.top += atOffset[ 1 ];
12145
12146	return this.each(function() {
12147		var collisionPosition, using,
12148			elem = $( this ),
12149			elemWidth = elem.outerWidth(),
12150			elemHeight = elem.outerHeight(),
12151			marginLeft = parseCss( this, "marginLeft" ),
12152			marginTop = parseCss( this, "marginTop" ),
12153			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
12154			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
12155			position = $.extend( {}, basePosition ),
12156			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
12157
12158		if ( options.my[ 0 ] === "right" ) {
12159			position.left -= elemWidth;
12160		} else if ( options.my[ 0 ] === "center" ) {
12161			position.left -= elemWidth / 2;
12162		}
12163
12164		if ( options.my[ 1 ] === "bottom" ) {
12165			position.top -= elemHeight;
12166		} else if ( options.my[ 1 ] === "center" ) {
12167			position.top -= elemHeight / 2;
12168		}
12169
12170		position.left += myOffset[ 0 ];
12171		position.top += myOffset[ 1 ];
12172
12173		// if the browser doesn't support fractions, then round for consistent results
12174		if ( !$.support.offsetFractions ) {
12175			position.left = round( position.left );
12176			position.top = round( position.top );
12177		}
12178
12179		collisionPosition = {
12180			marginLeft: marginLeft,
12181			marginTop: marginTop
12182		};
12183
12184		$.each( [ "left", "top" ], function( i, dir ) {
12185			if ( $.ui.position[ collision[ i ] ] ) {
12186				$.ui.position[ collision[ i ] ][ dir ]( position, {
12187					targetWidth: targetWidth,
12188					targetHeight: targetHeight,
12189					elemWidth: elemWidth,
12190					elemHeight: elemHeight,
12191					collisionPosition: collisionPosition,
12192					collisionWidth: collisionWidth,
12193					collisionHeight: collisionHeight,
12194					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
12195					my: options.my,
12196					at: options.at,
12197					within: within,
12198					elem : elem
12199				});
12200			}
12201		});
12202
12203		if ( options.using ) {
12204			// adds feedback as second argument to using callback, if present
12205			using = function( props ) {
12206				var left = targetOffset.left - position.left,
12207					right = left + targetWidth - elemWidth,
12208					top = targetOffset.top - position.top,
12209					bottom = top + targetHeight - elemHeight,
12210					feedback = {
12211						target: {
12212							element: target,
12213							left: targetOffset.left,
12214							top: targetOffset.top,
12215							width: targetWidth,
12216							height: targetHeight
12217						},
12218						element: {
12219							element: elem,
12220							left: position.left,
12221							top: position.top,
12222							width: elemWidth,
12223							height: elemHeight
12224						},
12225						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
12226						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
12227					};
12228				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
12229					feedback.horizontal = "center";
12230				}
12231				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
12232					feedback.vertical = "middle";
12233				}
12234				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
12235					feedback.important = "horizontal";
12236				} else {
12237					feedback.important = "vertical";
12238				}
12239				options.using.call( this, props, feedback );
12240			};
12241		}
12242
12243		elem.offset( $.extend( position, { using: using } ) );
12244	});
12245};
12246
12247$.ui.position = {
12248	fit: {
12249		left: function( position, data ) {
12250			var within = data.within,
12251				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
12252				outerWidth = within.width,
12253				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12254				overLeft = withinOffset - collisionPosLeft,
12255				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
12256				newOverRight;
12257
12258			// element is wider than within
12259			if ( data.collisionWidth > outerWidth ) {
12260				// element is initially over the left side of within
12261				if ( overLeft > 0 && overRight <= 0 ) {
12262					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
12263					position.left += overLeft - newOverRight;
12264				// element is initially over right side of within
12265				} else if ( overRight > 0 && overLeft <= 0 ) {
12266					position.left = withinOffset;
12267				// element is initially over both left and right sides of within
12268				} else {
12269					if ( overLeft > overRight ) {
12270						position.left = withinOffset + outerWidth - data.collisionWidth;
12271					} else {
12272						position.left = withinOffset;
12273					}
12274				}
12275			// too far left -> align with left edge
12276			} else if ( overLeft > 0 ) {
12277				position.left += overLeft;
12278			// too far right -> align with right edge
12279			} else if ( overRight > 0 ) {
12280				position.left -= overRight;
12281			// adjust based on position and margin
12282			} else {
12283				position.left = max( position.left - collisionPosLeft, position.left );
12284			}
12285		},
12286		top: function( position, data ) {
12287			var within = data.within,
12288				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
12289				outerHeight = data.within.height,
12290				collisionPosTop = position.top - data.collisionPosition.marginTop,
12291				overTop = withinOffset - collisionPosTop,
12292				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
12293				newOverBottom;
12294
12295			// element is taller than within
12296			if ( data.collisionHeight > outerHeight ) {
12297				// element is initially over the top of within
12298				if ( overTop > 0 && overBottom <= 0 ) {
12299					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
12300					position.top += overTop - newOverBottom;
12301				// element is initially over bottom of within
12302				} else if ( overBottom > 0 && overTop <= 0 ) {
12303					position.top = withinOffset;
12304				// element is initially over both top and bottom of within
12305				} else {
12306					if ( overTop > overBottom ) {
12307						position.top = withinOffset + outerHeight - data.collisionHeight;
12308					} else {
12309						position.top = withinOffset;
12310					}
12311				}
12312			// too far up -> align with top
12313			} else if ( overTop > 0 ) {
12314				position.top += overTop;
12315			// too far down -> align with bottom edge
12316			} else if ( overBottom > 0 ) {
12317				position.top -= overBottom;
12318			// adjust based on position and margin
12319			} else {
12320				position.top = max( position.top - collisionPosTop, position.top );
12321			}
12322		}
12323	},
12324	flip: {
12325		left: function( position, data ) {
12326			var within = data.within,
12327				withinOffset = within.offset.left + within.scrollLeft,
12328				outerWidth = within.width,
12329				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
12330				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12331				overLeft = collisionPosLeft - offsetLeft,
12332				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
12333				myOffset = data.my[ 0 ] === "left" ?
12334					-data.elemWidth :
12335					data.my[ 0 ] === "right" ?
12336						data.elemWidth :
12337						0,
12338				atOffset = data.at[ 0 ] === "left" ?
12339					data.targetWidth :
12340					data.at[ 0 ] === "right" ?
12341						-data.targetWidth :
12342						0,
12343				offset = -2 * data.offset[ 0 ],
12344				newOverRight,
12345				newOverLeft;
12346
12347			if ( overLeft < 0 ) {
12348				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
12349				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
12350					position.left += myOffset + atOffset + offset;
12351				}
12352			}
12353			else if ( overRight > 0 ) {
12354				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
12355				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
12356					position.left += myOffset + atOffset + offset;
12357				}
12358			}
12359		},
12360		top: function( position, data ) {
12361			var within = data.within,
12362				withinOffset = within.offset.top + within.scrollTop,
12363				outerHeight = within.height,
12364				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
12365				collisionPosTop = position.top - data.collisionPosition.marginTop,
12366				overTop = collisionPosTop - offsetTop,
12367				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
12368				top = data.my[ 1 ] === "top",
12369				myOffset = top ?
12370					-data.elemHeight :
12371					data.my[ 1 ] === "bottom" ?
12372						data.elemHeight :
12373						0,
12374				atOffset = data.at[ 1 ] === "top" ?
12375					data.targetHeight :
12376					data.at[ 1 ] === "bottom" ?
12377						-data.targetHeight :
12378						0,
12379				offset = -2 * data.offset[ 1 ],
12380				newOverTop,
12381				newOverBottom;
12382			if ( overTop < 0 ) {
12383				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
12384				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
12385					position.top += myOffset + atOffset + offset;
12386				}
12387			}
12388			else if ( overBottom > 0 ) {
12389				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
12390				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
12391					position.top += myOffset + atOffset + offset;
12392				}
12393			}
12394		}
12395	},
12396	flipfit: {
12397		left: function() {
12398			$.ui.position.flip.left.apply( this, arguments );
12399			$.ui.position.fit.left.apply( this, arguments );
12400		},
12401		top: function() {
12402			$.ui.position.flip.top.apply( this, arguments );
12403			$.ui.position.fit.top.apply( this, arguments );
12404		}
12405	}
12406};
12407
12408// fraction support test
12409(function () {
12410	var testElement, testElementParent, testElementStyle, offsetLeft, i,
12411		body = document.getElementsByTagName( "body" )[ 0 ],
12412		div = document.createElement( "div" );
12413
12414	//Create a "fake body" for testing based on method used in jQuery.support
12415	testElement = document.createElement( body ? "div" : "body" );
12416	testElementStyle = {
12417		visibility: "hidden",
12418		width: 0,
12419		height: 0,
12420		border: 0,
12421		margin: 0,
12422		background: "none"
12423	};
12424	if ( body ) {
12425		$.extend( testElementStyle, {
12426			position: "absolute",
12427			left: "-1000px",
12428			top: "-1000px"
12429		});
12430	}
12431	for ( i in testElementStyle ) {
12432		testElement.style[ i ] = testElementStyle[ i ];
12433	}
12434	testElement.appendChild( div );
12435	testElementParent = body || document.documentElement;
12436	testElementParent.insertBefore( testElement, testElementParent.firstChild );
12437
12438	div.style.cssText = "position: absolute; left: 10.7432222px;";
12439
12440	offsetLeft = $( div ).offset().left;
12441	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
12442
12443	testElement.innerHTML = "";
12444	testElementParent.removeChild( testElement );
12445})();
12446
12447}( jQuery ) );
12448
12449(function( $, undefined ) {
12450
12451$.widget( "ui.progressbar", {
12452	version: "1.10.1",
12453	options: {
12454		max: 100,
12455		value: 0,
12456
12457		change: null,
12458		complete: null
12459	},
12460
12461	min: 0,
12462
12463	_create: function() {
12464		// Constrain initial value
12465		this.oldValue = this.options.value = this._constrainedValue();
12466
12467		this.element
12468			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12469			.attr({
12470				// Only set static values, aria-valuenow and aria-valuemax are
12471				// set inside _refreshValue()
12472				role: "progressbar",
12473				"aria-valuemin": this.min
12474			});
12475
12476		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12477			.appendTo( this.element );
12478
12479		this._refreshValue();
12480	},
12481
12482	_destroy: function() {
12483		this.element
12484			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12485			.removeAttr( "role" )
12486			.removeAttr( "aria-valuemin" )
12487			.removeAttr( "aria-valuemax" )
12488			.removeAttr( "aria-valuenow" );
12489
12490		this.valueDiv.remove();
12491	},
12492
12493	value: function( newValue ) {
12494		if ( newValue === undefined ) {
12495			return this.options.value;
12496		}
12497
12498		this.options.value = this._constrainedValue( newValue );
12499		this._refreshValue();
12500	},
12501
12502	_constrainedValue: function( newValue ) {
12503		if ( newValue === undefined ) {
12504			newValue = this.options.value;
12505		}
12506
12507		this.indeterminate = newValue === false;
12508
12509		// sanitize value
12510		if ( typeof newValue !== "number" ) {
12511			newValue = 0;
12512		}
12513
12514		return this.indeterminate ? false :
12515			Math.min( this.options.max, Math.max( this.min, newValue ) );
12516	},
12517
12518	_setOptions: function( options ) {
12519		// Ensure "value" option is set after other values (like max)
12520		var value = options.value;
12521		delete options.value;
12522
12523		this._super( options );
12524
12525		this.options.value = this._constrainedValue( value );
12526		this._refreshValue();
12527	},
12528
12529	_setOption: function( key, value ) {
12530		if ( key === "max" ) {
12531			// Don't allow a max less than min
12532			value = Math.max( this.min, value );
12533		}
12534
12535		this._super( key, value );
12536	},
12537
12538	_percentage: function() {
12539		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12540	},
12541
12542	_refreshValue: function() {
12543		var value = this.options.value,
12544			percentage = this._percentage();
12545
12546		this.valueDiv
12547			.toggle( this.indeterminate || value > this.min )
12548			.toggleClass( "ui-corner-right", value === this.options.max )
12549			.width( percentage.toFixed(0) + "%" );
12550
12551		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
12552
12553		if ( this.indeterminate ) {
12554			this.element.removeAttr( "aria-valuenow" );
12555			if ( !this.overlayDiv ) {
12556				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
12557			}
12558		} else {
12559			this.element.attr({
12560				"aria-valuemax": this.options.max,
12561				"aria-valuenow": value
12562			});
12563			if ( this.overlayDiv ) {
12564				this.overlayDiv.remove();
12565				this.overlayDiv = null;
12566			}
12567		}
12568
12569		if ( this.oldValue !== value ) {
12570			this.oldValue = value;
12571			this._trigger( "change" );
12572		}
12573		if ( value === this.options.max ) {
12574			this._trigger( "complete" );
12575		}
12576	}
12577});
12578
12579})( jQuery );
12580
12581(function( $, undefined ) {
12582
12583// number of pages in a slider
12584// (how many times can you page up/down to go through the whole range)
12585var numPages = 5;
12586
12587$.widget( "ui.slider", $.ui.mouse, {
12588	version: "1.10.1",
12589	widgetEventPrefix: "slide",
12590
12591	options: {
12592		animate: false,
12593		distance: 0,
12594		max: 100,
12595		min: 0,
12596		orientation: "horizontal",
12597		range: false,
12598		step: 1,
12599		value: 0,
12600		values: null,
12601
12602		// callbacks
12603		change: null,
12604		slide: null,
12605		start: null,
12606		stop: null
12607	},
12608
12609	_create: function() {
12610		this._keySliding = false;
12611		this._mouseSliding = false;
12612		this._animateOff = true;
12613		this._handleIndex = null;
12614		this._detectOrientation();
12615		this._mouseInit();
12616
12617		this.element
12618			.addClass( "ui-slider" +
12619				" ui-slider-" + this.orientation +
12620				" ui-widget" +
12621				" ui-widget-content" +
12622				" ui-corner-all");
12623
12624		this._refresh();
12625		this._setOption( "disabled", this.options.disabled );
12626
12627		this._animateOff = false;
12628	},
12629
12630	_refresh: function() {
12631		this._createRange();
12632		this._createHandles();
12633		this._setupEvents();
12634		this._refreshValue();
12635	},
12636
12637	_createHandles: function() {
12638		var i, handleCount,
12639			options = this.options,
12640			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12641			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12642			handles = [];
12643
12644		handleCount = ( options.values && options.values.length ) || 1;
12645
12646		if ( existingHandles.length > handleCount ) {
12647			existingHandles.slice( handleCount ).remove();
12648			existingHandles = existingHandles.slice( 0, handleCount );
12649		}
12650
12651		for ( i = existingHandles.length; i < handleCount; i++ ) {
12652			handles.push( handle );
12653		}
12654
12655		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12656
12657		this.handle = this.handles.eq( 0 );
12658
12659		this.handles.each(function( i ) {
12660			$( this ).data( "ui-slider-handle-index", i );
12661		});
12662	},
12663
12664	_createRange: function() {
12665		var options = this.options,
12666			classes = "";
12667
12668		if ( options.range ) {
12669			if ( options.range === true ) {
12670				if ( !options.values ) {
12671					options.values = [ this._valueMin(), this._valueMin() ];
12672				} else if ( options.values.length && options.values.length !== 2 ) {
12673					options.values = [ options.values[0], options.values[0] ];
12674				} else if ( $.isArray( options.values ) ) {
12675					options.values = options.values.slice(0);
12676				}
12677			}
12678
12679			if ( !this.range || !this.range.length ) {
12680				this.range = $( "<div></div>" )
12681					.appendTo( this.element );
12682
12683				classes = "ui-slider-range" +
12684				// note: this isn't the most fittingly semantic framework class for this element,
12685				// but worked best visually with a variety of themes
12686				" ui-widget-header ui-corner-all";
12687			} else {
12688				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12689					// Handle range switching from true to min/max
12690					.css({
12691						"left": "",
12692						"bottom": ""
12693					});
12694			}
12695
12696			this.range.addClass( classes +
12697				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12698		} else {
12699			this.range = $([]);
12700		}
12701	},
12702
12703	_setupEvents: function() {
12704		var elements = this.handles.add( this.range ).filter( "a" );
12705		this._off( elements );
12706		this._on( elements, this._handleEvents );
12707		this._hoverable( elements );
12708		this._focusable( elements );
12709	},
12710
12711	_destroy: function() {
12712		this.handles.remove();
12713		this.range.remove();
12714
12715		this.element
12716			.removeClass( "ui-slider" +
12717				" ui-slider-horizontal" +
12718				" ui-slider-vertical" +
12719				" ui-widget" +
12720				" ui-widget-content" +
12721				" ui-corner-all" );
12722
12723		this._mouseDestroy();
12724	},
12725
12726	_mouseCapture: function( event ) {
12727		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12728			that = this,
12729			o = this.options;
12730
12731		if ( o.disabled ) {
12732			return false;
12733		}
12734
12735		this.elementSize = {
12736			width: this.element.outerWidth(),
12737			height: this.element.outerHeight()
12738		};
12739		this.elementOffset = this.element.offset();
12740
12741		position = { x: event.pageX, y: event.pageY };
12742		normValue = this._normValueFromMouse( position );
12743		distance = this._valueMax() - this._valueMin() + 1;
12744		this.handles.each(function( i ) {
12745			var thisDistance = Math.abs( normValue - that.values(i) );
12746			if (( distance > thisDistance ) ||
12747				( distance === thisDistance &&
12748					(i === that._lastChangedValue || that.values(i) === o.min ))) {
12749				distance = thisDistance;
12750				closestHandle = $( this );
12751				index = i;
12752			}
12753		});
12754
12755		allowed = this._start( event, index );
12756		if ( allowed === false ) {
12757			return false;
12758		}
12759		this._mouseSliding = true;
12760
12761		this._handleIndex = index;
12762
12763		closestHandle
12764			.addClass( "ui-state-active" )
12765			.focus();
12766
12767		offset = closestHandle.offset();
12768		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12769		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12770			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12771			top: event.pageY - offset.top -
12772				( closestHandle.height() / 2 ) -
12773				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12774				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12775				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12776		};
12777
12778		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12779			this._slide( event, index, normValue );
12780		}
12781		this._animateOff = true;
12782		return true;
12783	},
12784
12785	_mouseStart: function() {
12786		return true;
12787	},
12788
12789	_mouseDrag: function( event ) {
12790		var position = { x: event.pageX, y: event.pageY },
12791			normValue = this._normValueFromMouse( position );
12792
12793		this._slide( event, this._handleIndex, normValue );
12794
12795		return false;
12796	},
12797
12798	_mouseStop: function( event ) {
12799		this.handles.removeClass( "ui-state-active" );
12800		this._mouseSliding = false;
12801
12802		this._stop( event, this._handleIndex );
12803		this._change( event, this._handleIndex );
12804
12805		this._handleIndex = null;
12806		this._clickOffset = null;
12807		this._animateOff = false;
12808
12809		return false;
12810	},
12811
12812	_detectOrientation: function() {
12813		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12814	},
12815
12816	_normValueFromMouse: function( position ) {
12817		var pixelTotal,
12818			pixelMouse,
12819			percentMouse,
12820			valueTotal,
12821			valueMouse;
12822
12823		if ( this.orientation === "horizontal" ) {
12824			pixelTotal = this.elementSize.width;
12825			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12826		} else {
12827			pixelTotal = this.elementSize.height;
12828			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12829		}
12830
12831		percentMouse = ( pixelMouse / pixelTotal );
12832		if ( percentMouse > 1 ) {
12833			percentMouse = 1;
12834		}
12835		if ( percentMouse < 0 ) {
12836			percentMouse = 0;
12837		}
12838		if ( this.orientation === "vertical" ) {
12839			percentMouse = 1 - percentMouse;
12840		}
12841
12842		valueTotal = this._valueMax() - this._valueMin();
12843		valueMouse = this._valueMin() + percentMouse * valueTotal;
12844
12845		return this._trimAlignValue( valueMouse );
12846	},
12847
12848	_start: function( event, index ) {
12849		var uiHash = {
12850			handle: this.handles[ index ],
12851			value: this.value()
12852		};
12853		if ( this.options.values && this.options.values.length ) {
12854			uiHash.value = this.values( index );
12855			uiHash.values = this.values();
12856		}
12857		return this._trigger( "start", event, uiHash );
12858	},
12859
12860	_slide: function( event, index, newVal ) {
12861		var otherVal,
12862			newValues,
12863			allowed;
12864
12865		if ( this.options.values && this.options.values.length ) {
12866			otherVal = this.values( index ? 0 : 1 );
12867
12868			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12869					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12870				) {
12871				newVal = otherVal;
12872			}
12873
12874			if ( newVal !== this.values( index ) ) {
12875				newValues = this.values();
12876				newValues[ index ] = newVal;
12877				// A slide can be canceled by returning false from the slide callback
12878				allowed = this._trigger( "slide", event, {
12879					handle: this.handles[ index ],
12880					value: newVal,
12881					values: newValues
12882				} );
12883				otherVal = this.values( index ? 0 : 1 );
12884				if ( allowed !== false ) {
12885					this.values( index, newVal, true );
12886				}
12887			}
12888		} else {
12889			if ( newVal !== this.value() ) {
12890				// A slide can be canceled by returning false from the slide callback
12891				allowed = this._trigger( "slide", event, {
12892					handle: this.handles[ index ],
12893					value: newVal
12894				} );
12895				if ( allowed !== false ) {
12896					this.value( newVal );
12897				}
12898			}
12899		}
12900	},
12901
12902	_stop: function( event, index ) {
12903		var uiHash = {
12904			handle: this.handles[ index ],
12905			value: this.value()
12906		};
12907		if ( this.options.values && this.options.values.length ) {
12908			uiHash.value = this.values( index );
12909			uiHash.values = this.values();
12910		}
12911
12912		this._trigger( "stop", event, uiHash );
12913	},
12914
12915	_change: function( event, index ) {
12916		if ( !this._keySliding && !this._mouseSliding ) {
12917			var uiHash = {
12918				handle: this.handles[ index ],
12919				value: this.value()
12920			};
12921			if ( this.options.values && this.options.values.length ) {
12922				uiHash.value = this.values( index );
12923				uiHash.values = this.values();
12924			}
12925
12926			//store the last changed value index for reference when handles overlap
12927			this._lastChangedValue = index;
12928
12929			this._trigger( "change", event, uiHash );
12930		}
12931	},
12932
12933	value: function( newValue ) {
12934		if ( arguments.length ) {
12935			this.options.value = this._trimAlignValue( newValue );
12936			this._refreshValue();
12937			this._change( null, 0 );
12938			return;
12939		}
12940
12941		return this._value();
12942	},
12943
12944	values: function( index, newValue ) {
12945		var vals,
12946			newValues,
12947			i;
12948
12949		if ( arguments.length > 1 ) {
12950			this.options.values[ index ] = this._trimAlignValue( newValue );
12951			this._refreshValue();
12952			this._change( null, index );
12953			return;
12954		}
12955
12956		if ( arguments.length ) {
12957			if ( $.isArray( arguments[ 0 ] ) ) {
12958				vals = this.options.values;
12959				newValues = arguments[ 0 ];
12960				for ( i = 0; i < vals.length; i += 1 ) {
12961					vals[ i ] = this._trimAlignValue( newValues[ i ] );
12962					this._change( null, i );
12963				}
12964				this._refreshValue();
12965			} else {
12966				if ( this.options.values && this.options.values.length ) {
12967					return this._values( index );
12968				} else {
12969					return this.value();
12970				}
12971			}
12972		} else {
12973			return this._values();
12974		}
12975	},
12976
12977	_setOption: function( key, value ) {
12978		var i,
12979			valsLength = 0;
12980
12981		if ( key === "range" && this.options.range === true ) {
12982			if ( value === "min" ) {
12983				this.options.value = this._values( 0 );
12984				this.options.values = null;
12985			} else if ( value === "max" ) {
12986				this.options.value = this._values( this.options.values.length-1 );
12987				this.options.values = null;
12988			}
12989		}
12990
12991		if ( $.isArray( this.options.values ) ) {
12992			valsLength = this.options.values.length;
12993		}
12994
12995		$.Widget.prototype._setOption.apply( this, arguments );
12996
12997		switch ( key ) {
12998			case "orientation":
12999				this._detectOrientation();
13000				this.element
13001					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
13002					.addClass( "ui-slider-" + this.orientation );
13003				this._refreshValue();
13004				break;
13005			case "value":
13006				this._animateOff = true;
13007				this._refreshValue();
13008				this._change( null, 0 );
13009				this._animateOff = false;
13010				break;
13011			case "values":
13012				this._animateOff = true;
13013				this._refreshValue();
13014				for ( i = 0; i < valsLength; i += 1 ) {
13015					this._change( null, i );
13016				}
13017				this._animateOff = false;
13018				break;
13019			case "min":
13020			case "max":
13021				this._animateOff = true;
13022				this._refreshValue();
13023				this._animateOff = false;
13024				break;
13025			case "range":
13026				this._animateOff = true;
13027				this._refresh();
13028				this._animateOff = false;
13029				break;
13030		}
13031	},
13032
13033	//internal value getter
13034	// _value() returns value trimmed by min and max, aligned by step
13035	_value: function() {
13036		var val = this.options.value;
13037		val = this._trimAlignValue( val );
13038
13039		return val;
13040	},
13041
13042	//internal values getter
13043	// _values() returns array of values trimmed by min and max, aligned by step
13044	// _values( index ) returns single value trimmed by min and max, aligned by step
13045	_values: function( index ) {
13046		var val,
13047			vals,
13048			i;
13049
13050		if ( arguments.length ) {
13051			val = this.options.values[ index ];
13052			val = this._trimAlignValue( val );
13053
13054			return val;
13055		} else if ( this.options.values && this.options.values.length ) {
13056			// .slice() creates a copy of the array
13057			// this copy gets trimmed by min and max and then returned
13058			vals = this.options.values.slice();
13059			for ( i = 0; i < vals.length; i+= 1) {
13060				vals[ i ] = this._trimAlignValue( vals[ i ] );
13061			}
13062
13063			return vals;
13064		} else {
13065			return [];
13066		}
13067	},
13068
13069	// returns the step-aligned value that val is closest to, between (inclusive) min and max
13070	_trimAlignValue: function( val ) {
13071		if ( val <= this._valueMin() ) {
13072			return this._valueMin();
13073		}
13074		if ( val >= this._valueMax() ) {
13075			return this._valueMax();
13076		}
13077		var step = ( this.options.step > 0 ) ? this.options.step : 1,
13078			valModStep = (val - this._valueMin()) % step,
13079			alignValue = val - valModStep;
13080
13081		if ( Math.abs(valModStep) * 2 >= step ) {
13082			alignValue += ( valModStep > 0 ) ? step : ( -step );
13083		}
13084
13085		// Since JavaScript has problems with large floats, round
13086		// the final value to 5 digits after the decimal point (see #4124)
13087		return parseFloat( alignValue.toFixed(5) );
13088	},
13089
13090	_valueMin: function() {
13091		return this.options.min;
13092	},
13093
13094	_valueMax: function() {
13095		return this.options.max;
13096	},
13097
13098	_refreshValue: function() {
13099		var lastValPercent, valPercent, value, valueMin, valueMax,
13100			oRange = this.options.range,
13101			o = this.options,
13102			that = this,
13103			animate = ( !this._animateOff ) ? o.animate : false,
13104			_set = {};
13105
13106		if ( this.options.values && this.options.values.length ) {
13107			this.handles.each(function( i ) {
13108				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13109				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13110				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13111				if ( that.options.range === true ) {
13112					if ( that.orientation === "horizontal" ) {
13113						if ( i === 0 ) {
13114							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13115						}
13116						if ( i === 1 ) {
13117							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13118						}
13119					} else {
13120						if ( i === 0 ) {
13121							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13122						}
13123						if ( i === 1 ) {
13124							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13125						}
13126					}
13127				}
13128				lastValPercent = valPercent;
13129			});
13130		} else {
13131			value = this.value();
13132			valueMin = this._valueMin();
13133			valueMax = this._valueMax();
13134			valPercent = ( valueMax !== valueMin ) ?
13135					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13136					0;
13137			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13138			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13139
13140			if ( oRange === "min" && this.orientation === "horizontal" ) {
13141				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13142			}
13143			if ( oRange === "max" && this.orientation === "horizontal" ) {
13144				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13145			}
13146			if ( oRange === "min" && this.orientation === "vertical" ) {
13147				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13148			}
13149			if ( oRange === "max" && this.orientation === "vertical" ) {
13150				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13151			}
13152		}
13153	},
13154
13155	_handleEvents: {
13156		keydown: function( event ) {
13157			/*jshint maxcomplexity:25*/
13158			var allowed, curVal, newVal, step,
13159				index = $( event.target ).data( "ui-slider-handle-index" );
13160
13161			switch ( event.keyCode ) {
13162				case $.ui.keyCode.HOME:
13163				case $.ui.keyCode.END:
13164				case $.ui.keyCode.PAGE_UP:
13165				case $.ui.keyCode.PAGE_DOWN:
13166				case $.ui.keyCode.UP:
13167				case $.ui.keyCode.RIGHT:
13168				case $.ui.keyCode.DOWN:
13169				case $.ui.keyCode.LEFT:
13170					event.preventDefault();
13171					if ( !this._keySliding ) {
13172						this._keySliding = true;
13173						$( event.target ).addClass( "ui-state-active" );
13174						allowed = this._start( event, index );
13175						if ( allowed === false ) {
13176							return;
13177						}
13178					}
13179					break;
13180			}
13181
13182			step = this.options.step;
13183			if ( this.options.values && this.options.values.length ) {
13184				curVal = newVal = this.values( index );
13185			} else {
13186				curVal = newVal = this.value();
13187			}
13188
13189			switch ( event.keyCode ) {
13190				case $.ui.keyCode.HOME:
13191					newVal = this._valueMin();
13192					break;
13193				case $.ui.keyCode.END:
13194					newVal = this._valueMax();
13195					break;
13196				case $.ui.keyCode.PAGE_UP:
13197					newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13198					break;
13199				case $.ui.keyCode.PAGE_DOWN:
13200					newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13201					break;
13202				case $.ui.keyCode.UP:
13203				case $.ui.keyCode.RIGHT:
13204					if ( curVal === this._valueMax() ) {
13205						return;
13206					}
13207					newVal = this._trimAlignValue( curVal + step );
13208					break;
13209				case $.ui.keyCode.DOWN:
13210				case $.ui.keyCode.LEFT:
13211					if ( curVal === this._valueMin() ) {
13212						return;
13213					}
13214					newVal = this._trimAlignValue( curVal - step );
13215					break;
13216			}
13217
13218			this._slide( event, index, newVal );
13219		},
13220		click: function( event ) {
13221			event.preventDefault();
13222		},
13223		keyup: function( event ) {
13224			var index = $( event.target ).data( "ui-slider-handle-index" );
13225
13226			if ( this._keySliding ) {
13227				this._keySliding = false;
13228				this._stop( event, index );
13229				this._change( event, index );
13230				$( event.target ).removeClass( "ui-state-active" );
13231			}
13232		}
13233	}
13234
13235});
13236
13237}(jQuery));
13238
13239(function( $ ) {
13240
13241function modifier( fn ) {
13242	return function() {
13243		var previous = this.element.val();
13244		fn.apply( this, arguments );
13245		this._refresh();
13246		if ( previous !== this.element.val() ) {
13247			this._trigger( "change" );
13248		}
13249	};
13250}
13251
13252$.widget( "ui.spinner", {
13253	version: "1.10.1",
13254	defaultElement: "<input>",
13255	widgetEventPrefix: "spin",
13256	options: {
13257		culture: null,
13258		icons: {
13259			down: "ui-icon-triangle-1-s",
13260			up: "ui-icon-triangle-1-n"
13261		},
13262		incremental: true,
13263		max: null,
13264		min: null,
13265		numberFormat: null,
13266		page: 10,
13267		step: 1,
13268
13269		change: null,
13270		spin: null,
13271		start: null,
13272		stop: null
13273	},
13274
13275	_create: function() {
13276		// handle string values that need to be parsed
13277		this._setOption( "max", this.options.max );
13278		this._setOption( "min", this.options.min );
13279		this._setOption( "step", this.options.step );
13280
13281		// format the value, but don't constrain
13282		this._value( this.element.val(), true );
13283
13284		this._draw();
13285		this._on( this._events );
13286		this._refresh();
13287
13288		// turning off autocomplete prevents the browser from remembering the
13289		// value when navigating through history, so we re-enable autocomplete
13290		// if the page is unloaded before the widget is destroyed. #7790
13291		this._on( this.window, {
13292			beforeunload: function() {
13293				this.element.removeAttr( "autocomplete" );
13294			}
13295		});
13296	},
13297
13298	_getCreateOptions: function() {
13299		var options = {},
13300			element = this.element;
13301
13302		$.each( [ "min", "max", "step" ], function( i, option ) {
13303			var value = element.attr( option );
13304			if ( value !== undefined && value.length ) {
13305				options[ option ] = value;
13306			}
13307		});
13308
13309		return options;
13310	},
13311
13312	_events: {
13313		keydown: function( event ) {
13314			if ( this._start( event ) && this._keydown( event ) ) {
13315				event.preventDefault();
13316			}
13317		},
13318		keyup: "_stop",
13319		focus: function() {
13320			this.previous = this.element.val();
13321		},
13322		blur: function( event ) {
13323			if ( this.cancelBlur ) {
13324				delete this.cancelBlur;
13325				return;
13326			}
13327
13328			this._refresh();
13329			if ( this.previous !== this.element.val() ) {
13330				this._trigger( "change", event );
13331			}
13332		},
13333		mousewheel: function( event, delta ) {
13334			if ( !delta ) {
13335				return;
13336			}
13337			if ( !this.spinning && !this._start( event ) ) {
13338				return false;
13339			}
13340
13341			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
13342			clearTimeout( this.mousewheelTimer );
13343			this.mousewheelTimer = this._delay(function() {
13344				if ( this.spinning ) {
13345					this._stop( event );
13346				}
13347			}, 100 );
13348			event.preventDefault();
13349		},
13350		"mousedown .ui-spinner-button": function( event ) {
13351			var previous;
13352
13353			// We never want the buttons to have focus; whenever the user is
13354			// interacting with the spinner, the focus should be on the input.
13355			// If the input is focused then this.previous is properly set from
13356			// when the input first received focus. If the input is not focused
13357			// then we need to set this.previous based on the value before spinning.
13358			previous = this.element[0] === this.document[0].activeElement ?
13359				this.previous : this.element.val();
13360			function checkFocus() {
13361				var isActive = this.element[0] === this.document[0].activeElement;
13362				if ( !isActive ) {
13363					this.element.focus();
13364					this.previous = previous;
13365					// support: IE
13366					// IE sets focus asynchronously, so we need to check if focus
13367					// moved off of the input because the user clicked on the button.
13368					this._delay(function() {
13369						this.previous = previous;
13370					});
13371				}
13372			}
13373
13374			// ensure focus is on (or stays on) the text field
13375			event.preventDefault();
13376			checkFocus.call( this );
13377
13378			// support: IE
13379			// IE doesn't prevent moving focus even with event.preventDefault()
13380			// so we set a flag to know when we should ignore the blur event
13381			// and check (again) if focus moved off of the input.
13382			this.cancelBlur = true;
13383			this._delay(function() {
13384				delete this.cancelBlur;
13385				checkFocus.call( this );
13386			});
13387
13388			if ( this._start( event ) === false ) {
13389				return;
13390			}
13391
13392			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13393		},
13394		"mouseup .ui-spinner-button": "_stop",
13395		"mouseenter .ui-spinner-button": function( event ) {
13396			// button will add ui-state-active if mouse was down while mouseleave and kept down
13397			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13398				return;
13399			}
13400
13401			if ( this._start( event ) === false ) {
13402				return false;
13403			}
13404			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13405		},
13406		// TODO: do we really want to consider this a stop?
13407		// shouldn't we just stop the repeater and wait until mouseup before
13408		// we trigger the stop event?
13409		"mouseleave .ui-spinner-button": "_stop"
13410	},
13411
13412	_draw: function() {
13413		var uiSpinner = this.uiSpinner = this.element
13414			.addClass( "ui-spinner-input" )
13415			.attr( "autocomplete", "off" )
13416			.wrap( this._uiSpinnerHtml() )
13417			.parent()
13418				// add buttons
13419				.append( this._buttonHtml() );
13420
13421		this.element.attr( "role", "spinbutton" );
13422
13423		// button bindings
13424		this.buttons = uiSpinner.find( ".ui-spinner-button" )
13425			.attr( "tabIndex", -1 )
13426			.button()
13427			.removeClass( "ui-corner-all" );
13428
13429		// IE 6 doesn't understand height: 50% for the buttons
13430		// unless the wrapper has an explicit height
13431		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
13432				uiSpinner.height() > 0 ) {
13433			uiSpinner.height( uiSpinner.height() );
13434		}
13435
13436		// disable spinner if element was already disabled
13437		if ( this.options.disabled ) {
13438			this.disable();
13439		}
13440	},
13441
13442	_keydown: function( event ) {
13443		var options = this.options,
13444			keyCode = $.ui.keyCode;
13445
13446		switch ( event.keyCode ) {
13447		case keyCode.UP:
13448			this._repeat( null, 1, event );
13449			return true;
13450		case keyCode.DOWN:
13451			this._repeat( null, -1, event );
13452			return true;
13453		case keyCode.PAGE_UP:
13454			this._repeat( null, options.page, event );
13455			return true;
13456		case keyCode.PAGE_DOWN:
13457			this._repeat( null, -options.page, event );
13458			return true;
13459		}
13460
13461		return false;
13462	},
13463
13464	_uiSpinnerHtml: function() {
13465		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
13466	},
13467
13468	_buttonHtml: function() {
13469		return "" +
13470			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
13471				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
13472			"</a>" +
13473			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
13474				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
13475			"</a>";
13476	},
13477
13478	_start: function( event ) {
13479		if ( !this.spinning && this._trigger( "start", event ) === false ) {
13480			return false;
13481		}
13482
13483		if ( !this.counter ) {
13484			this.counter = 1;
13485		}
13486		this.spinning = true;
13487		return true;
13488	},
13489
13490	_repeat: function( i, steps, event ) {
13491		i = i || 500;
13492
13493		clearTimeout( this.timer );
13494		this.timer = this._delay(function() {
13495			this._repeat( 40, steps, event );
13496		}, i );
13497
13498		this._spin( steps * this.options.step, event );
13499	},
13500
13501	_spin: function( step, event ) {
13502		var value = this.value() || 0;
13503
13504		if ( !this.counter ) {
13505			this.counter = 1;
13506		}
13507
13508		value = this._adjustValue( value + step * this._increment( this.counter ) );
13509
13510		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
13511			this._value( value );
13512			this.counter++;
13513		}
13514	},
13515
13516	_increment: function( i ) {
13517		var incremental = this.options.incremental;
13518
13519		if ( incremental ) {
13520			return $.isFunction( incremental ) ?
13521				incremental( i ) :
13522				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
13523		}
13524
13525		return 1;
13526	},
13527
13528	_precision: function() {
13529		var precision = this._precisionOf( this.options.step );
13530		if ( this.options.min !== null ) {
13531			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13532		}
13533		return precision;
13534	},
13535
13536	_precisionOf: function( num ) {
13537		var str = num.toString(),
13538			decimal = str.indexOf( "." );
13539		return decimal === -1 ? 0 : str.length - decimal - 1;
13540	},
13541
13542	_adjustValue: function( value ) {
13543		var base, aboveMin,
13544			options = this.options;
13545
13546		// make sure we're at a valid step
13547		// - find out where we are relative to the base (min or 0)
13548		base = options.min !== null ? options.min : 0;
13549		aboveMin = value - base;
13550		// - round to the nearest step
13551		aboveMin = Math.round(aboveMin / options.step) * options.step;
13552		// - rounding is based on 0, so adjust back to our base
13553		value = base + aboveMin;
13554
13555		// fix precision from bad JS floating point math
13556		value = parseFloat( value.toFixed( this._precision() ) );
13557
13558		// clamp the value
13559		if ( options.max !== null && value > options.max) {
13560			return options.max;
13561		}
13562		if ( options.min !== null && value < options.min ) {
13563			return options.min;
13564		}
13565
13566		return value;
13567	},
13568
13569	_stop: function( event ) {
13570		if ( !this.spinning ) {
13571			return;
13572		}
13573
13574		clearTimeout( this.timer );
13575		clearTimeout( this.mousewheelTimer );
13576		this.counter = 0;
13577		this.spinning = false;
13578		this._trigger( "stop", event );
13579	},
13580
13581	_setOption: function( key, value ) {
13582		if ( key === "culture" || key === "numberFormat" ) {
13583			var prevValue = this._parse( this.element.val() );
13584			this.options[ key ] = value;
13585			this.element.val( this._format( prevValue ) );
13586			return;
13587		}
13588
13589		if ( key === "max" || key === "min" || key === "step" ) {
13590			if ( typeof value === "string" ) {
13591				value = this._parse( value );
13592			}
13593		}
13594		if ( key === "icons" ) {
13595			this.buttons.first().find( ".ui-icon" )
13596				.removeClass( this.options.icons.up )
13597				.addClass( value.up );
13598			this.buttons.last().find( ".ui-icon" )
13599				.removeClass( this.options.icons.down )
13600				.addClass( value.down );
13601		}
13602
13603		this._super( key, value );
13604
13605		if ( key === "disabled" ) {
13606			if ( value ) {
13607				this.element.prop( "disabled", true );
13608				this.buttons.button( "disable" );
13609			} else {
13610				this.element.prop( "disabled", false );
13611				this.buttons.button( "enable" );
13612			}
13613		}
13614	},
13615
13616	_setOptions: modifier(function( options ) {
13617		this._super( options );
13618		this._value( this.element.val() );
13619	}),
13620
13621	_parse: function( val ) {
13622		if ( typeof val === "string" && val !== "" ) {
13623			val = window.Globalize && this.options.numberFormat ?
13624				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13625		}
13626		return val === "" || isNaN( val ) ? null : val;
13627	},
13628
13629	_format: function( value ) {
13630		if ( value === "" ) {
13631			return "";
13632		}
13633		return window.Globalize && this.options.numberFormat ?
13634			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13635			value;
13636	},
13637
13638	_refresh: function() {
13639		this.element.attr({
13640			"aria-valuemin": this.options.min,
13641			"aria-valuemax": this.options.max,
13642			// TODO: what should we do with values that can't be parsed?
13643			"aria-valuenow": this._parse( this.element.val() )
13644		});
13645	},
13646
13647	// update the value without triggering change
13648	_value: function( value, allowAny ) {
13649		var parsed;
13650		if ( value !== "" ) {
13651			parsed = this._parse( value );
13652			if ( parsed !== null ) {
13653				if ( !allowAny ) {
13654					parsed = this._adjustValue( parsed );
13655				}
13656				value = this._format( parsed );
13657			}
13658		}
13659		this.element.val( value );
13660		this._refresh();
13661	},
13662
13663	_destroy: function() {
13664		this.element
13665			.removeClass( "ui-spinner-input" )
13666			.prop( "disabled", false )
13667			.removeAttr( "autocomplete" )
13668			.removeAttr( "role" )
13669			.removeAttr( "aria-valuemin" )
13670			.removeAttr( "aria-valuemax" )
13671			.removeAttr( "aria-valuenow" );
13672		this.uiSpinner.replaceWith( this.element );
13673	},
13674
13675	stepUp: modifier(function( steps ) {
13676		this._stepUp( steps );
13677	}),
13678	_stepUp: function( steps ) {
13679		if ( this._start() ) {
13680			this._spin( (steps || 1) * this.options.step );
13681			this._stop();
13682		}
13683	},
13684
13685	stepDown: modifier(function( steps ) {
13686		this._stepDown( steps );
13687	}),
13688	_stepDown: function( steps ) {
13689		if ( this._start() ) {
13690			this._spin( (steps || 1) * -this.options.step );
13691			this._stop();
13692		}
13693	},
13694
13695	pageUp: modifier(function( pages ) {
13696		this._stepUp( (pages || 1) * this.options.page );
13697	}),
13698
13699	pageDown: modifier(function( pages ) {
13700		this._stepDown( (pages || 1) * this.options.page );
13701	}),
13702
13703	value: function( newVal ) {
13704		if ( !arguments.length ) {
13705			return this._parse( this.element.val() );
13706		}
13707		modifier( this._value ).call( this, newVal );
13708	},
13709
13710	widget: function() {
13711		return this.uiSpinner;
13712	}
13713});
13714
13715}( jQuery ) );
13716
13717(function( $, undefined ) {
13718
13719var tabId = 0,
13720	rhash = /#.*$/;
13721
13722function getNextTabId() {
13723	return ++tabId;
13724}
13725
13726function isLocal( anchor ) {
13727	return anchor.hash.length > 1 &&
13728		decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
13729			decodeURIComponent( location.href.replace( rhash, "" ) );
13730}
13731
13732$.widget( "ui.tabs", {
13733	version: "1.10.1",
13734	delay: 300,
13735	options: {
13736		active: null,
13737		collapsible: false,
13738		event: "click",
13739		heightStyle: "content",
13740		hide: null,
13741		show: null,
13742
13743		// callbacks
13744		activate: null,
13745		beforeActivate: null,
13746		beforeLoad: null,
13747		load: null
13748	},
13749
13750	_create: function() {
13751		var that = this,
13752			options = this.options;
13753
13754		this.running = false;
13755
13756		this.element
13757			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13758			.toggleClass( "ui-tabs-collapsible", options.collapsible )
13759			// Prevent users from focusing disabled tabs via click
13760			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13761				if ( $( this ).is( ".ui-state-disabled" ) ) {
13762					event.preventDefault();
13763				}
13764			})
13765			// support: IE <9
13766			// Preventing the default action in mousedown doesn't prevent IE
13767			// from focusing the element, so if the anchor gets focused, blur.
13768			// We don't have to worry about focusing the previously focused
13769			// element since clicking on a non-focusable element should focus
13770			// the body anyway.
13771			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13772				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13773					this.blur();
13774				}
13775			});
13776
13777		this._processTabs();
13778		options.active = this._initialActive();
13779
13780		// Take disabling tabs via class attribute from HTML
13781		// into account and update option properly.
13782		if ( $.isArray( options.disabled ) ) {
13783			options.disabled = $.unique( options.disabled.concat(
13784				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13785					return that.tabs.index( li );
13786				})
13787			) ).sort();
13788		}
13789
13790		// check for length avoids error when initializing empty list
13791		if ( this.options.active !== false && this.anchors.length ) {
13792			this.active = this._findActive( options.active );
13793		} else {
13794			this.active = $();
13795		}
13796
13797		this._refresh();
13798
13799		if ( this.active.length ) {
13800			this.load( options.active );
13801		}
13802	},
13803
13804	_initialActive: function() {
13805		var active = this.options.active,
13806			collapsible = this.options.collapsible,
13807			locationHash = location.hash.substring( 1 );
13808
13809		if ( active === null ) {
13810			// check the fragment identifier in the URL
13811			if ( locationHash ) {
13812				this.tabs.each(function( i, tab ) {
13813					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13814						active = i;
13815						return false;
13816					}
13817				});
13818			}
13819
13820			// check for a tab marked active via a class
13821			if ( active === null ) {
13822				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13823			}
13824
13825			// no active tab, set to false
13826			if ( active === null || active === -1 ) {
13827				active = this.tabs.length ? 0 : false;
13828			}
13829		}
13830
13831		// handle numbers: negative, out of range
13832		if ( active !== false ) {
13833			active = this.tabs.index( this.tabs.eq( active ) );
13834			if ( active === -1 ) {
13835				active = collapsible ? false : 0;
13836			}
13837		}
13838
13839		// don't allow collapsible: false and active: false
13840		if ( !collapsible && active === false && this.anchors.length ) {
13841			active = 0;
13842		}
13843
13844		return active;
13845	},
13846
13847	_getCreateEventData: function() {
13848		return {
13849			tab: this.active,
13850			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13851		};
13852	},
13853
13854	_tabKeydown: function( event ) {
13855		/*jshint maxcomplexity:15*/
13856		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13857			selectedIndex = this.tabs.index( focusedTab ),
13858			goingForward = true;
13859
13860		if ( this._handlePageNav( event ) ) {
13861			return;
13862		}
13863
13864		switch ( event.keyCode ) {
13865			case $.ui.keyCode.RIGHT:
13866			case $.ui.keyCode.DOWN:
13867				selectedIndex++;
13868				break;
13869			case $.ui.keyCode.UP:
13870			case $.ui.keyCode.LEFT:
13871				goingForward = false;
13872				selectedIndex--;
13873				break;
13874			case $.ui.keyCode.END:
13875				selectedIndex = this.anchors.length - 1;
13876				break;
13877			case $.ui.keyCode.HOME:
13878				selectedIndex = 0;
13879				break;
13880			case $.ui.keyCode.SPACE:
13881				// Activate only, no collapsing
13882				event.preventDefault();
13883				clearTimeout( this.activating );
13884				this._activate( selectedIndex );
13885				return;
13886			case $.ui.keyCode.ENTER:
13887				// Toggle (cancel delayed activation, allow collapsing)
13888				event.preventDefault();
13889				clearTimeout( this.activating );
13890				// Determine if we should collapse or activate
13891				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13892				return;
13893			default:
13894				return;
13895		}
13896
13897		// Focus the appropriate tab, based on which key was pressed
13898		event.preventDefault();
13899		clearTimeout( this.activating );
13900		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13901
13902		// Navigating with control key will prevent automatic activation
13903		if ( !event.ctrlKey ) {
13904			// Update aria-selected immediately so that AT think the tab is already selected.
13905			// Otherwise AT may confuse the user by stating that they need to activate the tab,
13906			// but the tab will already be activated by the time the announcement finishes.
13907			focusedTab.attr( "aria-selected", "false" );
13908			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13909
13910			this.activating = this._delay(function() {
13911				this.option( "active", selectedIndex );
13912			}, this.delay );
13913		}
13914	},
13915
13916	_panelKeydown: function( event ) {
13917		if ( this._handlePageNav( event ) ) {
13918			return;
13919		}
13920
13921		// Ctrl+up moves focus to the current tab
13922		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13923			event.preventDefault();
13924			this.active.focus();
13925		}
13926	},
13927
13928	// Alt+page up/down moves focus to the previous/next tab (and activates)
13929	_handlePageNav: function( event ) {
13930		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13931			this._activate( this._focusNextTab( this.options.active - 1, false ) );
13932			return true;
13933		}
13934		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13935			this._activate( this._focusNextTab( this.options.active + 1, true ) );
13936			return true;
13937		}
13938	},
13939
13940	_findNextTab: function( index, goingForward ) {
13941		var lastTabIndex = this.tabs.length - 1;
13942
13943		function constrain() {
13944			if ( index > lastTabIndex ) {
13945				index = 0;
13946			}
13947			if ( index < 0 ) {
13948				index = lastTabIndex;
13949			}
13950			return index;
13951		}
13952
13953		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
13954			index = goingForward ? index + 1 : index - 1;
13955		}
13956
13957		return index;
13958	},
13959
13960	_focusNextTab: function( index, goingForward ) {
13961		index = this._findNextTab( index, goingForward );
13962		this.tabs.eq( index ).focus();
13963		return index;
13964	},
13965
13966	_setOption: function( key, value ) {
13967		if ( key === "active" ) {
13968			// _activate() will handle invalid values and update this.options
13969			this._activate( value );
13970			return;
13971		}
13972
13973		if ( key === "disabled" ) {
13974			// don't use the widget factory's disabled handling
13975			this._setupDisabled( value );
13976			return;
13977		}
13978
13979		this._super( key, value);
13980
13981		if ( key === "collapsible" ) {
13982			this.element.toggleClass( "ui-tabs-collapsible", value );
13983			// Setting collapsible: false while collapsed; open first panel
13984			if ( !value && this.options.active === false ) {
13985				this._activate( 0 );
13986			}
13987		}
13988
13989		if ( key === "event" ) {
13990			this._setupEvents( value );
13991		}
13992
13993		if ( key === "heightStyle" ) {
13994			this._setupHeightStyle( value );
13995		}
13996	},
13997
13998	_tabId: function( tab ) {
13999		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
14000	},
14001
14002	_sanitizeSelector: function( hash ) {
14003		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14004	},
14005
14006	refresh: function() {
14007		var options = this.options,
14008			lis = this.tablist.children( ":has(a[href])" );
14009
14010		// get disabled tabs from class attribute from HTML
14011		// this will get converted to a boolean if needed in _refresh()
14012		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14013			return lis.index( tab );
14014		});
14015
14016		this._processTabs();
14017
14018		// was collapsed or no tabs
14019		if ( options.active === false || !this.anchors.length ) {
14020			options.active = false;
14021			this.active = $();
14022		// was active, but active tab is gone
14023		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14024			// all remaining tabs are disabled
14025			if ( this.tabs.length === options.disabled.length ) {
14026				options.active = false;
14027				this.active = $();
14028			// activate previous tab
14029			} else {
14030				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14031			}
14032		// was active, active tab still exists
14033		} else {
14034			// make sure active index is correct
14035			options.active = this.tabs.index( this.active );
14036		}
14037
14038		this._refresh();
14039	},
14040
14041	_refresh: function() {
14042		this._setupDisabled( this.options.disabled );
14043		this._setupEvents( this.options.event );
14044		this._setupHeightStyle( this.options.heightStyle );
14045
14046		this.tabs.not( this.active ).attr({
14047			"aria-selected": "false",
14048			tabIndex: -1
14049		});
14050		this.panels.not( this._getPanelForTab( this.active ) )
14051			.hide()
14052			.attr({
14053				"aria-expanded": "false",
14054				"aria-hidden": "true"
14055			});
14056
14057		// Make sure one tab is in the tab order
14058		if ( !this.active.length ) {
14059			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14060		} else {
14061			this.active
14062				.addClass( "ui-tabs-active ui-state-active" )
14063				.attr({
14064					"aria-selected": "true",
14065					tabIndex: 0
14066				});
14067			this._getPanelForTab( this.active )
14068				.show()
14069				.attr({
14070					"aria-expanded": "true",
14071					"aria-hidden": "false"
14072				});
14073		}
14074	},
14075
14076	_processTabs: function() {
14077		var that = this;
14078
14079		this.tablist = this._getList()
14080			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14081			.attr( "role", "tablist" );
14082
14083		this.tabs = this.tablist.find( "> li:has(a[href])" )
14084			.addClass( "ui-state-default ui-corner-top" )
14085			.attr({
14086				role: "tab",
14087				tabIndex: -1
14088			});
14089
14090		this.anchors = this.tabs.map(function() {
14091				return $( "a", this )[ 0 ];
14092			})
14093			.addClass( "ui-tabs-anchor" )
14094			.attr({
14095				role: "presentation",
14096				tabIndex: -1
14097			});
14098
14099		this.panels = $();
14100
14101		this.anchors.each(function( i, anchor ) {
14102			var selector, panel, panelId,
14103				anchorId = $( anchor ).uniqueId().attr( "id" ),
14104				tab = $( anchor ).closest( "li" ),
14105				originalAriaControls = tab.attr( "aria-controls" );
14106
14107			// inline tab
14108			if ( isLocal( anchor ) ) {
14109				selector = anchor.hash;
14110				panel = that.element.find( that._sanitizeSelector( selector ) );
14111			// remote tab
14112			} else {
14113				panelId = that._tabId( tab );
14114				selector = "#" + panelId;
14115				panel = that.element.find( selector );
14116				if ( !panel.length ) {
14117					panel = that._createPanel( panelId );
14118					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14119				}
14120				panel.attr( "aria-live", "polite" );
14121			}
14122
14123			if ( panel.length) {
14124				that.panels = that.panels.add( panel );
14125			}
14126			if ( originalAriaControls ) {
14127				tab.data( "ui-tabs-aria-controls", originalAriaControls );
14128			}
14129			tab.attr({
14130				"aria-controls": selector.substring( 1 ),
14131				"aria-labelledby": anchorId
14132			});
14133			panel.attr( "aria-labelledby", anchorId );
14134		});
14135
14136		this.panels
14137			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14138			.attr( "role", "tabpanel" );
14139	},
14140
14141	// allow overriding how to find the list for rare usage scenarios (#7715)
14142	_getList: function() {
14143		return this.element.find( "ol,ul" ).eq( 0 );
14144	},
14145
14146	_createPanel: function( id ) {
14147		return $( "<div>" )
14148			.attr( "id", id )
14149			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14150			.data( "ui-tabs-destroy", true );
14151	},
14152
14153	_setupDisabled: function( disabled ) {
14154		if ( $.isArray( disabled ) ) {
14155			if ( !disabled.length ) {
14156				disabled = false;
14157			} else if ( disabled.length === this.anchors.length ) {
14158				disabled = true;
14159			}
14160		}
14161
14162		// disable tabs
14163		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
14164			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14165				$( li )
14166					.addClass( "ui-state-disabled" )
14167					.attr( "aria-disabled", "true" );
14168			} else {
14169				$( li )
14170					.removeClass( "ui-state-disabled" )
14171					.removeAttr( "aria-disabled" );
14172			}
14173		}
14174
14175		this.options.disabled = disabled;
14176	},
14177
14178	_setupEvents: function( event ) {
14179		var events = {
14180			click: function( event ) {
14181				event.preventDefault();
14182			}
14183		};
14184		if ( event ) {
14185			$.each( event.split(" "), function( index, eventName ) {
14186				events[ eventName ] = "_eventHandler";
14187			});
14188		}
14189
14190		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14191		this._on( this.anchors, events );
14192		this._on( this.tabs, { keydown: "_tabKeydown" } );
14193		this._on( this.panels, { keydown: "_panelKeydown" } );
14194
14195		this._focusable( this.tabs );
14196		this._hoverable( this.tabs );
14197	},
14198
14199	_setupHeightStyle: function( heightStyle ) {
14200		var maxHeight,
14201			parent = this.element.parent();
14202
14203		if ( heightStyle === "fill" ) {
14204			maxHeight = parent.height();
14205			maxHeight -= this.element.outerHeight() - this.element.height();
14206
14207			this.element.siblings( ":visible" ).each(function() {
14208				var elem = $( this ),
14209					position = elem.css( "position" );
14210
14211				if ( position === "absolute" || position === "fixed" ) {
14212					return;
14213				}
14214				maxHeight -= elem.outerHeight( true );
14215			});
14216
14217			this.element.children().not( this.panels ).each(function() {
14218				maxHeight -= $( this ).outerHeight( true );
14219			});
14220
14221			this.panels.each(function() {
14222				$( this ).height( Math.max( 0, maxHeight -
14223					$( this ).innerHeight() + $( this ).height() ) );
14224			})
14225			.css( "overflow", "auto" );
14226		} else if ( heightStyle === "auto" ) {
14227			maxHeight = 0;
14228			this.panels.each(function() {
14229				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14230			}).height( maxHeight );
14231		}
14232	},
14233
14234	_eventHandler: function( event ) {
14235		var options = this.options,
14236			active = this.active,
14237			anchor = $( event.currentTarget ),
14238			tab = anchor.closest( "li" ),
14239			clickedIsActive = tab[ 0 ] === active[ 0 ],
14240			collapsing = clickedIsActive && options.collapsible,
14241			toShow = collapsing ? $() : this._getPanelForTab( tab ),
14242			toHide = !active.length ? $() : this._getPanelForTab( active ),
14243			eventData = {
14244				oldTab: active,
14245				oldPanel: toHide,
14246				newTab: collapsing ? $() : tab,
14247				newPanel: toShow
14248			};
14249
14250		event.preventDefault();
14251
14252		if ( tab.hasClass( "ui-state-disabled" ) ||
14253				// tab is already loading
14254				tab.hasClass( "ui-tabs-loading" ) ||
14255				// can't switch durning an animation
14256				this.running ||
14257				// click on active header, but not collapsible
14258				( clickedIsActive && !options.collapsible ) ||
14259				// allow canceling activation
14260				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14261			return;
14262		}
14263
14264		options.active = collapsing ? false : this.tabs.index( tab );
14265
14266		this.active = clickedIsActive ? $() : tab;
14267		if ( this.xhr ) {
14268			this.xhr.abort();
14269		}
14270
14271		if ( !toHide.length && !toShow.length ) {
14272			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14273		}
14274
14275		if ( toShow.length ) {
14276			this.load( this.tabs.index( tab ), event );
14277		}
14278		this._toggle( event, eventData );
14279	},
14280
14281	// handles show/hide for selecting tabs
14282	_toggle: function( event, eventData ) {
14283		var that = this,
14284			toShow = eventData.newPanel,
14285			toHide = eventData.oldPanel;
14286
14287		this.running = true;
14288
14289		function complete() {
14290			that.running = false;
14291			that._trigger( "activate", event, eventData );
14292		}
14293
14294		function show() {
14295			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14296
14297			if ( toShow.length && that.options.show ) {
14298				that._show( toShow, that.options.show, complete );
14299			} else {
14300				toShow.show();
14301				complete();
14302			}
14303		}
14304
14305		// start out by hiding, then showing, then completing
14306		if ( toHide.length && this.options.hide ) {
14307			this._hide( toHide, this.options.hide, function() {
14308				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14309				show();
14310			});
14311		} else {
14312			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14313			toHide.hide();
14314			show();
14315		}
14316
14317		toHide.attr({
14318			"aria-expanded": "false",
14319			"aria-hidden": "true"
14320		});
14321		eventData.oldTab.attr( "aria-selected", "false" );
14322		// If we're switching tabs, remove the old tab from the tab order.
14323		// If we're opening from collapsed state, remove the previous tab from the tab order.
14324		// If we're collapsing, then keep the collapsing tab in the tab order.
14325		if ( toShow.length && toHide.length ) {
14326			eventData.oldTab.attr( "tabIndex", -1 );
14327		} else if ( toShow.length ) {
14328			this.tabs.filter(function() {
14329				return $( this ).attr( "tabIndex" ) === 0;
14330			})
14331			.attr( "tabIndex", -1 );
14332		}
14333
14334		toShow.attr({
14335			"aria-expanded": "true",
14336			"aria-hidden": "false"
14337		});
14338		eventData.newTab.attr({
14339			"aria-selected": "true",
14340			tabIndex: 0
14341		});
14342	},
14343
14344	_activate: function( index ) {
14345		var anchor,
14346			active = this._findActive( index );
14347
14348		// trying to activate the already active panel
14349		if ( active[ 0 ] === this.active[ 0 ] ) {
14350			return;
14351		}
14352
14353		// trying to collapse, simulate a click on the current active header
14354		if ( !active.length ) {
14355			active = this.active;
14356		}
14357
14358		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14359		this._eventHandler({
14360			target: anchor,
14361			currentTarget: anchor,
14362			preventDefault: $.noop
14363		});
14364	},
14365
14366	_findActive: function( index ) {
14367		return index === false ? $() : this.tabs.eq( index );
14368	},
14369
14370	_getIndex: function( index ) {
14371		// meta-function to give users option to provide a href string instead of a numerical index.
14372		if ( typeof index === "string" ) {
14373			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
14374		}
14375
14376		return index;
14377	},
14378
14379	_destroy: function() {
14380		if ( this.xhr ) {
14381			this.xhr.abort();
14382		}
14383
14384		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
14385
14386		this.tablist
14387			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14388			.removeAttr( "role" );
14389
14390		this.anchors
14391			.removeClass( "ui-tabs-anchor" )
14392			.removeAttr( "role" )
14393			.removeAttr( "tabIndex" )
14394			.removeUniqueId();
14395
14396		this.tabs.add( this.panels ).each(function() {
14397			if ( $.data( this, "ui-tabs-destroy" ) ) {
14398				$( this ).remove();
14399			} else {
14400				$( this )
14401					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
14402						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
14403					.removeAttr( "tabIndex" )
14404					.removeAttr( "aria-live" )
14405					.removeAttr( "aria-busy" )
14406					.removeAttr( "aria-selected" )
14407					.removeAttr( "aria-labelledby" )
14408					.removeAttr( "aria-hidden" )
14409					.removeAttr( "aria-expanded" )
14410					.removeAttr( "role" );
14411			}
14412		});
14413
14414		this.tabs.each(function() {
14415			var li = $( this ),
14416				prev = li.data( "ui-tabs-aria-controls" );
14417			if ( prev ) {
14418				li
14419					.attr( "aria-controls", prev )
14420					.removeData( "ui-tabs-aria-controls" );
14421			} else {
14422				li.removeAttr( "aria-controls" );
14423			}
14424		});
14425
14426		this.panels.show();
14427
14428		if ( this.options.heightStyle !== "content" ) {
14429			this.panels.css( "height", "" );
14430		}
14431	},
14432
14433	enable: function( index ) {
14434		var disabled = this.options.disabled;
14435		if ( disabled === false ) {
14436			return;
14437		}
14438
14439		if ( index === undefined ) {
14440			disabled = false;
14441		} else {
14442			index = this._getIndex( index );
14443			if ( $.isArray( disabled ) ) {
14444				disabled = $.map( disabled, function( num ) {
14445					return num !== index ? num : null;
14446				});
14447			} else {
14448				disabled = $.map( this.tabs, function( li, num ) {
14449					return num !== index ? num : null;
14450				});
14451			}
14452		}
14453		this._setupDisabled( disabled );
14454	},
14455
14456	disable: function( index ) {
14457		var disabled = this.options.disabled;
14458		if ( disabled === true ) {
14459			return;
14460		}
14461
14462		if ( index === undefined ) {
14463			disabled = true;
14464		} else {
14465			index = this._getIndex( index );
14466			if ( $.inArray( index, disabled ) !== -1 ) {
14467				return;
14468			}
14469			if ( $.isArray( disabled ) ) {
14470				disabled = $.merge( [ index ], disabled ).sort();
14471			} else {
14472				disabled = [ index ];
14473			}
14474		}
14475		this._setupDisabled( disabled );
14476	},
14477
14478	load: function( index, event ) {
14479		index = this._getIndex( index );
14480		var that = this,
14481			tab = this.tabs.eq( index ),
14482			anchor = tab.find( ".ui-tabs-anchor" ),
14483			panel = this._getPanelForTab( tab ),
14484			eventData = {
14485				tab: tab,
14486				panel: panel
14487			};
14488
14489		// not remote
14490		if ( isLocal( anchor[ 0 ] ) ) {
14491			return;
14492		}
14493
14494		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14495
14496		// support: jQuery <1.8
14497		// jQuery <1.8 returns false if the request is canceled in beforeSend,
14498		// but as of 1.8, $.ajax() always returns a jqXHR object.
14499		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14500			tab.addClass( "ui-tabs-loading" );
14501			panel.attr( "aria-busy", "true" );
14502
14503			this.xhr
14504				.success(function( response ) {
14505					// support: jQuery <1.8
14506					// http://bugs.jquery.com/ticket/11778
14507					setTimeout(function() {
14508						panel.html( response );
14509						that._trigger( "load", event, eventData );
14510					}, 1 );
14511				})
14512				.complete(function( jqXHR, status ) {
14513					// support: jQuery <1.8
14514					// http://bugs.jquery.com/ticket/11778
14515					setTimeout(function() {
14516						if ( status === "abort" ) {
14517							that.panels.stop( false, true );
14518						}
14519
14520						tab.removeClass( "ui-tabs-loading" );
14521						panel.removeAttr( "aria-busy" );
14522
14523						if ( jqXHR === that.xhr ) {
14524							delete that.xhr;
14525						}
14526					}, 1 );
14527				});
14528		}
14529	},
14530
14531	_ajaxSettings: function( anchor, event, eventData ) {
14532		var that = this;
14533		return {
14534			url: anchor.attr( "href" ),
14535			beforeSend: function( jqXHR, settings ) {
14536				return that._trigger( "beforeLoad", event,
14537					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14538			}
14539		};
14540	},
14541
14542	_getPanelForTab: function( tab ) {
14543		var id = $( tab ).attr( "aria-controls" );
14544		return this.element.find( this._sanitizeSelector( "#" + id ) );
14545	}
14546});
14547
14548})( jQuery );
14549
14550(function( $ ) {
14551
14552var increments = 0;
14553
14554function addDescribedBy( elem, id ) {
14555	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14556	describedby.push( id );
14557	elem
14558		.data( "ui-tooltip-id", id )
14559		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14560}
14561
14562function removeDescribedBy( elem ) {
14563	var id = elem.data( "ui-tooltip-id" ),
14564		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14565		index = $.inArray( id, describedby );
14566	if ( index !== -1 ) {
14567		describedby.splice( index, 1 );
14568	}
14569
14570	elem.removeData( "ui-tooltip-id" );
14571	describedby = $.trim( describedby.join( " " ) );
14572	if ( describedby ) {
14573		elem.attr( "aria-describedby", describedby );
14574	} else {
14575		elem.removeAttr( "aria-describedby" );
14576	}
14577}
14578
14579$.widget( "ui.tooltip", {
14580	version: "1.10.1",
14581	options: {
14582		content: function() {
14583			// support: IE<9, Opera in jQuery <1.7
14584			// .text() can't accept undefined, so coerce to a string
14585			var title = $( this ).attr( "title" ) || "";
14586			// Escape title, since we're going from an attribute to raw HTML
14587			return $( "<a>" ).text( title ).html();
14588		},
14589		hide: true,
14590		// Disabled elements have inconsistent behavior across browsers (#8661)
14591		items: "[title]:not([disabled])",
14592		position: {
14593			my: "left top+15",
14594			at: "left bottom",
14595			collision: "flipfit flip"
14596		},
14597		show: true,
14598		tooltipClass: null,
14599		track: false,
14600
14601		// callbacks
14602		close: null,
14603		open: null
14604	},
14605
14606	_create: function() {
14607		this._on({
14608			mouseover: "open",
14609			focusin: "open"
14610		});
14611
14612		// IDs of generated tooltips, needed for destroy
14613		this.tooltips = {};
14614		// IDs of parent tooltips where we removed the title attribute
14615		this.parents = {};
14616
14617		if ( this.options.disabled ) {
14618			this._disable();
14619		}
14620	},
14621
14622	_setOption: function( key, value ) {
14623		var that = this;
14624
14625		if ( key === "disabled" ) {
14626			this[ value ? "_disable" : "_enable" ]();
14627			this.options[ key ] = value;
14628			// disable element style changes
14629			return;
14630		}
14631
14632		this._super( key, value );
14633
14634		if ( key === "content" ) {
14635			$.each( this.tooltips, function( id, element ) {
14636				that._updateContent( element );
14637			});
14638		}
14639	},
14640
14641	_disable: function() {
14642		var that = this;
14643
14644		// close open tooltips
14645		$.each( this.tooltips, function( id, element ) {
14646			var event = $.Event( "blur" );
14647			event.target = event.currentTarget = element[0];
14648			that.close( event, true );
14649		});
14650
14651		// remove title attributes to prevent native tooltips
14652		this.element.find( this.options.items ).addBack().each(function() {
14653			var element = $( this );
14654			if ( element.is( "[title]" ) ) {
14655				element
14656					.data( "ui-tooltip-title", element.attr( "title" ) )
14657					.attr( "title", "" );
14658			}
14659		});
14660	},
14661
14662	_enable: function() {
14663		// restore title attributes
14664		this.element.find( this.options.items ).addBack().each(function() {
14665			var element = $( this );
14666			if ( element.data( "ui-tooltip-title" ) ) {
14667				element.attr( "title", element.data( "ui-tooltip-title" ) );
14668			}
14669		});
14670	},
14671
14672	open: function( event ) {
14673		var that = this,
14674			target = $( event ? event.target : this.element )
14675				// we need closest here due to mouseover bubbling,
14676				// but always pointing at the same event target
14677				.closest( this.options.items );
14678
14679		// No element to show a tooltip for or the tooltip is already open
14680		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14681			return;
14682		}
14683
14684		if ( target.attr( "title" ) ) {
14685			target.data( "ui-tooltip-title", target.attr( "title" ) );
14686		}
14687
14688		target.data( "ui-tooltip-open", true );
14689
14690		// kill parent tooltips, custom or native, for hover
14691		if ( event && event.type === "mouseover" ) {
14692			target.parents().each(function() {
14693				var parent = $( this ),
14694					blurEvent;
14695				if ( parent.data( "ui-tooltip-open" ) ) {
14696					blurEvent = $.Event( "blur" );
14697					blurEvent.target = blurEvent.currentTarget = this;
14698					that.close( blurEvent, true );
14699				}
14700				if ( parent.attr( "title" ) ) {
14701					parent.uniqueId();
14702					that.parents[ this.id ] = {
14703						element: this,
14704						title: parent.attr( "title" )
14705					};
14706					parent.attr( "title", "" );
14707				}
14708			});
14709		}
14710
14711		this._updateContent( target, event );
14712	},
14713
14714	_updateContent: function( target, event ) {
14715		var content,
14716			contentOption = this.options.content,
14717			that = this,
14718			eventType = event ? event.type : null;
14719
14720		if ( typeof contentOption === "string" ) {
14721			return this._open( event, target, contentOption );
14722		}
14723
14724		content = contentOption.call( target[0], function( response ) {
14725			// ignore async response if tooltip was closed already
14726			if ( !target.data( "ui-tooltip-open" ) ) {
14727				return;
14728			}
14729			// IE may instantly serve a cached response for ajax requests
14730			// delay this call to _open so the other call to _open runs first
14731			that._delay(function() {
14732				// jQuery creates a special event for focusin when it doesn't
14733				// exist natively. To improve performance, the native event
14734				// object is reused and the type is changed. Therefore, we can't
14735				// rely on the type being correct after the event finished
14736				// bubbling, so we set it back to the previous value. (#8740)
14737				if ( event ) {
14738					event.type = eventType;
14739				}
14740				this._open( event, target, response );
14741			});
14742		});
14743		if ( content ) {
14744			this._open( event, target, content );
14745		}
14746	},
14747
14748	_open: function( event, target, content ) {
14749		var tooltip, events, delayedShow,
14750			positionOption = $.extend( {}, this.options.position );
14751
14752		if ( !content ) {
14753			return;
14754		}
14755
14756		// Content can be updated multiple times. If the tooltip already
14757		// exists, then just update the content and bail.
14758		tooltip = this._find( target );
14759		if ( tooltip.length ) {
14760			tooltip.find( ".ui-tooltip-content" ).html( content );
14761			return;
14762		}
14763
14764		// if we have a title, clear it to prevent the native tooltip
14765		// we have to check first to avoid defining a title if none exists
14766		// (we don't want to cause an element to start matching [title])
14767		//
14768		// We use removeAttr only for key events, to allow IE to export the correct
14769		// accessible attributes. For mouse events, set to empty string to avoid
14770		// native tooltip showing up (happens only when removing inside mouseover).
14771		if ( target.is( "[title]" ) ) {
14772			if ( event && event.type === "mouseover" ) {
14773				target.attr( "title", "" );
14774			} else {
14775				target.removeAttr( "title" );
14776			}
14777		}
14778
14779		tooltip = this._tooltip( target );
14780		addDescribedBy( target, tooltip.attr( "id" ) );
14781		tooltip.find( ".ui-tooltip-content" ).html( content );
14782
14783		function position( event ) {
14784			positionOption.of = event;
14785			if ( tooltip.is( ":hidden" ) ) {
14786				return;
14787			}
14788			tooltip.position( positionOption );
14789		}
14790		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14791			this._on( this.document, {
14792				mousemove: position
14793			});
14794			// trigger once to override element-relative positioning
14795			position( event );
14796		} else {
14797			tooltip.position( $.extend({
14798				of: target
14799			}, this.options.position ) );
14800		}
14801
14802		tooltip.hide();
14803
14804		this._show( tooltip, this.options.show );
14805		// Handle tracking tooltips that are shown with a delay (#8644). As soon
14806		// as the tooltip is visible, position the tooltip using the most recent
14807		// event.
14808		if ( this.options.show && this.options.show.delay ) {
14809			delayedShow = this.delayedShow = setInterval(function() {
14810				if ( tooltip.is( ":visible" ) ) {
14811					position( positionOption.of );
14812					clearInterval( delayedShow );
14813				}
14814			}, $.fx.interval );
14815		}
14816
14817		this._trigger( "open", event, { tooltip: tooltip } );
14818
14819		events = {
14820			keyup: function( event ) {
14821				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14822					var fakeEvent = $.Event(event);
14823					fakeEvent.currentTarget = target[0];
14824					this.close( fakeEvent, true );
14825				}
14826			},
14827			remove: function() {
14828				this._removeTooltip( tooltip );
14829			}
14830		};
14831		if ( !event || event.type === "mouseover" ) {
14832			events.mouseleave = "close";
14833		}
14834		if ( !event || event.type === "focusin" ) {
14835			events.focusout = "close";
14836		}
14837		this._on( true, target, events );
14838	},
14839
14840	close: function( event ) {
14841		var that = this,
14842			target = $( event ? event.currentTarget : this.element ),
14843			tooltip = this._find( target );
14844
14845		// disabling closes the tooltip, so we need to track when we're closing
14846		// to avoid an infinite loop in case the tooltip becomes disabled on close
14847		if ( this.closing ) {
14848			return;
14849		}
14850
14851		// Clear the interval for delayed tracking tooltips
14852		clearInterval( this.delayedShow );
14853
14854		// only set title if we had one before (see comment in _open())
14855		if ( target.data( "ui-tooltip-title" ) ) {
14856			target.attr( "title", target.data( "ui-tooltip-title" ) );
14857		}
14858
14859		removeDescribedBy( target );
14860
14861		tooltip.stop( true );
14862		this._hide( tooltip, this.options.hide, function() {
14863			that._removeTooltip( $( this ) );
14864		});
14865
14866		target.removeData( "ui-tooltip-open" );
14867		this._off( target, "mouseleave focusout keyup" );
14868		// Remove 'remove' binding only on delegated targets
14869		if ( target[0] !== this.element[0] ) {
14870			this._off( target, "remove" );
14871		}
14872		this._off( this.document, "mousemove" );
14873
14874		if ( event && event.type === "mouseleave" ) {
14875			$.each( this.parents, function( id, parent ) {
14876				$( parent.element ).attr( "title", parent.title );
14877				delete that.parents[ id ];
14878			});
14879		}
14880
14881		this.closing = true;
14882		this._trigger( "close", event, { tooltip: tooltip } );
14883		this.closing = false;
14884	},
14885
14886	_tooltip: function( element ) {
14887		var id = "ui-tooltip-" + increments++,
14888			tooltip = $( "<div>" )
14889				.attr({
14890					id: id,
14891					role: "tooltip"
14892				})
14893				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14894					( this.options.tooltipClass || "" ) );
14895		$( "<div>" )
14896			.addClass( "ui-tooltip-content" )
14897			.appendTo( tooltip );
14898		tooltip.appendTo( this.document[0].body );
14899		this.tooltips[ id ] = element;
14900		return tooltip;
14901	},
14902
14903	_find: function( target ) {
14904		var id = target.data( "ui-tooltip-id" );
14905		return id ? $( "#" + id ) : $();
14906	},
14907
14908	_removeTooltip: function( tooltip ) {
14909		tooltip.remove();
14910		delete this.tooltips[ tooltip.attr( "id" ) ];
14911	},
14912
14913	_destroy: function() {
14914		var that = this;
14915
14916		// close open tooltips
14917		$.each( this.tooltips, function( id, element ) {
14918			// Delegate to close method to handle common cleanup
14919			var event = $.Event( "blur" );
14920			event.target = event.currentTarget = element[0];
14921			that.close( event, true );
14922
14923			// Remove immediately; destroying an open tooltip doesn't use the
14924			// hide animation
14925			$( "#" + id ).remove();
14926
14927			// Restore the title
14928			if ( element.data( "ui-tooltip-title" ) ) {
14929				element.attr( "title", element.data( "ui-tooltip-title" ) );
14930				element.removeData( "ui-tooltip-title" );
14931			}
14932		});
14933	}
14934});
14935
14936}( jQuery ) );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.