PageSourceSearch

https://auraf.ru/bitrix/templates/aura-flowers-new/js/jquery-ui-1.9.2.custom.js?1715628634235068

js auraf.ru collected 2026-10-07 17:00:36 UTC 235,068 bytes, 6,577 lines download raw bytes

vendor: 6,214 bytes, lines 1-227
1/*! jQuery UI - v1.9.2 - 2013-11-19
2* http://jqueryui.com
3* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.datepicker.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.9.2",
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;
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().andSelf().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
179$(function() {
180	var body = document.body,
181		div = body.appendChild( div = document.createElement( "div" ) );
182
183	// access offsetHeight before setting the style to prevent a layout bug
184	// in IE 9 which causes the element to continue to take up space even
185	// after it is removed from the DOM (#8026)
186	div.offsetHeight;
187
188	$.extend( div.style, {
189		minHeight: "100px",
190		height: "auto",
191		padding: 0,
192		borderWidth: 0
193	});
194
195	$.support.minHeight = div.offsetHeight === 100;
196	$.support.selectstart = "onselectstart" in div;
197
198	// set display to none to avoid a layout bug in IE
199	// http://dev.jquery.com/ticket/4014
200	body.removeChild( div ).style.display = "none";
201});
202
203// support: jQuery <1.8
204if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
205	$.each( [ "Width", "Height" ], function( i, name ) {
206		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
207			type = name.toLowerCase(),
208			orig = {
209				innerWidth: $.fn.innerWidth,
210				innerHeight: $.fn.innerHeight,
211				outerWidth: $.fn.outerWidth,
212				outerHeight: $.fn.outerHeight
213			};
214
215		function reduce( elem, size, border, margin ) {
216			$.each( side, function() {
217				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
218				if ( border ) {
219					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
220				}
221				if ( margin ) {
222					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
223				}
224			});
225			return size;
226		}
227
228		$.fn[ "inner" + name ] = function( size ) {
229			if ( size === undefined ) {
230				return orig[ "inner" + name ].call( this );
231			}
232
233			return this.each(function() {
234				$( this ).css( type, reduce( this, size ) + "px" );
235			});
236		};
237
238		$.fn[ "outer" + name] = function( size, margin ) {
239			if ( typeof size !== "number" ) {
240				return orig[ "outer" + name ].call( this, size );
241			}
242
243			return this.each(function() {
244				$( this).css( type, reduce( this, size, true, margin ) + "px" );
245			});
246		};
247	});
248}
249
250// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
251if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
252	$.fn.removeData = (function( removeData ) {
253		return function( key ) {
254			if ( arguments.length ) {
255				return removeData.call( this, $.camelCase( key ) );
256			} else {
257				return removeData.call( this );
258			}
259		};
260	})( $.fn.removeData );
261}
262
263
264
265
266
267// deprecated
268
269(function() {
270	var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
271	$.ui.ie = uaMatch.length ? true : false;
272	$.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
273})();
274
275$.fn.extend({
276	disableSelection: function() {
277		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
278			".ui-disableSelection", function( event ) {
279				event.preventDefault();
280			});
281	},
282
283	enableSelection: function() {
284		return this.unbind( ".ui-disableSelection" );
285	}
286});
287
288$.extend( $.ui, {
289	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
290	plugin: {
291		add: function( module, option, set ) {
292			var i,
293				proto = $.ui[ module ].prototype;
294			for ( i in set ) {
295				proto.plugins[ i ] = proto.plugins[ i ] || [];
296				proto.plugins[ i ].push( [ option, set[ i ] ] );
297			}
298		},
299		call: function( instance, name, args ) {
300			var i,
301				set = instance.plugins[ name ];
302			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
303				return;
304			}
305
306			for ( i = 0; i < set.length; i++ ) {
307				if ( instance.options[ set[ i ][ 0 ] ] ) {
308					set[ i ][ 1 ].apply( instance.element, args );
309				}
310			}
311		}
312	},
313
314	contains: $.contains,
315
316	// only used by resizable
317	hasScroll: function( el, a ) {
318
319		//If overflow is hidden, the element might have extra content, but the user wants to hide it
320		if ( $( el ).css( "overflow" ) === "hidden") {
321			return false;
322		}
323
324		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
325			has = false;
326
327		if ( el[ scroll ] > 0 ) {
328			return true;
329		}
330
331		// TODO: determine which cases actually cause this to happen
332		// if the element doesn't have the scroll set, see if it's possible to
333		// set the scroll
334		el[ scroll ] = 1;
335		has = ( el[ scroll ] > 0 );
336		el[ scroll ] = 0;
337		return has;
338	},
339
340	// these are odd functions, fix the API or move into individual plugins
341	isOverAxis: function( x, reference, size ) {
342		//Determines when x coordinate is over "b" element axis
343		return ( x > reference ) && ( x < ( reference + size ) );
344	},
345	isOver: function( y, x, top, left, height, width ) {
346		//Determines when x, y coordinates is over "b" element
347		return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
348	}
349});
350
351})( jQuery );
352(function( $, undefined ) {
353
354var uuid = 0,
355	slice = Array.prototype.slice,
356	_cleanData = $.cleanData;
357$.cleanData = function( elems ) {
358	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
359		try {
360			$( elem ).triggerHandler( "remove" );
361		// http://bugs.jquery.com/ticket/8235
362		} catch( e ) {}
363	}
364	_cleanData( elems );
365};
366
367$.widget = function( name, base, prototype ) {
368	var fullName, existingConstructor, constructor, basePrototype,
369		namespace = name.split( "." )[ 0 ];
370
371	name = name.split( "." )[ 1 ];
372	fullName = namespace + "-" + name;
373
374	if ( !prototype ) {
375		prototype = base;
376		base = $.Widget;
377	}
378
379	// create selector for plugin
380	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
381		return !!$.data( elem, fullName );
382	};
383
384	$[ namespace ] = $[ namespace ] || {};
385	existingConstructor = $[ namespace ][ name ];
386	constructor = $[ namespace ][ name ] = function( options, element ) {
387		// allow instantiation without "new" keyword
388		if ( !this._createWidget ) {
389			return new constructor( options, element );
390		}
391
392		// allow instantiation without initializing for simple inheritance
393		// must use "new" keyword (the code above always passes args)
394		if ( arguments.length ) {
395			this._createWidget( options, element );
396		}
397	};
398	// extend with the existing constructor to carry over any static properties
399	$.extend( constructor, existingConstructor, {
400		version: prototype.version,
401		// copy the object used to create the prototype in case we need to
402		// redefine the widget later
403		_proto: $.extend( {}, prototype ),
404		// track widgets that inherit from this widget in case this widget is
405		// redefined after a widget inherits from it
406		_childConstructors: []
407	});
408
409	basePrototype = new base();
410	// we need to make the options hash a property directly on the new instance
411	// otherwise we'll modify the options hash on the prototype that we're
412	// inheriting from
413	basePrototype.options = $.widget.extend( {}, basePrototype.options );
414	$.each( prototype, function( prop, value ) {
415		if ( $.isFunction( value ) ) {
416			prototype[ prop ] = (function() {
417				var _super = function() {
418						return base.prototype[ prop ].apply( this, arguments );
419					},
420					_superApply = function( args ) {
421						return base.prototype[ prop ].apply( this, args );
422					};
423				return function() {
424					var __super = this._super,
425						__superApply = this._superApply,
426						returnValue;
427
428					this._super = _super;
429					this._superApply = _superApply;
430
vendor: 12,147 bytes, lines 431-848
431					returnValue = value.apply( this, arguments );
432
433					this._super = __super;
434					this._superApply = __superApply;
435
436					return returnValue;
437				};
438			})();
439		}
440	});
441	constructor.prototype = $.widget.extend( basePrototype, {
442		// TODO: remove support for widgetEventPrefix
443		// always use the name + a colon as the prefix, e.g., draggable:start
444		// don't prefix for widgets that aren't DOM-based
445		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
446	}, prototype, {
447		constructor: constructor,
448		namespace: namespace,
449		widgetName: name,
450		// TODO remove widgetBaseClass, see #8155
451		widgetBaseClass: fullName,
452		widgetFullName: fullName
453	});
454
455	// If this widget is being redefined then we need to find all widgets that
456	// are inheriting from it and redefine all of them so that they inherit from
457	// the new version of this widget. We're essentially trying to replace one
458	// level in the prototype chain.
459	if ( existingConstructor ) {
460		$.each( existingConstructor._childConstructors, function( i, child ) {
461			var childPrototype = child.prototype;
462
463			// redefine the child widget using the same prototype that was
464			// originally used, but inherit from the new version of the base
465			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
466		});
467		// remove the list of existing child constructors from the old constructor
468		// so the old child constructors can be garbage collected
469		delete existingConstructor._childConstructors;
470	} else {
471		base._childConstructors.push( constructor );
472	}
473
474	$.widget.bridge( name, constructor );
475};
476
477$.widget.extend = function( target ) {
478	var input = slice.call( arguments, 1 ),
479		inputIndex = 0,
480		inputLength = input.length,
481		key,
482		value;
483	for ( ; inputIndex < inputLength; inputIndex++ ) {
484		for ( key in input[ inputIndex ] ) {
485			value = input[ inputIndex ][ key ];
486			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
487				// Clone objects
488				if ( $.isPlainObject( value ) ) {
489					target[ key ] = $.isPlainObject( target[ key ] ) ?
490						$.widget.extend( {}, target[ key ], value ) :
491						// Don't extend strings, arrays, etc. with objects
492						$.widget.extend( {}, value );
493				// Copy everything else by reference
494				} else {
495					target[ key ] = value;
496				}
497			}
498		}
499	}
500	return target;
501};
502
503$.widget.bridge = function( name, object ) {
504	var fullName = object.prototype.widgetFullName || name;
505	$.fn[ name ] = function( options ) {
506		var isMethodCall = typeof options === "string",
507			args = slice.call( arguments, 1 ),
508			returnValue = this;
509
510		// allow multiple hashes to be passed on init
511		options = !isMethodCall && args.length ?
512			$.widget.extend.apply( null, [ options ].concat(args) ) :
513			options;
514
515		if ( isMethodCall ) {
516			this.each(function() {
517				var methodValue,
518					instance = $.data( this, fullName );
519				if ( !instance ) {
520					return $.error( "cannot call methods on " + name + " prior to initialization; " +
521						"attempted to call method '" + options + "'" );
522				}
523				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
524					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
525				}
526				methodValue = instance[ options ].apply( instance, args );
527				if ( methodValue !== instance && methodValue !== undefined ) {
528					returnValue = methodValue && methodValue.jquery ?
529						returnValue.pushStack( methodValue.get() ) :
530						methodValue;
531					return false;
532				}
533			});
534		} else {
535			this.each(function() {
536				var instance = $.data( this, fullName );
537				if ( instance ) {
538					instance.option( options || {} )._init();
539				} else {
540					$.data( this, fullName, new object( options, this ) );
541				}
542			});
543		}
544
545		return returnValue;
546	};
547};
548
549$.Widget = function( /* options, element */ ) {};
550$.Widget._childConstructors = [];
551
552$.Widget.prototype = {
553	widgetName: "widget",
554	widgetEventPrefix: "",
555	defaultElement: "<div>",
556	options: {
557		disabled: false,
558
559		// callbacks
560		create: null
561	},
562	_createWidget: function( options, element ) {
563		element = $( element || this.defaultElement || this )[ 0 ];
564		this.element = $( element );
565		this.uuid = uuid++;
566		this.eventNamespace = "." + this.widgetName + this.uuid;
567		this.options = $.widget.extend( {},
568			this.options,
569			this._getCreateOptions(),
570			options );
571
572		this.bindings = $();
573		this.hoverable = $();
574		this.focusable = $();
575
576		if ( element !== this ) {
577			// 1.9 BC for #7810
578			// TODO remove dual storage
579			$.data( element, this.widgetName, this );
580			$.data( element, this.widgetFullName, this );
581			this._on( true, this.element, {
582				remove: function( event ) {
583					if ( event.target === element ) {
584						this.destroy();
585					}
586				}
587			});
588			this.document = $( element.style ?
589				// element within the document
590				element.ownerDocument :
591				// element is window or document
592				element.document || element );
593			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
594		}
595
596		this._create();
597		this._trigger( "create", null, this._getCreateEventData() );
598		this._init();
599	},
600	_getCreateOptions: $.noop,
601	_getCreateEventData: $.noop,
602	_create: $.noop,
603	_init: $.noop,
604
605	destroy: function() {
606		this._destroy();
607		// we can probably remove the unbind calls in 2.0
608		// all event bindings should go through this._on()
609		this.element
610			.unbind( this.eventNamespace )
611			// 1.9 BC for #7810
612			// TODO remove dual storage
613			.removeData( this.widgetName )
614			.removeData( this.widgetFullName )
615			// support: jquery <1.6.3
616			// http://bugs.jquery.com/ticket/9413
617			.removeData( $.camelCase( this.widgetFullName ) );
618		this.widget()
619			.unbind( this.eventNamespace )
620			.removeAttr( "aria-disabled" )
621			.removeClass(
622				this.widgetFullName + "-disabled " +
623				"ui-state-disabled" );
624
625		// clean up events and states
626		this.bindings.unbind( this.eventNamespace );
627		this.hoverable.removeClass( "ui-state-hover" );
628		this.focusable.removeClass( "ui-state-focus" );
629	},
630	_destroy: $.noop,
631
632	widget: function() {
633		return this.element;
634	},
635
636	option: function( key, value ) {
637		var options = key,
638			parts,
639			curOption,
640			i;
641
642		if ( arguments.length === 0 ) {
643			// don't return a reference to the internal hash
644			return $.widget.extend( {}, this.options );
645		}
646
647		if ( typeof key === "string" ) {
648			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
649			options = {};
650			parts = key.split( "." );
651			key = parts.shift();
652			if ( parts.length ) {
653				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
654				for ( i = 0; i < parts.length - 1; i++ ) {
655					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
656					curOption = curOption[ parts[ i ] ];
657				}
658				key = parts.pop();
659				if ( value === undefined ) {
660					return curOption[ key ] === undefined ? null : curOption[ key ];
661				}
662				curOption[ key ] = value;
663			} else {
664				if ( value === undefined ) {
665					return this.options[ key ] === undefined ? null : this.options[ key ];
666				}
667				options[ key ] = value;
668			}
669		}
670
671		this._setOptions( options );
672
673		return this;
674	},
675	_setOptions: function( options ) {
676		var key;
677
678		for ( key in options ) {
679			this._setOption( key, options[ key ] );
680		}
681
682		return this;
683	},
684	_setOption: function( key, value ) {
685		this.options[ key ] = value;
686
687		if ( key === "disabled" ) {
688			this.widget()
689				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
690				.attr( "aria-disabled", value );
691			this.hoverable.removeClass( "ui-state-hover" );
692			this.focusable.removeClass( "ui-state-focus" );
693		}
694
695		return this;
696	},
697
698	enable: function() {
699		return this._setOption( "disabled", false );
700	},
701	disable: function() {
702		return this._setOption( "disabled", true );
703	},
704
705	_on: function( suppressDisabledCheck, element, handlers ) {
706		var delegateElement,
707			instance = this;
708
709		// no suppressDisabledCheck flag, shuffle arguments
710		if ( typeof suppressDisabledCheck !== "boolean" ) {
711			handlers = element;
712			element = suppressDisabledCheck;
713			suppressDisabledCheck = false;
714		}
715
716		// no element argument, shuffle and use this.element
717		if ( !handlers ) {
718			handlers = element;
719			element = this.element;
720			delegateElement = this.widget();
721		} else {
722			// accept selectors, DOM elements
723			element = delegateElement = $( element );
724			this.bindings = this.bindings.add( element );
725		}
726
727		$.each( handlers, function( event, handler ) {
728			function handlerProxy() {
729				// allow widgets to customize the disabled handling
730				// - disabled as an array instead of boolean
731				// - disabled class as method for disabling individual parts
732				if ( !suppressDisabledCheck &&
733						( instance.options.disabled === true ||
734							$( this ).hasClass( "ui-state-disabled" ) ) ) {
735					return;
736				}
737				return ( typeof handler === "string" ? instance[ handler ] : handler )
738					.apply( instance, arguments );
739			}
740
741			// copy the guid so direct unbinding works
742			if ( typeof handler !== "string" ) {
743				handlerProxy.guid = handler.guid =
744					handler.guid || handlerProxy.guid || $.guid++;
745			}
746
747			var match = event.match( /^(\w+)\s*(.*)$/ ),
748				eventName = match[1] + instance.eventNamespace,
749				selector = match[2];
750			if ( selector ) {
751				delegateElement.delegate( selector, eventName, handlerProxy );
752			} else {
753				element.bind( eventName, handlerProxy );
754			}
755		});
756	},
757
758	_off: function( element, eventName ) {
759		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
760		element.unbind( eventName ).undelegate( eventName );
761	},
762
763	_delay: function( handler, delay ) {
764		function handlerProxy() {
765			return ( typeof handler === "string" ? instance[ handler ] : handler )
766				.apply( instance, arguments );
767		}
768		var instance = this;
769		return setTimeout( handlerProxy, delay || 0 );
770	},
771
772	_hoverable: function( element ) {
773		this.hoverable = this.hoverable.add( element );
774		this._on( element, {
775			mouseenter: function( event ) {
776				$( event.currentTarget ).addClass( "ui-state-hover" );
777			},
778			mouseleave: function( event ) {
779				$( event.currentTarget ).removeClass( "ui-state-hover" );
780			}
781		});
782	},
783
784	_focusable: function( element ) {
785		this.focusable = this.focusable.add( element );
786		this._on( element, {
787			focusin: function( event ) {
788				$( event.currentTarget ).addClass( "ui-state-focus" );
789			},
790			focusout: function( event ) {
791				$( event.currentTarget ).removeClass( "ui-state-focus" );
792			}
793		});
794	},
795
796	_trigger: function( type, event, data ) {
797		var prop, orig,
798			callback = this.options[ type ];
799
800		data = data || {};
801		event = $.Event( event );
802		event.type = ( type === this.widgetEventPrefix ?
803			type :
804			this.widgetEventPrefix + type ).toLowerCase();
805		// the original event may come from any element
806		// so we need to reset the target on the new event
807		event.target = this.element[ 0 ];
808
809		// copy original event properties over to the new event
810		orig = event.originalEvent;
811		if ( orig ) {
812			for ( prop in orig ) {
813				if ( !( prop in event ) ) {
814					event[ prop ] = orig[ prop ];
815				}
816			}
817		}
818
819		this.element.trigger( event, data );
820		return !( $.isFunction( callback ) &&
821			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
822			event.isDefaultPrevented() );
823	}
824};
825
826$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
827	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
828		if ( typeof options === "string" ) {
829			options = { effect: options };
830		}
831		var hasOptions,
832			effectName = !options ?
833				method :
834				options === true || typeof options === "number" ?
835					defaultEffect :
836					options.effect || defaultEffect;
837		options = options || {};
838		if ( typeof options === "number" ) {
839			options = { duration: options };
840		}
841		hasOptions = !$.isEmptyObject( options );
842		options.complete = callback;
843		if ( options.delay ) {
844			element.delay( options.delay );
845		}
846		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
847			element[ method ]( options );
848		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,170 bytes, lines 849-1003
849			element[ effectName ]( options.duration, options.easing, callback );
850		} else {
851			element.queue(function( next ) {
852				$( this )[ method ]();
853				if ( callback ) {
854					callback.call( element[ 0 ] );
855				}
856				next();
857			});
858		}
859	};
860});
861
862// DEPRECATED
863if ( $.uiBackCompat !== false ) {
864	$.Widget.prototype._getCreateOptions = function() {
865		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
866	};
867}
868
869})( jQuery );
870(function( $, undefined ) {
871
872var mouseHandled = false;
873$( document ).mouseup( function( e ) {
874	mouseHandled = false;
875});
876
877$.widget("ui.mouse", {
878	version: "1.9.2",
879	options: {
880		cancel: 'input,textarea,button,select,option',
881		distance: 1,
882		delay: 0
883	},
884	_mouseInit: function() {
885		var that = this;
886
887		this.element
888			.bind('mousedown.'+this.widgetName, function(event) {
889				return that._mouseDown(event);
890			})
891			.bind('click.'+this.widgetName, function(event) {
892				if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
893					$.removeData(event.target, that.widgetName + '.preventClickEvent');
894					event.stopImmediatePropagation();
895					return false;
896				}
897			});
898
899		this.started = false;
900	},
901
902	// TODO: make sure destroying one instance of mouse doesn't mess with
903	// other instances of mouse
904	_mouseDestroy: function() {
905		this.element.unbind('.'+this.widgetName);
906		if ( this._mouseMoveDelegate ) {
907			$(document)
908				.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
909				.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
910		}
911	},
912
913	_mouseDown: function(event) {
914		// don't let more than one widget handle mouseStart
915		if( mouseHandled ) { return; }
916
917		// we may have missed mouseup (out of window)
918		(this._mouseStarted && this._mouseUp(event));
919
920		this._mouseDownEvent = event;
921
922		var that = this,
923			btnIsLeft = (event.which === 1),
924			// event.target.nodeName works around a bug in IE 8 with
925			// disabled inputs (#7620)
926			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
927		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
928			return true;
929		}
930
931		this.mouseDelayMet = !this.options.delay;
932		if (!this.mouseDelayMet) {
933			this._mouseDelayTimer = setTimeout(function() {
934				that.mouseDelayMet = true;
935			}, this.options.delay);
936		}
937
938		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
939			this._mouseStarted = (this._mouseStart(event) !== false);
940			if (!this._mouseStarted) {
941				event.preventDefault();
942				return true;
943			}
944		}
945
946		// Click event may never have fired (Gecko & Opera)
947		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
948			$.removeData(event.target, this.widgetName + '.preventClickEvent');
949		}
950
951		// these delegates are required to keep context
952		this._mouseMoveDelegate = function(event) {
953			return that._mouseMove(event);
954		};
955		this._mouseUpDelegate = function(event) {
956			return that._mouseUp(event);
957		};
958		$(document)
959			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
960			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
961
962		event.preventDefault();
963
964		mouseHandled = true;
965		return true;
966	},
967
968	_mouseMove: function(event) {
969		// IE mouseup check - mouseup happened when mouse was out of window
970		if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
971			return this._mouseUp(event);
972		}
973
974		if (this._mouseStarted) {
975			this._mouseDrag(event);
976			return event.preventDefault();
977		}
978
979		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
980			this._mouseStarted =
981				(this._mouseStart(this._mouseDownEvent, event) !== false);
982			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
983		}
984
985		return !this._mouseStarted;
986	},
987
988	_mouseUp: function(event) {
989		$(document)
990			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
991			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
992
993		if (this._mouseStarted) {
994			this._mouseStarted = false;
995
996			if (event.target === this._mouseDownEvent.target) {
997				$.data(event.target, this.widgetName + '.preventClickEvent', true);
998			}
999
1000			this._mouseStop(event);
1001		}
1002
1003		return false;
1004	},
1005
1006	_mouseDistanceMet: function(event) {
1007		return (Math.max(
1008				Math.abs(this._mouseDownEvent.pageX - event.pageX),
1009				Math.abs(this._mouseDownEvent.pageY - event.pageY)
1010			) >= this.options.distance
1011		);
1012	},
1013
1014	_mouseDelayMet: function(event) {
1015		return this.mouseDelayMet;
1016	},
1017
1018	// These are placeholder methods, to be overriden by extending plugin
1019	_mouseStart: function(event) {},
1020	_mouseDrag: function(event) {},
1021	_mouseStop: function(event) {},
1022	_mouseCapture: function(event) { return true; }
1023});
1024
1025})(jQuery);
1026(function( $, undefined ) {
1027
1028$.ui = $.ui || {};
1029
1030var cachedScrollbarWidth,
1031	max = Math.max,
1032	abs = Math.abs,
1033	round = Math.round,
1034	rhorizontal = /left|center|right/,
1035	rvertical = /top|center|bottom/,
1036	roffset = /[\+\-]\d+%?/,
1037	rposition = /^\w+/,
1038	rpercent = /%$/,
1039	_position = $.fn.position;
1040
1041function getOffsets( offsets, width, height ) {
1042	return [
1043		parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1044		parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1045	];
1046}
1047function parseCss( element, property ) {
1048	return parseInt( $.css( element, property ), 10 ) || 0;
1049}
1050
1051$.position = {
1052	scrollbarWidth: function() {
1053		if ( cachedScrollbarWidth !== undefined ) {
1054			return cachedScrollbarWidth;
1055		}
1056		var w1, w2,
1057			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1058			innerDiv = div.children()[0];
1059
1060		$( "body" ).append( div );
1061		w1 = innerDiv.offsetWidth;
1062		div.css( "overflow", "scroll" );
1063
1064		w2 = innerDiv.offsetWidth;
1065
1066		if ( w1 === w2 ) {
1067			w2 = div[0].clientWidth;
1068		}
1069
1070		div.remove();
1071
1072		return (cachedScrollbarWidth = w1 - w2);
1073	},
1074	getScrollInfo: function( within ) {
1075		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
1076			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
1077			hasOverflowX = overflowX === "scroll" ||
1078				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1079			hasOverflowY = overflowY === "scroll" ||
1080				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1081		return {
1082			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
1083			height: hasOverflowY ? $.position.scrollbarWidth() : 0
1084		};
1085	},
1086	getWithinInfo: function( element ) {
1087		var withinElement = $( element || window ),
1088			isWindow = $.isWindow( withinElement[0] );
1089		return {
1090			element: withinElement,
1091			isWindow: isWindow,
1092			offset: withinElement.offset() || { left: 0, top: 0 },
1093			scrollLeft: withinElement.scrollLeft(),
1094			scrollTop: withinElement.scrollTop(),
1095			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1096			height: isWindow ? withinElement.height() : withinElement.outerHeight()
1097		};
1098	}
1099};
1100
1101$.fn.position = function( options ) {
1102	if ( !options || !options.of ) {
1103		return _position.apply( this, arguments );
1104	}
1105
1106	// make a copy, we don't want to modify arguments
1107	options = $.extend( {}, options );
1108
1109	var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
1110		target = $( options.of ),
1111		within = $.position.getWithinInfo( options.within ),
1112		scrollInfo = $.position.getScrollInfo( within ),
1113		targetElem = target[0],
1114		collision = ( options.collision || "flip" ).split( " " ),
1115		offsets = {};
1116
1117	if ( targetElem.nodeType === 9 ) {
1118		targetWidth = target.width();
1119		targetHeight = target.height();
1120		targetOffset = { top: 0, left: 0 };
1121	} else if ( $.isWindow( targetElem ) ) {
1122		targetWidth = target.width();
1123		targetHeight = target.height();
1124		targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
1125	} else if ( targetElem.preventDefault ) {
1126		// force left top to allow flipping
1127		options.at = "left top";
1128		targetWidth = targetHeight = 0;
1129		targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
1130	} else {
1131		targetWidth = target.outerWidth();
1132		targetHeight = target.outerHeight();
1133		targetOffset = target.offset();
1134	}
1135	// clone to reuse original targetOffset later
1136	basePosition = $.extend( {}, targetOffset );
1137
1138	// force my and at to have valid horizontal and vertical positions
1139	// if a value is missing or invalid, it will be converted to center
1140	$.each( [ "my", "at" ], function() {
1141		var pos = ( options[ this ] || "" ).split( " " ),
1142			horizontalOffset,
1143			verticalOffset;
1144
1145		if ( pos.length === 1) {
1146			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 12,659 bytes, lines 1147-1544
1147				pos.concat( [ "center" ] ) :
1148				rvertical.test( pos[ 0 ] ) ?
1149					[ "center" ].concat( pos ) :
1150					[ "center", "center" ];
1151		}
1152		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1153		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1154
1155		// calculate offsets
1156		horizontalOffset = roffset.exec( pos[ 0 ] );
1157		verticalOffset = roffset.exec( pos[ 1 ] );
1158		offsets[ this ] = [
1159			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1160			verticalOffset ? verticalOffset[ 0 ] : 0
1161		];
1162
1163		// reduce to just the positions without the offsets
1164		options[ this ] = [
1165			rposition.exec( pos[ 0 ] )[ 0 ],
1166			rposition.exec( pos[ 1 ] )[ 0 ]
1167		];
1168	});
1169
1170	// normalize collision option
1171	if ( collision.length === 1 ) {
1172		collision[ 1 ] = collision[ 0 ];
1173	}
1174
1175	if ( options.at[ 0 ] === "right" ) {
1176		basePosition.left += targetWidth;
1177	} else if ( options.at[ 0 ] === "center" ) {
1178		basePosition.left += targetWidth / 2;
1179	}
1180
1181	if ( options.at[ 1 ] === "bottom" ) {
1182		basePosition.top += targetHeight;
1183	} else if ( options.at[ 1 ] === "center" ) {
1184		basePosition.top += targetHeight / 2;
1185	}
1186
1187	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1188	basePosition.left += atOffset[ 0 ];
1189	basePosition.top += atOffset[ 1 ];
1190
1191	return this.each(function() {
1192		var collisionPosition, using,
1193			elem = $( this ),
1194			elemWidth = elem.outerWidth(),
1195			elemHeight = elem.outerHeight(),
1196			marginLeft = parseCss( this, "marginLeft" ),
1197			marginTop = parseCss( this, "marginTop" ),
1198			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1199			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1200			position = $.extend( {}, basePosition ),
1201			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1202
1203		if ( options.my[ 0 ] === "right" ) {
1204			position.left -= elemWidth;
1205		} else if ( options.my[ 0 ] === "center" ) {
1206			position.left -= elemWidth / 2;
1207		}
1208
1209		if ( options.my[ 1 ] === "bottom" ) {
1210			position.top -= elemHeight;
1211		} else if ( options.my[ 1 ] === "center" ) {
1212			position.top -= elemHeight / 2;
1213		}
1214
1215		position.left += myOffset[ 0 ];
1216		position.top += myOffset[ 1 ];
1217
1218		// if the browser doesn't support fractions, then round for consistent results
1219		if ( !$.support.offsetFractions ) {
1220			position.left = round( position.left );
1221			position.top = round( position.top );
1222		}
1223
1224		collisionPosition = {
1225			marginLeft: marginLeft,
1226			marginTop: marginTop
1227		};
1228
1229		$.each( [ "left", "top" ], function( i, dir ) {
1230			if ( $.ui.position[ collision[ i ] ] ) {
1231				$.ui.position[ collision[ i ] ][ dir ]( position, {
1232					targetWidth: targetWidth,
1233					targetHeight: targetHeight,
1234					elemWidth: elemWidth,
1235					elemHeight: elemHeight,
1236					collisionPosition: collisionPosition,
1237					collisionWidth: collisionWidth,
1238					collisionHeight: collisionHeight,
1239					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1240					my: options.my,
1241					at: options.at,
1242					within: within,
1243					elem : elem
1244				});
1245			}
1246		});
1247
1248		if ( $.fn.bgiframe ) {
1249			elem.bgiframe();
1250		}
1251
1252		if ( options.using ) {
1253			// adds feedback as second argument to using callback, if present
1254			using = function( props ) {
1255				var left = targetOffset.left - position.left,
1256					right = left + targetWidth - elemWidth,
1257					top = targetOffset.top - position.top,
1258					bottom = top + targetHeight - elemHeight,
1259					feedback = {
1260						target: {
1261							element: target,
1262							left: targetOffset.left,
1263							top: targetOffset.top,
1264							width: targetWidth,
1265							height: targetHeight
1266						},
1267						element: {
1268							element: elem,
1269							left: position.left,
1270							top: position.top,
1271							width: elemWidth,
1272							height: elemHeight
1273						},
1274						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1275						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1276					};
1277				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1278					feedback.horizontal = "center";
1279				}
1280				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1281					feedback.vertical = "middle";
1282				}
1283				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1284					feedback.important = "horizontal";
1285				} else {
1286					feedback.important = "vertical";
1287				}
1288				options.using.call( this, props, feedback );
1289			};
1290		}
1291
1292		elem.offset( $.extend( position, { using: using } ) );
1293	});
1294};
1295
1296$.ui.position = {
1297	fit: {
1298		left: function( position, data ) {
1299			var within = data.within,
1300				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1301				outerWidth = within.width,
1302				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1303				overLeft = withinOffset - collisionPosLeft,
1304				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1305				newOverRight;
1306
1307			// element is wider than within
1308			if ( data.collisionWidth > outerWidth ) {
1309				// element is initially over the left side of within
1310				if ( overLeft > 0 && overRight <= 0 ) {
1311					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1312					position.left += overLeft - newOverRight;
1313				// element is initially over right side of within
1314				} else if ( overRight > 0 && overLeft <= 0 ) {
1315					position.left = withinOffset;
1316				// element is initially over both left and right sides of within
1317				} else {
1318					if ( overLeft > overRight ) {
1319						position.left = withinOffset + outerWidth - data.collisionWidth;
1320					} else {
1321						position.left = withinOffset;
1322					}
1323				}
1324			// too far left -> align with left edge
1325			} else if ( overLeft > 0 ) {
1326				position.left += overLeft;
1327			// too far right -> align with right edge
1328			} else if ( overRight > 0 ) {
1329				position.left -= overRight;
1330			// adjust based on position and margin
1331			} else {
1332				position.left = max( position.left - collisionPosLeft, position.left );
1333			}
1334		},
1335		top: function( position, data ) {
1336			var within = data.within,
1337				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1338				outerHeight = data.within.height,
1339				collisionPosTop = position.top - data.collisionPosition.marginTop,
1340				overTop = withinOffset - collisionPosTop,
1341				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1342				newOverBottom;
1343
1344			// element is taller than within
1345			if ( data.collisionHeight > outerHeight ) {
1346				// element is initially over the top of within
1347				if ( overTop > 0 && overBottom <= 0 ) {
1348					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1349					position.top += overTop - newOverBottom;
1350				// element is initially over bottom of within
1351				} else if ( overBottom > 0 && overTop <= 0 ) {
1352					position.top = withinOffset;
1353				// element is initially over both top and bottom of within
1354				} else {
1355					if ( overTop > overBottom ) {
1356						position.top = withinOffset + outerHeight - data.collisionHeight;
1357					} else {
1358						position.top = withinOffset;
1359					}
1360				}
1361			// too far up -> align with top
1362			} else if ( overTop > 0 ) {
1363				position.top += overTop;
1364			// too far down -> align with bottom edge
1365			} else if ( overBottom > 0 ) {
1366				position.top -= overBottom;
1367			// adjust based on position and margin
1368			} else {
1369				position.top = max( position.top - collisionPosTop, position.top );
1370			}
1371		}
1372	},
1373	flip: {
1374		left: function( position, data ) {
1375			var within = data.within,
1376				withinOffset = within.offset.left + within.scrollLeft,
1377				outerWidth = within.width,
1378				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1379				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1380				overLeft = collisionPosLeft - offsetLeft,
1381				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1382				myOffset = data.my[ 0 ] === "left" ?
1383					-data.elemWidth :
1384					data.my[ 0 ] === "right" ?
1385						data.elemWidth :
1386						0,
1387				atOffset = data.at[ 0 ] === "left" ?
1388					data.targetWidth :
1389					data.at[ 0 ] === "right" ?
1390						-data.targetWidth :
1391						0,
1392				offset = -2 * data.offset[ 0 ],
1393				newOverRight,
1394				newOverLeft;
1395
1396			if ( overLeft < 0 ) {
1397				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1398				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1399					position.left += myOffset + atOffset + offset;
1400				}
1401			}
1402			else if ( overRight > 0 ) {
1403				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1404				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1405					position.left += myOffset + atOffset + offset;
1406				}
1407			}
1408		},
1409		top: function( position, data ) {
1410			var within = data.within,
1411				withinOffset = within.offset.top + within.scrollTop,
1412				outerHeight = within.height,
1413				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1414				collisionPosTop = position.top - data.collisionPosition.marginTop,
1415				overTop = collisionPosTop - offsetTop,
1416				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1417				top = data.my[ 1 ] === "top",
1418				myOffset = top ?
1419					-data.elemHeight :
1420					data.my[ 1 ] === "bottom" ?
1421						data.elemHeight :
1422						0,
1423				atOffset = data.at[ 1 ] === "top" ?
1424					data.targetHeight :
1425					data.at[ 1 ] === "bottom" ?
1426						-data.targetHeight :
1427						0,
1428				offset = -2 * data.offset[ 1 ],
1429				newOverTop,
1430				newOverBottom;
1431			if ( overTop < 0 ) {
1432				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1433				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1434					position.top += myOffset + atOffset + offset;
1435				}
1436			}
1437			else if ( overBottom > 0 ) {
1438				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1439				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1440					position.top += myOffset + atOffset + offset;
1441				}
1442			}
1443		}
1444	},
1445	flipfit: {
1446		left: function() {
1447			$.ui.position.flip.left.apply( this, arguments );
1448			$.ui.position.fit.left.apply( this, arguments );
1449		},
1450		top: function() {
1451			$.ui.position.flip.top.apply( this, arguments );
1452			$.ui.position.fit.top.apply( this, arguments );
1453		}
1454	}
1455};
1456
1457// fraction support test
1458(function () {
1459	var testElement, testElementParent, testElementStyle, offsetLeft, i,
1460		body = document.getElementsByTagName( "body" )[ 0 ],
1461		div = document.createElement( "div" );
1462
1463	//Create a "fake body" for testing based on method used in jQuery.support
1464	testElement = document.createElement( body ? "div" : "body" );
1465	testElementStyle = {
1466		visibility: "hidden",
1467		width: 0,
1468		height: 0,
1469		border: 0,
1470		margin: 0,
1471		background: "none"
1472	};
1473	if ( body ) {
1474		$.extend( testElementStyle, {
1475			position: "absolute",
1476			left: "-1000px",
1477			top: "-1000px"
1478		});
1479	}
1480	for ( i in testElementStyle ) {
1481		testElement.style[ i ] = testElementStyle[ i ];
1482	}
1483	testElement.appendChild( div );
1484	testElementParent = body || document.documentElement;
1485	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1486
1487	div.style.cssText = "position: absolute; left: 10.7432222px;";
1488
1489	offsetLeft = $( div ).offset().left;
1490	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1491
1492	testElement.innerHTML = "";
1493	testElementParent.removeChild( testElement );
1494})();
1495
1496// DEPRECATED
1497if ( $.uiBackCompat !== false ) {
1498	// offset option
1499	(function( $ ) {
1500		var _position = $.fn.position;
1501		$.fn.position = function( options ) {
1502			if ( !options || !options.offset ) {
1503				return _position.call( this, options );
1504			}
1505			var offset = options.offset.split( " " ),
1506				at = options.at.split( " " );
1507			if ( offset.length === 1 ) {
1508				offset[ 1 ] = offset[ 0 ];
1509			}
1510			if ( /^\d/.test( offset[ 0 ] ) ) {
1511				offset[ 0 ] = "+" + offset[ 0 ];
1512			}
1513			if ( /^\d/.test( offset[ 1 ] ) ) {
1514				offset[ 1 ] = "+" + offset[ 1 ];
1515			}
1516			if ( at.length === 1 ) {
1517				if ( /left|center|right/.test( at[ 0 ] ) ) {
1518					at[ 1 ] = "center";
1519				} else {
1520					at[ 1 ] = at[ 0 ];
1521					at[ 0 ] = "center";
1522				}
1523			}
1524			return _position.call( this, $.extend( options, {
1525				at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
1526				offset: undefined
1527			} ) );
1528		};
1529	}( jQuery ) );
1530}
1531
1532}( jQuery ) );
1533(function( $, undefined ) {
1534
1535$.widget("ui.draggable", $.ui.mouse, {
1536	version: "1.9.2",
1537	widgetEventPrefix: "drag",
1538	options: {
1539		addClasses: true,
1540		appendTo: "parent",
1541		axis: false,
1542		connectToSortable: false,
1543		containment: false,
1544		cursor: "auto",
1545		cursorAt: false,
1546		grid: false,
1547		handle: false,
1548		helper: "original",
1549		iframeFix: false,
1550		opacity: false,
1551		refreshPositions: false,
1552		revert: false,
1553		revertDuration: 500,
1554		scope: "default",
1555		scroll: true,
1556		scrollSensitivity: 20,
1557		scrollSpeed: 20,
1558		snap: false,
1559		snapMode: "both",
1560		snapTolerance: 20,
1561		stack: false,
1562		zIndex: false
1563	},
1564	_create: function() {
1565
1566		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1567			this.element[0].style.position = 'relative';
1568
1569		(this.options.addClasses && this.element.addClass("ui-draggable"));
1570		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1571
1572		this._mouseInit();
1573
1574	},
1575
1576	_destroy: function() {
1577		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1578		this._mouseDestroy();
1579	},
1580
1581	_mouseCapture: function(event) {
1582
1583		var o = this.options;
1584
1585		// among others, prevent a drag on a resizable-handle
1586		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1587			return false;
1588
1589		//Quit if we're not on a valid handle
1590		this.handle = this._getHandle(event);
1591		if (!this.handle)
1592			return false;
1593
1594		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1595			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1596			.css({
1597				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1598				position: "absolute", opacity: "0.001", zIndex: 1000
1599			})
1600			.css($(this).offset())
1601			.appendTo("body");
1602		});
1603
1604		return true;
1605
1606	},
1607
1608	_mouseStart: function(event) {
1609
1610		var o = this.options;
1611
1612		//Create and append the visible helper
1613		this.helper = this._createHelper(event);
1614
1615		this.helper.addClass("ui-draggable-dragging");
1616
1617		//Cache the helper size
1618		this._cacheHelperProportions();
1619
1620		//If ddmanager is used for droppables, set the global draggable
1621		if($.ui.ddmanager)
1622			$.ui.ddmanager.current = this;
1623
1624		/*
1625		 * - Position generation -
1626		 * This block generates everything position related - it's the core of draggables.
1627		 */
1628
1629		//Cache the margins of the original element
1630		this._cacheMargins();
1631
1632		//Store the helper's css position
1633		this.cssPosition = this.helper.css("position");
1634		this.scrollParent = this.helper.scrollParent();
1635
1636		//The element's absolute position on the page minus margins
1637		this.offset = this.positionAbs = this.element.offset();
1638		this.offset = {
1639			top: this.offset.top - this.margins.top,
1640			left: this.offset.left - this.margins.left
1641		};
1642
1643		$.extend(this.offset, {
1644			click: { //Where the click happened, relative to the element
1645				left: event.pageX - this.offset.left,
1646				top: event.pageY - this.offset.top
1647			},
1648			parent: this._getParentOffset(),
1649			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1650		});
1651
1652		//Generate the original position
1653		this.originalPosition = this.position = this._generatePosition(event);
1654		this.originalPageX = event.pageX;
1655		this.originalPageY = event.pageY;
1656
1657		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1658		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1659
1660		//Set a containment if given in the options
1661		if(o.containment)
1662			this._setContainment();
1663
1664		//Trigger event + callbacks
1665		if(this._trigger("start", event) === false) {
1666			this._clear();
1667			return false;
1668		}
1669
1670		//Recache the helper size
1671		this._cacheHelperProportions();
1672
1673		//Prepare the droppable offsets
1674		if ($.ui.ddmanager && !o.dropBehaviour)
1675			$.ui.ddmanager.prepareOffsets(this, event);
1676
1677
1678		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1679
1680		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1681		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1682
1683		return true;
1684	},
1685
1686	_mouseDrag: function(event, noPropagation) {
1687
1688		//Compute the helpers position
1689		this.position = this._generatePosition(event);
1690		this.positionAbs = this._convertPositionTo("absolute");
1691
1692		//Call plugins and callbacks and use the resulting position if something is returned
1693		if (!noPropagation) {
1694			var ui = this._uiHash();
1695			if(this._trigger('drag', event, ui) === false) {
1696				this._mouseUp({});
1697				return false;
1698			}
1699			this.position = ui.position;
1700		}
1701
1702		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1703		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1704		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1705
1706		return false;
1707	},
1708
1709	_mouseStop: function(event) {
1710
1711		//If we are using droppables, inform the manager about the drop
1712		var dropped = false;
1713		if ($.ui.ddmanager && !this.options.dropBehaviour)
1714			dropped = $.ui.ddmanager.drop(this, event);
1715
1716		//if a drop comes from outside (a sortable)
1717		if(this.dropped) {
1718			dropped = this.dropped;
1719			this.dropped = false;
1720		}
1721
1722		//if the original element is no longer in the DOM don't bother to continue (see #8269)
1723		var element = this.element[0], elementInDom = false;
1724		while ( element && (element = element.parentNode) ) {
1725			if (element == document ) {
1726				elementInDom = true;
1727			}
1728		}
1729		if ( !elementInDom && this.options.helper === "original" )
1730			return false;
1731
1732		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))) {
1733			var that = this;
1734			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1735				if(that._trigger("stop", event) !== false) {
1736					that._clear();
1737				}
1738			});
1739		} else {
1740			if(this._trigger("stop", event) !== false) {
1741				this._clear();
1742			}
1743		}
1744
1745		return false;
1746	},
1747
1748	_mouseUp: function(event) {
1749		//Remove frame helpers
1750		$("div.ui-draggable-iframeFix").each(function() {
1751			this.parentNode.removeChild(this);
1752		});
1753
1754		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1755		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1756
1757		return $.ui.mouse.prototype._mouseUp.call(this, event);
1758	},
1759
1760	cancel: function() {
1761
1762		if(this.helper.is(".ui-draggable-dragging")) {
1763			this._mouseUp({});
1764		} else {
1765			this._clear();
1766		}
1767
1768		return this;
1769
1770	},
1771
1772	_getHandle: function(event) {
1773
1774		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1775		$(this.options.handle, this.element)
1776			.find("*")
1777			.andSelf()
1778			.each(function() {
1779				if(this == event.target) handle = true;
1780			});
1781
1782		return handle;
1783
1784	},
1785
1786	_createHelper: function(event) {
1787
1788		var o = this.options;
1789		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1790
1791		if(!helper.parents('body').length)
1792			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1793
1794		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1795			helper.css("position", "absolute");
1796
1797		return helper;
1798
1799	},
1800
1801	_adjustOffsetFromHelper: function(obj) {
1802		if (typeof obj == 'string') {
1803			obj = obj.split(' ');
1804		}
1805		if ($.isArray(obj)) {
1806			obj = {left: +obj[0], top: +obj[1] || 0};
1807		}
1808		if ('left' in obj) {
1809			this.offset.click.left = obj.left + this.margins.left;
1810		}
1811		if ('right' in obj) {
1812			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1813		}
1814		if ('top' in obj) {
1815			this.offset.click.top = obj.top + this.margins.top;
1816		}
1817		if ('bottom' in obj) {
1818			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1819		}
1820	},
1821
1822	_getParentOffset: function() {
1823
1824		//Get the offsetParent and cache its position
1825		this.offsetParent = this.helper.offsetParent();
1826		var po = this.offsetParent.offset();
1827
1828		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1829		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1830		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1831		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1832		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1833			po.left += this.scrollParent.scrollLeft();
1834			po.top += this.scrollParent.scrollTop();
1835		}
1836
1837		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1838		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
1839			po = { top: 0, left: 0 };
1840
1841		return {
1842			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),
184210) || 0),
1843			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1844		};
1845
1846	},
1847
1848	_getRelativeOffset: function() {
1849
1850		if(this.cssPosition == "relative") {
1851			var p = this.element.position();
1852			return {
1853				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1854				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1855			};
1856		} else {
1857			return { top: 0, left: 0 };
1858		}
1859
1860	},
1861
1862	_cacheMargins: function() {
1863		this.margins = {
1864			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1865			top: (parseInt(this.element.css("marginTop"),10) || 0),
1866			right: (parseInt(this.element.css("marginRight"),10) || 0),
1867			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1868		};
1869	},
1870
1871	_cacheHelperProportions: function() {
1872		this.helperProportions = {
1873			width: this.helper.outerWidth(),
1874			height: this.helper.outerHeight()
1875		};
1876	},
1877
1878	_setContainment: function() {
1879
1880		var o = this.options;
1881		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1882		if(o.containment == 'document' || o.containment == 'window') this.containment = [
1883			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1884			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1885			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1886			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1887		];
1888
1889		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1890			var c = $(o.containment);
1891			var ce = c[0]; if(!ce) return;
1892			var co = c.offset();
1893			var over = ($(ce).css("overflow") != 'hidden');
1894
1895			this.containment = [
1896				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1897				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1898				(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,
1899				(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
1900			];
1901			this.relative_container = c;
1902
1903		} else if(o.containment.constructor == Array) {
1904			this.containment = o.containment;
1905		}
1906
1907	},
1908
1909	_convertPositionTo: function(d, pos) {
1910
1911		if(!pos) pos = this.position;
1912		var mod = d == "absolute" ? 1 : -1;
1913		var o = this.options, 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);
1914
1915		return {
1916			top: (
1917				pos.top																	// The absolute mouse position
1918				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1919				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
1920				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1921			),
1922			left: (
1923				pos.left																// The absolute mouse position
1924				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1925				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
1926				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1927			)
1928		};
1929
1930	},
1931
1932	_generatePosition: function(event) {
1933
1934		var o = this.options, 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);
1935		var pageX = event.pageX;
1936		var pageY = event.pageY;
1937
1938		/*
1939		 * - Position constraining -
1940		 * Constrain the position to a mix of grid, containment.
1941		 */
1942
1943		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1944			var containment;
1945			if(this.containment) {
1946			if (this.relative_container){
1947				var co = this.relative_container.offset();
1948				containment = [ this.containment[0] + co.left,
1949					this.containment[1] + co.top,
1950					this.containment[2] + co.left,
1951					this.containment[3] + co.top ];
1952			}
1953			else {
1954				containment = this.containment;
1955			}
1956
1957				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1958				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1959				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1960				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1961			}
1962
1963			if(o.grid) {
1964				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1965				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1966				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;
1967
1968				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1969				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;
1970			}
1971
1972		}
1973
1974		return {
1975			top: (
1976				pageY																// The absolute mouse position
1977				- this.offset.click.top													// Click offset (relative to the element)
1978				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
1979				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
1980				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1981			),
1982			left: (
1983				pageX																// The absolute mouse position
1984				- this.offset.click.left												// Click offset (relative to the element)
1985				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
1986				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
1987				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1988			)
1989		};
1990
1991	},
1992
1993	_clear: function() {
1994		this.helper.removeClass("ui-draggable-dragging");
1995		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1996		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
1997		this.helper = null;
1998		this.cancelHelperRemoval = false;
1999	},
2000
2001	// From now on bulk stuff - mainly helpers
2002
2003	_trigger: function(type, event, ui) {
2004		ui = ui || this._uiHash();
2005		$.ui.plugin.call(this, type, [event, ui]);
2006		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
2007		return $.Widget.prototype._trigger.call(this, type, event, ui);
2008	},
2009
2010	plugins: {},
2011
2012	_uiHash: function(event) {
2013		return {
2014			helper: this.helper,
2015			position: this.position,
2016			originalPosition: this.originalPosition,
2017			offset: this.positionAbs
2018		};
2019	}
2020
2021});
2022
2023$.ui.plugin.add("draggable", "connectToSortable", {
2024	start: function(event, ui) {
2025
2026		var inst = $(this).data("draggable"), o = inst.options,
2027			uiSortable = $.extend({}, ui, { item: inst.element });
2028		inst.sortables = [];
2029		$(o.connectToSortable).each(function() {
2030			var sortable = $.data(this, 'sortable');
2031			if (sortable && !sortable.options.disabled) {
2032				inst.sortables.push({
2033					instance: sortable,
2034					shouldRevert: sortable.options.revert
2035				});
2036				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).
2037				sortable._trigger("activate", event, uiSortable);
2038			}
2039		});
2040
2041	},
2042	stop: function(event, ui) {
2043
2044		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2045		var inst = $(this).data("draggable"),
2046			uiSortable = $.extend({}, ui, { item: inst.element });
2047
2048		$.each(inst.sortables, function() {
2049			if(this.instance.isOver) {
2050
2051				this.instance.isOver = 0;
2052
2053				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2054				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2055
2056				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
2057				if(this.shouldRevert) this.instance.options.revert = true;
2058
2059				//Trigger the stop of the sortable
2060				this.instance._mouseStop(event);
2061
2062				this.instance.options.helper = this.instance.options._helper;
2063
2064				//If the helper has been the original item, restore properties in the sortable
2065				if(inst.options.helper == 'original')
2066					this.instance.currentItem.css({ top: 'auto', left: 'auto' });
2067
2068			} else {
2069				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2070				this.instance._trigger("deactivate", event, uiSortable);
2071			}
2072
2073		});
2074
2075	},
2076	drag: function(event, ui) {
2077
2078		var inst = $(this).data("draggable"), that = this;
2079
2080		var checkPos = function(o) {
2081			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
2082			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
2083			var itemHeight = o.height, itemWidth = o.width;
2084			var itemTop = o.top, itemLeft = o.left;
2085
2086			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
2087		};
2088
2089		$.each(inst.sortables, function(i) {
2090
2091			var innermostIntersecting = false;
2092			var thisSortable = this;
2093			//Copy over some variables to allow calling the sortable's native _intersectsWith
2094			this.instance.positionAbs = inst.positionAbs;
2095			this.instance.helperProportions = inst.helperProportions;
2096			this.instance.offset.click = inst.offset.click;
2097
2098			if(this.instance._intersectsWith(this.instance.containerCache)) {
2099				innermostIntersecting = true;
2100				$.each(inst.sortables, function () {
2101					this.instance.positionAbs = inst.positionAbs;
2102					this.instance.helperProportions = inst.helperProportions;
2103					this.instance.offset.click = inst.offset.click;
2104					if  (this != thisSortable
2105						&& this.instance._intersectsWith(this.instance.containerCache)
2106						&& $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
2107						innermostIntersecting = false;
2108						return innermostIntersecting;
2109				});
2110			}
2111
2112
2113			if(innermostIntersecting) {
2114				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2115				if(!this.instance.isOver) {
2116
2117					this.instance.isOver = 1;
2118					//Now we fake the start of dragging for the sortable instance,
2119					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2120					//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)
2121					this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
2122					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2123					this.instance.options.helper = function() { return ui.helper[0]; };
2124
2125					event.target = this.instance.currentItem[0];
2126					this.instance._mouseCapture(event, true);
2127					this.instance._mouseStart(event, true, true);
2128
2129					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2130					this.instance.offset.click.top = inst.offset.click.top;
2131					this.instance.offset.click.left = inst.offset.click.left;
2132					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2133					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2134
2135					inst._trigger("toSortable", event);
2136					inst.dropped = this.instance.element; //draggable revert needs that
2137					//hack so receive/update callbacks work (mostly)
2138					inst.currentItem = inst.element;
2139					this.instance.fromOutside = inst;
2140
2141				}
2142
2143				//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
2144				if(this.instance.currentItem) this.instance._mouseDrag(event);
2145
2146			} else {
2147
2148				//If it doesn't intersect with the sortable, and it intersected before,
2149				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2150				if(this.instance.isOver) {
2151
2152					this.instance.isOver = 0;
2153					this.instance.cancelHelperRemoval = true;
2154
2155					//Prevent reverting on this forced stop
2156					this.instance.options.revert = false;
2157
2158					// The out event needs to be triggered independently
2159					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
2160
2161					this.instance._mouseStop(event, true);
2162					this.instance.options.helper = this.instance.options._helper;
2163
2164					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2165					this.instance.currentItem.remove();
2166					if(this.instance.placeholder) this.instance.placeholder.remove();
2167
2168					inst._trigger("fromSortable", event);
2169					inst.dropped = false; //draggable revert needs that
2170				}
2171
2172			};
2173
2174		});
2175
2176	}
2177});
2178
2179$.ui.plugin.add("draggable", "cursor", {
2180	start: function(event, ui) {
2181		var t = $('body'), o = $(this).data('draggable').options;
2182		if (t.css("cursor")) o._cursor = t.css("cursor");
2183		t.css("cursor", o.cursor);
2184	},
2185	stop: function(event, ui) {
2186		var o = $(this).data('draggable').options;
2187		if (o._cursor) $('body').css("cursor", o._cursor);
2188	}
2189});
2190
2191$.ui.plugin.add("draggable", "opacity", {
2192	start: function(event, ui) {
2193		var t = $(ui.helper), o = $(this).data('draggable').options;
2194		if(t.css("opacity")) o._opacity = t.css("opacity");
2195		t.css('opacity', o.opacity);
2196	},
2197	stop: function(event, ui) {
2198		var o = $(this).data('draggable').options;
2199		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
2200	}
2201});
2202
2203$.ui.plugin.add("draggable", "scroll", {
2204	start: function(event, ui) {
2205		var i = $(this).data("draggable");
2206		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
2207	},
2208	drag: function(event, ui) {
2209
2210		var i = $(this).data("draggable"), o = i.options, scrolled = false;
2211
2212		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
2213
2214			if(!o.axis || o.axis != 'x') {
2215				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
2216					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2217				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
2218					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2219			}
2220
2221			if(!o.axis || o.axis != 'y') {
2222				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
2223					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2224				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
2225					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2226			}
2227
2228		} else {
2229
2230			if(!o.axis || o.axis != 'x') {
2231				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
2232					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2233				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
2234					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2235			}
2236
2237			if(!o.axis || o.axis != 'y') {
2238				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
2239					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2240				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
2241					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2242			}
2243
2244		}
2245
2246		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
2247			$.ui.ddmanager.prepareOffsets(i, event);
2248
2249	}
2250});
2251
2252$.ui.plugin.add("draggable", "snap", {
2253	start: function(event, ui) {
2254
2255		var i = $(this).data("draggable"), o = i.options;
2256		i.snapElements = [];
2257
2258		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
2259			var $t = $(this); var $o = $t.offset();
2260			if(this != i.element[0]) i.snapElements.push({
2261				item: this,
2262				width: $t.outerWidth(), height: $t.outerHeight(),
2263				top: $o.top, left: $o.left
2264			});
2265		});
2266
2267	},
2268	drag: function(event, ui) {
2269
2270		var inst = $(this).data("draggable"), o = inst.options;
2271		var d = o.snapTolerance;
2272
2273		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2274			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2275
2276		for (var i = inst.snapElements.length - 1; i >= 0; i--){
2277
2278			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
2279				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
2280
2281			//Yes, I know, this is insane ;)
2282			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))) {
2283				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2284				inst.snapElements[i].snapping = false;
2285				continue;
2286			}
2287
2288			if(o.snapMode != 'inner') {
2289				var ts = Math.abs(t - y2) <= d;
2290				var bs = Math.abs(b - y1) <= d;
2291				var ls = Math.abs(l - x2) <= d;
2292				var rs = Math.abs(r - x1) <= d;
2293				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2294				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2295				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2296				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2297			}
2298
2299			var first = (ts || bs || ls || rs);
2300
2301			if(o.snapMode != 'outer') {
2302				var ts = Math.abs(t - y1) <= d;
2303				var bs = Math.abs(b - y2) <= d;
2304				var ls = Math.abs(l - x1) <= d;
2305				var rs = Math.abs(r - x2) <= d;
2306				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2307				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2308				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2309				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2310			}
2311
2312			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
2313				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2314			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2315
2316		};
2317
2318	}
2319});
2320
2321$.ui.plugin.add("draggable", "stack", {
2322	start: function(event, ui) {
2323
2324		var o = $(this).data("draggable").options;
2325
2326		var group = $.makeArray($(o.stack)).sort(function(a,b) {
2327			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2328		});
2329		if (!group.length) { return; }
2330
2331		var min = parseInt(group[0].style.zIndex) || 0;
2332		$(group).each(function(i) {
2333			this.style.zIndex = min + i;
2334		});
2335
2336		this[0].style.zIndex = min + group.length;
2337
2338	}
2339});
2340
2341$.ui.plugin.add("draggable", "zIndex", {
2342	start: function(event, ui) {
2343		var t = $(ui.helper), o = $(this).data("draggable").options;
2344		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
2345		t.css('zIndex', o.zIndex);
2346	},
2347	stop: function(event, ui) {
2348		var o = $(this).data("draggable").options;
2349		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
2350	}
2351});
2352
2353})(jQuery);
2354(function( $, undefined ) {
2355
2356$.widget("ui.droppable", {
2357	version: "1.9.2",
2358	widgetEventPrefix: "drop",
2359	options: {
2360		accept: '*',
2361		activeClass: false,
2362		addClasses: true,
2363		greedy: false,
2364		hoverClass: false,
2365		scope: 'default',
2366		tolerance: 'intersect'
2367	},
2368	_create: function() {
2369
2370		var o = this.options, accept = o.accept;
2371		this.isover = 0; this.isout = 1;
2372
2373		this.accept = $.isFunction(accept) ? accept : function(d) {
2374			return d.is(accept);
2375		};
2376
2377		//Store the droppable's proportions
2378		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
2379
2380		// Add the reference and positions to the manager
2381		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
2382		$.ui.ddmanager.droppables[o.scope].push(this);
2383
2384		(o.addClasses && this.element.addClass("ui-droppable"));
2385
2386	},
2387
2388	_destroy: function() {
2389		var drop = $.ui.ddmanager.droppables[this.options.scope];
2390		for ( var i = 0; i < drop.length; i++ )
2391			if ( drop[i] == this )
2392				drop.splice(i, 1);
2393
2394		this.element.removeClass("ui-droppable ui-droppable-disabled");
2395	},
2396
2397	_setOption: function(key, value) {
2398
2399		if(key == 'accept') {
2400			this.accept = $.isFunction(value) ? value : function(d) {
2401				return d.is(value);
2402			};
2403		}
2404		$.Widget.prototype._setOption.apply(this, arguments);
2405	},
2406
2407	_activate: function(event) {
2408		var draggable = $.ui.ddmanager.current;
2409		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
2410		(draggable && this._trigger('activate', event, this.ui(draggable)));
2411	},
2412
2413	_deactivate: function(event) {
2414		var draggable = $.ui.ddmanager.current;
2415		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2416		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
2417	},
2418
2419	_over: function(event) {
2420
2421		var draggable = $.ui.ddmanager.current;
2422		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2423
2424		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2425			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
2426			this._trigger('over', event, this.ui(draggable));
2427		}
2428
2429	},
2430
2431	_out: function(event) {
2432
2433		var draggable = $.ui.ddmanager.current;
2434		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2435
2436		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2437			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2438			this._trigger('out', event, this.ui(draggable));
2439		}
2440
2441	},
2442
2443	_drop: function(event,custom) {
2444
2445		var draggable = custom || $.ui.ddmanager.current;
2446		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
2447
2448		var childrenIntersection = false;
2449		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
2450			var inst = $.data(this, 'droppable');
2451			if(
2452				inst.options.greedy
2453				&& !inst.options.disabled
2454				&& inst.options.scope == draggable.options.scope
2455				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
2456				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2457			) { childrenIntersection = true; return false; }
2458		});
2459		if(childrenIntersection) return false;
2460
2461		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2462			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2463			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2464			this._trigger('drop', event, this.ui(draggable));
2465			return this.element;
2466		}
2467
2468		return false;
2469
2470	},
2471
2472	ui: function(c) {
2473		return {
2474			draggable: (c.currentItem || c.element),
2475			helper: c.helper,
2476			position: c.position,
2477			offset: c.positionAbs
2478		};
2479	}
2480
2481});
2482
2483$.ui.intersect = function(draggable, droppable, toleranceMode) {
2484
2485	if (!droppable.offset) return false;
2486
2487	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2488		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
2489	var l = droppable.offset.left, r = l + droppable.proportions.width,
2490		t = droppable.offset.top, b = t + droppable.proportions.height;
2491
2492	switch (toleranceMode) {
2493		case 'fit':
2494			return (l <= x1 && x2 <= r
2495				&& t <= y1 && y2 <= b);
2496			break;
2497		case 'intersect':
2498			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
2499				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
2500				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
2501				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2502			break;
2503		case 'pointer':
2504			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2505				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2506				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2507			return isOver;
2508			break;
2509		case 'touch':
2510			return (
2511					(y1 >= t && y1 <= b) ||	// Top edge touching
2512					(y2 >= t && y2 <= b) ||	// Bottom edge touching
2513					(y1 < t && y2 > b)		// Surrounded vertically
2514				) && (
2515					(x1 >= l && x1 <= r) ||	// Left edge touching
2516					(x2 >= l && x2 <= r) ||	// Right edge touching
2517					(x1 < l && x2 > r)		// Surrounded horizontally
2518				);
2519			break;
2520		default:
2521			return false;
2522			break;
2523		}
2524
2525};
2526
2527/*
2528	This manager tracks offsets of draggables and droppables
2529*/
2530$.ui.ddmanager = {
2531	current: null,
2532	droppables: { 'default': [] },
2533	prepareOffsets: function(t, event) {
2534
2535		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2536		var type = event ? event.type : null; // workaround for #2317
2537		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2538
2539		droppablesLoop: for (var i = 0; i < m.length; i++) {
2540
2541			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
2542			for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
2543			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue
2544
2545			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2546
2547			m[i].offset = m[i].element.offset();
2548			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2549
2550		}
2551
2552	},
2553	drop: function(draggable, event) {
2554
2555		var dropped = false;
2556		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2557
2558			if(!this.options) return;
2559			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2560				dropped = this._drop.call(this, event) || dropped;
2561
2562			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2563				this.isout = 1; this.isover = 0;
2564				this._deactivate.call(this, event);
2565			}
2566
2567		});
2568		return dropped;
2569
2570	},
2571	dragStart: function( draggable, event ) {
2572		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2573		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2574			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2575		});
2576	},
2577	drag: function(draggable, event) {
2578
2579		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2580		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2581
2582		//Run through all droppables and check their positions based on specific tolerance options
2583		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2584
2585			if(this.options.disabled || this.greedyChild || !this.visible) return;
2586			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2587
2588			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2589			if(!c) return;
2590
2591			var parentInstance;
2592			if (this.options.greedy) {
2593				// find droppable parents with same scope
2594				var scope = this.options.scope;
2595				var parent = this.element.parents(':data(droppable)').filter(function () {
2596					return $.data(this, 'droppable').options.scope === scope;
2597				});
2598
2599				if (parent.length) {
2600					parentInstance = $.data(parent[0], 'droppable');
2601					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2602				}
2603			}
2604
2605			// we just moved into a greedy child
2606			if (parentInstance && c == 'isover') {
2607				parentInstance['isover'] = 0;
2608				parentInstance['isout'] = 1;
2609				parentInstance._out.call(parentInstance, event);
2610			}
2611
2612			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2613			this[c == "isover" ? "_over" : "_out"].call(this, event);
2614
2615			// we just moved out of a greedy child
2616			if (parentInstance && c == 'isout') {
2617				parentInstance['isout'] = 0;
2618				parentInstance['isover'] = 1;
2619				parentInstance._over.call(parentInstance, event);
2620			}
2621		});
2622
2623	},
2624	dragStop: function( draggable, event ) {
2625		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2626		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2627		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2628	}
2629};
2630
2631})(jQuery);
2632(function( $, undefined ) {
2633
2634$.widget("ui.resizable", $.ui.mouse, {
2635	version: "1.9.2",
2636	widgetEventPrefix: "resize",
2637	options: {
2638		alsoResize: false,
2639		animate: false,
2640		animateDuration: "slow",
2641		animateEasing: "swing",
2642		aspectRatio: false,
2643		autoHide: false,
2644		containment: false,
2645		ghost: false,
2646		grid: false,
2647		handles: "e,s,se",
2648		helper: false,
2649		maxHeight: null,
2650		maxWidth: null,
2651		minHeight: 10,
2652		minWidth: 10,
2653		zIndex: 1000
2654	},
2655	_create: function() {
2656
2657		var that = this, o = this.options;
2658		this.element.addClass("ui-resizable");
2659
2660		$.extend(this, {
2661			_aspectRatio: !!(o.aspectRatio),
2662			aspectRatio: o.aspectRatio,
2663			originalElement: this.element,
2664			_proportionallyResizeElements: [],
2665			_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2666		});
2667
2668		//Wrap the element if it cannot hold child nodes
2669		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2670
2671			//Create a wrapper element and set the wrapper to the new current internal element
2672			this.element.wrap(
2673				$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2674					position: this.element.css('position'),
2675					width: this.element.outerWidth(),
2676					height: this.element.outerHeight(),
2677					top: this.element.css('top'),
2678					left: this.element.css('left')
2679				})
2680			);
2681
2682			//Overwrite the original this.element
2683			this.element = this.element.parent().data(
2684				"resizable", this.element.data('resizable')
2685			);
2686
2687			this.elementIsWrapper = true;
2688
2689			//Move margins to the wrapper
2690			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2691			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2692
2693			//Prevent Safari textarea resize
2694			this.originalResizeStyle = this.originalElement.css('resize');
2695			this.originalElement.css('resize', 'none');
2696
2697			//Push the actual element to our proportionallyResize internal array
2698			this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2699
2700			// avoid IE jump (hard set the margin)
2701			this.originalElement.css({ margin: this.originalElement.css('margin') });
2702
2703			// fix handlers offset
2704			this._proportionallyResize();
2705
2706		}
2707
2708		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' });
2709		if(this.handles.constructor == String) {
2710
2711			if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2712			var n = this.handles.split(","); this.handles = {};
2713
2714			for(var i = 0; i < n.length; i++) {
2715
2716				var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2717				var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2718
2719				// Apply zIndex to all handles - see #7960
2720				axis.css({ zIndex: o.zIndex });
2721
2722				//TODO : What's going on here?
2723				if ('se' == handle) {
2724					axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2725				};
2726
2727				//Insert into internal handles object and append to element
2728				this.handles[handle] = '.ui-resizable-'+handle;
2729				this.element.append(axis);
2730			}
2731
2732		}
2733
2734		this._renderAxis = function(target) {
2735
2736			target = target || this.element;
2737
2738			for(var i in this.handles) {
2739
2740				if(this.handles[i].constructor == String)
2741					this.handles[i] = $(this.handles[i], this.element).show();
2742
2743				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2744				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2745
2746					var axis = $(this.handles[i], this.element), padWrapper = 0;
2747
2748					//Checking the correct pad and border
2749					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2750
2751					//The padding type i have to apply...
2752					var padPos = [ 'padding',
2753						/ne|nw|n/.test(i) ? 'Top' :
2754						/se|sw|s/.test(i) ? 'Bottom' :
2755						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
2756
2757					target.css(padPos, padWrapper);
2758
2759					this._proportionallyResize();
2760
2761				}
2762
2763				//TODO: What's that good for? There's not anything to be executed left
2764				if(!$(this.handles[i]).length)
2765					continue;
2766
2767			}
2768		};
2769
2770		//TODO: make renderAxis a prototype function
2771		this._renderAxis(this.element);
2772
2773		this._handles = $('.ui-resizable-handle', this.element)
2774			.disableSelection();
2775
2776		//Matching axis name
2777		this._handles.mouseover(function() {
2778			if (!that.resizing) {
2779				if (this.className)
2780					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2781				//Axis, default = se
2782				that.axis = axis && axis[1] ? axis[1] : 'se';
2783			}
2784		});
2785
2786		//If we want to auto hide the elements
2787		if (o.autoHide) {
2788			this._handles.hide();
2789			$(this.element)
2790				.addClass("ui-resizable-autohide")
2791				.mouseenter(function() {
2792					if (o.disabled) return;
2793					$(this).removeClass("ui-resizable-autohide");
2794					that._handles.show();
2795				})
2796				.mouseleave(function(){
2797					if (o.disabled) return;
2798					if (!that.resizing) {
2799						$(this).addClass("ui-resizable-autohide");
2800						that._handles.hide();
2801					}
2802				});
2803		}
2804
2805		//Initialize the mouse interaction
2806		this._mouseInit();
2807
2808	},
2809
2810	_destroy: function() {
2811
2812		this._mouseDestroy();
2813
2814		var _destroy = function(exp) {
2815			$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2816				.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2817		};
2818
2819		//TODO: Unwrap at same DOM position
2820		if (this.elementIsWrapper) {
2821			_destroy(this.element);
2822			var wrapper = this.element;
2823			this.originalElement.css({
2824				position: wrapper.css('position'),
2825				width: wrapper.outerWidth(),
2826				height: wrapper.outerHeight(),
2827				top: wrapper.css('top'),
2828				left: wrapper.css('left')
2829			}).insertAfter( wrapper );
2830			wrapper.remove();
2831		}
2832
2833		this.originalElement.css('resize', this.originalResizeStyle);
2834		_destroy(this.originalElement);
2835
2836		return this;
2837	},
2838
2839	_mouseCapture: function(event) {
2840		var handle = false;
2841		for (var i in this.handles) {
2842			if ($(this.handles[i])[0] == event.target) {
2843				handle = true;
2844			}
2845		}
2846
2847		return !this.options.disabled && handle;
2848	},
2849
2850	_mouseStart: function(event) {
2851
2852		var o = this.options, iniPos = this.element.position(), el = this.element;
2853
2854		this.resizing = true;
2855		this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2856
2857		// bugfix for http://dev.jquery.com/ticket/1749
2858		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2859			el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2860		}
2861
2862		this._renderProxy();
2863
2864		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2865
2866		if (o.containment) {
2867			curleft += $(o.containment).scrollLeft() || 0;
2868			curtop += $(o.containment).scrollTop() || 0;
2869		}
2870
2871		//Store needed variables
2872		this.offset = this.helper.offset();
2873		this.position = { left: curleft, top: curtop };
2874		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2875		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2876		this.originalPosition = { left: curleft, top: curtop };
2877		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2878		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2879
2880		//Aspect Ratio
2881		this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2882
2883		var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2884		$('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2885
2886		el.addClass("ui-resizable-resizing");
2887		this._propagate("start", event);
2888		return true;
2889	},
2890
2891	_mouseDrag: function(event) {
2892
2893		//Increase performance, avoid regex
2894		var el = this.helper, o = this.options, props = {},
2895			that = this, smp = this.originalMousePosition, a = this.axis;
2896
2897		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2898		var trigger = this._change[a];
2899		if (!trigger) return false;
2900
2901		// Calculate the attrs that will be change
2902		var data = trigger.apply(this, [event, dx, dy]);
2903
2904		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2905		this._updateVirtualBoundaries(event.shiftKey);
2906		if (this._aspectRatio || event.shiftKey)
2907			data = this._updateRatio(data, event);
2908
2909		data = this._respectSize(data, event);
2910
2911		// plugins callbacks need to be called first
2912		this._propagate("resize", event);
2913
2914		el.css({
2915			top: this.position.top + "px", left: this.position.left + "px",
2916			width: this.size.width + "px", height: this.size.height + "px"
2917		});
2918
2919		if (!this._helper && this._proportionallyResizeElements.length)
2920			this._proportionallyResize();
2921
2922		this._updateCache(data);
2923
2924		// calling the user callback at the end
2925		this._trigger('resize', event, this.ui());
2926
2927		return false;
2928	},
2929
2930	_mouseStop: function(event) {
2931
2932		this.resizing = false;
2933		var o = this.options, that = this;
2934
2935		if(this._helper) {
2936			var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2937				soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2938				soffsetw = ista ? 0 : that.sizeDiff.width;
2939
2940			var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
2941				left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
2942				top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
2943
2944			if (!o.animate)
2945				this.element.css($.extend(s, { top: top, left: left }));
2946
2947			that.helper.height(that.size.height);
2948			that.helper.width(that.size.width);
2949
2950			if (this._helper && !o.animate) this._proportionallyResize();
2951		}
2952
2953		$('body').css('cursor', 'auto');
2954
2955		this.element.removeClass("ui-resizable-resizing");
2956
2957		this._propagate("stop", event);
2958
2959		if (this._helper) this.helper.remove();
2960		return false;
2961
2962	},
2963
2964	_updateVirtualBoundaries: function(forceAspectRatio) {
2965		var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2966
2967		b = {
2968			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2969			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2970			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2971			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2972		};
2973
2974		if(this._aspectRatio || forceAspectRatio) {
2975			// We want to create an enclosing box whose aspect ration is the requested one
2976			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2977			pMinWidth = b.minHeight * this.aspectRatio;
2978			pMinHeight = b.minWidth / this.aspectRatio;
2979			pMaxWidth = b.maxHeight * this.aspectRatio;
2980			pMaxHeight = b.maxWidth / this.aspectRatio;
2981
2982			if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2983			if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2984			if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2985			if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2986		}
2987		this._vBoundaries = b;
2988	},
2989
2990	_updateCache: function(data) {
2991		var o = this.options;
2992		this.offset = this.helper.offset();
2993		if (isNumber(data.left)) this.position.left = data.left;
2994		if (isNumber(data.top)) this.position.top = data.top;
2995		if (isNumber(data.height)) this.size.height = data.height;
2996		if (isNumber(data.width)) this.size.width = data.width;
2997	},
2998
2999	_updateRatio: function(data, event) {
3000
3001		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
3002
3003		if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
3004		else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
3005
3006		if (a == 'sw') {
3007			data.left = cpos.left + (csize.width - data.width);
3008			data.top = null;
3009		}
3010		if (a == 'nw') {
3011			data.top = cpos.top + (csize.height - data.height);
3012			data.left = cpos.left + (csize.width - data.width);
3013		}
3014
3015		return data;
3016	},
3017
3018	_respectSize: function(data, event) {
3019
3020		var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
3021				ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3022					isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
3023
3024		if (isminw) data.width = o.minWidth;
3025		if (isminh) data.height = o.minHeight;
3026		if (ismaxw) data.width = o.maxWidth;
3027		if (ismaxh) data.height = o.maxHeight;
3028
3029		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
3030		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3031
3032		if (isminw && cw) data.left = dw - o.minWidth;
3033		if (ismaxw && cw) data.left = dw - o.maxWidth;
3034		if (isminh && ch)	data.top = dh - o.minHeight;
3035		if (ismaxh && ch)	data.top = dh - o.maxHeight;
3036
3037		// fixing jump error on top/left - bug #2330
3038		var isNotwh = !data.width && !data.height;
3039		if (isNotwh && !data.left && data.top) data.top = null;
3040		else if (isNotwh && !data.top && data.left) data.left = null;
3041
3042		return data;
3043	},
3044
3045	_proportionallyResize: function() {
3046
3047		var o = this.options;
3048		if (!this._proportionallyResizeElements.length) return;
3049		var element = this.helper || this.element;
3050
3051		for (var i=0; i < this._proportionallyResizeElements.length; i++) {
3052
3053			var prel = this._proportionallyResizeElements[i];
3054
3055			if (!this.borderDif) {
3056				var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
3057					p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
3058
3059				this.borderDif = $.map(b, function(v, i) {
3060					var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
3061					return border + padding;
3062				});
3063			}
3064
3065			prel.css({
3066				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
3067				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
3068			});
3069
3070		};
3071
3072	},
3073
3074	_renderProxy: function() {
3075
3076		var el = this.element, o = this.options;
3077		this.elementOffset = el.offset();
3078
3079		if(this._helper) {
3080
3081			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
3082
3083			// fix ie6 offset TODO: This seems broken
3084			var ie6offset = ($.ui.ie6 ? 1 : 0),
3085			pxyoffset = ( $.ui.ie6 ? 2 : -1 );
3086
3087			this.helper.addClass(this._helper).css({
3088				width: this.element.outerWidth() + pxyoffset,
3089				height: this.element.outerHeight() + pxyoffset,
3090				position: 'absolute',
3091				left: this.elementOffset.left - ie6offset +'px',
3092				top: this.elementOffset.top - ie6offset +'px',
3093				zIndex: ++o.zIndex //TODO: Don't modify option
3094			});
3095
3096			this.helper
3097				.appendTo("body")
3098				.disableSelection();
3099
3100		} else {
3101			this.helper = this.element;
3102		}
3103
3104	},
3105
3106	_change: {
3107		e: function(event, dx, dy) {
3108			return { width: this.originalSize.width + dx };
3109		},
3110		w: function(event, dx, dy) {
3111			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
3112			return { left: sp.left + dx, width: cs.width - dx };
3113		},
3114		n: function(event, dx, dy) {
3115			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
3116			return { top: sp.top + dy, height: cs.height - dy };
3117		},
3118		s: function(event, dx, dy) {
3119			return { height: this.originalSize.height + dy };
3120		},
3121		se: function(event, dx, dy) {
3122			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3123		},
3124		sw: function(event, dx, dy) {
3125			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3126		},
3127		ne: function(event, dx, dy) {
3128			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3129		},
3130		nw: function(event, dx, dy) {
3131			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3132		}
3133	},
3134
3135	_propagate: function(n, event) {
3136		$.ui.plugin.call(this, n, [event, this.ui()]);
3137		(n != "resize" && this._trigger(n, event, this.ui()));
3138	},
3139
3140	plugins: {},
3141
3142	ui: function() {
3143		return {
3144			originalElement: this.originalElement,
3145			element: this.element,
3146			helper: this.helper,
3147			position: this.position,
3148			size: this.size,
3149			originalSize: this.originalSize,
3150			originalPosition: this.originalPosition
3151		};
3152	}
3153
3154});
3155
3156/*
3157 * Resizable Extensions
3158 */
3159
3160$.ui.plugin.add("resizable", "alsoResize", {
3161
3162	start: function (event, ui) {
3163		var that = $(this).data("resizable"), o = that.options;
3164
3165		var _store = function (exp) {
3166			$(exp).each(function() {
3167				var el = $(this);
3168				el.data("resizable-alsoresize", {
3169					width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3170					left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
3171				});
3172			});
3173		};
3174
3175		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
3176			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3177			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3178		}else{
3179			_store(o.alsoResize);
3180		}
3181	},
3182
3183	resize: function (event, ui) {
3184		var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
3185
3186		var delta = {
3187			height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3188			top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3189		},
3190
3191		_alsoResize = function (exp, c) {
3192			$(exp).each(function() {
3193				var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
3194					css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
3195
3196				$.each(css, function (i, prop) {
3197					var sum = (start[prop]||0) + (delta[prop]||0);
3198					if (sum && sum >= 0)
3199						style[prop] = sum || null;
3200				});
3201
3202				el.css(style);
3203			});
3204		};
3205
3206		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
3207			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3208		}else{
3209			_alsoResize(o.alsoResize);
3210		}
3211	},
3212
3213	stop: function (event, ui) {
3214		$(this).removeData("resizable-alsoresize");
3215	}
3216});
3217
3218$.ui.plugin.add("resizable", "animate", {
3219
3220	stop: function(event, ui) {
3221		var that = $(this).data("resizable"), o = that.options;
3222
3223		var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3224					soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
3225						soffsetw = ista ? 0 : that.sizeDiff.width;
3226
3227		var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3228					left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
3229						top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
3230
3231		that.element.animate(
3232			$.extend(style, top && left ? { top: top, left: left } : {}), {
3233				duration: o.animateDuration,
3234				easing: o.animateEasing,
3235				step: function() {
3236
3237					var data = {
3238						width: parseInt(that.element.css('width'), 10),
3239						height: parseInt(that.element.css('height'), 10),
3240						top: parseInt(that.element.css('top'), 10),
3241						left: parseInt(that.element.css('left'), 10)
3242					};
3243
3244					if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
3245
3246					// propagating resize, and updating values for each animation step
3247					that._updateCache(data);
3248					that._propagate("resize", event);
3249
3250				}
3251			}
3252		);
3253	}
3254
3255});
3256
3257$.ui.plugin.add("resizable", "containment", {
3258
3259	start: function(event, ui) {
3260		var that = $(this).data("resizable"), o = that.options, el = that.element;
3261		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
3262		if (!ce) return;
3263
3264		that.containerElement = $(ce);
3265
3266		if (/document/.test(oc) || oc == document) {
3267			that.containerOffset = { left: 0, top: 0 };
3268			that.containerPosition = { left: 0, top: 0 };
3269
3270			that.parentData = {
3271				element: $(document), left: 0, top: 0,
3272				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3273			};
3274		}
3275
3276		// i'm a node, so compute top, left, right, bottom
3277		else {
3278			var element = $(ce), p = [];
3279			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3280
3281			that.containerOffset = element.offset();
3282			that.containerPosition = element.position();
3283			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3284
3285			var co = that.containerOffset, ch = that.containerSize.height,	cw = that.containerSize.width,
3286						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3287
3288			that.parentData = {
3289				element: ce, left: co.left, top: co.top, width: width, height: height
3290			};
3291		}
3292	},
3293
3294	resize: function(event, ui) {
3295		var that = $(this).data("resizable"), o = that.options,
3296				ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
3297				pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
3298
3299		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
3300
3301		if (cp.left < (that._helper ? co.left : 0)) {
3302			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3303			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
3304			that.position.left = o.helper ? co.left : 0;
3305		}
3306
3307		if (cp.top < (that._helper ? co.top : 0)) {
3308			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3309			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
3310			that.position.top = that._helper ? co.top : 0;
3311		}
3312
3313		that.offset.left = that.parentData.left+that.position.left;
3314		that.offset.top = that.parentData.top+that.position.top;
3315
3316		var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
3317					hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3318
3319		var isParent = that.containerElement.get(0) == that.element.parent().get(0),
3320			isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
3321
3322		if(isParent && isOffsetRelative) woset -= that.parentData.left;
3323
3324		if (woset + that.size.width >= that.parentData.width) {
3325			that.size.width = that.parentData.width - woset;
3326			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
3327		}
3328
3329		if (hoset + that.size.height >= that.parentData.height) {
3330			that.size.height = that.parentData.height - hoset;
3331			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
3332		}
3333	},
3334
3335	stop: function(event, ui){
3336		var that = $(this).data("resizable"), o = that.options, cp = that.position,
3337				co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
3338
3339		var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
3340
3341		if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
3342			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3343
3344		if (that._helper && !o.animate && (/static/).test(ce.css('position')))
3345			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3346
3347	}
3348});
3349
3350$.ui.plugin.add("resizable", "ghost", {
3351
3352	start: function(event, ui) {
3353
3354		var that = $(this).data("resizable"), o = that.options, cs = that.size;
3355
3356		that.ghost = that.originalElement.clone();
3357		that.ghost
3358			.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3359			.addClass('ui-resizable-ghost')
3360			.addClass(typeof o.ghost == 'string' ? o.ghost : '');
3361
3362		that.ghost.appendTo(that.helper);
3363
3364	},
3365
3366	resize: function(event, ui){
3367		var that = $(this).data("resizable"), o = that.options;
3368		if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
3369	},
3370
3371	stop: function(event, ui){
3372		var that = $(this).data("resizable"), o = that.options;
3373		if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
3374	}
3375
3376});
3377
3378$.ui.plugin.add("resizable", "grid", {
3379
3380	resize: function(event, ui) {
3381		var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
3382		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
3383		var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
3384
3385		if (/^(se|s|e)$/.test(a)) {
3386			that.size.width = os.width + ox;
3387			that.size.height = os.height + oy;
3388		}
3389		else if (/^(ne)$/.test(a)) {
3390			that.size.width = os.width + ox;
3391			that.size.height = os.height + oy;
3392			that.position.top = op.top - oy;
3393		}
3394		else if (/^(sw)$/.test(a)) {
3395			that.size.width = os.width + ox;
3396			that.size.height = os.height + oy;
3397			that.position.left = op.left - ox;
3398		}
3399		else {
3400			that.size.width = os.width + ox;
3401			that.size.height = os.height + oy;
3402			that.position.top = op.top - oy;
3403			that.position.left = op.left - ox;
3404		}
3405	}
3406
3407});
3408
3409var num = function(v) {
3410	return parseInt(v, 10) || 0;
3411};
3412
3413var isNumber = function(value) {
3414	return !isNaN(parseInt(value, 10));
3415};
3416
3417})(jQuery);
3418(function( $, undefined ) {
3419
3420$.widget("ui.selectable", $.ui.mouse, {
3421	version: "1.9.2",
3422	options: {
3423		appendTo: 'body',
3424		autoRefresh: true,
3425		distance: 0,
3426		filter: '*',
3427		tolerance: 'touch'
3428	},
3429	_create: function() {
3430		var that = this;
3431
3432		this.element.addClass("ui-selectable");
3433
3434		this.dragged = false;
3435
3436		// cache selectee children based on filter
3437		var selectees;
3438		this.refresh = function() {
3439			selectees = $(that.options.filter, that.element[0]);
3440			selectees.addClass("ui-selectee");
3441			selectees.each(function() {
3442				var $this = $(this);
3443				var pos = $this.offset();
3444				$.data(this, "selectable-item", {
3445					element: this,
3446					$element: $this,
3447					left: pos.left,
3448					top: pos.top,
3449					right: pos.left + $this.outerWidth(),
3450					bottom: pos.top + $this.outerHeight(),
3451					startselected: false,
3452					selected: $this.hasClass('ui-selected'),
3453					selecting: $this.hasClass('ui-selecting'),
3454					unselecting: $this.hasClass('ui-unselecting')
3455				});
3456			});
3457		};
3458		this.refresh();
3459
3460		this.selectees = selectees.addClass("ui-selectee");
3461
3462		this._mouseInit();
3463
3464		this.helper = $("<div class='ui-selectable-helper'></div>");
3465	},
3466
3467	_destroy: function() {
3468		this.selectees
3469			.removeClass("ui-selectee")
3470			.removeData("selectable-item");
3471		this.element
3472			.removeClass("ui-selectable ui-selectable-disabled");
3473		this._mouseDestroy();
3474	},
3475
3476	_mouseStart: function(event) {
3477		var that = this;
3478
3479		this.opos = [event.pageX, event.pageY];
3480
3481		if (this.options.disabled)
3482			return;
3483
3484		var options = this.options;
3485
3486		this.selectees = $(options.filter, this.element[0]);
3487
3488		this._trigger("start", event);
3489
3490		$(options.appendTo).append(this.helper);
3491		// position helper (lasso)
3492		this.helper.css({
3493			"left": event.clientX,
3494			"top": event.clientY,
3495			"width": 0,
3496			"height": 0
3497		});
3498
3499		if (options.autoRefresh) {
3500			this.refresh();
3501		}
3502
3503		this.selectees.filter('.ui-selected').each(function() {
3504			var selectee = $.data(this, "selectable-item");
3505			selectee.startselected = true;
3506			if (!event.metaKey && !event.ctrlKey) {
3507				selectee.$element.removeClass('ui-selected');
3508				selectee.selected = false;
vendor: 4,195 bytes, lines 3509-3647
3509				selectee.$element.addClass('ui-unselecting');
3510				selectee.unselecting = true;
3511				// selectable UNSELECTING callback
3512				that._trigger("unselecting", event, {
3513					unselecting: selectee.element
3514				});
3515			}
3516		});
3517
3518		$(event.target).parents().andSelf().each(function() {
3519			var selectee = $.data(this, "selectable-item");
3520			if (selectee) {
3521				var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
3522				selectee.$element
3523					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3524					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3525				selectee.unselecting = !doSelect;
3526				selectee.selecting = doSelect;
3527				selectee.selected = doSelect;
3528				// selectable (UN)SELECTING callback
3529				if (doSelect) {
3530					that._trigger("selecting", event, {
3531						selecting: selectee.element
3532					});
3533				} else {
3534					that._trigger("unselecting", event, {
3535						unselecting: selectee.element
3536					});
3537				}
3538				return false;
3539			}
3540		});
3541
3542	},
3543
3544	_mouseDrag: function(event) {
3545		var that = this;
3546		this.dragged = true;
3547
3548		if (this.options.disabled)
3549			return;
3550
3551		var options = this.options;
3552
3553		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3554		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3555		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3556		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3557
3558		this.selectees.each(function() {
3559			var selectee = $.data(this, "selectable-item");
3560			//prevent helper from being selected if appendTo: selectable
3561			if (!selectee || selectee.element == that.element[0])
3562				return;
3563			var hit = false;
3564			if (options.tolerance == 'touch') {
3565				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3566			} else if (options.tolerance == 'fit') {
3567				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3568			}
3569
3570			if (hit) {
3571				// SELECT
3572				if (selectee.selected) {
3573					selectee.$element.removeClass('ui-selected');
3574					selectee.selected = false;
3575				}
3576				if (selectee.unselecting) {
3577					selectee.$element.removeClass('ui-unselecting');
3578					selectee.unselecting = false;
3579				}
3580				if (!selectee.selecting) {
3581					selectee.$element.addClass('ui-selecting');
3582					selectee.selecting = true;
3583					// selectable SELECTING callback
3584					that._trigger("selecting", event, {
3585						selecting: selectee.element
3586					});
3587				}
3588			} else {
3589				// UNSELECT
3590				if (selectee.selecting) {
3591					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3592						selectee.$element.removeClass('ui-selecting');
3593						selectee.selecting = false;
3594						selectee.$element.addClass('ui-selected');
3595						selectee.selected = true;
3596					} else {
3597						selectee.$element.removeClass('ui-selecting');
3598						selectee.selecting = false;
3599						if (selectee.startselected) {
3600							selectee.$element.addClass('ui-unselecting');
3601							selectee.unselecting = true;
3602						}
3603						// selectable UNSELECTING callback
3604						that._trigger("unselecting", event, {
3605							unselecting: selectee.element
3606						});
3607					}
3608				}
3609				if (selectee.selected) {
3610					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3611						selectee.$element.removeClass('ui-selected');
3612						selectee.selected = false;
3613
3614						selectee.$element.addClass('ui-unselecting');
3615						selectee.unselecting = true;
3616						// selectable UNSELECTING callback
3617						that._trigger("unselecting", event, {
3618							unselecting: selectee.element
3619						});
3620					}
3621				}
3622			}
3623		});
3624
3625		return false;
3626	},
3627
3628	_mouseStop: function(event) {
3629		var that = this;
3630
3631		this.dragged = false;
3632
3633		var options = this.options;
3634
3635		$('.ui-unselecting', this.element[0]).each(function() {
3636			var selectee = $.data(this, "selectable-item");
3637			selectee.$element.removeClass('ui-unselecting');
3638			selectee.unselecting = false;
3639			selectee.startselected = false;
3640			that._trigger("unselected", event, {
3641				unselected: selectee.element
3642			});
3643		});
3644		$('.ui-selecting', this.element[0]).each(function() {
3645			var selectee = $.data(this, "selectable-item");
3646			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3647			selectee.selecting = false;
3648			selectee.selected = true;
3649			selectee.startselected = true;
3650			that._trigger("selected", event, {
3651				selected: selectee.element
3652			});
3653		});
3654		this._trigger("stop", event);
3655
3656		this.helper.remove();
3657
3658		return false;
3659	}
3660
3661});
3662
3663})(jQuery);
3664(function( $, undefined ) {
3665
3666$.widget("ui.sortable", $.ui.mouse, {
3667	version: "1.9.2",
3668	widgetEventPrefix: "sort",
3669	ready: false,
3670	options: {
3671		appendTo: "parent",
3672		axis: false,
3673		connectWith: false,
3674		containment: false,
3675		cursor: 'auto',
3676		cursorAt: false,
3677		dropOnEmpty: true,
3678		forcePlaceholderSize: false,
3679		forceHelperSize: false,
3680		grid: false,
3681		handle: false,
3682		helper: "original",
3683		items: '> *',
3684		opacity: false,
3685		placeholder: false,
3686		revert: false,
3687		scroll: true,
3688		scrollSensitivity: 20,
3689		scrollSpeed: 20,
3690		scope: "default",
3691		tolerance: "intersect",
3692		zIndex: 1000
3693	},
3694	_create: function() {
3695
3696		var o = this.options;
3697		this.containerCache = {};
3698		this.element.addClass("ui-sortable");
3699
3700		//Get the items
3701		this.refresh();
3702
3703		//Let's determine if the items are being displayed horizontally
3704		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;
3705
3706		//Let's determine the parent's offset
3707		this.offset = this.element.offset();
3708
3709		//Initialize mouse events for interaction
3710		this._mouseInit();
3711
3712		//We're ready to go
3713		this.ready = true
3714
3715	},
3716
3717	_destroy: function() {
3718		this.element
3719			.removeClass("ui-sortable ui-sortable-disabled");
3720		this._mouseDestroy();
3721
3722		for ( var i = this.items.length - 1; i >= 0; i-- )
3723			this.items[i].item.removeData(this.widgetName + "-item");
3724
3725		return this;
3726	},
3727
3728	_setOption: function(key, value){
3729		if ( key === "disabled" ) {
3730			this.options[ key ] = value;
3731
3732			this.widget().toggleClass( "ui-sortable-disabled", !!value );
3733		} else {
3734			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3735			$.Widget.prototype._setOption.apply(this, arguments);
3736		}
3737	},
3738
3739	_mouseCapture: function(event, overrideHandle) {
3740		var that = this;
3741
3742		if (this.reverting) {
3743			return false;
3744		}
3745
3746		if(this.options.disabled || this.options.type == 'static') return false;
3747
3748		//We have to refresh the items data once first
3749		this._refreshItems(event);
3750
3751		//Find out if the clicked node (or one of its parents) is a actual item in this.items
3752		var currentItem = null, nodes = $(event.target).parents().each(function() {
3753			if($.data(this, that.widgetName + '-item') == that) {
3754				currentItem = $(this);
3755				return false;
3756			}
3757		});
3758		if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
3759
3760		if(!currentItem) return false;
3761		if(this.options.handle && !overrideHandle) {
3762			var validHandle = false;
3763
3764			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3765			if(!validHandle) return false;
3766		}
3767
3768		this.currentItem = currentItem;
3769		this._removeCurrentsFromItems();
3770		return true;
3771
3772	},
3773
3774	_mouseStart: function(event, overrideHandle, noActivation) {
3775
3776		var o = this.options;
3777		this.currentContainer = this;
3778
3779		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3780		this.refreshPositions();
3781
3782		//Create and append the visible helper
3783		this.helper = this._createHelper(event);
3784
3785		//Cache the helper size
3786		this._cacheHelperProportions();
3787
3788		/*
3789		 * - Position generation -
3790		 * This block generates everything position related - it's the core of draggables.
3791		 */
3792
3793		//Cache the margins of the original element
3794		this._cacheMargins();
3795
3796		//Get the next scrolling parent
3797		this.scrollParent = this.helper.scrollParent();
3798
3799		//The element's absolute position on the page minus margins
3800		this.offset = this.currentItem.offset();
3801		this.offset = {
3802			top: this.offset.top - this.margins.top,
3803			left: this.offset.left - this.margins.left
3804		};
3805
3806		$.extend(this.offset, {
3807			click: { //Where the click happened, relative to the element
3808				left: event.pageX - this.offset.left,
3809				top: event.pageY - this.offset.top
3810			},
3811			parent: this._getParentOffset(),
3812			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3813		});
3814
3815		// Only after we got the offset, we can change the helper's position to absolute
3816		// TODO: Still need to figure out a way to make relative sorting possible
3817		this.helper.css("position", "absolute");
3818		this.cssPosition = this.helper.css("position");
3819
3820		//Generate the original position
3821		this.originalPosition = this._generatePosition(event);
3822		this.originalPageX = event.pageX;
3823		this.originalPageY = event.pageY;
3824
3825		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3826		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3827
3828		//Cache the former DOM position
3829		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3830
3831		//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
3832		if(this.helper[0] != this.currentItem[0]) {
3833			this.currentItem.hide();
3834		}
3835
3836		//Create the placeholder
3837		this._createPlaceholder();
3838
3839		//Set a containment if given in the options
3840		if(o.containment)
3841			this._setContainment();
3842
3843		if(o.cursor) { // cursor option
3844			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3845			$('body').css("cursor", o.cursor);
3846		}
3847
3848		if(o.opacity) { // opacity option
3849			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3850			this.helper.css("opacity", o.opacity);
3851		}
3852
3853		if(o.zIndex) { // zIndex option
3854			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3855			this.helper.css("zIndex", o.zIndex);
3856		}
3857
3858		//Prepare scrolling
3859		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3860			this.overflowOffset = this.scrollParent.offset();
3861
3862		//Call callbacks
3863		this._trigger("start", event, this._uiHash());
3864
3865		//Recache the helper size
3866		if(!this._preserveHelperProportions)
3867			this._cacheHelperProportions();
3868
3869
3870		//Post 'activate' events to possible containers
3871		if(!noActivation) {
3872			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
3873		}
3874
3875		//Prepare possible droppables
3876		if($.ui.ddmanager)
3877			$.ui.ddmanager.current = this;
3878
3879		if ($.ui.ddmanager && !o.dropBehaviour)
3880			$.ui.ddmanager.prepareOffsets(this, event);
3881
3882		this.dragging = true;
3883
3884		this.helper.addClass("ui-sortable-helper");
3885		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3886		return true;
3887
3888	},
3889
3890	_mouseDrag: function(event) {
3891
3892		//Compute the helpers position
3893		this.position = this._generatePosition(event);
3894		this.positionAbs = this._convertPositionTo("absolute");
3895
3896		if (!this.lastPositionAbs) {
3897			this.lastPositionAbs = this.positionAbs;
3898		}
3899
3900		//Do scrolling
3901		if(this.options.scroll) {
3902			var o = this.options, scrolled = false;
3903			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3904
3905				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3906					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3907				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3908					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3909
3910				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3911					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3912				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3913					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3914
3915			} else {
3916
3917				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3918					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3919				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3920					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3921
3922				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3923					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3924				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3925					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3926
3927			}
3928
3929			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3930				$.ui.ddmanager.prepareOffsets(this, event);
3931		}
3932
3933		//Regenerate the absolute position used for position checks
3934		this.positionAbs = this._convertPositionTo("absolute");
3935
3936		//Set the helper position
3937		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3938		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3939
3940		//Rearrange
3941		for (var i = this.items.length - 1; i >= 0; i--) {
3942
3943			//Cache variables and intersection, continue if no intersection
3944			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3945			if (!intersection) continue;
3946
3947			// Only put the placeholder inside the current Container, skip all
3948			// items form other containers. This works because when moving
3949			// an item from one container to another the
3950			// currentContainer is switched before the placeholder is moved.
3951			//
3952			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
3953			// beetween the outer and inner container.
3954			if (item.instance !== this.currentContainer) continue;
3955
3956			if (itemElement != this.currentItem[0] //cannot intersect with itself
3957				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3958				&&	!$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3959				&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
3960				//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3961			) {
3962
3963				this.direction = intersection == 1 ? "down" : "up";
3964
3965				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3966					this._rearrange(event, item);
3967				} else {
3968					break;
3969				}
3970
3971				this._trigger("change", event, this._uiHash());
3972				break;
3973			}
3974		}
3975
3976		//Post events to containers
3977		this._contactContainers(event);
3978
3979		//Interconnect with droppables
3980		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3981
3982		//Call callbacks
3983		this._trigger('sort', event, this._uiHash());
3984
3985		this.lastPositionAbs = this.positionAbs;
3986		return false;
3987
3988	},
3989
3990	_mouseStop: function(event, noPropagation) {
3991
3992		if(!event) return;
3993
3994		//If we are using droppables, inform the manager about the drop
3995		if ($.ui.ddmanager && !this.options.dropBehaviour)
3996			$.ui.ddmanager.drop(this, event);
3997
3998		if(this.options.revert) {
3999			var that = this;
4000			var cur = this.placeholder.offset();
4001
4002			this.reverting = true;
4003
4004			$(this.helper).animate({
4005				left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
4006				top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
4007			}, parseInt(this.options.revert, 10) || 500, function() {
4008				that._clear(event);
4009			});
4010		} else {
4011			this._clear(event, noPropagation);
4012		}
4013
4014		return false;
4015
4016	},
4017
4018	cancel: function() {
4019
4020		if(this.dragging) {
4021
4022			this._mouseUp({ target: null });
4023
4024			if(this.options.helper == "original")
4025				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4026			else
4027				this.currentItem.show();
4028
4029			//Post deactivating events to containers
4030			for (var i = this.containers.length - 1; i >= 0; i--){
4031				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4032				if(this.containers[i].containerCache.over) {
4033					this.containers[i]._trigger("out", null, this._uiHash(this));
4034					this.containers[i].containerCache.over = 0;
4035				}
4036			}
4037
4038		}
4039
4040		if (this.placeholder) {
4041			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4042			if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4043			if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
4044
4045			$.extend(this, {
4046				helper: null,
4047				dragging: false,
4048				reverting: false,
4049				_noFinalSort: null
4050			});
4051
4052			if(this.domPosition.prev) {
4053				$(this.domPosition.prev).after(this.currentItem);
4054			} else {
4055				$(this.domPosition.parent).prepend(this.currentItem);
4056			}
4057		}
4058
4059		return this;
4060
4061	},
4062
4063	serialize: function(o) {
4064
4065		var items = this._getItemsAsjQuery(o && o.connected);
4066		var str = []; o = o || {};
4067
4068		$(items).each(function() {
4069			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
4070			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
4071		});
4072
4073		if(!str.length && o.key) {
4074			str.push(o.key + '=');
4075		}
4076
4077		return str.join('&');
4078
4079	},
4080
4081	toArray: function(o) {
4082
4083		var items = this._getItemsAsjQuery(o && o.connected);
4084		var ret = []; o = o || {};
4085
4086		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
4087		return ret;
4088
4089	},
4090
4091	/* Be careful with the following core functions */
4092	_intersectsWith: function(item) {
4093
4094		var x1 = this.positionAbs.left,
4095			x2 = x1 + this.helperProportions.width,
4096			y1 = this.positionAbs.top,
4097			y2 = y1 + this.helperProportions.height;
4098
4099		var l = item.left,
4100			r = l + item.width,
4101			t = item.top,
4102			b = t + item.height;
4103
4104		var dyClick = this.offset.click.top,
4105			dxClick = this.offset.click.left;
4106
4107		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
4108
4109		if(	   this.options.tolerance == "pointer"
4110			|| this.options.forcePointerForContainers
4111			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
4112		) {
4113			return isOverElement;
4114		} else {
4115
4116			return (l < x1 + (this.helperProportions.width / 2) // Right Half
4117				&& x2 - (this.helperProportions.width / 2) < r // Left Half
4118				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
4119				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
4120
4121		}
4122	},
4123
4124	_intersectsWithPointer: function(item) {
4125
4126		var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4127			isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4128			isOverElement = isOverElementHeight && isOverElementWidth,
4129			verticalDirection = this._getDragVerticalDirection(),
4130			horizontalDirection = this._getDragHorizontalDirection();
4131
4132		if (!isOverElement)
4133			return false;
4134
4135		return this.floating ?
4136			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
4137			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
4138
4139	},
4140
4141	_intersectsWithSides: function(item) {
4142
4143		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4144			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4145			verticalDirection = this._getDragVerticalDirection(),
4146			horizontalDirection = this._getDragHorizontalDirection();
4147
4148		if (this.floating && horizontalDirection) {
4149			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
4150		} else {
4151			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
4152		}
4153
4154	},
4155
4156	_getDragVerticalDirection: function() {
4157		var delta = this.positionAbs.top - this.lastPositionAbs.top;
4158		return delta != 0 && (delta > 0 ? "down" : "up");
4159	},
4160
4161	_getDragHorizontalDirection: function() {
4162		var delta = this.positionAbs.left - this.lastPositionAbs.left;
4163		return delta != 0 && (delta > 0 ? "right" : "left");
4164	},
4165
4166	refresh: function(event) {
4167		this._refreshItems(event);
4168		this.refreshPositions();
4169		return this;
4170	},
4171
4172	_connectWith: function() {
4173		var options = this.options;
4174		return options.connectWith.constructor == String
4175			? [options.connectWith]
4176			: options.connectWith;
4177	},
4178
4179	_getItemsAsjQuery: function(connected) {
4180
4181		var items = [];
4182		var queries = [];
4183		var connectWith = this._connectWith();
4184
4185		if(connectWith && connected) {
4186			for (var i = connectWith.length - 1; i >= 0; i--){
4187				var cur = $(connectWith[i]);
4188				for (var j = cur.length - 1; j >= 0; j--){
4189					var inst = $.data(cur[j], this.widgetName);
4190					if(inst && inst != this && !inst.options.disabled) {
4191						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]);
4192					}
4193				};
4194			};
4195		}
4196
4197		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]);
4198
4199		for (var i = queries.length - 1; i >= 0; i--){
4200			queries[i][0].each(function() {
4201				items.push(this);
4202			});
4203		};
4204
4205		return $(items);
4206
4207	},
4208
4209	_removeCurrentsFromItems: function() {
4210
4211		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4212
4213		this.items = $.grep(this.items, function (item) {
4214			for (var j=0; j < list.length; j++) {
4215				if(list[j] == item.item[0])
4216					return false;
4217			};
4218			return true;
4219		});
4220
4221	},
4222
4223	_refreshItems: function(event) {
4224
4225		this.items = [];
4226		this.containers = [this];
4227		var items = this.items;
4228		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
4229		var connectWith = this._connectWith();
4230
4231		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4232			for (var i = connectWith.length - 1; i >= 0; i--){
4233				var cur = $(connectWith[i]);
4234				for (var j = cur.length - 1; j >= 0; j--){
4235					var inst = $.data(cur[j], this.widgetName);
4236					if(inst && inst != this && !inst.options.disabled) {
4237						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4238						this.containers.push(inst);
4239					}
4240				};
4241			};
4242		}
4243
4244		for (var i = queries.length - 1; i >= 0; i--) {
4245			var targetData = queries[i][1];
4246			var _queries = queries[i][0];
4247
4248			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4249				var item = $(_queries[j]);
4250
4251				item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
4252
4253				items.push({
4254					item: item,
4255					instance: targetData,
4256					width: 0, height: 0,
4257					left: 0, top: 0
4258				});
4259			};
4260		};
4261
4262	},
4263
4264	refreshPositions: function(fast) {
4265
4266		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4267		if(this.offsetParent && this.helper) {
4268			this.offset.parent = this._getParentOffset();
4269		}
4270
4271		for (var i = this.items.length - 1; i >= 0; i--){
4272			var item = this.items[i];
4273
4274			//We ignore calculating positions of all connected containers when we're not over them
4275			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
4276				continue;
4277
4278			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4279
4280			if (!fast) {
4281				item.width = t.outerWidth();
4282				item.height = t.outerHeight();
4283			}
4284
4285			var p = t.offset();
4286			item.left = p.left;
4287			item.top = p.top;
4288		};
4289
4290		if(this.options.custom && this.options.custom.refreshContainers
4290) {
4291			this.options.custom.refreshContainers.call(this);
4292		} else {
4293			for (var i = this.containers.length - 1; i >= 0; i--){
4294				var p = this.containers[i].element.offset();
4295				this.containers[i].containerCache.left = p.left;
4296				this.containers[i].containerCache.top = p.top;
4297				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
4298				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4299			};
4300		}
4301
4302		return this;
4303	},
4304
4305	_createPlaceholder: function(that) {
4306		that = that || this;
4307		var o = that.options;
4308
4309		if(!o.placeholder || o.placeholder.constructor == String) {
4310			var className = o.placeholder;
4311			o.placeholder = {
4312				element: function() {
4313
4314					var el = $(document.createElement(that.currentItem[0].nodeName))
4315						.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4316						.removeClass("ui-sortable-helper")[0];
4317
4318					if(!className)
4319						el.style.visibility = "hidden";
4320
4321					return el;
4322				},
4323				update: function(container, p) {
4324
4325					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4326					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4327					if(className && !o.forcePlaceholderSize) return;
4328
4329					//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
4330					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
4331					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
4332				}
4333			};
4334		}
4335
4336		//Create the placeholder
4337		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4338
4339		//Append it after the actual current item
4340		that.currentItem.after(that.placeholder);
4341
4342		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4343		o.placeholder.update(that, that.placeholder);
4344
4345	},
4346
4347	_contactContainers: function(event) {
4348
4349		// get innermost container that intersects with item
4350		var innermostContainer = null, innermostIndex = null;
4351
4352
4353		for (var i = this.containers.length - 1; i >= 0; i--){
4354
4355			// never consider a container that's located within the item itself
4356			if($.contains(this.currentItem[0], this.containers[i].element[0]))
4357				continue;
4358
4359			if(this._intersectsWith(this.containers[i].containerCache)) {
4360
4361				// if we've already found a container and it's more "inner" than this, then continue
4362				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
4363					continue;
4364
4365				innermostContainer = this.containers[i];
4366				innermostIndex = i;
4367
4368			} else {
4369				// container doesn't intersect. trigger "out" event if necessary
4370				if(this.containers[i].containerCache.over) {
4371					this.containers[i]._trigger("out", event, this._uiHash(this));
4372					this.containers[i].containerCache.over = 0;
4373				}
4374			}
4375
4376		}
4377
4378		// if no intersecting containers found, return
4379		if(!innermostContainer) return;
4380
4381		// move the item into the container if it's not there already
4382		if(this.containers.length === 1) {
4383			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4384			this.containers[innermostIndex].containerCache.over = 1;
4385		} else {
4386
4387			//When entering a new container, we will find the item with the least distance and append our item near it
4388			var dist = 10000; var itemWithLeastDistance = null;
4389			var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
4390			var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
4391			var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4392			for (var j = this.items.length - 1; j >= 0; j--) {
4393				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
4394				if(this.items[j].item[0] == this.currentItem[0]) continue;
4395				var cur = this.items[j].item.offset()[posProperty];
4396				var nearBottom = false;
4397				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4398					nearBottom = true;
4399					cur += this.items[j][sizeProperty];
4400				}
4401
4402				if(Math.abs(cur - base) < dist) {
4403					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4404					this.direction = nearBottom ? "up": "down";
4405				}
4406			}
4407
4408			if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
4409				return;
4410
4411			this.currentContainer = this.containers[innermostIndex];
4412			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4413			this._trigger("change", event, this._uiHash());
4414			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4415
4416			//Update the placeholder
4417			this.options.placeholder.update(this.currentContainer, this.placeholder);
4418
4419			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4420			this.containers[innermostIndex].containerCache.over = 1;
4421		}
4422
4423
4424	},
4425
4426	_createHelper: function(event) {
4427
4428		var o = this.options;
4429		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
4430
4431		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
4432			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4433
4434		if(helper[0] == this.currentItem[0])
4435			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
4435: this.currentItem.css("left") };
4436
4437		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
4438		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
4439
4440		return helper;
4441
4442	},
4443
4444	_adjustOffsetFromHelper: function(obj) {
4445		if (typeof obj == 'string') {
4446			obj = obj.split(' ');
4447		}
4448		if ($.isArray(obj)) {
4449			obj = {left: +obj[0], top: +obj[1] || 0};
4450		}
4451		if ('left' in obj) {
4452			this.offset.click.left = obj.left + this.margins.left;
4453		}
4454		if ('right' in obj) {
4455			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4456		}
4457		if ('top' in obj) {
4458			this.offset.click.top = obj.top + this.margins.top;
4459		}
4460		if ('bottom' in obj) {
4461			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4462		}
4463	},
4464
4465	_getParentOffset: function() {
4466
4467
4468		//Get the offsetParent and cache its position
4469		this.offsetParent = this.helper.offsetParent();
4470		var po = this.offsetParent.offset();
4471
4472		// This is a special case where we need to modify a offset calculated on start, since the following happened:
4473		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4474		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4475		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4476		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4477			po.left += this.scrollParent.scrollLeft();
4478			po.top += this.scrollParent.scrollTop();
4479		}
4480
4481		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4482		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
4483			po = { top: 0, left: 0 };
4484
4485		return {
4486			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4487			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4488		};
4489
4490	},
4491
4492	_getRelativeOffset: function() {
4493
4494		if(this.cssPosition == "relative") {
4495			var p = this.currentItem.position();
4496			return {
4497				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4498				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4499			};
4500		} else {
4501			return { top: 0, left: 0 };
4502		}
4503
4504	},
4505
4506	_cacheMargins: function() {
4507		this.margins = {
4508			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4509			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4510		};
4511	},
4512
4513	_cacheHelperProportions: function() {
4514		this.helperProportions = {
4515			width: this.helper.outerWidth(),
4516			height: this.helper.outerHeight()
4517		};
4518	},
4519
4520	_setContainment: function() {
4521
4522		var o = this.options;
4523		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4524		if(o.containment == 'document' || o.containment == 'window') this.containment = [
4525			0 - this.offset.relative.left - this.offset.parent.left,
4526			0 - this.offset.relative.top - this.offset.parent.top,
4527			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4528			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4529		];
4530
4531		if(!(/^(document|window|parent)$/).test(o.containment)) {
4532			var ce = $(o.containment)[0];
4533			var co = $(o.containment).offset();
4534			var over = ($(ce).css("overflow") != 'hidden');
4535
4536			this.containment = [
4537				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4538				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4539				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,
4540				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
454010) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4541			];
4542		}
4543
4544	},
4545
4546	_convertPositionTo: function(d, pos) {
4547
4548		if(!pos) pos = this.position;
4549		var mod = d == "absolute" ? 1 : -1;
4550		var o = this.options, 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);
4551
4552		return {
4553			top: (
4554				pos.top																	// The absolute mouse position
4555				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4556				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
4557				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4558			),
4559			left: (
4560				pos.left																// The absolute mouse position
4561				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4562				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
4563				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4564			)
4565		};
4566
4567	},
4568
4569	_generatePosition: function(event) {
4570
4571		var o = this.options, 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);
4572
4573		// This is another very weird special case that only happens for relative elements:
4574		// 1. If the css position is relative
4575		// 2. and the scroll parent is the document or similar to the offset parent
4576		// we have to refresh the relative offset during the scroll so there are no jumps
4577		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4578			this.offset.relative = this._getRelativeOffset();
4579		}
4580
4581		var pageX = event.pageX;
4582		var pageY = event.pageY;
4583
4584		/*
4585		 * - Position constraining -
4586		 * Constrain the position to a mix of grid, containment.
4587		 */
4588
4589		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4590
4591			if(this.containment) {
4592				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4593				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4594				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4595				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4596			}
4597
4598			if(o.grid) {
4599				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4600				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;
4601
4602				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4603				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;
4604			}
4605
4606		}
4607
4608		return {
4609			top: (
4610				pageY																// The absolute mouse position
4611				- this.offset.click.top													// Click offset (relative to the element)
4612				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
4613				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
4614				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4615			),
4616			left: (
4617				pageX																// The absolute mouse position
4618				- this.offset.click.left												// Click offset (relative to the element)
4619				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
4620				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
4621				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4622			)
4623		};
4624
4625	},
4626
4627	_rearrange: function(event, i, a, hardRefresh) {
4628
4629		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));
4630
4631		//Various things done here to improve the performance:
4632		// 1. we create a setTimeout, that calls refreshPositions
4633		// 2. on the instance, we have a counter variable, that get's higher after every append
4634		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4635		// 4. this lets only the last addition to the timeout stack through
4636		this.counter = this.counter ? ++this.counter : 1;
4637		var counter = this.counter;
4638
4639		this._delay(function() {
4640			if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4641		});
4642
4643	},
4644
4645	_clear: function(event, noPropagation) {
4646
4647		this.reverting = false;
4648		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
4649		// everything else normalized again
4650		var delayedTriggers = [];
4651
4652		// We first have to update the dom position of the actual currentItem
4653		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4654		if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4655		this._noFinalSort = null;
4656
4657		if(this.helper[0] == this.currentItem[0]) {
4658			for(var i in this._storedCSS) {
4659				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4660			}
4661			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4662		} else {
4663			this.currentItem.show();
4664		}
4665
4666		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4667		if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4668
4669		// Check if the items Container has Changed and trigger appropriate
4670		// events.
4671		if (this !== this.currentContainer) {
4672			if(!noPropagation) {
4673				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4674				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4675				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4676			}
4677		}
4678
4679
4680		//Post events to containers
4681		for (var i = this.containers.length - 1; i >= 0; i--){
4682			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4683			if(this.containers[i].containerCache.over) {
4684				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4685				this.containers[i].containerCache.over = 0;
4686			}
4687		}
4688
4689		//Do what was originally in plugins
4690		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4691		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4692		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4693
4694		this.dragging = false;
4695		if(this.cancelHelperRemoval) {
4696			if(!noPropagation) {
4697				this._trigger("beforeStop", event, this._uiHash());
4698				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4699				this._trigger("stop", event, this._uiHash());
4700			}
4701
4702			this.fromOutside = false;
4703			return false;
4704		}
4705
4706		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4707
4708		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4709		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4710
4711		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4712
4713		if(!noPropagation) {
4714			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4715			this._trigger("stop", event, this._uiHash());
4716		}
4717
4718		this.fromOutside = false;
4719		return true;
4720
4721	},
4722
4723	_trigger: function() {
4724		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4725			this.cancel();
4726		}
4727	},
4728
4729	_uiHash: function(_inst) {
4730		var inst = _inst || this;
4731		return {
4732			helper: inst.helper,
4733			placeholder: inst.placeholder || $([]),
4734			position: inst.position,
4735			originalPosition: inst.originalPosition,
4736			offset: inst.positionAbs,
4737			item: inst.currentItem,
4738			sender: _inst ? _inst.element : null
4739		};
4740	}
4741
4742});
4743
4744})(jQuery);
4745(function( $, undefined ) {
4746
4747$.extend($.ui, { datepicker: { version: "1.9.2" } });
4748
4749var PROP_NAME = 'datepicker';
4750var dpuuid = new Date().getTime();
4751var instActive;
4752
4753/* Date picker manager.
4754   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
4755   Settings for (groups of) date pickers are maintained in an instance object,
4756   allowing multiple different settings on the same page. */
4757
4758function Datepicker() {
4759	this.debug = false; // Change this to true to start debugging
4760	this._curInst = null; // The current instance in use
4761	this._keyEvent = false; // If the last event was a key event
4762	this._disabledInputs = []; // List of date picker inputs that have been disabled
4763	this._datepickerShowing = false; // True if the popup picker is showing , false if not
4764	this._inDialog = false; // True if showing within a "dialog", false if not
4765	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
4766	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
4767	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
4768	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
4769	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
4770	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
4771	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
4772	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
4773	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
4774	this.regional = []; // Available regional settings, indexed by language code
4775	this.regional[''] = { // Default regional settings
4776		closeText: 'Done', // Display text for close link
4777		prevText: 'Prev', // Display text for previous month link
4778		nextText: 'Next', // Display text for next month link
4779		currentText: 'Today', // Display text for current month link
4780		monthNames: ['January','February','March','April','May','June',
4781			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
4782		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
4783		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
4784		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
4785		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
4786		weekHeader: 'Wk', // Column header for week of the year
4787		dateFormat: 'mm/dd/yy', // See format options on parseDate
4788		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
4789		isRTL: false, // True if right-to-left language, false if left-to-right
4790		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
4791		yearSuffix: '' // Additional text to append to the year in the month headers
4792	};
4793	this._defaults = { // Global defaults for all the date picker instances
4794		showOn: 'focus', // 'focus' for popup on focus,
4795			// 'button' for trigger button, or 'both' for either
vendor: 4,836 bytes, lines 4796-4882
4796		showAnim: 'fadeIn', // Name of jQuery animation for popup
4797		showOptions: {}, // Options for enhanced animations
4798		defaultDate: null, // Used when field is blank: actual date,
4799			// +/-number for offset from today, null for today
4800		appendText: '', // Display text following the input box, e.g. showing the format
4801		buttonText: '...', // Text for trigger button
4802		buttonImage: '', // URL for trigger button image
4803		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
4804		hideIfNoPrevNext: false, // True to hide next/previous month links
4805			// if not applicable, false to just disable them
4806		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
4807		gotoCurrent: false, // True if today link goes back to current selection instead
4808		changeMonth: false, // True if month can be selected directly, false if only prev/next
4809		changeYear: false, // True if year can be selected directly, false if only prev/next
4810		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
4811			// either relative to today's year (-nn:+nn), relative to currently displayed year
4812			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
4813		showOtherMonths: false, // True to show dates in other months, false to leave blank
4814		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
4815		showWeek: false, // True to show week of the year, false to not show it
4816		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
4817			// takes a Date and returns the number of the week for it
4818		shortYearCutoff: '+10', // Short year values < this are in the current century,
4819			// > this are in the previous century,
4820			// string value starting with '+' for current year + value
4821		minDate: null, // The earliest selectable date, or null for no limit
4822		maxDate: null, // The latest selectable date, or null for no limit
4823		duration: 'fast', // Duration of display/closure
4824		beforeShowDay: null, // Function that takes a date and returns an array with
4825			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
4826			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
4827		beforeShow: null, // Function that takes an input field and
4828			// returns a set of custom settings for the date picker
4829		onSelect: null, // Define a callback function when a date is selected
4830		onChangeMonthYear: null, // Define a callback function when the month or year is changed
4831		onClose: null, // Define a callback function when the datepicker is closed
4832		numberOfMonths: 1, // Number of months to show at a time
4833		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
4834		stepMonths: 1, // Number of months to step back/forward
4835		stepBigMonths: 12, // Number of months to step back/forward for the big links
4836		altField: '', // Selector for an alternate field to store selected dates into
4837		altFormat: '', // The date format to use for the alternate field
4838		constrainInput: true, // The input is constrained by the current date format
4839		showButtonPanel: false, // True to show button panel, false to not show it
4840		autoSize: false, // True to size the input for the date format, false to leave as is
4841		disabled: false // The initial disabled state
4842	};
4843	$.extend(this._defaults, this.regional['']);
4844	this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
4845}
4846
4847$.extend(Datepicker.prototype, {
4848	/* Class name added to elements to indicate already configured with a date picker. */
4849	markerClassName: 'hasDatepicker',
4850
4851	//Keep track of the maximum number of rows displayed (see #7043)
4852	maxRows: 4,
4853
4854	/* Debug logging (if enabled). */
4855	log: function () {
4856		if (this.debug)
4857			console.log.apply('', arguments);
4858	},
4859
4860	// TODO rename to "widget" when switching to widget factory
4861	_widgetDatepicker: function() {
4862		return this.dpDiv;
4863	},
4864
4865	/* Override the default settings for all instances of the date picker.
4866	   @param  settings  object - the new settings to use as defaults (anonymous object)
4867	   @return the manager object */
4868	setDefaults: function(settings) {
4869		extendRemove(this._defaults, settings || {});
4870		return this;
4871	},
4872
4873	/* Attach the date picker to a jQuery selection.
4874	   @param  target    element - the target input field or division or span
4875	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
4876	_attachDatepicker: function(target, settings) {
4877		// check for settings on the control itself - in namespace 'date:'
4878		var inlineSettings = null;
4879		for (var attrName in this._defaults) {
4880			var attrValue = target.getAttribute('date:' + attrName);
4881			if (attrValue) {
4882				inlineSettings = inlineSettings || {};
4883				try {
4884					inlineSettings[attrName] = eval(attrValue);
4885				} catch (err) {
4886					inlineSettings[attrName] = attrValue;
4887				}
4888			}
4889		}
4890		var nodeName = target.nodeName.toLowerCase();
4891		var inline = (nodeName == 'div' || nodeName == 'span');
4892		if (!target.id) {
4893			this.uuid += 1;
4894			target.id = 'dp' + this.uuid;
4895		}
4896		var inst = this._newInst($(target), inline);
4897		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
4898		if (nodeName == 'input') {
4899			this._connectDatepicker(target, inst);
4900		} else if (inline) {
4901			this._inlineDatepicker(target, inst);
4902		}
4903	},
4904
4905	/* Create a new instance object. */
4906	_newInst: function(target, inline) {
4907		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
4908		return {id: id, input: target, // associated target
4909			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
4910			drawMonth: 0, drawYear: 0, // month being drawn
4911			inline: inline, // is datepicker inline or not
4912			dpDiv: (!inline ? this.dpDiv : // presentation div
4913			bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
4914	},
4915
4916	/* Attach the date picker to an input field. */
4917	_connectDatepicker: function(target, inst) {
4918		var input = $(target);
4919		inst.append = $([]);
4920		inst.trigger = $([]);
4921		if (input.hasClass(this.markerClassName))
4922			return;
4923		this._attachments(input, inst);
4924		input.addClass(this.markerClassName).keydown(this._doKeyDown).
4925			keypress(this._doKeyPress).keyup(this._doKeyUp).
4926			bind("setData.datepicker", function(event, key, value) {
4927				inst.settings[key] = value;
4928			}).bind("getData.datepicker", function(event, key) {
4929				return this._get(inst, key);
4930			});
4931		this._autoSize(inst);
4932		$.data(target, PROP_NAME, inst);
4933		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
4934		if( inst.settings.disabled ) {
4935			this._disableDatepicker( target );
4936		}
4937	},
4938
4939	/* Make attachments based on settings. */
4940	_attachments: function(input, inst) {
4941		var appendText = this._get(inst, 'appendText');
4942		var isRTL = this._get(inst, 'isRTL');
4943		if (inst.append)
4944			inst.append.remove();
4945		if (appendText) {
4946			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
4947			input[isRTL ? 'before' : 'after'](inst.append);
4948		}
4949		input.unbind('focus', this._showDatepicker);
4950		if (inst.trigger)
4951			inst.trigger.remove();
4952		var showOn = this._get(inst, 'showOn');
4953		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
4954			input.focus(this._showDatepicker);
4955		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
4956			var buttonText = this._get(inst, 'buttonText');
4957			var buttonImage = this._get(inst, 'buttonImage');
4958			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
4959				$('<img/>').addClass(this._triggerClass).
4960					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
4961				$('<button type="button"></button>').addClass(this._triggerClass).
4962					html(buttonImage == '' ? buttonText : $('<img/>').attr(
4963					{ src:buttonImage, alt:buttonText, title:buttonText })));
4964			input[isRTL ? 'before' : 'after'](inst.trigger);
4965			inst.trigger.click(function() {
4966				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
4967					$.datepicker._hideDatepicker();
4968				else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
4969					$.datepicker._hideDatepicker();
4970					$.datepicker._showDatepicker(input[0]);
4971				} else
4972					$.datepicker._showDatepicker(input[0]);
4973				return false;
4974			});
4975		}
4976	},
4977
4978	/* Apply the maximum length for the date format. */
4979	_autoSize: function(inst) {
4980		if (this._get(inst, 'autoSize') && !inst.inline) {
4981			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
4982			var dateFormat = this._get(inst, 'dateFormat');
4983			if (dateFormat.match(/[DM]/)) {
4984				var findMax = function(names) {
4985					var max = 0;
4986					var maxI = 0;
4987					for (var i = 0; i < names.length; i++) {
4988						if (names[i].length > max) {
4989							max = names[i].length;
4990							maxI = i;
4991						}
4992					}
vendor: 4,711 bytes, lines 4993-5108
4993					return maxI;
4994				};
4995				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4996					'monthNames' : 'monthNamesShort'))));
4997				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4998					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
4999			}
5000			inst.input.attr('size', this._formatDate(inst, date).length);
5001		}
5002	},
5003
5004	/* Attach an inline date picker to a div. */
5005	_inlineDatepicker: function(target, inst) {
5006		var divSpan = $(target);
5007		if (divSpan.hasClass(this.markerClassName))
5008			return;
5009		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
5010			bind("setData.datepicker", function(event, key, value){
5011				inst.settings[key] = value;
5012			}).bind("getData.datepicker", function(event, key){
5013				return this._get(inst, key);
5014			});
5015		$.data(target, PROP_NAME, inst);
5016		this._setDate(inst, this._getDefaultDate(inst), true);
5017		this._updateDatepicker(inst);
5018		this._updateAlternate(inst);
5019		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
5020		if( inst.settings.disabled ) {
5021			this._disableDatepicker( target );
5022		}
5023		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
5024		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
5025		inst.dpDiv.css( "display", "block" );
5026	},
5027
5028	/* Pop-up the date picker in a "dialog" box.
5029	   @param  input     element - ignored
5030	   @param  date      string or Date - the initial date to display
5031	   @param  onSelect  function - the function to call when a date is selected
5032	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
5033	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
5034	                     event - with x/y coordinates or
5035	                     leave empty for default (screen centre)
5036	   @return the manager object */
5037	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
5038		var inst = this._dialogInst; // internal instance
5039		if (!inst) {
5040			this.uuid += 1;
5041			var id = 'dp' + this.uuid;
5042			this._dialogInput = $('<input type="text" id="' + id +
5043				'" style="position: absolute; top: -100px; width: 0px;"/>');
5044			this._dialogInput.keydown(this._doKeyDown);
5045			$('body').append(this._dialogInput);
5046			inst = this._dialogInst = this._newInst(this._dialogInput, false);
5047			inst.settings = {};
5048			$.data(this._dialogInput[0], PROP_NAME, inst);
5049		}
5050		extendRemove(inst.settings, settings || {});
5051		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
5052		this._dialogInput.val(date);
5053
5054		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
5055		if (!this._pos) {
5056			var browserWidth = document.documentElement.clientWidth;
5057			var browserHeight = document.documentElement.clientHeight;
5058			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
5059			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
5060			this._pos = // should use actual width/height below
5061				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
5062		}
5063
5064		// move input on screen for focus, but hidden behind dialog
5065		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
5066		inst.settings.onSelect = onSelect;
5067		this._inDialog = true;
5068		this.dpDiv.addClass(this._dialogClass);
5069		this._showDatepicker(this._dialogInput[0]);
5070		if ($.blockUI)
5071			$.blockUI(this.dpDiv);
5072		$.data(this._dialogInput[0], PROP_NAME, inst);
5073		return this;
5074	},
5075
5076	/* Detach a datepicker from its control.
5077	   @param  target    element - the target input field or division or span */
5078	_destroyDatepicker: function(target) {
5079		var $target = $(target);
5080		var inst = $.data(target, PROP_NAME);
5081		if (!$target.hasClass(this.markerClassName)) {
5082			return;
5083		}
5084		var nodeName = target.nodeName.toLowerCase();
5085		$.removeData(target, PROP_NAME);
5086		if (nodeName == 'input') {
5087			inst.append.remove();
5088			inst.trigger.remove();
5089			$target.removeClass(this.markerClassName).
5090				unbind('focus', this._showDatepicker).
5091				unbind('keydown', this._doKeyDown).
5092				unbind('keypress', this._doKeyPress).
5093				unbind('keyup', this._doKeyUp);
5094		} else if (nodeName == 'div' || nodeName == 'span')
5095			$target.removeClass(this.markerClassName).empty();
5096	},
5097
5098	/* Enable the date picker to a jQuery selection.
5099	   @param  target    element - the target input field or division or span */
5100	_enableDatepicker: function(target) {
5101		var $target = $(target);
5102		var inst = $.data(target, PROP_NAME);
5103		if (!$target.hasClass(this.markerClassName)) {
5104			return;
5105		}
5106		var nodeName = target.nodeName.toLowerCase();
5107		if (nodeName == 'input') {
5108			target.disabled = false;
5109			inst.trigger.filter('button').
5110				each(function() { this.disabled = false; }).end().
5111				filter('img').css({opacity: '1.0', cursor: ''});
5112		}
5113		else if (nodeName == 'div' || nodeName == 'span') {
5114			var inline = $target.children('.' + this._inlineClass);
5115			inline.children().removeClass('ui-state-disabled');
5116			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
5117				prop("disabled", false);
5118		}
5119		this._disabledInputs = $.map(this._disabledInputs,
5120			function(value) { return (value == target ? null : value); }); // delete entry
5121	},
5122
5123	/* Disable the date picker to a jQuery selection.
5124	   @param  target    element - the target input field or division or span */
5125	_disableDatepicker: function(target) {
5126		var $target = $(target);
5127		var inst = $.data(target, PROP_NAME);
5128		if (!$target.hasClass(this.markerClassName)) {
5129			return;
5130		}
5131		var nodeName = target.nodeName.toLowerCase();
5132		if (nodeName == 'input') {
5133			target.disabled = true;
5134			inst.trigger.filter('button').
5135				each(function() { this.disabled = true; }).end().
5136				filter('img').css({opacity: '0.5', cursor: 'default'});
5137		}
5138		else if (nodeName == 'div' || nodeName == 'span') {
5139			var inline = $target.children('.' + this._inlineClass);
5140			inline.children().addClass('ui-state-disabled');
5141			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
5142				prop("disabled", true);
5143		}
5144		this._disabledInputs = $.map(this._disabledInputs,
5145			function(value) { return (value == target ? null : value); }); // delete entry
5146		this._disabledInputs[this._disabledInputs.length] = target;
5147	},
5148
5149	/* Is the first field in a jQuery collection disabled as a datepicker?
5150	   @param  target    element - the target input field or division or span
5151	   @return boolean - true if disabled, false if enabled */
5152	_isDisabledDatepicker: function(target) {
5153		if (!target) {
5154			return false;
5155		}
5156		for (var i = 0; i < this._disabledInputs.length; i++) {
5157			if (this._disabledInputs[i] == target)
5158				return true;
5159		}
5160		return false;
5161	},
5162
5163	/* Retrieve the instance data for the target control.
5164	   @param  target  element - the target input field or division or span
5165	   @return  object - the associated instance data
5166	   @throws  error if a jQuery problem getting data */
5167	_getInst: function(target) {
5168		try {
5169			return $.data(target, PROP_NAME);
5170		}
5171		catch (err) {
5172			throw 'Missing instance data for this datepicker';
5173		}
5174	},
5175
5176	/* Update or retrieve the settings for a date picker attached to an input field or division.
5177	   @param  target  element - the target input field or division or span
5178	   @param  name    object - the new settings to update or
5179	                   string - the name of the setting to change or retrieve,
5180	                   when retrieving also 'all' for all instance settings or
5181	                   'defaults' for all global defaults
5182	   @param  value   any - the new value for the setting
5183	                   (omit if above is an object or to retrieve a value) */
5184	_optionDatepicker: function(target, name, value) {
5185		var inst = this._getInst(target);
5186		if (arguments.length == 2 && typeof name == 'string') {
5187			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
5188				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
5189				this._get(inst, name)) : null));
5190		}
5191		var settings = name || {};
5192		if (typeof name == 'string') {
5193			settings = {};
5194			settings[name] = value;
5195		}
5196		if (inst) {
5197			if (this._curInst == inst) {
5198				this._hideDatepicker();
5199			}
5200			var date = this._getDateDatepicker(target, true);
5201			var minDate = this._getMinMaxDate(inst, 'min');
5202			var maxDate = this._getMinMaxDate(inst, 'max');
5203			extendRemove(inst.settings, settings);
5204			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
5205			if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
5206				inst.settings.minDate = this._formatDate(inst, minDate);
5207			if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
5208				inst.settings.maxDate = this._formatDate(inst, maxDate);
5209			this._attachments($(target), inst);
5210			this._autoSize(inst);
5211			this._setDate(inst, date);
5212			this._updateAlternate(inst);
5213			this._updateDatepicker(inst);
5214		}
5215	},
5216
5217	// change method deprecated
5218	_changeDatepicker: function(target, name, value) {
5219		this._optionDatepicker(target, name, value);
5220	},
5221
5222	/* Redraw the date picker attached to an input field or division.
5223	   @param  target  element - the target input field or division or span */
5224	_refreshDatepicker: function(target) {
5225		var inst = this._getInst(target);
5226		if (inst) {
5227			this._updateDatepicker(inst);
5228		}
5229	},
5230
5231	/* Set the dates for a jQuery selection.
5232	   @param  target   element - the target input field or division or span
5233	   @param  date     Date - the new date */
5234	_setDateDatepicker: function(target, date) {
5235		var inst = this._getInst(target);
5236		if (inst) {
5237			this._setDate(inst, date);
5238			this._updateDatepicker(inst);
5239			this._updateAlternate(inst);
5240		}
5241	},
5242
5243	/* Get the date(s) for the first entry in a jQuery selection.
5244	   @param  target     element - the target input field or division or span
5245	   @param  noDefault  boolean - true if no default date is to be used
5246	   @return Date - the current date */
5247	_getDateDatepicker: function(target, noDefault) {
5248		var inst = this._getInst(target);
5249		if (inst && !inst.inline)
5250			this._setDateFromField(inst, noDefault);
5251		return (inst ? this._getDate(inst) : null);
5252	},
5253
5254	/* Handle keystrokes. */
5255	_doKeyDown: function(event) {
5256		var inst = $.datepicker._getInst(event.target);
5257		var handled = true;
5258		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
5259		inst._keyEvent = true;
5260		if ($.datepicker._datepickerShowing)
5261			switch (event.keyCode) {
5262				case 9: $.datepicker._hideDatepicker();
5263						handled = false;
5264						break; // hide on tab out
5265				case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
5266									$.datepicker._currentClass + ')', inst.dpDiv);
5267						if (sel[0])
5268							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
5269							var onSelect = $.datepicker._get(inst, 'onSelect');
5270							if (onSelect) {
5271								var dateStr = $.datepicker._formatDate(inst);
5272
5273								// trigger custom callback
5274								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
5275							}
5276						else
5277							$.datepicker._hideDatepicker();
5278						return false; // don't submit the form
5279						break; // select the value on enter
5280				case 27: $.datepicker._hideDatepicker();
5281						break; // hide on escape
5282				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
5283							-$.datepicker._get(inst, 'stepBigMonths') :
5284							-$.datepicker._get(inst, 'stepMonths')), 'M');
5285						break; // previous month/year on page up/+ ctrl
5286				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
5287							+$.datepicker._get(inst, 'stepBigMonths') :
5288							+$.datepicker._get(inst, 'stepMonths')), 'M');
5289						break; // next month/year on page down/+ ctrl
5290				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
5291						handled = event.ctrlKey || event.metaKey;
5292						break; // clear on ctrl or command +end
5293				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
5294						handled = event.ctrlKey || event.metaKey;
5295						break; // current on ctrl or command +home
5296				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
5297						handled = event.ctrlKey || event.metaKey;
5298						// -1 day on ctrl or command +left
5299						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
5300									-$.datepicker._get(inst, 'stepBigMonths') :
5301									-$.datepicker._get(inst, 'stepMonths')), 'M');
5302						// next month/year on alt +left on Mac
5303						break;
5304				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
5305						handled = event.ctrlKey || event.metaKey;
5306						break; // -1 week on ctrl or command +up
5307				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
5308						handled = event.ctrlKey || event.metaKey;
5309						// +1 day on ctrl or command +right
5310						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
5311									+$.datepicker._get(inst, 'stepBigMonths') :
5312									+$.datepicker._get(inst, 'stepMonths')), 'M');
5313						// next month/year on alt +right
5314						break;
5315				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
5316						handled = event.ctrlKey || event.metaKey;
5317						break; // +1 week on ctrl or command +down
5318				default: handled = false;
5319			}
5320		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
5321			$.datepicker._showDatepicker(this);
5322		else {
5323			handled = false;
5324		}
5325		if (handled) {
5326			event.preventDefault();
5327			event.stopPropagation();
5328		}
5329	},
5330
5331	/* Filter entered characters - based on date format. */
5332	_doKeyPress: function(event) {
5333		var inst = $.datepicker._getInst(event.target);
5334		if ($.datepicker._get(inst, 'constrainInput')) {
5335			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
5336			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
5337			return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
5338		}
5339	},
5340
5341	/* Synchronise manual entry and field/alternate field. */
5342	_doKeyUp: function(event) {
5343		var inst = $.datepicker._getInst(event.target);
vendor: 8,608 bytes, lines 5344-5545
5344		if (inst.input.val() != inst.lastVal) {
5345			try {
5346				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
5347					(inst.input ? inst.input.val() : null),
5348					$.datepicker._getFormatConfig(inst));
5349				if (date) { // only if valid
5350					$.datepicker._setDateFromField(inst);
5351					$.datepicker._updateAlternate(inst);
5352					$.datepicker._updateDatepicker(inst);
5353				}
5354			}
5355			catch (err) {
5356				$.datepicker.log(err);
5357			}
5358		}
5359		return true;
5360	},
5361
5362	/* Pop-up the date picker for a given input field.
5363	   If false returned from beforeShow event handler do not show.
5364	   @param  input  element - the input field attached to the date picker or
5365	                  event - if triggered by focus */
5366	_showDatepicker: function(input) {
5367		input = input.target || input;
5368		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
5369			input = $('input', input.parentNode)[0];
5370		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
5371			return;
5372		var inst = $.datepicker._getInst(input);
5373		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
5374			$.datepicker._curInst.dpDiv.stop(true, true);
5375			if ( inst && $.datepicker._datepickerShowing ) {
5376				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
5377			}
5378		}
5379		var beforeShow = $.datepicker._get(inst, 'beforeShow');
5380		var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
5381		if(beforeShowSettings === false){
5382			//false
5383			return;
5384		}
5385		extendRemove(inst.settings, beforeShowSettings);
5386		inst.lastVal = null;
5387		$.datepicker._lastInput = input;
5388		$.datepicker._setDateFromField(inst);
5389		if ($.datepicker._inDialog) // hide cursor
5390			input.value = '';
5391		if (!$.datepicker._pos) { // position below input
5392			$.datepicker._pos = $.datepicker._findPos(input);
5393			$.datepicker._pos[1] += input.offsetHeight; // add the height
5394		}
5395		var isFixed = false;
5396		$(input).parents().each(function() {
5397			isFixed |= $(this).css('position') == 'fixed';
5398			return !isFixed;
5399		});
5400		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
5401		$.datepicker._pos = null;
5402		//to avoid flashes on Firefox
5403		inst.dpDiv.empty();
5404		// determine sizing offscreen
5405		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
5406		$.datepicker._updateDatepicker(inst);
5407		// fix width for dynamic number of date pickers
5408		// and adjust position before showing
5409		offset = $.datepicker._checkOffset(inst, offset, isFixed);
5410		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
5411			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
5412			left: offset.left + 'px', top: offset.top + 'px'});
5413		if (!inst.inline) {
5414			var showAnim = $.datepicker._get(inst, 'showAnim');
5415			var duration = $.datepicker._get(inst, 'duration');
5416			var postProcess = function() {
5417				var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
5418				if( !! cover.length ){
5419					var borders = $.datepicker._getBorders(inst.dpDiv);
5420					cover.css({left: -borders[0], top: -borders[1],
5421						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
5422				}
5423			};
5424			inst.dpDiv.zIndex($(input).zIndex()+1);
5425			$.datepicker._datepickerShowing = true;
5426
5427			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
5428			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
5429				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
5430			else
5431				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
5432			if (!showAnim || !duration)
5433				postProcess();
5434			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
5435				inst.input.focus();
5436			$.datepicker._curInst = inst;
5437		}
5438	},
5439
5440	/* Generate the date picker content. */
5441	_updateDatepicker: function(inst) {
5442		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
5443		var borders = $.datepicker._getBorders(inst.dpDiv);
5444		instActive = inst; // for delegate hover events
5445		inst.dpDiv.empty().append(this._generateHTML(inst));
5446		this._attachHandlers(inst);
5447		var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
5448		if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
5449			cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
5450		}
5451		inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
5452		var numMonths = this._getNumberOfMonths(inst);
5453		var cols = numMonths[1];
5454		var width = 17;
5455		inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
5456		if (cols > 1)
5457			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
5458		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
5459			'Class']('ui-datepicker-multi');
5460		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
5461			'Class']('ui-datepicker-rtl');
5462		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
5463				// #6694 - don't focus the input if it's already focused
5464				// this breaks the change event in IE
5465				inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
5466			inst.input.focus();
5467		// deffered render of the years select (to avoid flashes on Firefox)
5468		if( inst.yearshtml ){
5469			var origyearshtml = inst.yearshtml;
5470			setTimeout(function(){
5471				//assure that inst.yearshtml didn't change.
5472				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
5473					inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
5474				}
5475				origyearshtml = inst.yearshtml = null;
5476			}, 0);
5477		}
5478	},
5479
5480	/* Retrieve the size of left and top borders for an element.
5481	   @param  elem  (jQuery object) the element of interest
5482	   @return  (number[2]) the left and top borders */
5483	_getBorders: function(elem) {
5484		var convert = function(value) {
5485			return {thin: 1, medium: 2, thick: 3}[value] || value;
5486		};
5487		return [parseFloat(convert(elem.css('border-left-width'))),
5488			parseFloat(convert(elem.css('border-top-width')))];
5489	},
5490
5491	/* Check positioning to remain on screen. */
5492	_checkOffset: function(inst, offset, isFixed) {
5493		var dpWidth = inst.dpDiv.outerWidth();
5494		var dpHeight = inst.dpDiv.outerHeight();
5495		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
5496		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
5497		var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
5498		var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
5499
5500		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
5501		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
5502		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
5503
5504		// now check if datepicker is showing outside window viewport - move to a better place if so.
5505		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
5506			Math.abs(offset.left + dpWidth - viewWidth) : 0);
5507		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
5508			Math.abs(dpHeight + inputHeight) : 0);
5509
5510		return offset;
5511	},
5512
5513	/* Find an object's position on the screen. */
5514	_findPos: function(obj) {
5515		var inst = this._getInst(obj);
5516		var isRTL = this._get(inst, 'isRTL');
5517		while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
5518			obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
5519		}
5520		var position = $(obj).offset();
5521		return [position.left, position.top];
5522	},
5523
5524	/* Hide the date picker from view.
5525	   @param  input  element - the input field attached to the date picker */
5526	_hideDatepicker: function(input) {
5527		var inst = this._curInst;
5528		if (!inst || (input && inst != $.data(input, PROP_NAME)))
5529			return;
5530		if (this._datepickerShowing) {
5531			var showAnim = this._get(inst, 'showAnim');
5532			var duration = this._get(inst, 'duration');
5533			var postProcess = function() {
5534				$.datepicker._tidyDialog(inst);
5535			};
5536
5537			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
5538			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
5539				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
5540			else
5541				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
5542					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
5543			if (!showAnim)
5544				postProcess();
5545			this._datepickerShowing = false;
5546			var onClose = this._get(inst, 'onClose');
5547			if (onClose)
5548				onClose.apply((inst.input ? inst.input[0] : null),
5549					[(inst.input ? inst.input.val() : ''), inst]);
5550			this._lastInput = null;
5551			if (this._inDialog) {
5552				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
5553				if ($.blockUI) {
5554					$.unblockUI();
5555					$('body').append(this.dpDiv);
5556				}
5557			}
5558			this._inDialog = false;
5559		}
5560	},
5561
5562	/* Tidy up after a dialog display. */
5563	_tidyDialog: function(inst) {
5564		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
5565	},
5566
5567	/* Close date picker if clicked elsewhere. */
5568	_checkExternalClick: function(event) {
5569		if (!$.datepicker._curInst)
5570			return;
5571
5572		var $target = $(event.target),
5573			inst = $.datepicker._getInst($target[0]);
5574
5575		if ( ( ( $target[0].id != $.datepicker._mainDivId &&
5576				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
5577				!$target.hasClass($.datepicker.markerClassName) &&
5578				!$target.closest("." + $.datepicker._triggerClass).length &&
5579				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
5580			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
5581			$.datepicker._hideDatepicker();
5582	},
5583
5584	/* Adjust one of the date sub-fields. */
5585	_adjustDate: function(id, offset, period) {
5586		var target = $(id);
5587		var inst = this._getInst(target[0]);
5588		if (this._isDisabledDatepicker(target[0])) {
5589			return;
5590		}
5591		this._adjustInstDate(inst, offset +
5592			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
5593			period);
5594		this._updateDatepicker(inst);
5595	},
5596
5597	/* Action for current link. */
5598	_gotoToday: function(id) {
5599		var target = $(id);
5600		var inst = this._getInst(target[0]);
5601		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
5602			inst.selectedDay = inst.currentDay;
5603			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
5604			inst.drawYear = inst.selectedYear = inst.currentYear;
5605		}
5606		else {
5607			var date = new Date();
5608			inst.selectedDay = date.getDate();
5609			inst.drawMonth = inst.selectedMonth = date.getMonth();
5610			inst.drawYear = inst.selectedYear = date.getFullYear();
5611		}
5612		this._notifyChange(inst);
5613		this._adjustDate(target);
5614	},
5615
5616	/* Action for selecting a new month/year. */
5617	_selectMonthYear: function(id, select, period) {
5618		var target = $(id);
5619		var inst = this._getInst(target[0]);
5620		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
5621		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
5622			parseInt(select.options[select.selectedIndex].value,10);
5623		this._notifyChange(inst);
5624		this._adjustDate(target);
5625	},
5626
5627	/* Action for selecting a day. */
5628	_selectDay: function(id, month, year, td) {
5629		var target = $(id);
5630		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
5631			return;
5632		}
5633		var inst = this._getInst(target[0]);
5634		inst.selectedDay = inst.currentDay = $('a', td).html();
5635		inst.selectedMonth = inst.currentMonth = month;
5636		inst.selectedYear = inst.currentYear = year;
5637		this._selectDate(id, this._formatDate(inst,
5638			inst.currentDay, inst.currentMonth, inst.currentYear));
5639	},
5640
5641	/* Erase the input field and hide the date picker. */
5642	_clearDate: function(id) {
5643		var target = $(id);
5644		var inst = this._getInst(target[0]);
5645		this._selectDate(target, '');
5646	},
5647
5648	/* Update the input field with the selected date. */
5649	_selectDate: function(id, dateStr) {
5650		var target = $(id);
5651		var inst = this._getInst(target[0]);
5652		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
5653		if (inst.input)
5654			inst.input.val(dateStr);
5655		this._updateAlternate(inst);
5656		var onSelect = this._get(inst, 'onSelect');
5657		if (onSelect)
5658			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
5659		else if (inst.input)
5660			inst.input.trigger('change'); // fire the change event
5661		if (inst.inline)
5662			this._updateDatepicker(inst);
5663		else {
5664			this._hideDatepicker();
5665			this._lastInput = inst.input[0];
5666			if (typeof(inst.input[0]) != 'object')
5667				inst.input.focus(); // restore focus
5668			this._lastInput = null;
5669		}
5670	},
5671
5672	/* Update any alternate field to synchronise with the main field. */
5673	_updateAlternate: function(inst) {
5674		var altField = this._get(inst, 'altField');
5675		if (altField) { // update alternate field too
5676			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
5677			var date = this._getDate(inst);
5678			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
5679			$(altField).each(function() { $(this).val(dateStr); });
5680		}
5681	},
5682
5683	/* Set as beforeShowDay function to prevent selection of weekends.
5684	   @param  date  Date - the date to customise
5685	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
5686	noWeekends: function(date) {
5687		var day = date.getDay();
5688		return [(day > 0 && day < 6), ''];
5689	},
5690
5691	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
5692	   @param  date  Date - the date to get the week for
5693	   @return  number - the number of the week within the year that contains this date */
5694	iso8601Week: function(date) {
5695		var checkDate = new Date(date.getTime());
5696		// Find Thursday of this week starting on Monday
5697		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
5698		var time = checkDate.getTime();
5699		checkDate.setMonth(0); // Compare with Jan 1
5700		checkDate.setDate(1);
5701		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
5702	},
5703
5704	/* Parse a string value into a date object.
5705	   See formatDate below for the possible formats.
5706
vendor: 4,158 bytes, lines 5707-5815
5707	   @param  format    string - the expected format of the date
5708	   @param  value     string - the date in the above format
5709	   @param  settings  Object - attributes include:
5710	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
5711	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
5712	                     dayNames         string[7] - names of the days from Sunday (optional)
5713	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
5714	                     monthNames       string[12] - names of the months (optional)
5715	   @return  Date - the extracted date value or null if value is blank */
5716	parseDate: function (format, value, settings) {
5717		if (format == null || value == null)
5718			throw 'Invalid arguments';
5719		value = (typeof value == 'object' ? value.toString() : value + '');
5720		if (value == '')
5721			return null;
5722		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
5723		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
5724				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
5725		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
5726		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
5727		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
5728		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
5729		var year = -1;
5730		var month = -1;
5731		var day = -1;
5732		var doy = -1;
5733		var literal = false;
5734		// Check whether a format character is doubled
5735		var lookAhead = function(match) {
5736			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
5737			if (matches)
5738				iFormat++;
5739			return matches;
5740		};
5741		// Extract a number from the string value
5742		var getNumber = function(match) {
5743			var isDoubled = lookAhead(match);
5744			var size = (match == '@' ? 14 : (match == '!' ? 20 :
5745				(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
5746			var digits = new RegExp('^\\d{1,' + size + '}');
5747			var num = value.substring(iValue).match(digits);
5748			if (!num)
5749				throw 'Missing number at position ' + iValue;
5750			iValue += num[0].length;
5751			return parseInt(num[0], 10);
5752		};
5753		// Extract a name from the string value and convert to an index
5754		var getName = function(match, shortNames, longNames) {
5755			var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
5756				return [ [k, v] ];
5757			}).sort(function (a, b) {
5758				return -(a[1].length - b[1].length);
5759			});
5760			var index = -1;
5761			$.each(names, function (i, pair) {
5762				var name = pair[1];
5763				if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
5764					index = pair[0];
5765					iValue += name.length;
5766					return false;
5767				}
5768			});
5769			if (index != -1)
5770				return index + 1;
5771			else
5772				throw 'Unknown name at position ' + iValue;
5773		};
5774		// Confirm that a literal character matches the string value
5775		var checkLiteral = function() {
5776			if (value.charAt(iValue) != format.charAt(iFormat))
5777				throw 'Unexpected literal at position ' + iValue;
5778			iValue++;
5779		};
5780		var iValue = 0;
5781		for (var iFormat = 0; iFormat < format.length; iFormat++) {
5782			if (literal)
5783				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
5784					literal = false;
5785				else
5786					checkLiteral();
5787			else
5788				switch (format.charAt(iFormat)) {
5789					case 'd':
5790						day = getNumber('d');
5791						break;
5792					case 'D':
5793						getName('D', dayNamesShort, dayNames);
5794						break;
5795					case 'o':
5796						doy = getNumber('o');
5797						break;
5798					case 'm':
5799						month = getNumber('m');
5800						break;
5801					case 'M':
5802						month = getName('M', monthNamesShort, monthNames);
5803						break;
5804					case 'y':
5805						year = getNumber('y');
5806						break;
5807					case '@':
5808						var date = new Date(getNumber('@'));
5809						year = date.getFullYear();
5810						month = date.getMonth() + 1;
5811						day = date.getDate();
5812						break;
5813					case '!':
5814						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
5815						year = date.getFullYear();
5816						month = date.getMonth() + 1;
5817						day = date.getDate();
5818						break;
5819					case "'":
5820						if (lookAhead("'"))
5821							checkLiteral();
5822						else
5823							literal = true;
5824						break;
5825					default:
5826						checkLiteral();
5827				}
5828		}
5829		if (iValue < value.length){
5830			var extra = value.substr(iValue);
5831			if (!/^\s+/.test(extra)) {
5832				throw "Extra/unparsed characters found in date: " + extra;
5833			}
5834		}
5835		if (year == -1)
5836			year = new Date().getFullYear();
5837		else if (year < 100)
5838			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
5839				(year <= shortYearCutoff ? 0 : -100);
5840		if (doy > -1) {
5841			month = 1;
5842			day = doy;
5843			do {
5844				var dim = this._getDaysInMonth(year, month - 1);
5845				if (day <= dim)
5846					break;
5847				month++;
5848				day -= dim;
5849			} while (true);
5850		}
5851		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
5852		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
5853			throw 'Invalid date'; // E.g. 31/02/00
5854		return date;
5855	},
5856
5857	/* Standard date formats. */
5858	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
5859	COOKIE: 'D, dd M yy',
5860	ISO_8601: 'yy-mm-dd',
5861	RFC_822: 'D, d M y',
5862	RFC_850: 'DD, dd-M-y',
5863	RFC_1036: 'D, d M y',
5864	RFC_1123: 'D, d M yy',
5865	RFC_2822: 'D, d M yy',
5866	RSS: 'D, d M y', // RFC 822
5867	TICKS: '!',
5868	TIMESTAMP: '@',
5869	W3C: 'yy-mm-dd', // ISO 8601
5870
5871	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
5872		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5873
5874	/* Format a date object into a string value.
5875	   The format can be combinations of the following:
5876	   d  - day of month (no leading zero)
5877	   dd - day of month (two digit)
5878	   o  - day of year (no leading zeros)
5879	   oo - day of year (three digit)
5880	   D  - day name short
5881	   DD - day name long
5882	   m  - month of year (no leading zero)
5883	   mm - month of year (two digit)
5884	   M  - month name short
5885	   MM - month name long
5886	   y  - year (two digit)
5887	   yy - year (four digit)
5888	   @ - Unix timestamp (ms since 01/01/1970)
5889	   ! - Windows ticks (100ns since 01/01/0001)
5890	   '...' - literal text
5891	   '' - single quote
5892
5893	   @param  format    string - the desired format of the date
5894	   @param  date      Date - the date value to format
5895	   @param  settings  Object - attributes include:
5896	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
5897	                     dayNames         string[7] - names of the days from Sunday (optional)
5898	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
5899	                     monthNames       string[12] - names of the months (optional)
5900	   @return  string - the date in the above format */
5901	formatDate: function (format, date, settings) {
5902		if (!date)
5903			return '';
5904		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
5905		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
5906		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
5907		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
5908		// Check whether a format character is doubled
5909		var lookAhead = function(match) {
5910			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
5911			if (matches)
5912				iFormat++;
5913			return matches;
5914		};
5915		// Format a number, with leading zero if necessary
5916		var formatNumber = function(match, value, len) {
5917			var num = '' + value;
5918			if (lookAhead(match))
5919				while (num.length < len)
5920					num = '0' + num;
5921			return num;
5922		};
5923		// Format a name, short or long as requested
5924		var formatName = function(match, value, shortNames, longNames) {
5925			return (lookAhead(match) ? longNames[value] : shortNames[value]);
5926		};
5927		var output = '';
5928		var literal = false;
5929		if (date)
5930			for (var iFormat = 0; iFormat < format.length; iFormat++) {
5931				if (literal)
5932					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
5933						literal = false;
5934					else
5935						output += format.charAt(iFormat);
5936				else
5937					switch (format.charAt(iFormat)) {
5938						case 'd':
5939							output += formatNumber('d', date.getDate(), 2);
5940							break;
5941						case 'D':
5942							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
5943							break;
5944						case 'o':
5945							output += formatNumber('o',
5946								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5947							break;
5948						case 'm':
5949							output += formatNumber('m', date.getMonth() + 1, 2);
5950							break;
5951						case 'M':
5952							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
5953							break;
5954						case 'y':
5955							output += (lookAhead('y') ? date.getFullYear() :
5956								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
5957							break;
5958						case '@':
5959							output += date.getTime();
5960							break;
5961						case '!':
5962							output += date.getTime() * 10000 + this._ticksTo1970;
5963							break;
vendor: 5,981 bytes, lines 5964-6145
5964						case "'":
5965							if (lookAhead("'"))
5966								output += "'";
5967							else
5968								literal = true;
5969							break;
5970						default:
5971							output += format.charAt(iFormat);
5972					}
5973			}
5974		return output;
5975	},
5976
5977	/* Extract all possible characters from the date format. */
5978	_possibleChars: function (format) {
5979		var chars = '';
5980		var literal = false;
5981		// Check whether a format character is doubled
5982		var lookAhead = function(match) {
5983			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
5984			if (matches)
5985				iFormat++;
5986			return matches;
5987		};
5988		for (var iFormat = 0; iFormat < format.length; iFormat++)
5989			if (literal)
5990				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
5991					literal = false;
5992				else
5993					chars += format.charAt(iFormat);
5994			else
5995				switch (format.charAt(iFormat)) {
5996					case 'd': case 'm': case 'y': case '@':
5997						chars += '0123456789';
5998						break;
5999					case 'D': case 'M':
6000						return null; // Accept anything
6001					case "'":
6002						if (lookAhead("'"))
6003							chars += "'";
6004						else
6005							literal = true;
6006						break;
6007					default:
6008						chars += format.charAt(iFormat);
6009				}
6010		return chars;
6011	},
6012
6013	/* Get a setting value, defaulting if necessary. */
6014	_get: function(inst, name) {
6015		return inst.settings[name] !== undefined ?
6016			inst.settings[name] : this._defaults[name];
6017	},
6018
6019	/* Parse existing date and initialise date picker. */
6020	_setDateFromField: function(inst, noDefault) {
6021		if (inst.input.val() == inst.lastVal) {
6022			return;
6023		}
6024		var dateFormat = this._get(inst, 'dateFormat');
6025		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
6026		var date, defaultDate;
6027		date = defaultDate = this._getDefaultDate(inst);
6028		var settings = this._getFormatConfig(inst);
6029		try {
6030			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
6031		} catch (event) {
6032			this.log(event);
6033			dates = (noDefault ? '' : dates);
6034		}
6035		inst.selectedDay = date.getDate();
6036		inst.drawMonth = inst.selectedMonth = date.getMonth();
6037		inst.drawYear = inst.selectedYear = date.getFullYear();
6038		inst.currentDay = (dates ? date.getDate() : 0);
6039		inst.currentMonth = (dates ? date.getMonth() : 0);
6040		inst.currentYear = (dates ? date.getFullYear() : 0);
6041		this._adjustInstDate(inst);
6042	},
6043
6044	/* Retrieve the default date shown on opening. */
6045	_getDefaultDate: function(inst) {
6046		return this._restrictMinMax(inst,
6047			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
6048	},
6049
6050	/* A date may be specified as an exact value or a relative one. */
6051	_determineDate: function(inst, date, defaultDate) {
6052		var offsetNumeric = function(offset) {
6053			var date = new Date();
6054			date.setDate(date.getDate() + offset);
6055			return date;
6056		};
6057		var offsetString = function(offset) {
6058			try {
6059				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
6060					offset, $.datepicker._getFormatConfig(inst));
6061			}
6062			catch (e) {
6063				// Ignore
6064			}
6065			var date = (offset.toLowerCase().match(/^c/) ?
6066				$.datepicker._getDate(inst) : null) || new Date();
6067			var year = date.getFullYear();
6068			var month = date.getMonth();
6069			var day = date.getDate();
6070			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
6071			var matches = pattern.exec(offset);
6072			while (matches) {
6073				switch (matches[2] || 'd') {
6074					case 'd' : case 'D' :
6075						day += parseInt(matches[1],10); break;
6076					case 'w' : case 'W' :
6077						day += parseInt(matches[1],10) * 7; break;
6078					case 'm' : case 'M' :
6079						month += parseInt(matches[1],10);
6080						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
6081						break;
6082					case 'y': case 'Y' :
6083						year += parseInt(matches[1],10);
6084						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
6085						break;
6086				}
6087				matches = pattern.exec(offset);
6088			}
6089			return new Date(year, month, day);
6090		};
6091		var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
6092			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
6093		newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
6094		if (newDate) {
6095			newDate.setHours(0);
6096			newDate.setMinutes(0);
6097			newDate.setSeconds(0);
6098			newDate.setMilliseconds(0);
6099		}
6100		return this._daylightSavingAdjust(newDate);
6101	},
6102
6103	/* Handle switch to/from daylight saving.
6104	   Hours may be non-zero on daylight saving cut-over:
6105	   > 12 when midnight changeover, but then cannot generate
6106	   midnight datetime, so jump to 1AM, otherwise reset.
6107	   @param  date  (Date) the date to check
6108	   @return  (Date) the corrected date */
6109	_daylightSavingAdjust: function(date) {
6110		if (!date) return null;
6111		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
6112		return date;
6113	},
6114
6115	/* Set the date(s) directly. */
6116	_setDate: function(inst, date, noChange) {
6117		var clear = !date;
6118		var origMonth = inst.selectedMonth;
6119		var origYear = inst.selectedYear;
6120		var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
6121		inst.selectedDay = inst.currentDay = newDate.getDate();
6122		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
6123		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
6124		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
6125			this._notifyChange(inst);
6126		this._adjustInstDate(inst);
6127		if (inst.input) {
6128			inst.input.val(clear ? '' : this._formatDate(inst));
6129		}
6130	},
6131
6132	/* Retrieve the date(s) directly. */
6133	_getDate: function(inst) {
6134		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
6135			this._daylightSavingAdjust(new Date(
6136			inst.currentYear, inst.currentMonth, inst.currentDay)));
6137			return startDate;
6138	},
6139
6140	/* Attach the onxxx handlers.  These are declared statically so
6141	 * they work with static code transformers like Caja.
6142	 */
6143	_attachHandlers: function(inst) {
6144		var stepMonths = this._get(inst, 'stepMonths');
6145		var id = '#' + inst.id.replace( /\\\\/g, "\\" );
6146		inst.dpDiv.find('[data-handler]').map(function () {
6147			var handler = {
6148				prev: function () {
6149					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
6150				},
6151				next: function () {
6152					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
6153				},
6154				hide: function () {
6155					window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
6156				},
6157				today: function () {
6158					window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
6159				},
6160				selectDay: function () {
6161					window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
6162					return false;
6163				},
6164				selectMonth: function () {
6165					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
6166					return false;
6167				},
6168				selectYear: function () {
6169					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
6170					return false;
6171				}
6172			};
6173			$(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
6174		});
6175	},
6176
6177	/* Generate the HTML for the current state of the date picker. */
6178	_generateHTML: function(inst) {
6179		var today = new Date();
6180		today = this._daylightSavingAdjust(
6181			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
6182		var isRTL = this._get(inst, 'isRTL');
6183		var showButtonPanel = this._get(inst, 'showButtonPanel');
6184		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
6185		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
6186		var numMonths = this._getNumberOfMonths(inst);
6187		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
6188		var stepMonths = this._get(inst, 'stepMonths');
6189		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
6190		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
6191			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
6192		var minDate = this._getMinMaxDate(inst, 'min');
6193		var maxDate = this._getMinMaxDate(inst, 'max');
6194		var drawMonth = inst.drawMonth - showCurrentAtPos;
6195		var drawYear = inst.drawYear;
6196		if (drawMonth < 0) {
6197			drawMonth += 12;
6198			drawYear--;
6199		}
6200		if (maxDate) {
6201			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
6202				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
6203			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
6204			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
6205				drawMonth--;
6206				if (drawMonth < 0) {
6207					drawMonth = 11;
6208					drawYear--;
6209				}
6210			}
6211		}
6212		inst.drawMonth = drawMonth;
6213		inst.drawYear = drawYear;
6214		var prevText = this._get(inst, 'prevText');
6215		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
6216			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
6217			this._getFormatConfig(inst)));
6218		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
6219			'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
6220			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
6221			(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>'));
6222		var nextText = this._get(inst, 'nextText');
6223		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
6224			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
6225			this._getFormatConfig(inst)));
6226		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
6227			'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
6228			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
6229			(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>'));
6230		var currentText = this._get(inst, 'currentText');
6231		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
6232		currentText = (!navigationAsDateFormat ? currentText :
6233			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
6234		var 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">' +
6235			this._get(inst, 'closeText') + '</button>' : '');
6236		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
6237			(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"' +
6238			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
6239		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
6240		firstDay = (isNaN(firstDay) ? 0 : firstDay);
6241		var showWeek = this._get(inst, 'showWeek');
6242		var dayNames = this._get(inst, 'dayNames');
6243		var dayNamesShort = this._get(inst, 'dayNamesShort');
6244		var dayNamesMin = this._get(inst, 'dayNamesMin');
6245		var monthNames = this._get(inst, 'monthNames');
6246		var monthNamesShort = this._get(inst, 'monthNamesShort');
6247		var beforeShowDay = this._get(inst, 'beforeShowDay');
6248		var showOtherMonths = this._get(inst, 'showOtherMonths');
6249		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
6250		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
6251		var defaultDate = this._getDefaultDate(inst);
6252		var html = '';
6253		for (var row = 0; row < numMonths[0]; row++) {
6254			var group = '';
6255			this.maxRows = 4;
6256			for (var col = 0; col < numMonths[1]; col++) {
6257				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
6258				var cornerClass = ' ui-corner-all';
6259				var calender = '';
6260				if (isMultiMonth) {
6261					calender += '<div class="ui-datepicker-group';
6262					if (numMonths[1] > 1)
6263						switch (col) {
6264							case 0: calender += ' ui-datepicker-group-first';
6265								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
6266							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
6267								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
6268							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
6269						}
6270					calender += '">';
6271				}
6272				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
6273					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
6274					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
6275					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
6276					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
6277					'</div><table class="ui-datepicker-calendar"><thead>' +
6278					'<tr>';
6279				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
6280				for (var dow = 0; dow < 7; dow++) { // days of the week
6281					var day = (dow + firstDay) % 7;
6282					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
6282' +
6283						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
6284				}
6285				calender += thead + '</tr></thead><tbody>';
6286				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
6287				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
6288					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
6289				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
6290				var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
6291				var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
6292				this.maxRows = numRows;
6293				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
6294				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
6295					calender += '<tr>';
6296					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
6297						this._get(inst, 'calculateWeek')(printDate) + '</td>');
6298					for (var dow = 0; dow < 7; dow++) { // create date picker days
6299						var daySettings = (beforeShowDay ?
6300							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
6301						var otherMonth = (printDate.getMonth() != drawMonth);
6302						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
6303							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
6304						tbody += '<td class="' +
6305							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
6306							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
6307							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
6308							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
6309							// or defaultDate is current printedDate and defaultDate is selectedDate
6310							' ' + this._dayOverClass : '') + // highlight selected day
6311							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
6312							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
6313							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
6314							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
6315							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
6316							(unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
6317							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
6318							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
6319							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
6320							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
6321							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
6322							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
6323						printDate.setDate(printDate.getDate() + 1);
6324						printDate = this._daylightSavingAdjust(printDate);
6325					}
6326					calender += tbody + '</tr>';
6327				}
6328				drawMonth++;
6329				if (drawMonth > 11) {
6330					drawMonth = 0;
6331					drawYear++;
6332				}
6333				calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
6334							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
6335				group += calender;
6336			}
6337			html += group;
6338		}
6339		html += buttonPanel + ($.ui.ie6 && !inst.inline ?
6340			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
6341		inst._keyEvent = false;
6342		return html;
6343	},
6344
6345	/* Generate the month and year header. */
6346	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
6347			secondary, monthNames, monthNamesShort) {
6348		var changeMonth = this._get(inst, 'changeMonth');
6349		var changeYear = this._get(inst, 'changeYear');
6350		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
6351		var html = '<div class="ui-datepicker-title">';
6352		var monthHtml = '';
6353		// month selection
6354		if (secondary || !changeMonth)
6355			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
6356		else {
6357			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
6358			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
6359			monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
6360			for (var month = 0; month < 12; month++) {
6361				if ((!inMinYear || month >= minDate.getMonth()) &&
6362						(!inMaxYear || month <= maxDate.getMonth()))
6363					monthHtml += '<option value="' + month + '"' +
6364						(month == drawMonth ? ' selected="selected"' : '') +
6365						'>' + monthNamesShort[month] + '</option>';
6366			}
6367			monthHtml += '</select>';
6368		}
6369		if (!showMonthAfterYear)
6370			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
6371		// year selection
6372		if ( !inst.yearshtml ) {
6373			inst.yearshtml = '';
6374			if (secondary || !changeYear)
6375				html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
6376			else {
6377				// determine range of years to display
6378				var years = this._get(inst, 'yearRange').split(':');
6379				var thisYear = new Date().getFullYear();
6380				var determineYear = function(value) {
6381					var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
6382						(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
6383						parseInt(value, 10)));
6384					return (isNaN(year) ? thisYear : year);
6385				};
6386				var year = determineYear(years[0]);
6387				var endYear = Math.max(year, determineYear(years[1] || ''));
6388				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
6389				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
6390				inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
6391				for (; year <= endYear; year++) {
6392					inst.yearshtml += '<option value="' + year + '"' +
6393						(year == drawYear ? ' selected="selected"' : '') +
6394						'>' + year + '</option>';
6395				}
6396				inst.yearshtml += '</select>';
6397
6398				html += inst.yearshtml;
6399				inst.yearshtml = null;
6400			}
6401		}
6402		html += this._get(inst, 'yearSuffix');
6403		if (showMonthAfterYear)
6404			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
6405		html += '</div>'; // Close datepicker_header
6406		return html;
6407	},
6408
6409	/* Adjust one of the date sub-fields. */
6410	_adjustInstDate: function(inst, offset, period) {
6411		var year = inst.drawYear + (period == 'Y' ? offset : 0);
6412		var month = inst.drawMonth + (period == 'M' ? offset : 0);
6413		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
6414			(period == 'D' ? offset : 0);
6415		var date = this._restrictMinMax(inst,
6416			this._daylightSavingAdjust(new Date(year, month, day)));
6417		inst.selectedDay = date.getDate();
6418		inst.drawMonth = inst.selectedMonth = date.getMonth();
6419		inst.drawYear = inst.selectedYear = date.getFullYear();
6420		if (period == 'M' || period == 'Y')
6421			this._notifyChange(inst);
6422	},
6423
6424	/* Ensure a date is within any min/max bounds. */
6425	_restrictMinMax: function(inst, date) {
6426		var minDate = this._getMinMaxDate(inst, 'min');
6427		var maxDate = this._getMinMaxDate(inst, 'max');
6428		var newDate = (minDate && date < minDate ? minDate : date);
6429		newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
6430		return newDate;
6431	},
6432
6433	/* Notify change of month/year. */
6434	_notifyChange: function(inst) {
6435		var onChange = this._get(inst, 'onChangeMonthYear');
6436		if (onChange)
6437			onChange.apply((inst.input ? inst.input[0] : null),
6438				[inst.selectedYear, inst.selectedMonth + 1, inst]);
6439	},
6440
6441	/* Determine the number of months to show. */
6442	_getNumberOfMonths: function(inst) {
6443		var numMonths = this._get(inst, 'numberOfMonths');
6444		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
6445	},
6446
6447	/* Determine the current maximum date - ensure no time components are set. */
6448	_getMinMaxDate: function(inst, minMax) {
6449		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
6450	},
6451
6452	/* Find the number of days in a given month. */
6453	_getDaysInMonth: function(year, month) {
6454		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
6455	},
6456
6457	/* Find the day of the week of the first of a month. */
6458	_getFirstDayOfMonth: function(year, month) {
6459		return new Date(year, month, 1).getDay();
6460	},
6461
6462	/* Determines if we should allow a "next/prev" month display change. */
6463	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
6464		var numMonths = this._getNumberOfMonths(inst);
6465		var date = this._daylightSavingAdjust(new Date(curYear,
6466			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
6467		if (offset < 0)
6468			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
6469		return this._isInRange(inst, date);
6470	},
6471
6472	/* Is the given date in the accepted range? */
6473	_isInRange: function(inst, date) {
6474		var minDate = this._getMinMaxDate(inst, 'min');
6475		var maxDate = this._getMinMaxDate(inst, 'max');
6476		return ((!minDate || date.getTime() >= minDate.getTime()) &&
6477			(!maxDate || date.getTime() <= maxDate.getTime()));
6478	},
6479
6480	/* Provide the configuration settings for formatting/parsing. */
6481	_getFormatConfig: function(inst) {
6482		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
6483		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
6484			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
6485		return {shortYearCutoff: shortYearCutoff,
6486			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
6487			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
6488	},
6489
6490	/* Format the given date for display. */
6491	_formatDate: function(inst, day, month, year) {
6492		if (!day) {
6493			inst.currentDay = inst.selectedDay;
6494			inst.currentMonth = inst.selectedMonth;
6495			inst.currentYear = inst.selectedYear;
6496		}
6497		var date = (day ? (typeof day == 'object' ? day :
6498			this._daylightSavingAdjust(new Date(year, month, day))) :
6499			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
6500		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
6501	}
6502});
6503
6504/*
6505 * Bind hover events for datepicker elements.
6506 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
6507 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
6508 */
6509function bindHover(dpDiv) {
6510	var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
6511	return dpDiv.delegate(selector, 'mouseout', function() {
6512			$(this).removeClass('ui-state-hover');
6513			if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
6514			if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
6515		})
6516		.delegate(selector, 'mouseover', function(){
6517			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
6518				$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
6519				$(this).addClass('ui-state-hover');
6520				if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
6521				if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
6522			}
6523		});
6524}
6525
6526/* jQuery extend now ignores nulls! */
6527function extendRemove(target, props) {
6528	$.extend(target, props);
6529	for (var name in props)
6530		if (props[name] == null || props[name] == undefined)
6531			target[name] = props[name];
6532	return target;
6533};
6534
6535/* Invoke the datepicker functionality.
6536   @param  options  string - a command, optionally followed by additional parameters or
6537	                Object - settings for attaching new datepicker functionality
6538   @return  jQuery object */
6539$.fn.datepicker = function(options){
6540
6541	/* Verify an empty collection wasn't passed - Fixes #6976 */
6542	if ( !this.length ) {
6543		return this;
6544	}
6545
6546	/* Initialise the date picker. */
6547	if (!$.datepicker.initialized) {
6548		$(document).mousedown($.datepicker._checkExternalClick).
6549			find(document.body).append($.datepicker.dpDiv);
6550		$.datepicker.initialized = true;
6551	}
6552
6553	var otherArgs = Array.prototype.slice.call(arguments, 1);
6554	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
6555		return $.datepicker['_' + options + 'Datepicker'].
6556			apply($.datepicker, [this[0]].concat(otherArgs));
6557	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
6558		return $.datepicker['_' + options + 'Datepicker'].
6559			apply($.datepicker, [this[0]].concat(otherArgs));
6560	return this.each(function() {
6561		typeof options == 'string' ?
6562			$.datepicker['_' + options + 'Datepicker'].
6563				apply($.datepicker, [this].concat(otherArgs)) :
6564			$.datepicker._attachDatepicker(this, options);
6565	});
6566};
6567
6568$.datepicker = new Datepicker(); // singleton instance
6569$.datepicker.initialized = false;
6570$.datepicker.uuid = new Date().getTime();
6571$.datepicker.version = "1.9.2";
6572
6573// Workaround for #4055
6574// Add another global to avoid noConflict issues with inline event handlers
6575window['DP_jQuery_' + dpuuid] = $;
6576
6577})(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.