shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

jquery-ui.js (487207B)


      1 /*! jQuery UI - v1.11.4 - 2016-04-08
      2 * http://jqueryui.com
      3 * Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
      4 * Copyright jQuery Foundation and other contributors; Licensed MIT */
      5 
      6 (function( factory ) {
      7 	if ( typeof define === "function" && define.amd ) {
      8 
      9 		// AMD. Register as an anonymous module.
     10 		define([ "jquery" ], factory );
     11 	} else {
     12 
     13 		// Browser globals
     14 		factory( jQuery );
     15 	}
     16 }(function( $ ) {
     17 /*!
     18  * jQuery UI Core 1.11.4
     19  * http://jqueryui.com
     20  *
     21  * Copyright jQuery Foundation and other contributors
     22  * Released under the MIT license.
     23  * http://jquery.org/license
     24  *
     25  * http://api.jqueryui.com/category/ui-core/
     26  */
     27 
     28 
     29 // $.ui might exist from components with no dependencies, e.g., $.ui.position
     30 $.ui = $.ui || {};
     31 
     32 $.extend( $.ui, {
     33 	version: "1.11.4",
     34 
     35 	keyCode: {
     36 		BACKSPACE: 8,
     37 		COMMA: 188,
     38 		DELETE: 46,
     39 		DOWN: 40,
     40 		END: 35,
     41 		ENTER: 13,
     42 		ESCAPE: 27,
     43 		HOME: 36,
     44 		LEFT: 37,
     45 		PAGE_DOWN: 34,
     46 		PAGE_UP: 33,
     47 		PERIOD: 190,
     48 		RIGHT: 39,
     49 		SPACE: 32,
     50 		TAB: 9,
     51 		UP: 38
     52 	}
     53 });
     54 
     55 // plugins
     56 $.fn.extend({
     57 	scrollParent: function( includeHidden ) {
     58 		var position = this.css( "position" ),
     59 			excludeStaticParent = position === "absolute",
     60 			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
     61 			scrollParent = this.parents().filter( function() {
     62 				var parent = $( this );
     63 				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
     64 					return false;
     65 				}
     66 				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
     67 			}).eq( 0 );
     68 
     69 		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
     70 	},
     71 
     72 	uniqueId: (function() {
     73 		var uuid = 0;
     74 
     75 		return function() {
     76 			return this.each(function() {
     77 				if ( !this.id ) {
     78 					this.id = "ui-id-" + ( ++uuid );
     79 				}
     80 			});
     81 		};
     82 	})(),
     83 
     84 	removeUniqueId: function() {
     85 		return this.each(function() {
     86 			if ( /^ui-id-\d+$/.test( this.id ) ) {
     87 				$( this ).removeAttr( "id" );
     88 			}
     89 		});
     90 	}
     91 });
     92 
     93 // selectors
     94 function focusable( element, isTabIndexNotNaN ) {
     95 	var map, mapName, img,
     96 		nodeName = element.nodeName.toLowerCase();
     97 	if ( "area" === nodeName ) {
     98 		map = element.parentNode;
     99 		mapName = map.name;
    100 		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
    101 			return false;
    102 		}
    103 		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
    104 		return !!img && visible( img );
    105 	}
    106 	return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
    107 		!element.disabled :
    108 		"a" === nodeName ?
    109 			element.href || isTabIndexNotNaN :
    110 			isTabIndexNotNaN) &&
    111 		// the element and all of its ancestors must be visible
    112 		visible( element );
    113 }
    114 
    115 function visible( element ) {
    116 	return $.expr.filters.visible( element ) &&
    117 		!$( element ).parents().addBack().filter(function() {
    118 			return $.css( this, "visibility" ) === "hidden";
    119 		}).length;
    120 }
    121 
    122 $.extend( $.expr[ ":" ], {
    123 	data: $.expr.createPseudo ?
    124 		$.expr.createPseudo(function( dataName ) {
    125 			return function( elem ) {
    126 				return !!$.data( elem, dataName );
    127 			};
    128 		}) :
    129 		// support: jQuery <1.8
    130 		function( elem, i, match ) {
    131 			return !!$.data( elem, match[ 3 ] );
    132 		},
    133 
    134 	focusable: function( element ) {
    135 		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
    136 	},
    137 
    138 	tabbable: function( element ) {
    139 		var tabIndex = $.attr( element, "tabindex" ),
    140 			isTabIndexNaN = isNaN( tabIndex );
    141 		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
    142 	}
    143 });
    144 
    145 // support: jQuery <1.8
    146 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
    147 	$.each( [ "Width", "Height" ], function( i, name ) {
    148 		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
    149 			type = name.toLowerCase(),
    150 			orig = {
    151 				innerWidth: $.fn.innerWidth,
    152 				innerHeight: $.fn.innerHeight,
    153 				outerWidth: $.fn.outerWidth,
    154 				outerHeight: $.fn.outerHeight
    155 			};
    156 
    157 		function reduce( elem, size, border, margin ) {
    158 			$.each( side, function() {
    159 				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
    160 				if ( border ) {
    161 					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
    162 				}
    163 				if ( margin ) {
    164 					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
    165 				}
    166 			});
    167 			return size;
    168 		}
    169 
    170 		$.fn[ "inner" + name ] = function( size ) {
    171 			if ( size === undefined ) {
    172 				return orig[ "inner" + name ].call( this );
    173 			}
    174 
    175 			return this.each(function() {
    176 				$( this ).css( type, reduce( this, size ) + "px" );
    177 			});
    178 		};
    179 
    180 		$.fn[ "outer" + name] = function( size, margin ) {
    181 			if ( typeof size !== "number" ) {
    182 				return orig[ "outer" + name ].call( this, size );
    183 			}
    184 
    185 			return this.each(function() {
    186 				$( this).css( type, reduce( this, size, true, margin ) + "px" );
    187 			});
    188 		};
    189 	});
    190 }
    191 
    192 // support: jQuery <1.8
    193 if ( !$.fn.addBack ) {
    194 	$.fn.addBack = function( selector ) {
    195 		return this.add( selector == null ?
    196 			this.prevObject : this.prevObject.filter( selector )
    197 		);
    198 	};
    199 }
    200 
    201 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
    202 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
    203 	$.fn.removeData = (function( removeData ) {
    204 		return function( key ) {
    205 			if ( arguments.length ) {
    206 				return removeData.call( this, $.camelCase( key ) );
    207 			} else {
    208 				return removeData.call( this );
    209 			}
    210 		};
    211 	})( $.fn.removeData );
    212 }
    213 
    214 // deprecated
    215 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
    216 
    217 $.fn.extend({
    218 	focus: (function( orig ) {
    219 		return function( delay, fn ) {
    220 			return typeof delay === "number" ?
    221 				this.each(function() {
    222 					var elem = this;
    223 					setTimeout(function() {
    224 						$( elem ).focus();
    225 						if ( fn ) {
    226 							fn.call( elem );
    227 						}
    228 					}, delay );
    229 				}) :
    230 				orig.apply( this, arguments );
    231 		};
    232 	})( $.fn.focus ),
    233 
    234 	disableSelection: (function() {
    235 		var eventType = "onselectstart" in document.createElement( "div" ) ?
    236 			"selectstart" :
    237 			"mousedown";
    238 
    239 		return function() {
    240 			return this.bind( eventType + ".ui-disableSelection", function( event ) {
    241 				event.preventDefault();
    242 			});
    243 		};
    244 	})(),
    245 
    246 	enableSelection: function() {
    247 		return this.unbind( ".ui-disableSelection" );
    248 	},
    249 
    250 	zIndex: function( zIndex ) {
    251 		if ( zIndex !== undefined ) {
    252 			return this.css( "zIndex", zIndex );
    253 		}
    254 
    255 		if ( this.length ) {
    256 			var elem = $( this[ 0 ] ), position, value;
    257 			while ( elem.length && elem[ 0 ] !== document ) {
    258 				// Ignore z-index if position is set to a value where z-index is ignored by the browser
    259 				// This makes behavior of this function consistent across browsers
    260 				// WebKit always returns auto if the element is positioned
    261 				position = elem.css( "position" );
    262 				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
    263 					// IE returns 0 when zIndex is not specified
    264 					// other browsers return a string
    265 					// we ignore the case of nested elements with an explicit value of 0
    266 					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
    267 					value = parseInt( elem.css( "zIndex" ), 10 );
    268 					if ( !isNaN( value ) && value !== 0 ) {
    269 						return value;
    270 					}
    271 				}
    272 				elem = elem.parent();
    273 			}
    274 		}
    275 
    276 		return 0;
    277 	}
    278 });
    279 
    280 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
    281 $.ui.plugin = {
    282 	add: function( module, option, set ) {
    283 		var i,
    284 			proto = $.ui[ module ].prototype;
    285 		for ( i in set ) {
    286 			proto.plugins[ i ] = proto.plugins[ i ] || [];
    287 			proto.plugins[ i ].push( [ option, set[ i ] ] );
    288 		}
    289 	},
    290 	call: function( instance, name, args, allowDisconnected ) {
    291 		var i,
    292 			set = instance.plugins[ name ];
    293 
    294 		if ( !set ) {
    295 			return;
    296 		}
    297 
    298 		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
    299 			return;
    300 		}
    301 
    302 		for ( i = 0; i < set.length; i++ ) {
    303 			if ( instance.options[ set[ i ][ 0 ] ] ) {
    304 				set[ i ][ 1 ].apply( instance.element, args );
    305 			}
    306 		}
    307 	}
    308 };
    309 
    310 
    311 /*!
    312  * jQuery UI Widget 1.11.4
    313  * http://jqueryui.com
    314  *
    315  * Copyright jQuery Foundation and other contributors
    316  * Released under the MIT license.
    317  * http://jquery.org/license
    318  *
    319  * http://api.jqueryui.com/jQuery.widget/
    320  */
    321 
    322 
    323 var widget_uuid = 0,
    324 	widget_slice = Array.prototype.slice;
    325 
    326 $.cleanData = (function( orig ) {
    327 	return function( elems ) {
    328 		var events, elem, i;
    329 		for ( i = 0; (elem = elems[i]) != null; i++ ) {
    330 			try {
    331 
    332 				// Only trigger remove when necessary to save time
    333 				events = $._data( elem, "events" );
    334 				if ( events && events.remove ) {
    335 					$( elem ).triggerHandler( "remove" );
    336 				}
    337 
    338 			// http://bugs.jquery.com/ticket/8235
    339 			} catch ( e ) {}
    340 		}
    341 		orig( elems );
    342 	};
    343 })( $.cleanData );
    344 
    345 $.widget = function( name, base, prototype ) {
    346 	var fullName, existingConstructor, constructor, basePrototype,
    347 		// proxiedPrototype allows the provided prototype to remain unmodified
    348 		// so that it can be used as a mixin for multiple widgets (#8876)
    349 		proxiedPrototype = {},
    350 		namespace = name.split( "." )[ 0 ];
    351 
    352 	name = name.split( "." )[ 1 ];
    353 	fullName = namespace + "-" + name;
    354 
    355 	if ( !prototype ) {
    356 		prototype = base;
    357 		base = $.Widget;
    358 	}
    359 
    360 	// create selector for plugin
    361 	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
    362 		return !!$.data( elem, fullName );
    363 	};
    364 
    365 	$[ namespace ] = $[ namespace ] || {};
    366 	existingConstructor = $[ namespace ][ name ];
    367 	constructor = $[ namespace ][ name ] = function( options, element ) {
    368 		// allow instantiation without "new" keyword
    369 		if ( !this._createWidget ) {
    370 			return new constructor( options, element );
    371 		}
    372 
    373 		// allow instantiation without initializing for simple inheritance
    374 		// must use "new" keyword (the code above always passes args)
    375 		if ( arguments.length ) {
    376 			this._createWidget( options, element );
    377 		}
    378 	};
    379 	// extend with the existing constructor to carry over any static properties
    380 	$.extend( constructor, existingConstructor, {
    381 		version: prototype.version,
    382 		// copy the object used to create the prototype in case we need to
    383 		// redefine the widget later
    384 		_proto: $.extend( {}, prototype ),
    385 		// track widgets that inherit from this widget in case this widget is
    386 		// redefined after a widget inherits from it
    387 		_childConstructors: []
    388 	});
    389 
    390 	basePrototype = new base();
    391 	// we need to make the options hash a property directly on the new instance
    392 	// otherwise we'll modify the options hash on the prototype that we're
    393 	// inheriting from
    394 	basePrototype.options = $.widget.extend( {}, basePrototype.options );
    395 	$.each( prototype, function( prop, value ) {
    396 		if ( !$.isFunction( value ) ) {
    397 			proxiedPrototype[ prop ] = value;
    398 			return;
    399 		}
    400 		proxiedPrototype[ prop ] = (function() {
    401 			var _super = function() {
    402 					return base.prototype[ prop ].apply( this, arguments );
    403 				},
    404 				_superApply = function( args ) {
    405 					return base.prototype[ prop ].apply( this, args );
    406 				};
    407 			return function() {
    408 				var __super = this._super,
    409 					__superApply = this._superApply,
    410 					returnValue;
    411 
    412 				this._super = _super;
    413 				this._superApply = _superApply;
    414 
    415 				returnValue = value.apply( this, arguments );
    416 
    417 				this._super = __super;
    418 				this._superApply = __superApply;
    419 
    420 				return returnValue;
    421 			};
    422 		})();
    423 	});
    424 	constructor.prototype = $.widget.extend( basePrototype, {
    425 		// TODO: remove support for widgetEventPrefix
    426 		// always use the name + a colon as the prefix, e.g., draggable:start
    427 		// don't prefix for widgets that aren't DOM-based
    428 		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
    429 	}, proxiedPrototype, {
    430 		constructor: constructor,
    431 		namespace: namespace,
    432 		widgetName: name,
    433 		widgetFullName: fullName
    434 	});
    435 
    436 	// If this widget is being redefined then we need to find all widgets that
    437 	// are inheriting from it and redefine all of them so that they inherit from
    438 	// the new version of this widget. We're essentially trying to replace one
    439 	// level in the prototype chain.
    440 	if ( existingConstructor ) {
    441 		$.each( existingConstructor._childConstructors, function( i, child ) {
    442 			var childPrototype = child.prototype;
    443 
    444 			// redefine the child widget using the same prototype that was
    445 			// originally used, but inherit from the new version of the base
    446 			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
    447 		});
    448 		// remove the list of existing child constructors from the old constructor
    449 		// so the old child constructors can be garbage collected
    450 		delete existingConstructor._childConstructors;
    451 	} else {
    452 		base._childConstructors.push( constructor );
    453 	}
    454 
    455 	$.widget.bridge( name, constructor );
    456 
    457 	return constructor;
    458 };
    459 
    460 $.widget.extend = function( target ) {
    461 	var input = widget_slice.call( arguments, 1 ),
    462 		inputIndex = 0,
    463 		inputLength = input.length,
    464 		key,
    465 		value;
    466 	for ( ; inputIndex < inputLength; inputIndex++ ) {
    467 		for ( key in input[ inputIndex ] ) {
    468 			value = input[ inputIndex ][ key ];
    469 			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
    470 				// Clone objects
    471 				if ( $.isPlainObject( value ) ) {
    472 					target[ key ] = $.isPlainObject( target[ key ] ) ?
    473 						$.widget.extend( {}, target[ key ], value ) :
    474 						// Don't extend strings, arrays, etc. with objects
    475 						$.widget.extend( {}, value );
    476 				// Copy everything else by reference
    477 				} else {
    478 					target[ key ] = value;
    479 				}
    480 			}
    481 		}
    482 	}
    483 	return target;
    484 };
    485 
    486 $.widget.bridge = function( name, object ) {
    487 	var fullName = object.prototype.widgetFullName || name;
    488 	$.fn[ name ] = function( options ) {
    489 		var isMethodCall = typeof options === "string",
    490 			args = widget_slice.call( arguments, 1 ),
    491 			returnValue = this;
    492 
    493 		if ( isMethodCall ) {
    494 			this.each(function() {
    495 				var methodValue,
    496 					instance = $.data( this, fullName );
    497 				if ( options === "instance" ) {
    498 					returnValue = instance;
    499 					return false;
    500 				}
    501 				if ( !instance ) {
    502 					return $.error( "cannot call methods on " + name + " prior to initialization; " +
    503 						"attempted to call method '" + options + "'" );
    504 				}
    505 				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
    506 					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
    507 				}
    508 				methodValue = instance[ options ].apply( instance, args );
    509 				if ( methodValue !== instance && methodValue !== undefined ) {
    510 					returnValue = methodValue && methodValue.jquery ?
    511 						returnValue.pushStack( methodValue.get() ) :
    512 						methodValue;
    513 					return false;
    514 				}
    515 			});
    516 		} else {
    517 
    518 			// Allow multiple hashes to be passed on init
    519 			if ( args.length ) {
    520 				options = $.widget.extend.apply( null, [ options ].concat(args) );
    521 			}
    522 
    523 			this.each(function() {
    524 				var instance = $.data( this, fullName );
    525 				if ( instance ) {
    526 					instance.option( options || {} );
    527 					if ( instance._init ) {
    528 						instance._init();
    529 					}
    530 				} else {
    531 					$.data( this, fullName, new object( options, this ) );
    532 				}
    533 			});
    534 		}
    535 
    536 		return returnValue;
    537 	};
    538 };
    539 
    540 $.Widget = function( /* options, element */ ) {};
    541 $.Widget._childConstructors = [];
    542 
    543 $.Widget.prototype = {
    544 	widgetName: "widget",
    545 	widgetEventPrefix: "",
    546 	defaultElement: "<div>",
    547 	options: {
    548 		disabled: false,
    549 
    550 		// callbacks
    551 		create: null
    552 	},
    553 	_createWidget: function( options, element ) {
    554 		element = $( element || this.defaultElement || this )[ 0 ];
    555 		this.element = $( element );
    556 		this.uuid = widget_uuid++;
    557 		this.eventNamespace = "." + this.widgetName + this.uuid;
    558 
    559 		this.bindings = $();
    560 		this.hoverable = $();
    561 		this.focusable = $();
    562 
    563 		if ( element !== this ) {
    564 			$.data( element, this.widgetFullName, this );
    565 			this._on( true, this.element, {
    566 				remove: function( event ) {
    567 					if ( event.target === element ) {
    568 						this.destroy();
    569 					}
    570 				}
    571 			});
    572 			this.document = $( element.style ?
    573 				// element within the document
    574 				element.ownerDocument :
    575 				// element is window or document
    576 				element.document || element );
    577 			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
    578 		}
    579 
    580 		this.options = $.widget.extend( {},
    581 			this.options,
    582 			this._getCreateOptions(),
    583 			options );
    584 
    585 		this._create();
    586 		this._trigger( "create", null, this._getCreateEventData() );
    587 		this._init();
    588 	},
    589 	_getCreateOptions: $.noop,
    590 	_getCreateEventData: $.noop,
    591 	_create: $.noop,
    592 	_init: $.noop,
    593 
    594 	destroy: function() {
    595 		this._destroy();
    596 		// we can probably remove the unbind calls in 2.0
    597 		// all event bindings should go through this._on()
    598 		this.element
    599 			.unbind( this.eventNamespace )
    600 			.removeData( this.widgetFullName )
    601 			// support: jquery <1.6.3
    602 			// http://bugs.jquery.com/ticket/9413
    603 			.removeData( $.camelCase( this.widgetFullName ) );
    604 		this.widget()
    605 			.unbind( this.eventNamespace )
    606 			.removeAttr( "aria-disabled" )
    607 			.removeClass(
    608 				this.widgetFullName + "-disabled " +
    609 				"ui-state-disabled" );
    610 
    611 		// clean up events and states
    612 		this.bindings.unbind( this.eventNamespace );
    613 		this.hoverable.removeClass( "ui-state-hover" );
    614 		this.focusable.removeClass( "ui-state-focus" );
    615 	},
    616 	_destroy: $.noop,
    617 
    618 	widget: function() {
    619 		return this.element;
    620 	},
    621 
    622 	option: function( key, value ) {
    623 		var options = key,
    624 			parts,
    625 			curOption,
    626 			i;
    627 
    628 		if ( arguments.length === 0 ) {
    629 			// don't return a reference to the internal hash
    630 			return $.widget.extend( {}, this.options );
    631 		}
    632 
    633 		if ( typeof key === "string" ) {
    634 			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
    635 			options = {};
    636 			parts = key.split( "." );
    637 			key = parts.shift();
    638 			if ( parts.length ) {
    639 				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
    640 				for ( i = 0; i < parts.length - 1; i++ ) {
    641 					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
    642 					curOption = curOption[ parts[ i ] ];
    643 				}
    644 				key = parts.pop();
    645 				if ( arguments.length === 1 ) {
    646 					return curOption[ key ] === undefined ? null : curOption[ key ];
    647 				}
    648 				curOption[ key ] = value;
    649 			} else {
    650 				if ( arguments.length === 1 ) {
    651 					return this.options[ key ] === undefined ? null : this.options[ key ];
    652 				}
    653 				options[ key ] = value;
    654 			}
    655 		}
    656 
    657 		this._setOptions( options );
    658 
    659 		return this;
    660 	},
    661 	_setOptions: function( options ) {
    662 		var key;
    663 
    664 		for ( key in options ) {
    665 			this._setOption( key, options[ key ] );
    666 		}
    667 
    668 		return this;
    669 	},
    670 	_setOption: function( key, value ) {
    671 		this.options[ key ] = value;
    672 
    673 		if ( key === "disabled" ) {
    674 			this.widget()
    675 				.toggleClass( this.widgetFullName + "-disabled", !!value );
    676 
    677 			// If the widget is becoming disabled, then nothing is interactive
    678 			if ( value ) {
    679 				this.hoverable.removeClass( "ui-state-hover" );
    680 				this.focusable.removeClass( "ui-state-focus" );
    681 			}
    682 		}
    683 
    684 		return this;
    685 	},
    686 
    687 	enable: function() {
    688 		return this._setOptions({ disabled: false });
    689 	},
    690 	disable: function() {
    691 		return this._setOptions({ disabled: true });
    692 	},
    693 
    694 	_on: function( suppressDisabledCheck, element, handlers ) {
    695 		var delegateElement,
    696 			instance = this;
    697 
    698 		// no suppressDisabledCheck flag, shuffle arguments
    699 		if ( typeof suppressDisabledCheck !== "boolean" ) {
    700 			handlers = element;
    701 			element = suppressDisabledCheck;
    702 			suppressDisabledCheck = false;
    703 		}
    704 
    705 		// no element argument, shuffle and use this.element
    706 		if ( !handlers ) {
    707 			handlers = element;
    708 			element = this.element;
    709 			delegateElement = this.widget();
    710 		} else {
    711 			element = delegateElement = $( element );
    712 			this.bindings = this.bindings.add( element );
    713 		}
    714 
    715 		$.each( handlers, function( event, handler ) {
    716 			function handlerProxy() {
    717 				// allow widgets to customize the disabled handling
    718 				// - disabled as an array instead of boolean
    719 				// - disabled class as method for disabling individual parts
    720 				if ( !suppressDisabledCheck &&
    721 						( instance.options.disabled === true ||
    722 							$( this ).hasClass( "ui-state-disabled" ) ) ) {
    723 					return;
    724 				}
    725 				return ( typeof handler === "string" ? instance[ handler ] : handler )
    726 					.apply( instance, arguments );
    727 			}
    728 
    729 			// copy the guid so direct unbinding works
    730 			if ( typeof handler !== "string" ) {
    731 				handlerProxy.guid = handler.guid =
    732 					handler.guid || handlerProxy.guid || $.guid++;
    733 			}
    734 
    735 			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
    736 				eventName = match[1] + instance.eventNamespace,
    737 				selector = match[2];
    738 			if ( selector ) {
    739 				delegateElement.delegate( selector, eventName, handlerProxy );
    740 			} else {
    741 				element.bind( eventName, handlerProxy );
    742 			}
    743 		});
    744 	},
    745 
    746 	_off: function( element, eventName ) {
    747 		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
    748 			this.eventNamespace;
    749 		element.unbind( eventName ).undelegate( eventName );
    750 
    751 		// Clear the stack to avoid memory leaks (#10056)
    752 		this.bindings = $( this.bindings.not( element ).get() );
    753 		this.focusable = $( this.focusable.not( element ).get() );
    754 		this.hoverable = $( this.hoverable.not( element ).get() );
    755 	},
    756 
    757 	_delay: function( handler, delay ) {
    758 		function handlerProxy() {
    759 			return ( typeof handler === "string" ? instance[ handler ] : handler )
    760 				.apply( instance, arguments );
    761 		}
    762 		var instance = this;
    763 		return setTimeout( handlerProxy, delay || 0 );
    764 	},
    765 
    766 	_hoverable: function( element ) {
    767 		this.hoverable = this.hoverable.add( element );
    768 		this._on( element, {
    769 			mouseenter: function( event ) {
    770 				$( event.currentTarget ).addClass( "ui-state-hover" );
    771 			},
    772 			mouseleave: function( event ) {
    773 				$( event.currentTarget ).removeClass( "ui-state-hover" );
    774 			}
    775 		});
    776 	},
    777 
    778 	_focusable: function( element ) {
    779 		this.focusable = this.focusable.add( element );
    780 		this._on( element, {
    781 			focusin: function( event ) {
    782 				$( event.currentTarget ).addClass( "ui-state-focus" );
    783 			},
    784 			focusout: function( event ) {
    785 				$( event.currentTarget ).removeClass( "ui-state-focus" );
    786 			}
    787 		});
    788 	},
    789 
    790 	_trigger: function( type, event, data ) {
    791 		var prop, orig,
    792 			callback = this.options[ type ];
    793 
    794 		data = data || {};
    795 		event = $.Event( event );
    796 		event.type = ( type === this.widgetEventPrefix ?
    797 			type :
    798 			this.widgetEventPrefix + type ).toLowerCase();
    799 		// the original event may come from any element
    800 		// so we need to reset the target on the new event
    801 		event.target = this.element[ 0 ];
    802 
    803 		// copy original event properties over to the new event
    804 		orig = event.originalEvent;
    805 		if ( orig ) {
    806 			for ( prop in orig ) {
    807 				if ( !( prop in event ) ) {
    808 					event[ prop ] = orig[ prop ];
    809 				}
    810 			}
    811 		}
    812 
    813 		this.element.trigger( event, data );
    814 		return !( $.isFunction( callback ) &&
    815 			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
    816 			event.isDefaultPrevented() );
    817 	}
    818 };
    819 
    820 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
    821 	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
    822 		if ( typeof options === "string" ) {
    823 			options = { effect: options };
    824 		}
    825 		var hasOptions,
    826 			effectName = !options ?
    827 				method :
    828 				options === true || typeof options === "number" ?
    829 					defaultEffect :
    830 					options.effect || defaultEffect;
    831 		options = options || {};
    832 		if ( typeof options === "number" ) {
    833 			options = { duration: options };
    834 		}
    835 		hasOptions = !$.isEmptyObject( options );
    836 		options.complete = callback;
    837 		if ( options.delay ) {
    838 			element.delay( options.delay );
    839 		}
    840 		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
    841 			element[ method ]( options );
    842 		} else if ( effectName !== method && element[ effectName ] ) {
    843 			element[ effectName ]( options.duration, options.easing, callback );
    844 		} else {
    845 			element.queue(function( next ) {
    846 				$( this )[ method ]();
    847 				if ( callback ) {
    848 					callback.call( element[ 0 ] );
    849 				}
    850 				next();
    851 			});
    852 		}
    853 	};
    854 });
    855 
    856 var widget = $.widget;
    857 
    858 
    859 /*!
    860  * jQuery UI Mouse 1.11.4
    861  * http://jqueryui.com
    862  *
    863  * Copyright jQuery Foundation and other contributors
    864  * Released under the MIT license.
    865  * http://jquery.org/license
    866  *
    867  * http://api.jqueryui.com/mouse/
    868  */
    869 
    870 
    871 var mouseHandled = false;
    872 $( document ).mouseup( function() {
    873 	mouseHandled = false;
    874 });
    875 
    876 var mouse = $.widget("ui.mouse", {
    877 	version: "1.11.4",
    878 	options: {
    879 		cancel: "input,textarea,button,select,option",
    880 		distance: 1,
    881 		delay: 0
    882 	},
    883 	_mouseInit: function() {
    884 		var that = this;
    885 
    886 		this.element
    887 			.bind("mousedown." + this.widgetName, function(event) {
    888 				return that._mouseDown(event);
    889 			})
    890 			.bind("click." + this.widgetName, function(event) {
    891 				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
    892 					$.removeData(event.target, that.widgetName + ".preventClickEvent");
    893 					event.stopImmediatePropagation();
    894 					return false;
    895 				}
    896 			});
    897 
    898 		this.started = false;
    899 	},
    900 
    901 	// TODO: make sure destroying one instance of mouse doesn't mess with
    902 	// other instances of mouse
    903 	_mouseDestroy: function() {
    904 		this.element.unbind("." + this.widgetName);
    905 		if ( this._mouseMoveDelegate ) {
    906 			this.document
    907 				.unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
    908 				.unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
    909 		}
    910 	},
    911 
    912 	_mouseDown: function(event) {
    913 		// don't let more than one widget handle mouseStart
    914 		if ( mouseHandled ) {
    915 			return;
    916 		}
    917 
    918 		this._mouseMoved = false;
    919 
    920 		// we may have missed mouseup (out of window)
    921 		(this._mouseStarted && this._mouseUp(event));
    922 
    923 		this._mouseDownEvent = event;
    924 
    925 		var that = this,
    926 			btnIsLeft = (event.which === 1),
    927 			// event.target.nodeName works around a bug in IE 8 with
    928 			// disabled inputs (#7620)
    929 			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
    930 		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
    931 			return true;
    932 		}
    933 
    934 		this.mouseDelayMet = !this.options.delay;
    935 		if (!this.mouseDelayMet) {
    936 			this._mouseDelayTimer = setTimeout(function() {
    937 				that.mouseDelayMet = true;
    938 			}, this.options.delay);
    939 		}
    940 
    941 		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
    942 			this._mouseStarted = (this._mouseStart(event) !== false);
    943 			if (!this._mouseStarted) {
    944 				event.preventDefault();
    945 				return true;
    946 			}
    947 		}
    948 
    949 		// Click event may never have fired (Gecko & Opera)
    950 		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
    951 			$.removeData(event.target, this.widgetName + ".preventClickEvent");
    952 		}
    953 
    954 		// these delegates are required to keep context
    955 		this._mouseMoveDelegate = function(event) {
    956 			return that._mouseMove(event);
    957 		};
    958 		this._mouseUpDelegate = function(event) {
    959 			return that._mouseUp(event);
    960 		};
    961 
    962 		this.document
    963 			.bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
    964 			.bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
    965 
    966 		event.preventDefault();
    967 
    968 		mouseHandled = true;
    969 		return true;
    970 	},
    971 
    972 	_mouseMove: function(event) {
    973 		// Only check for mouseups outside the document if you've moved inside the document
    974 		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
    975 		// fire a mousemove event if content is placed under the cursor. See #7778
    976 		// Support: IE <9
    977 		if ( this._mouseMoved ) {
    978 			// IE mouseup check - mouseup happened when mouse was out of window
    979 			if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
    980 				return this._mouseUp(event);
    981 
    982 			// Iframe mouseup check - mouseup occurred in another document
    983 			} else if ( !event.which ) {
    984 				return this._mouseUp( event );
    985 			}
    986 		}
    987 
    988 		if ( event.which || event.button ) {
    989 			this._mouseMoved = true;
    990 		}
    991 
    992 		if (this._mouseStarted) {
    993 			this._mouseDrag(event);
    994 			return event.preventDefault();
    995 		}
    996 
    997 		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
    998 			this._mouseStarted =
    999 				(this._mouseStart(this._mouseDownEvent, event) !== false);
   1000 			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
   1001 		}
   1002 
   1003 		return !this._mouseStarted;
   1004 	},
   1005 
   1006 	_mouseUp: function(event) {
   1007 		this.document
   1008 			.unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
   1009 			.unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
   1010 
   1011 		if (this._mouseStarted) {
   1012 			this._mouseStarted = false;
   1013 
   1014 			if (event.target === this._mouseDownEvent.target) {
   1015 				$.data(event.target, this.widgetName + ".preventClickEvent", true);
   1016 			}
   1017 
   1018 			this._mouseStop(event);
   1019 		}
   1020 
   1021 		mouseHandled = false;
   1022 		return false;
   1023 	},
   1024 
   1025 	_mouseDistanceMet: function(event) {
   1026 		return (Math.max(
   1027 				Math.abs(this._mouseDownEvent.pageX - event.pageX),
   1028 				Math.abs(this._mouseDownEvent.pageY - event.pageY)
   1029 			) >= this.options.distance
   1030 		);
   1031 	},
   1032 
   1033 	_mouseDelayMet: function(/* event */) {
   1034 		return this.mouseDelayMet;
   1035 	},
   1036 
   1037 	// These are placeholder methods, to be overriden by extending plugin
   1038 	_mouseStart: function(/* event */) {},
   1039 	_mouseDrag: function(/* event */) {},
   1040 	_mouseStop: function(/* event */) {},
   1041 	_mouseCapture: function(/* event */) { return true; }
   1042 });
   1043 
   1044 
   1045 /*!
   1046  * jQuery UI Position 1.11.4
   1047  * http://jqueryui.com
   1048  *
   1049  * Copyright jQuery Foundation and other contributors
   1050  * Released under the MIT license.
   1051  * http://jquery.org/license
   1052  *
   1053  * http://api.jqueryui.com/position/
   1054  */
   1055 
   1056 (function() {
   1057 
   1058 $.ui = $.ui || {};
   1059 
   1060 var cachedScrollbarWidth, supportsOffsetFractions,
   1061 	max = Math.max,
   1062 	abs = Math.abs,
   1063 	round = Math.round,
   1064 	rhorizontal = /left|center|right/,
   1065 	rvertical = /top|center|bottom/,
   1066 	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
   1067 	rposition = /^\w+/,
   1068 	rpercent = /%$/,
   1069 	_position = $.fn.position;
   1070 
   1071 function getOffsets( offsets, width, height ) {
   1072 	return [
   1073 		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
   1074 		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
   1075 	];
   1076 }
   1077 
   1078 function parseCss( element, property ) {
   1079 	return parseInt( $.css( element, property ), 10 ) || 0;
   1080 }
   1081 
   1082 function getDimensions( elem ) {
   1083 	var raw = elem[0];
   1084 	if ( raw.nodeType === 9 ) {
   1085 		return {
   1086 			width: elem.width(),
   1087 			height: elem.height(),
   1088 			offset: { top: 0, left: 0 }
   1089 		};
   1090 	}
   1091 	if ( $.isWindow( raw ) ) {
   1092 		return {
   1093 			width: elem.width(),
   1094 			height: elem.height(),
   1095 			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
   1096 		};
   1097 	}
   1098 	if ( raw.preventDefault ) {
   1099 		return {
   1100 			width: 0,
   1101 			height: 0,
   1102 			offset: { top: raw.pageY, left: raw.pageX }
   1103 		};
   1104 	}
   1105 	return {
   1106 		width: elem.outerWidth(),
   1107 		height: elem.outerHeight(),
   1108 		offset: elem.offset()
   1109 	};
   1110 }
   1111 
   1112 $.position = {
   1113 	scrollbarWidth: function() {
   1114 		if ( cachedScrollbarWidth !== undefined ) {
   1115 			return cachedScrollbarWidth;
   1116 		}
   1117 		var w1, w2,
   1118 			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
   1119 			innerDiv = div.children()[0];
   1120 
   1121 		$( "body" ).append( div );
   1122 		w1 = innerDiv.offsetWidth;
   1123 		div.css( "overflow", "scroll" );
   1124 
   1125 		w2 = innerDiv.offsetWidth;
   1126 
   1127 		if ( w1 === w2 ) {
   1128 			w2 = div[0].clientWidth;
   1129 		}
   1130 
   1131 		div.remove();
   1132 
   1133 		return (cachedScrollbarWidth = w1 - w2);
   1134 	},
   1135 	getScrollInfo: function( within ) {
   1136 		var overflowX = within.isWindow || within.isDocument ? "" :
   1137 				within.element.css( "overflow-x" ),
   1138 			overflowY = within.isWindow || within.isDocument ? "" :
   1139 				within.element.css( "overflow-y" ),
   1140 			hasOverflowX = overflowX === "scroll" ||
   1141 				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
   1142 			hasOverflowY = overflowY === "scroll" ||
   1143 				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
   1144 		return {
   1145 			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
   1146 			height: hasOverflowX ? $.position.scrollbarWidth() : 0
   1147 		};
   1148 	},
   1149 	getWithinInfo: function( element ) {
   1150 		var withinElement = $( element || window ),
   1151 			isWindow = $.isWindow( withinElement[0] ),
   1152 			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
   1153 		return {
   1154 			element: withinElement,
   1155 			isWindow: isWindow,
   1156 			isDocument: isDocument,
   1157 			offset: withinElement.offset() || { left: 0, top: 0 },
   1158 			scrollLeft: withinElement.scrollLeft(),
   1159 			scrollTop: withinElement.scrollTop(),
   1160 
   1161 			// support: jQuery 1.6.x
   1162 			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
   1163 			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
   1164 			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
   1165 		};
   1166 	}
   1167 };
   1168 
   1169 $.fn.position = function( options ) {
   1170 	if ( !options || !options.of ) {
   1171 		return _position.apply( this, arguments );
   1172 	}
   1173 
   1174 	// make a copy, we don't want to modify arguments
   1175 	options = $.extend( {}, options );
   1176 
   1177 	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
   1178 		target = $( options.of ),
   1179 		within = $.position.getWithinInfo( options.within ),
   1180 		scrollInfo = $.position.getScrollInfo( within ),
   1181 		collision = ( options.collision || "flip" ).split( " " ),
   1182 		offsets = {};
   1183 
   1184 	dimensions = getDimensions( target );
   1185 	if ( target[0].preventDefault ) {
   1186 		// force left top to allow flipping
   1187 		options.at = "left top";
   1188 	}
   1189 	targetWidth = dimensions.width;
   1190 	targetHeight = dimensions.height;
   1191 	targetOffset = dimensions.offset;
   1192 	// clone to reuse original targetOffset later
   1193 	basePosition = $.extend( {}, targetOffset );
   1194 
   1195 	// force my and at to have valid horizontal and vertical positions
   1196 	// if a value is missing or invalid, it will be converted to center
   1197 	$.each( [ "my", "at" ], function() {
   1198 		var pos = ( options[ this ] || "" ).split( " " ),
   1199 			horizontalOffset,
   1200 			verticalOffset;
   1201 
   1202 		if ( pos.length === 1) {
   1203 			pos = rhorizontal.test( pos[ 0 ] ) ?
   1204 				pos.concat( [ "center" ] ) :
   1205 				rvertical.test( pos[ 0 ] ) ?
   1206 					[ "center" ].concat( pos ) :
   1207 					[ "center", "center" ];
   1208 		}
   1209 		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
   1210 		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
   1211 
   1212 		// calculate offsets
   1213 		horizontalOffset = roffset.exec( pos[ 0 ] );
   1214 		verticalOffset = roffset.exec( pos[ 1 ] );
   1215 		offsets[ this ] = [
   1216 			horizontalOffset ? horizontalOffset[ 0 ] : 0,
   1217 			verticalOffset ? verticalOffset[ 0 ] : 0
   1218 		];
   1219 
   1220 		// reduce to just the positions without the offsets
   1221 		options[ this ] = [
   1222 			rposition.exec( pos[ 0 ] )[ 0 ],
   1223 			rposition.exec( pos[ 1 ] )[ 0 ]
   1224 		];
   1225 	});
   1226 
   1227 	// normalize collision option
   1228 	if ( collision.length === 1 ) {
   1229 		collision[ 1 ] = collision[ 0 ];
   1230 	}
   1231 
   1232 	if ( options.at[ 0 ] === "right" ) {
   1233 		basePosition.left += targetWidth;
   1234 	} else if ( options.at[ 0 ] === "center" ) {
   1235 		basePosition.left += targetWidth / 2;
   1236 	}
   1237 
   1238 	if ( options.at[ 1 ] === "bottom" ) {
   1239 		basePosition.top += targetHeight;
   1240 	} else if ( options.at[ 1 ] === "center" ) {
   1241 		basePosition.top += targetHeight / 2;
   1242 	}
   1243 
   1244 	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
   1245 	basePosition.left += atOffset[ 0 ];
   1246 	basePosition.top += atOffset[ 1 ];
   1247 
   1248 	return this.each(function() {
   1249 		var collisionPosition, using,
   1250 			elem = $( this ),
   1251 			elemWidth = elem.outerWidth(),
   1252 			elemHeight = elem.outerHeight(),
   1253 			marginLeft = parseCss( this, "marginLeft" ),
   1254 			marginTop = parseCss( this, "marginTop" ),
   1255 			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
   1256 			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
   1257 			position = $.extend( {}, basePosition ),
   1258 			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
   1259 
   1260 		if ( options.my[ 0 ] === "right" ) {
   1261 			position.left -= elemWidth;
   1262 		} else if ( options.my[ 0 ] === "center" ) {
   1263 			position.left -= elemWidth / 2;
   1264 		}
   1265 
   1266 		if ( options.my[ 1 ] === "bottom" ) {
   1267 			position.top -= elemHeight;
   1268 		} else if ( options.my[ 1 ] === "center" ) {
   1269 			position.top -= elemHeight / 2;
   1270 		}
   1271 
   1272 		position.left += myOffset[ 0 ];
   1273 		position.top += myOffset[ 1 ];
   1274 
   1275 		// if the browser doesn't support fractions, then round for consistent results
   1276 		if ( !supportsOffsetFractions ) {
   1277 			position.left = round( position.left );
   1278 			position.top = round( position.top );
   1279 		}
   1280 
   1281 		collisionPosition = {
   1282 			marginLeft: marginLeft,
   1283 			marginTop: marginTop
   1284 		};
   1285 
   1286 		$.each( [ "left", "top" ], function( i, dir ) {
   1287 			if ( $.ui.position[ collision[ i ] ] ) {
   1288 				$.ui.position[ collision[ i ] ][ dir ]( position, {
   1289 					targetWidth: targetWidth,
   1290 					targetHeight: targetHeight,
   1291 					elemWidth: elemWidth,
   1292 					elemHeight: elemHeight,
   1293 					collisionPosition: collisionPosition,
   1294 					collisionWidth: collisionWidth,
   1295 					collisionHeight: collisionHeight,
   1296 					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
   1297 					my: options.my,
   1298 					at: options.at,
   1299 					within: within,
   1300 					elem: elem
   1301 				});
   1302 			}
   1303 		});
   1304 
   1305 		if ( options.using ) {
   1306 			// adds feedback as second argument to using callback, if present
   1307 			using = function( props ) {
   1308 				var left = targetOffset.left - position.left,
   1309 					right = left + targetWidth - elemWidth,
   1310 					top = targetOffset.top - position.top,
   1311 					bottom = top + targetHeight - elemHeight,
   1312 					feedback = {
   1313 						target: {
   1314 							element: target,
   1315 							left: targetOffset.left,
   1316 							top: targetOffset.top,
   1317 							width: targetWidth,
   1318 							height: targetHeight
   1319 						},
   1320 						element: {
   1321 							element: elem,
   1322 							left: position.left,
   1323 							top: position.top,
   1324 							width: elemWidth,
   1325 							height: elemHeight
   1326 						},
   1327 						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
   1328 						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
   1329 					};
   1330 				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
   1331 					feedback.horizontal = "center";
   1332 				}
   1333 				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
   1334 					feedback.vertical = "middle";
   1335 				}
   1336 				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
   1337 					feedback.important = "horizontal";
   1338 				} else {
   1339 					feedback.important = "vertical";
   1340 				}
   1341 				options.using.call( this, props, feedback );
   1342 			};
   1343 		}
   1344 
   1345 		elem.offset( $.extend( position, { using: using } ) );
   1346 	});
   1347 };
   1348 
   1349 $.ui.position = {
   1350 	fit: {
   1351 		left: function( position, data ) {
   1352 			var within = data.within,
   1353 				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
   1354 				outerWidth = within.width,
   1355 				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
   1356 				overLeft = withinOffset - collisionPosLeft,
   1357 				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
   1358 				newOverRight;
   1359 
   1360 			// element is wider than within
   1361 			if ( data.collisionWidth > outerWidth ) {
   1362 				// element is initially over the left side of within
   1363 				if ( overLeft > 0 && overRight <= 0 ) {
   1364 					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
   1365 					position.left += overLeft - newOverRight;
   1366 				// element is initially over right side of within
   1367 				} else if ( overRight > 0 && overLeft <= 0 ) {
   1368 					position.left = withinOffset;
   1369 				// element is initially over both left and right sides of within
   1370 				} else {
   1371 					if ( overLeft > overRight ) {
   1372 						position.left = withinOffset + outerWidth - data.collisionWidth;
   1373 					} else {
   1374 						position.left = withinOffset;
   1375 					}
   1376 				}
   1377 			// too far left -> align with left edge
   1378 			} else if ( overLeft > 0 ) {
   1379 				position.left += overLeft;
   1380 			// too far right -> align with right edge
   1381 			} else if ( overRight > 0 ) {
   1382 				position.left -= overRight;
   1383 			// adjust based on position and margin
   1384 			} else {
   1385 				position.left = max( position.left - collisionPosLeft, position.left );
   1386 			}
   1387 		},
   1388 		top: function( position, data ) {
   1389 			var within = data.within,
   1390 				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
   1391 				outerHeight = data.within.height,
   1392 				collisionPosTop = position.top - data.collisionPosition.marginTop,
   1393 				overTop = withinOffset - collisionPosTop,
   1394 				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
   1395 				newOverBottom;
   1396 
   1397 			// element is taller than within
   1398 			if ( data.collisionHeight > outerHeight ) {
   1399 				// element is initially over the top of within
   1400 				if ( overTop > 0 && overBottom <= 0 ) {
   1401 					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
   1402 					position.top += overTop - newOverBottom;
   1403 				// element is initially over bottom of within
   1404 				} else if ( overBottom > 0 && overTop <= 0 ) {
   1405 					position.top = withinOffset;
   1406 				// element is initially over both top and bottom of within
   1407 				} else {
   1408 					if ( overTop > overBottom ) {
   1409 						position.top = withinOffset + outerHeight - data.collisionHeight;
   1410 					} else {
   1411 						position.top = withinOffset;
   1412 					}
   1413 				}
   1414 			// too far up -> align with top
   1415 			} else if ( overTop > 0 ) {
   1416 				position.top += overTop;
   1417 			// too far down -> align with bottom edge
   1418 			} else if ( overBottom > 0 ) {
   1419 				position.top -= overBottom;
   1420 			// adjust based on position and margin
   1421 			} else {
   1422 				position.top = max( position.top - collisionPosTop, position.top );
   1423 			}
   1424 		}
   1425 	},
   1426 	flip: {
   1427 		left: function( position, data ) {
   1428 			var within = data.within,
   1429 				withinOffset = within.offset.left + within.scrollLeft,
   1430 				outerWidth = within.width,
   1431 				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
   1432 				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
   1433 				overLeft = collisionPosLeft - offsetLeft,
   1434 				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
   1435 				myOffset = data.my[ 0 ] === "left" ?
   1436 					-data.elemWidth :
   1437 					data.my[ 0 ] === "right" ?
   1438 						data.elemWidth :
   1439 						0,
   1440 				atOffset = data.at[ 0 ] === "left" ?
   1441 					data.targetWidth :
   1442 					data.at[ 0 ] === "right" ?
   1443 						-data.targetWidth :
   1444 						0,
   1445 				offset = -2 * data.offset[ 0 ],
   1446 				newOverRight,
   1447 				newOverLeft;
   1448 
   1449 			if ( overLeft < 0 ) {
   1450 				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
   1451 				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
   1452 					position.left += myOffset + atOffset + offset;
   1453 				}
   1454 			} else if ( overRight > 0 ) {
   1455 				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
   1456 				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
   1457 					position.left += myOffset + atOffset + offset;
   1458 				}
   1459 			}
   1460 		},
   1461 		top: function( position, data ) {
   1462 			var within = data.within,
   1463 				withinOffset = within.offset.top + within.scrollTop,
   1464 				outerHeight = within.height,
   1465 				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
   1466 				collisionPosTop = position.top - data.collisionPosition.marginTop,
   1467 				overTop = collisionPosTop - offsetTop,
   1468 				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
   1469 				top = data.my[ 1 ] === "top",
   1470 				myOffset = top ?
   1471 					-data.elemHeight :
   1472 					data.my[ 1 ] === "bottom" ?
   1473 						data.elemHeight :
   1474 						0,
   1475 				atOffset = data.at[ 1 ] === "top" ?
   1476 					data.targetHeight :
   1477 					data.at[ 1 ] === "bottom" ?
   1478 						-data.targetHeight :
   1479 						0,
   1480 				offset = -2 * data.offset[ 1 ],
   1481 				newOverTop,
   1482 				newOverBottom;
   1483 			if ( overTop < 0 ) {
   1484 				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
   1485 				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
   1486 					position.top += myOffset + atOffset + offset;
   1487 				}
   1488 			} else if ( overBottom > 0 ) {
   1489 				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
   1490 				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
   1491 					position.top += myOffset + atOffset + offset;
   1492 				}
   1493 			}
   1494 		}
   1495 	},
   1496 	flipfit: {
   1497 		left: function() {
   1498 			$.ui.position.flip.left.apply( this, arguments );
   1499 			$.ui.position.fit.left.apply( this, arguments );
   1500 		},
   1501 		top: function() {
   1502 			$.ui.position.flip.top.apply( this, arguments );
   1503 			$.ui.position.fit.top.apply( this, arguments );
   1504 		}
   1505 	}
   1506 };
   1507 
   1508 // fraction support test
   1509 (function() {
   1510 	var testElement, testElementParent, testElementStyle, offsetLeft, i,
   1511 		body = document.getElementsByTagName( "body" )[ 0 ],
   1512 		div = document.createElement( "div" );
   1513 
   1514 	//Create a "fake body" for testing based on method used in jQuery.support
   1515 	testElement = document.createElement( body ? "div" : "body" );
   1516 	testElementStyle = {
   1517 		visibility: "hidden",
   1518 		width: 0,
   1519 		height: 0,
   1520 		border: 0,
   1521 		margin: 0,
   1522 		background: "none"
   1523 	};
   1524 	if ( body ) {
   1525 		$.extend( testElementStyle, {
   1526 			position: "absolute",
   1527 			left: "-1000px",
   1528 			top: "-1000px"
   1529 		});
   1530 	}
   1531 	for ( i in testElementStyle ) {
   1532 		testElement.style[ i ] = testElementStyle[ i ];
   1533 	}
   1534 	testElement.appendChild( div );
   1535 	testElementParent = body || document.documentElement;
   1536 	testElementParent.insertBefore( testElement, testElementParent.firstChild );
   1537 
   1538 	div.style.cssText = "position: absolute; left: 10.7432222px;";
   1539 
   1540 	offsetLeft = $( div ).offset().left;
   1541 	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
   1542 
   1543 	testElement.innerHTML = "";
   1544 	testElementParent.removeChild( testElement );
   1545 })();
   1546 
   1547 })();
   1548 
   1549 var position = $.ui.position;
   1550 
   1551 
   1552 /*!
   1553  * jQuery UI Draggable 1.11.4
   1554  * http://jqueryui.com
   1555  *
   1556  * Copyright jQuery Foundation and other contributors
   1557  * Released under the MIT license.
   1558  * http://jquery.org/license
   1559  *
   1560  * http://api.jqueryui.com/draggable/
   1561  */
   1562 
   1563 
   1564 $.widget("ui.draggable", $.ui.mouse, {
   1565 	version: "1.11.4",
   1566 	widgetEventPrefix: "drag",
   1567 	options: {
   1568 		addClasses: true,
   1569 		appendTo: "parent",
   1570 		axis: false,
   1571 		connectToSortable: false,
   1572 		containment: false,
   1573 		cursor: "auto",
   1574 		cursorAt: false,
   1575 		grid: false,
   1576 		handle: false,
   1577 		helper: "original",
   1578 		iframeFix: false,
   1579 		opacity: false,
   1580 		refreshPositions: false,
   1581 		revert: false,
   1582 		revertDuration: 500,
   1583 		scope: "default",
   1584 		scroll: true,
   1585 		scrollSensitivity: 20,
   1586 		scrollSpeed: 20,
   1587 		snap: false,
   1588 		snapMode: "both",
   1589 		snapTolerance: 20,
   1590 		stack: false,
   1591 		zIndex: false,
   1592 
   1593 		// callbacks
   1594 		drag: null,
   1595 		start: null,
   1596 		stop: null
   1597 	},
   1598 	_create: function() {
   1599 
   1600 		if ( this.options.helper === "original" ) {
   1601 			this._setPositionRelative();
   1602 		}
   1603 		if (this.options.addClasses){
   1604 			this.element.addClass("ui-draggable");
   1605 		}
   1606 		if (this.options.disabled){
   1607 			this.element.addClass("ui-draggable-disabled");
   1608 		}
   1609 		this._setHandleClassName();
   1610 
   1611 		this._mouseInit();
   1612 	},
   1613 
   1614 	_setOption: function( key, value ) {
   1615 		this._super( key, value );
   1616 		if ( key === "handle" ) {
   1617 			this._removeHandleClassName();
   1618 			this._setHandleClassName();
   1619 		}
   1620 	},
   1621 
   1622 	_destroy: function() {
   1623 		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
   1624 			this.destroyOnClear = true;
   1625 			return;
   1626 		}
   1627 		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
   1628 		this._removeHandleClassName();
   1629 		this._mouseDestroy();
   1630 	},
   1631 
   1632 	_mouseCapture: function(event) {
   1633 		var o = this.options;
   1634 
   1635 		this._blurActiveElement( event );
   1636 
   1637 		// among others, prevent a drag on a resizable-handle
   1638 		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
   1639 			return false;
   1640 		}
   1641 
   1642 		//Quit if we're not on a valid handle
   1643 		this.handle = this._getHandle(event);
   1644 		if (!this.handle) {
   1645 			return false;
   1646 		}
   1647 
   1648 		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
   1649 
   1650 		return true;
   1651 
   1652 	},
   1653 
   1654 	_blockFrames: function( selector ) {
   1655 		this.iframeBlocks = this.document.find( selector ).map(function() {
   1656 			var iframe = $( this );
   1657 
   1658 			return $( "<div>" )
   1659 				.css( "position", "absolute" )
   1660 				.appendTo( iframe.parent() )
   1661 				.outerWidth( iframe.outerWidth() )
   1662 				.outerHeight( iframe.outerHeight() )
   1663 				.offset( iframe.offset() )[ 0 ];
   1664 		});
   1665 	},
   1666 
   1667 	_unblockFrames: function() {
   1668 		if ( this.iframeBlocks ) {
   1669 			this.iframeBlocks.remove();
   1670 			delete this.iframeBlocks;
   1671 		}
   1672 	},
   1673 
   1674 	_blurActiveElement: function( event ) {
   1675 		var document = this.document[ 0 ];
   1676 
   1677 		// Only need to blur if the event occurred on the draggable itself, see #10527
   1678 		if ( !this.handleElement.is( event.target ) ) {
   1679 			return;
   1680 		}
   1681 
   1682 		// support: IE9
   1683 		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
   1684 		try {
   1685 
   1686 			// Support: IE9, IE10
   1687 			// If the <body> is blurred, IE will switch windows, see #9520
   1688 			if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
   1689 
   1690 				// Blur any element that currently has focus, see #4261
   1691 				$( document.activeElement ).blur();
   1692 			}
   1693 		} catch ( error ) {}
   1694 	},
   1695 
   1696 	_mouseStart: function(event) {
   1697 
   1698 		var o = this.options;
   1699 
   1700 		//Create and append the visible helper
   1701 		this.helper = this._createHelper(event);
   1702 
   1703 		this.helper.addClass("ui-draggable-dragging");
   1704 
   1705 		//Cache the helper size
   1706 		this._cacheHelperProportions();
   1707 
   1708 		//If ddmanager is used for droppables, set the global draggable
   1709 		if ($.ui.ddmanager) {
   1710 			$.ui.ddmanager.current = this;
   1711 		}
   1712 
   1713 		/*
   1714 		 * - Position generation -
   1715 		 * This block generates everything position related - it's the core of draggables.
   1716 		 */
   1717 
   1718 		//Cache the margins of the original element
   1719 		this._cacheMargins();
   1720 
   1721 		//Store the helper's css position
   1722 		this.cssPosition = this.helper.css( "position" );
   1723 		this.scrollParent = this.helper.scrollParent( true );
   1724 		this.offsetParent = this.helper.offsetParent();
   1725 		this.hasFixedAncestor = this.helper.parents().filter(function() {
   1726 				return $( this ).css( "position" ) === "fixed";
   1727 			}).length > 0;
   1728 
   1729 		//The element's absolute position on the page minus margins
   1730 		this.positionAbs = this.element.offset();
   1731 		this._refreshOffsets( event );
   1732 
   1733 		//Generate the original position
   1734 		this.originalPosition = this.position = this._generatePosition( event, false );
   1735 		this.originalPageX = event.pageX;
   1736 		this.originalPageY = event.pageY;
   1737 
   1738 		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
   1739 		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
   1740 
   1741 		//Set a containment if given in the options
   1742 		this._setContainment();
   1743 
   1744 		//Trigger event + callbacks
   1745 		if (this._trigger("start", event) === false) {
   1746 			this._clear();
   1747 			return false;
   1748 		}
   1749 
   1750 		//Recache the helper size
   1751 		this._cacheHelperProportions();
   1752 
   1753 		//Prepare the droppable offsets
   1754 		if ($.ui.ddmanager && !o.dropBehaviour) {
   1755 			$.ui.ddmanager.prepareOffsets(this, event);
   1756 		}
   1757 
   1758 		// Reset helper's right/bottom css if they're set and set explicit width/height instead
   1759 		// as this prevents resizing of elements with right/bottom set (see #7772)
   1760 		this._normalizeRightBottom();
   1761 
   1762 		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
   1763 
   1764 		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
   1765 		if ( $.ui.ddmanager ) {
   1766 			$.ui.ddmanager.dragStart(this, event);
   1767 		}
   1768 
   1769 		return true;
   1770 	},
   1771 
   1772 	_refreshOffsets: function( event ) {
   1773 		this.offset = {
   1774 			top: this.positionAbs.top - this.margins.top,
   1775 			left: this.positionAbs.left - this.margins.left,
   1776 			scroll: false,
   1777 			parent: this._getParentOffset(),
   1778 			relative: this._getRelativeOffset()
   1779 		};
   1780 
   1781 		this.offset.click = {
   1782 			left: event.pageX - this.offset.left,
   1783 			top: event.pageY - this.offset.top
   1784 		};
   1785 	},
   1786 
   1787 	_mouseDrag: function(event, noPropagation) {
   1788 		// reset any necessary cached properties (see #5009)
   1789 		if ( this.hasFixedAncestor ) {
   1790 			this.offset.parent = this._getParentOffset();
   1791 		}
   1792 
   1793 		//Compute the helpers position
   1794 		this.position = this._generatePosition( event, true );
   1795 		this.positionAbs = this._convertPositionTo("absolute");
   1796 
   1797 		//Call plugins and callbacks and use the resulting position if something is returned
   1798 		if (!noPropagation) {
   1799 			var ui = this._uiHash();
   1800 			if (this._trigger("drag", event, ui) === false) {
   1801 				this._mouseUp({});
   1802 				return false;
   1803 			}
   1804 			this.position = ui.position;
   1805 		}
   1806 
   1807 		this.helper[ 0 ].style.left = this.position.left + "px";
   1808 		this.helper[ 0 ].style.top = this.position.top + "px";
   1809 
   1810 		if ($.ui.ddmanager) {
   1811 			$.ui.ddmanager.drag(this, event);
   1812 		}
   1813 
   1814 		return false;
   1815 	},
   1816 
   1817 	_mouseStop: function(event) {
   1818 
   1819 		//If we are using droppables, inform the manager about the drop
   1820 		var that = this,
   1821 			dropped = false;
   1822 		if ($.ui.ddmanager && !this.options.dropBehaviour) {
   1823 			dropped = $.ui.ddmanager.drop(this, event);
   1824 		}
   1825 
   1826 		//if a drop comes from outside (a sortable)
   1827 		if (this.dropped) {
   1828 			dropped = this.dropped;
   1829 			this.dropped = false;
   1830 		}
   1831 
   1832 		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))) {
   1833 			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
   1834 				if (that._trigger("stop", event) !== false) {
   1835 					that._clear();
   1836 				}
   1837 			});
   1838 		} else {
   1839 			if (this._trigger("stop", event) !== false) {
   1840 				this._clear();
   1841 			}
   1842 		}
   1843 
   1844 		return false;
   1845 	},
   1846 
   1847 	_mouseUp: function( event ) {
   1848 		this._unblockFrames();
   1849 
   1850 		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
   1851 		if ( $.ui.ddmanager ) {
   1852 			$.ui.ddmanager.dragStop(this, event);
   1853 		}
   1854 
   1855 		// Only need to focus if the event occurred on the draggable itself, see #10527
   1856 		if ( this.handleElement.is( event.target ) ) {
   1857 			// The interaction is over; whether or not the click resulted in a drag, focus the element
   1858 			this.element.focus();
   1859 		}
   1860 
   1861 		return $.ui.mouse.prototype._mouseUp.call(this, event);
   1862 	},
   1863 
   1864 	cancel: function() {
   1865 
   1866 		if (this.helper.is(".ui-draggable-dragging")) {
   1867 			this._mouseUp({});
   1868 		} else {
   1869 			this._clear();
   1870 		}
   1871 
   1872 		return this;
   1873 
   1874 	},
   1875 
   1876 	_getHandle: function(event) {
   1877 		return this.options.handle ?
   1878 			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
   1879 			true;
   1880 	},
   1881 
   1882 	_setHandleClassName: function() {
   1883 		this.handleElement = this.options.handle ?
   1884 			this.element.find( this.options.handle ) : this.element;
   1885 		this.handleElement.addClass( "ui-draggable-handle" );
   1886 	},
   1887 
   1888 	_removeHandleClassName: function() {
   1889 		this.handleElement.removeClass( "ui-draggable-handle" );
   1890 	},
   1891 
   1892 	_createHelper: function(event) {
   1893 
   1894 		var o = this.options,
   1895 			helperIsFunction = $.isFunction( o.helper ),
   1896 			helper = helperIsFunction ?
   1897 				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
   1898 				( o.helper === "clone" ?
   1899 					this.element.clone().removeAttr( "id" ) :
   1900 					this.element );
   1901 
   1902 		if (!helper.parents("body").length) {
   1903 			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
   1904 		}
   1905 
   1906 		// http://bugs.jqueryui.com/ticket/9446
   1907 		// a helper function can return the original element
   1908 		// which wouldn't have been set to relative in _create
   1909 		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
   1910 			this._setPositionRelative();
   1911 		}
   1912 
   1913 		if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
   1914 			helper.css("position", "absolute");
   1915 		}
   1916 
   1917 		return helper;
   1918 
   1919 	},
   1920 
   1921 	_setPositionRelative: function() {
   1922 		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
   1923 			this.element[ 0 ].style.position = "relative";
   1924 		}
   1925 	},
   1926 
   1927 	_adjustOffsetFromHelper: function(obj) {
   1928 		if (typeof obj === "string") {
   1929 			obj = obj.split(" ");
   1930 		}
   1931 		if ($.isArray(obj)) {
   1932 			obj = { left: +obj[0], top: +obj[1] || 0 };
   1933 		}
   1934 		if ("left" in obj) {
   1935 			this.offset.click.left = obj.left + this.margins.left;
   1936 		}
   1937 		if ("right" in obj) {
   1938 			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
   1939 		}
   1940 		if ("top" in obj) {
   1941 			this.offset.click.top = obj.top + this.margins.top;
   1942 		}
   1943 		if ("bottom" in obj) {
   1944 			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
   1945 		}
   1946 	},
   1947 
   1948 	_isRootNode: function( element ) {
   1949 		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
   1950 	},
   1951 
   1952 	_getParentOffset: function() {
   1953 
   1954 		//Get the offsetParent and cache its position
   1955 		var po = this.offsetParent.offset(),
   1956 			document = this.document[ 0 ];
   1957 
   1958 		// This is a special case where we need to modify a offset calculated on start, since the following happened:
   1959 		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
   1960 		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
   1961 		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
   1962 		if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
   1963 			po.left += this.scrollParent.scrollLeft();
   1964 			po.top += this.scrollParent.scrollTop();
   1965 		}
   1966 
   1967 		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
   1968 			po = { top: 0, left: 0 };
   1969 		}
   1970 
   1971 		return {
   1972 			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
   1973 			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
   1974 		};
   1975 
   1976 	},
   1977 
   1978 	_getRelativeOffset: function() {
   1979 		if ( this.cssPosition !== "relative" ) {
   1980 			return { top: 0, left: 0 };
   1981 		}
   1982 
   1983 		var p = this.element.position(),
   1984 			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
   1985 
   1986 		return {
   1987 			top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
   1988 			left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
   1989 		};
   1990 
   1991 	},
   1992 
   1993 	_cacheMargins: function() {
   1994 		this.margins = {
   1995 			left: (parseInt(this.element.css("marginLeft"), 10) || 0),
   1996 			top: (parseInt(this.element.css("marginTop"), 10) || 0),
   1997 			right: (parseInt(this.element.css("marginRight"), 10) || 0),
   1998 			bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
   1999 		};
   2000 	},
   2001 
   2002 	_cacheHelperProportions: function() {
   2003 		this.helperProportions = {
   2004 			width: this.helper.outerWidth(),
   2005 			height: this.helper.outerHeight()
   2006 		};
   2007 	},
   2008 
   2009 	_setContainment: function() {
   2010 
   2011 		var isUserScrollable, c, ce,
   2012 			o = this.options,
   2013 			document = this.document[ 0 ];
   2014 
   2015 		this.relativeContainer = null;
   2016 
   2017 		if ( !o.containment ) {
   2018 			this.containment = null;
   2019 			return;
   2020 		}
   2021 
   2022 		if ( o.containment === "window" ) {
   2023 			this.containment = [
   2024 				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
   2025 				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
   2026 				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
   2027 				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
   2028 			];
   2029 			return;
   2030 		}
   2031 
   2032 		if ( o.containment === "document") {
   2033 			this.containment = [
   2034 				0,
   2035 				0,
   2036 				$( document ).width() - this.helperProportions.width - this.margins.left,
   2037 				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
   2038 			];
   2039 			return;
   2040 		}
   2041 
   2042 		if ( o.containment.constructor === Array ) {
   2043 			this.containment = o.containment;
   2044 			return;
   2045 		}
   2046 
   2047 		if ( o.containment === "parent" ) {
   2048 			o.containment = this.helper[ 0 ].parentNode;
   2049 		}
   2050 
   2051 		c = $( o.containment );
   2052 		ce = c[ 0 ];
   2053 
   2054 		if ( !ce ) {
   2055 			return;
   2056 		}
   2057 
   2058 		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
   2059 
   2060 		this.containment = [
   2061 			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
   2062 			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
   2063 			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
   2064 				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
   2065 				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
   2066 				this.helperProportions.width -
   2067 				this.margins.left -
   2068 				this.margins.right,
   2069 			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
   2070 				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
   2071 				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
   2072 				this.helperProportions.height -
   2073 				this.margins.top -
   2074 				this.margins.bottom
   2075 		];
   2076 		this.relativeContainer = c;
   2077 	},
   2078 
   2079 	_convertPositionTo: function(d, pos) {
   2080 
   2081 		if (!pos) {
   2082 			pos = this.position;
   2083 		}
   2084 
   2085 		var mod = d === "absolute" ? 1 : -1,
   2086 			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
   2087 
   2088 		return {
   2089 			top: (
   2090 				pos.top	+																// The absolute mouse position
   2091 				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
   2092 				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
   2093 				( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
   2094 			),
   2095 			left: (
   2096 				pos.left +																// The absolute mouse position
   2097 				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
   2098 				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
   2099 				( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
   2100 			)
   2101 		};
   2102 
   2103 	},
   2104 
   2105 	_generatePosition: function( event, constrainPosition ) {
   2106 
   2107 		var containment, co, top, left,
   2108 			o = this.options,
   2109 			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
   2110 			pageX = event.pageX,
   2111 			pageY = event.pageY;
   2112 
   2113 		// Cache the scroll
   2114 		if ( !scrollIsRootNode || !this.offset.scroll ) {
   2115 			this.offset.scroll = {
   2116 				top: this.scrollParent.scrollTop(),
   2117 				left: this.scrollParent.scrollLeft()
   2118 			};
   2119 		}
   2120 
   2121 		/*
   2122 		 * - Position constraining -
   2123 		 * Constrain the position to a mix of grid, containment.
   2124 		 */
   2125 
   2126 		// If we are not dragging yet, we won't check for options
   2127 		if ( constrainPosition ) {
   2128 			if ( this.containment ) {
   2129 				if ( this.relativeContainer ){
   2130 					co = this.relativeContainer.offset();
   2131 					containment = [
   2132 						this.containment[ 0 ] + co.left,
   2133 						this.containment[ 1 ] + co.top,
   2134 						this.containment[ 2 ] + co.left,
   2135 						this.containment[ 3 ] + co.top
   2136 					];
   2137 				} else {
   2138 					containment = this.containment;
   2139 				}
   2140 
   2141 				if (event.pageX - this.offset.click.left < containment[0]) {
   2142 					pageX = containment[0] + this.offset.click.left;
   2143 				}
   2144 				if (event.pageY - this.offset.click.top < containment[1]) {
   2145 					pageY = containment[1] + this.offset.click.top;
   2146 				}
   2147 				if (event.pageX - this.offset.click.left > containment[2]) {
   2148 					pageX = containment[2] + this.offset.click.left;
   2149 				}
   2150 				if (event.pageY - this.offset.click.top > containment[3]) {
   2151 					pageY = containment[3] + this.offset.click.top;
   2152 				}
   2153 			}
   2154 
   2155 			if (o.grid) {
   2156 				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
   2157 				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
   2158 				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;
   2159 
   2160 				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
   2161 				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;
   2162 			}
   2163 
   2164 			if ( o.axis === "y" ) {
   2165 				pageX = this.originalPageX;
   2166 			}
   2167 
   2168 			if ( o.axis === "x" ) {
   2169 				pageY = this.originalPageY;
   2170 			}
   2171 		}
   2172 
   2173 		return {
   2174 			top: (
   2175 				pageY -																	// The absolute mouse position
   2176 				this.offset.click.top	-												// Click offset (relative to the element)
   2177 				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
   2178 				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
   2179 				( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
   2180 			),
   2181 			left: (
   2182 				pageX -																	// The absolute mouse position
   2183 				this.offset.click.left -												// Click offset (relative to the element)
   2184 				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
   2185 				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
   2186 				( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
   2187 			)
   2188 		};
   2189 
   2190 	},
   2191 
   2192 	_clear: function() {
   2193 		this.helper.removeClass("ui-draggable-dragging");
   2194 		if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
   2195 			this.helper.remove();
   2196 		}
   2197 		this.helper = null;
   2198 		this.cancelHelperRemoval = false;
   2199 		if ( this.destroyOnClear ) {
   2200 			this.destroy();
   2201 		}
   2202 	},
   2203 
   2204 	_normalizeRightBottom: function() {
   2205 		if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
   2206 			this.helper.width( this.helper.width() );
   2207 			this.helper.css( "right", "auto" );
   2208 		}
   2209 		if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
   2210 			this.helper.height( this.helper.height() );
   2211 			this.helper.css( "bottom", "auto" );
   2212 		}
   2213 	},
   2214 
   2215 	// From now on bulk stuff - mainly helpers
   2216 
   2217 	_trigger: function( type, event, ui ) {
   2218 		ui = ui || this._uiHash();
   2219 		$.ui.plugin.call( this, type, [ event, ui, this ], true );
   2220 
   2221 		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
   2222 		if ( /^(drag|start|stop)/.test( type ) ) {
   2223 			this.positionAbs = this._convertPositionTo( "absolute" );
   2224 			ui.offset = this.positionAbs;
   2225 		}
   2226 		return $.Widget.prototype._trigger.call( this, type, event, ui );
   2227 	},
   2228 
   2229 	plugins: {},
   2230 
   2231 	_uiHash: function() {
   2232 		return {
   2233 			helper: this.helper,
   2234 			position: this.position,
   2235 			originalPosition: this.originalPosition,
   2236 			offset: this.positionAbs
   2237 		};
   2238 	}
   2239 
   2240 });
   2241 
   2242 $.ui.plugin.add( "draggable", "connectToSortable", {
   2243 	start: function( event, ui, draggable ) {
   2244 		var uiSortable = $.extend( {}, ui, {
   2245 			item: draggable.element
   2246 		});
   2247 
   2248 		draggable.sortables = [];
   2249 		$( draggable.options.connectToSortable ).each(function() {
   2250 			var sortable = $( this ).sortable( "instance" );
   2251 
   2252 			if ( sortable && !sortable.options.disabled ) {
   2253 				draggable.sortables.push( sortable );
   2254 
   2255 				// refreshPositions is called at drag start to refresh the containerCache
   2256 				// which is used in drag. This ensures it's initialized and synchronized
   2257 				// with any changes that might have happened on the page since initialization.
   2258 				sortable.refreshPositions();
   2259 				sortable._trigger("activate", event, uiSortable);
   2260 			}
   2261 		});
   2262 	},
   2263 	stop: function( event, ui, draggable ) {
   2264 		var uiSortable = $.extend( {}, ui, {
   2265 			item: draggable.element
   2266 		});
   2267 
   2268 		draggable.cancelHelperRemoval = false;
   2269 
   2270 		$.each( draggable.sortables, function() {
   2271 			var sortable = this;
   2272 
   2273 			if ( sortable.isOver ) {
   2274 				sortable.isOver = 0;
   2275 
   2276 				// Allow this sortable to handle removing the helper
   2277 				draggable.cancelHelperRemoval = true;
   2278 				sortable.cancelHelperRemoval = false;
   2279 
   2280 				// Use _storedCSS To restore properties in the sortable,
   2281 				// as this also handles revert (#9675) since the draggable
   2282 				// may have modified them in unexpected ways (#8809)
   2283 				sortable._storedCSS = {
   2284 					position: sortable.placeholder.css( "position" ),
   2285 					top: sortable.placeholder.css( "top" ),
   2286 					left: sortable.placeholder.css( "left" )
   2287 				};
   2288 
   2289 				sortable._mouseStop(event);
   2290 
   2291 				// Once drag has ended, the sortable should return to using
   2292 				// its original helper, not the shared helper from draggable
   2293 				sortable.options.helper = sortable.options._helper;
   2294 			} else {
   2295 				// Prevent this Sortable from removing the helper.
   2296 				// However, don't set the draggable to remove the helper
   2297 				// either as another connected Sortable may yet handle the removal.
   2298 				sortable.cancelHelperRemoval = true;
   2299 
   2300 				sortable._trigger( "deactivate", event, uiSortable );
   2301 			}
   2302 		});
   2303 	},
   2304 	drag: function( event, ui, draggable ) {
   2305 		$.each( draggable.sortables, function() {
   2306 			var innermostIntersecting = false,
   2307 				sortable = this;
   2308 
   2309 			// Copy over variables that sortable's _intersectsWith uses
   2310 			sortable.positionAbs = draggable.positionAbs;
   2311 			sortable.helperProportions = draggable.helperProportions;
   2312 			sortable.offset.click = draggable.offset.click;
   2313 
   2314 			if ( sortable._intersectsWith( sortable.containerCache ) ) {
   2315 				innermostIntersecting = true;
   2316 
   2317 				$.each( draggable.sortables, function() {
   2318 					// Copy over variables that sortable's _intersectsWith uses
   2319 					this.positionAbs = draggable.positionAbs;
   2320 					this.helperProportions = draggable.helperProportions;
   2321 					this.offset.click = draggable.offset.click;
   2322 
   2323 					if ( this !== sortable &&
   2324 							this._intersectsWith( this.containerCache ) &&
   2325 							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
   2326 						innermostIntersecting = false;
   2327 					}
   2328 
   2329 					return innermostIntersecting;
   2330 				});
   2331 			}
   2332 
   2333 			if ( innermostIntersecting ) {
   2334 				// If it intersects, we use a little isOver variable and set it once,
   2335 				// so that the move-in stuff gets fired only once.
   2336 				if ( !sortable.isOver ) {
   2337 					sortable.isOver = 1;
   2338 
   2339 					// Store draggable's parent in case we need to reappend to it later.
   2340 					draggable._parent = ui.helper.parent();
   2341 
   2342 					sortable.currentItem = ui.helper
   2343 						.appendTo( sortable.element )
   2344 						.data( "ui-sortable-item", true );
   2345 
   2346 					// Store helper option to later restore it
   2347 					sortable.options._helper = sortable.options.helper;
   2348 
   2349 					sortable.options.helper = function() {
   2350 						return ui.helper[ 0 ];
   2351 					};
   2352 
   2353 					// Fire the start events of the sortable with our passed browser event,
   2354 					// and our own helper (so it doesn't create a new one)
   2355 					event.target = sortable.currentItem[ 0 ];
   2356 					sortable._mouseCapture( event, true );
   2357 					sortable._mouseStart( event, true, true );
   2358 
   2359 					// Because the browser event is way off the new appended portlet,
   2360 					// modify necessary variables to reflect the changes
   2361 					sortable.offset.click.top = draggable.offset.click.top;
   2362 					sortable.offset.click.left = draggable.offset.click.left;
   2363 					sortable.offset.parent.left -= draggable.offset.parent.left -
   2364 						sortable.offset.parent.left;
   2365 					sortable.offset.parent.top -= draggable.offset.parent.top -
   2366 						sortable.offset.parent.top;
   2367 
   2368 					draggable._trigger( "toSortable", event );
   2369 
   2370 					// Inform draggable that the helper is in a valid drop zone,
   2371 					// used solely in the revert option to handle "valid/invalid".
   2372 					draggable.dropped = sortable.element;
   2373 
   2374 					// Need to refreshPositions of all sortables in the case that
   2375 					// adding to one sortable changes the location of the other sortables (#9675)
   2376 					$.each( draggable.sortables, function() {
   2377 						this.refreshPositions();
   2378 					});
   2379 
   2380 					// hack so receive/update callbacks work (mostly)
   2381 					draggable.currentItem = draggable.element;
   2382 					sortable.fromOutside = draggable;
   2383 				}
   2384 
   2385 				if ( sortable.currentItem ) {
   2386 					sortable._mouseDrag( event );
   2387 					// Copy the sortable's position because the draggable's can potentially reflect
   2388 					// a relative position, while sortable is always absolute, which the dragged
   2389 					// element has now become. (#8809)
   2390 					ui.position = sortable.position;
   2391 				}
   2392 			} else {
   2393 				// If it doesn't intersect with the sortable, and it intersected before,
   2394 				// we fake the drag stop of the sortable, but make sure it doesn't remove
   2395 				// the helper by using cancelHelperRemoval.
   2396 				if ( sortable.isOver ) {
   2397 
   2398 					sortable.isOver = 0;
   2399 					sortable.cancelHelperRemoval = true;
   2400 
   2401 					// Calling sortable's mouseStop would trigger a revert,
   2402 					// so revert must be temporarily false until after mouseStop is called.
   2403 					sortable.options._revert = sortable.options.revert;
   2404 					sortable.options.revert = false;
   2405 
   2406 					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
   2407 					sortable._mouseStop( event, true );
   2408 
   2409 					// restore sortable behaviors that were modfied
   2410 					// when the draggable entered the sortable area (#9481)
   2411 					sortable.options.revert = sortable.options._revert;
   2412 					sortable.options.helper = sortable.options._helper;
   2413 
   2414 					if ( sortable.placeholder ) {
   2415 						sortable.placeholder.remove();
   2416 					}
   2417 
   2418 					// Restore and recalculate the draggable's offset considering the sortable
   2419 					// may have modified them in unexpected ways. (#8809, #10669)
   2420 					ui.helper.appendTo( draggable._parent );
   2421 					draggable._refreshOffsets( event );
   2422 					ui.position = draggable._generatePosition( event, true );
   2423 
   2424 					draggable._trigger( "fromSortable", event );
   2425 
   2426 					// Inform draggable that the helper is no longer in a valid drop zone
   2427 					draggable.dropped = false;
   2428 
   2429 					// Need to refreshPositions of all sortables just in case removing
   2430 					// from one sortable changes the location of other sortables (#9675)
   2431 					$.each( draggable.sortables, function() {
   2432 						this.refreshPositions();
   2433 					});
   2434 				}
   2435 			}
   2436 		});
   2437 	}
   2438 });
   2439 
   2440 $.ui.plugin.add("draggable", "cursor", {
   2441 	start: function( event, ui, instance ) {
   2442 		var t = $( "body" ),
   2443 			o = instance.options;
   2444 
   2445 		if (t.css("cursor")) {
   2446 			o._cursor = t.css("cursor");
   2447 		}
   2448 		t.css("cursor", o.cursor);
   2449 	},
   2450 	stop: function( event, ui, instance ) {
   2451 		var o = instance.options;
   2452 		if (o._cursor) {
   2453 			$("body").css("cursor", o._cursor);
   2454 		}
   2455 	}
   2456 });
   2457 
   2458 $.ui.plugin.add("draggable", "opacity", {
   2459 	start: function( event, ui, instance ) {
   2460 		var t = $( ui.helper ),
   2461 			o = instance.options;
   2462 		if (t.css("opacity")) {
   2463 			o._opacity = t.css("opacity");
   2464 		}
   2465 		t.css("opacity", o.opacity);
   2466 	},
   2467 	stop: function( event, ui, instance ) {
   2468 		var o = instance.options;
   2469 		if (o._opacity) {
   2470 			$(ui.helper).css("opacity", o._opacity);
   2471 		}
   2472 	}
   2473 });
   2474 
   2475 $.ui.plugin.add("draggable", "scroll", {
   2476 	start: function( event, ui, i ) {
   2477 		if ( !i.scrollParentNotHidden ) {
   2478 			i.scrollParentNotHidden = i.helper.scrollParent( false );
   2479 		}
   2480 
   2481 		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
   2482 			i.overflowOffset = i.scrollParentNotHidden.offset();
   2483 		}
   2484 	},
   2485 	drag: function( event, ui, i  ) {
   2486 
   2487 		var o = i.options,
   2488 			scrolled = false,
   2489 			scrollParent = i.scrollParentNotHidden[ 0 ],
   2490 			document = i.document[ 0 ];
   2491 
   2492 		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
   2493 			if ( !o.axis || o.axis !== "x" ) {
   2494 				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
   2495 					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
   2496 				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
   2497 					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
   2498 				}
   2499 			}
   2500 
   2501 			if ( !o.axis || o.axis !== "y" ) {
   2502 				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
   2503 					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
   2504 				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
   2505 					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
   2506 				}
   2507 			}
   2508 
   2509 		} else {
   2510 
   2511 			if (!o.axis || o.axis !== "x") {
   2512 				if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
   2513 					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
   2514 				} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
   2515 					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
   2516 				}
   2517 			}
   2518 
   2519 			if (!o.axis || o.axis !== "y") {
   2520 				if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
   2521 					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
   2522 				} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
   2523 					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
   2524 				}
   2525 			}
   2526 
   2527 		}
   2528 
   2529 		if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
   2530 			$.ui.ddmanager.prepareOffsets(i, event);
   2531 		}
   2532 
   2533 	}
   2534 });
   2535 
   2536 $.ui.plugin.add("draggable", "snap", {
   2537 	start: function( event, ui, i ) {
   2538 
   2539 		var o = i.options;
   2540 
   2541 		i.snapElements = [];
   2542 
   2543 		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
   2544 			var $t = $(this),
   2545 				$o = $t.offset();
   2546 			if (this !== i.element[0]) {
   2547 				i.snapElements.push({
   2548 					item: this,
   2549 					width: $t.outerWidth(), height: $t.outerHeight(),
   2550 					top: $o.top, left: $o.left
   2551 				});
   2552 			}
   2553 		});
   2554 
   2555 	},
   2556 	drag: function( event, ui, inst ) {
   2557 
   2558 		var ts, bs, ls, rs, l, r, t, b, i, first,
   2559 			o = inst.options,
   2560 			d = o.snapTolerance,
   2561 			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
   2562 			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
   2563 
   2564 		for (i = inst.snapElements.length - 1; i >= 0; i--){
   2565 
   2566 			l = inst.snapElements[i].left - inst.margins.left;
   2567 			r = l + inst.snapElements[i].width;
   2568 			t = inst.snapElements[i].top - inst.margins.top;
   2569 			b = t + inst.snapElements[i].height;
   2570 
   2571 			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
   2572 				if (inst.snapElements[i].snapping) {
   2573 					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
   2574 				}
   2575 				inst.snapElements[i].snapping = false;
   2576 				continue;
   2577 			}
   2578 
   2579 			if (o.snapMode !== "inner") {
   2580 				ts = Math.abs(t - y2) <= d;
   2581 				bs = Math.abs(b - y1) <= d;
   2582 				ls = Math.abs(l - x2) <= d;
   2583 				rs = Math.abs(r - x1) <= d;
   2584 				if (ts) {
   2585 					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
   2586 				}
   2587 				if (bs) {
   2588 					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
   2589 				}
   2590 				if (ls) {
   2591 					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
   2592 				}
   2593 				if (rs) {
   2594 					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
   2595 				}
   2596 			}
   2597 
   2598 			first = (ts || bs || ls || rs);
   2599 
   2600 			if (o.snapMode !== "outer") {
   2601 				ts = Math.abs(t - y1) <= d;
   2602 				bs = Math.abs(b - y2) <= d;
   2603 				ls = Math.abs(l - x1) <= d;
   2604 				rs = Math.abs(r - x2) <= d;
   2605 				if (ts) {
   2606 					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
   2607 				}
   2608 				if (bs) {
   2609 					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
   2610 				}
   2611 				if (ls) {
   2612 					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
   2613 				}
   2614 				if (rs) {
   2615 					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
   2616 				}
   2617 			}
   2618 
   2619 			if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
   2620 				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
   2621 			}
   2622 			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
   2623 
   2624 		}
   2625 
   2626 	}
   2627 });
   2628 
   2629 $.ui.plugin.add("draggable", "stack", {
   2630 	start: function( event, ui, instance ) {
   2631 		var min,
   2632 			o = instance.options,
   2633 			group = $.makeArray($(o.stack)).sort(function(a, b) {
   2634 				return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
   2635 			});
   2636 
   2637 		if (!group.length) { return; }
   2638 
   2639 		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
   2640 		$(group).each(function(i) {
   2641 			$(this).css("zIndex", min + i);
   2642 		});
   2643 		this.css("zIndex", (min + group.length));
   2644 	}
   2645 });
   2646 
   2647 $.ui.plugin.add("draggable", "zIndex", {
   2648 	start: function( event, ui, instance ) {
   2649 		var t = $( ui.helper ),
   2650 			o = instance.options;
   2651 
   2652 		if (t.css("zIndex")) {
   2653 			o._zIndex = t.css("zIndex");
   2654 		}
   2655 		t.css("zIndex", o.zIndex);
   2656 	},
   2657 	stop: function( event, ui, instance ) {
   2658 		var o = instance.options;
   2659 
   2660 		if (o._zIndex) {
   2661 			$(ui.helper).css("zIndex", o._zIndex);
   2662 		}
   2663 	}
   2664 });
   2665 
   2666 var draggable = $.ui.draggable;
   2667 
   2668 
   2669 /*!
   2670  * jQuery UI Droppable 1.11.4
   2671  * http://jqueryui.com
   2672  *
   2673  * Copyright jQuery Foundation and other contributors
   2674  * Released under the MIT license.
   2675  * http://jquery.org/license
   2676  *
   2677  * http://api.jqueryui.com/droppable/
   2678  */
   2679 
   2680 
   2681 $.widget( "ui.droppable", {
   2682 	version: "1.11.4",
   2683 	widgetEventPrefix: "drop",
   2684 	options: {
   2685 		accept: "*",
   2686 		activeClass: false,
   2687 		addClasses: true,
   2688 		greedy: false,
   2689 		hoverClass: false,
   2690 		scope: "default",
   2691 		tolerance: "intersect",
   2692 
   2693 		// callbacks
   2694 		activate: null,
   2695 		deactivate: null,
   2696 		drop: null,
   2697 		out: null,
   2698 		over: null
   2699 	},
   2700 	_create: function() {
   2701 
   2702 		var proportions,
   2703 			o = this.options,
   2704 			accept = o.accept;
   2705 
   2706 		this.isover = false;
   2707 		this.isout = true;
   2708 
   2709 		this.accept = $.isFunction( accept ) ? accept : function( d ) {
   2710 			return d.is( accept );
   2711 		};
   2712 
   2713 		this.proportions = function( /* valueToWrite */ ) {
   2714 			if ( arguments.length ) {
   2715 				// Store the droppable's proportions
   2716 				proportions = arguments[ 0 ];
   2717 			} else {
   2718 				// Retrieve or derive the droppable's proportions
   2719 				return proportions ?
   2720 					proportions :
   2721 					proportions = {
   2722 						width: this.element[ 0 ].offsetWidth,
   2723 						height: this.element[ 0 ].offsetHeight
   2724 					};
   2725 			}
   2726 		};
   2727 
   2728 		this._addToManager( o.scope );
   2729 
   2730 		o.addClasses && this.element.addClass( "ui-droppable" );
   2731 
   2732 	},
   2733 
   2734 	_addToManager: function( scope ) {
   2735 		// Add the reference and positions to the manager
   2736 		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
   2737 		$.ui.ddmanager.droppables[ scope ].push( this );
   2738 	},
   2739 
   2740 	_splice: function( drop ) {
   2741 		var i = 0;
   2742 		for ( ; i < drop.length; i++ ) {
   2743 			if ( drop[ i ] === this ) {
   2744 				drop.splice( i, 1 );
   2745 			}
   2746 		}
   2747 	},
   2748 
   2749 	_destroy: function() {
   2750 		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
   2751 
   2752 		this._splice( drop );
   2753 
   2754 		this.element.removeClass( "ui-droppable ui-droppable-disabled" );
   2755 	},
   2756 
   2757 	_setOption: function( key, value ) {
   2758 
   2759 		if ( key === "accept" ) {
   2760 			this.accept = $.isFunction( value ) ? value : function( d ) {
   2761 				return d.is( value );
   2762 			};
   2763 		} else if ( key === "scope" ) {
   2764 			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
   2765 
   2766 			this._splice( drop );
   2767 			this._addToManager( value );
   2768 		}
   2769 
   2770 		this._super( key, value );
   2771 	},
   2772 
   2773 	_activate: function( event ) {
   2774 		var draggable = $.ui.ddmanager.current;
   2775 		if ( this.options.activeClass ) {
   2776 			this.element.addClass( this.options.activeClass );
   2777 		}
   2778 		if ( draggable ){
   2779 			this._trigger( "activate", event, this.ui( draggable ) );
   2780 		}
   2781 	},
   2782 
   2783 	_deactivate: function( event ) {
   2784 		var draggable = $.ui.ddmanager.current;
   2785 		if ( this.options.activeClass ) {
   2786 			this.element.removeClass( this.options.activeClass );
   2787 		}
   2788 		if ( draggable ){
   2789 			this._trigger( "deactivate", event, this.ui( draggable ) );
   2790 		}
   2791 	},
   2792 
   2793 	_over: function( event ) {
   2794 
   2795 		var draggable = $.ui.ddmanager.current;
   2796 
   2797 		// Bail if draggable and droppable are same element
   2798 		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
   2799 			return;
   2800 		}
   2801 
   2802 		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
   2803 			if ( this.options.hoverClass ) {
   2804 				this.element.addClass( this.options.hoverClass );
   2805 			}
   2806 			this._trigger( "over", event, this.ui( draggable ) );
   2807 		}
   2808 
   2809 	},
   2810 
   2811 	_out: function( event ) {
   2812 
   2813 		var draggable = $.ui.ddmanager.current;
   2814 
   2815 		// Bail if draggable and droppable are same element
   2816 		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
   2817 			return;
   2818 		}
   2819 
   2820 		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
   2821 			if ( this.options.hoverClass ) {
   2822 				this.element.removeClass( this.options.hoverClass );
   2823 			}
   2824 			this._trigger( "out", event, this.ui( draggable ) );
   2825 		}
   2826 
   2827 	},
   2828 
   2829 	_drop: function( event, custom ) {
   2830 
   2831 		var draggable = custom || $.ui.ddmanager.current,
   2832 			childrenIntersection = false;
   2833 
   2834 		// Bail if draggable and droppable are same element
   2835 		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
   2836 			return false;
   2837 		}
   2838 
   2839 		this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
   2840 			var inst = $( this ).droppable( "instance" );
   2841 			if (
   2842 				inst.options.greedy &&
   2843 				!inst.options.disabled &&
   2844 				inst.options.scope === draggable.options.scope &&
   2845 				inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
   2846 				$.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
   2847 			) { childrenIntersection = true; return false; }
   2848 		});
   2849 		if ( childrenIntersection ) {
   2850 			return false;
   2851 		}
   2852 
   2853 		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
   2854 			if ( this.options.activeClass ) {
   2855 				this.element.removeClass( this.options.activeClass );
   2856 			}
   2857 			if ( this.options.hoverClass ) {
   2858 				this.element.removeClass( this.options.hoverClass );
   2859 			}
   2860 			this._trigger( "drop", event, this.ui( draggable ) );
   2861 			return this.element;
   2862 		}
   2863 
   2864 		return false;
   2865 
   2866 	},
   2867 
   2868 	ui: function( c ) {
   2869 		return {
   2870 			draggable: ( c.currentItem || c.element ),
   2871 			helper: c.helper,
   2872 			position: c.position,
   2873 			offset: c.positionAbs
   2874 		};
   2875 	}
   2876 
   2877 });
   2878 
   2879 $.ui.intersect = (function() {
   2880 	function isOverAxis( x, reference, size ) {
   2881 		return ( x >= reference ) && ( x < ( reference + size ) );
   2882 	}
   2883 
   2884 	return function( draggable, droppable, toleranceMode, event ) {
   2885 
   2886 		if ( !droppable.offset ) {
   2887 			return false;
   2888 		}
   2889 
   2890 		var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
   2891 			y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
   2892 			x2 = x1 + draggable.helperProportions.width,
   2893 			y2 = y1 + draggable.helperProportions.height,
   2894 			l = droppable.offset.left,
   2895 			t = droppable.offset.top,
   2896 			r = l + droppable.proportions().width,
   2897 			b = t + droppable.proportions().height;
   2898 
   2899 		switch ( toleranceMode ) {
   2900 		case "fit":
   2901 			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
   2902 		case "intersect":
   2903 			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
   2904 				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
   2905 				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
   2906 				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
   2907 		case "pointer":
   2908 			return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
   2909 		case "touch":
   2910 			return (
   2911 				( y1 >= t && y1 <= b ) || // Top edge touching
   2912 				( y2 >= t && y2 <= b ) || // Bottom edge touching
   2913 				( y1 < t && y2 > b ) // Surrounded vertically
   2914 			) && (
   2915 				( x1 >= l && x1 <= r ) || // Left edge touching
   2916 				( x2 >= l && x2 <= r ) || // Right edge touching
   2917 				( x1 < l && x2 > r ) // Surrounded horizontally
   2918 			);
   2919 		default:
   2920 			return false;
   2921 		}
   2922 	};
   2923 })();
   2924 
   2925 /*
   2926 	This manager tracks offsets of draggables and droppables
   2927 */
   2928 $.ui.ddmanager = {
   2929 	current: null,
   2930 	droppables: { "default": [] },
   2931 	prepareOffsets: function( t, event ) {
   2932 
   2933 		var i, j,
   2934 			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
   2935 			type = event ? event.type : null, // workaround for #2317
   2936 			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
   2937 
   2938 		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
   2939 
   2940 			// No disabled and non-accepted
   2941 			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
   2942 				continue;
   2943 			}
   2944 
   2945 			// Filter out elements in the current dragged item
   2946 			for ( j = 0; j < list.length; j++ ) {
   2947 				if ( list[ j ] === m[ i ].element[ 0 ] ) {
   2948 					m[ i ].proportions().height = 0;
   2949 					continue droppablesLoop;
   2950 				}
   2951 			}
   2952 
   2953 			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
   2954 			if ( !m[ i ].visible ) {
   2955 				continue;
   2956 			}
   2957 
   2958 			// Activate the droppable if used directly from draggables
   2959 			if ( type === "mousedown" ) {
   2960 				m[ i ]._activate.call( m[ i ], event );
   2961 			}
   2962 
   2963 			m[ i ].offset = m[ i ].element.offset();
   2964 			m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
   2965 
   2966 		}
   2967 
   2968 	},
   2969 	drop: function( draggable, event ) {
   2970 
   2971 		var dropped = false;
   2972 		// Create a copy of the droppables in case the list changes during the drop (#9116)
   2973 		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
   2974 
   2975 			if ( !this.options ) {
   2976 				return;
   2977 			}
   2978 			if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
   2979 				dropped = this._drop.call( this, event ) || dropped;
   2980 			}
   2981 
   2982 			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
   2983 				this.isout = true;
   2984 				this.isover = false;
   2985 				this._deactivate.call( this, event );
   2986 			}
   2987 
   2988 		});
   2989 		return dropped;
   2990 
   2991 	},
   2992 	dragStart: function( draggable, event ) {
   2993 		// Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
   2994 		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
   2995 			if ( !draggable.options.refreshPositions ) {
   2996 				$.ui.ddmanager.prepareOffsets( draggable, event );
   2997 			}
   2998 		});
   2999 	},
   3000 	drag: function( draggable, event ) {
   3001 
   3002 		// If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
   3003 		if ( draggable.options.refreshPositions ) {
   3004 			$.ui.ddmanager.prepareOffsets( draggable, event );
   3005 		}
   3006 
   3007 		// Run through all droppables and check their positions based on specific tolerance options
   3008 		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
   3009 
   3010 			if ( this.options.disabled || this.greedyChild || !this.visible ) {
   3011 				return;
   3012 			}
   3013 
   3014 			var parentInstance, scope, parent,
   3015 				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
   3016 				c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
   3017 			if ( !c ) {
   3018 				return;
   3019 			}
   3020 
   3021 			if ( this.options.greedy ) {
   3022 				// find droppable parents with same scope
   3023 				scope = this.options.scope;
   3024 				parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
   3025 					return $( this ).droppable( "instance" ).options.scope === scope;
   3026 				});
   3027 
   3028 				if ( parent.length ) {
   3029 					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
   3030 					parentInstance.greedyChild = ( c === "isover" );
   3031 				}
   3032 			}
   3033 
   3034 			// we just moved into a greedy child
   3035 			if ( parentInstance && c === "isover" ) {
   3036 				parentInstance.isover = false;
   3037 				parentInstance.isout = true;
   3038 				parentInstance._out.call( parentInstance, event );
   3039 			}
   3040 
   3041 			this[ c ] = true;
   3042 			this[c === "isout" ? "isover" : "isout"] = false;
   3043 			this[c === "isover" ? "_over" : "_out"].call( this, event );
   3044 
   3045 			// we just moved out of a greedy child
   3046 			if ( parentInstance && c === "isout" ) {
   3047 				parentInstance.isout = false;
   3048 				parentInstance.isover = true;
   3049 				parentInstance._over.call( parentInstance, event );
   3050 			}
   3051 		});
   3052 
   3053 	},
   3054 	dragStop: function( draggable, event ) {
   3055 		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
   3056 		// Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
   3057 		if ( !draggable.options.refreshPositions ) {
   3058 			$.ui.ddmanager.prepareOffsets( draggable, event );
   3059 		}
   3060 	}
   3061 };
   3062 
   3063 var droppable = $.ui.droppable;
   3064 
   3065 
   3066 /*!
   3067  * jQuery UI Resizable 1.11.4
   3068  * http://jqueryui.com
   3069  *
   3070  * Copyright jQuery Foundation and other contributors
   3071  * Released under the MIT license.
   3072  * http://jquery.org/license
   3073  *
   3074  * http://api.jqueryui.com/resizable/
   3075  */
   3076 
   3077 
   3078 $.widget("ui.resizable", $.ui.mouse, {
   3079 	version: "1.11.4",
   3080 	widgetEventPrefix: "resize",
   3081 	options: {
   3082 		alsoResize: false,
   3083 		animate: false,
   3084 		animateDuration: "slow",
   3085 		animateEasing: "swing",
   3086 		aspectRatio: false,
   3087 		autoHide: false,
   3088 		containment: false,
   3089 		ghost: false,
   3090 		grid: false,
   3091 		handles: "e,s,se",
   3092 		helper: false,
   3093 		maxHeight: null,
   3094 		maxWidth: null,
   3095 		minHeight: 10,
   3096 		minWidth: 10,
   3097 		// See #7960
   3098 		zIndex: 90,
   3099 
   3100 		// callbacks
   3101 		resize: null,
   3102 		start: null,
   3103 		stop: null
   3104 	},
   3105 
   3106 	_num: function( value ) {
   3107 		return parseInt( value, 10 ) || 0;
   3108 	},
   3109 
   3110 	_isNumber: function( value ) {
   3111 		return !isNaN( parseInt( value, 10 ) );
   3112 	},
   3113 
   3114 	_hasScroll: function( el, a ) {
   3115 
   3116 		if ( $( el ).css( "overflow" ) === "hidden") {
   3117 			return false;
   3118 		}
   3119 
   3120 		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
   3121 			has = false;
   3122 
   3123 		if ( el[ scroll ] > 0 ) {
   3124 			return true;
   3125 		}
   3126 
   3127 		// TODO: determine which cases actually cause this to happen
   3128 		// if the element doesn't have the scroll set, see if it's possible to
   3129 		// set the scroll
   3130 		el[ scroll ] = 1;
   3131 		has = ( el[ scroll ] > 0 );
   3132 		el[ scroll ] = 0;
   3133 		return has;
   3134 	},
   3135 
   3136 	_create: function() {
   3137 
   3138 		var n, i, handle, axis, hname,
   3139 			that = this,
   3140 			o = this.options;
   3141 		this.element.addClass("ui-resizable");
   3142 
   3143 		$.extend(this, {
   3144 			_aspectRatio: !!(o.aspectRatio),
   3145 			aspectRatio: o.aspectRatio,
   3146 			originalElement: this.element,
   3147 			_proportionallyResizeElements: [],
   3148 			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
   3149 		});
   3150 
   3151 		// Wrap the element if it cannot hold child nodes
   3152 		if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
   3153 
   3154 			this.element.wrap(
   3155 				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
   3156 					position: this.element.css("position"),
   3157 					width: this.element.outerWidth(),
   3158 					height: this.element.outerHeight(),
   3159 					top: this.element.css("top"),
   3160 					left: this.element.css("left")
   3161 				})
   3162 			);
   3163 
   3164 			this.element = this.element.parent().data(
   3165 				"ui-resizable", this.element.resizable( "instance" )
   3166 			);
   3167 
   3168 			this.elementIsWrapper = true;
   3169 
   3170 			this.element.css({
   3171 				marginLeft: this.originalElement.css("marginLeft"),
   3172 				marginTop: this.originalElement.css("marginTop"),
   3173 				marginRight: this.originalElement.css("marginRight"),
   3174 				marginBottom: this.originalElement.css("marginBottom")
   3175 			});
   3176 			this.originalElement.css({
   3177 				marginLeft: 0,
   3178 				marginTop: 0,
   3179 				marginRight: 0,
   3180 				marginBottom: 0
   3181 			});
   3182 			// support: Safari
   3183 			// Prevent Safari textarea resize
   3184 			this.originalResizeStyle = this.originalElement.css("resize");
   3185 			this.originalElement.css("resize", "none");
   3186 
   3187 			this._proportionallyResizeElements.push( this.originalElement.css({
   3188 				position: "static",
   3189 				zoom: 1,
   3190 				display: "block"
   3191 			}) );
   3192 
   3193 			// support: IE9
   3194 			// avoid IE jump (hard set the margin)
   3195 			this.originalElement.css({ margin: this.originalElement.css("margin") });
   3196 
   3197 			this._proportionallyResize();
   3198 		}
   3199 
   3200 		this.handles = o.handles ||
   3201 			( !$(".ui-resizable-handle", this.element).length ?
   3202 				"e,s,se" : {
   3203 					n: ".ui-resizable-n",
   3204 					e: ".ui-resizable-e",
   3205 					s: ".ui-resizable-s",
   3206 					w: ".ui-resizable-w",
   3207 					se: ".ui-resizable-se",
   3208 					sw: ".ui-resizable-sw",
   3209 					ne: ".ui-resizable-ne",
   3210 					nw: ".ui-resizable-nw"
   3211 				} );
   3212 
   3213 		this._handles = $();
   3214 		if ( this.handles.constructor === String ) {
   3215 
   3216 			if ( this.handles === "all") {
   3217 				this.handles = "n,e,s,w,se,sw,ne,nw";
   3218 			}
   3219 
   3220 			n = this.handles.split(",");
   3221 			this.handles = {};
   3222 
   3223 			for (i = 0; i < n.length; i++) {
   3224 
   3225 				handle = $.trim(n[i]);
   3226 				hname = "ui-resizable-" + handle;
   3227 				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
   3228 
   3229 				axis.css({ zIndex: o.zIndex });
   3230 
   3231 				// TODO : What's going on here?
   3232 				if ("se" === handle) {
   3233 					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
   3234 				}
   3235 
   3236 				this.handles[handle] = ".ui-resizable-" + handle;
   3237 				this.element.append(axis);
   3238 			}
   3239 
   3240 		}
   3241 
   3242 		this._renderAxis = function(target) {
   3243 
   3244 			var i, axis, padPos, padWrapper;
   3245 
   3246 			target = target || this.element;
   3247 
   3248 			for (i in this.handles) {
   3249 
   3250 				if (this.handles[i].constructor === String) {
   3251 					this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
   3252 				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
   3253 					this.handles[ i ] = $( this.handles[ i ] );
   3254 					this._on( this.handles[ i ], { "mousedown": that._mouseDown });
   3255 				}
   3256 
   3257 				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
   3258 
   3259 					axis = $(this.handles[i], this.element);
   3260 
   3261 					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
   3262 
   3263 					padPos = [ "padding",
   3264 						/ne|nw|n/.test(i) ? "Top" :
   3265 						/se|sw|s/.test(i) ? "Bottom" :
   3266 						/^e$/.test(i) ? "Right" : "Left" ].join("");
   3267 
   3268 					target.css(padPos, padWrapper);
   3269 
   3270 					this._proportionallyResize();
   3271 				}
   3272 
   3273 				this._handles = this._handles.add( this.handles[ i ] );
   3274 			}
   3275 		};
   3276 
   3277 		// TODO: make renderAxis a prototype function
   3278 		this._renderAxis(this.element);
   3279 
   3280 		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
   3281 		this._handles.disableSelection();
   3282 
   3283 		this._handles.mouseover(function() {
   3284 			if (!that.resizing) {
   3285 				if (this.className) {
   3286 					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
   3287 				}
   3288 				that.axis = axis && axis[1] ? axis[1] : "se";
   3289 			}
   3290 		});
   3291 
   3292 		if (o.autoHide) {
   3293 			this._handles.hide();
   3294 			$(this.element)
   3295 				.addClass("ui-resizable-autohide")
   3296 				.mouseenter(function() {
   3297 					if (o.disabled) {
   3298 						return;
   3299 					}
   3300 					$(this).removeClass("ui-resizable-autohide");
   3301 					that._handles.show();
   3302 				})
   3303 				.mouseleave(function() {
   3304 					if (o.disabled) {
   3305 						return;
   3306 					}
   3307 					if (!that.resizing) {
   3308 						$(this).addClass("ui-resizable-autohide");
   3309 						that._handles.hide();
   3310 					}
   3311 				});
   3312 		}
   3313 
   3314 		this._mouseInit();
   3315 	},
   3316 
   3317 	_destroy: function() {
   3318 
   3319 		this._mouseDestroy();
   3320 
   3321 		var wrapper,
   3322 			_destroy = function(exp) {
   3323 				$(exp)
   3324 					.removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
   3325 					.removeData("resizable")
   3326 					.removeData("ui-resizable")
   3327 					.unbind(".resizable")
   3328 					.find(".ui-resizable-handle")
   3329 						.remove();
   3330 			};
   3331 
   3332 		// TODO: Unwrap at same DOM position
   3333 		if (this.elementIsWrapper) {
   3334 			_destroy(this.element);
   3335 			wrapper = this.element;
   3336 			this.originalElement.css({
   3337 				position: wrapper.css("position"),
   3338 				width: wrapper.outerWidth(),
   3339 				height: wrapper.outerHeight(),
   3340 				top: wrapper.css("top"),
   3341 				left: wrapper.css("left")
   3342 			}).insertAfter( wrapper );
   3343 			wrapper.remove();
   3344 		}
   3345 
   3346 		this.originalElement.css("resize", this.originalResizeStyle);
   3347 		_destroy(this.originalElement);
   3348 
   3349 		return this;
   3350 	},
   3351 
   3352 	_mouseCapture: function(event) {
   3353 		var i, handle,
   3354 			capture = false;
   3355 
   3356 		for (i in this.handles) {
   3357 			handle = $(this.handles[i])[0];
   3358 			if (handle === event.target || $.contains(handle, event.target)) {
   3359 				capture = true;
   3360 			}
   3361 		}
   3362 
   3363 		return !this.options.disabled && capture;
   3364 	},
   3365 
   3366 	_mouseStart: function(event) {
   3367 
   3368 		var curleft, curtop, cursor,
   3369 			o = this.options,
   3370 			el = this.element;
   3371 
   3372 		this.resizing = true;
   3373 
   3374 		this._renderProxy();
   3375 
   3376 		curleft = this._num(this.helper.css("left"));
   3377 		curtop = this._num(this.helper.css("top"));
   3378 
   3379 		if (o.containment) {
   3380 			curleft += $(o.containment).scrollLeft() || 0;
   3381 			curtop += $(o.containment).scrollTop() || 0;
   3382 		}
   3383 
   3384 		this.offset = this.helper.offset();
   3385 		this.position = { left: curleft, top: curtop };
   3386 
   3387 		this.size = this._helper ? {
   3388 				width: this.helper.width(),
   3389 				height: this.helper.height()
   3390 			} : {
   3391 				width: el.width(),
   3392 				height: el.height()
   3393 			};
   3394 
   3395 		this.originalSize = this._helper ? {
   3396 				width: el.outerWidth(),
   3397 				height: el.outerHeight()
   3398 			} : {
   3399 				width: el.width(),
   3400 				height: el.height()
   3401 			};
   3402 
   3403 		this.sizeDiff = {
   3404 			width: el.outerWidth() - el.width(),
   3405 			height: el.outerHeight() - el.height()
   3406 		};
   3407 
   3408 		this.originalPosition = { left: curleft, top: curtop };
   3409 		this.originalMousePosition = { left: event.pageX, top: event.pageY };
   3410 
   3411 		this.aspectRatio = (typeof o.aspectRatio === "number") ?
   3412 			o.aspectRatio :
   3413 			((this.originalSize.width / this.originalSize.height) || 1);
   3414 
   3415 		cursor = $(".ui-resizable-" + this.axis).css("cursor");
   3416 		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
   3417 
   3418 		el.addClass("ui-resizable-resizing");
   3419 		this._propagate("start", event);
   3420 		return true;
   3421 	},
   3422 
   3423 	_mouseDrag: function(event) {
   3424 
   3425 		var data, props,
   3426 			smp = this.originalMousePosition,
   3427 			a = this.axis,
   3428 			dx = (event.pageX - smp.left) || 0,
   3429 			dy = (event.pageY - smp.top) || 0,
   3430 			trigger = this._change[a];
   3431 
   3432 		this._updatePrevProperties();
   3433 
   3434 		if (!trigger) {
   3435 			return false;
   3436 		}
   3437 
   3438 		data = trigger.apply(this, [ event, dx, dy ]);
   3439 
   3440 		this._updateVirtualBoundaries(event.shiftKey);
   3441 		if (this._aspectRatio || event.shiftKey) {
   3442 			data = this._updateRatio(data, event);
   3443 		}
   3444 
   3445 		data = this._respectSize(data, event);
   3446 
   3447 		this._updateCache(data);
   3448 
   3449 		this._propagate("resize", event);
   3450 
   3451 		props = this._applyChanges();
   3452 
   3453 		if ( !this._helper && this._proportionallyResizeElements.length ) {
   3454 			this._proportionallyResize();
   3455 		}
   3456 
   3457 		if ( !$.isEmptyObject( props ) ) {
   3458 			this._updatePrevProperties();
   3459 			this._trigger( "resize", event, this.ui() );
   3460 			this._applyChanges();
   3461 		}
   3462 
   3463 		return false;
   3464 	},
   3465 
   3466 	_mouseStop: function(event) {
   3467 
   3468 		this.resizing = false;
   3469 		var pr, ista, soffseth, soffsetw, s, left, top,
   3470 			o = this.options, that = this;
   3471 
   3472 		if (this._helper) {
   3473 
   3474 			pr = this._proportionallyResizeElements;
   3475 			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
   3476 			soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
   3477 			soffsetw = ista ? 0 : that.sizeDiff.width;
   3478 
   3479 			s = {
   3480 				width: (that.helper.width()  - soffsetw),
   3481 				height: (that.helper.height() - soffseth)
   3482 			};
   3483 			left = (parseInt(that.element.css("left"), 10) +
   3484 				(that.position.left - that.originalPosition.left)) || null;
   3485 			top = (parseInt(that.element.css("top"), 10) +
   3486 				(that.position.top - that.originalPosition.top)) || null;
   3487 
   3488 			if (!o.animate) {
   3489 				this.element.css($.extend(s, { top: top, left: left }));
   3490 			}
   3491 
   3492 			that.helper.height(that.size.height);
   3493 			that.helper.width(that.size.width);
   3494 
   3495 			if (this._helper && !o.animate) {
   3496 				this._proportionallyResize();
   3497 			}
   3498 		}
   3499 
   3500 		$("body").css("cursor", "auto");
   3501 
   3502 		this.element.removeClass("ui-resizable-resizing");
   3503 
   3504 		this._propagate("stop", event);
   3505 
   3506 		if (this._helper) {
   3507 			this.helper.remove();
   3508 		}
   3509 
   3510 		return false;
   3511 
   3512 	},
   3513 
   3514 	_updatePrevProperties: function() {
   3515 		this.prevPosition = {
   3516 			top: this.position.top,
   3517 			left: this.position.left
   3518 		};
   3519 		this.prevSize = {
   3520 			width: this.size.width,
   3521 			height: this.size.height
   3522 		};
   3523 	},
   3524 
   3525 	_applyChanges: function() {
   3526 		var props = {};
   3527 
   3528 		if ( this.position.top !== this.prevPosition.top ) {
   3529 			props.top = this.position.top + "px";
   3530 		}
   3531 		if ( this.position.left !== this.prevPosition.left ) {
   3532 			props.left = this.position.left + "px";
   3533 		}
   3534 		if ( this.size.width !== this.prevSize.width ) {
   3535 			props.width = this.size.width + "px";
   3536 		}
   3537 		if ( this.size.height !== this.prevSize.height ) {
   3538 			props.height = this.size.height + "px";
   3539 		}
   3540 
   3541 		this.helper.css( props );
   3542 
   3543 		return props;
   3544 	},
   3545 
   3546 	_updateVirtualBoundaries: function(forceAspectRatio) {
   3547 		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
   3548 			o = this.options;
   3549 
   3550 		b = {
   3551 			minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
   3552 			maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
   3553 			minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
   3554 			maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
   3555 		};
   3556 
   3557 		if (this._aspectRatio || forceAspectRatio) {
   3558 			pMinWidth = b.minHeight * this.aspectRatio;
   3559 			pMinHeight = b.minWidth / this.aspectRatio;
   3560 			pMaxWidth = b.maxHeight * this.aspectRatio;
   3561 			pMaxHeight = b.maxWidth / this.aspectRatio;
   3562 
   3563 			if (pMinWidth > b.minWidth) {
   3564 				b.minWidth = pMinWidth;
   3565 			}
   3566 			if (pMinHeight > b.minHeight) {
   3567 				b.minHeight = pMinHeight;
   3568 			}
   3569 			if (pMaxWidth < b.maxWidth) {
   3570 				b.maxWidth = pMaxWidth;
   3571 			}
   3572 			if (pMaxHeight < b.maxHeight) {
   3573 				b.maxHeight = pMaxHeight;
   3574 			}
   3575 		}
   3576 		this._vBoundaries = b;
   3577 	},
   3578 
   3579 	_updateCache: function(data) {
   3580 		this.offset = this.helper.offset();
   3581 		if (this._isNumber(data.left)) {
   3582 			this.position.left = data.left;
   3583 		}
   3584 		if (this._isNumber(data.top)) {
   3585 			this.position.top = data.top;
   3586 		}
   3587 		if (this._isNumber(data.height)) {
   3588 			this.size.height = data.height;
   3589 		}
   3590 		if (this._isNumber(data.width)) {
   3591 			this.size.width = data.width;
   3592 		}
   3593 	},
   3594 
   3595 	_updateRatio: function( data ) {
   3596 
   3597 		var cpos = this.position,
   3598 			csize = this.size,
   3599 			a = this.axis;
   3600 
   3601 		if (this._isNumber(data.height)) {
   3602 			data.width = (data.height * this.aspectRatio);
   3603 		} else if (this._isNumber(data.width)) {
   3604 			data.height = (data.width / this.aspectRatio);
   3605 		}
   3606 
   3607 		if (a === "sw") {
   3608 			data.left = cpos.left + (csize.width - data.width);
   3609 			data.top = null;
   3610 		}
   3611 		if (a === "nw") {
   3612 			data.top = cpos.top + (csize.height - data.height);
   3613 			data.left = cpos.left + (csize.width - data.width);
   3614 		}
   3615 
   3616 		return data;
   3617 	},
   3618 
   3619 	_respectSize: function( data ) {
   3620 
   3621 		var o = this._vBoundaries,
   3622 			a = this.axis,
   3623 			ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
   3624 			ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
   3625 			isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
   3626 			isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
   3627 			dw = this.originalPosition.left + this.originalSize.width,
   3628 			dh = this.position.top + this.size.height,
   3629 			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
   3630 		if (isminw) {
   3631 			data.width = o.minWidth;
   3632 		}
   3633 		if (isminh) {
   3634 			data.height = o.minHeight;
   3635 		}
   3636 		if (ismaxw) {
   3637 			data.width = o.maxWidth;
   3638 		}
   3639 		if (ismaxh) {
   3640 			data.height = o.maxHeight;
   3641 		}
   3642 
   3643 		if (isminw && cw) {
   3644 			data.left = dw - o.minWidth;
   3645 		}
   3646 		if (ismaxw && cw) {
   3647 			data.left = dw - o.maxWidth;
   3648 		}
   3649 		if (isminh && ch) {
   3650 			data.top = dh - o.minHeight;
   3651 		}
   3652 		if (ismaxh && ch) {
   3653 			data.top = dh - o.maxHeight;
   3654 		}
   3655 
   3656 		// Fixing jump error on top/left - bug #2330
   3657 		if (!data.width && !data.height && !data.left && data.top) {
   3658 			data.top = null;
   3659 		} else if (!data.width && !data.height && !data.top && data.left) {
   3660 			data.left = null;
   3661 		}
   3662 
   3663 		return data;
   3664 	},
   3665 
   3666 	_getPaddingPlusBorderDimensions: function( element ) {
   3667 		var i = 0,
   3668 			widths = [],
   3669 			borders = [
   3670 				element.css( "borderTopWidth" ),
   3671 				element.css( "borderRightWidth" ),
   3672 				element.css( "borderBottomWidth" ),
   3673 				element.css( "borderLeftWidth" )
   3674 			],
   3675 			paddings = [
   3676 				element.css( "paddingTop" ),
   3677 				element.css( "paddingRight" ),
   3678 				element.css( "paddingBottom" ),
   3679 				element.css( "paddingLeft" )
   3680 			];
   3681 
   3682 		for ( ; i < 4; i++ ) {
   3683 			widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
   3684 			widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
   3685 		}
   3686 
   3687 		return {
   3688 			height: widths[ 0 ] + widths[ 2 ],
   3689 			width: widths[ 1 ] + widths[ 3 ]
   3690 		};
   3691 	},
   3692 
   3693 	_proportionallyResize: function() {
   3694 
   3695 		if (!this._proportionallyResizeElements.length) {
   3696 			return;
   3697 		}
   3698 
   3699 		var prel,
   3700 			i = 0,
   3701 			element = this.helper || this.element;
   3702 
   3703 		for ( ; i < this._proportionallyResizeElements.length; i++) {
   3704 
   3705 			prel = this._proportionallyResizeElements[i];
   3706 
   3707 			// TODO: Seems like a bug to cache this.outerDimensions
   3708 			// considering that we are in a loop.
   3709 			if (!this.outerDimensions) {
   3710 				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
   3711 			}
   3712 
   3713 			prel.css({
   3714 				height: (element.height() - this.outerDimensions.height) || 0,
   3715 				width: (element.width() - this.outerDimensions.width) || 0
   3716 			});
   3717 
   3718 		}
   3719 
   3720 	},
   3721 
   3722 	_renderProxy: function() {
   3723 
   3724 		var el = this.element, o = this.options;
   3725 		this.elementOffset = el.offset();
   3726 
   3727 		if (this._helper) {
   3728 
   3729 			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
   3730 
   3731 			this.helper.addClass(this._helper).css({
   3732 				width: this.element.outerWidth() - 1,
   3733 				height: this.element.outerHeight() - 1,
   3734 				position: "absolute",
   3735 				left: this.elementOffset.left + "px",
   3736 				top: this.elementOffset.top + "px",
   3737 				zIndex: ++o.zIndex //TODO: Don't modify option
   3738 			});
   3739 
   3740 			this.helper
   3741 				.appendTo("body")
   3742 				.disableSelection();
   3743 
   3744 		} else {
   3745 			this.helper = this.element;
   3746 		}
   3747 
   3748 	},
   3749 
   3750 	_change: {
   3751 		e: function(event, dx) {
   3752 			return { width: this.originalSize.width + dx };
   3753 		},
   3754 		w: function(event, dx) {
   3755 			var cs = this.originalSize, sp = this.originalPosition;
   3756 			return { left: sp.left + dx, width: cs.width - dx };
   3757 		},
   3758 		n: function(event, dx, dy) {
   3759 			var cs = this.originalSize, sp = this.originalPosition;
   3760 			return { top: sp.top + dy, height: cs.height - dy };
   3761 		},
   3762 		s: function(event, dx, dy) {
   3763 			return { height: this.originalSize.height + dy };
   3764 		},
   3765 		se: function(event, dx, dy) {
   3766 			return $.extend(this._change.s.apply(this, arguments),
   3767 				this._change.e.apply(this, [ event, dx, dy ]));
   3768 		},
   3769 		sw: function(event, dx, dy) {
   3770 			return $.extend(this._change.s.apply(this, arguments),
   3771 				this._change.w.apply(this, [ event, dx, dy ]));
   3772 		},
   3773 		ne: function(event, dx, dy) {
   3774 			return $.extend(this._change.n.apply(this, arguments),
   3775 				this._change.e.apply(this, [ event, dx, dy ]));
   3776 		},
   3777 		nw: function(event, dx, dy) {
   3778 			return $.extend(this._change.n.apply(this, arguments),
   3779 				this._change.w.apply(this, [ event, dx, dy ]));
   3780 		}
   3781 	},
   3782 
   3783 	_propagate: function(n, event) {
   3784 		$.ui.plugin.call(this, n, [ event, this.ui() ]);
   3785 		(n !== "resize" && this._trigger(n, event, this.ui()));
   3786 	},
   3787 
   3788 	plugins: {},
   3789 
   3790 	ui: function() {
   3791 		return {
   3792 			originalElement: this.originalElement,
   3793 			element: this.element,
   3794 			helper: this.helper,
   3795 			position: this.position,
   3796 			size: this.size,
   3797 			originalSize: this.originalSize,
   3798 			originalPosition: this.originalPosition
   3799 		};
   3800 	}
   3801 
   3802 });
   3803 
   3804 /*
   3805  * Resizable Extensions
   3806  */
   3807 
   3808 $.ui.plugin.add("resizable", "animate", {
   3809 
   3810 	stop: function( event ) {
   3811 		var that = $(this).resizable( "instance" ),
   3812 			o = that.options,
   3813 			pr = that._proportionallyResizeElements,
   3814 			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
   3815 			soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
   3816 			soffsetw = ista ? 0 : that.sizeDiff.width,
   3817 			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
   3818 			left = (parseInt(that.element.css("left"), 10) +
   3819 				(that.position.left - that.originalPosition.left)) || null,
   3820 			top = (parseInt(that.element.css("top"), 10) +
   3821 				(that.position.top - that.originalPosition.top)) || null;
   3822 
   3823 		that.element.animate(
   3824 			$.extend(style, top && left ? { top: top, left: left } : {}), {
   3825 				duration: o.animateDuration,
   3826 				easing: o.animateEasing,
   3827 				step: function() {
   3828 
   3829 					var data = {
   3830 						width: parseInt(that.element.css("width"), 10),
   3831 						height: parseInt(that.element.css("height"), 10),
   3832 						top: parseInt(that.element.css("top"), 10),
   3833 						left: parseInt(that.element.css("left"), 10)
   3834 					};
   3835 
   3836 					if (pr && pr.length) {
   3837 						$(pr[0]).css({ width: data.width, height: data.height });
   3838 					}
   3839 
   3840 					// propagating resize, and updating values for each animation step
   3841 					that._updateCache(data);
   3842 					that._propagate("resize", event);
   3843 
   3844 				}
   3845 			}
   3846 		);
   3847 	}
   3848 
   3849 });
   3850 
   3851 $.ui.plugin.add( "resizable", "containment", {
   3852 
   3853 	start: function() {
   3854 		var element, p, co, ch, cw, width, height,
   3855 			that = $( this ).resizable( "instance" ),
   3856 			o = that.options,
   3857 			el = that.element,
   3858 			oc = o.containment,
   3859 			ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
   3860 
   3861 		if ( !ce ) {
   3862 			return;
   3863 		}
   3864 
   3865 		that.containerElement = $( ce );
   3866 
   3867 		if ( /document/.test( oc ) || oc === document ) {
   3868 			that.containerOffset = {
   3869 				left: 0,
   3870 				top: 0
   3871 			};
   3872 			that.containerPosition = {
   3873 				left: 0,
   3874 				top: 0
   3875 			};
   3876 
   3877 			that.parentData = {
   3878 				element: $( document ),
   3879 				left: 0,
   3880 				top: 0,
   3881 				width: $( document ).width(),
   3882 				height: $( document ).height() || document.body.parentNode.scrollHeight
   3883 			};
   3884 		} else {
   3885 			element = $( ce );
   3886 			p = [];
   3887 			$([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
   3888 				p[ i ] = that._num( element.css( "padding" + name ) );
   3889 			});
   3890 
   3891 			that.containerOffset = element.offset();
   3892 			that.containerPosition = element.position();
   3893 			that.containerSize = {
   3894 				height: ( element.innerHeight() - p[ 3 ] ),
   3895 				width: ( element.innerWidth() - p[ 1 ] )
   3896 			};
   3897 
   3898 			co = that.containerOffset;
   3899 			ch = that.containerSize.height;
   3900 			cw = that.containerSize.width;
   3901 			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
   3902 			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
   3903 
   3904 			that.parentData = {
   3905 				element: ce,
   3906 				left: co.left,
   3907 				top: co.top,
   3908 				width: width,
   3909 				height: height
   3910 			};
   3911 		}
   3912 	},
   3913 
   3914 	resize: function( event ) {
   3915 		var woset, hoset, isParent, isOffsetRelative,
   3916 			that = $( this ).resizable( "instance" ),
   3917 			o = that.options,
   3918 			co = that.containerOffset,
   3919 			cp = that.position,
   3920 			pRatio = that._aspectRatio || event.shiftKey,
   3921 			cop = {
   3922 				top: 0,
   3923 				left: 0
   3924 			},
   3925 			ce = that.containerElement,
   3926 			continueResize = true;
   3927 
   3928 		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
   3929 			cop = co;
   3930 		}
   3931 
   3932 		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
   3933 			that.size.width = that.size.width +
   3934 				( that._helper ?
   3935 					( that.position.left - co.left ) :
   3936 					( that.position.left - cop.left ) );
   3937 
   3938 			if ( pRatio ) {
   3939 				that.size.height = that.size.width / that.aspectRatio;
   3940 				continueResize = false;
   3941 			}
   3942 			that.position.left = o.helper ? co.left : 0;
   3943 		}
   3944 
   3945 		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
   3946 			that.size.height = that.size.height +
   3947 				( that._helper ?
   3948 					( that.position.top - co.top ) :
   3949 					that.position.top );
   3950 
   3951 			if ( pRatio ) {
   3952 				that.size.width = that.size.height * that.aspectRatio;
   3953 				continueResize = false;
   3954 			}
   3955 			that.position.top = that._helper ? co.top : 0;
   3956 		}
   3957 
   3958 		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
   3959 		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
   3960 
   3961 		if ( isParent && isOffsetRelative ) {
   3962 			that.offset.left = that.parentData.left + that.position.left;
   3963 			that.offset.top = that.parentData.top + that.position.top;
   3964 		} else {
   3965 			that.offset.left = that.element.offset().left;
   3966 			that.offset.top = that.element.offset().top;
   3967 		}
   3968 
   3969 		woset = Math.abs( that.sizeDiff.width +
   3970 			(that._helper ?
   3971 				that.offset.left - cop.left :
   3972 				(that.offset.left - co.left)) );
   3973 
   3974 		hoset = Math.abs( that.sizeDiff.height +
   3975 			(that._helper ?
   3976 				that.offset.top - cop.top :
   3977 				(that.offset.top - co.top)) );
   3978 
   3979 		if ( woset + that.size.width >= that.parentData.width ) {
   3980 			that.size.width = that.parentData.width - woset;
   3981 			if ( pRatio ) {
   3982 				that.size.height = that.size.width / that.aspectRatio;
   3983 				continueResize = false;
   3984 			}
   3985 		}
   3986 
   3987 		if ( hoset + that.size.height >= that.parentData.height ) {
   3988 			that.size.height = that.parentData.height - hoset;
   3989 			if ( pRatio ) {
   3990 				that.size.width = that.size.height * that.aspectRatio;
   3991 				continueResize = false;
   3992 			}
   3993 		}
   3994 
   3995 		if ( !continueResize ) {
   3996 			that.position.left = that.prevPosition.left;
   3997 			that.position.top = that.prevPosition.top;
   3998 			that.size.width = that.prevSize.width;
   3999 			that.size.height = that.prevSize.height;
   4000 		}
   4001 	},
   4002 
   4003 	stop: function() {
   4004 		var that = $( this ).resizable( "instance" ),
   4005 			o = that.options,
   4006 			co = that.containerOffset,
   4007 			cop = that.containerPosition,
   4008 			ce = that.containerElement,
   4009 			helper = $( that.helper ),
   4010 			ho = helper.offset(),
   4011 			w = helper.outerWidth() - that.sizeDiff.width,
   4012 			h = helper.outerHeight() - that.sizeDiff.height;
   4013 
   4014 		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
   4015 			$( this ).css({
   4016 				left: ho.left - cop.left - co.left,
   4017 				width: w,
   4018 				height: h
   4019 			});
   4020 		}
   4021 
   4022 		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
   4023 			$( this ).css({
   4024 				left: ho.left - cop.left - co.left,
   4025 				width: w,
   4026 				height: h
   4027 			});
   4028 		}
   4029 	}
   4030 });
   4031 
   4032 $.ui.plugin.add("resizable", "alsoResize", {
   4033 
   4034 	start: function() {
   4035 		var that = $(this).resizable( "instance" ),
   4036 			o = that.options;
   4037 
   4038 		$(o.alsoResize).each(function() {
   4039 			var el = $(this);
   4040 			el.data("ui-resizable-alsoresize", {
   4041 				width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
   4042 				left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
   4043 			});
   4044 		});
   4045 	},
   4046 
   4047 	resize: function(event, ui) {
   4048 		var that = $(this).resizable( "instance" ),
   4049 			o = that.options,
   4050 			os = that.originalSize,
   4051 			op = that.originalPosition,
   4052 			delta = {
   4053 				height: (that.size.height - os.height) || 0,
   4054 				width: (that.size.width - os.width) || 0,
   4055 				top: (that.position.top - op.top) || 0,
   4056 				left: (that.position.left - op.left) || 0
   4057 			};
   4058 
   4059 			$(o.alsoResize).each(function() {
   4060 				var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
   4061 					css = el.parents(ui.originalElement[0]).length ?
   4062 							[ "width", "height" ] :
   4063 							[ "width", "height", "top", "left" ];
   4064 
   4065 				$.each(css, function(i, prop) {
   4066 					var sum = (start[prop] || 0) + (delta[prop] || 0);
   4067 					if (sum && sum >= 0) {
   4068 						style[prop] = sum || null;
   4069 					}
   4070 				});
   4071 
   4072 				el.css(style);
   4073 			});
   4074 	},
   4075 
   4076 	stop: function() {
   4077 		$(this).removeData("resizable-alsoresize");
   4078 	}
   4079 });
   4080 
   4081 $.ui.plugin.add("resizable", "ghost", {
   4082 
   4083 	start: function() {
   4084 
   4085 		var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
   4086 
   4087 		that.ghost = that.originalElement.clone();
   4088 		that.ghost
   4089 			.css({
   4090 				opacity: 0.25,
   4091 				display: "block",
   4092 				position: "relative",
   4093 				height: cs.height,
   4094 				width: cs.width,
   4095 				margin: 0,
   4096 				left: 0,
   4097 				top: 0
   4098 			})
   4099 			.addClass("ui-resizable-ghost")
   4100 			.addClass(typeof o.ghost === "string" ? o.ghost : "");
   4101 
   4102 		that.ghost.appendTo(that.helper);
   4103 
   4104 	},
   4105 
   4106 	resize: function() {
   4107 		var that = $(this).resizable( "instance" );
   4108 		if (that.ghost) {
   4109 			that.ghost.css({
   4110 				position: "relative",
   4111 				height: that.size.height,
   4112 				width: that.size.width
   4113 			});
   4114 		}
   4115 	},
   4116 
   4117 	stop: function() {
   4118 		var that = $(this).resizable( "instance" );
   4119 		if (that.ghost && that.helper) {
   4120 			that.helper.get(0).removeChild(that.ghost.get(0));
   4121 		}
   4122 	}
   4123 
   4124 });
   4125 
   4126 $.ui.plugin.add("resizable", "grid", {
   4127 
   4128 	resize: function() {
   4129 		var outerDimensions,
   4130 			that = $(this).resizable( "instance" ),
   4131 			o = that.options,
   4132 			cs = that.size,
   4133 			os = that.originalSize,
   4134 			op = that.originalPosition,
   4135 			a = that.axis,
   4136 			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
   4137 			gridX = (grid[0] || 1),
   4138 			gridY = (grid[1] || 1),
   4139 			ox = Math.round((cs.width - os.width) / gridX) * gridX,
   4140 			oy = Math.round((cs.height - os.height) / gridY) * gridY,
   4141 			newWidth = os.width + ox,
   4142 			newHeight = os.height + oy,
   4143 			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
   4144 			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
   4145 			isMinWidth = o.minWidth && (o.minWidth > newWidth),
   4146 			isMinHeight = o.minHeight && (o.minHeight > newHeight);
   4147 
   4148 		o.grid = grid;
   4149 
   4150 		if (isMinWidth) {
   4151 			newWidth += gridX;
   4152 		}
   4153 		if (isMinHeight) {
   4154 			newHeight += gridY;
   4155 		}
   4156 		if (isMaxWidth) {
   4157 			newWidth -= gridX;
   4158 		}
   4159 		if (isMaxHeight) {
   4160 			newHeight -= gridY;
   4161 		}
   4162 
   4163 		if (/^(se|s|e)$/.test(a)) {
   4164 			that.size.width = newWidth;
   4165 			that.size.height = newHeight;
   4166 		} else if (/^(ne)$/.test(a)) {
   4167 			that.size.width = newWidth;
   4168 			that.size.height = newHeight;
   4169 			that.position.top = op.top - oy;
   4170 		} else if (/^(sw)$/.test(a)) {
   4171 			that.size.width = newWidth;
   4172 			that.size.height = newHeight;
   4173 			that.position.left = op.left - ox;
   4174 		} else {
   4175 			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
   4176 				outerDimensions = that._getPaddingPlusBorderDimensions( this );
   4177 			}
   4178 
   4179 			if ( newHeight - gridY > 0 ) {
   4180 				that.size.height = newHeight;
   4181 				that.position.top = op.top - oy;
   4182 			} else {
   4183 				newHeight = gridY - outerDimensions.height;
   4184 				that.size.height = newHeight;
   4185 				that.position.top = op.top + os.height - newHeight;
   4186 			}
   4187 			if ( newWidth - gridX > 0 ) {
   4188 				that.size.width = newWidth;
   4189 				that.position.left = op.left - ox;
   4190 			} else {
   4191 				newWidth = gridX - outerDimensions.width;
   4192 				that.size.width = newWidth;
   4193 				that.position.left = op.left + os.width - newWidth;
   4194 			}
   4195 		}
   4196 	}
   4197 
   4198 });
   4199 
   4200 var resizable = $.ui.resizable;
   4201 
   4202 
   4203 /*!
   4204  * jQuery UI Selectable 1.11.4
   4205  * http://jqueryui.com
   4206  *
   4207  * Copyright jQuery Foundation and other contributors
   4208  * Released under the MIT license.
   4209  * http://jquery.org/license
   4210  *
   4211  * http://api.jqueryui.com/selectable/
   4212  */
   4213 
   4214 
   4215 var selectable = $.widget("ui.selectable", $.ui.mouse, {
   4216 	version: "1.11.4",
   4217 	options: {
   4218 		appendTo: "body",
   4219 		autoRefresh: true,
   4220 		distance: 0,
   4221 		filter: "*",
   4222 		tolerance: "touch",
   4223 
   4224 		// callbacks
   4225 		selected: null,
   4226 		selecting: null,
   4227 		start: null,
   4228 		stop: null,
   4229 		unselected: null,
   4230 		unselecting: null
   4231 	},
   4232 	_create: function() {
   4233 		var selectees,
   4234 			that = this;
   4235 
   4236 		this.element.addClass("ui-selectable");
   4237 
   4238 		this.dragged = false;
   4239 
   4240 		// cache selectee children based on filter
   4241 		this.refresh = function() {
   4242 			selectees = $(that.options.filter, that.element[0]);
   4243 			selectees.addClass("ui-selectee");
   4244 			selectees.each(function() {
   4245 				var $this = $(this),
   4246 					pos = $this.offset();
   4247 				$.data(this, "selectable-item", {
   4248 					element: this,
   4249 					$element: $this,
   4250 					left: pos.left,
   4251 					top: pos.top,
   4252 					right: pos.left + $this.outerWidth(),
   4253 					bottom: pos.top + $this.outerHeight(),
   4254 					startselected: false,
   4255 					selected: $this.hasClass("ui-selected"),
   4256 					selecting: $this.hasClass("ui-selecting"),
   4257 					unselecting: $this.hasClass("ui-unselecting")
   4258 				});
   4259 			});
   4260 		};
   4261 		this.refresh();
   4262 
   4263 		this.selectees = selectees.addClass("ui-selectee");
   4264 
   4265 		this._mouseInit();
   4266 
   4267 		this.helper = $("<div class='ui-selectable-helper'></div>");
   4268 	},
   4269 
   4270 	_destroy: function() {
   4271 		this.selectees
   4272 			.removeClass("ui-selectee")
   4273 			.removeData("selectable-item");
   4274 		this.element
   4275 			.removeClass("ui-selectable ui-selectable-disabled");
   4276 		this._mouseDestroy();
   4277 	},
   4278 
   4279 	_mouseStart: function(event) {
   4280 		var that = this,
   4281 			options = this.options;
   4282 
   4283 		this.opos = [ event.pageX, event.pageY ];
   4284 
   4285 		if (this.options.disabled) {
   4286 			return;
   4287 		}
   4288 
   4289 		this.selectees = $(options.filter, this.element[0]);
   4290 
   4291 		this._trigger("start", event);
   4292 
   4293 		$(options.appendTo).append(this.helper);
   4294 		// position helper (lasso)
   4295 		this.helper.css({
   4296 			"left": event.pageX,
   4297 			"top": event.pageY,
   4298 			"width": 0,
   4299 			"height": 0
   4300 		});
   4301 
   4302 		if (options.autoRefresh) {
   4303 			this.refresh();
   4304 		}
   4305 
   4306 		this.selectees.filter(".ui-selected").each(function() {
   4307 			var selectee = $.data(this, "selectable-item");
   4308 			selectee.startselected = true;
   4309 			if (!event.metaKey && !event.ctrlKey) {
   4310 				selectee.$element.removeClass("ui-selected");
   4311 				selectee.selected = false;
   4312 				selectee.$element.addClass("ui-unselecting");
   4313 				selectee.unselecting = true;
   4314 				// selectable UNSELECTING callback
   4315 				that._trigger("unselecting", event, {
   4316 					unselecting: selectee.element
   4317 				});
   4318 			}
   4319 		});
   4320 
   4321 		$(event.target).parents().addBack().each(function() {
   4322 			var doSelect,
   4323 				selectee = $.data(this, "selectable-item");
   4324 			if (selectee) {
   4325 				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
   4326 				selectee.$element
   4327 					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
   4328 					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
   4329 				selectee.unselecting = !doSelect;
   4330 				selectee.selecting = doSelect;
   4331 				selectee.selected = doSelect;
   4332 				// selectable (UN)SELECTING callback
   4333 				if (doSelect) {
   4334 					that._trigger("selecting", event, {
   4335 						selecting: selectee.element
   4336 					});
   4337 				} else {
   4338 					that._trigger("unselecting", event, {
   4339 						unselecting: selectee.element
   4340 					});
   4341 				}
   4342 				return false;
   4343 			}
   4344 		});
   4345 
   4346 	},
   4347 
   4348 	_mouseDrag: function(event) {
   4349 
   4350 		this.dragged = true;
   4351 
   4352 		if (this.options.disabled) {
   4353 			return;
   4354 		}
   4355 
   4356 		var tmp,
   4357 			that = this,
   4358 			options = this.options,
   4359 			x1 = this.opos[0],
   4360 			y1 = this.opos[1],
   4361 			x2 = event.pageX,
   4362 			y2 = event.pageY;
   4363 
   4364 		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
   4365 		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
   4366 		this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
   4367 
   4368 		this.selectees.each(function() {
   4369 			var selectee = $.data(this, "selectable-item"),
   4370 				hit = false;
   4371 
   4372 			//prevent helper from being selected if appendTo: selectable
   4373 			if (!selectee || selectee.element === that.element[0]) {
   4374 				return;
   4375 			}
   4376 
   4377 			if (options.tolerance === "touch") {
   4378 				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
   4379 			} else if (options.tolerance === "fit") {
   4380 				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
   4381 			}
   4382 
   4383 			if (hit) {
   4384 				// SELECT
   4385 				if (selectee.selected) {
   4386 					selectee.$element.removeClass("ui-selected");
   4387 					selectee.selected = false;
   4388 				}
   4389 				if (selectee.unselecting) {
   4390 					selectee.$element.removeClass("ui-unselecting");
   4391 					selectee.unselecting = false;
   4392 				}
   4393 				if (!selectee.selecting) {
   4394 					selectee.$element.addClass("ui-selecting");
   4395 					selectee.selecting = true;
   4396 					// selectable SELECTING callback
   4397 					that._trigger("selecting", event, {
   4398 						selecting: selectee.element
   4399 					});
   4400 				}
   4401 			} else {
   4402 				// UNSELECT
   4403 				if (selectee.selecting) {
   4404 					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
   4405 						selectee.$element.removeClass("ui-selecting");
   4406 						selectee.selecting = false;
   4407 						selectee.$element.addClass("ui-selected");
   4408 						selectee.selected = true;
   4409 					} else {
   4410 						selectee.$element.removeClass("ui-selecting");
   4411 						selectee.selecting = false;
   4412 						if (selectee.startselected) {
   4413 							selectee.$element.addClass("ui-unselecting");
   4414 							selectee.unselecting = true;
   4415 						}
   4416 						// selectable UNSELECTING callback
   4417 						that._trigger("unselecting", event, {
   4418 							unselecting: selectee.element
   4419 						});
   4420 					}
   4421 				}
   4422 				if (selectee.selected) {
   4423 					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
   4424 						selectee.$element.removeClass("ui-selected");
   4425 						selectee.selected = false;
   4426 
   4427 						selectee.$element.addClass("ui-unselecting");
   4428 						selectee.unselecting = true;
   4429 						// selectable UNSELECTING callback
   4430 						that._trigger("unselecting", event, {
   4431 							unselecting: selectee.element
   4432 						});
   4433 					}
   4434 				}
   4435 			}
   4436 		});
   4437 
   4438 		return false;
   4439 	},
   4440 
   4441 	_mouseStop: function(event) {
   4442 		var that = this;
   4443 
   4444 		this.dragged = false;
   4445 
   4446 		$(".ui-unselecting", this.element[0]).each(function() {
   4447 			var selectee = $.data(this, "selectable-item");
   4448 			selectee.$element.removeClass("ui-unselecting");
   4449 			selectee.unselecting = false;
   4450 			selectee.startselected = false;
   4451 			that._trigger("unselected", event, {
   4452 				unselected: selectee.element
   4453 			});
   4454 		});
   4455 		$(".ui-selecting", this.element[0]).each(function() {
   4456 			var selectee = $.data(this, "selectable-item");
   4457 			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
   4458 			selectee.selecting = false;
   4459 			selectee.selected = true;
   4460 			selectee.startselected = true;
   4461 			that._trigger("selected", event, {
   4462 				selected: selectee.element
   4463 			});
   4464 		});
   4465 		this._trigger("stop", event);
   4466 
   4467 		this.helper.remove();
   4468 
   4469 		return false;
   4470 	}
   4471 
   4472 });
   4473 
   4474 
   4475 /*!
   4476  * jQuery UI Sortable 1.11.4
   4477  * http://jqueryui.com
   4478  *
   4479  * Copyright jQuery Foundation and other contributors
   4480  * Released under the MIT license.
   4481  * http://jquery.org/license
   4482  *
   4483  * http://api.jqueryui.com/sortable/
   4484  */
   4485 
   4486 
   4487 var sortable = $.widget("ui.sortable", $.ui.mouse, {
   4488 	version: "1.11.4",
   4489 	widgetEventPrefix: "sort",
   4490 	ready: false,
   4491 	options: {
   4492 		appendTo: "parent",
   4493 		axis: false,
   4494 		connectWith: false,
   4495 		containment: false,
   4496 		cursor: "auto",
   4497 		cursorAt: false,
   4498 		dropOnEmpty: true,
   4499 		forcePlaceholderSize: false,
   4500 		forceHelperSize: false,
   4501 		grid: false,
   4502 		handle: false,
   4503 		helper: "original",
   4504 		items: "> *",
   4505 		opacity: false,
   4506 		placeholder: false,
   4507 		revert: false,
   4508 		scroll: true,
   4509 		scrollSensitivity: 20,
   4510 		scrollSpeed: 20,
   4511 		scope: "default",
   4512 		tolerance: "intersect",
   4513 		zIndex: 1000,
   4514 
   4515 		// callbacks
   4516 		activate: null,
   4517 		beforeStop: null,
   4518 		change: null,
   4519 		deactivate: null,
   4520 		out: null,
   4521 		over: null,
   4522 		receive: null,
   4523 		remove: null,
   4524 		sort: null,
   4525 		start: null,
   4526 		stop: null,
   4527 		update: null
   4528 	},
   4529 
   4530 	_isOverAxis: function( x, reference, size ) {
   4531 		return ( x >= reference ) && ( x < ( reference + size ) );
   4532 	},
   4533 
   4534 	_isFloating: function( item ) {
   4535 		return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
   4536 	},
   4537 
   4538 	_create: function() {
   4539 		this.containerCache = {};
   4540 		this.element.addClass("ui-sortable");
   4541 
   4542 		//Get the items
   4543 		this.refresh();
   4544 
   4545 		//Let's determine the parent's offset
   4546 		this.offset = this.element.offset();
   4547 
   4548 		//Initialize mouse events for interaction
   4549 		this._mouseInit();
   4550 
   4551 		this._setHandleClassName();
   4552 
   4553 		//We're ready to go
   4554 		this.ready = true;
   4555 
   4556 	},
   4557 
   4558 	_setOption: function( key, value ) {
   4559 		this._super( key, value );
   4560 
   4561 		if ( key === "handle" ) {
   4562 			this._setHandleClassName();
   4563 		}
   4564 	},
   4565 
   4566 	_setHandleClassName: function() {
   4567 		this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
   4568 		$.each( this.items, function() {
   4569 			( this.instance.options.handle ?
   4570 				this.item.find( this.instance.options.handle ) : this.item )
   4571 				.addClass( "ui-sortable-handle" );
   4572 		});
   4573 	},
   4574 
   4575 	_destroy: function() {
   4576 		this.element
   4577 			.removeClass( "ui-sortable ui-sortable-disabled" )
   4578 			.find( ".ui-sortable-handle" )
   4579 				.removeClass( "ui-sortable-handle" );
   4580 		this._mouseDestroy();
   4581 
   4582 		for ( var i = this.items.length - 1; i >= 0; i-- ) {
   4583 			this.items[i].item.removeData(this.widgetName + "-item");
   4584 		}
   4585 
   4586 		return this;
   4587 	},
   4588 
   4589 	_mouseCapture: function(event, overrideHandle) {
   4590 		var currentItem = null,
   4591 			validHandle = false,
   4592 			that = this;
   4593 
   4594 		if (this.reverting) {
   4595 			return false;
   4596 		}
   4597 
   4598 		if(this.options.disabled || this.options.type === "static") {
   4599 			return false;
   4600 		}
   4601 
   4602 		//We have to refresh the items data once first
   4603 		this._refreshItems(event);
   4604 
   4605 		//Find out if the clicked node (or one of its parents) is a actual item in this.items
   4606 		$(event.target).parents().each(function() {
   4607 			if($.data(this, that.widgetName + "-item") === that) {
   4608 				currentItem = $(this);
   4609 				return false;
   4610 			}
   4611 		});
   4612 		if($.data(event.target, that.widgetName + "-item") === that) {
   4613 			currentItem = $(event.target);
   4614 		}
   4615 
   4616 		if(!currentItem) {
   4617 			return false;
   4618 		}
   4619 		if(this.options.handle && !overrideHandle) {
   4620 			$(this.options.handle, currentItem).find("*").addBack().each(function() {
   4621 				if(this === event.target) {
   4622 					validHandle = true;
   4623 				}
   4624 			});
   4625 			if(!validHandle) {
   4626 				return false;
   4627 			}
   4628 		}
   4629 
   4630 		this.currentItem = currentItem;
   4631 		this._removeCurrentsFromItems();
   4632 		return true;
   4633 
   4634 	},
   4635 
   4636 	_mouseStart: function(event, overrideHandle, noActivation) {
   4637 
   4638 		var i, body,
   4639 			o = this.options;
   4640 
   4641 		this.currentContainer = this;
   4642 
   4643 		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
   4644 		this.refreshPositions();
   4645 
   4646 		//Create and append the visible helper
   4647 		this.helper = this._createHelper(event);
   4648 
   4649 		//Cache the helper size
   4650 		this._cacheHelperProportions();
   4651 
   4652 		/*
   4653 		 * - Position generation -
   4654 		 * This block generates everything position related - it's the core of draggables.
   4655 		 */
   4656 
   4657 		//Cache the margins of the original element
   4658 		this._cacheMargins();
   4659 
   4660 		//Get the next scrolling parent
   4661 		this.scrollParent = this.helper.scrollParent();
   4662 
   4663 		//The element's absolute position on the page minus margins
   4664 		this.offset = this.currentItem.offset();
   4665 		this.offset = {
   4666 			top: this.offset.top - this.margins.top,
   4667 			left: this.offset.left - this.margins.left
   4668 		};
   4669 
   4670 		$.extend(this.offset, {
   4671 			click: { //Where the click happened, relative to the element
   4672 				left: event.pageX - this.offset.left,
   4673 				top: event.pageY - this.offset.top
   4674 			},
   4675 			parent: this._getParentOffset(),
   4676 			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
   4677 		});
   4678 
   4679 		// Only after we got the offset, we can change the helper's position to absolute
   4680 		// TODO: Still need to figure out a way to make relative sorting possible
   4681 		this.helper.css("position", "absolute");
   4682 		this.cssPosition = this.helper.css("position");
   4683 
   4684 		//Generate the original position
   4685 		this.originalPosition = this._generatePosition(event);
   4686 		this.originalPageX = event.pageX;
   4687 		this.originalPageY = event.pageY;
   4688 
   4689 		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
   4690 		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
   4691 
   4692 		//Cache the former DOM position
   4693 		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
   4694 
   4695 		//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
   4696 		if(this.helper[0] !== this.currentItem[0]) {
   4697 			this.currentItem.hide();
   4698 		}
   4699 
   4700 		//Create the placeholder
   4701 		this._createPlaceholder();
   4702 
   4703 		//Set a containment if given in the options
   4704 		if(o.containment) {
   4705 			this._setContainment();
   4706 		}
   4707 
   4708 		if( o.cursor && o.cursor !== "auto" ) { // cursor option
   4709 			body = this.document.find( "body" );
   4710 
   4711 			// support: IE
   4712 			this.storedCursor = body.css( "cursor" );
   4713 			body.css( "cursor", o.cursor );
   4714 
   4715 			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
   4716 		}
   4717 
   4718 		if(o.opacity) { // opacity option
   4719 			if (this.helper.css("opacity")) {
   4720 				this._storedOpacity = this.helper.css("opacity");
   4721 			}
   4722 			this.helper.css("opacity", o.opacity);
   4723 		}
   4724 
   4725 		if(o.zIndex) { // zIndex option
   4726 			if (this.helper.css("zIndex")) {
   4727 				this._storedZIndex = this.helper.css("zIndex");
   4728 			}
   4729 			this.helper.css("zIndex", o.zIndex);
   4730 		}
   4731 
   4732 		//Prepare scrolling
   4733 		if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
   4734 			this.overflowOffset = this.scrollParent.offset();
   4735 		}
   4736 
   4737 		//Call callbacks
   4738 		this._trigger("start", event, this._uiHash());
   4739 
   4740 		//Recache the helper size
   4741 		if(!this._preserveHelperProportions) {
   4742 			this._cacheHelperProportions();
   4743 		}
   4744 
   4745 
   4746 		//Post "activate" events to possible containers
   4747 		if( !noActivation ) {
   4748 			for ( i = this.containers.length - 1; i >= 0; i-- ) {
   4749 				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
   4750 			}
   4751 		}
   4752 
   4753 		//Prepare possible droppables
   4754 		if($.ui.ddmanager) {
   4755 			$.ui.ddmanager.current = this;
   4756 		}
   4757 
   4758 		if ($.ui.ddmanager && !o.dropBehaviour) {
   4759 			$.ui.ddmanager.prepareOffsets(this, event);
   4760 		}
   4761 
   4762 		this.dragging = true;
   4763 
   4764 		this.helper.addClass("ui-sortable-helper");
   4765 		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
   4766 		return true;
   4767 
   4768 	},
   4769 
   4770 	_mouseDrag: function(event) {
   4771 		var i, item, itemElement, intersection,
   4772 			o = this.options,
   4773 			scrolled = false;
   4774 
   4775 		//Compute the helpers position
   4776 		this.position = this._generatePosition(event);
   4777 		this.positionAbs = this._convertPositionTo("absolute");
   4778 
   4779 		if (!this.lastPositionAbs) {
   4780 			this.lastPositionAbs = this.positionAbs;
   4781 		}
   4782 
   4783 		//Do scrolling
   4784 		if(this.options.scroll) {
   4785 			if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
   4786 
   4787 				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
   4788 					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
   4789 				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
   4790 					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
   4791 				}
   4792 
   4793 				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
   4794 					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
   4795 				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
   4796 					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
   4797 				}
   4798 
   4799 			} else {
   4800 
   4801 				if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
   4802 					scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
   4803 				} else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
   4804 					scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
   4805 				}
   4806 
   4807 				if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
   4808 					scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
   4809 				} else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
   4810 					scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
   4811 				}
   4812 
   4813 			}
   4814 
   4815 			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
   4816 				$.ui.ddmanager.prepareOffsets(this, event);
   4817 			}
   4818 		}
   4819 
   4820 		//Regenerate the absolute position used for position checks
   4821 		this.positionAbs = this._convertPositionTo("absolute");
   4822 
   4823 		//Set the helper position
   4824 		if(!this.options.axis || this.options.axis !== "y") {
   4825 			this.helper[0].style.left = this.position.left+"px";
   4826 		}
   4827 		if(!this.options.axis || this.options.axis !== "x") {
   4828 			this.helper[0].style.top = this.position.top+"px";
   4829 		}
   4830 
   4831 		//Rearrange
   4832 		for (i = this.items.length - 1; i >= 0; i--) {
   4833 
   4834 			//Cache variables and intersection, continue if no intersection
   4835 			item = this.items[i];
   4836 			itemElement = item.item[0];
   4837 			intersection = this._intersectsWithPointer(item);
   4838 			if (!intersection) {
   4839 				continue;
   4840 			}
   4841 
   4842 			// Only put the placeholder inside the current Container, skip all
   4843 			// items from other containers. This works because when moving
   4844 			// an item from one container to another the
   4845 			// currentContainer is switched before the placeholder is moved.
   4846 			//
   4847 			// Without this, moving items in "sub-sortables" can cause
   4848 			// the placeholder to jitter between the outer and inner container.
   4849 			if (item.instance !== this.currentContainer) {
   4850 				continue;
   4851 			}
   4852 
   4853 			// cannot intersect with itself
   4854 			// no useless actions that have been done before
   4855 			// no action if the item moved is the parent of the item checked
   4856 			if (itemElement !== this.currentItem[0] &&
   4857 				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
   4858 				!$.contains(this.placeholder[0], itemElement) &&
   4859 				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
   4860 			) {
   4861 
   4862 				this.direction = intersection === 1 ? "down" : "up";
   4863 
   4864 				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
   4865 					this._rearrange(event, item);
   4866 				} else {
   4867 					break;
   4868 				}
   4869 
   4870 				this._trigger("change", event, this._uiHash());
   4871 				break;
   4872 			}
   4873 		}
   4874 
   4875 		//Post events to containers
   4876 		this._contactContainers(event);
   4877 
   4878 		//Interconnect with droppables
   4879 		if($.ui.ddmanager) {
   4880 			$.ui.ddmanager.drag(this, event);
   4881 		}
   4882 
   4883 		//Call callbacks
   4884 		this._trigger("sort", event, this._uiHash());
   4885 
   4886 		this.lastPositionAbs = this.positionAbs;
   4887 		return false;
   4888 
   4889 	},
   4890 
   4891 	_mouseStop: function(event, noPropagation) {
   4892 
   4893 		if(!event) {
   4894 			return;
   4895 		}
   4896 
   4897 		//If we are using droppables, inform the manager about the drop
   4898 		if ($.ui.ddmanager && !this.options.dropBehaviour) {
   4899 			$.ui.ddmanager.drop(this, event);
   4900 		}
   4901 
   4902 		if(this.options.revert) {
   4903 			var that = this,
   4904 				cur = this.placeholder.offset(),
   4905 				axis = this.options.axis,
   4906 				animation = {};
   4907 
   4908 			if ( !axis || axis === "x" ) {
   4909 				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
   4910 			}
   4911 			if ( !axis || axis === "y" ) {
   4912 				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
   4913 			}
   4914 			this.reverting = true;
   4915 			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
   4916 				that._clear(event);
   4917 			});
   4918 		} else {
   4919 			this._clear(event, noPropagation);
   4920 		}
   4921 
   4922 		return false;
   4923 
   4924 	},
   4925 
   4926 	cancel: function() {
   4927 
   4928 		if(this.dragging) {
   4929 
   4930 			this._mouseUp({ target: null });
   4931 
   4932 			if(this.options.helper === "original") {
   4933 				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
   4934 			} else {
   4935 				this.currentItem.show();
   4936 			}
   4937 
   4938 			//Post deactivating events to containers
   4939 			for (var i = this.containers.length - 1; i >= 0; i--){
   4940 				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
   4941 				if(this.containers[i].containerCache.over) {
   4942 					this.containers[i]._trigger("out", null, this._uiHash(this));
   4943 					this.containers[i].containerCache.over = 0;
   4944 				}
   4945 			}
   4946 
   4947 		}
   4948 
   4949 		if (this.placeholder) {
   4950 			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
   4951 			if(this.placeholder[0].parentNode) {
   4952 				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
   4953 			}
   4954 			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
   4955 				this.helper.remove();
   4956 			}
   4957 
   4958 			$.extend(this, {
   4959 				helper: null,
   4960 				dragging: false,
   4961 				reverting: false,
   4962 				_noFinalSort: null
   4963 			});
   4964 
   4965 			if(this.domPosition.prev) {
   4966 				$(this.domPosition.prev).after(this.currentItem);
   4967 			} else {
   4968 				$(this.domPosition.parent).prepend(this.currentItem);
   4969 			}
   4970 		}
   4971 
   4972 		return this;
   4973 
   4974 	},
   4975 
   4976 	serialize: function(o) {
   4977 
   4978 		var items = this._getItemsAsjQuery(o && o.connected),
   4979 			str = [];
   4980 		o = o || {};
   4981 
   4982 		$(items).each(function() {
   4983 			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
   4984 			if (res) {
   4985 				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
   4986 			}
   4987 		});
   4988 
   4989 		if(!str.length && o.key) {
   4990 			str.push(o.key + "=");
   4991 		}
   4992 
   4993 		return str.join("&");
   4994 
   4995 	},
   4996 
   4997 	toArray: function(o) {
   4998 
   4999 		var items = this._getItemsAsjQuery(o && o.connected),
   5000 			ret = [];
   5001 
   5002 		o = o || {};
   5003 
   5004 		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
   5005 		return ret;
   5006 
   5007 	},
   5008 
   5009 	/* Be careful with the following core functions */
   5010 	_intersectsWith: function(item) {
   5011 
   5012 		var x1 = this.positionAbs.left,
   5013 			x2 = x1 + this.helperProportions.width,
   5014 			y1 = this.positionAbs.top,
   5015 			y2 = y1 + this.helperProportions.height,
   5016 			l = item.left,
   5017 			r = l + item.width,
   5018 			t = item.top,
   5019 			b = t + item.height,
   5020 			dyClick = this.offset.click.top,
   5021 			dxClick = this.offset.click.left,
   5022 			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
   5023 			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
   5024 			isOverElement = isOverElementHeight && isOverElementWidth;
   5025 
   5026 		if ( this.options.tolerance === "pointer" ||
   5027 			this.options.forcePointerForContainers ||
   5028 			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
   5029 		) {
   5030 			return isOverElement;
   5031 		} else {
   5032 
   5033 			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
   5034 				x2 - (this.helperProportions.width / 2) < r && // Left Half
   5035 				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
   5036 				y2 - (this.helperProportions.height / 2) < b ); // Top Half
   5037 
   5038 		}
   5039 	},
   5040 
   5041 	_intersectsWithPointer: function(item) {
   5042 
   5043 		var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
   5044 			isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
   5045 			isOverElement = isOverElementHeight && isOverElementWidth,
   5046 			verticalDirection = this._getDragVerticalDirection(),
   5047 			horizontalDirection = this._getDragHorizontalDirection();
   5048 
   5049 		if (!isOverElement) {
   5050 			return false;
   5051 		}
   5052 
   5053 		return this.floating ?
   5054 			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
   5055 			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
   5056 
   5057 	},
   5058 
   5059 	_intersectsWithSides: function(item) {
   5060 
   5061 		var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
   5062 			isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
   5063 			verticalDirection = this._getDragVerticalDirection(),
   5064 			horizontalDirection = this._getDragHorizontalDirection();
   5065 
   5066 		if (this.floating && horizontalDirection) {
   5067 			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
   5068 		} else {
   5069 			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
   5070 		}
   5071 
   5072 	},
   5073 
   5074 	_getDragVerticalDirection: function() {
   5075 		var delta = this.positionAbs.top - this.lastPositionAbs.top;
   5076 		return delta !== 0 && (delta > 0 ? "down" : "up");
   5077 	},
   5078 
   5079 	_getDragHorizontalDirection: function() {
   5080 		var delta = this.positionAbs.left - this.lastPositionAbs.left;
   5081 		return delta !== 0 && (delta > 0 ? "right" : "left");
   5082 	},
   5083 
   5084 	refresh: function(event) {
   5085 		this._refreshItems(event);
   5086 		this._setHandleClassName();
   5087 		this.refreshPositions();
   5088 		return this;
   5089 	},
   5090 
   5091 	_connectWith: function() {
   5092 		var options = this.options;
   5093 		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
   5094 	},
   5095 
   5096 	_getItemsAsjQuery: function(connected) {
   5097 
   5098 		var i, j, cur, inst,
   5099 			items = [],
   5100 			queries = [],
   5101 			connectWith = this._connectWith();
   5102 
   5103 		if(connectWith && connected) {
   5104 			for (i = connectWith.length - 1; i >= 0; i--){
   5105 				cur = $(connectWith[i], this.document[0]);
   5106 				for ( j = cur.length - 1; j >= 0; j--){
   5107 					inst = $.data(cur[j], this.widgetFullName);
   5108 					if(inst && inst !== this && !inst.options.disabled) {
   5109 						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]);
   5110 					}
   5111 				}
   5112 			}
   5113 		}
   5114 
   5115 		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]);
   5116 
   5117 		function addItems() {
   5118 			items.push( this );
   5119 		}
   5120 		for (i = queries.length - 1; i >= 0; i--){
   5121 			queries[i][0].each( addItems );
   5122 		}
   5123 
   5124 		return $(items);
   5125 
   5126 	},
   5127 
   5128 	_removeCurrentsFromItems: function() {
   5129 
   5130 		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
   5131 
   5132 		this.items = $.grep(this.items, function (item) {
   5133 			for (var j=0; j < list.length; j++) {
   5134 				if(list[j] === item.item[0]) {
   5135 					return false;
   5136 				}
   5137 			}
   5138 			return true;
   5139 		});
   5140 
   5141 	},
   5142 
   5143 	_refreshItems: function(event) {
   5144 
   5145 		this.items = [];
   5146 		this.containers = [this];
   5147 
   5148 		var i, j, cur, inst, targetData, _queries, item, queriesLength,
   5149 			items = this.items,
   5150 			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
   5151 			connectWith = this._connectWith();
   5152 
   5153 		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
   5154 			for (i = connectWith.length - 1; i >= 0; i--){
   5155 				cur = $(connectWith[i], this.document[0]);
   5156 				for (j = cur.length - 1; j >= 0; j--){
   5157 					inst = $.data(cur[j], this.widgetFullName);
   5158 					if(inst && inst !== this && !inst.options.disabled) {
   5159 						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
   5160 						this.containers.push(inst);
   5161 					}
   5162 				}
   5163 			}
   5164 		}
   5165 
   5166 		for (i = queries.length - 1; i >= 0; i--) {
   5167 			targetData = queries[i][1];
   5168 			_queries = queries[i][0];
   5169 
   5170 			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
   5171 				item = $(_queries[j]);
   5172 
   5173 				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
   5174 
   5175 				items.push({
   5176 					item: item,
   5177 					instance: targetData,
   5178 					width: 0, height: 0,
   5179 					left: 0, top: 0
   5180 				});
   5181 			}
   5182 		}
   5183 
   5184 	},
   5185 
   5186 	refreshPositions: function(fast) {
   5187 
   5188 		// Determine whether items are being displayed horizontally
   5189 		this.floating = this.items.length ?
   5190 			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
   5191 			false;
   5192 
   5193 		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
   5194 		if(this.offsetParent && this.helper) {
   5195 			this.offset.parent = this._getParentOffset();
   5196 		}
   5197 
   5198 		var i, item, t, p;
   5199 
   5200 		for (i = this.items.length - 1; i >= 0; i--){
   5201 			item = this.items[i];
   5202 
   5203 			//We ignore calculating positions of all connected containers when we're not over them
   5204 			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
   5205 				continue;
   5206 			}
   5207 
   5208 			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
   5209 
   5210 			if (!fast) {
   5211 				item.width = t.outerWidth();
   5212 				item.height = t.outerHeight();
   5213 			}
   5214 
   5215 			p = t.offset();
   5216 			item.left = p.left;
   5217 			item.top = p.top;
   5218 		}
   5219 
   5220 		if(this.options.custom && this.options.custom.refreshContainers) {
   5221 			this.options.custom.refreshContainers.call(this);
   5222 		} else {
   5223 			for (i = this.containers.length - 1; i >= 0; i--){
   5224 				p = this.containers[i].element.offset();
   5225 				this.containers[i].containerCache.left = p.left;
   5226 				this.containers[i].containerCache.top = p.top;
   5227 				this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
   5228 				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
   5229 			}
   5230 		}
   5231 
   5232 		return this;
   5233 	},
   5234 
   5235 	_createPlaceholder: function(that) {
   5236 		that = that || this;
   5237 		var className,
   5238 			o = that.options;
   5239 
   5240 		if(!o.placeholder || o.placeholder.constructor === String) {
   5241 			className = o.placeholder;
   5242 			o.placeholder = {
   5243 				element: function() {
   5244 
   5245 					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
   5246 						element = $( "<" + nodeName + ">", that.document[0] )
   5247 							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
   5248 							.removeClass("ui-sortable-helper");
   5249 
   5250 					if ( nodeName === "tbody" ) {
   5251 						that._createTrPlaceholder(
   5252 							that.currentItem.find( "tr" ).eq( 0 ),
   5253 							$( "<tr>", that.document[ 0 ] ).appendTo( element )
   5254 						);
   5255 					} else if ( nodeName === "tr" ) {
   5256 						that._createTrPlaceholder( that.currentItem, element );
   5257 					} else if ( nodeName === "img" ) {
   5258 						element.attr( "src", that.currentItem.attr( "src" ) );
   5259 					}
   5260 
   5261 					if ( !className ) {
   5262 						element.css( "visibility", "hidden" );
   5263 					}
   5264 
   5265 					return element;
   5266 				},
   5267 				update: function(container, p) {
   5268 
   5269 					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
   5270 					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
   5271 					if(className && !o.forcePlaceholderSize) {
   5272 						return;
   5273 					}
   5274 
   5275 					//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
   5276 					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
   5277 					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
   5278 				}
   5279 			};
   5280 		}
   5281 
   5282 		//Create the placeholder
   5283 		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
   5284 
   5285 		//Append it after the actual current item
   5286 		that.currentItem.after(that.placeholder);
   5287 
   5288 		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
   5289 		o.placeholder.update(that, that.placeholder);
   5290 
   5291 	},
   5292 
   5293 	_createTrPlaceholder: function( sourceTr, targetTr ) {
   5294 		var that = this;
   5295 
   5296 		sourceTr.children().each(function() {
   5297 			$( "<td>&#160;</td>", that.document[ 0 ] )
   5298 				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
   5299 				.appendTo( targetTr );
   5300 		});
   5301 	},
   5302 
   5303 	_contactContainers: function(event) {
   5304 		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
   5305 			innermostContainer = null,
   5306 			innermostIndex = null;
   5307 
   5308 		// get innermost container that intersects with item
   5309 		for (i = this.containers.length - 1; i >= 0; i--) {
   5310 
   5311 			// never consider a container that's located within the item itself
   5312 			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
   5313 				continue;
   5314 			}
   5315 
   5316 			if(this._intersectsWith(this.containers[i].containerCache)) {
   5317 
   5318 				// if we've already found a container and it's more "inner" than this, then continue
   5319 				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
   5320 					continue;
   5321 				}
   5322 
   5323 				innermostContainer = this.containers[i];
   5324 				innermostIndex = i;
   5325 
   5326 			} else {
   5327 				// container doesn't intersect. trigger "out" event if necessary
   5328 				if(this.containers[i].containerCache.over) {
   5329 					this.containers[i]._trigger("out", event, this._uiHash(this));
   5330 					this.containers[i].containerCache.over = 0;
   5331 				}
   5332 			}
   5333 
   5334 		}
   5335 
   5336 		// if no intersecting containers found, return
   5337 		if(!innermostContainer) {
   5338 			return;
   5339 		}
   5340 
   5341 		// move the item into the container if it's not there already
   5342 		if(this.containers.length === 1) {
   5343 			if (!this.containers[innermostIndex].containerCache.over) {
   5344 				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
   5345 				this.containers[innermostIndex].containerCache.over = 1;
   5346 			}
   5347 		} else {
   5348 
   5349 			//When entering a new container, we will find the item with the least distance and append our item near it
   5350 			dist = 10000;
   5351 			itemWithLeastDistance = null;
   5352 			floating = innermostContainer.floating || this._isFloating(this.currentItem);
   5353 			posProperty = floating ? "left" : "top";
   5354 			sizeProperty = floating ? "width" : "height";
   5355 			axis = floating ? "clientX" : "clientY";
   5356 
   5357 			for (j = this.items.length - 1; j >= 0; j--) {
   5358 				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
   5359 					continue;
   5360 				}
   5361 				if(this.items[j].item[0] === this.currentItem[0]) {
   5362 					continue;
   5363 				}
   5364 
   5365 				cur = this.items[j].item.offset()[posProperty];
   5366 				nearBottom = false;
   5367 				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
   5368 					nearBottom = true;
   5369 				}
   5370 
   5371 				if ( Math.abs( event[ axis ] - cur ) < dist ) {
   5372 					dist = Math.abs( event[ axis ] - cur );
   5373 					itemWithLeastDistance = this.items[ j ];
   5374 					this.direction = nearBottom ? "up": "down";
   5375 				}
   5376 			}
   5377 
   5378 			//Check if dropOnEmpty is enabled
   5379 			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
   5380 				return;
   5381 			}
   5382 
   5383 			if(this.currentContainer === this.containers[innermostIndex]) {
   5384 				if ( !this.currentContainer.containerCache.over ) {
   5385 					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
   5386 					this.currentContainer.containerCache.over = 1;
   5387 				}
   5388 				return;
   5389 			}
   5390 
   5391 			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
   5392 			this._trigger("change", event, this._uiHash());
   5393 			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
   5394 			this.currentContainer = this.containers[innermostIndex];
   5395 
   5396 			//Update the placeholder
   5397 			this.options.placeholder.update(this.currentContainer, this.placeholder);
   5398 
   5399 			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
   5400 			this.containers[innermostIndex].containerCache.over = 1;
   5401 		}
   5402 
   5403 
   5404 	},
   5405 
   5406 	_createHelper: function(event) {
   5407 
   5408 		var o = this.options,
   5409 			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
   5410 
   5411 		//Add the helper to the DOM if that didn't happen already
   5412 		if(!helper.parents("body").length) {
   5413 			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
   5414 		}
   5415 
   5416 		if(helper[0] === this.currentItem[0]) {
   5417 			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
   5418 		}
   5419 
   5420 		if(!helper[0].style.width || o.forceHelperSize) {
   5421 			helper.width(this.currentItem.width());
   5422 		}
   5423 		if(!helper[0].style.height || o.forceHelperSize) {
   5424 			helper.height(this.currentItem.height());
   5425 		}
   5426 
   5427 		return helper;
   5428 
   5429 	},
   5430 
   5431 	_adjustOffsetFromHelper: function(obj) {
   5432 		if (typeof obj === "string") {
   5433 			obj = obj.split(" ");
   5434 		}
   5435 		if ($.isArray(obj)) {
   5436 			obj = {left: +obj[0], top: +obj[1] || 0};
   5437 		}
   5438 		if ("left" in obj) {
   5439 			this.offset.click.left = obj.left + this.margins.left;
   5440 		}
   5441 		if ("right" in obj) {
   5442 			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
   5443 		}
   5444 		if ("top" in obj) {
   5445 			this.offset.click.top = obj.top + this.margins.top;
   5446 		}
   5447 		if ("bottom" in obj) {
   5448 			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
   5449 		}
   5450 	},
   5451 
   5452 	_getParentOffset: function() {
   5453 
   5454 
   5455 		//Get the offsetParent and cache its position
   5456 		this.offsetParent = this.helper.offsetParent();
   5457 		var po = this.offsetParent.offset();
   5458 
   5459 		// This is a special case where we need to modify a offset calculated on start, since the following happened:
   5460 		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
   5461 		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
   5462 		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
   5463 		if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
   5464 			po.left += this.scrollParent.scrollLeft();
   5465 			po.top += this.scrollParent.scrollTop();
   5466 		}
   5467 
   5468 		// This needs to be actually done for all browsers, since pageX/pageY includes this information
   5469 		// with an ugly IE fix
   5470 		if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
   5471 			po = { top: 0, left: 0 };
   5472 		}
   5473 
   5474 		return {
   5475 			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
   5476 			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
   5477 		};
   5478 
   5479 	},
   5480 
   5481 	_getRelativeOffset: function() {
   5482 
   5483 		if(this.cssPosition === "relative") {
   5484 			var p = this.currentItem.position();
   5485 			return {
   5486 				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
   5487 				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
   5488 			};
   5489 		} else {
   5490 			return { top: 0, left: 0 };
   5491 		}
   5492 
   5493 	},
   5494 
   5495 	_cacheMargins: function() {
   5496 		this.margins = {
   5497 			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
   5498 			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
   5499 		};
   5500 	},
   5501 
   5502 	_cacheHelperProportions: function() {
   5503 		this.helperProportions = {
   5504 			width: this.helper.outerWidth(),
   5505 			height: this.helper.outerHeight()
   5506 		};
   5507 	},
   5508 
   5509 	_setContainment: function() {
   5510 
   5511 		var ce, co, over,
   5512 			o = this.options;
   5513 		if(o.containment === "parent") {
   5514 			o.containment = this.helper[0].parentNode;
   5515 		}
   5516 		if(o.containment === "document" || o.containment === "window") {
   5517 			this.containment = [
   5518 				0 - this.offset.relative.left - this.offset.parent.left,
   5519 				0 - this.offset.relative.top - this.offset.parent.top,
   5520 				o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
   5521 				(o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
   5522 			];
   5523 		}
   5524 
   5525 		if(!(/^(document|window|parent)$/).test(o.containment)) {
   5526 			ce = $(o.containment)[0];
   5527 			co = $(o.containment).offset();
   5528 			over = ($(ce).css("overflow") !== "hidden");
   5529 
   5530 			this.containment = [
   5531 				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
   5532 				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
   5533 				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,
   5534 				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
   5535 			];
   5536 		}
   5537 
   5538 	},
   5539 
   5540 	_convertPositionTo: function(d, pos) {
   5541 
   5542 		if(!pos) {
   5543 			pos = this.position;
   5544 		}
   5545 		var mod = d === "absolute" ? 1 : -1,
   5546 			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
   5547 			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
   5548 
   5549 		return {
   5550 			top: (
   5551 				pos.top	+																// The absolute mouse position
   5552 				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
   5553 				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
   5554 				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
   5555 			),
   5556 			left: (
   5557 				pos.left +																// The absolute mouse position
   5558 				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
   5559 				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
   5560 				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
   5561 			)
   5562 		};
   5563 
   5564 	},
   5565 
   5566 	_generatePosition: function(event) {
   5567 
   5568 		var top, left,
   5569 			o = this.options,
   5570 			pageX = event.pageX,
   5571 			pageY = event.pageY,
   5572 			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
   5573 
   5574 		// This is another very weird special case that only happens for relative elements:
   5575 		// 1. If the css position is relative
   5576 		// 2. and the scroll parent is the document or similar to the offset parent
   5577 		// we have to refresh the relative offset during the scroll so there are no jumps
   5578 		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
   5579 			this.offset.relative = this._getRelativeOffset();
   5580 		}
   5581 
   5582 		/*
   5583 		 * - Position constraining -
   5584 		 * Constrain the position to a mix of grid, containment.
   5585 		 */
   5586 
   5587 		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
   5588 
   5589 			if(this.containment) {
   5590 				if(event.pageX - this.offset.click.left < this.containment[0]) {
   5591 					pageX = this.containment[0] + this.offset.click.left;
   5592 				}
   5593 				if(event.pageY - this.offset.click.top < this.containment[1]) {
   5594 					pageY = this.containment[1] + this.offset.click.top;
   5595 				}
   5596 				if(event.pageX - this.offset.click.left > this.containment[2]) {
   5597 					pageX = this.containment[2] + this.offset.click.left;
   5598 				}
   5599 				if(event.pageY - this.offset.click.top > this.containment[3]) {
   5600 					pageY = this.containment[3] + this.offset.click.top;
   5601 				}
   5602 			}
   5603 
   5604 			if(o.grid) {
   5605 				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
   5606 				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;
   5607 
   5608 				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
   5609 				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;
   5610 			}
   5611 
   5612 		}
   5613 
   5614 		return {
   5615 			top: (
   5616 				pageY -																// The absolute mouse position
   5617 				this.offset.click.top -													// Click offset (relative to the element)
   5618 				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
   5619 				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
   5620 				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
   5621 			),
   5622 			left: (
   5623 				pageX -																// The absolute mouse position
   5624 				this.offset.click.left -												// Click offset (relative to the element)
   5625 				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
   5626 				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
   5627 				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
   5628 			)
   5629 		};
   5630 
   5631 	},
   5632 
   5633 	_rearrange: function(event, i, a, hardRefresh) {
   5634 
   5635 		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));
   5636 
   5637 		//Various things done here to improve the performance:
   5638 		// 1. we create a setTimeout, that calls refreshPositions
   5639 		// 2. on the instance, we have a counter variable, that get's higher after every append
   5640 		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
   5641 		// 4. this lets only the last addition to the timeout stack through
   5642 		this.counter = this.counter ? ++this.counter : 1;
   5643 		var counter = this.counter;
   5644 
   5645 		this._delay(function() {
   5646 			if(counter === this.counter) {
   5647 				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
   5648 			}
   5649 		});
   5650 
   5651 	},
   5652 
   5653 	_clear: function(event, noPropagation) {
   5654 
   5655 		this.reverting = false;
   5656 		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
   5657 		// everything else normalized again
   5658 		var i,
   5659 			delayedTriggers = [];
   5660 
   5661 		// We first have to update the dom position of the actual currentItem
   5662 		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
   5663 		if(!this._noFinalSort && this.currentItem.parent().length) {
   5664 			this.placeholder.before(this.currentItem);
   5665 		}
   5666 		this._noFinalSort = null;
   5667 
   5668 		if(this.helper[0] === this.currentItem[0]) {
   5669 			for(i in this._storedCSS) {
   5670 				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
   5671 					this._storedCSS[i] = "";
   5672 				}
   5673 			}
   5674 			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
   5675 		} else {
   5676 			this.currentItem.show();
   5677 		}
   5678 
   5679 		if(this.fromOutside && !noPropagation) {
   5680 			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
   5681 		}
   5682 		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
   5683 			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
   5684 		}
   5685 
   5686 		// Check if the items Container has Changed and trigger appropriate
   5687 		// events.
   5688 		if (this !== this.currentContainer) {
   5689 			if(!noPropagation) {
   5690 				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
   5691 				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
   5692 				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
   5693 			}
   5694 		}
   5695 
   5696 
   5697 		//Post events to containers
   5698 		function delayEvent( type, instance, container ) {
   5699 			return function( event ) {
   5700 				container._trigger( type, event, instance._uiHash( instance ) );
   5701 			};
   5702 		}
   5703 		for (i = this.containers.length - 1; i >= 0; i--){
   5704 			if (!noPropagation) {
   5705 				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
   5706 			}
   5707 			if(this.containers[i].containerCache.over) {
   5708 				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
   5709 				this.containers[i].containerCache.over = 0;
   5710 			}
   5711 		}
   5712 
   5713 		//Do what was originally in plugins
   5714 		if ( this.storedCursor ) {
   5715 			this.document.find( "body" ).css( "cursor", this.storedCursor );
   5716 			this.storedStylesheet.remove();
   5717 		}
   5718 		if(this._storedOpacity) {
   5719 			this.helper.css("opacity", this._storedOpacity);
   5720 		}
   5721 		if(this._storedZIndex) {
   5722 			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
   5723 		}
   5724 
   5725 		this.dragging = false;
   5726 
   5727 		if(!noPropagation) {
   5728 			this._trigger("beforeStop", event, this._uiHash());
   5729 		}
   5730 
   5731 		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
   5732 		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
   5733 
   5734 		if ( !this.cancelHelperRemoval ) {
   5735 			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
   5736 				this.helper.remove();
   5737 			}
   5738 			this.helper = null;
   5739 		}
   5740 
   5741 		if(!noPropagation) {
   5742 			for (i=0; i < delayedTriggers.length; i++) {
   5743 				delayedTriggers[i].call(this, event);
   5744 			} //Trigger all delayed events
   5745 			this._trigger("stop", event, this._uiHash());
   5746 		}
   5747 
   5748 		this.fromOutside = false;
   5749 		return !this.cancelHelperRemoval;
   5750 
   5751 	},
   5752 
   5753 	_trigger: function() {
   5754 		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
   5755 			this.cancel();
   5756 		}
   5757 	},
   5758 
   5759 	_uiHash: function(_inst) {
   5760 		var inst = _inst || this;
   5761 		return {
   5762 			helper: inst.helper,
   5763 			placeholder: inst.placeholder || $([]),
   5764 			position: inst.position,
   5765 			originalPosition: inst.originalPosition,
   5766 			offset: inst.positionAbs,
   5767 			item: inst.currentItem,
   5768 			sender: _inst ? _inst.element : null
   5769 		};
   5770 	}
   5771 
   5772 });
   5773 
   5774 
   5775 /*!
   5776  * jQuery UI Accordion 1.11.4
   5777  * http://jqueryui.com
   5778  *
   5779  * Copyright jQuery Foundation and other contributors
   5780  * Released under the MIT license.
   5781  * http://jquery.org/license
   5782  *
   5783  * http://api.jqueryui.com/accordion/
   5784  */
   5785 
   5786 
   5787 var accordion = $.widget( "ui.accordion", {
   5788 	version: "1.11.4",
   5789 	options: {
   5790 		active: 0,
   5791 		animate: {},
   5792 		collapsible: false,
   5793 		event: "click",
   5794 		header: "> li > :first-child,> :not(li):even",
   5795 		heightStyle: "auto",
   5796 		icons: {
   5797 			activeHeader: "ui-icon-triangle-1-s",
   5798 			header: "ui-icon-triangle-1-e"
   5799 		},
   5800 
   5801 		// callbacks
   5802 		activate: null,
   5803 		beforeActivate: null
   5804 	},
   5805 
   5806 	hideProps: {
   5807 		borderTopWidth: "hide",
   5808 		borderBottomWidth: "hide",
   5809 		paddingTop: "hide",
   5810 		paddingBottom: "hide",
   5811 		height: "hide"
   5812 	},
   5813 
   5814 	showProps: {
   5815 		borderTopWidth: "show",
   5816 		borderBottomWidth: "show",
   5817 		paddingTop: "show",
   5818 		paddingBottom: "show",
   5819 		height: "show"
   5820 	},
   5821 
   5822 	_create: function() {
   5823 		var options = this.options;
   5824 		this.prevShow = this.prevHide = $();
   5825 		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
   5826 			// ARIA
   5827 			.attr( "role", "tablist" );
   5828 
   5829 		// don't allow collapsible: false and active: false / null
   5830 		if ( !options.collapsible && (options.active === false || options.active == null) ) {
   5831 			options.active = 0;
   5832 		}
   5833 
   5834 		this._processPanels();
   5835 		// handle negative values
   5836 		if ( options.active < 0 ) {
   5837 			options.active += this.headers.length;
   5838 		}
   5839 		this._refresh();
   5840 	},
   5841 
   5842 	_getCreateEventData: function() {
   5843 		return {
   5844 			header: this.active,
   5845 			panel: !this.active.length ? $() : this.active.next()
   5846 		};
   5847 	},
   5848 
   5849 	_createIcons: function() {
   5850 		var icons = this.options.icons;
   5851 		if ( icons ) {
   5852 			$( "<span>" )
   5853 				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
   5854 				.prependTo( this.headers );
   5855 			this.active.children( ".ui-accordion-header-icon" )
   5856 				.removeClass( icons.header )
   5857 				.addClass( icons.activeHeader );
   5858 			this.headers.addClass( "ui-accordion-icons" );
   5859 		}
   5860 	},
   5861 
   5862 	_destroyIcons: function() {
   5863 		this.headers
   5864 			.removeClass( "ui-accordion-icons" )
   5865 			.children( ".ui-accordion-header-icon" )
   5866 				.remove();
   5867 	},
   5868 
   5869 	_destroy: function() {
   5870 		var contents;
   5871 
   5872 		// clean up main element
   5873 		this.element
   5874 			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
   5875 			.removeAttr( "role" );
   5876 
   5877 		// clean up headers
   5878 		this.headers
   5879 			.removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
   5880 				"ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
   5881 			.removeAttr( "role" )
   5882 			.removeAttr( "aria-expanded" )
   5883 			.removeAttr( "aria-selected" )
   5884 			.removeAttr( "aria-controls" )
   5885 			.removeAttr( "tabIndex" )
   5886 			.removeUniqueId();
   5887 
   5888 		this._destroyIcons();
   5889 
   5890 		// clean up content panels
   5891 		contents = this.headers.next()
   5892 			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
   5893 				"ui-accordion-content ui-accordion-content-active ui-state-disabled" )
   5894 			.css( "display", "" )
   5895 			.removeAttr( "role" )
   5896 			.removeAttr( "aria-hidden" )
   5897 			.removeAttr( "aria-labelledby" )
   5898 			.removeUniqueId();
   5899 
   5900 		if ( this.options.heightStyle !== "content" ) {
   5901 			contents.css( "height", "" );
   5902 		}
   5903 	},
   5904 
   5905 	_setOption: function( key, value ) {
   5906 		if ( key === "active" ) {
   5907 			// _activate() will handle invalid values and update this.options
   5908 			this._activate( value );
   5909 			return;
   5910 		}
   5911 
   5912 		if ( key === "event" ) {
   5913 			if ( this.options.event ) {
   5914 				this._off( this.headers, this.options.event );
   5915 			}
   5916 			this._setupEvents( value );
   5917 		}
   5918 
   5919 		this._super( key, value );
   5920 
   5921 		// setting collapsible: false while collapsed; open first panel
   5922 		if ( key === "collapsible" && !value && this.options.active === false ) {
   5923 			this._activate( 0 );
   5924 		}
   5925 
   5926 		if ( key === "icons" ) {
   5927 			this._destroyIcons();
   5928 			if ( value ) {
   5929 				this._createIcons();
   5930 			}
   5931 		}
   5932 
   5933 		// #5332 - opacity doesn't cascade to positioned elements in IE
   5934 		// so we need to add the disabled class to the headers and panels
   5935 		if ( key === "disabled" ) {
   5936 			this.element
   5937 				.toggleClass( "ui-state-disabled", !!value )
   5938 				.attr( "aria-disabled", value );
   5939 			this.headers.add( this.headers.next() )
   5940 				.toggleClass( "ui-state-disabled", !!value );
   5941 		}
   5942 	},
   5943 
   5944 	_keydown: function( event ) {
   5945 		if ( event.altKey || event.ctrlKey ) {
   5946 			return;
   5947 		}
   5948 
   5949 		var keyCode = $.ui.keyCode,
   5950 			length = this.headers.length,
   5951 			currentIndex = this.headers.index( event.target ),
   5952 			toFocus = false;
   5953 
   5954 		switch ( event.keyCode ) {
   5955 			case keyCode.RIGHT:
   5956 			case keyCode.DOWN:
   5957 				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
   5958 				break;
   5959 			case keyCode.LEFT:
   5960 			case keyCode.UP:
   5961 				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
   5962 				break;
   5963 			case keyCode.SPACE:
   5964 			case keyCode.ENTER:
   5965 				this._eventHandler( event );
   5966 				break;
   5967 			case keyCode.HOME:
   5968 				toFocus = this.headers[ 0 ];
   5969 				break;
   5970 			case keyCode.END:
   5971 				toFocus = this.headers[ length - 1 ];
   5972 				break;
   5973 		}
   5974 
   5975 		if ( toFocus ) {
   5976 			$( event.target ).attr( "tabIndex", -1 );
   5977 			$( toFocus ).attr( "tabIndex", 0 );
   5978 			toFocus.focus();
   5979 			event.preventDefault();
   5980 		}
   5981 	},
   5982 
   5983 	_panelKeyDown: function( event ) {
   5984 		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
   5985 			$( event.currentTarget ).prev().focus();
   5986 		}
   5987 	},
   5988 
   5989 	refresh: function() {
   5990 		var options = this.options;
   5991 		this._processPanels();
   5992 
   5993 		// was collapsed or no panel
   5994 		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
   5995 			options.active = false;
   5996 			this.active = $();
   5997 		// active false only when collapsible is true
   5998 		} else if ( options.active === false ) {
   5999 			this._activate( 0 );
   6000 		// was active, but active panel is gone
   6001 		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
   6002 			// all remaining panel are disabled
   6003 			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
   6004 				options.active = false;
   6005 				this.active = $();
   6006 			// activate previous panel
   6007 			} else {
   6008 				this._activate( Math.max( 0, options.active - 1 ) );
   6009 			}
   6010 		// was active, active panel still exists
   6011 		} else {
   6012 			// make sure active index is correct
   6013 			options.active = this.headers.index( this.active );
   6014 		}
   6015 
   6016 		this._destroyIcons();
   6017 
   6018 		this._refresh();
   6019 	},
   6020 
   6021 	_processPanels: function() {
   6022 		var prevHeaders = this.headers,
   6023 			prevPanels = this.panels;
   6024 
   6025 		this.headers = this.element.find( this.options.header )
   6026 			.addClass( "ui-accordion-header ui-state-default ui-corner-all" );
   6027 
   6028 		this.panels = this.headers.next()
   6029 			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
   6030 			.filter( ":not(.ui-accordion-content-active)" )
   6031 			.hide();
   6032 
   6033 		// Avoid memory leaks (#10056)
   6034 		if ( prevPanels ) {
   6035 			this._off( prevHeaders.not( this.headers ) );
   6036 			this._off( prevPanels.not( this.panels ) );
   6037 		}
   6038 	},
   6039 
   6040 	_refresh: function() {
   6041 		var maxHeight,
   6042 			options = this.options,
   6043 			heightStyle = options.heightStyle,
   6044 			parent = this.element.parent();
   6045 
   6046 		this.active = this._findActive( options.active )
   6047 			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
   6048 			.removeClass( "ui-corner-all" );
   6049 		this.active.next()
   6050 			.addClass( "ui-accordion-content-active" )
   6051 			.show();
   6052 
   6053 		this.headers
   6054 			.attr( "role", "tab" )
   6055 			.each(function() {
   6056 				var header = $( this ),
   6057 					headerId = header.uniqueId().attr( "id" ),
   6058 					panel = header.next(),
   6059 					panelId = panel.uniqueId().attr( "id" );
   6060 				header.attr( "aria-controls", panelId );
   6061 				panel.attr( "aria-labelledby", headerId );
   6062 			})
   6063 			.next()
   6064 				.attr( "role", "tabpanel" );
   6065 
   6066 		this.headers
   6067 			.not( this.active )
   6068 			.attr({
   6069 				"aria-selected": "false",
   6070 				"aria-expanded": "false",
   6071 				tabIndex: -1
   6072 			})
   6073 			.next()
   6074 				.attr({
   6075 					"aria-hidden": "true"
   6076 				})
   6077 				.hide();
   6078 
   6079 		// make sure at least one header is in the tab order
   6080 		if ( !this.active.length ) {
   6081 			this.headers.eq( 0 ).attr( "tabIndex", 0 );
   6082 		} else {
   6083 			this.active.attr({
   6084 				"aria-selected": "true",
   6085 				"aria-expanded": "true",
   6086 				tabIndex: 0
   6087 			})
   6088 			.next()
   6089 				.attr({
   6090 					"aria-hidden": "false"
   6091 				});
   6092 		}
   6093 
   6094 		this._createIcons();
   6095 
   6096 		this._setupEvents( options.event );
   6097 
   6098 		if ( heightStyle === "fill" ) {
   6099 			maxHeight = parent.height();
   6100 			this.element.siblings( ":visible" ).each(function() {
   6101 				var elem = $( this ),
   6102 					position = elem.css( "position" );
   6103 
   6104 				if ( position === "absolute" || position === "fixed" ) {
   6105 					return;
   6106 				}
   6107 				maxHeight -= elem.outerHeight( true );
   6108 			});
   6109 
   6110 			this.headers.each(function() {
   6111 				maxHeight -= $( this ).outerHeight( true );
   6112 			});
   6113 
   6114 			this.headers.next()
   6115 				.each(function() {
   6116 					$( this ).height( Math.max( 0, maxHeight -
   6117 						$( this ).innerHeight() + $( this ).height() ) );
   6118 				})
   6119 				.css( "overflow", "auto" );
   6120 		} else if ( heightStyle === "auto" ) {
   6121 			maxHeight = 0;
   6122 			this.headers.next()
   6123 				.each(function() {
   6124 					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
   6125 				})
   6126 				.height( maxHeight );
   6127 		}
   6128 	},
   6129 
   6130 	_activate: function( index ) {
   6131 		var active = this._findActive( index )[ 0 ];
   6132 
   6133 		// trying to activate the already active panel
   6134 		if ( active === this.active[ 0 ] ) {
   6135 			return;
   6136 		}
   6137 
   6138 		// trying to collapse, simulate a click on the currently active header
   6139 		active = active || this.active[ 0 ];
   6140 
   6141 		this._eventHandler({
   6142 			target: active,
   6143 			currentTarget: active,
   6144 			preventDefault: $.noop
   6145 		});
   6146 	},
   6147 
   6148 	_findActive: function( selector ) {
   6149 		return typeof selector === "number" ? this.headers.eq( selector ) : $();
   6150 	},
   6151 
   6152 	_setupEvents: function( event ) {
   6153 		var events = {
   6154 			keydown: "_keydown"
   6155 		};
   6156 		if ( event ) {
   6157 			$.each( event.split( " " ), function( index, eventName ) {
   6158 				events[ eventName ] = "_eventHandler";
   6159 			});
   6160 		}
   6161 
   6162 		this._off( this.headers.add( this.headers.next() ) );
   6163 		this._on( this.headers, events );
   6164 		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
   6165 		this._hoverable( this.headers );
   6166 		this._focusable( this.headers );
   6167 	},
   6168 
   6169 	_eventHandler: function( event ) {
   6170 		var options = this.options,
   6171 			active = this.active,
   6172 			clicked = $( event.currentTarget ),
   6173 			clickedIsActive = clicked[ 0 ] === active[ 0 ],
   6174 			collapsing = clickedIsActive && options.collapsible,
   6175 			toShow = collapsing ? $() : clicked.next(),
   6176 			toHide = active.next(),
   6177 			eventData = {
   6178 				oldHeader: active,
   6179 				oldPanel: toHide,
   6180 				newHeader: collapsing ? $() : clicked,
   6181 				newPanel: toShow
   6182 			};
   6183 
   6184 		event.preventDefault();
   6185 
   6186 		if (
   6187 				// click on active header, but not collapsible
   6188 				( clickedIsActive && !options.collapsible ) ||
   6189 				// allow canceling activation
   6190 				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
   6191 			return;
   6192 		}
   6193 
   6194 		options.active = collapsing ? false : this.headers.index( clicked );
   6195 
   6196 		// when the call to ._toggle() comes after the class changes
   6197 		// it causes a very odd bug in IE 8 (see #6720)
   6198 		this.active = clickedIsActive ? $() : clicked;
   6199 		this._toggle( eventData );
   6200 
   6201 		// switch classes
   6202 		// corner classes on the previously active header stay after the animation
   6203 		active.removeClass( "ui-accordion-header-active ui-state-active" );
   6204 		if ( options.icons ) {
   6205 			active.children( ".ui-accordion-header-icon" )
   6206 				.removeClass( options.icons.activeHeader )
   6207 				.addClass( options.icons.header );
   6208 		}
   6209 
   6210 		if ( !clickedIsActive ) {
   6211 			clicked
   6212 				.removeClass( "ui-corner-all" )
   6213 				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
   6214 			if ( options.icons ) {
   6215 				clicked.children( ".ui-accordion-header-icon" )
   6216 					.removeClass( options.icons.header )
   6217 					.addClass( options.icons.activeHeader );
   6218 			}
   6219 
   6220 			clicked
   6221 				.next()
   6222 				.addClass( "ui-accordion-content-active" );
   6223 		}
   6224 	},
   6225 
   6226 	_toggle: function( data ) {
   6227 		var toShow = data.newPanel,
   6228 			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
   6229 
   6230 		// handle activating a panel during the animation for another activation
   6231 		this.prevShow.add( this.prevHide ).stop( true, true );
   6232 		this.prevShow = toShow;
   6233 		this.prevHide = toHide;
   6234 
   6235 		if ( this.options.animate ) {
   6236 			this._animate( toShow, toHide, data );
   6237 		} else {
   6238 			toHide.hide();
   6239 			toShow.show();
   6240 			this._toggleComplete( data );
   6241 		}
   6242 
   6243 		toHide.attr({
   6244 			"aria-hidden": "true"
   6245 		});
   6246 		toHide.prev().attr({
   6247 			"aria-selected": "false",
   6248 			"aria-expanded": "false"
   6249 		});
   6250 		// if we're switching panels, remove the old header from the tab order
   6251 		// if we're opening from collapsed state, remove the previous header from the tab order
   6252 		// if we're collapsing, then keep the collapsing header in the tab order
   6253 		if ( toShow.length && toHide.length ) {
   6254 			toHide.prev().attr({
   6255 				"tabIndex": -1,
   6256 				"aria-expanded": "false"
   6257 			});
   6258 		} else if ( toShow.length ) {
   6259 			this.headers.filter(function() {
   6260 				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
   6261 			})
   6262 			.attr( "tabIndex", -1 );
   6263 		}
   6264 
   6265 		toShow
   6266 			.attr( "aria-hidden", "false" )
   6267 			.prev()
   6268 				.attr({
   6269 					"aria-selected": "true",
   6270 					"aria-expanded": "true",
   6271 					tabIndex: 0
   6272 				});
   6273 	},
   6274 
   6275 	_animate: function( toShow, toHide, data ) {
   6276 		var total, easing, duration,
   6277 			that = this,
   6278 			adjust = 0,
   6279 			boxSizing = toShow.css( "box-sizing" ),
   6280 			down = toShow.length &&
   6281 				( !toHide.length || ( toShow.index() < toHide.index() ) ),
   6282 			animate = this.options.animate || {},
   6283 			options = down && animate.down || animate,
   6284 			complete = function() {
   6285 				that._toggleComplete( data );
   6286 			};
   6287 
   6288 		if ( typeof options === "number" ) {
   6289 			duration = options;
   6290 		}
   6291 		if ( typeof options === "string" ) {
   6292 			easing = options;
   6293 		}
   6294 		// fall back from options to animation in case of partial down settings
   6295 		easing = easing || options.easing || animate.easing;
   6296 		duration = duration || options.duration || animate.duration;
   6297 
   6298 		if ( !toHide.length ) {
   6299 			return toShow.animate( this.showProps, duration, easing, complete );
   6300 		}
   6301 		if ( !toShow.length ) {
   6302 			return toHide.animate( this.hideProps, duration, easing, complete );
   6303 		}
   6304 
   6305 		total = toShow.show().outerHeight();
   6306 		toHide.animate( this.hideProps, {
   6307 			duration: duration,
   6308 			easing: easing,
   6309 			step: function( now, fx ) {
   6310 				fx.now = Math.round( now );
   6311 			}
   6312 		});
   6313 		toShow
   6314 			.hide()
   6315 			.animate( this.showProps, {
   6316 				duration: duration,
   6317 				easing: easing,
   6318 				complete: complete,
   6319 				step: function( now, fx ) {
   6320 					fx.now = Math.round( now );
   6321 					if ( fx.prop !== "height" ) {
   6322 						if ( boxSizing === "content-box" ) {
   6323 							adjust += fx.now;
   6324 						}
   6325 					} else if ( that.options.heightStyle !== "content" ) {
   6326 						fx.now = Math.round( total - toHide.outerHeight() - adjust );
   6327 						adjust = 0;
   6328 					}
   6329 				}
   6330 			});
   6331 	},
   6332 
   6333 	_toggleComplete: function( data ) {
   6334 		var toHide = data.oldPanel;
   6335 
   6336 		toHide
   6337 			.removeClass( "ui-accordion-content-active" )
   6338 			.prev()
   6339 				.removeClass( "ui-corner-top" )
   6340 				.addClass( "ui-corner-all" );
   6341 
   6342 		// Work around for rendering bug in IE (#5421)
   6343 		if ( toHide.length ) {
   6344 			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
   6345 		}
   6346 		this._trigger( "activate", null, data );
   6347 	}
   6348 });
   6349 
   6350 
   6351 /*!
   6352  * jQuery UI Menu 1.11.4
   6353  * http://jqueryui.com
   6354  *
   6355  * Copyright jQuery Foundation and other contributors
   6356  * Released under the MIT license.
   6357  * http://jquery.org/license
   6358  *
   6359  * http://api.jqueryui.com/menu/
   6360  */
   6361 
   6362 
   6363 var menu = $.widget( "ui.menu", {
   6364 	version: "1.11.4",
   6365 	defaultElement: "<ul>",
   6366 	delay: 300,
   6367 	options: {
   6368 		icons: {
   6369 			submenu: "ui-icon-carat-1-e"
   6370 		},
   6371 		items: "> *",
   6372 		menus: "ul",
   6373 		position: {
   6374 			my: "left-1 top",
   6375 			at: "right top"
   6376 		},
   6377 		role: "menu",
   6378 
   6379 		// callbacks
   6380 		blur: null,
   6381 		focus: null,
   6382 		select: null
   6383 	},
   6384 
   6385 	_create: function() {
   6386 		this.activeMenu = this.element;
   6387 
   6388 		// Flag used to prevent firing of the click handler
   6389 		// as the event bubbles up through nested menus
   6390 		this.mouseHandled = false;
   6391 		this.element
   6392 			.uniqueId()
   6393 			.addClass( "ui-menu ui-widget ui-widget-content" )
   6394 			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
   6395 			.attr({
   6396 				role: this.options.role,
   6397 				tabIndex: 0
   6398 			});
   6399 
   6400 		if ( this.options.disabled ) {
   6401 			this.element
   6402 				.addClass( "ui-state-disabled" )
   6403 				.attr( "aria-disabled", "true" );
   6404 		}
   6405 
   6406 		this._on({
   6407 			// Prevent focus from sticking to links inside menu after clicking
   6408 			// them (focus should always stay on UL during navigation).
   6409 			"mousedown .ui-menu-item": function( event ) {
   6410 				event.preventDefault();
   6411 			},
   6412 			"click .ui-menu-item": function( event ) {
   6413 				var target = $( event.target );
   6414 				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
   6415 					this.select( event );
   6416 
   6417 					// Only set the mouseHandled flag if the event will bubble, see #9469.
   6418 					if ( !event.isPropagationStopped() ) {
   6419 						this.mouseHandled = true;
   6420 					}
   6421 
   6422 					// Open submenu on click
   6423 					if ( target.has( ".ui-menu" ).length ) {
   6424 						this.expand( event );
   6425 					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
   6426 
   6427 						// Redirect focus to the menu
   6428 						this.element.trigger( "focus", [ true ] );
   6429 
   6430 						// If the active item is on the top level, let it stay active.
   6431 						// Otherwise, blur the active item since it is no longer visible.
   6432 						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
   6433 							clearTimeout( this.timer );
   6434 						}
   6435 					}
   6436 				}
   6437 			},
   6438 			"mouseenter .ui-menu-item": function( event ) {
   6439 				// Ignore mouse events while typeahead is active, see #10458.
   6440 				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
   6441 				// is over an item in the menu
   6442 				if ( this.previousFilter ) {
   6443 					return;
   6444 				}
   6445 				var target = $( event.currentTarget );
   6446 				// Remove ui-state-active class from siblings of the newly focused menu item
   6447 				// to avoid a jump caused by adjacent elements both having a class with a border
   6448 				target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
   6449 				this.focus( event, target );
   6450 			},
   6451 			mouseleave: "collapseAll",
   6452 			"mouseleave .ui-menu": "collapseAll",
   6453 			focus: function( event, keepActiveItem ) {
   6454 				// If there's already an active item, keep it active
   6455 				// If not, activate the first item
   6456 				var item = this.active || this.element.find( this.options.items ).eq( 0 );
   6457 
   6458 				if ( !keepActiveItem ) {
   6459 					this.focus( event, item );
   6460 				}
   6461 			},
   6462 			blur: function( event ) {
   6463 				this._delay(function() {
   6464 					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
   6465 						this.collapseAll( event );
   6466 					}
   6467 				});
   6468 			},
   6469 			keydown: "_keydown"
   6470 		});
   6471 
   6472 		this.refresh();
   6473 
   6474 		// Clicks outside of a menu collapse any open menus
   6475 		this._on( this.document, {
   6476 			click: function( event ) {
   6477 				if ( this._closeOnDocumentClick( event ) ) {
   6478 					this.collapseAll( event );
   6479 				}
   6480 
   6481 				// Reset the mouseHandled flag
   6482 				this.mouseHandled = false;
   6483 			}
   6484 		});
   6485 	},
   6486 
   6487 	_destroy: function() {
   6488 		// Destroy (sub)menus
   6489 		this.element
   6490 			.removeAttr( "aria-activedescendant" )
   6491 			.find( ".ui-menu" ).addBack()
   6492 				.removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
   6493 				.removeAttr( "role" )
   6494 				.removeAttr( "tabIndex" )
   6495 				.removeAttr( "aria-labelledby" )
   6496 				.removeAttr( "aria-expanded" )
   6497 				.removeAttr( "aria-hidden" )
   6498 				.removeAttr( "aria-disabled" )
   6499 				.removeUniqueId()
   6500 				.show();
   6501 
   6502 		// Destroy menu items
   6503 		this.element.find( ".ui-menu-item" )
   6504 			.removeClass( "ui-menu-item" )
   6505 			.removeAttr( "role" )
   6506 			.removeAttr( "aria-disabled" )
   6507 			.removeUniqueId()
   6508 			.removeClass( "ui-state-hover" )
   6509 			.removeAttr( "tabIndex" )
   6510 			.removeAttr( "role" )
   6511 			.removeAttr( "aria-haspopup" )
   6512 			.children().each( function() {
   6513 				var elem = $( this );
   6514 				if ( elem.data( "ui-menu-submenu-carat" ) ) {
   6515 					elem.remove();
   6516 				}
   6517 			});
   6518 
   6519 		// Destroy menu dividers
   6520 		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
   6521 	},
   6522 
   6523 	_keydown: function( event ) {
   6524 		var match, prev, character, skip,
   6525 			preventDefault = true;
   6526 
   6527 		switch ( event.keyCode ) {
   6528 		case $.ui.keyCode.PAGE_UP:
   6529 			this.previousPage( event );
   6530 			break;
   6531 		case $.ui.keyCode.PAGE_DOWN:
   6532 			this.nextPage( event );
   6533 			break;
   6534 		case $.ui.keyCode.HOME:
   6535 			this._move( "first", "first", event );
   6536 			break;
   6537 		case $.ui.keyCode.END:
   6538 			this._move( "last", "last", event );
   6539 			break;
   6540 		case $.ui.keyCode.UP:
   6541 			this.previous( event );
   6542 			break;
   6543 		case $.ui.keyCode.DOWN:
   6544 			this.next( event );
   6545 			break;
   6546 		case $.ui.keyCode.LEFT:
   6547 			this.collapse( event );
   6548 			break;
   6549 		case $.ui.keyCode.RIGHT:
   6550 			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
   6551 				this.expand( event );
   6552 			}
   6553 			break;
   6554 		case $.ui.keyCode.ENTER:
   6555 		case $.ui.keyCode.SPACE:
   6556 			this._activate( event );
   6557 			break;
   6558 		case $.ui.keyCode.ESCAPE:
   6559 			this.collapse( event );
   6560 			break;
   6561 		default:
   6562 			preventDefault = false;
   6563 			prev = this.previousFilter || "";
   6564 			character = String.fromCharCode( event.keyCode );
   6565 			skip = false;
   6566 
   6567 			clearTimeout( this.filterTimer );
   6568 
   6569 			if ( character === prev ) {
   6570 				skip = true;
   6571 			} else {
   6572 				character = prev + character;
   6573 			}
   6574 
   6575 			match = this._filterMenuItems( character );
   6576 			match = skip && match.index( this.active.next() ) !== -1 ?
   6577 				this.active.nextAll( ".ui-menu-item" ) :
   6578 				match;
   6579 
   6580 			// If no matches on the current filter, reset to the last character pressed
   6581 			// to move down the menu to the first item that starts with that character
   6582 			if ( !match.length ) {
   6583 				character = String.fromCharCode( event.keyCode );
   6584 				match = this._filterMenuItems( character );
   6585 			}
   6586 
   6587 			if ( match.length ) {
   6588 				this.focus( event, match );
   6589 				this.previousFilter = character;
   6590 				this.filterTimer = this._delay(function() {
   6591 					delete this.previousFilter;
   6592 				}, 1000 );
   6593 			} else {
   6594 				delete this.previousFilter;
   6595 			}
   6596 		}
   6597 
   6598 		if ( preventDefault ) {
   6599 			event.preventDefault();
   6600 		}
   6601 	},
   6602 
   6603 	_activate: function( event ) {
   6604 		if ( !this.active.is( ".ui-state-disabled" ) ) {
   6605 			if ( this.active.is( "[aria-haspopup='true']" ) ) {
   6606 				this.expand( event );
   6607 			} else {
   6608 				this.select( event );
   6609 			}
   6610 		}
   6611 	},
   6612 
   6613 	refresh: function() {
   6614 		var menus, items,
   6615 			that = this,
   6616 			icon = this.options.icons.submenu,
   6617 			submenus = this.element.find( this.options.menus );
   6618 
   6619 		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
   6620 
   6621 		// Initialize nested menus
   6622 		submenus.filter( ":not(.ui-menu)" )
   6623 			.addClass( "ui-menu ui-widget ui-widget-content ui-front" )
   6624 			.hide()
   6625 			.attr({
   6626 				role: this.options.role,
   6627 				"aria-hidden": "true",
   6628 				"aria-expanded": "false"
   6629 			})
   6630 			.each(function() {
   6631 				var menu = $( this ),
   6632 					item = menu.parent(),
   6633 					submenuCarat = $( "<span>" )
   6634 						.addClass( "ui-menu-icon ui-icon " + icon )
   6635 						.data( "ui-menu-submenu-carat", true );
   6636 
   6637 				item
   6638 					.attr( "aria-haspopup", "true" )
   6639 					.prepend( submenuCarat );
   6640 				menu.attr( "aria-labelledby", item.attr( "id" ) );
   6641 			});
   6642 
   6643 		menus = submenus.add( this.element );
   6644 		items = menus.find( this.options.items );
   6645 
   6646 		// Initialize menu-items containing spaces and/or dashes only as dividers
   6647 		items.not( ".ui-menu-item" ).each(function() {
   6648 			var item = $( this );
   6649 			if ( that._isDivider( item ) ) {
   6650 				item.addClass( "ui-widget-content ui-menu-divider" );
   6651 			}
   6652 		});
   6653 
   6654 		// Don't refresh list items that are already adapted
   6655 		items.not( ".ui-menu-item, .ui-menu-divider" )
   6656 			.addClass( "ui-menu-item" )
   6657 			.uniqueId()
   6658 			.attr({
   6659 				tabIndex: -1,
   6660 				role: this._itemRole()
   6661 			});
   6662 
   6663 		// Add aria-disabled attribute to any disabled menu item
   6664 		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
   6665 
   6666 		// If the active item has been removed, blur the menu
   6667 		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
   6668 			this.blur();
   6669 		}
   6670 	},
   6671 
   6672 	_itemRole: function() {
   6673 		return {
   6674 			menu: "menuitem",
   6675 			listbox: "option"
   6676 		}[ this.options.role ];
   6677 	},
   6678 
   6679 	_setOption: function( key, value ) {
   6680 		if ( key === "icons" ) {
   6681 			this.element.find( ".ui-menu-icon" )
   6682 				.removeClass( this.options.icons.submenu )
   6683 				.addClass( value.submenu );
   6684 		}
   6685 		if ( key === "disabled" ) {
   6686 			this.element
   6687 				.toggleClass( "ui-state-disabled", !!value )
   6688 				.attr( "aria-disabled", value );
   6689 		}
   6690 		this._super( key, value );
   6691 	},
   6692 
   6693 	focus: function( event, item ) {
   6694 		var nested, focused;
   6695 		this.blur( event, event && event.type === "focus" );
   6696 
   6697 		this._scrollIntoView( item );
   6698 
   6699 		this.active = item.first();
   6700 		focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
   6701 		// Only update aria-activedescendant if there's a role
   6702 		// otherwise we assume focus is managed elsewhere
   6703 		if ( this.options.role ) {
   6704 			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
   6705 		}
   6706 
   6707 		// Highlight active parent menu item, if any
   6708 		this.active
   6709 			.parent()
   6710 			.closest( ".ui-menu-item" )
   6711 			.addClass( "ui-state-active" );
   6712 
   6713 		if ( event && event.type === "keydown" ) {
   6714 			this._close();
   6715 		} else {
   6716 			this.timer = this._delay(function() {
   6717 				this._close();
   6718 			}, this.delay );
   6719 		}
   6720 
   6721 		nested = item.children( ".ui-menu" );
   6722 		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
   6723 			this._startOpening(nested);
   6724 		}
   6725 		this.activeMenu = item.parent();
   6726 
   6727 		this._trigger( "focus", event, { item: item } );
   6728 	},
   6729 
   6730 	_scrollIntoView: function( item ) {
   6731 		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
   6732 		if ( this._hasScroll() ) {
   6733 			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
   6734 			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
   6735 			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
   6736 			scroll = this.activeMenu.scrollTop();
   6737 			elementHeight = this.activeMenu.height();
   6738 			itemHeight = item.outerHeight();
   6739 
   6740 			if ( offset < 0 ) {
   6741 				this.activeMenu.scrollTop( scroll + offset );
   6742 			} else if ( offset + itemHeight > elementHeight ) {
   6743 				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
   6744 			}
   6745 		}
   6746 	},
   6747 
   6748 	blur: function( event, fromFocus ) {
   6749 		if ( !fromFocus ) {
   6750 			clearTimeout( this.timer );
   6751 		}
   6752 
   6753 		if ( !this.active ) {
   6754 			return;
   6755 		}
   6756 
   6757 		this.active.removeClass( "ui-state-focus" );
   6758 		this.active = null;
   6759 
   6760 		this._trigger( "blur", event, { item: this.active } );
   6761 	},
   6762 
   6763 	_startOpening: function( submenu ) {
   6764 		clearTimeout( this.timer );
   6765 
   6766 		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
   6767 		// shift in the submenu position when mousing over the carat icon
   6768 		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
   6769 			return;
   6770 		}
   6771 
   6772 		this.timer = this._delay(function() {
   6773 			this._close();
   6774 			this._open( submenu );
   6775 		}, this.delay );
   6776 	},
   6777 
   6778 	_open: function( submenu ) {
   6779 		var position = $.extend({
   6780 			of: this.active
   6781 		}, this.options.position );
   6782 
   6783 		clearTimeout( this.timer );
   6784 		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
   6785 			.hide()
   6786 			.attr( "aria-hidden", "true" );
   6787 
   6788 		submenu
   6789 			.show()
   6790 			.removeAttr( "aria-hidden" )
   6791 			.attr( "aria-expanded", "true" )
   6792 			.position( position );
   6793 	},
   6794 
   6795 	collapseAll: function( event, all ) {
   6796 		clearTimeout( this.timer );
   6797 		this.timer = this._delay(function() {
   6798 			// If we were passed an event, look for the submenu that contains the event
   6799 			var currentMenu = all ? this.element :
   6800 				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
   6801 
   6802 			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
   6803 			if ( !currentMenu.length ) {
   6804 				currentMenu = this.element;
   6805 			}
   6806 
   6807 			this._close( currentMenu );
   6808 
   6809 			this.blur( event );
   6810 			this.activeMenu = currentMenu;
   6811 		}, this.delay );
   6812 	},
   6813 
   6814 	// With no arguments, closes the currently active menu - if nothing is active
   6815 	// it closes all menus.  If passed an argument, it will search for menus BELOW
   6816 	_close: function( startMenu ) {
   6817 		if ( !startMenu ) {
   6818 			startMenu = this.active ? this.active.parent() : this.element;
   6819 		}
   6820 
   6821 		startMenu
   6822 			.find( ".ui-menu" )
   6823 				.hide()
   6824 				.attr( "aria-hidden", "true" )
   6825 				.attr( "aria-expanded", "false" )
   6826 			.end()
   6827 			.find( ".ui-state-active" ).not( ".ui-state-focus" )
   6828 				.removeClass( "ui-state-active" );
   6829 	},
   6830 
   6831 	_closeOnDocumentClick: function( event ) {
   6832 		return !$( event.target ).closest( ".ui-menu" ).length;
   6833 	},
   6834 
   6835 	_isDivider: function( item ) {
   6836 
   6837 		// Match hyphen, em dash, en dash
   6838 		return !/[^\-\u2014\u2013\s]/.test( item.text() );
   6839 	},
   6840 
   6841 	collapse: function( event ) {
   6842 		var newItem = this.active &&
   6843 			this.active.parent().closest( ".ui-menu-item", this.element );
   6844 		if ( newItem && newItem.length ) {
   6845 			this._close();
   6846 			this.focus( event, newItem );
   6847 		}
   6848 	},
   6849 
   6850 	expand: function( event ) {
   6851 		var newItem = this.active &&
   6852 			this.active
   6853 				.children( ".ui-menu " )
   6854 				.find( this.options.items )
   6855 				.first();
   6856 
   6857 		if ( newItem && newItem.length ) {
   6858 			this._open( newItem.parent() );
   6859 
   6860 			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
   6861 			this._delay(function() {
   6862 				this.focus( event, newItem );
   6863 			});
   6864 		}
   6865 	},
   6866 
   6867 	next: function( event ) {
   6868 		this._move( "next", "first", event );
   6869 	},
   6870 
   6871 	previous: function( event ) {
   6872 		this._move( "prev", "last", event );
   6873 	},
   6874 
   6875 	isFirstItem: function() {
   6876 		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
   6877 	},
   6878 
   6879 	isLastItem: function() {
   6880 		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
   6881 	},
   6882 
   6883 	_move: function( direction, filter, event ) {
   6884 		var next;
   6885 		if ( this.active ) {
   6886 			if ( direction === "first" || direction === "last" ) {
   6887 				next = this.active
   6888 					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
   6889 					.eq( -1 );
   6890 			} else {
   6891 				next = this.active
   6892 					[ direction + "All" ]( ".ui-menu-item" )
   6893 					.eq( 0 );
   6894 			}
   6895 		}
   6896 		if ( !next || !next.length || !this.active ) {
   6897 			next = this.activeMenu.find( this.options.items )[ filter ]();
   6898 		}
   6899 
   6900 		this.focus( event, next );
   6901 	},
   6902 
   6903 	nextPage: function( event ) {
   6904 		var item, base, height;
   6905 
   6906 		if ( !this.active ) {
   6907 			this.next( event );
   6908 			return;
   6909 		}
   6910 		if ( this.isLastItem() ) {
   6911 			return;
   6912 		}
   6913 		if ( this._hasScroll() ) {
   6914 			base = this.active.offset().top;
   6915 			height = this.element.height();
   6916 			this.active.nextAll( ".ui-menu-item" ).each(function() {
   6917 				item = $( this );
   6918 				return item.offset().top - base - height < 0;
   6919 			});
   6920 
   6921 			this.focus( event, item );
   6922 		} else {
   6923 			this.focus( event, this.activeMenu.find( this.options.items )
   6924 				[ !this.active ? "first" : "last" ]() );
   6925 		}
   6926 	},
   6927 
   6928 	previousPage: function( event ) {
   6929 		var item, base, height;
   6930 		if ( !this.active ) {
   6931 			this.next( event );
   6932 			return;
   6933 		}
   6934 		if ( this.isFirstItem() ) {
   6935 			return;
   6936 		}
   6937 		if ( this._hasScroll() ) {
   6938 			base = this.active.offset().top;
   6939 			height = this.element.height();
   6940 			this.active.prevAll( ".ui-menu-item" ).each(function() {
   6941 				item = $( this );
   6942 				return item.offset().top - base + height > 0;
   6943 			});
   6944 
   6945 			this.focus( event, item );
   6946 		} else {
   6947 			this.focus( event, this.activeMenu.find( this.options.items ).first() );
   6948 		}
   6949 	},
   6950 
   6951 	_hasScroll: function() {
   6952 		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
   6953 	},
   6954 
   6955 	select: function( event ) {
   6956 		// TODO: It should never be possible to not have an active item at this
   6957 		// point, but the tests don't trigger mouseenter before click.
   6958 		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
   6959 		var ui = { item: this.active };
   6960 		if ( !this.active.has( ".ui-menu" ).length ) {
   6961 			this.collapseAll( event, true );
   6962 		}
   6963 		this._trigger( "select", event, ui );
   6964 	},
   6965 
   6966 	_filterMenuItems: function(character) {
   6967 		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
   6968 			regex = new RegExp( "^" + escapedCharacter, "i" );
   6969 
   6970 		return this.activeMenu
   6971 			.find( this.options.items )
   6972 
   6973 			// Only match on items, not dividers or other content (#10571)
   6974 			.filter( ".ui-menu-item" )
   6975 			.filter(function() {
   6976 				return regex.test( $.trim( $( this ).text() ) );
   6977 			});
   6978 	}
   6979 });
   6980 
   6981 
   6982 /*!
   6983  * jQuery UI Autocomplete 1.11.4
   6984  * http://jqueryui.com
   6985  *
   6986  * Copyright jQuery Foundation and other contributors
   6987  * Released under the MIT license.
   6988  * http://jquery.org/license
   6989  *
   6990  * http://api.jqueryui.com/autocomplete/
   6991  */
   6992 
   6993 
   6994 $.widget( "ui.autocomplete", {
   6995 	version: "1.11.4",
   6996 	defaultElement: "<input>",
   6997 	options: {
   6998 		appendTo: null,
   6999 		autoFocus: false,
   7000 		delay: 300,
   7001 		minLength: 1,
   7002 		position: {
   7003 			my: "left top",
   7004 			at: "left bottom",
   7005 			collision: "none"
   7006 		},
   7007 		source: null,
   7008 
   7009 		// callbacks
   7010 		change: null,
   7011 		close: null,
   7012 		focus: null,
   7013 		open: null,
   7014 		response: null,
   7015 		search: null,
   7016 		select: null
   7017 	},
   7018 
   7019 	requestIndex: 0,
   7020 	pending: 0,
   7021 
   7022 	_create: function() {
   7023 		// Some browsers only repeat keydown events, not keypress events,
   7024 		// so we use the suppressKeyPress flag to determine if we've already
   7025 		// handled the keydown event. #7269
   7026 		// Unfortunately the code for & in keypress is the same as the up arrow,
   7027 		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
   7028 		// events when we know the keydown event was used to modify the
   7029 		// search term. #7799
   7030 		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
   7031 			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
   7032 			isTextarea = nodeName === "textarea",
   7033 			isInput = nodeName === "input";
   7034 
   7035 		this.isMultiLine =
   7036 			// Textareas are always multi-line
   7037 			isTextarea ? true :
   7038 			// Inputs are always single-line, even if inside a contentEditable element
   7039 			// IE also treats inputs as contentEditable
   7040 			isInput ? false :
   7041 			// All other element types are determined by whether or not they're contentEditable
   7042 			this.element.prop( "isContentEditable" );
   7043 
   7044 		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
   7045 		this.isNewMenu = true;
   7046 
   7047 		this.element
   7048 			.addClass( "ui-autocomplete-input" )
   7049 			.attr( "autocomplete", "off" );
   7050 
   7051 		this._on( this.element, {
   7052 			keydown: function( event ) {
   7053 				if ( this.element.prop( "readOnly" ) ) {
   7054 					suppressKeyPress = true;
   7055 					suppressInput = true;
   7056 					suppressKeyPressRepeat = true;
   7057 					return;
   7058 				}
   7059 
   7060 				suppressKeyPress = false;
   7061 				suppressInput = false;
   7062 				suppressKeyPressRepeat = false;
   7063 				var keyCode = $.ui.keyCode;
   7064 				switch ( event.keyCode ) {
   7065 				case keyCode.PAGE_UP:
   7066 					suppressKeyPress = true;
   7067 					this._move( "previousPage", event );
   7068 					break;
   7069 				case keyCode.PAGE_DOWN:
   7070 					suppressKeyPress = true;
   7071 					this._move( "nextPage", event );
   7072 					break;
   7073 				case keyCode.UP:
   7074 					suppressKeyPress = true;
   7075 					this._keyEvent( "previous", event );
   7076 					break;
   7077 				case keyCode.DOWN:
   7078 					suppressKeyPress = true;
   7079 					this._keyEvent( "next", event );
   7080 					break;
   7081 				case keyCode.ENTER:
   7082 					// when menu is open and has focus
   7083 					if ( this.menu.active ) {
   7084 						// #6055 - Opera still allows the keypress to occur
   7085 						// which causes forms to submit
   7086 						suppressKeyPress = true;
   7087 						event.preventDefault();
   7088 						this.menu.select( event );
   7089 					}
   7090 					break;
   7091 				case keyCode.TAB:
   7092 					if ( this.menu.active ) {
   7093 						this.menu.select( event );
   7094 					}
   7095 					break;
   7096 				case keyCode.ESCAPE:
   7097 					if ( this.menu.element.is( ":visible" ) ) {
   7098 						if ( !this.isMultiLine ) {
   7099 							this._value( this.term );
   7100 						}
   7101 						this.close( event );
   7102 						// Different browsers have different default behavior for escape
   7103 						// Single press can mean undo or clear
   7104 						// Double press in IE means clear the whole form
   7105 						event.preventDefault();
   7106 					}
   7107 					break;
   7108 				default:
   7109 					suppressKeyPressRepeat = true;
   7110 					// search timeout should be triggered before the input value is changed
   7111 					this._searchTimeout( event );
   7112 					break;
   7113 				}
   7114 			},
   7115 			keypress: function( event ) {
   7116 				if ( suppressKeyPress ) {
   7117 					suppressKeyPress = false;
   7118 					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
   7119 						event.preventDefault();
   7120 					}
   7121 					return;
   7122 				}
   7123 				if ( suppressKeyPressRepeat ) {
   7124 					return;
   7125 				}
   7126 
   7127 				// replicate some key handlers to allow them to repeat in Firefox and Opera
   7128 				var keyCode = $.ui.keyCode;
   7129 				switch ( event.keyCode ) {
   7130 				case keyCode.PAGE_UP:
   7131 					this._move( "previousPage", event );
   7132 					break;
   7133 				case keyCode.PAGE_DOWN:
   7134 					this._move( "nextPage", event );
   7135 					break;
   7136 				case keyCode.UP:
   7137 					this._keyEvent( "previous", event );
   7138 					break;
   7139 				case keyCode.DOWN:
   7140 					this._keyEvent( "next", event );
   7141 					break;
   7142 				}
   7143 			},
   7144 			input: function( event ) {
   7145 				if ( suppressInput ) {
   7146 					suppressInput = false;
   7147 					event.preventDefault();
   7148 					return;
   7149 				}
   7150 				this._searchTimeout( event );
   7151 			},
   7152 			focus: function() {
   7153 				this.selectedItem = null;
   7154 				this.previous = this._value();
   7155 			},
   7156 			blur: function( event ) {
   7157 				if ( this.cancelBlur ) {
   7158 					delete this.cancelBlur;
   7159 					return;
   7160 				}
   7161 
   7162 				clearTimeout( this.searching );
   7163 				this.close( event );
   7164 				this._change( event );
   7165 			}
   7166 		});
   7167 
   7168 		this._initSource();
   7169 		this.menu = $( "<ul>" )
   7170 			.addClass( "ui-autocomplete ui-front" )
   7171 			.appendTo( this._appendTo() )
   7172 			.menu({
   7173 				// disable ARIA support, the live region takes care of that
   7174 				role: null
   7175 			})
   7176 			.hide()
   7177 			.menu( "instance" );
   7178 
   7179 		this._on( this.menu.element, {
   7180 			mousedown: function( event ) {
   7181 				// prevent moving focus out of the text field
   7182 				event.preventDefault();
   7183 
   7184 				// IE doesn't prevent moving focus even with event.preventDefault()
   7185 				// so we set a flag to know when we should ignore the blur event
   7186 				this.cancelBlur = true;
   7187 				this._delay(function() {
   7188 					delete this.cancelBlur;
   7189 				});
   7190 
   7191 				// clicking on the scrollbar causes focus to shift to the body
   7192 				// but we can't detect a mouseup or a click immediately afterward
   7193 				// so we have to track the next mousedown and close the menu if
   7194 				// the user clicks somewhere outside of the autocomplete
   7195 				var menuElement = this.menu.element[ 0 ];
   7196 				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
   7197 					this._delay(function() {
   7198 						var that = this;
   7199 						this.document.one( "mousedown", function( event ) {
   7200 							if ( event.target !== that.element[ 0 ] &&
   7201 									event.target !== menuElement &&
   7202 									!$.contains( menuElement, event.target ) ) {
   7203 								that.close();
   7204 							}
   7205 						});
   7206 					});
   7207 				}
   7208 			},
   7209 			menufocus: function( event, ui ) {
   7210 				var label, item;
   7211 				// support: Firefox
   7212 				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
   7213 				if ( this.isNewMenu ) {
   7214 					this.isNewMenu = false;
   7215 					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
   7216 						this.menu.blur();
   7217 
   7218 						this.document.one( "mousemove", function() {
   7219 							$( event.target ).trigger( event.originalEvent );
   7220 						});
   7221 
   7222 						return;
   7223 					}
   7224 				}
   7225 
   7226 				item = ui.item.data( "ui-autocomplete-item" );
   7227 				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
   7228 					// use value to match what will end up in the input, if it was a key event
   7229 					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
   7230 						this._value( item.value );
   7231 					}
   7232 				}
   7233 
   7234 				// Announce the value in the liveRegion
   7235 				label = ui.item.attr( "aria-label" ) || item.value;
   7236 				if ( label && $.trim( label ).length ) {
   7237 					this.liveRegion.children().hide();
   7238 					$( "<div>" ).text( label ).appendTo( this.liveRegion );
   7239 				}
   7240 			},
   7241 			menuselect: function( event, ui ) {
   7242 				var item = ui.item.data( "ui-autocomplete-item" ),
   7243 					previous = this.previous;
   7244 
   7245 				// only trigger when focus was lost (click on menu)
   7246 				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
   7247 					this.element.focus();
   7248 					this.previous = previous;
   7249 					// #6109 - IE triggers two focus events and the second
   7250 					// is asynchronous, so we need to reset the previous
   7251 					// term synchronously and asynchronously :-(
   7252 					this._delay(function() {
   7253 						this.previous = previous;
   7254 						this.selectedItem = item;
   7255 					});
   7256 				}
   7257 
   7258 				if ( false !== this._trigger( "select", event, { item: item } ) ) {
   7259 					this._value( item.value );
   7260 				}
   7261 				// reset the term after the select event
   7262 				// this allows custom select handling to work properly
   7263 				this.term = this._value();
   7264 
   7265 				this.close( event );
   7266 				this.selectedItem = item;
   7267 			}
   7268 		});
   7269 
   7270 		this.liveRegion = $( "<span>", {
   7271 				role: "status",
   7272 				"aria-live": "assertive",
   7273 				"aria-relevant": "additions"
   7274 			})
   7275 			.addClass( "ui-helper-hidden-accessible" )
   7276 			.appendTo( this.document[ 0 ].body );
   7277 
   7278 		// turning off autocomplete prevents the browser from remembering the
   7279 		// value when navigating through history, so we re-enable autocomplete
   7280 		// if the page is unloaded before the widget is destroyed. #7790
   7281 		this._on( this.window, {
   7282 			beforeunload: function() {
   7283 				this.element.removeAttr( "autocomplete" );
   7284 			}
   7285 		});
   7286 	},
   7287 
   7288 	_destroy: function() {
   7289 		clearTimeout( this.searching );
   7290 		this.element
   7291 			.removeClass( "ui-autocomplete-input" )
   7292 			.removeAttr( "autocomplete" );
   7293 		this.menu.element.remove();
   7294 		this.liveRegion.remove();
   7295 	},
   7296 
   7297 	_setOption: function( key, value ) {
   7298 		this._super( key, value );
   7299 		if ( key === "source" ) {
   7300 			this._initSource();
   7301 		}
   7302 		if ( key === "appendTo" ) {
   7303 			this.menu.element.appendTo( this._appendTo() );
   7304 		}
   7305 		if ( key === "disabled" && value && this.xhr ) {
   7306 			this.xhr.abort();
   7307 		}
   7308 	},
   7309 
   7310 	_appendTo: function() {
   7311 		var element = this.options.appendTo;
   7312 
   7313 		if ( element ) {
   7314 			element = element.jquery || element.nodeType ?
   7315 				$( element ) :
   7316 				this.document.find( element ).eq( 0 );
   7317 		}
   7318 
   7319 		if ( !element || !element[ 0 ] ) {
   7320 			element = this.element.closest( ".ui-front" );
   7321 		}
   7322 
   7323 		if ( !element.length ) {
   7324 			element = this.document[ 0 ].body;
   7325 		}
   7326 
   7327 		return element;
   7328 	},
   7329 
   7330 	_initSource: function() {
   7331 		var array, url,
   7332 			that = this;
   7333 		if ( $.isArray( this.options.source ) ) {
   7334 			array = this.options.source;
   7335 			this.source = function( request, response ) {
   7336 				response( $.ui.autocomplete.filter( array, request.term ) );
   7337 			};
   7338 		} else if ( typeof this.options.source === "string" ) {
   7339 			url = this.options.source;
   7340 			this.source = function( request, response ) {
   7341 				if ( that.xhr ) {
   7342 					that.xhr.abort();
   7343 				}
   7344 				that.xhr = $.ajax({
   7345 					url: url,
   7346 					data: request,
   7347 					dataType: "json",
   7348 					success: function( data ) {
   7349 						response( data );
   7350 					},
   7351 					error: function() {
   7352 						response([]);
   7353 					}
   7354 				});
   7355 			};
   7356 		} else {
   7357 			this.source = this.options.source;
   7358 		}
   7359 	},
   7360 
   7361 	_searchTimeout: function( event ) {
   7362 		clearTimeout( this.searching );
   7363 		this.searching = this._delay(function() {
   7364 
   7365 			// Search if the value has changed, or if the user retypes the same value (see #7434)
   7366 			var equalValues = this.term === this._value(),
   7367 				menuVisible = this.menu.element.is( ":visible" ),
   7368 				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
   7369 
   7370 			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
   7371 				this.selectedItem = null;
   7372 				this.search( null, event );
   7373 			}
   7374 		}, this.options.delay );
   7375 	},
   7376 
   7377 	search: function( value, event ) {
   7378 		value = value != null ? value : this._value();
   7379 
   7380 		// always save the actual value, not the one passed as an argument
   7381 		this.term = this._value();
   7382 
   7383 		if ( value.length < this.options.minLength ) {
   7384 			return this.close( event );
   7385 		}
   7386 
   7387 		if ( this._trigger( "search", event ) === false ) {
   7388 			return;
   7389 		}
   7390 
   7391 		return this._search( value );
   7392 	},
   7393 
   7394 	_search: function( value ) {
   7395 		this.pending++;
   7396 		this.element.addClass( "ui-autocomplete-loading" );
   7397 		this.cancelSearch = false;
   7398 
   7399 		this.source( { term: value }, this._response() );
   7400 	},
   7401 
   7402 	_response: function() {
   7403 		var index = ++this.requestIndex;
   7404 
   7405 		return $.proxy(function( content ) {
   7406 			if ( index === this.requestIndex ) {
   7407 				this.__response( content );
   7408 			}
   7409 
   7410 			this.pending--;
   7411 			if ( !this.pending ) {
   7412 				this.element.removeClass( "ui-autocomplete-loading" );
   7413 			}
   7414 		}, this );
   7415 	},
   7416 
   7417 	__response: function( content ) {
   7418 		if ( content ) {
   7419 			content = this._normalize( content );
   7420 		}
   7421 		this._trigger( "response", null, { content: content } );
   7422 		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
   7423 			this._suggest( content );
   7424 			this._trigger( "open" );
   7425 		} else {
   7426 			// use ._close() instead of .close() so we don't cancel future searches
   7427 			this._close();
   7428 		}
   7429 	},
   7430 
   7431 	close: function( event ) {
   7432 		this.cancelSearch = true;
   7433 		this._close( event );
   7434 	},
   7435 
   7436 	_close: function( event ) {
   7437 		if ( this.menu.element.is( ":visible" ) ) {
   7438 			this.menu.element.hide();
   7439 			this.menu.blur();
   7440 			this.isNewMenu = true;
   7441 			this._trigger( "close", event );
   7442 		}
   7443 	},
   7444 
   7445 	_change: function( event ) {
   7446 		if ( this.previous !== this._value() ) {
   7447 			this._trigger( "change", event, { item: this.selectedItem } );
   7448 		}
   7449 	},
   7450 
   7451 	_normalize: function( items ) {
   7452 		// assume all items have the right format when the first item is complete
   7453 		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
   7454 			return items;
   7455 		}
   7456 		return $.map( items, function( item ) {
   7457 			if ( typeof item === "string" ) {
   7458 				return {
   7459 					label: item,
   7460 					value: item
   7461 				};
   7462 			}
   7463 			return $.extend( {}, item, {
   7464 				label: item.label || item.value,
   7465 				value: item.value || item.label
   7466 			});
   7467 		});
   7468 	},
   7469 
   7470 	_suggest: function( items ) {
   7471 		var ul = this.menu.element.empty();
   7472 		this._renderMenu( ul, items );
   7473 		this.isNewMenu = true;
   7474 		this.menu.refresh();
   7475 
   7476 		// size and position menu
   7477 		ul.show();
   7478 		this._resizeMenu();
   7479 		ul.position( $.extend({
   7480 			of: this.element
   7481 		}, this.options.position ) );
   7482 
   7483 		if ( this.options.autoFocus ) {
   7484 			this.menu.next();
   7485 		}
   7486 	},
   7487 
   7488 	_resizeMenu: function() {
   7489 		var ul = this.menu.element;
   7490 		ul.outerWidth( Math.max(
   7491 			// Firefox wraps long text (possibly a rounding bug)
   7492 			// so we add 1px to avoid the wrapping (#7513)
   7493 			ul.width( "" ).outerWidth() + 1,
   7494 			this.element.outerWidth()
   7495 		) );
   7496 	},
   7497 
   7498 	_renderMenu: function( ul, items ) {
   7499 		var that = this;
   7500 		$.each( items, function( index, item ) {
   7501 			that._renderItemData( ul, item );
   7502 		});
   7503 	},
   7504 
   7505 	_renderItemData: function( ul, item ) {
   7506 		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
   7507 	},
   7508 
   7509 	_renderItem: function( ul, item ) {
   7510 		return $( "<li>" ).text( item.label ).appendTo( ul );
   7511 	},
   7512 
   7513 	_move: function( direction, event ) {
   7514 		if ( !this.menu.element.is( ":visible" ) ) {
   7515 			this.search( null, event );
   7516 			return;
   7517 		}
   7518 		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
   7519 				this.menu.isLastItem() && /^next/.test( direction ) ) {
   7520 
   7521 			if ( !this.isMultiLine ) {
   7522 				this._value( this.term );
   7523 			}
   7524 
   7525 			this.menu.blur();
   7526 			return;
   7527 		}
   7528 		this.menu[ direction ]( event );
   7529 	},
   7530 
   7531 	widget: function() {
   7532 		return this.menu.element;
   7533 	},
   7534 
   7535 	_value: function() {
   7536 		return this.valueMethod.apply( this.element, arguments );
   7537 	},
   7538 
   7539 	_keyEvent: function( keyEvent, event ) {
   7540 		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
   7541 			this._move( keyEvent, event );
   7542 
   7543 			// prevents moving cursor to beginning/end of the text field in some browsers
   7544 			event.preventDefault();
   7545 		}
   7546 	}
   7547 });
   7548 
   7549 $.extend( $.ui.autocomplete, {
   7550 	escapeRegex: function( value ) {
   7551 		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
   7552 	},
   7553 	filter: function( array, term ) {
   7554 		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
   7555 		return $.grep( array, function( value ) {
   7556 			return matcher.test( value.label || value.value || value );
   7557 		});
   7558 	}
   7559 });
   7560 
   7561 // live region extension, adding a `messages` option
   7562 // NOTE: This is an experimental API. We are still investigating
   7563 // a full solution for string manipulation and internationalization.
   7564 $.widget( "ui.autocomplete", $.ui.autocomplete, {
   7565 	options: {
   7566 		messages: {
   7567 			noResults: "No search results.",
   7568 			results: function( amount ) {
   7569 				return amount + ( amount > 1 ? " results are" : " result is" ) +
   7570 					" available, use up and down arrow keys to navigate.";
   7571 			}
   7572 		}
   7573 	},
   7574 
   7575 	__response: function( content ) {
   7576 		var message;
   7577 		this._superApply( arguments );
   7578 		if ( this.options.disabled || this.cancelSearch ) {
   7579 			return;
   7580 		}
   7581 		if ( content && content.length ) {
   7582 			message = this.options.messages.results( content.length );
   7583 		} else {
   7584 			message = this.options.messages.noResults;
   7585 		}
   7586 		this.liveRegion.children().hide();
   7587 		$( "<div>" ).text( message ).appendTo( this.liveRegion );
   7588 	}
   7589 });
   7590 
   7591 var autocomplete = $.ui.autocomplete;
   7592 
   7593 
   7594 /*!
   7595  * jQuery UI Button 1.11.4
   7596  * http://jqueryui.com
   7597  *
   7598  * Copyright jQuery Foundation and other contributors
   7599  * Released under the MIT license.
   7600  * http://jquery.org/license
   7601  *
   7602  * http://api.jqueryui.com/button/
   7603  */
   7604 
   7605 
   7606 var lastActive,
   7607 	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
   7608 	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
   7609 	formResetHandler = function() {
   7610 		var form = $( this );
   7611 		setTimeout(function() {
   7612 			form.find( ":ui-button" ).button( "refresh" );
   7613 		}, 1 );
   7614 	},
   7615 	radioGroup = function( radio ) {
   7616 		var name = radio.name,
   7617 			form = radio.form,
   7618 			radios = $( [] );
   7619 		if ( name ) {
   7620 			name = name.replace( /'/g, "\\'" );
   7621 			if ( form ) {
   7622 				radios = $( form ).find( "[name='" + name + "'][type=radio]" );
   7623 			} else {
   7624 				radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
   7625 					.filter(function() {
   7626 						return !this.form;
   7627 					});
   7628 			}
   7629 		}
   7630 		return radios;
   7631 	};
   7632 
   7633 $.widget( "ui.button", {
   7634 	version: "1.11.4",
   7635 	defaultElement: "<button>",
   7636 	options: {
   7637 		disabled: null,
   7638 		text: true,
   7639 		label: null,
   7640 		icons: {
   7641 			primary: null,
   7642 			secondary: null
   7643 		}
   7644 	},
   7645 	_create: function() {
   7646 		this.element.closest( "form" )
   7647 			.unbind( "reset" + this.eventNamespace )
   7648 			.bind( "reset" + this.eventNamespace, formResetHandler );
   7649 
   7650 		if ( typeof this.options.disabled !== "boolean" ) {
   7651 			this.options.disabled = !!this.element.prop( "disabled" );
   7652 		} else {
   7653 			this.element.prop( "disabled", this.options.disabled );
   7654 		}
   7655 
   7656 		this._determineButtonType();
   7657 		this.hasTitle = !!this.buttonElement.attr( "title" );
   7658 
   7659 		var that = this,
   7660 			options = this.options,
   7661 			toggleButton = this.type === "checkbox" || this.type === "radio",
   7662 			activeClass = !toggleButton ? "ui-state-active" : "";
   7663 
   7664 		if ( options.label === null ) {
   7665 			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
   7666 		}
   7667 
   7668 		this._hoverable( this.buttonElement );
   7669 
   7670 		this.buttonElement
   7671 			.addClass( baseClasses )
   7672 			.attr( "role", "button" )
   7673 			.bind( "mouseenter" + this.eventNamespace, function() {
   7674 				if ( options.disabled ) {
   7675 					return;
   7676 				}
   7677 				if ( this === lastActive ) {
   7678 					$( this ).addClass( "ui-state-active" );
   7679 				}
   7680 			})
   7681 			.bind( "mouseleave" + this.eventNamespace, function() {
   7682 				if ( options.disabled ) {
   7683 					return;
   7684 				}
   7685 				$( this ).removeClass( activeClass );
   7686 			})
   7687 			.bind( "click" + this.eventNamespace, function( event ) {
   7688 				if ( options.disabled ) {
   7689 					event.preventDefault();
   7690 					event.stopImmediatePropagation();
   7691 				}
   7692 			});
   7693 
   7694 		// Can't use _focusable() because the element that receives focus
   7695 		// and the element that gets the ui-state-focus class are different
   7696 		this._on({
   7697 			focus: function() {
   7698 				this.buttonElement.addClass( "ui-state-focus" );
   7699 			},
   7700 			blur: function() {
   7701 				this.buttonElement.removeClass( "ui-state-focus" );
   7702 			}
   7703 		});
   7704 
   7705 		if ( toggleButton ) {
   7706 			this.element.bind( "change" + this.eventNamespace, function() {
   7707 				that.refresh();
   7708 			});
   7709 		}
   7710 
   7711 		if ( this.type === "checkbox" ) {
   7712 			this.buttonElement.bind( "click" + this.eventNamespace, function() {
   7713 				if ( options.disabled ) {
   7714 					return false;
   7715 				}
   7716 			});
   7717 		} else if ( this.type === "radio" ) {
   7718 			this.buttonElement.bind( "click" + this.eventNamespace, function() {
   7719 				if ( options.disabled ) {
   7720 					return false;
   7721 				}
   7722 				$( this ).addClass( "ui-state-active" );
   7723 				that.buttonElement.attr( "aria-pressed", "true" );
   7724 
   7725 				var radio = that.element[ 0 ];
   7726 				radioGroup( radio )
   7727 					.not( radio )
   7728 					.map(function() {
   7729 						return $( this ).button( "widget" )[ 0 ];
   7730 					})
   7731 					.removeClass( "ui-state-active" )
   7732 					.attr( "aria-pressed", "false" );
   7733 			});
   7734 		} else {
   7735 			this.buttonElement
   7736 				.bind( "mousedown" + this.eventNamespace, function() {
   7737 					if ( options.disabled ) {
   7738 						return false;
   7739 					}
   7740 					$( this ).addClass( "ui-state-active" );
   7741 					lastActive = this;
   7742 					that.document.one( "mouseup", function() {
   7743 						lastActive = null;
   7744 					});
   7745 				})
   7746 				.bind( "mouseup" + this.eventNamespace, function() {
   7747 					if ( options.disabled ) {
   7748 						return false;
   7749 					}
   7750 					$( this ).removeClass( "ui-state-active" );
   7751 				})
   7752 				.bind( "keydown" + this.eventNamespace, function(event) {
   7753 					if ( options.disabled ) {
   7754 						return false;
   7755 					}
   7756 					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
   7757 						$( this ).addClass( "ui-state-active" );
   7758 					}
   7759 				})
   7760 				// see #8559, we bind to blur here in case the button element loses
   7761 				// focus between keydown and keyup, it would be left in an "active" state
   7762 				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
   7763 					$( this ).removeClass( "ui-state-active" );
   7764 				});
   7765 
   7766 			if ( this.buttonElement.is("a") ) {
   7767 				this.buttonElement.keyup(function(event) {
   7768 					if ( event.keyCode === $.ui.keyCode.SPACE ) {
   7769 						// TODO pass through original event correctly (just as 2nd argument doesn't work)
   7770 						$( this ).click();
   7771 					}
   7772 				});
   7773 			}
   7774 		}
   7775 
   7776 		this._setOption( "disabled", options.disabled );
   7777 		this._resetButton();
   7778 	},
   7779 
   7780 	_determineButtonType: function() {
   7781 		var ancestor, labelSelector, checked;
   7782 
   7783 		if ( this.element.is("[type=checkbox]") ) {
   7784 			this.type = "checkbox";
   7785 		} else if ( this.element.is("[type=radio]") ) {
   7786 			this.type = "radio";
   7787 		} else if ( this.element.is("input") ) {
   7788 			this.type = "input";
   7789 		} else {
   7790 			this.type = "button";
   7791 		}
   7792 
   7793 		if ( this.type === "checkbox" || this.type === "radio" ) {
   7794 			// we don't search against the document in case the element
   7795 			// is disconnected from the DOM
   7796 			ancestor = this.element.parents().last();
   7797 			labelSelector = "label[for='" + this.element.attr("id") + "']";
   7798 			this.buttonElement = ancestor.find( labelSelector );
   7799 			if ( !this.buttonElement.length ) {
   7800 				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
   7801 				this.buttonElement = ancestor.filter( labelSelector );
   7802 				if ( !this.buttonElement.length ) {
   7803 					this.buttonElement = ancestor.find( labelSelector );
   7804 				}
   7805 			}
   7806 			this.element.addClass( "ui-helper-hidden-accessible" );
   7807 
   7808 			checked = this.element.is( ":checked" );
   7809 			if ( checked ) {
   7810 				this.buttonElement.addClass( "ui-state-active" );
   7811 			}
   7812 			this.buttonElement.prop( "aria-pressed", checked );
   7813 		} else {
   7814 			this.buttonElement = this.element;
   7815 		}
   7816 	},
   7817 
   7818 	widget: function() {
   7819 		return this.buttonElement;
   7820 	},
   7821 
   7822 	_destroy: function() {
   7823 		this.element
   7824 			.removeClass( "ui-helper-hidden-accessible" );
   7825 		this.buttonElement
   7826 			.removeClass( baseClasses + " ui-state-active " + typeClasses )
   7827 			.removeAttr( "role" )
   7828 			.removeAttr( "aria-pressed" )
   7829 			.html( this.buttonElement.find(".ui-button-text").html() );
   7830 
   7831 		if ( !this.hasTitle ) {
   7832 			this.buttonElement.removeAttr( "title" );
   7833 		}
   7834 	},
   7835 
   7836 	_setOption: function( key, value ) {
   7837 		this._super( key, value );
   7838 		if ( key === "disabled" ) {
   7839 			this.widget().toggleClass( "ui-state-disabled", !!value );
   7840 			this.element.prop( "disabled", !!value );
   7841 			if ( value ) {
   7842 				if ( this.type === "checkbox" || this.type === "radio" ) {
   7843 					this.buttonElement.removeClass( "ui-state-focus" );
   7844 				} else {
   7845 					this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
   7846 				}
   7847 			}
   7848 			return;
   7849 		}
   7850 		this._resetButton();
   7851 	},
   7852 
   7853 	refresh: function() {
   7854 		//See #8237 & #8828
   7855 		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
   7856 
   7857 		if ( isDisabled !== this.options.disabled ) {
   7858 			this._setOption( "disabled", isDisabled );
   7859 		}
   7860 		if ( this.type === "radio" ) {
   7861 			radioGroup( this.element[0] ).each(function() {
   7862 				if ( $( this ).is( ":checked" ) ) {
   7863 					$( this ).button( "widget" )
   7864 						.addClass( "ui-state-active" )
   7865 						.attr( "aria-pressed", "true" );
   7866 				} else {
   7867 					$( this ).button( "widget" )
   7868 						.removeClass( "ui-state-active" )
   7869 						.attr( "aria-pressed", "false" );
   7870 				}
   7871 			});
   7872 		} else if ( this.type === "checkbox" ) {
   7873 			if ( this.element.is( ":checked" ) ) {
   7874 				this.buttonElement
   7875 					.addClass( "ui-state-active" )
   7876 					.attr( "aria-pressed", "true" );
   7877 			} else {
   7878 				this.buttonElement
   7879 					.removeClass( "ui-state-active" )
   7880 					.attr( "aria-pressed", "false" );
   7881 			}
   7882 		}
   7883 	},
   7884 
   7885 	_resetButton: function() {
   7886 		if ( this.type === "input" ) {
   7887 			if ( this.options.label ) {
   7888 				this.element.val( this.options.label );
   7889 			}
   7890 			return;
   7891 		}
   7892 		var buttonElement = this.buttonElement.removeClass( typeClasses ),
   7893 			buttonText = $( "<span></span>", this.document[0] )
   7894 				.addClass( "ui-button-text" )
   7895 				.html( this.options.label )
   7896 				.appendTo( buttonElement.empty() )
   7897 				.text(),
   7898 			icons = this.options.icons,
   7899 			multipleIcons = icons.primary && icons.secondary,
   7900 			buttonClasses = [];
   7901 
   7902 		if ( icons.primary || icons.secondary ) {
   7903 			if ( this.options.text ) {
   7904 				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
   7905 			}
   7906 
   7907 			if ( icons.primary ) {
   7908 				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
   7909 			}
   7910 
   7911 			if ( icons.secondary ) {
   7912 				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
   7913 			}
   7914 
   7915 			if ( !this.options.text ) {
   7916 				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
   7917 
   7918 				if ( !this.hasTitle ) {
   7919 					buttonElement.attr( "title", $.trim( buttonText ) );
   7920 				}
   7921 			}
   7922 		} else {
   7923 			buttonClasses.push( "ui-button-text-only" );
   7924 		}
   7925 		buttonElement.addClass( buttonClasses.join( " " ) );
   7926 	}
   7927 });
   7928 
   7929 $.widget( "ui.buttonset", {
   7930 	version: "1.11.4",
   7931 	options: {
   7932 		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
   7933 	},
   7934 
   7935 	_create: function() {
   7936 		this.element.addClass( "ui-buttonset" );
   7937 	},
   7938 
   7939 	_init: function() {
   7940 		this.refresh();
   7941 	},
   7942 
   7943 	_setOption: function( key, value ) {
   7944 		if ( key === "disabled" ) {
   7945 			this.buttons.button( "option", key, value );
   7946 		}
   7947 
   7948 		this._super( key, value );
   7949 	},
   7950 
   7951 	refresh: function() {
   7952 		var rtl = this.element.css( "direction" ) === "rtl",
   7953 			allButtons = this.element.find( this.options.items ),
   7954 			existingButtons = allButtons.filter( ":ui-button" );
   7955 
   7956 		// Initialize new buttons
   7957 		allButtons.not( ":ui-button" ).button();
   7958 
   7959 		// Refresh existing buttons
   7960 		existingButtons.button( "refresh" );
   7961 
   7962 		this.buttons = allButtons
   7963 			.map(function() {
   7964 				return $( this ).button( "widget" )[ 0 ];
   7965 			})
   7966 				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
   7967 				.filter( ":first" )
   7968 					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
   7969 				.end()
   7970 				.filter( ":last" )
   7971 					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
   7972 				.end()
   7973 			.end();
   7974 	},
   7975 
   7976 	_destroy: function() {
   7977 		this.element.removeClass( "ui-buttonset" );
   7978 		this.buttons
   7979 			.map(function() {
   7980 				return $( this ).button( "widget" )[ 0 ];
   7981 			})
   7982 				.removeClass( "ui-corner-left ui-corner-right" )
   7983 			.end()
   7984 			.button( "destroy" );
   7985 	}
   7986 });
   7987 
   7988 var button = $.ui.button;
   7989 
   7990 
   7991 /*!
   7992  * jQuery UI Datepicker 1.11.4
   7993  * http://jqueryui.com
   7994  *
   7995  * Copyright jQuery Foundation and other contributors
   7996  * Released under the MIT license.
   7997  * http://jquery.org/license
   7998  *
   7999  * http://api.jqueryui.com/datepicker/
   8000  */
   8001 
   8002 
   8003 $.extend($.ui, { datepicker: { version: "1.11.4" } });
   8004 
   8005 var datepicker_instActive;
   8006 
   8007 function datepicker_getZindex( elem ) {
   8008 	var position, value;
   8009 	while ( elem.length && elem[ 0 ] !== document ) {
   8010 		// Ignore z-index if position is set to a value where z-index is ignored by the browser
   8011 		// This makes behavior of this function consistent across browsers
   8012 		// WebKit always returns auto if the element is positioned
   8013 		position = elem.css( "position" );
   8014 		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
   8015 			// IE returns 0 when zIndex is not specified
   8016 			// other browsers return a string
   8017 			// we ignore the case of nested elements with an explicit value of 0
   8018 			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
   8019 			value = parseInt( elem.css( "zIndex" ), 10 );
   8020 			if ( !isNaN( value ) && value !== 0 ) {
   8021 				return value;
   8022 			}
   8023 		}
   8024 		elem = elem.parent();
   8025 	}
   8026 
   8027 	return 0;
   8028 }
   8029 /* Date picker manager.
   8030    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
   8031    Settings for (groups of) date pickers are maintained in an instance object,
   8032    allowing multiple different settings on the same page. */
   8033 
   8034 function Datepicker() {
   8035 	this._curInst = null; // The current instance in use
   8036 	this._keyEvent = false; // If the last event was a key event
   8037 	this._disabledInputs = []; // List of date picker inputs that have been disabled
   8038 	this._datepickerShowing = false; // True if the popup picker is showing , false if not
   8039 	this._inDialog = false; // True if showing within a "dialog", false if not
   8040 	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
   8041 	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
   8042 	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
   8043 	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
   8044 	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
   8045 	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
   8046 	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
   8047 	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
   8048 	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
   8049 	this.regional = []; // Available regional settings, indexed by language code
   8050 	this.regional[""] = { // Default regional settings
   8051 		closeText: "Done", // Display text for close link
   8052 		prevText: "Prev", // Display text for previous month link
   8053 		nextText: "Next", // Display text for next month link
   8054 		currentText: "Today", // Display text for current month link
   8055 		monthNames: ["January","February","March","April","May","June",
   8056 			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
   8057 		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
   8058 		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
   8059 		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
   8060 		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
   8061 		weekHeader: "Wk", // Column header for week of the year
   8062 		dateFormat: "mm/dd/yy", // See format options on parseDate
   8063 		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
   8064 		isRTL: false, // True if right-to-left language, false if left-to-right
   8065 		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
   8066 		yearSuffix: "" // Additional text to append to the year in the month headers
   8067 	};
   8068 	this._defaults = { // Global defaults for all the date picker instances
   8069 		showOn: "focus", // "focus" for popup on focus,
   8070 			// "button" for trigger button, or "both" for either
   8071 		showAnim: "fadeIn", // Name of jQuery animation for popup
   8072 		showOptions: {}, // Options for enhanced animations
   8073 		defaultDate: null, // Used when field is blank: actual date,
   8074 			// +/-number for offset from today, null for today
   8075 		appendText: "", // Display text following the input box, e.g. showing the format
   8076 		buttonText: "...", // Text for trigger button
   8077 		buttonImage: "", // URL for trigger button image
   8078 		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
   8079 		hideIfNoPrevNext: false, // True to hide next/previous month links
   8080 			// if not applicable, false to just disable them
   8081 		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
   8082 		gotoCurrent: false, // True if today link goes back to current selection instead
   8083 		changeMonth: false, // True if month can be selected directly, false if only prev/next
   8084 		changeYear: false, // True if year can be selected directly, false if only prev/next
   8085 		yearRange: "c-10:c+10", // Range of years to display in drop-down,
   8086 			// either relative to today's year (-nn:+nn), relative to currently displayed year
   8087 			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
   8088 		showOtherMonths: false, // True to show dates in other months, false to leave blank
   8089 		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
   8090 		showWeek: false, // True to show week of the year, false to not show it
   8091 		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
   8092 			// takes a Date and returns the number of the week for it
   8093 		shortYearCutoff: "+10", // Short year values < this are in the current century,
   8094 			// > this are in the previous century,
   8095 			// string value starting with "+" for current year + value
   8096 		minDate: null, // The earliest selectable date, or null for no limit
   8097 		maxDate: null, // The latest selectable date, or null for no limit
   8098 		duration: "fast", // Duration of display/closure
   8099 		beforeShowDay: null, // Function that takes a date and returns an array with
   8100 			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
   8101 			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
   8102 		beforeShow: null, // Function that takes an input field and
   8103 			// returns a set of custom settings for the date picker
   8104 		onSelect: null, // Define a callback function when a date is selected
   8105 		onChangeMonthYear: null, // Define a callback function when the month or year is changed
   8106 		onClose: null, // Define a callback function when the datepicker is closed
   8107 		numberOfMonths: 1, // Number of months to show at a time
   8108 		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
   8109 		stepMonths: 1, // Number of months to step back/forward
   8110 		stepBigMonths: 12, // Number of months to step back/forward for the big links
   8111 		altField: "", // Selector for an alternate field to store selected dates into
   8112 		altFormat: "", // The date format to use for the alternate field
   8113 		constrainInput: true, // The input is constrained by the current date format
   8114 		showButtonPanel: false, // True to show button panel, false to not show it
   8115 		autoSize: false, // True to size the input for the date format, false to leave as is
   8116 		disabled: false // The initial disabled state
   8117 	};
   8118 	$.extend(this._defaults, this.regional[""]);
   8119 	this.regional.en = $.extend( true, {}, this.regional[ "" ]);
   8120 	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
   8121 	this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
   8122 }
   8123 
   8124 $.extend(Datepicker.prototype, {
   8125 	/* Class name added to elements to indicate already configured with a date picker. */
   8126 	markerClassName: "hasDatepicker",
   8127 
   8128 	//Keep track of the maximum number of rows displayed (see #7043)
   8129 	maxRows: 4,
   8130 
   8131 	// TODO rename to "widget" when switching to widget factory
   8132 	_widgetDatepicker: function() {
   8133 		return this.dpDiv;
   8134 	},
   8135 
   8136 	/* Override the default settings for all instances of the date picker.
   8137 	 * @param  settings  object - the new settings to use as defaults (anonymous object)
   8138 	 * @return the manager object
   8139 	 */
   8140 	setDefaults: function(settings) {
   8141 		datepicker_extendRemove(this._defaults, settings || {});
   8142 		return this;
   8143 	},
   8144 
   8145 	/* Attach the date picker to a jQuery selection.
   8146 	 * @param  target	element - the target input field or division or span
   8147 	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
   8148 	 */
   8149 	_attachDatepicker: function(target, settings) {
   8150 		var nodeName, inline, inst;
   8151 		nodeName = target.nodeName.toLowerCase();
   8152 		inline = (nodeName === "div" || nodeName === "span");
   8153 		if (!target.id) {
   8154 			this.uuid += 1;
   8155 			target.id = "dp" + this.uuid;
   8156 		}
   8157 		inst = this._newInst($(target), inline);
   8158 		inst.settings = $.extend({}, settings || {});
   8159 		if (nodeName === "input") {
   8160 			this._connectDatepicker(target, inst);
   8161 		} else if (inline) {
   8162 			this._inlineDatepicker(target, inst);
   8163 		}
   8164 	},
   8165 
   8166 	/* Create a new instance object. */
   8167 	_newInst: function(target, inline) {
   8168 		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
   8169 		return {id: id, input: target, // associated target
   8170 			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
   8171 			drawMonth: 0, drawYear: 0, // month being drawn
   8172 			inline: inline, // is datepicker inline or not
   8173 			dpDiv: (!inline ? this.dpDiv : // presentation div
   8174 			datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
   8175 	},
   8176 
   8177 	/* Attach the date picker to an input field. */
   8178 	_connectDatepicker: function(target, inst) {
   8179 		var input = $(target);
   8180 		inst.append = $([]);
   8181 		inst.trigger = $([]);
   8182 		if (input.hasClass(this.markerClassName)) {
   8183 			return;
   8184 		}
   8185 		this._attachments(input, inst);
   8186 		input.addClass(this.markerClassName).keydown(this._doKeyDown).
   8187 			keypress(this._doKeyPress).keyup(this._doKeyUp);
   8188 		this._autoSize(inst);
   8189 		$.data(target, "datepicker", inst);
   8190 		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
   8191 		if( inst.settings.disabled ) {
   8192 			this._disableDatepicker( target );
   8193 		}
   8194 	},
   8195 
   8196 	/* Make attachments based on settings. */
   8197 	_attachments: function(input, inst) {
   8198 		var showOn, buttonText, buttonImage,
   8199 			appendText = this._get(inst, "appendText"),
   8200 			isRTL = this._get(inst, "isRTL");
   8201 
   8202 		if (inst.append) {
   8203 			inst.append.remove();
   8204 		}
   8205 		if (appendText) {
   8206 			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
   8207 			input[isRTL ? "before" : "after"](inst.append);
   8208 		}
   8209 
   8210 		input.unbind("focus", this._showDatepicker);
   8211 
   8212 		if (inst.trigger) {
   8213 			inst.trigger.remove();
   8214 		}
   8215 
   8216 		showOn = this._get(inst, "showOn");
   8217 		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
   8218 			input.focus(this._showDatepicker);
   8219 		}
   8220 		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
   8221 			buttonText = this._get(inst, "buttonText");
   8222 			buttonImage = this._get(inst, "buttonImage");
   8223 			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
   8224 				$("<img/>").addClass(this._triggerClass).
   8225 					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
   8226 				$("<button type='button'></button>").addClass(this._triggerClass).
   8227 					html(!buttonImage ? buttonText : $("<img/>").attr(
   8228 					{ src:buttonImage, alt:buttonText, title:buttonText })));
   8229 			input[isRTL ? "before" : "after"](inst.trigger);
   8230 			inst.trigger.click(function() {
   8231 				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
   8232 					$.datepicker._hideDatepicker();
   8233 				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
   8234 					$.datepicker._hideDatepicker();
   8235 					$.datepicker._showDatepicker(input[0]);
   8236 				} else {
   8237 					$.datepicker._showDatepicker(input[0]);
   8238 				}
   8239 				return false;
   8240 			});
   8241 		}
   8242 	},
   8243 
   8244 	/* Apply the maximum length for the date format. */
   8245 	_autoSize: function(inst) {
   8246 		if (this._get(inst, "autoSize") && !inst.inline) {
   8247 			var findMax, max, maxI, i,
   8248 				date = new Date(2009, 12 - 1, 20), // Ensure double digits
   8249 				dateFormat = this._get(inst, "dateFormat");
   8250 
   8251 			if (dateFormat.match(/[DM]/)) {
   8252 				findMax = function(names) {
   8253 					max = 0;
   8254 					maxI = 0;
   8255 					for (i = 0; i < names.length; i++) {
   8256 						if (names[i].length > max) {
   8257 							max = names[i].length;
   8258 							maxI = i;
   8259 						}
   8260 					}
   8261 					return maxI;
   8262 				};
   8263 				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
   8264 					"monthNames" : "monthNamesShort"))));
   8265 				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
   8266 					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
   8267 			}
   8268 			inst.input.attr("size", this._formatDate(inst, date).length);
   8269 		}
   8270 	},
   8271 
   8272 	/* Attach an inline date picker to a div. */
   8273 	_inlineDatepicker: function(target, inst) {
   8274 		var divSpan = $(target);
   8275 		if (divSpan.hasClass(this.markerClassName)) {
   8276 			return;
   8277 		}
   8278 		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
   8279 		$.data(target, "datepicker", inst);
   8280 		this._setDate(inst, this._getDefaultDate(inst), true);
   8281 		this._updateDatepicker(inst);
   8282 		this._updateAlternate(inst);
   8283 		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
   8284 		if( inst.settings.disabled ) {
   8285 			this._disableDatepicker( target );
   8286 		}
   8287 		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
   8288 		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
   8289 		inst.dpDiv.css( "display", "block" );
   8290 	},
   8291 
   8292 	/* Pop-up the date picker in a "dialog" box.
   8293 	 * @param  input element - ignored
   8294 	 * @param  date	string or Date - the initial date to display
   8295 	 * @param  onSelect  function - the function to call when a date is selected
   8296 	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
   8297 	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
   8298 	 *					event - with x/y coordinates or
   8299 	 *					leave empty for default (screen centre)
   8300 	 * @return the manager object
   8301 	 */
   8302 	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
   8303 		var id, browserWidth, browserHeight, scrollX, scrollY,
   8304 			inst = this._dialogInst; // internal instance
   8305 
   8306 		if (!inst) {
   8307 			this.uuid += 1;
   8308 			id = "dp" + this.uuid;
   8309 			this._dialogInput = $("<input type='text' id='" + id +
   8310 				"' style='position: absolute; top: -100px; width: 0px;'/>");
   8311 			this._dialogInput.keydown(this._doKeyDown);
   8312 			$("body").append(this._dialogInput);
   8313 			inst = this._dialogInst = this._newInst(this._dialogInput, false);
   8314 			inst.settings = {};
   8315 			$.data(this._dialogInput[0], "datepicker", inst);
   8316 		}
   8317 		datepicker_extendRemove(inst.settings, settings || {});
   8318 		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
   8319 		this._dialogInput.val(date);
   8320 
   8321 		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
   8322 		if (!this._pos) {
   8323 			browserWidth = document.documentElement.clientWidth;
   8324 			browserHeight = document.documentElement.clientHeight;
   8325 			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
   8326 			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
   8327 			this._pos = // should use actual width/height below
   8328 				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
   8329 		}
   8330 
   8331 		// move input on screen for focus, but hidden behind dialog
   8332 		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
   8333 		inst.settings.onSelect = onSelect;
   8334 		this._inDialog = true;
   8335 		this.dpDiv.addClass(this._dialogClass);
   8336 		this._showDatepicker(this._dialogInput[0]);
   8337 		if ($.blockUI) {
   8338 			$.blockUI(this.dpDiv);
   8339 		}
   8340 		$.data(this._dialogInput[0], "datepicker", inst);
   8341 		return this;
   8342 	},
   8343 
   8344 	/* Detach a datepicker from its control.
   8345 	 * @param  target	element - the target input field or division or span
   8346 	 */
   8347 	_destroyDatepicker: function(target) {
   8348 		var nodeName,
   8349 			$target = $(target),
   8350 			inst = $.data(target, "datepicker");
   8351 
   8352 		if (!$target.hasClass(this.markerClassName)) {
   8353 			return;
   8354 		}
   8355 
   8356 		nodeName = target.nodeName.toLowerCase();
   8357 		$.removeData(target, "datepicker");
   8358 		if (nodeName === "input") {
   8359 			inst.append.remove();
   8360 			inst.trigger.remove();
   8361 			$target.removeClass(this.markerClassName).
   8362 				unbind("focus", this._showDatepicker).
   8363 				unbind("keydown", this._doKeyDown).
   8364 				unbind("keypress", this._doKeyPress).
   8365 				unbind("keyup", this._doKeyUp);
   8366 		} else if (nodeName === "div" || nodeName === "span") {
   8367 			$target.removeClass(this.markerClassName).empty();
   8368 		}
   8369 
   8370 		if ( datepicker_instActive === inst ) {
   8371 			datepicker_instActive = null;
   8372 		}
   8373 	},
   8374 
   8375 	/* Enable the date picker to a jQuery selection.
   8376 	 * @param  target	element - the target input field or division or span
   8377 	 */
   8378 	_enableDatepicker: function(target) {
   8379 		var nodeName, inline,
   8380 			$target = $(target),
   8381 			inst = $.data(target, "datepicker");
   8382 
   8383 		if (!$target.hasClass(this.markerClassName)) {
   8384 			return;
   8385 		}
   8386 
   8387 		nodeName = target.nodeName.toLowerCase();
   8388 		if (nodeName === "input") {
   8389 			target.disabled = false;
   8390 			inst.trigger.filter("button").
   8391 				each(function() { this.disabled = false; }).end().
   8392 				filter("img").css({opacity: "1.0", cursor: ""});
   8393 		} else if (nodeName === "div" || nodeName === "span") {
   8394 			inline = $target.children("." + this._inlineClass);
   8395 			inline.children().removeClass("ui-state-disabled");
   8396 			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
   8397 				prop("disabled", false);
   8398 		}
   8399 		this._disabledInputs = $.map(this._disabledInputs,
   8400 			function(value) { return (value === target ? null : value); }); // delete entry
   8401 	},
   8402 
   8403 	/* Disable the date picker to a jQuery selection.
   8404 	 * @param  target	element - the target input field or division or span
   8405 	 */
   8406 	_disableDatepicker: function(target) {
   8407 		var nodeName, inline,
   8408 			$target = $(target),
   8409 			inst = $.data(target, "datepicker");
   8410 
   8411 		if (!$target.hasClass(this.markerClassName)) {
   8412 			return;
   8413 		}
   8414 
   8415 		nodeName = target.nodeName.toLowerCase();
   8416 		if (nodeName === "input") {
   8417 			target.disabled = true;
   8418 			inst.trigger.filter("button").
   8419 				each(function() { this.disabled = true; }).end().
   8420 				filter("img").css({opacity: "0.5", cursor: "default"});
   8421 		} else if (nodeName === "div" || nodeName === "span") {
   8422 			inline = $target.children("." + this._inlineClass);
   8423 			inline.children().addClass("ui-state-disabled");
   8424 			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
   8425 				prop("disabled", true);
   8426 		}
   8427 		this._disabledInputs = $.map(this._disabledInputs,
   8428 			function(value) { return (value === target ? null : value); }); // delete entry
   8429 		this._disabledInputs[this._disabledInputs.length] = target;
   8430 	},
   8431 
   8432 	/* Is the first field in a jQuery collection disabled as a datepicker?
   8433 	 * @param  target	element - the target input field or division or span
   8434 	 * @return boolean - true if disabled, false if enabled
   8435 	 */
   8436 	_isDisabledDatepicker: function(target) {
   8437 		if (!target) {
   8438 			return false;
   8439 		}
   8440 		for (var i = 0; i < this._disabledInputs.length; i++) {
   8441 			if (this._disabledInputs[i] === target) {
   8442 				return true;
   8443 			}
   8444 		}
   8445 		return false;
   8446 	},
   8447 
   8448 	/* Retrieve the instance data for the target control.
   8449 	 * @param  target  element - the target input field or division or span
   8450 	 * @return  object - the associated instance data
   8451 	 * @throws  error if a jQuery problem getting data
   8452 	 */
   8453 	_getInst: function(target) {
   8454 		try {
   8455 			return $.data(target, "datepicker");
   8456 		}
   8457 		catch (err) {
   8458 			throw "Missing instance data for this datepicker";
   8459 		}
   8460 	},
   8461 
   8462 	/* Update or retrieve the settings for a date picker attached to an input field or division.
   8463 	 * @param  target  element - the target input field or division or span
   8464 	 * @param  name	object - the new settings to update or
   8465 	 *				string - the name of the setting to change or retrieve,
   8466 	 *				when retrieving also "all" for all instance settings or
   8467 	 *				"defaults" for all global defaults
   8468 	 * @param  value   any - the new value for the setting
   8469 	 *				(omit if above is an object or to retrieve a value)
   8470 	 */
   8471 	_optionDatepicker: function(target, name, value) {
   8472 		var settings, date, minDate, maxDate,
   8473 			inst = this._getInst(target);
   8474 
   8475 		if (arguments.length === 2 && typeof name === "string") {
   8476 			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
   8477 				(inst ? (name === "all" ? $.extend({}, inst.settings) :
   8478 				this._get(inst, name)) : null));
   8479 		}
   8480 
   8481 		settings = name || {};
   8482 		if (typeof name === "string") {
   8483 			settings = {};
   8484 			settings[name] = value;
   8485 		}
   8486 
   8487 		if (inst) {
   8488 			if (this._curInst === inst) {
   8489 				this._hideDatepicker();
   8490 			}
   8491 
   8492 			date = this._getDateDatepicker(target, true);
   8493 			minDate = this._getMinMaxDate(inst, "min");
   8494 			maxDate = this._getMinMaxDate(inst, "max");
   8495 			datepicker_extendRemove(inst.settings, settings);
   8496 			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
   8497 			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
   8498 				inst.settings.minDate = this._formatDate(inst, minDate);
   8499 			}
   8500 			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
   8501 				inst.settings.maxDate = this._formatDate(inst, maxDate);
   8502 			}
   8503 			if ( "disabled" in settings ) {
   8504 				if ( settings.disabled ) {
   8505 					this._disableDatepicker(target);
   8506 				} else {
   8507 					this._enableDatepicker(target);
   8508 				}
   8509 			}
   8510 			this._attachments($(target), inst);
   8511 			this._autoSize(inst);
   8512 			this._setDate(inst, date);
   8513 			this._updateAlternate(inst);
   8514 			this._updateDatepicker(inst);
   8515 		}
   8516 	},
   8517 
   8518 	// change method deprecated
   8519 	_changeDatepicker: function(target, name, value) {
   8520 		this._optionDatepicker(target, name, value);
   8521 	},
   8522 
   8523 	/* Redraw the date picker attached to an input field or division.
   8524 	 * @param  target  element - the target input field or division or span
   8525 	 */
   8526 	_refreshDatepicker: function(target) {
   8527 		var inst = this._getInst(target);
   8528 		if (inst) {
   8529 			this._updateDatepicker(inst);
   8530 		}
   8531 	},
   8532 
   8533 	/* Set the dates for a jQuery selection.
   8534 	 * @param  target element - the target input field or division or span
   8535 	 * @param  date	Date - the new date
   8536 	 */
   8537 	_setDateDatepicker: function(target, date) {
   8538 		var inst = this._getInst(target);
   8539 		if (inst) {
   8540 			this._setDate(inst, date);
   8541 			this._updateDatepicker(inst);
   8542 			this._updateAlternate(inst);
   8543 		}
   8544 	},
   8545 
   8546 	/* Get the date(s) for the first entry in a jQuery selection.
   8547 	 * @param  target element - the target input field or division or span
   8548 	 * @param  noDefault boolean - true if no default date is to be used
   8549 	 * @return Date - the current date
   8550 	 */
   8551 	_getDateDatepicker: function(target, noDefault) {
   8552 		var inst = this._getInst(target);
   8553 		if (inst && !inst.inline) {
   8554 			this._setDateFromField(inst, noDefault);
   8555 		}
   8556 		return (inst ? this._getDate(inst) : null);
   8557 	},
   8558 
   8559 	/* Handle keystrokes. */
   8560 	_doKeyDown: function(event) {
   8561 		var onSelect, dateStr, sel,
   8562 			inst = $.datepicker._getInst(event.target),
   8563 			handled = true,
   8564 			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
   8565 
   8566 		inst._keyEvent = true;
   8567 		if ($.datepicker._datepickerShowing) {
   8568 			switch (event.keyCode) {
   8569 				case 9: $.datepicker._hideDatepicker();
   8570 						handled = false;
   8571 						break; // hide on tab out
   8572 				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
   8573 									$.datepicker._currentClass + ")", inst.dpDiv);
   8574 						if (sel[0]) {
   8575 							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
   8576 						}
   8577 
   8578 						onSelect = $.datepicker._get(inst, "onSelect");
   8579 						if (onSelect) {
   8580 							dateStr = $.datepicker._formatDate(inst);
   8581 
   8582 							// trigger custom callback
   8583 							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
   8584 						} else {
   8585 							$.datepicker._hideDatepicker();
   8586 						}
   8587 
   8588 						return false; // don't submit the form
   8589 				case 27: $.datepicker._hideDatepicker();
   8590 						break; // hide on escape
   8591 				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
   8592 							-$.datepicker._get(inst, "stepBigMonths") :
   8593 							-$.datepicker._get(inst, "stepMonths")), "M");
   8594 						break; // previous month/year on page up/+ ctrl
   8595 				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
   8596 							+$.datepicker._get(inst, "stepBigMonths") :
   8597 							+$.datepicker._get(inst, "stepMonths")), "M");
   8598 						break; // next month/year on page down/+ ctrl
   8599 				case 35: if (event.ctrlKey || event.metaKey) {
   8600 							$.datepicker._clearDate(event.target);
   8601 						}
   8602 						handled = event.ctrlKey || event.metaKey;
   8603 						break; // clear on ctrl or command +end
   8604 				case 36: if (event.ctrlKey || event.metaKey) {
   8605 							$.datepicker._gotoToday(event.target);
   8606 						}
   8607 						handled = event.ctrlKey || event.metaKey;
   8608 						break; // current on ctrl or command +home
   8609 				case 37: if (event.ctrlKey || event.metaKey) {
   8610 							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
   8611 						}
   8612 						handled = event.ctrlKey || event.metaKey;
   8613 						// -1 day on ctrl or command +left
   8614 						if (event.originalEvent.altKey) {
   8615 							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
   8616 								-$.datepicker._get(inst, "stepBigMonths") :
   8617 								-$.datepicker._get(inst, "stepMonths")), "M");
   8618 						}
   8619 						// next month/year on alt +left on Mac
   8620 						break;
   8621 				case 38: if (event.ctrlKey || event.metaKey) {
   8622 							$.datepicker._adjustDate(event.target, -7, "D");
   8623 						}
   8624 						handled = event.ctrlKey || event.metaKey;
   8625 						break; // -1 week on ctrl or command +up
   8626 				case 39: if (event.ctrlKey || event.metaKey) {
   8627 							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
   8628 						}
   8629 						handled = event.ctrlKey || event.metaKey;
   8630 						// +1 day on ctrl or command +right
   8631 						if (event.originalEvent.altKey) {
   8632 							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
   8633 								+$.datepicker._get(inst, "stepBigMonths") :
   8634 								+$.datepicker._get(inst, "stepMonths")), "M");
   8635 						}
   8636 						// next month/year on alt +right
   8637 						break;
   8638 				case 40: if (event.ctrlKey || event.metaKey) {
   8639 							$.datepicker._adjustDate(event.target, +7, "D");
   8640 						}
   8641 						handled = event.ctrlKey || event.metaKey;
   8642 						break; // +1 week on ctrl or command +down
   8643 				default: handled = false;
   8644 			}
   8645 		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
   8646 			$.datepicker._showDatepicker(this);
   8647 		} else {
   8648 			handled = false;
   8649 		}
   8650 
   8651 		if (handled) {
   8652 			event.preventDefault();
   8653 			event.stopPropagation();
   8654 		}
   8655 	},
   8656 
   8657 	/* Filter entered characters - based on date format. */
   8658 	_doKeyPress: function(event) {
   8659 		var chars, chr,
   8660 			inst = $.datepicker._getInst(event.target);
   8661 
   8662 		if ($.datepicker._get(inst, "constrainInput")) {
   8663 			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
   8664 			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
   8665 			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
   8666 		}
   8667 	},
   8668 
   8669 	/* Synchronise manual entry and field/alternate field. */
   8670 	_doKeyUp: function(event) {
   8671 		var date,
   8672 			inst = $.datepicker._getInst(event.target);
   8673 
   8674 		if (inst.input.val() !== inst.lastVal) {
   8675 			try {
   8676 				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
   8677 					(inst.input ? inst.input.val() : null),
   8678 					$.datepicker._getFormatConfig(inst));
   8679 
   8680 				if (date) { // only if valid
   8681 					$.datepicker._setDateFromField(inst);
   8682 					$.datepicker._updateAlternate(inst);
   8683 					$.datepicker._updateDatepicker(inst);
   8684 				}
   8685 			}
   8686 			catch (err) {
   8687 			}
   8688 		}
   8689 		return true;
   8690 	},
   8691 
   8692 	/* Pop-up the date picker for a given input field.
   8693 	 * If false returned from beforeShow event handler do not show.
   8694 	 * @param  input  element - the input field attached to the date picker or
   8695 	 *					event - if triggered by focus
   8696 	 */
   8697 	_showDatepicker: function(input) {
   8698 		input = input.target || input;
   8699 		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
   8700 			input = $("input", input.parentNode)[0];
   8701 		}
   8702 
   8703 		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
   8704 			return;
   8705 		}
   8706 
   8707 		var inst, beforeShow, beforeShowSettings, isFixed,
   8708 			offset, showAnim, duration;
   8709 
   8710 		inst = $.datepicker._getInst(input);
   8711 		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
   8712 			$.datepicker._curInst.dpDiv.stop(true, true);
   8713 			if ( inst && $.datepicker._datepickerShowing ) {
   8714 				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
   8715 			}
   8716 		}
   8717 
   8718 		beforeShow = $.datepicker._get(inst, "beforeShow");
   8719 		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
   8720 		if(beforeShowSettings === false){
   8721 			return;
   8722 		}
   8723 		datepicker_extendRemove(inst.settings, beforeShowSettings);
   8724 
   8725 		inst.lastVal = null;
   8726 		$.datepicker._lastInput = input;
   8727 		$.datepicker._setDateFromField(inst);
   8728 
   8729 		if ($.datepicker._inDialog) { // hide cursor
   8730 			input.value = "";
   8731 		}
   8732 		if (!$.datepicker._pos) { // position below input
   8733 			$.datepicker._pos = $.datepicker._findPos(input);
   8734 			$.datepicker._pos[1] += input.offsetHeight; // add the height
   8735 		}
   8736 
   8737 		isFixed = false;
   8738 		$(input).parents().each(function() {
   8739 			isFixed |= $(this).css("position") === "fixed";
   8740 			return !isFixed;
   8741 		});
   8742 
   8743 		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
   8744 		$.datepicker._pos = null;
   8745 		//to avoid flashes on Firefox
   8746 		inst.dpDiv.empty();
   8747 		// determine sizing offscreen
   8748 		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
   8749 		$.datepicker._updateDatepicker(inst);
   8750 		// fix width for dynamic number of date pickers
   8751 		// and adjust position before showing
   8752 		offset = $.datepicker._checkOffset(inst, offset, isFixed);
   8753 		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
   8754 			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
   8755 			left: offset.left + "px", top: offset.top + "px"});
   8756 
   8757 		if (!inst.inline) {
   8758 			showAnim = $.datepicker._get(inst, "showAnim");
   8759 			duration = $.datepicker._get(inst, "duration");
   8760 			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
   8761 			$.datepicker._datepickerShowing = true;
   8762 
   8763 			if ( $.effects && $.effects.effect[ showAnim ] ) {
   8764 				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
   8765 			} else {
   8766 				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
   8767 			}
   8768 
   8769 			if ( $.datepicker._shouldFocusInput( inst ) ) {
   8770 				inst.input.focus();
   8771 			}
   8772 
   8773 			$.datepicker._curInst = inst;
   8774 		}
   8775 	},
   8776 
   8777 	/* Generate the date picker content. */
   8778 	_updateDatepicker: function(inst) {
   8779 		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
   8780 		datepicker_instActive = inst; // for delegate hover events
   8781 		inst.dpDiv.empty().append(this._generateHTML(inst));
   8782 		this._attachHandlers(inst);
   8783 
   8784 		var origyearshtml,
   8785 			numMonths = this._getNumberOfMonths(inst),
   8786 			cols = numMonths[1],
   8787 			width = 17,
   8788 			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
   8789 
   8790 		if ( activeCell.length > 0 ) {
   8791 			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
   8792 		}
   8793 
   8794 		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
   8795 		if (cols > 1) {
   8796 			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
   8797 		}
   8798 		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
   8799 			"Class"]("ui-datepicker-multi");
   8800 		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
   8801 			"Class"]("ui-datepicker-rtl");
   8802 
   8803 		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
   8804 			inst.input.focus();
   8805 		}
   8806 
   8807 		// deffered render of the years select (to avoid flashes on Firefox)
   8808 		if( inst.yearshtml ){
   8809 			origyearshtml = inst.yearshtml;
   8810 			setTimeout(function(){
   8811 				//assure that inst.yearshtml didn't change.
   8812 				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
   8813 					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
   8814 				}
   8815 				origyearshtml = inst.yearshtml = null;
   8816 			}, 0);
   8817 		}
   8818 	},
   8819 
   8820 	// #6694 - don't focus the input if it's already focused
   8821 	// this breaks the change event in IE
   8822 	// Support: IE and jQuery <1.9
   8823 	_shouldFocusInput: function( inst ) {
   8824 		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
   8825 	},
   8826 
   8827 	/* Check positioning to remain on screen. */
   8828 	_checkOffset: function(inst, offset, isFixed) {
   8829 		var dpWidth = inst.dpDiv.outerWidth(),
   8830 			dpHeight = inst.dpDiv.outerHeight(),
   8831 			inputWidth = inst.input ? inst.input.outerWidth() : 0,
   8832 			inputHeight = inst.input ? inst.input.outerHeight() : 0,
   8833 			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
   8834 			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
   8835 
   8836 		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
   8837 		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
   8838 		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
   8839 
   8840 		// now check if datepicker is showing outside window viewport - move to a better place if so.
   8841 		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
   8842 			Math.abs(offset.left + dpWidth - viewWidth) : 0);
   8843 		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
   8844 			Math.abs(dpHeight + inputHeight) : 0);
   8845 
   8846 		return offset;
   8847 	},
   8848 
   8849 	/* Find an object's position on the screen. */
   8850 	_findPos: function(obj) {
   8851 		var position,
   8852 			inst = this._getInst(obj),
   8853 			isRTL = this._get(inst, "isRTL");
   8854 
   8855 		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
   8856 			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
   8857 		}
   8858 
   8859 		position = $(obj).offset();
   8860 		return [position.left, position.top];
   8861 	},
   8862 
   8863 	/* Hide the date picker from view.
   8864 	 * @param  input  element - the input field attached to the date picker
   8865 	 */
   8866 	_hideDatepicker: function(input) {
   8867 		var showAnim, duration, postProcess, onClose,
   8868 			inst = this._curInst;
   8869 
   8870 		if (!inst || (input && inst !== $.data(input, "datepicker"))) {
   8871 			return;
   8872 		}
   8873 
   8874 		if (this._datepickerShowing) {
   8875 			showAnim = this._get(inst, "showAnim");
   8876 			duration = this._get(inst, "duration");
   8877 			postProcess = function() {
   8878 				$.datepicker._tidyDialog(inst);
   8879 			};
   8880 
   8881 			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
   8882 			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
   8883 				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
   8884 			} else {
   8885 				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
   8886 					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
   8887 			}
   8888 
   8889 			if (!showAnim) {
   8890 				postProcess();
   8891 			}
   8892 			this._datepickerShowing = false;
   8893 
   8894 			onClose = this._get(inst, "onClose");
   8895 			if (onClose) {
   8896 				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
   8897 			}
   8898 
   8899 			this._lastInput = null;
   8900 			if (this._inDialog) {
   8901 				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
   8902 				if ($.blockUI) {
   8903 					$.unblockUI();
   8904 					$("body").append(this.dpDiv);
   8905 				}
   8906 			}
   8907 			this._inDialog = false;
   8908 		}
   8909 	},
   8910 
   8911 	/* Tidy up after a dialog display. */
   8912 	_tidyDialog: function(inst) {
   8913 		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
   8914 	},
   8915 
   8916 	/* Close date picker if clicked elsewhere. */
   8917 	_checkExternalClick: function(event) {
   8918 		if (!$.datepicker._curInst) {
   8919 			return;
   8920 		}
   8921 
   8922 		var $target = $(event.target),
   8923 			inst = $.datepicker._getInst($target[0]);
   8924 
   8925 		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
   8926 				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
   8927 				!$target.hasClass($.datepicker.markerClassName) &&
   8928 				!$target.closest("." + $.datepicker._triggerClass).length &&
   8929 				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
   8930 			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
   8931 				$.datepicker._hideDatepicker();
   8932 		}
   8933 	},
   8934 
   8935 	/* Adjust one of the date sub-fields. */
   8936 	_adjustDate: function(id, offset, period) {
   8937 		var target = $(id),
   8938 			inst = this._getInst(target[0]);
   8939 
   8940 		if (this._isDisabledDatepicker(target[0])) {
   8941 			return;
   8942 		}
   8943 		this._adjustInstDate(inst, offset +
   8944 			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
   8945 			period);
   8946 		this._updateDatepicker(inst);
   8947 	},
   8948 
   8949 	/* Action for current link. */
   8950 	_gotoToday: function(id) {
   8951 		var date,
   8952 			target = $(id),
   8953 			inst = this._getInst(target[0]);
   8954 
   8955 		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
   8956 			inst.selectedDay = inst.currentDay;
   8957 			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
   8958 			inst.drawYear = inst.selectedYear = inst.currentYear;
   8959 		} else {
   8960 			date = new Date();
   8961 			inst.selectedDay = date.getDate();
   8962 			inst.drawMonth = inst.selectedMonth = date.getMonth();
   8963 			inst.drawYear = inst.selectedYear = date.getFullYear();
   8964 		}
   8965 		this._notifyChange(inst);
   8966 		this._adjustDate(target);
   8967 	},
   8968 
   8969 	/* Action for selecting a new month/year. */
   8970 	_selectMonthYear: function(id, select, period) {
   8971 		var target = $(id),
   8972 			inst = this._getInst(target[0]);
   8973 
   8974 		inst["selected" + (period === "M" ? "Month" : "Year")] =
   8975 		inst["draw" + (period === "M" ? "Month" : "Year")] =
   8976 			parseInt(select.options[select.selectedIndex].value,10);
   8977 
   8978 		this._notifyChange(inst);
   8979 		this._adjustDate(target);
   8980 	},
   8981 
   8982 	/* Action for selecting a day. */
   8983 	_selectDay: function(id, month, year, td) {
   8984 		var inst,
   8985 			target = $(id);
   8986 
   8987 		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
   8988 			return;
   8989 		}
   8990 
   8991 		inst = this._getInst(target[0]);
   8992 		inst.selectedDay = inst.currentDay = $("a", td).html();
   8993 		inst.selectedMonth = inst.currentMonth = month;
   8994 		inst.selectedYear = inst.currentYear = year;
   8995 		this._selectDate(id, this._formatDate(inst,
   8996 			inst.currentDay, inst.currentMonth, inst.currentYear));
   8997 	},
   8998 
   8999 	/* Erase the input field and hide the date picker. */
   9000 	_clearDate: function(id) {
   9001 		var target = $(id);
   9002 		this._selectDate(target, "");
   9003 	},
   9004 
   9005 	/* Update the input field with the selected date. */
   9006 	_selectDate: function(id, dateStr) {
   9007 		var onSelect,
   9008 			target = $(id),
   9009 			inst = this._getInst(target[0]);
   9010 
   9011 		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
   9012 		if (inst.input) {
   9013 			inst.input.val(dateStr);
   9014 		}
   9015 		this._updateAlternate(inst);
   9016 
   9017 		onSelect = this._get(inst, "onSelect");
   9018 		if (onSelect) {
   9019 			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
   9020 		} else if (inst.input) {
   9021 			inst.input.trigger("change"); // fire the change event
   9022 		}
   9023 
   9024 		if (inst.inline){
   9025 			this._updateDatepicker(inst);
   9026 		} else {
   9027 			this._hideDatepicker();
   9028 			this._lastInput = inst.input[0];
   9029 			if (typeof(inst.input[0]) !== "object") {
   9030 				inst.input.focus(); // restore focus
   9031 			}
   9032 			this._lastInput = null;
   9033 		}
   9034 	},
   9035 
   9036 	/* Update any alternate field to synchronise with the main field. */
   9037 	_updateAlternate: function(inst) {
   9038 		var altFormat, date, dateStr,
   9039 			altField = this._get(inst, "altField");
   9040 
   9041 		if (altField) { // update alternate field too
   9042 			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
   9043 			date = this._getDate(inst);
   9044 			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
   9045 			$(altField).each(function() { $(this).val(dateStr); });
   9046 		}
   9047 	},
   9048 
   9049 	/* Set as beforeShowDay function to prevent selection of weekends.
   9050 	 * @param  date  Date - the date to customise
   9051 	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
   9052 	 */
   9053 	noWeekends: function(date) {
   9054 		var day = date.getDay();
   9055 		return [(day > 0 && day < 6), ""];
   9056 	},
   9057 
   9058 	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
   9059 	 * @param  date  Date - the date to get the week for
   9060 	 * @return  number - the number of the week within the year that contains this date
   9061 	 */
   9062 	iso8601Week: function(date) {
   9063 		var time,
   9064 			checkDate = new Date(date.getTime());
   9065 
   9066 		// Find Thursday of this week starting on Monday
   9067 		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
   9068 
   9069 		time = checkDate.getTime();
   9070 		checkDate.setMonth(0); // Compare with Jan 1
   9071 		checkDate.setDate(1);
   9072 		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
   9073 	},
   9074 
   9075 	/* Parse a string value into a date object.
   9076 	 * See formatDate below for the possible formats.
   9077 	 *
   9078 	 * @param  format string - the expected format of the date
   9079 	 * @param  value string - the date in the above format
   9080 	 * @param  settings Object - attributes include:
   9081 	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
   9082 	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
   9083 	 *					dayNames		string[7] - names of the days from Sunday (optional)
   9084 	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
   9085 	 *					monthNames		string[12] - names of the months (optional)
   9086 	 * @return  Date - the extracted date value or null if value is blank
   9087 	 */
   9088 	parseDate: function (format, value, settings) {
   9089 		if (format == null || value == null) {
   9090 			throw "Invalid arguments";
   9091 		}
   9092 
   9093 		value = (typeof value === "object" ? value.toString() : value + "");
   9094 		if (value === "") {
   9095 			return null;
   9096 		}
   9097 
   9098 		var iFormat, dim, extra,
   9099 			iValue = 0,
   9100 			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
   9101 			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
   9102 				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
   9103 			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
   9104 			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
   9105 			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
   9106 			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
   9107 			year = -1,
   9108 			month = -1,
   9109 			day = -1,
   9110 			doy = -1,
   9111 			literal = false,
   9112 			date,
   9113 			// Check whether a format character is doubled
   9114 			lookAhead = function(match) {
   9115 				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
   9116 				if (matches) {
   9117 					iFormat++;
   9118 				}
   9119 				return matches;
   9120 			},
   9121 			// Extract a number from the string value
   9122 			getNumber = function(match) {
   9123 				var isDoubled = lookAhead(match),
   9124 					size = (match === "@" ? 14 : (match === "!" ? 20 :
   9125 					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
   9126 					minSize = (match === "y" ? size : 1),
   9127 					digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
   9128 					num = value.substring(iValue).match(digits);
   9129 				if (!num) {
   9130 					throw "Missing number at position " + iValue;
   9131 				}
   9132 				iValue += num[0].length;
   9133 				return parseInt(num[0], 10);
   9134 			},
   9135 			// Extract a name from the string value and convert to an index
   9136 			getName = function(match, shortNames, longNames) {
   9137 				var index = -1,
   9138 					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
   9139 						return [ [k, v] ];
   9140 					}).sort(function (a, b) {
   9141 						return -(a[1].length - b[1].length);
   9142 					});
   9143 
   9144 				$.each(names, function (i, pair) {
   9145 					var name = pair[1];
   9146 					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
   9147 						index = pair[0];
   9148 						iValue += name.length;
   9149 						return false;
   9150 					}
   9151 				});
   9152 				if (index !== -1) {
   9153 					return index + 1;
   9154 				} else {
   9155 					throw "Unknown name at position " + iValue;
   9156 				}
   9157 			},
   9158 			// Confirm that a literal character matches the string value
   9159 			checkLiteral = function() {
   9160 				if (value.charAt(iValue) !== format.charAt(iFormat)) {
   9161 					throw "Unexpected literal at position " + iValue;
   9162 				}
   9163 				iValue++;
   9164 			};
   9165 
   9166 		for (iFormat = 0; iFormat < format.length; iFormat++) {
   9167 			if (literal) {
   9168 				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
   9169 					literal = false;
   9170 				} else {
   9171 					checkLiteral();
   9172 				}
   9173 			} else {
   9174 				switch (format.charAt(iFormat)) {
   9175 					case "d":
   9176 						day = getNumber("d");
   9177 						break;
   9178 					case "D":
   9179 						getName("D", dayNamesShort, dayNames);
   9180 						break;
   9181 					case "o":
   9182 						doy = getNumber("o");
   9183 						break;
   9184 					case "m":
   9185 						month = getNumber("m");
   9186 						break;
   9187 					case "M":
   9188 						month = getName("M", monthNamesShort, monthNames);
   9189 						break;
   9190 					case "y":
   9191 						year = getNumber("y");
   9192 						break;
   9193 					case "@":
   9194 						date = new Date(getNumber("@"));
   9195 						year = date.getFullYear();
   9196 						month = date.getMonth() + 1;
   9197 						day = date.getDate();
   9198 						break;
   9199 					case "!":
   9200 						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
   9201 						year = date.getFullYear();
   9202 						month = date.getMonth() + 1;
   9203 						day = date.getDate();
   9204 						break;
   9205 					case "'":
   9206 						if (lookAhead("'")){
   9207 							checkLiteral();
   9208 						} else {
   9209 							literal = true;
   9210 						}
   9211 						break;
   9212 					default:
   9213 						checkLiteral();
   9214 				}
   9215 			}
   9216 		}
   9217 
   9218 		if (iValue < value.length){
   9219 			extra = value.substr(iValue);
   9220 			if (!/^\s+/.test(extra)) {
   9221 				throw "Extra/unparsed characters found in date: " + extra;
   9222 			}
   9223 		}
   9224 
   9225 		if (year === -1) {
   9226 			year = new Date().getFullYear();
   9227 		} else if (year < 100) {
   9228 			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
   9229 				(year <= shortYearCutoff ? 0 : -100);
   9230 		}
   9231 
   9232 		if (doy > -1) {
   9233 			month = 1;
   9234 			day = doy;
   9235 			do {
   9236 				dim = this._getDaysInMonth(year, month - 1);
   9237 				if (day <= dim) {
   9238 					break;
   9239 				}
   9240 				month++;
   9241 				day -= dim;
   9242 			} while (true);
   9243 		}
   9244 
   9245 		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
   9246 		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
   9247 			throw "Invalid date"; // E.g. 31/02/00
   9248 		}
   9249 		return date;
   9250 	},
   9251 
   9252 	/* Standard date formats. */
   9253 	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
   9254 	COOKIE: "D, dd M yy",
   9255 	ISO_8601: "yy-mm-dd",
   9256 	RFC_822: "D, d M y",
   9257 	RFC_850: "DD, dd-M-y",
   9258 	RFC_1036: "D, d M y",
   9259 	RFC_1123: "D, d M yy",
   9260 	RFC_2822: "D, d M yy",
   9261 	RSS: "D, d M y", // RFC 822
   9262 	TICKS: "!",
   9263 	TIMESTAMP: "@",
   9264 	W3C: "yy-mm-dd", // ISO 8601
   9265 
   9266 	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
   9267 		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
   9268 
   9269 	/* Format a date object into a string value.
   9270 	 * The format can be combinations of the following:
   9271 	 * d  - day of month (no leading zero)
   9272 	 * dd - day of month (two digit)
   9273 	 * o  - day of year (no leading zeros)
   9274 	 * oo - day of year (three digit)
   9275 	 * D  - day name short
   9276 	 * DD - day name long
   9277 	 * m  - month of year (no leading zero)
   9278 	 * mm - month of year (two digit)
   9279 	 * M  - month name short
   9280 	 * MM - month name long
   9281 	 * y  - year (two digit)
   9282 	 * yy - year (four digit)
   9283 	 * @ - Unix timestamp (ms since 01/01/1970)
   9284 	 * ! - Windows ticks (100ns since 01/01/0001)
   9285 	 * "..." - literal text
   9286 	 * '' - single quote
   9287 	 *
   9288 	 * @param  format string - the desired format of the date
   9289 	 * @param  date Date - the date value to format
   9290 	 * @param  settings Object - attributes include:
   9291 	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
   9292 	 *					dayNames		string[7] - names of the days from Sunday (optional)
   9293 	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
   9294 	 *					monthNames		string[12] - names of the months (optional)
   9295 	 * @return  string - the date in the above format
   9296 	 */
   9297 	formatDate: function (format, date, settings) {
   9298 		if (!date) {
   9299 			return "";
   9300 		}
   9301 
   9302 		var iFormat,
   9303 			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
   9304 			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
   9305 			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
   9306 			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
   9307 			// Check whether a format character is doubled
   9308 			lookAhead = function(match) {
   9309 				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
   9310 				if (matches) {
   9311 					iFormat++;
   9312 				}
   9313 				return matches;
   9314 			},
   9315 			// Format a number, with leading zero if necessary
   9316 			formatNumber = function(match, value, len) {
   9317 				var num = "" + value;
   9318 				if (lookAhead(match)) {
   9319 					while (num.length < len) {
   9320 						num = "0" + num;
   9321 					}
   9322 				}
   9323 				return num;
   9324 			},
   9325 			// Format a name, short or long as requested
   9326 			formatName = function(match, value, shortNames, longNames) {
   9327 				return (lookAhead(match) ? longNames[value] : shortNames[value]);
   9328 			},
   9329 			output = "",
   9330 			literal = false;
   9331 
   9332 		if (date) {
   9333 			for (iFormat = 0; iFormat < format.length; iFormat++) {
   9334 				if (literal) {
   9335 					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
   9336 						literal = false;
   9337 					} else {
   9338 						output += format.charAt(iFormat);
   9339 					}
   9340 				} else {
   9341 					switch (format.charAt(iFormat)) {
   9342 						case "d":
   9343 							output += formatNumber("d", date.getDate(), 2);
   9344 							break;
   9345 						case "D":
   9346 							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
   9347 							break;
   9348 						case "o":
   9349 							output += formatNumber("o",
   9350 								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
   9351 							break;
   9352 						case "m":
   9353 							output += formatNumber("m", date.getMonth() + 1, 2);
   9354 							break;
   9355 						case "M":
   9356 							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
   9357 							break;
   9358 						case "y":
   9359 							output += (lookAhead("y") ? date.getFullYear() :
   9360 								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
   9361 							break;
   9362 						case "@":
   9363 							output += date.getTime();
   9364 							break;
   9365 						case "!":
   9366 							output += date.getTime() * 10000 + this._ticksTo1970;
   9367 							break;
   9368 						case "'":
   9369 							if (lookAhead("'")) {
   9370 								output += "'";
   9371 							} else {
   9372 								literal = true;
   9373 							}
   9374 							break;
   9375 						default:
   9376 							output += format.charAt(iFormat);
   9377 					}
   9378 				}
   9379 			}
   9380 		}
   9381 		return output;
   9382 	},
   9383 
   9384 	/* Extract all possible characters from the date format. */
   9385 	_possibleChars: function (format) {
   9386 		var iFormat,
   9387 			chars = "",
   9388 			literal = false,
   9389 			// Check whether a format character is doubled
   9390 			lookAhead = function(match) {
   9391 				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
   9392 				if (matches) {
   9393 					iFormat++;
   9394 				}
   9395 				return matches;
   9396 			};
   9397 
   9398 		for (iFormat = 0; iFormat < format.length; iFormat++) {
   9399 			if (literal) {
   9400 				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
   9401 					literal = false;
   9402 				} else {
   9403 					chars += format.charAt(iFormat);
   9404 				}
   9405 			} else {
   9406 				switch (format.charAt(iFormat)) {
   9407 					case "d": case "m": case "y": case "@":
   9408 						chars += "0123456789";
   9409 						break;
   9410 					case "D": case "M":
   9411 						return null; // Accept anything
   9412 					case "'":
   9413 						if (lookAhead("'")) {
   9414 							chars += "'";
   9415 						} else {
   9416 							literal = true;
   9417 						}
   9418 						break;
   9419 					default:
   9420 						chars += format.charAt(iFormat);
   9421 				}
   9422 			}
   9423 		}
   9424 		return chars;
   9425 	},
   9426 
   9427 	/* Get a setting value, defaulting if necessary. */
   9428 	_get: function(inst, name) {
   9429 		return inst.settings[name] !== undefined ?
   9430 			inst.settings[name] : this._defaults[name];
   9431 	},
   9432 
   9433 	/* Parse existing date and initialise date picker. */
   9434 	_setDateFromField: function(inst, noDefault) {
   9435 		if (inst.input.val() === inst.lastVal) {
   9436 			return;
   9437 		}
   9438 
   9439 		var dateFormat = this._get(inst, "dateFormat"),
   9440 			dates = inst.lastVal = inst.input ? inst.input.val() : null,
   9441 			defaultDate = this._getDefaultDate(inst),
   9442 			date = defaultDate,
   9443 			settings = this._getFormatConfig(inst);
   9444 
   9445 		try {
   9446 			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
   9447 		} catch (event) {
   9448 			dates = (noDefault ? "" : dates);
   9449 		}
   9450 		inst.selectedDay = date.getDate();
   9451 		inst.drawMonth = inst.selectedMonth = date.getMonth();
   9452 		inst.drawYear = inst.selectedYear = date.getFullYear();
   9453 		inst.currentDay = (dates ? date.getDate() : 0);
   9454 		inst.currentMonth = (dates ? date.getMonth() : 0);
   9455 		inst.currentYear = (dates ? date.getFullYear() : 0);
   9456 		this._adjustInstDate(inst);
   9457 	},
   9458 
   9459 	/* Retrieve the default date shown on opening. */
   9460 	_getDefaultDate: function(inst) {
   9461 		return this._restrictMinMax(inst,
   9462 			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
   9463 	},
   9464 
   9465 	/* A date may be specified as an exact value or a relative one. */
   9466 	_determineDate: function(inst, date, defaultDate) {
   9467 		var offsetNumeric = function(offset) {
   9468 				var date = new Date();
   9469 				date.setDate(date.getDate() + offset);
   9470 				return date;
   9471 			},
   9472 			offsetString = function(offset) {
   9473 				try {
   9474 					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
   9475 						offset, $.datepicker._getFormatConfig(inst));
   9476 				}
   9477 				catch (e) {
   9478 					// Ignore
   9479 				}
   9480 
   9481 				var date = (offset.toLowerCase().match(/^c/) ?
   9482 					$.datepicker._getDate(inst) : null) || new Date(),
   9483 					year = date.getFullYear(),
   9484 					month = date.getMonth(),
   9485 					day = date.getDate(),
   9486 					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
   9487 					matches = pattern.exec(offset);
   9488 
   9489 				while (matches) {
   9490 					switch (matches[2] || "d") {
   9491 						case "d" : case "D" :
   9492 							day += parseInt(matches[1],10); break;
   9493 						case "w" : case "W" :
   9494 							day += parseInt(matches[1],10) * 7; break;
   9495 						case "m" : case "M" :
   9496 							month += parseInt(matches[1],10);
   9497 							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
   9498 							break;
   9499 						case "y": case "Y" :
   9500 							year += parseInt(matches[1],10);
   9501 							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
   9502 							break;
   9503 					}
   9504 					matches = pattern.exec(offset);
   9505 				}
   9506 				return new Date(year, month, day);
   9507 			},
   9508 			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
   9509 				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
   9510 
   9511 		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
   9512 		if (newDate) {
   9513 			newDate.setHours(0);
   9514 			newDate.setMinutes(0);
   9515 			newDate.setSeconds(0);
   9516 			newDate.setMilliseconds(0);
   9517 		}
   9518 		return this._daylightSavingAdjust(newDate);
   9519 	},
   9520 
   9521 	/* Handle switch to/from daylight saving.
   9522 	 * Hours may be non-zero on daylight saving cut-over:
   9523 	 * > 12 when midnight changeover, but then cannot generate
   9524 	 * midnight datetime, so jump to 1AM, otherwise reset.
   9525 	 * @param  date  (Date) the date to check
   9526 	 * @return  (Date) the corrected date
   9527 	 */
   9528 	_daylightSavingAdjust: function(date) {
   9529 		if (!date) {
   9530 			return null;
   9531 		}
   9532 		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
   9533 		return date;
   9534 	},
   9535 
   9536 	/* Set the date(s) directly. */
   9537 	_setDate: function(inst, date, noChange) {
   9538 		var clear = !date,
   9539 			origMonth = inst.selectedMonth,
   9540 			origYear = inst.selectedYear,
   9541 			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
   9542 
   9543 		inst.selectedDay = inst.currentDay = newDate.getDate();
   9544 		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
   9545 		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
   9546 		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
   9547 			this._notifyChange(inst);
   9548 		}
   9549 		this._adjustInstDate(inst);
   9550 		if (inst.input) {
   9551 			inst.input.val(clear ? "" : this._formatDate(inst));
   9552 		}
   9553 	},
   9554 
   9555 	/* Retrieve the date(s) directly. */
   9556 	_getDate: function(inst) {
   9557 		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
   9558 			this._daylightSavingAdjust(new Date(
   9559 			inst.currentYear, inst.currentMonth, inst.currentDay)));
   9560 			return startDate;
   9561 	},
   9562 
   9563 	/* Attach the onxxx handlers.  These are declared statically so
   9564 	 * they work with static code transformers like Caja.
   9565 	 */
   9566 	_attachHandlers: function(inst) {
   9567 		var stepMonths = this._get(inst, "stepMonths"),
   9568 			id = "#" + inst.id.replace( /\\\\/g, "\\" );
   9569 		inst.dpDiv.find("[data-handler]").map(function () {
   9570 			var handler = {
   9571 				prev: function () {
   9572 					$.datepicker._adjustDate(id, -stepMonths, "M");
   9573 				},
   9574 				next: function () {
   9575 					$.datepicker._adjustDate(id, +stepMonths, "M");
   9576 				},
   9577 				hide: function () {
   9578 					$.datepicker._hideDatepicker();
   9579 				},
   9580 				today: function () {
   9581 					$.datepicker._gotoToday(id);
   9582 				},
   9583 				selectDay: function () {
   9584 					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
   9585 					return false;
   9586 				},
   9587 				selectMonth: function () {
   9588 					$.datepicker._selectMonthYear(id, this, "M");
   9589 					return false;
   9590 				},
   9591 				selectYear: function () {
   9592 					$.datepicker._selectMonthYear(id, this, "Y");
   9593 					return false;
   9594 				}
   9595 			};
   9596 			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
   9597 		});
   9598 	},
   9599 
   9600 	/* Generate the HTML for the current state of the date picker. */
   9601 	_generateHTML: function(inst) {
   9602 		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
   9603 			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
   9604 			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
   9605 			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
   9606 			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
   9607 			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
   9608 			tempDate = new Date(),
   9609 			today = this._daylightSavingAdjust(
   9610 				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
   9611 			isRTL = this._get(inst, "isRTL"),
   9612 			showButtonPanel = this._get(inst, "showButtonPanel"),
   9613 			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
   9614 			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
   9615 			numMonths = this._getNumberOfMonths(inst),
   9616 			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
   9617 			stepMonths = this._get(inst, "stepMonths"),
   9618 			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
   9619 			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
   9620 				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
   9621 			minDate = this._getMinMaxDate(inst, "min"),
   9622 			maxDate = this._getMinMaxDate(inst, "max"),
   9623 			drawMonth = inst.drawMonth - showCurrentAtPos,
   9624 			drawYear = inst.drawYear;
   9625 
   9626 		if (drawMonth < 0) {
   9627 			drawMonth += 12;
   9628 			drawYear--;
   9629 		}
   9630 		if (maxDate) {
   9631 			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
   9632 				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
   9633 			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
   9634 			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
   9635 				drawMonth--;
   9636 				if (drawMonth < 0) {
   9637 					drawMonth = 11;
   9638 					drawYear--;
   9639 				}
   9640 			}
   9641 		}
   9642 		inst.drawMonth = drawMonth;
   9643 		inst.drawYear = drawYear;
   9644 
   9645 		prevText = this._get(inst, "prevText");
   9646 		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
   9647 			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
   9648 			this._getFormatConfig(inst)));
   9649 
   9650 		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
   9651 			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
   9652 			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
   9653 			(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>"));
   9654 
   9655 		nextText = this._get(inst, "nextText");
   9656 		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
   9657 			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
   9658 			this._getFormatConfig(inst)));
   9659 
   9660 		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
   9661 			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
   9662 			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
   9663 			(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>"));
   9664 
   9665 		currentText = this._get(inst, "currentText");
   9666 		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
   9667 		currentText = (!navigationAsDateFormat ? currentText :
   9668 			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
   9669 
   9670 		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'>" +
   9671 			this._get(inst, "closeText") + "</button>" : "");
   9672 
   9673 		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
   9674 			(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'" +
   9675 			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
   9676 
   9677 		firstDay = parseInt(this._get(inst, "firstDay"),10);
   9678 		firstDay = (isNaN(firstDay) ? 0 : firstDay);
   9679 
   9680 		showWeek = this._get(inst, "showWeek");
   9681 		dayNames = this._get(inst, "dayNames");
   9682 		dayNamesMin = this._get(inst, "dayNamesMin");
   9683 		monthNames = this._get(inst, "monthNames");
   9684 		monthNamesShort = this._get(inst, "monthNamesShort");
   9685 		beforeShowDay = this._get(inst, "beforeShowDay");
   9686 		showOtherMonths = this._get(inst, "showOtherMonths");
   9687 		selectOtherMonths = this._get(inst, "selectOtherMonths");
   9688 		defaultDate = this._getDefaultDate(inst);
   9689 		html = "";
   9690 		dow;
   9691 		for (row = 0; row < numMonths[0]; row++) {
   9692 			group = "";
   9693 			this.maxRows = 4;
   9694 			for (col = 0; col < numMonths[1]; col++) {
   9695 				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
   9696 				cornerClass = " ui-corner-all";
   9697 				calender = "";
   9698 				if (isMultiMonth) {
   9699 					calender += "<div class='ui-datepicker-group";
   9700 					if (numMonths[1] > 1) {
   9701 						switch (col) {
   9702 							case 0: calender += " ui-datepicker-group-first";
   9703 								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
   9704 							case numMonths[1]-1: calender += " ui-datepicker-group-last";
   9705 								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
   9706 							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
   9707 						}
   9708 					}
   9709 					calender += "'>";
   9710 				}
   9711 				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
   9712 					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
   9713 					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
   9714 					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
   9715 					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
   9716 					"</div><table class='ui-datepicker-calendar'><thead>" +
   9717 					"<tr>";
   9718 				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
   9719 				for (dow = 0; dow < 7; dow++) { // days of the week
   9720 					day = (dow + firstDay) % 7;
   9721 					thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
   9722 						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
   9723 				}
   9724 				calender += thead + "</tr></thead><tbody>";
   9725 				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
   9726 				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
   9727 					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
   9728 				}
   9729 				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
   9730 				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
   9731 				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
   9732 				this.maxRows = numRows;
   9733 				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
   9734 				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
   9735 					calender += "<tr>";
   9736 					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
   9737 						this._get(inst, "calculateWeek")(printDate) + "</td>");
   9738 					for (dow = 0; dow < 7; dow++) { // create date picker days
   9739 						daySettings = (beforeShowDay ?
   9740 							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
   9741 						otherMonth = (printDate.getMonth() !== drawMonth);
   9742 						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
   9743 							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
   9744 						tbody += "<td class='" +
   9745 							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
   9746 							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
   9747 							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
   9748 							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
   9749 							// or defaultDate is current printedDate and defaultDate is selectedDate
   9750 							" " + this._dayOverClass : "") + // highlight selected day
   9751 							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
   9752 							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
   9753 							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
   9754 							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
   9755 							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
   9756 							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
   9757 							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
   9758 							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
   9759 							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
   9760 							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
   9761 							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
   9762 							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
   9763 						printDate.setDate(printDate.getDate() + 1);
   9764 						printDate = this._daylightSavingAdjust(printDate);
   9765 					}
   9766 					calender += tbody + "</tr>";
   9767 				}
   9768 				drawMonth++;
   9769 				if (drawMonth > 11) {
   9770 					drawMonth = 0;
   9771 					drawYear++;
   9772 				}
   9773 				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
   9774 							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
   9775 				group += calender;
   9776 			}
   9777 			html += group;
   9778 		}
   9779 		html += buttonPanel;
   9780 		inst._keyEvent = false;
   9781 		return html;
   9782 	},
   9783 
   9784 	/* Generate the month and year header. */
   9785 	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
   9786 			secondary, monthNames, monthNamesShort) {
   9787 
   9788 		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
   9789 			changeMonth = this._get(inst, "changeMonth"),
   9790 			changeYear = this._get(inst, "changeYear"),
   9791 			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
   9792 			html = "<div class='ui-datepicker-title'>",
   9793 			monthHtml = "";
   9794 
   9795 		// month selection
   9796 		if (secondary || !changeMonth) {
   9797 			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
   9798 		} else {
   9799 			inMinYear = (minDate && minDate.getFullYear() === drawYear);
   9800 			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
   9801 			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
   9802 			for ( month = 0; month < 12; month++) {
   9803 				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
   9804 					monthHtml += "<option value='" + month + "'" +
   9805 						(month === drawMonth ? " selected='selected'" : "") +
   9806 						">" + monthNamesShort[month] + "</option>";
   9807 				}
   9808 			}
   9809 			monthHtml += "</select>";
   9810 		}
   9811 
   9812 		if (!showMonthAfterYear) {
   9813 			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
   9814 		}
   9815 
   9816 		// year selection
   9817 		if ( !inst.yearshtml ) {
   9818 			inst.yearshtml = "";
   9819 			if (secondary || !changeYear) {
   9820 				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
   9821 			} else {
   9822 				// determine range of years to display
   9823 				years = this._get(inst, "yearRange").split(":");
   9824 				thisYear = new Date().getFullYear();
   9825 				determineYear = function(value) {
   9826 					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
   9827 						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
   9828 						parseInt(value, 10)));
   9829 					return (isNaN(year) ? thisYear : year);
   9830 				};
   9831 				year = determineYear(years[0]);
   9832 				endYear = Math.max(year, determineYear(years[1] || ""));
   9833 				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
   9834 				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
   9835 				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
   9836 				for (; year <= endYear; year++) {
   9837 					inst.yearshtml += "<option value='" + year + "'" +
   9838 						(year === drawYear ? " selected='selected'" : "") +
   9839 						">" + year + "</option>";
   9840 				}
   9841 				inst.yearshtml += "</select>";
   9842 
   9843 				html += inst.yearshtml;
   9844 				inst.yearshtml = null;
   9845 			}
   9846 		}
   9847 
   9848 		html += this._get(inst, "yearSuffix");
   9849 		if (showMonthAfterYear) {
   9850 			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
   9851 		}
   9852 		html += "</div>"; // Close datepicker_header
   9853 		return html;
   9854 	},
   9855 
   9856 	/* Adjust one of the date sub-fields. */
   9857 	_adjustInstDate: function(inst, offset, period) {
   9858 		var year = inst.drawYear + (period === "Y" ? offset : 0),
   9859 			month = inst.drawMonth + (period === "M" ? offset : 0),
   9860 			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
   9861 			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
   9862 
   9863 		inst.selectedDay = date.getDate();
   9864 		inst.drawMonth = inst.selectedMonth = date.getMonth();
   9865 		inst.drawYear = inst.selectedYear = date.getFullYear();
   9866 		if (period === "M" || period === "Y") {
   9867 			this._notifyChange(inst);
   9868 		}
   9869 	},
   9870 
   9871 	/* Ensure a date is within any min/max bounds. */
   9872 	_restrictMinMax: function(inst, date) {
   9873 		var minDate = this._getMinMaxDate(inst, "min"),
   9874 			maxDate = this._getMinMaxDate(inst, "max"),
   9875 			newDate = (minDate && date < minDate ? minDate : date);
   9876 		return (maxDate && newDate > maxDate ? maxDate : newDate);
   9877 	},
   9878 
   9879 	/* Notify change of month/year. */
   9880 	_notifyChange: function(inst) {
   9881 		var onChange = this._get(inst, "onChangeMonthYear");
   9882 		if (onChange) {
   9883 			onChange.apply((inst.input ? inst.input[0] : null),
   9884 				[inst.selectedYear, inst.selectedMonth + 1, inst]);
   9885 		}
   9886 	},
   9887 
   9888 	/* Determine the number of months to show. */
   9889 	_getNumberOfMonths: function(inst) {
   9890 		var numMonths = this._get(inst, "numberOfMonths");
   9891 		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
   9892 	},
   9893 
   9894 	/* Determine the current maximum date - ensure no time components are set. */
   9895 	_getMinMaxDate: function(inst, minMax) {
   9896 		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
   9897 	},
   9898 
   9899 	/* Find the number of days in a given month. */
   9900 	_getDaysInMonth: function(year, month) {
   9901 		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
   9902 	},
   9903 
   9904 	/* Find the day of the week of the first of a month. */
   9905 	_getFirstDayOfMonth: function(year, month) {
   9906 		return new Date(year, month, 1).getDay();
   9907 	},
   9908 
   9909 	/* Determines if we should allow a "next/prev" month display change. */
   9910 	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
   9911 		var numMonths = this._getNumberOfMonths(inst),
   9912 			date = this._daylightSavingAdjust(new Date(curYear,
   9913 			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
   9914 
   9915 		if (offset < 0) {
   9916 			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
   9917 		}
   9918 		return this._isInRange(inst, date);
   9919 	},
   9920 
   9921 	/* Is the given date in the accepted range? */
   9922 	_isInRange: function(inst, date) {
   9923 		var yearSplit, currentYear,
   9924 			minDate = this._getMinMaxDate(inst, "min"),
   9925 			maxDate = this._getMinMaxDate(inst, "max"),
   9926 			minYear = null,
   9927 			maxYear = null,
   9928 			years = this._get(inst, "yearRange");
   9929 			if (years){
   9930 				yearSplit = years.split(":");
   9931 				currentYear = new Date().getFullYear();
   9932 				minYear = parseInt(yearSplit[0], 10);
   9933 				maxYear = parseInt(yearSplit[1], 10);
   9934 				if ( yearSplit[0].match(/[+\-].*/) ) {
   9935 					minYear += currentYear;
   9936 				}
   9937 				if ( yearSplit[1].match(/[+\-].*/) ) {
   9938 					maxYear += currentYear;
   9939 				}
   9940 			}
   9941 
   9942 		return ((!minDate || date.getTime() >= minDate.getTime()) &&
   9943 			(!maxDate || date.getTime() <= maxDate.getTime()) &&
   9944 			(!minYear || date.getFullYear() >= minYear) &&
   9945 			(!maxYear || date.getFullYear() <= maxYear));
   9946 	},
   9947 
   9948 	/* Provide the configuration settings for formatting/parsing. */
   9949 	_getFormatConfig: function(inst) {
   9950 		var shortYearCutoff = this._get(inst, "shortYearCutoff");
   9951 		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
   9952 			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
   9953 		return {shortYearCutoff: shortYearCutoff,
   9954 			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
   9955 			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
   9956 	},
   9957 
   9958 	/* Format the given date for display. */
   9959 	_formatDate: function(inst, day, month, year) {
   9960 		if (!day) {
   9961 			inst.currentDay = inst.selectedDay;
   9962 			inst.currentMonth = inst.selectedMonth;
   9963 			inst.currentYear = inst.selectedYear;
   9964 		}
   9965 		var date = (day ? (typeof day === "object" ? day :
   9966 			this._daylightSavingAdjust(new Date(year, month, day))) :
   9967 			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
   9968 		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
   9969 	}
   9970 });
   9971 
   9972 /*
   9973  * Bind hover events for datepicker elements.
   9974  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
   9975  * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
   9976  */
   9977 function datepicker_bindHover(dpDiv) {
   9978 	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
   9979 	return dpDiv.delegate(selector, "mouseout", function() {
   9980 			$(this).removeClass("ui-state-hover");
   9981 			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
   9982 				$(this).removeClass("ui-datepicker-prev-hover");
   9983 			}
   9984 			if (this.className.indexOf("ui-datepicker-next") !== -1) {
   9985 				$(this).removeClass("ui-datepicker-next-hover");
   9986 			}
   9987 		})
   9988 		.delegate( selector, "mouseover", datepicker_handleMouseover );
   9989 }
   9990 
   9991 function datepicker_handleMouseover() {
   9992 	if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
   9993 		$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
   9994 		$(this).addClass("ui-state-hover");
   9995 		if (this.className.indexOf("ui-datepicker-prev") !== -1) {
   9996 			$(this).addClass("ui-datepicker-prev-hover");
   9997 		}
   9998 		if (this.className.indexOf("ui-datepicker-next") !== -1) {
   9999 			$(this).addClass("ui-datepicker-next-hover");
  10000 		}
  10001 	}
  10002 }
  10003 
  10004 /* jQuery extend now ignores nulls! */
  10005 function datepicker_extendRemove(target, props) {
  10006 	$.extend(target, props);
  10007 	for (var name in props) {
  10008 		if (props[name] == null) {
  10009 			target[name] = props[name];
  10010 		}
  10011 	}
  10012 	return target;
  10013 }
  10014 
  10015 /* Invoke the datepicker functionality.
  10016    @param  options  string - a command, optionally followed by additional parameters or
  10017 					Object - settings for attaching new datepicker functionality
  10018    @return  jQuery object */
  10019 $.fn.datepicker = function(options){
  10020 
  10021 	/* Verify an empty collection wasn't passed - Fixes #6976 */
  10022 	if ( !this.length ) {
  10023 		return this;
  10024 	}
  10025 
  10026 	/* Initialise the date picker. */
  10027 	if (!$.datepicker.initialized) {
  10028 		$(document).mousedown($.datepicker._checkExternalClick);
  10029 		$.datepicker.initialized = true;
  10030 	}
  10031 
  10032 	/* Append datepicker main container to body if not exist. */
  10033 	if ($("#"+$.datepicker._mainDivId).length === 0) {
  10034 		$("body").append($.datepicker.dpDiv);
  10035 	}
  10036 
  10037 	var otherArgs = Array.prototype.slice.call(arguments, 1);
  10038 	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
  10039 		return $.datepicker["_" + options + "Datepicker"].
  10040 			apply($.datepicker, [this[0]].concat(otherArgs));
  10041 	}
  10042 	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
  10043 		return $.datepicker["_" + options + "Datepicker"].
  10044 			apply($.datepicker, [this[0]].concat(otherArgs));
  10045 	}
  10046 	return this.each(function() {
  10047 		typeof options === "string" ?
  10048 			$.datepicker["_" + options + "Datepicker"].
  10049 				apply($.datepicker, [this].concat(otherArgs)) :
  10050 			$.datepicker._attachDatepicker(this, options);
  10051 	});
  10052 };
  10053 
  10054 $.datepicker = new Datepicker(); // singleton instance
  10055 $.datepicker.initialized = false;
  10056 $.datepicker.uuid = new Date().getTime();
  10057 $.datepicker.version = "1.11.4";
  10058 
  10059 var datepicker = $.datepicker;
  10060 
  10061 
  10062 /*!
  10063  * jQuery UI Dialog 1.11.4
  10064  * http://jqueryui.com
  10065  *
  10066  * Copyright jQuery Foundation and other contributors
  10067  * Released under the MIT license.
  10068  * http://jquery.org/license
  10069  *
  10070  * http://api.jqueryui.com/dialog/
  10071  */
  10072 
  10073 
  10074 var dialog = $.widget( "ui.dialog", {
  10075 	version: "1.11.4",
  10076 	options: {
  10077 		appendTo: "body",
  10078 		autoOpen: true,
  10079 		buttons: [],
  10080 		closeOnEscape: true,
  10081 		closeText: "Close",
  10082 		dialogClass: "",
  10083 		draggable: true,
  10084 		hide: null,
  10085 		height: "auto",
  10086 		maxHeight: null,
  10087 		maxWidth: null,
  10088 		minHeight: 150,
  10089 		minWidth: 150,
  10090 		modal: false,
  10091 		position: {
  10092 			my: "center",
  10093 			at: "center",
  10094 			of: window,
  10095 			collision: "fit",
  10096 			// Ensure the titlebar is always visible
  10097 			using: function( pos ) {
  10098 				var topOffset = $( this ).css( pos ).offset().top;
  10099 				if ( topOffset < 0 ) {
  10100 					$( this ).css( "top", pos.top - topOffset );
  10101 				}
  10102 			}
  10103 		},
  10104 		resizable: true,
  10105 		show: null,
  10106 		title: null,
  10107 		width: 300,
  10108 
  10109 		// callbacks
  10110 		beforeClose: null,
  10111 		close: null,
  10112 		drag: null,
  10113 		dragStart: null,
  10114 		dragStop: null,
  10115 		focus: null,
  10116 		open: null,
  10117 		resize: null,
  10118 		resizeStart: null,
  10119 		resizeStop: null
  10120 	},
  10121 
  10122 	sizeRelatedOptions: {
  10123 		buttons: true,
  10124 		height: true,
  10125 		maxHeight: true,
  10126 		maxWidth: true,
  10127 		minHeight: true,
  10128 		minWidth: true,
  10129 		width: true
  10130 	},
  10131 
  10132 	resizableRelatedOptions: {
  10133 		maxHeight: true,
  10134 		maxWidth: true,
  10135 		minHeight: true,
  10136 		minWidth: true
  10137 	},
  10138 
  10139 	_create: function() {
  10140 		this.originalCss = {
  10141 			display: this.element[ 0 ].style.display,
  10142 			width: this.element[ 0 ].style.width,
  10143 			minHeight: this.element[ 0 ].style.minHeight,
  10144 			maxHeight: this.element[ 0 ].style.maxHeight,
  10145 			height: this.element[ 0 ].style.height
  10146 		};
  10147 		this.originalPosition = {
  10148 			parent: this.element.parent(),
  10149 			index: this.element.parent().children().index( this.element )
  10150 		};
  10151 		this.originalTitle = this.element.attr( "title" );
  10152 		this.options.title = this.options.title || this.originalTitle;
  10153 
  10154 		this._createWrapper();
  10155 
  10156 		this.element
  10157 			.show()
  10158 			.removeAttr( "title" )
  10159 			.addClass( "ui-dialog-content ui-widget-content" )
  10160 			.appendTo( this.uiDialog );
  10161 
  10162 		this._createTitlebar();
  10163 		this._createButtonPane();
  10164 
  10165 		if ( this.options.draggable && $.fn.draggable ) {
  10166 			this._makeDraggable();
  10167 		}
  10168 		if ( this.options.resizable && $.fn.resizable ) {
  10169 			this._makeResizable();
  10170 		}
  10171 
  10172 		this._isOpen = false;
  10173 
  10174 		this._trackFocus();
  10175 	},
  10176 
  10177 	_init: function() {
  10178 		if ( this.options.autoOpen ) {
  10179 			this.open();
  10180 		}
  10181 	},
  10182 
  10183 	_appendTo: function() {
  10184 		var element = this.options.appendTo;
  10185 		if ( element && (element.jquery || element.nodeType) ) {
  10186 			return $( element );
  10187 		}
  10188 		return this.document.find( element || "body" ).eq( 0 );
  10189 	},
  10190 
  10191 	_destroy: function() {
  10192 		var next,
  10193 			originalPosition = this.originalPosition;
  10194 
  10195 		this._untrackInstance();
  10196 		this._destroyOverlay();
  10197 
  10198 		this.element
  10199 			.removeUniqueId()
  10200 			.removeClass( "ui-dialog-content ui-widget-content" )
  10201 			.css( this.originalCss )
  10202 			// Without detaching first, the following becomes really slow
  10203 			.detach();
  10204 
  10205 		this.uiDialog.stop( true, true ).remove();
  10206 
  10207 		if ( this.originalTitle ) {
  10208 			this.element.attr( "title", this.originalTitle );
  10209 		}
  10210 
  10211 		next = originalPosition.parent.children().eq( originalPosition.index );
  10212 		// Don't try to place the dialog next to itself (#8613)
  10213 		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
  10214 			next.before( this.element );
  10215 		} else {
  10216 			originalPosition.parent.append( this.element );
  10217 		}
  10218 	},
  10219 
  10220 	widget: function() {
  10221 		return this.uiDialog;
  10222 	},
  10223 
  10224 	disable: $.noop,
  10225 	enable: $.noop,
  10226 
  10227 	close: function( event ) {
  10228 		var activeElement,
  10229 			that = this;
  10230 
  10231 		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
  10232 			return;
  10233 		}
  10234 
  10235 		this._isOpen = false;
  10236 		this._focusedElement = null;
  10237 		this._destroyOverlay();
  10238 		this._untrackInstance();
  10239 
  10240 		if ( !this.opener.filter( ":focusable" ).focus().length ) {
  10241 
  10242 			// support: IE9
  10243 			// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
  10244 			try {
  10245 				activeElement = this.document[ 0 ].activeElement;
  10246 
  10247 				// Support: IE9, IE10
  10248 				// If the <body> is blurred, IE will switch windows, see #4520
  10249 				if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
  10250 
  10251 					// Hiding a focused element doesn't trigger blur in WebKit
  10252 					// so in case we have nothing to focus on, explicitly blur the active element
  10253 					// https://bugs.webkit.org/show_bug.cgi?id=47182
  10254 					$( activeElement ).blur();
  10255 				}
  10256 			} catch ( error ) {}
  10257 		}
  10258 
  10259 		this._hide( this.uiDialog, this.options.hide, function() {
  10260 			that._trigger( "close", event );
  10261 		});
  10262 	},
  10263 
  10264 	isOpen: function() {
  10265 		return this._isOpen;
  10266 	},
  10267 
  10268 	moveToTop: function() {
  10269 		this._moveToTop();
  10270 	},
  10271 
  10272 	_moveToTop: function( event, silent ) {
  10273 		var moved = false,
  10274 			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
  10275 				return +$( this ).css( "z-index" );
  10276 			}).get(),
  10277 			zIndexMax = Math.max.apply( null, zIndices );
  10278 
  10279 		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
  10280 			this.uiDialog.css( "z-index", zIndexMax + 1 );
  10281 			moved = true;
  10282 		}
  10283 
  10284 		if ( moved && !silent ) {
  10285 			this._trigger( "focus", event );
  10286 		}
  10287 		return moved;
  10288 	},
  10289 
  10290 	open: function() {
  10291 		var that = this;
  10292 		if ( this._isOpen ) {
  10293 			if ( this._moveToTop() ) {
  10294 				this._focusTabbable();
  10295 			}
  10296 			return;
  10297 		}
  10298 
  10299 		this._isOpen = true;
  10300 		this.opener = $( this.document[ 0 ].activeElement );
  10301 
  10302 		this._size();
  10303 		this._position();
  10304 		this._createOverlay();
  10305 		this._moveToTop( null, true );
  10306 
  10307 		// Ensure the overlay is moved to the top with the dialog, but only when
  10308 		// opening. The overlay shouldn't move after the dialog is open so that
  10309 		// modeless dialogs opened after the modal dialog stack properly.
  10310 		if ( this.overlay ) {
  10311 			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
  10312 		}
  10313 
  10314 		this._show( this.uiDialog, this.options.show, function() {
  10315 			that._focusTabbable();
  10316 			that._trigger( "focus" );
  10317 		});
  10318 
  10319 		// Track the dialog immediately upon openening in case a focus event
  10320 		// somehow occurs outside of the dialog before an element inside the
  10321 		// dialog is focused (#10152)
  10322 		this._makeFocusTarget();
  10323 
  10324 		this._trigger( "open" );
  10325 	},
  10326 
  10327 	_focusTabbable: function() {
  10328 		// Set focus to the first match:
  10329 		// 1. An element that was focused previously
  10330 		// 2. First element inside the dialog matching [autofocus]
  10331 		// 3. Tabbable element inside the content element
  10332 		// 4. Tabbable element inside the buttonpane
  10333 		// 5. The close button
  10334 		// 6. The dialog itself
  10335 		var hasFocus = this._focusedElement;
  10336 		if ( !hasFocus ) {
  10337 			hasFocus = this.element.find( "[autofocus]" );
  10338 		}
  10339 		if ( !hasFocus.length ) {
  10340 			hasFocus = this.element.find( ":tabbable" );
  10341 		}
  10342 		if ( !hasFocus.length ) {
  10343 			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
  10344 		}
  10345 		if ( !hasFocus.length ) {
  10346 			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
  10347 		}
  10348 		if ( !hasFocus.length ) {
  10349 			hasFocus = this.uiDialog;
  10350 		}
  10351 		hasFocus.eq( 0 ).focus();
  10352 	},
  10353 
  10354 	_keepFocus: function( event ) {
  10355 		function checkFocus() {
  10356 			var activeElement = this.document[0].activeElement,
  10357 				isActive = this.uiDialog[0] === activeElement ||
  10358 					$.contains( this.uiDialog[0], activeElement );
  10359 			if ( !isActive ) {
  10360 				this._focusTabbable();
  10361 			}
  10362 		}
  10363 		event.preventDefault();
  10364 		checkFocus.call( this );
  10365 		// support: IE
  10366 		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
  10367 		// so we check again later
  10368 		this._delay( checkFocus );
  10369 	},
  10370 
  10371 	_createWrapper: function() {
  10372 		this.uiDialog = $("<div>")
  10373 			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
  10374 				this.options.dialogClass )
  10375 			.hide()
  10376 			.attr({
  10377 				// Setting tabIndex makes the div focusable
  10378 				tabIndex: -1,
  10379 				role: "dialog"
  10380 			})
  10381 			.appendTo( this._appendTo() );
  10382 
  10383 		this._on( this.uiDialog, {
  10384 			keydown: function( event ) {
  10385 				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
  10386 						event.keyCode === $.ui.keyCode.ESCAPE ) {
  10387 					event.preventDefault();
  10388 					this.close( event );
  10389 					return;
  10390 				}
  10391 
  10392 				// prevent tabbing out of dialogs
  10393 				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
  10394 					return;
  10395 				}
  10396 				var tabbables = this.uiDialog.find( ":tabbable" ),
  10397 					first = tabbables.filter( ":first" ),
  10398 					last = tabbables.filter( ":last" );
  10399 
  10400 				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
  10401 					this._delay(function() {
  10402 						first.focus();
  10403 					});
  10404 					event.preventDefault();
  10405 				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
  10406 					this._delay(function() {
  10407 						last.focus();
  10408 					});
  10409 					event.preventDefault();
  10410 				}
  10411 			},
  10412 			mousedown: function( event ) {
  10413 				if ( this._moveToTop( event ) ) {
  10414 					this._focusTabbable();
  10415 				}
  10416 			}
  10417 		});
  10418 
  10419 		// We assume that any existing aria-describedby attribute means
  10420 		// that the dialog content is marked up properly
  10421 		// otherwise we brute force the content as the description
  10422 		if ( !this.element.find( "[aria-describedby]" ).length ) {
  10423 			this.uiDialog.attr({
  10424 				"aria-describedby": this.element.uniqueId().attr( "id" )
  10425 			});
  10426 		}
  10427 	},
  10428 
  10429 	_createTitlebar: function() {
  10430 		var uiDialogTitle;
  10431 
  10432 		this.uiDialogTitlebar = $( "<div>" )
  10433 			.addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
  10434 			.prependTo( this.uiDialog );
  10435 		this._on( this.uiDialogTitlebar, {
  10436 			mousedown: function( event ) {
  10437 				// Don't prevent click on close button (#8838)
  10438 				// Focusing a dialog that is partially scrolled out of view
  10439 				// causes the browser to scroll it into view, preventing the click event
  10440 				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
  10441 					// Dialog isn't getting focus when dragging (#8063)
  10442 					this.uiDialog.focus();
  10443 				}
  10444 			}
  10445 		});
  10446 
  10447 		// support: IE
  10448 		// Use type="button" to prevent enter keypresses in textboxes from closing the
  10449 		// dialog in IE (#9312)
  10450 		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
  10451 			.button({
  10452 				label: this.options.closeText,
  10453 				icons: {
  10454 					primary: "ui-icon-closethick"
  10455 				},
  10456 				text: false
  10457 			})
  10458 			.addClass( "ui-dialog-titlebar-close" )
  10459 			.appendTo( this.uiDialogTitlebar );
  10460 		this._on( this.uiDialogTitlebarClose, {
  10461 			click: function( event ) {
  10462 				event.preventDefault();
  10463 				this.close( event );
  10464 			}
  10465 		});
  10466 
  10467 		uiDialogTitle = $( "<span>" )
  10468 			.uniqueId()
  10469 			.addClass( "ui-dialog-title" )
  10470 			.prependTo( this.uiDialogTitlebar );
  10471 		this._title( uiDialogTitle );
  10472 
  10473 		this.uiDialog.attr({
  10474 			"aria-labelledby": uiDialogTitle.attr( "id" )
  10475 		});
  10476 	},
  10477 
  10478 	_title: function( title ) {
  10479 		if ( !this.options.title ) {
  10480 			title.html( "&#160;" );
  10481 		}
  10482 		title.text( this.options.title );
  10483 	},
  10484 
  10485 	_createButtonPane: function() {
  10486 		this.uiDialogButtonPane = $( "<div>" )
  10487 			.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
  10488 
  10489 		this.uiButtonSet = $( "<div>" )
  10490 			.addClass( "ui-dialog-buttonset" )
  10491 			.appendTo( this.uiDialogButtonPane );
  10492 
  10493 		this._createButtons();
  10494 	},
  10495 
  10496 	_createButtons: function() {
  10497 		var that = this,
  10498 			buttons = this.options.buttons;
  10499 
  10500 		// if we already have a button pane, remove it
  10501 		this.uiDialogButtonPane.remove();
  10502 		this.uiButtonSet.empty();
  10503 
  10504 		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
  10505 			this.uiDialog.removeClass( "ui-dialog-buttons" );
  10506 			return;
  10507 		}
  10508 
  10509 		$.each( buttons, function( name, props ) {
  10510 			var click, buttonOptions;
  10511 			props = $.isFunction( props ) ?
  10512 				{ click: props, text: name } :
  10513 				props;
  10514 			// Default to a non-submitting button
  10515 			props = $.extend( { type: "button" }, props );
  10516 			// Change the context for the click callback to be the main element
  10517 			click = props.click;
  10518 			props.click = function() {
  10519 				click.apply( that.element[ 0 ], arguments );
  10520 			};
  10521 			buttonOptions = {
  10522 				icons: props.icons,
  10523 				text: props.showText
  10524 			};
  10525 			delete props.icons;
  10526 			delete props.showText;
  10527 			$( "<button></button>", props )
  10528 				.button( buttonOptions )
  10529 				.appendTo( that.uiButtonSet );
  10530 		});
  10531 		this.uiDialog.addClass( "ui-dialog-buttons" );
  10532 		this.uiDialogButtonPane.appendTo( this.uiDialog );
  10533 	},
  10534 
  10535 	_makeDraggable: function() {
  10536 		var that = this,
  10537 			options = this.options;
  10538 
  10539 		function filteredUi( ui ) {
  10540 			return {
  10541 				position: ui.position,
  10542 				offset: ui.offset
  10543 			};
  10544 		}
  10545 
  10546 		this.uiDialog.draggable({
  10547 			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
  10548 			handle: ".ui-dialog-titlebar",
  10549 			containment: "document",
  10550 			start: function( event, ui ) {
  10551 				$( this ).addClass( "ui-dialog-dragging" );
  10552 				that._blockFrames();
  10553 				that._trigger( "dragStart", event, filteredUi( ui ) );
  10554 			},
  10555 			drag: function( event, ui ) {
  10556 				that._trigger( "drag", event, filteredUi( ui ) );
  10557 			},
  10558 			stop: function( event, ui ) {
  10559 				var left = ui.offset.left - that.document.scrollLeft(),
  10560 					top = ui.offset.top - that.document.scrollTop();
  10561 
  10562 				options.position = {
  10563 					my: "left top",
  10564 					at: "left" + (left >= 0 ? "+" : "") + left + " " +
  10565 						"top" + (top >= 0 ? "+" : "") + top,
  10566 					of: that.window
  10567 				};
  10568 				$( this ).removeClass( "ui-dialog-dragging" );
  10569 				that._unblockFrames();
  10570 				that._trigger( "dragStop", event, filteredUi( ui ) );
  10571 			}
  10572 		});
  10573 	},
  10574 
  10575 	_makeResizable: function() {
  10576 		var that = this,
  10577 			options = this.options,
  10578 			handles = options.resizable,
  10579 			// .ui-resizable has position: relative defined in the stylesheet
  10580 			// but dialogs have to use absolute or fixed positioning
  10581 			position = this.uiDialog.css("position"),
  10582 			resizeHandles = typeof handles === "string" ?
  10583 				handles	:
  10584 				"n,e,s,w,se,sw,ne,nw";
  10585 
  10586 		function filteredUi( ui ) {
  10587 			return {
  10588 				originalPosition: ui.originalPosition,
  10589 				originalSize: ui.originalSize,
  10590 				position: ui.position,
  10591 				size: ui.size
  10592 			};
  10593 		}
  10594 
  10595 		this.uiDialog.resizable({
  10596 			cancel: ".ui-dialog-content",
  10597 			containment: "document",
  10598 			alsoResize: this.element,
  10599 			maxWidth: options.maxWidth,
  10600 			maxHeight: options.maxHeight,
  10601 			minWidth: options.minWidth,
  10602 			minHeight: this._minHeight(),
  10603 			handles: resizeHandles,
  10604 			start: function( event, ui ) {
  10605 				$( this ).addClass( "ui-dialog-resizing" );
  10606 				that._blockFrames();
  10607 				that._trigger( "resizeStart", event, filteredUi( ui ) );
  10608 			},
  10609 			resize: function( event, ui ) {
  10610 				that._trigger( "resize", event, filteredUi( ui ) );
  10611 			},
  10612 			stop: function( event, ui ) {
  10613 				var offset = that.uiDialog.offset(),
  10614 					left = offset.left - that.document.scrollLeft(),
  10615 					top = offset.top - that.document.scrollTop();
  10616 
  10617 				options.height = that.uiDialog.height();
  10618 				options.width = that.uiDialog.width();
  10619 				options.position = {
  10620 					my: "left top",
  10621 					at: "left" + (left >= 0 ? "+" : "") + left + " " +
  10622 						"top" + (top >= 0 ? "+" : "") + top,
  10623 					of: that.window
  10624 				};
  10625 				$( this ).removeClass( "ui-dialog-resizing" );
  10626 				that._unblockFrames();
  10627 				that._trigger( "resizeStop", event, filteredUi( ui ) );
  10628 			}
  10629 		})
  10630 		.css( "position", position );
  10631 	},
  10632 
  10633 	_trackFocus: function() {
  10634 		this._on( this.widget(), {
  10635 			focusin: function( event ) {
  10636 				this._makeFocusTarget();
  10637 				this._focusedElement = $( event.target );
  10638 			}
  10639 		});
  10640 	},
  10641 
  10642 	_makeFocusTarget: function() {
  10643 		this._untrackInstance();
  10644 		this._trackingInstances().unshift( this );
  10645 	},
  10646 
  10647 	_untrackInstance: function() {
  10648 		var instances = this._trackingInstances(),
  10649 			exists = $.inArray( this, instances );
  10650 		if ( exists !== -1 ) {
  10651 			instances.splice( exists, 1 );
  10652 		}
  10653 	},
  10654 
  10655 	_trackingInstances: function() {
  10656 		var instances = this.document.data( "ui-dialog-instances" );
  10657 		if ( !instances ) {
  10658 			instances = [];
  10659 			this.document.data( "ui-dialog-instances", instances );
  10660 		}
  10661 		return instances;
  10662 	},
  10663 
  10664 	_minHeight: function() {
  10665 		var options = this.options;
  10666 
  10667 		return options.height === "auto" ?
  10668 			options.minHeight :
  10669 			Math.min( options.minHeight, options.height );
  10670 	},
  10671 
  10672 	_position: function() {
  10673 		// Need to show the dialog to get the actual offset in the position plugin
  10674 		var isVisible = this.uiDialog.is( ":visible" );
  10675 		if ( !isVisible ) {
  10676 			this.uiDialog.show();
  10677 		}
  10678 		this.uiDialog.position( this.options.position );
  10679 		if ( !isVisible ) {
  10680 			this.uiDialog.hide();
  10681 		}
  10682 	},
  10683 
  10684 	_setOptions: function( options ) {
  10685 		var that = this,
  10686 			resize = false,
  10687 			resizableOptions = {};
  10688 
  10689 		$.each( options, function( key, value ) {
  10690 			that._setOption( key, value );
  10691 
  10692 			if ( key in that.sizeRelatedOptions ) {
  10693 				resize = true;
  10694 			}
  10695 			if ( key in that.resizableRelatedOptions ) {
  10696 				resizableOptions[ key ] = value;
  10697 			}
  10698 		});
  10699 
  10700 		if ( resize ) {
  10701 			this._size();
  10702 			this._position();
  10703 		}
  10704 		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
  10705 			this.uiDialog.resizable( "option", resizableOptions );
  10706 		}
  10707 	},
  10708 
  10709 	_setOption: function( key, value ) {
  10710 		var isDraggable, isResizable,
  10711 			uiDialog = this.uiDialog;
  10712 
  10713 		if ( key === "dialogClass" ) {
  10714 			uiDialog
  10715 				.removeClass( this.options.dialogClass )
  10716 				.addClass( value );
  10717 		}
  10718 
  10719 		if ( key === "disabled" ) {
  10720 			return;
  10721 		}
  10722 
  10723 		this._super( key, value );
  10724 
  10725 		if ( key === "appendTo" ) {
  10726 			this.uiDialog.appendTo( this._appendTo() );
  10727 		}
  10728 
  10729 		if ( key === "buttons" ) {
  10730 			this._createButtons();
  10731 		}
  10732 
  10733 		if ( key === "closeText" ) {
  10734 			this.uiDialogTitlebarClose.button({
  10735 				// Ensure that we always pass a string
  10736 				label: "" + value
  10737 			});
  10738 		}
  10739 
  10740 		if ( key === "draggable" ) {
  10741 			isDraggable = uiDialog.is( ":data(ui-draggable)" );
  10742 			if ( isDraggable && !value ) {
  10743 				uiDialog.draggable( "destroy" );
  10744 			}
  10745 
  10746 			if ( !isDraggable && value ) {
  10747 				this._makeDraggable();
  10748 			}
  10749 		}
  10750 
  10751 		if ( key === "position" ) {
  10752 			this._position();
  10753 		}
  10754 
  10755 		if ( key === "resizable" ) {
  10756 			// currently resizable, becoming non-resizable
  10757 			isResizable = uiDialog.is( ":data(ui-resizable)" );
  10758 			if ( isResizable && !value ) {
  10759 				uiDialog.resizable( "destroy" );
  10760 			}
  10761 
  10762 			// currently resizable, changing handles
  10763 			if ( isResizable && typeof value === "string" ) {
  10764 				uiDialog.resizable( "option", "handles", value );
  10765 			}
  10766 
  10767 			// currently non-resizable, becoming resizable
  10768 			if ( !isResizable && value !== false ) {
  10769 				this._makeResizable();
  10770 			}
  10771 		}
  10772 
  10773 		if ( key === "title" ) {
  10774 			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
  10775 		}
  10776 	},
  10777 
  10778 	_size: function() {
  10779 		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
  10780 		// divs will both have width and height set, so we need to reset them
  10781 		var nonContentHeight, minContentHeight, maxContentHeight,
  10782 			options = this.options;
  10783 
  10784 		// Reset content sizing
  10785 		this.element.show().css({
  10786 			width: "auto",
  10787 			minHeight: 0,
  10788 			maxHeight: "none",
  10789 			height: 0
  10790 		});
  10791 
  10792 		if ( options.minWidth > options.width ) {
  10793 			options.width = options.minWidth;
  10794 		}
  10795 
  10796 		// reset wrapper sizing
  10797 		// determine the height of all the non-content elements
  10798 		nonContentHeight = this.uiDialog.css({
  10799 				height: "auto",
  10800 				width: options.width
  10801 			})
  10802 			.outerHeight();
  10803 		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
  10804 		maxContentHeight = typeof options.maxHeight === "number" ?
  10805 			Math.max( 0, options.maxHeight - nonContentHeight ) :
  10806 			"none";
  10807 
  10808 		if ( options.height === "auto" ) {
  10809 			this.element.css({
  10810 				minHeight: minContentHeight,
  10811 				maxHeight: maxContentHeight,
  10812 				height: "auto"
  10813 			});
  10814 		} else {
  10815 			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
  10816 		}
  10817 
  10818 		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
  10819 			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
  10820 		}
  10821 	},
  10822 
  10823 	_blockFrames: function() {
  10824 		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
  10825 			var iframe = $( this );
  10826 
  10827 			return $( "<div>" )
  10828 				.css({
  10829 					position: "absolute",
  10830 					width: iframe.outerWidth(),
  10831 					height: iframe.outerHeight()
  10832 				})
  10833 				.appendTo( iframe.parent() )
  10834 				.offset( iframe.offset() )[0];
  10835 		});
  10836 	},
  10837 
  10838 	_unblockFrames: function() {
  10839 		if ( this.iframeBlocks ) {
  10840 			this.iframeBlocks.remove();
  10841 			delete this.iframeBlocks;
  10842 		}
  10843 	},
  10844 
  10845 	_allowInteraction: function( event ) {
  10846 		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
  10847 			return true;
  10848 		}
  10849 
  10850 		// TODO: Remove hack when datepicker implements
  10851 		// the .ui-front logic (#8989)
  10852 		return !!$( event.target ).closest( ".ui-datepicker" ).length;
  10853 	},
  10854 
  10855 	_createOverlay: function() {
  10856 		if ( !this.options.modal ) {
  10857 			return;
  10858 		}
  10859 
  10860 		// We use a delay in case the overlay is created from an
  10861 		// event that we're going to be cancelling (#2804)
  10862 		var isOpening = true;
  10863 		this._delay(function() {
  10864 			isOpening = false;
  10865 		});
  10866 
  10867 		if ( !this.document.data( "ui-dialog-overlays" ) ) {
  10868 
  10869 			// Prevent use of anchors and inputs
  10870 			// Using _on() for an event handler shared across many instances is
  10871 			// safe because the dialogs stack and must be closed in reverse order
  10872 			this._on( this.document, {
  10873 				focusin: function( event ) {
  10874 					if ( isOpening ) {
  10875 						return;
  10876 					}
  10877 
  10878 					if ( !this._allowInteraction( event ) ) {
  10879 						event.preventDefault();
  10880 						this._trackingInstances()[ 0 ]._focusTabbable();
  10881 					}
  10882 				}
  10883 			});
  10884 		}
  10885 
  10886 		this.overlay = $( "<div>" )
  10887 			.addClass( "ui-widget-overlay ui-front" )
  10888 			.appendTo( this._appendTo() );
  10889 		this._on( this.overlay, {
  10890 			mousedown: "_keepFocus"
  10891 		});
  10892 		this.document.data( "ui-dialog-overlays",
  10893 			(this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
  10894 	},
  10895 
  10896 	_destroyOverlay: function() {
  10897 		if ( !this.options.modal ) {
  10898 			return;
  10899 		}
  10900 
  10901 		if ( this.overlay ) {
  10902 			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
  10903 
  10904 			if ( !overlays ) {
  10905 				this.document
  10906 					.unbind( "focusin" )
  10907 					.removeData( "ui-dialog-overlays" );
  10908 			} else {
  10909 				this.document.data( "ui-dialog-overlays", overlays );
  10910 			}
  10911 
  10912 			this.overlay.remove();
  10913 			this.overlay = null;
  10914 		}
  10915 	}
  10916 });
  10917 
  10918 
  10919 /*!
  10920  * jQuery UI Progressbar 1.11.4
  10921  * http://jqueryui.com
  10922  *
  10923  * Copyright jQuery Foundation and other contributors
  10924  * Released under the MIT license.
  10925  * http://jquery.org/license
  10926  *
  10927  * http://api.jqueryui.com/progressbar/
  10928  */
  10929 
  10930 
  10931 var progressbar = $.widget( "ui.progressbar", {
  10932 	version: "1.11.4",
  10933 	options: {
  10934 		max: 100,
  10935 		value: 0,
  10936 
  10937 		change: null,
  10938 		complete: null
  10939 	},
  10940 
  10941 	min: 0,
  10942 
  10943 	_create: function() {
  10944 		// Constrain initial value
  10945 		this.oldValue = this.options.value = this._constrainedValue();
  10946 
  10947 		this.element
  10948 			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
  10949 			.attr({
  10950 				// Only set static values, aria-valuenow and aria-valuemax are
  10951 				// set inside _refreshValue()
  10952 				role: "progressbar",
  10953 				"aria-valuemin": this.min
  10954 			});
  10955 
  10956 		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
  10957 			.appendTo( this.element );
  10958 
  10959 		this._refreshValue();
  10960 	},
  10961 
  10962 	_destroy: function() {
  10963 		this.element
  10964 			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
  10965 			.removeAttr( "role" )
  10966 			.removeAttr( "aria-valuemin" )
  10967 			.removeAttr( "aria-valuemax" )
  10968 			.removeAttr( "aria-valuenow" );
  10969 
  10970 		this.valueDiv.remove();
  10971 	},
  10972 
  10973 	value: function( newValue ) {
  10974 		if ( newValue === undefined ) {
  10975 			return this.options.value;
  10976 		}
  10977 
  10978 		this.options.value = this._constrainedValue( newValue );
  10979 		this._refreshValue();
  10980 	},
  10981 
  10982 	_constrainedValue: function( newValue ) {
  10983 		if ( newValue === undefined ) {
  10984 			newValue = this.options.value;
  10985 		}
  10986 
  10987 		this.indeterminate = newValue === false;
  10988 
  10989 		// sanitize value
  10990 		if ( typeof newValue !== "number" ) {
  10991 			newValue = 0;
  10992 		}
  10993 
  10994 		return this.indeterminate ? false :
  10995 			Math.min( this.options.max, Math.max( this.min, newValue ) );
  10996 	},
  10997 
  10998 	_setOptions: function( options ) {
  10999 		// Ensure "value" option is set after other values (like max)
  11000 		var value = options.value;
  11001 		delete options.value;
  11002 
  11003 		this._super( options );
  11004 
  11005 		this.options.value = this._constrainedValue( value );
  11006 		this._refreshValue();
  11007 	},
  11008 
  11009 	_setOption: function( key, value ) {
  11010 		if ( key === "max" ) {
  11011 			// Don't allow a max less than min
  11012 			value = Math.max( this.min, value );
  11013 		}
  11014 		if ( key === "disabled" ) {
  11015 			this.element
  11016 				.toggleClass( "ui-state-disabled", !!value )
  11017 				.attr( "aria-disabled", value );
  11018 		}
  11019 		this._super( key, value );
  11020 	},
  11021 
  11022 	_percentage: function() {
  11023 		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
  11024 	},
  11025 
  11026 	_refreshValue: function() {
  11027 		var value = this.options.value,
  11028 			percentage = this._percentage();
  11029 
  11030 		this.valueDiv
  11031 			.toggle( this.indeterminate || value > this.min )
  11032 			.toggleClass( "ui-corner-right", value === this.options.max )
  11033 			.width( percentage.toFixed(0) + "%" );
  11034 
  11035 		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
  11036 
  11037 		if ( this.indeterminate ) {
  11038 			this.element.removeAttr( "aria-valuenow" );
  11039 			if ( !this.overlayDiv ) {
  11040 				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
  11041 			}
  11042 		} else {
  11043 			this.element.attr({
  11044 				"aria-valuemax": this.options.max,
  11045 				"aria-valuenow": value
  11046 			});
  11047 			if ( this.overlayDiv ) {
  11048 				this.overlayDiv.remove();
  11049 				this.overlayDiv = null;
  11050 			}
  11051 		}
  11052 
  11053 		if ( this.oldValue !== value ) {
  11054 			this.oldValue = value;
  11055 			this._trigger( "change" );
  11056 		}
  11057 		if ( value === this.options.max ) {
  11058 			this._trigger( "complete" );
  11059 		}
  11060 	}
  11061 });
  11062 
  11063 
  11064 /*!
  11065  * jQuery UI Selectmenu 1.11.4
  11066  * http://jqueryui.com
  11067  *
  11068  * Copyright jQuery Foundation and other contributors
  11069  * Released under the MIT license.
  11070  * http://jquery.org/license
  11071  *
  11072  * http://api.jqueryui.com/selectmenu
  11073  */
  11074 
  11075 
  11076 var selectmenu = $.widget( "ui.selectmenu", {
  11077 	version: "1.11.4",
  11078 	defaultElement: "<select>",
  11079 	options: {
  11080 		appendTo: null,
  11081 		disabled: null,
  11082 		icons: {
  11083 			button: "ui-icon-triangle-1-s"
  11084 		},
  11085 		position: {
  11086 			my: "left top",
  11087 			at: "left bottom",
  11088 			collision: "none"
  11089 		},
  11090 		width: null,
  11091 
  11092 		// callbacks
  11093 		change: null,
  11094 		close: null,
  11095 		focus: null,
  11096 		open: null,
  11097 		select: null
  11098 	},
  11099 
  11100 	_create: function() {
  11101 		var selectmenuId = this.element.uniqueId().attr( "id" );
  11102 		this.ids = {
  11103 			element: selectmenuId,
  11104 			button: selectmenuId + "-button",
  11105 			menu: selectmenuId + "-menu"
  11106 		};
  11107 
  11108 		this._drawButton();
  11109 		this._drawMenu();
  11110 
  11111 		if ( this.options.disabled ) {
  11112 			this.disable();
  11113 		}
  11114 	},
  11115 
  11116 	_drawButton: function() {
  11117 		var that = this;
  11118 
  11119 		// Associate existing label with the new button
  11120 		this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
  11121 		this._on( this.label, {
  11122 			click: function( event ) {
  11123 				this.button.focus();
  11124 				event.preventDefault();
  11125 			}
  11126 		});
  11127 
  11128 		// Hide original select element
  11129 		this.element.hide();
  11130 
  11131 		// Create button
  11132 		this.button = $( "<span>", {
  11133 			"class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
  11134 			tabindex: this.options.disabled ? -1 : 0,
  11135 			id: this.ids.button,
  11136 			role: "combobox",
  11137 			"aria-expanded": "false",
  11138 			"aria-autocomplete": "list",
  11139 			"aria-owns": this.ids.menu,
  11140 			"aria-haspopup": "true"
  11141 		})
  11142 			.insertAfter( this.element );
  11143 
  11144 		$( "<span>", {
  11145 			"class": "ui-icon " + this.options.icons.button
  11146 		})
  11147 			.prependTo( this.button );
  11148 
  11149 		this.buttonText = $( "<span>", {
  11150 			"class": "ui-selectmenu-text"
  11151 		})
  11152 			.appendTo( this.button );
  11153 
  11154 		this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
  11155 		this._resizeButton();
  11156 
  11157 		this._on( this.button, this._buttonEvents );
  11158 		this.button.one( "focusin", function() {
  11159 
  11160 			// Delay rendering the menu items until the button receives focus.
  11161 			// The menu may have already been rendered via a programmatic open.
  11162 			if ( !that.menuItems ) {
  11163 				that._refreshMenu();
  11164 			}
  11165 		});
  11166 		this._hoverable( this.button );
  11167 		this._focusable( this.button );
  11168 	},
  11169 
  11170 	_drawMenu: function() {
  11171 		var that = this;
  11172 
  11173 		// Create menu
  11174 		this.menu = $( "<ul>", {
  11175 			"aria-hidden": "true",
  11176 			"aria-labelledby": this.ids.button,
  11177 			id: this.ids.menu
  11178 		});
  11179 
  11180 		// Wrap menu
  11181 		this.menuWrap = $( "<div>", {
  11182 			"class": "ui-selectmenu-menu ui-front"
  11183 		})
  11184 			.append( this.menu )
  11185 			.appendTo( this._appendTo() );
  11186 
  11187 		// Initialize menu widget
  11188 		this.menuInstance = this.menu
  11189 			.menu({
  11190 				role: "listbox",
  11191 				select: function( event, ui ) {
  11192 					event.preventDefault();
  11193 
  11194 					// support: IE8
  11195 					// If the item was selected via a click, the text selection
  11196 					// will be destroyed in IE
  11197 					that._setSelection();
  11198 
  11199 					that._select( ui.item.data( "ui-selectmenu-item" ), event );
  11200 				},
  11201 				focus: function( event, ui ) {
  11202 					var item = ui.item.data( "ui-selectmenu-item" );
  11203 
  11204 					// Prevent inital focus from firing and check if its a newly focused item
  11205 					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
  11206 						that._trigger( "focus", event, { item: item } );
  11207 						if ( !that.isOpen ) {
  11208 							that._select( item, event );
  11209 						}
  11210 					}
  11211 					that.focusIndex = item.index;
  11212 
  11213 					that.button.attr( "aria-activedescendant",
  11214 						that.menuItems.eq( item.index ).attr( "id" ) );
  11215 				}
  11216 			})
  11217 			.menu( "instance" );
  11218 
  11219 		// Adjust menu styles to dropdown
  11220 		this.menu
  11221 			.addClass( "ui-corner-bottom" )
  11222 			.removeClass( "ui-corner-all" );
  11223 
  11224 		// Don't close the menu on mouseleave
  11225 		this.menuInstance._off( this.menu, "mouseleave" );
  11226 
  11227 		// Cancel the menu's collapseAll on document click
  11228 		this.menuInstance._closeOnDocumentClick = function() {
  11229 			return false;
  11230 		};
  11231 
  11232 		// Selects often contain empty items, but never contain dividers
  11233 		this.menuInstance._isDivider = function() {
  11234 			return false;
  11235 		};
  11236 	},
  11237 
  11238 	refresh: function() {
  11239 		this._refreshMenu();
  11240 		this._setText( this.buttonText, this._getSelectedItem().text() );
  11241 		if ( !this.options.width ) {
  11242 			this._resizeButton();
  11243 		}
  11244 	},
  11245 
  11246 	_refreshMenu: function() {
  11247 		this.menu.empty();
  11248 
  11249 		var item,
  11250 			options = this.element.find( "option" );
  11251 
  11252 		if ( !options.length ) {
  11253 			return;
  11254 		}
  11255 
  11256 		this._parseOptions( options );
  11257 		this._renderMenu( this.menu, this.items );
  11258 
  11259 		this.menuInstance.refresh();
  11260 		this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
  11261 
  11262 		item = this._getSelectedItem();
  11263 
  11264 		// Update the menu to have the correct item focused
  11265 		this.menuInstance.focus( null, item );
  11266 		this._setAria( item.data( "ui-selectmenu-item" ) );
  11267 
  11268 		// Set disabled state
  11269 		this._setOption( "disabled", this.element.prop( "disabled" ) );
  11270 	},
  11271 
  11272 	open: function( event ) {
  11273 		if ( this.options.disabled ) {
  11274 			return;
  11275 		}
  11276 
  11277 		// If this is the first time the menu is being opened, render the items
  11278 		if ( !this.menuItems ) {
  11279 			this._refreshMenu();
  11280 		} else {
  11281 
  11282 			// Menu clears focus on close, reset focus to selected item
  11283 			this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
  11284 			this.menuInstance.focus( null, this._getSelectedItem() );
  11285 		}
  11286 
  11287 		this.isOpen = true;
  11288 		this._toggleAttr();
  11289 		this._resizeMenu();
  11290 		this._position();
  11291 
  11292 		this._on( this.document, this._documentClick );
  11293 
  11294 		this._trigger( "open", event );
  11295 	},
  11296 
  11297 	_position: function() {
  11298 		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
  11299 	},
  11300 
  11301 	close: function( event ) {
  11302 		if ( !this.isOpen ) {
  11303 			return;
  11304 		}
  11305 
  11306 		this.isOpen = false;
  11307 		this._toggleAttr();
  11308 
  11309 		this.range = null;
  11310 		this._off( this.document );
  11311 
  11312 		this._trigger( "close", event );
  11313 	},
  11314 
  11315 	widget: function() {
  11316 		return this.button;
  11317 	},
  11318 
  11319 	menuWidget: function() {
  11320 		return this.menu;
  11321 	},
  11322 
  11323 	_renderMenu: function( ul, items ) {
  11324 		var that = this,
  11325 			currentOptgroup = "";
  11326 
  11327 		$.each( items, function( index, item ) {
  11328 			if ( item.optgroup !== currentOptgroup ) {
  11329 				$( "<li>", {
  11330 					"class": "ui-selectmenu-optgroup ui-menu-divider" +
  11331 						( item.element.parent( "optgroup" ).prop( "disabled" ) ?
  11332 							" ui-state-disabled" :
  11333 							"" ),
  11334 					text: item.optgroup
  11335 				})
  11336 					.appendTo( ul );
  11337 
  11338 				currentOptgroup = item.optgroup;
  11339 			}
  11340 
  11341 			that._renderItemData( ul, item );
  11342 		});
  11343 	},
  11344 
  11345 	_renderItemData: function( ul, item ) {
  11346 		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
  11347 	},
  11348 
  11349 	_renderItem: function( ul, item ) {
  11350 		var li = $( "<li>" );
  11351 
  11352 		if ( item.disabled ) {
  11353 			li.addClass( "ui-state-disabled" );
  11354 		}
  11355 		this._setText( li, item.label );
  11356 
  11357 		return li.appendTo( ul );
  11358 	},
  11359 
  11360 	_setText: function( element, value ) {
  11361 		if ( value ) {
  11362 			element.text( value );
  11363 		} else {
  11364 			element.html( "&#160;" );
  11365 		}
  11366 	},
  11367 
  11368 	_move: function( direction, event ) {
  11369 		var item, next,
  11370 			filter = ".ui-menu-item";
  11371 
  11372 		if ( this.isOpen ) {
  11373 			item = this.menuItems.eq( this.focusIndex );
  11374 		} else {
  11375 			item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
  11376 			filter += ":not(.ui-state-disabled)";
  11377 		}
  11378 
  11379 		if ( direction === "first" || direction === "last" ) {
  11380 			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
  11381 		} else {
  11382 			next = item[ direction + "All" ]( filter ).eq( 0 );
  11383 		}
  11384 
  11385 		if ( next.length ) {
  11386 			this.menuInstance.focus( event, next );
  11387 		}
  11388 	},
  11389 
  11390 	_getSelectedItem: function() {
  11391 		return this.menuItems.eq( this.element[ 0 ].selectedIndex );
  11392 	},
  11393 
  11394 	_toggle: function( event ) {
  11395 		this[ this.isOpen ? "close" : "open" ]( event );
  11396 	},
  11397 
  11398 	_setSelection: function() {
  11399 		var selection;
  11400 
  11401 		if ( !this.range ) {
  11402 			return;
  11403 		}
  11404 
  11405 		if ( window.getSelection ) {
  11406 			selection = window.getSelection();
  11407 			selection.removeAllRanges();
  11408 			selection.addRange( this.range );
  11409 
  11410 		// support: IE8
  11411 		} else {
  11412 			this.range.select();
  11413 		}
  11414 
  11415 		// support: IE
  11416 		// Setting the text selection kills the button focus in IE, but
  11417 		// restoring the focus doesn't kill the selection.
  11418 		this.button.focus();
  11419 	},
  11420 
  11421 	_documentClick: {
  11422 		mousedown: function( event ) {
  11423 			if ( !this.isOpen ) {
  11424 				return;
  11425 			}
  11426 
  11427 			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
  11428 				this.close( event );
  11429 			}
  11430 		}
  11431 	},
  11432 
  11433 	_buttonEvents: {
  11434 
  11435 		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
  11436 		mousedown: function() {
  11437 			var selection;
  11438 
  11439 			if ( window.getSelection ) {
  11440 				selection = window.getSelection();
  11441 				if ( selection.rangeCount ) {
  11442 					this.range = selection.getRangeAt( 0 );
  11443 				}
  11444 
  11445 			// support: IE8
  11446 			} else {
  11447 				this.range = document.selection.createRange();
  11448 			}
  11449 		},
  11450 
  11451 		click: function( event ) {
  11452 			this._setSelection();
  11453 			this._toggle( event );
  11454 		},
  11455 
  11456 		keydown: function( event ) {
  11457 			var preventDefault = true;
  11458 			switch ( event.keyCode ) {
  11459 				case $.ui.keyCode.TAB:
  11460 				case $.ui.keyCode.ESCAPE:
  11461 					this.close( event );
  11462 					preventDefault = false;
  11463 					break;
  11464 				case $.ui.keyCode.ENTER:
  11465 					if ( this.isOpen ) {
  11466 						this._selectFocusedItem( event );
  11467 					}
  11468 					break;
  11469 				case $.ui.keyCode.UP:
  11470 					if ( event.altKey ) {
  11471 						this._toggle( event );
  11472 					} else {
  11473 						this._move( "prev", event );
  11474 					}
  11475 					break;
  11476 				case $.ui.keyCode.DOWN:
  11477 					if ( event.altKey ) {
  11478 						this._toggle( event );
  11479 					} else {
  11480 						this._move( "next", event );
  11481 					}
  11482 					break;
  11483 				case $.ui.keyCode.SPACE:
  11484 					if ( this.isOpen ) {
  11485 						this._selectFocusedItem( event );
  11486 					} else {
  11487 						this._toggle( event );
  11488 					}
  11489 					break;
  11490 				case $.ui.keyCode.LEFT:
  11491 					this._move( "prev", event );
  11492 					break;
  11493 				case $.ui.keyCode.RIGHT:
  11494 					this._move( "next", event );
  11495 					break;
  11496 				case $.ui.keyCode.HOME:
  11497 				case $.ui.keyCode.PAGE_UP:
  11498 					this._move( "first", event );
  11499 					break;
  11500 				case $.ui.keyCode.END:
  11501 				case $.ui.keyCode.PAGE_DOWN:
  11502 					this._move( "last", event );
  11503 					break;
  11504 				default:
  11505 					this.menu.trigger( event );
  11506 					preventDefault = false;
  11507 			}
  11508 
  11509 			if ( preventDefault ) {
  11510 				event.preventDefault();
  11511 			}
  11512 		}
  11513 	},
  11514 
  11515 	_selectFocusedItem: function( event ) {
  11516 		var item = this.menuItems.eq( this.focusIndex );
  11517 		if ( !item.hasClass( "ui-state-disabled" ) ) {
  11518 			this._select( item.data( "ui-selectmenu-item" ), event );
  11519 		}
  11520 	},
  11521 
  11522 	_select: function( item, event ) {
  11523 		var oldIndex = this.element[ 0 ].selectedIndex;
  11524 
  11525 		// Change native select element
  11526 		this.element[ 0 ].selectedIndex = item.index;
  11527 		this._setText( this.buttonText, item.label );
  11528 		this._setAria( item );
  11529 		this._trigger( "select", event, { item: item } );
  11530 
  11531 		if ( item.index !== oldIndex ) {
  11532 			this._trigger( "change", event, { item: item } );
  11533 		}
  11534 
  11535 		this.close( event );
  11536 	},
  11537 
  11538 	_setAria: function( item ) {
  11539 		var id = this.menuItems.eq( item.index ).attr( "id" );
  11540 
  11541 		this.button.attr({
  11542 			"aria-labelledby": id,
  11543 			"aria-activedescendant": id
  11544 		});
  11545 		this.menu.attr( "aria-activedescendant", id );
  11546 	},
  11547 
  11548 	_setOption: function( key, value ) {
  11549 		if ( key === "icons" ) {
  11550 			this.button.find( "span.ui-icon" )
  11551 				.removeClass( this.options.icons.button )
  11552 				.addClass( value.button );
  11553 		}
  11554 
  11555 		this._super( key, value );
  11556 
  11557 		if ( key === "appendTo" ) {
  11558 			this.menuWrap.appendTo( this._appendTo() );
  11559 		}
  11560 
  11561 		if ( key === "disabled" ) {
  11562 			this.menuInstance.option( "disabled", value );
  11563 			this.button
  11564 				.toggleClass( "ui-state-disabled", value )
  11565 				.attr( "aria-disabled", value );
  11566 
  11567 			this.element.prop( "disabled", value );
  11568 			if ( value ) {
  11569 				this.button.attr( "tabindex", -1 );
  11570 				this.close();
  11571 			} else {
  11572 				this.button.attr( "tabindex", 0 );
  11573 			}
  11574 		}
  11575 
  11576 		if ( key === "width" ) {
  11577 			this._resizeButton();
  11578 		}
  11579 	},
  11580 
  11581 	_appendTo: function() {
  11582 		var element = this.options.appendTo;
  11583 
  11584 		if ( element ) {
  11585 			element = element.jquery || element.nodeType ?
  11586 				$( element ) :
  11587 				this.document.find( element ).eq( 0 );
  11588 		}
  11589 
  11590 		if ( !element || !element[ 0 ] ) {
  11591 			element = this.element.closest( ".ui-front" );
  11592 		}
  11593 
  11594 		if ( !element.length ) {
  11595 			element = this.document[ 0 ].body;
  11596 		}
  11597 
  11598 		return element;
  11599 	},
  11600 
  11601 	_toggleAttr: function() {
  11602 		this.button
  11603 			.toggleClass( "ui-corner-top", this.isOpen )
  11604 			.toggleClass( "ui-corner-all", !this.isOpen )
  11605 			.attr( "aria-expanded", this.isOpen );
  11606 		this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
  11607 		this.menu.attr( "aria-hidden", !this.isOpen );
  11608 	},
  11609 
  11610 	_resizeButton: function() {
  11611 		var width = this.options.width;
  11612 
  11613 		if ( !width ) {
  11614 			width = this.element.show().outerWidth();
  11615 			this.element.hide();
  11616 		}
  11617 
  11618 		this.button.outerWidth( width );
  11619 	},
  11620 
  11621 	_resizeMenu: function() {
  11622 		this.menu.outerWidth( Math.max(
  11623 			this.button.outerWidth(),
  11624 
  11625 			// support: IE10
  11626 			// IE10 wraps long text (possibly a rounding bug)
  11627 			// so we add 1px to avoid the wrapping
  11628 			this.menu.width( "" ).outerWidth() + 1
  11629 		) );
  11630 	},
  11631 
  11632 	_getCreateOptions: function() {
  11633 		return { disabled: this.element.prop( "disabled" ) };
  11634 	},
  11635 
  11636 	_parseOptions: function( options ) {
  11637 		var data = [];
  11638 		options.each(function( index, item ) {
  11639 			var option = $( item ),
  11640 				optgroup = option.parent( "optgroup" );
  11641 			data.push({
  11642 				element: option,
  11643 				index: index,
  11644 				value: option.val(),
  11645 				label: option.text(),
  11646 				optgroup: optgroup.attr( "label" ) || "",
  11647 				disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
  11648 			});
  11649 		});
  11650 		this.items = data;
  11651 	},
  11652 
  11653 	_destroy: function() {
  11654 		this.menuWrap.remove();
  11655 		this.button.remove();
  11656 		this.element.show();
  11657 		this.element.removeUniqueId();
  11658 		this.label.attr( "for", this.ids.element );
  11659 	}
  11660 });
  11661 
  11662 
  11663 /*!
  11664  * jQuery UI Slider 1.11.4
  11665  * http://jqueryui.com
  11666  *
  11667  * Copyright jQuery Foundation and other contributors
  11668  * Released under the MIT license.
  11669  * http://jquery.org/license
  11670  *
  11671  * http://api.jqueryui.com/slider/
  11672  */
  11673 
  11674 
  11675 var slider = $.widget( "ui.slider", $.ui.mouse, {
  11676 	version: "1.11.4",
  11677 	widgetEventPrefix: "slide",
  11678 
  11679 	options: {
  11680 		animate: false,
  11681 		distance: 0,
  11682 		max: 100,
  11683 		min: 0,
  11684 		orientation: "horizontal",
  11685 		range: false,
  11686 		step: 1,
  11687 		value: 0,
  11688 		values: null,
  11689 
  11690 		// callbacks
  11691 		change: null,
  11692 		slide: null,
  11693 		start: null,
  11694 		stop: null
  11695 	},
  11696 
  11697 	// number of pages in a slider
  11698 	// (how many times can you page up/down to go through the whole range)
  11699 	numPages: 5,
  11700 
  11701 	_create: function() {
  11702 		this._keySliding = false;
  11703 		this._mouseSliding = false;
  11704 		this._animateOff = true;
  11705 		this._handleIndex = null;
  11706 		this._detectOrientation();
  11707 		this._mouseInit();
  11708 		this._calculateNewMax();
  11709 
  11710 		this.element
  11711 			.addClass( "ui-slider" +
  11712 				" ui-slider-" + this.orientation +
  11713 				" ui-widget" +
  11714 				" ui-widget-content" +
  11715 				" ui-corner-all");
  11716 
  11717 		this._refresh();
  11718 		this._setOption( "disabled", this.options.disabled );
  11719 
  11720 		this._animateOff = false;
  11721 	},
  11722 
  11723 	_refresh: function() {
  11724 		this._createRange();
  11725 		this._createHandles();
  11726 		this._setupEvents();
  11727 		this._refreshValue();
  11728 	},
  11729 
  11730 	_createHandles: function() {
  11731 		var i, handleCount,
  11732 			options = this.options,
  11733 			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
  11734 			handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
  11735 			handles = [];
  11736 
  11737 		handleCount = ( options.values && options.values.length ) || 1;
  11738 
  11739 		if ( existingHandles.length > handleCount ) {
  11740 			existingHandles.slice( handleCount ).remove();
  11741 			existingHandles = existingHandles.slice( 0, handleCount );
  11742 		}
  11743 
  11744 		for ( i = existingHandles.length; i < handleCount; i++ ) {
  11745 			handles.push( handle );
  11746 		}
  11747 
  11748 		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  11749 
  11750 		this.handle = this.handles.eq( 0 );
  11751 
  11752 		this.handles.each(function( i ) {
  11753 			$( this ).data( "ui-slider-handle-index", i );
  11754 		});
  11755 	},
  11756 
  11757 	_createRange: function() {
  11758 		var options = this.options,
  11759 			classes = "";
  11760 
  11761 		if ( options.range ) {
  11762 			if ( options.range === true ) {
  11763 				if ( !options.values ) {
  11764 					options.values = [ this._valueMin(), this._valueMin() ];
  11765 				} else if ( options.values.length && options.values.length !== 2 ) {
  11766 					options.values = [ options.values[0], options.values[0] ];
  11767 				} else if ( $.isArray( options.values ) ) {
  11768 					options.values = options.values.slice(0);
  11769 				}
  11770 			}
  11771 
  11772 			if ( !this.range || !this.range.length ) {
  11773 				this.range = $( "<div></div>" )
  11774 					.appendTo( this.element );
  11775 
  11776 				classes = "ui-slider-range" +
  11777 				// note: this isn't the most fittingly semantic framework class for this element,
  11778 				// but worked best visually with a variety of themes
  11779 				" ui-widget-header ui-corner-all";
  11780 			} else {
  11781 				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
  11782 					// Handle range switching from true to min/max
  11783 					.css({
  11784 						"left": "",
  11785 						"bottom": ""
  11786 					});
  11787 			}
  11788 
  11789 			this.range.addClass( classes +
  11790 				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
  11791 		} else {
  11792 			if ( this.range ) {
  11793 				this.range.remove();
  11794 			}
  11795 			this.range = null;
  11796 		}
  11797 	},
  11798 
  11799 	_setupEvents: function() {
  11800 		this._off( this.handles );
  11801 		this._on( this.handles, this._handleEvents );
  11802 		this._hoverable( this.handles );
  11803 		this._focusable( this.handles );
  11804 	},
  11805 
  11806 	_destroy: function() {
  11807 		this.handles.remove();
  11808 		if ( this.range ) {
  11809 			this.range.remove();
  11810 		}
  11811 
  11812 		this.element
  11813 			.removeClass( "ui-slider" +
  11814 				" ui-slider-horizontal" +
  11815 				" ui-slider-vertical" +
  11816 				" ui-widget" +
  11817 				" ui-widget-content" +
  11818 				" ui-corner-all" );
  11819 
  11820 		this._mouseDestroy();
  11821 	},
  11822 
  11823 	_mouseCapture: function( event ) {
  11824 		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  11825 			that = this,
  11826 			o = this.options;
  11827 
  11828 		if ( o.disabled ) {
  11829 			return false;
  11830 		}
  11831 
  11832 		this.elementSize = {
  11833 			width: this.element.outerWidth(),
  11834 			height: this.element.outerHeight()
  11835 		};
  11836 		this.elementOffset = this.element.offset();
  11837 
  11838 		position = { x: event.pageX, y: event.pageY };
  11839 		normValue = this._normValueFromMouse( position );
  11840 		distance = this._valueMax() - this._valueMin() + 1;
  11841 		this.handles.each(function( i ) {
  11842 			var thisDistance = Math.abs( normValue - that.values(i) );
  11843 			if (( distance > thisDistance ) ||
  11844 				( distance === thisDistance &&
  11845 					(i === that._lastChangedValue || that.values(i) === o.min ))) {
  11846 				distance = thisDistance;
  11847 				closestHandle = $( this );
  11848 				index = i;
  11849 			}
  11850 		});
  11851 
  11852 		allowed = this._start( event, index );
  11853 		if ( allowed === false ) {
  11854 			return false;
  11855 		}
  11856 		this._mouseSliding = true;
  11857 
  11858 		this._handleIndex = index;
  11859 
  11860 		closestHandle
  11861 			.addClass( "ui-state-active" )
  11862 			.focus();
  11863 
  11864 		offset = closestHandle.offset();
  11865 		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
  11866 		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  11867 			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  11868 			top: event.pageY - offset.top -
  11869 				( closestHandle.height() / 2 ) -
  11870 				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
  11871 				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
  11872 				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
  11873 		};
  11874 
  11875 		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  11876 			this._slide( event, index, normValue );
  11877 		}
  11878 		this._animateOff = true;
  11879 		return true;
  11880 	},
  11881 
  11882 	_mouseStart: function() {
  11883 		return true;
  11884 	},
  11885 
  11886 	_mouseDrag: function( event ) {
  11887 		var position = { x: event.pageX, y: event.pageY },
  11888 			normValue = this._normValueFromMouse( position );
  11889 
  11890 		this._slide( event, this._handleIndex, normValue );
  11891 
  11892 		return false;
  11893 	},
  11894 
  11895 	_mouseStop: function( event ) {
  11896 		this.handles.removeClass( "ui-state-active" );
  11897 		this._mouseSliding = false;
  11898 
  11899 		this._stop( event, this._handleIndex );
  11900 		this._change( event, this._handleIndex );
  11901 
  11902 		this._handleIndex = null;
  11903 		this._clickOffset = null;
  11904 		this._animateOff = false;
  11905 
  11906 		return false;
  11907 	},
  11908 
  11909 	_detectOrientation: function() {
  11910 		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  11911 	},
  11912 
  11913 	_normValueFromMouse: function( position ) {
  11914 		var pixelTotal,
  11915 			pixelMouse,
  11916 			percentMouse,
  11917 			valueTotal,
  11918 			valueMouse;
  11919 
  11920 		if ( this.orientation === "horizontal" ) {
  11921 			pixelTotal = this.elementSize.width;
  11922 			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
  11923 		} else {
  11924 			pixelTotal = this.elementSize.height;
  11925 			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
  11926 		}
  11927 
  11928 		percentMouse = ( pixelMouse / pixelTotal );
  11929 		if ( percentMouse > 1 ) {
  11930 			percentMouse = 1;
  11931 		}
  11932 		if ( percentMouse < 0 ) {
  11933 			percentMouse = 0;
  11934 		}
  11935 		if ( this.orientation === "vertical" ) {
  11936 			percentMouse = 1 - percentMouse;
  11937 		}
  11938 
  11939 		valueTotal = this._valueMax() - this._valueMin();
  11940 		valueMouse = this._valueMin() + percentMouse * valueTotal;
  11941 
  11942 		return this._trimAlignValue( valueMouse );
  11943 	},
  11944 
  11945 	_start: function( event, index ) {
  11946 		var uiHash = {
  11947 			handle: this.handles[ index ],
  11948 			value: this.value()
  11949 		};
  11950 		if ( this.options.values && this.options.values.length ) {
  11951 			uiHash.value = this.values( index );
  11952 			uiHash.values = this.values();
  11953 		}
  11954 		return this._trigger( "start", event, uiHash );
  11955 	},
  11956 
  11957 	_slide: function( event, index, newVal ) {
  11958 		var otherVal,
  11959 			newValues,
  11960 			allowed;
  11961 
  11962 		if ( this.options.values && this.options.values.length ) {
  11963 			otherVal = this.values( index ? 0 : 1 );
  11964 
  11965 			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
  11966 					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
  11967 				) {
  11968 				newVal = otherVal;
  11969 			}
  11970 
  11971 			if ( newVal !== this.values( index ) ) {
  11972 				newValues = this.values();
  11973 				newValues[ index ] = newVal;
  11974 				// A slide can be canceled by returning false from the slide callback
  11975 				allowed = this._trigger( "slide", event, {
  11976 					handle: this.handles[ index ],
  11977 					value: newVal,
  11978 					values: newValues
  11979 				} );
  11980 				otherVal = this.values( index ? 0 : 1 );
  11981 				if ( allowed !== false ) {
  11982 					this.values( index, newVal );
  11983 				}
  11984 			}
  11985 		} else {
  11986 			if ( newVal !== this.value() ) {
  11987 				// A slide can be canceled by returning false from the slide callback
  11988 				allowed = this._trigger( "slide", event, {
  11989 					handle: this.handles[ index ],
  11990 					value: newVal
  11991 				} );
  11992 				if ( allowed !== false ) {
  11993 					this.value( newVal );
  11994 				}
  11995 			}
  11996 		}
  11997 	},
  11998 
  11999 	_stop: function( event, index ) {
  12000 		var uiHash = {
  12001 			handle: this.handles[ index ],
  12002 			value: this.value()
  12003 		};
  12004 		if ( this.options.values && this.options.values.length ) {
  12005 			uiHash.value = this.values( index );
  12006 			uiHash.values = this.values();
  12007 		}
  12008 
  12009 		this._trigger( "stop", event, uiHash );
  12010 	},
  12011 
  12012 	_change: function( event, index ) {
  12013 		if ( !this._keySliding && !this._mouseSliding ) {
  12014 			var uiHash = {
  12015 				handle: this.handles[ index ],
  12016 				value: this.value()
  12017 			};
  12018 			if ( this.options.values && this.options.values.length ) {
  12019 				uiHash.value = this.values( index );
  12020 				uiHash.values = this.values();
  12021 			}
  12022 
  12023 			//store the last changed value index for reference when handles overlap
  12024 			this._lastChangedValue = index;
  12025 
  12026 			this._trigger( "change", event, uiHash );
  12027 		}
  12028 	},
  12029 
  12030 	value: function( newValue ) {
  12031 		if ( arguments.length ) {
  12032 			this.options.value = this._trimAlignValue( newValue );
  12033 			this._refreshValue();
  12034 			this._change( null, 0 );
  12035 			return;
  12036 		}
  12037 
  12038 		return this._value();
  12039 	},
  12040 
  12041 	values: function( index, newValue ) {
  12042 		var vals,
  12043 			newValues,
  12044 			i;
  12045 
  12046 		if ( arguments.length > 1 ) {
  12047 			this.options.values[ index ] = this._trimAlignValue( newValue );
  12048 			this._refreshValue();
  12049 			this._change( null, index );
  12050 			return;
  12051 		}
  12052 
  12053 		if ( arguments.length ) {
  12054 			if ( $.isArray( arguments[ 0 ] ) ) {
  12055 				vals = this.options.values;
  12056 				newValues = arguments[ 0 ];
  12057 				for ( i = 0; i < vals.length; i += 1 ) {
  12058 					vals[ i ] = this._trimAlignValue( newValues[ i ] );
  12059 					this._change( null, i );
  12060 				}
  12061 				this._refreshValue();
  12062 			} else {
  12063 				if ( this.options.values && this.options.values.length ) {
  12064 					return this._values( index );
  12065 				} else {
  12066 					return this.value();
  12067 				}
  12068 			}
  12069 		} else {
  12070 			return this._values();
  12071 		}
  12072 	},
  12073 
  12074 	_setOption: function( key, value ) {
  12075 		var i,
  12076 			valsLength = 0;
  12077 
  12078 		if ( key === "range" && this.options.range === true ) {
  12079 			if ( value === "min" ) {
  12080 				this.options.value = this._values( 0 );
  12081 				this.options.values = null;
  12082 			} else if ( value === "max" ) {
  12083 				this.options.value = this._values( this.options.values.length - 1 );
  12084 				this.options.values = null;
  12085 			}
  12086 		}
  12087 
  12088 		if ( $.isArray( this.options.values ) ) {
  12089 			valsLength = this.options.values.length;
  12090 		}
  12091 
  12092 		if ( key === "disabled" ) {
  12093 			this.element.toggleClass( "ui-state-disabled", !!value );
  12094 		}
  12095 
  12096 		this._super( key, value );
  12097 
  12098 		switch ( key ) {
  12099 			case "orientation":
  12100 				this._detectOrientation();
  12101 				this.element
  12102 					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
  12103 					.addClass( "ui-slider-" + this.orientation );
  12104 				this._refreshValue();
  12105 
  12106 				// Reset positioning from previous orientation
  12107 				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
  12108 				break;
  12109 			case "value":
  12110 				this._animateOff = true;
  12111 				this._refreshValue();
  12112 				this._change( null, 0 );
  12113 				this._animateOff = false;
  12114 				break;
  12115 			case "values":
  12116 				this._animateOff = true;
  12117 				this._refreshValue();
  12118 				for ( i = 0; i < valsLength; i += 1 ) {
  12119 					this._change( null, i );
  12120 				}
  12121 				this._animateOff = false;
  12122 				break;
  12123 			case "step":
  12124 			case "min":
  12125 			case "max":
  12126 				this._animateOff = true;
  12127 				this._calculateNewMax();
  12128 				this._refreshValue();
  12129 				this._animateOff = false;
  12130 				break;
  12131 			case "range":
  12132 				this._animateOff = true;
  12133 				this._refresh();
  12134 				this._animateOff = false;
  12135 				break;
  12136 		}
  12137 	},
  12138 
  12139 	//internal value getter
  12140 	// _value() returns value trimmed by min and max, aligned by step
  12141 	_value: function() {
  12142 		var val = this.options.value;
  12143 		val = this._trimAlignValue( val );
  12144 
  12145 		return val;
  12146 	},
  12147 
  12148 	//internal values getter
  12149 	// _values() returns array of values trimmed by min and max, aligned by step
  12150 	// _values( index ) returns single value trimmed by min and max, aligned by step
  12151 	_values: function( index ) {
  12152 		var val,
  12153 			vals,
  12154 			i;
  12155 
  12156 		if ( arguments.length ) {
  12157 			val = this.options.values[ index ];
  12158 			val = this._trimAlignValue( val );
  12159 
  12160 			return val;
  12161 		} else if ( this.options.values && this.options.values.length ) {
  12162 			// .slice() creates a copy of the array
  12163 			// this copy gets trimmed by min and max and then returned
  12164 			vals = this.options.values.slice();
  12165 			for ( i = 0; i < vals.length; i += 1) {
  12166 				vals[ i ] = this._trimAlignValue( vals[ i ] );
  12167 			}
  12168 
  12169 			return vals;
  12170 		} else {
  12171 			return [];
  12172 		}
  12173 	},
  12174 
  12175 	// returns the step-aligned value that val is closest to, between (inclusive) min and max
  12176 	_trimAlignValue: function( val ) {
  12177 		if ( val <= this._valueMin() ) {
  12178 			return this._valueMin();
  12179 		}
  12180 		if ( val >= this._valueMax() ) {
  12181 			return this._valueMax();
  12182 		}
  12183 		var step = ( this.options.step > 0 ) ? this.options.step : 1,
  12184 			valModStep = (val - this._valueMin()) % step,
  12185 			alignValue = val - valModStep;
  12186 
  12187 		if ( Math.abs(valModStep) * 2 >= step ) {
  12188 			alignValue += ( valModStep > 0 ) ? step : ( -step );
  12189 		}
  12190 
  12191 		// Since JavaScript has problems with large floats, round
  12192 		// the final value to 5 digits after the decimal point (see #4124)
  12193 		return parseFloat( alignValue.toFixed(5) );
  12194 	},
  12195 
  12196 	_calculateNewMax: function() {
  12197 		var max = this.options.max,
  12198 			min = this._valueMin(),
  12199 			step = this.options.step,
  12200 			aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
  12201 		max = aboveMin + min;
  12202 		this.max = parseFloat( max.toFixed( this._precision() ) );
  12203 	},
  12204 
  12205 	_precision: function() {
  12206 		var precision = this._precisionOf( this.options.step );
  12207 		if ( this.options.min !== null ) {
  12208 			precision = Math.max( precision, this._precisionOf( this.options.min ) );
  12209 		}
  12210 		return precision;
  12211 	},
  12212 
  12213 	_precisionOf: function( num ) {
  12214 		var str = num.toString(),
  12215 			decimal = str.indexOf( "." );
  12216 		return decimal === -1 ? 0 : str.length - decimal - 1;
  12217 	},
  12218 
  12219 	_valueMin: function() {
  12220 		return this.options.min;
  12221 	},
  12222 
  12223 	_valueMax: function() {
  12224 		return this.max;
  12225 	},
  12226 
  12227 	_refreshValue: function() {
  12228 		var lastValPercent, valPercent, value, valueMin, valueMax,
  12229 			oRange = this.options.range,
  12230 			o = this.options,
  12231 			that = this,
  12232 			animate = ( !this._animateOff ) ? o.animate : false,
  12233 			_set = {};
  12234 
  12235 		if ( this.options.values && this.options.values.length ) {
  12236 			this.handles.each(function( i ) {
  12237 				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
  12238 				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  12239 				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  12240 				if ( that.options.range === true ) {
  12241 					if ( that.orientation === "horizontal" ) {
  12242 						if ( i === 0 ) {
  12243 							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
  12244 						}
  12245 						if ( i === 1 ) {
  12246 							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  12247 						}
  12248 					} else {
  12249 						if ( i === 0 ) {
  12250 							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
  12251 						}
  12252 						if ( i === 1 ) {
  12253 							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  12254 						}
  12255 					}
  12256 				}
  12257 				lastValPercent = valPercent;
  12258 			});
  12259 		} else {
  12260 			value = this.value();
  12261 			valueMin = this._valueMin();
  12262 			valueMax = this._valueMax();
  12263 			valPercent = ( valueMax !== valueMin ) ?
  12264 					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  12265 					0;
  12266 			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  12267 			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  12268 
  12269 			if ( oRange === "min" && this.orientation === "horizontal" ) {
  12270 				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
  12271 			}
  12272 			if ( oRange === "max" && this.orientation === "horizontal" ) {
  12273 				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  12274 			}
  12275 			if ( oRange === "min" && this.orientation === "vertical" ) {
  12276 				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
  12277 			}
  12278 			if ( oRange === "max" && this.orientation === "vertical" ) {
  12279 				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  12280 			}
  12281 		}
  12282 	},
  12283 
  12284 	_handleEvents: {
  12285 		keydown: function( event ) {
  12286 			var allowed, curVal, newVal, step,
  12287 				index = $( event.target ).data( "ui-slider-handle-index" );
  12288 
  12289 			switch ( event.keyCode ) {
  12290 				case $.ui.keyCode.HOME:
  12291 				case $.ui.keyCode.END:
  12292 				case $.ui.keyCode.PAGE_UP:
  12293 				case $.ui.keyCode.PAGE_DOWN:
  12294 				case $.ui.keyCode.UP:
  12295 				case $.ui.keyCode.RIGHT:
  12296 				case $.ui.keyCode.DOWN:
  12297 				case $.ui.keyCode.LEFT:
  12298 					event.preventDefault();
  12299 					if ( !this._keySliding ) {
  12300 						this._keySliding = true;
  12301 						$( event.target ).addClass( "ui-state-active" );
  12302 						allowed = this._start( event, index );
  12303 						if ( allowed === false ) {
  12304 							return;
  12305 						}
  12306 					}
  12307 					break;
  12308 			}
  12309 
  12310 			step = this.options.step;
  12311 			if ( this.options.values && this.options.values.length ) {
  12312 				curVal = newVal = this.values( index );
  12313 			} else {
  12314 				curVal = newVal = this.value();
  12315 			}
  12316 
  12317 			switch ( event.keyCode ) {
  12318 				case $.ui.keyCode.HOME:
  12319 					newVal = this._valueMin();
  12320 					break;
  12321 				case $.ui.keyCode.END:
  12322 					newVal = this._valueMax();
  12323 					break;
  12324 				case $.ui.keyCode.PAGE_UP:
  12325 					newVal = this._trimAlignValue(
  12326 						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
  12327 					);
  12328 					break;
  12329 				case $.ui.keyCode.PAGE_DOWN:
  12330 					newVal = this._trimAlignValue(
  12331 						curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
  12332 					break;
  12333 				case $.ui.keyCode.UP:
  12334 				case $.ui.keyCode.RIGHT:
  12335 					if ( curVal === this._valueMax() ) {
  12336 						return;
  12337 					}
  12338 					newVal = this._trimAlignValue( curVal + step );
  12339 					break;
  12340 				case $.ui.keyCode.DOWN:
  12341 				case $.ui.keyCode.LEFT:
  12342 					if ( curVal === this._valueMin() ) {
  12343 						return;
  12344 					}
  12345 					newVal = this._trimAlignValue( curVal - step );
  12346 					break;
  12347 			}
  12348 
  12349 			this._slide( event, index, newVal );
  12350 		},
  12351 		keyup: function( event ) {
  12352 			var index = $( event.target ).data( "ui-slider-handle-index" );
  12353 
  12354 			if ( this._keySliding ) {
  12355 				this._keySliding = false;
  12356 				this._stop( event, index );
  12357 				this._change( event, index );
  12358 				$( event.target ).removeClass( "ui-state-active" );
  12359 			}
  12360 		}
  12361 	}
  12362 });
  12363 
  12364 
  12365 /*!
  12366  * jQuery UI Spinner 1.11.4
  12367  * http://jqueryui.com
  12368  *
  12369  * Copyright jQuery Foundation and other contributors
  12370  * Released under the MIT license.
  12371  * http://jquery.org/license
  12372  *
  12373  * http://api.jqueryui.com/spinner/
  12374  */
  12375 
  12376 
  12377 function spinner_modifier( fn ) {
  12378 	return function() {
  12379 		var previous = this.element.val();
  12380 		fn.apply( this, arguments );
  12381 		this._refresh();
  12382 		if ( previous !== this.element.val() ) {
  12383 			this._trigger( "change" );
  12384 		}
  12385 	};
  12386 }
  12387 
  12388 var spinner = $.widget( "ui.spinner", {
  12389 	version: "1.11.4",
  12390 	defaultElement: "<input>",
  12391 	widgetEventPrefix: "spin",
  12392 	options: {
  12393 		culture: null,
  12394 		icons: {
  12395 			down: "ui-icon-triangle-1-s",
  12396 			up: "ui-icon-triangle-1-n"
  12397 		},
  12398 		incremental: true,
  12399 		max: null,
  12400 		min: null,
  12401 		numberFormat: null,
  12402 		page: 10,
  12403 		step: 1,
  12404 
  12405 		change: null,
  12406 		spin: null,
  12407 		start: null,
  12408 		stop: null
  12409 	},
  12410 
  12411 	_create: function() {
  12412 		// handle string values that need to be parsed
  12413 		this._setOption( "max", this.options.max );
  12414 		this._setOption( "min", this.options.min );
  12415 		this._setOption( "step", this.options.step );
  12416 
  12417 		// Only format if there is a value, prevents the field from being marked
  12418 		// as invalid in Firefox, see #9573.
  12419 		if ( this.value() !== "" ) {
  12420 			// Format the value, but don't constrain.
  12421 			this._value( this.element.val(), true );
  12422 		}
  12423 
  12424 		this._draw();
  12425 		this._on( this._events );
  12426 		this._refresh();
  12427 
  12428 		// turning off autocomplete prevents the browser from remembering the
  12429 		// value when navigating through history, so we re-enable autocomplete
  12430 		// if the page is unloaded before the widget is destroyed. #7790
  12431 		this._on( this.window, {
  12432 			beforeunload: function() {
  12433 				this.element.removeAttr( "autocomplete" );
  12434 			}
  12435 		});
  12436 	},
  12437 
  12438 	_getCreateOptions: function() {
  12439 		var options = {},
  12440 			element = this.element;
  12441 
  12442 		$.each( [ "min", "max", "step" ], function( i, option ) {
  12443 			var value = element.attr( option );
  12444 			if ( value !== undefined && value.length ) {
  12445 				options[ option ] = value;
  12446 			}
  12447 		});
  12448 
  12449 		return options;
  12450 	},
  12451 
  12452 	_events: {
  12453 		keydown: function( event ) {
  12454 			if ( this._start( event ) && this._keydown( event ) ) {
  12455 				event.preventDefault();
  12456 			}
  12457 		},
  12458 		keyup: "_stop",
  12459 		focus: function() {
  12460 			this.previous = this.element.val();
  12461 		},
  12462 		blur: function( event ) {
  12463 			if ( this.cancelBlur ) {
  12464 				delete this.cancelBlur;
  12465 				return;
  12466 			}
  12467 
  12468 			this._stop();
  12469 			this._refresh();
  12470 			if ( this.previous !== this.element.val() ) {
  12471 				this._trigger( "change", event );
  12472 			}
  12473 		},
  12474 		mousewheel: function( event, delta ) {
  12475 			if ( !delta ) {
  12476 				return;
  12477 			}
  12478 			if ( !this.spinning && !this._start( event ) ) {
  12479 				return false;
  12480 			}
  12481 
  12482 			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
  12483 			clearTimeout( this.mousewheelTimer );
  12484 			this.mousewheelTimer = this._delay(function() {
  12485 				if ( this.spinning ) {
  12486 					this._stop( event );
  12487 				}
  12488 			}, 100 );
  12489 			event.preventDefault();
  12490 		},
  12491 		"mousedown .ui-spinner-button": function( event ) {
  12492 			var previous;
  12493 
  12494 			// We never want the buttons to have focus; whenever the user is
  12495 			// interacting with the spinner, the focus should be on the input.
  12496 			// If the input is focused then this.previous is properly set from
  12497 			// when the input first received focus. If the input is not focused
  12498 			// then we need to set this.previous based on the value before spinning.
  12499 			previous = this.element[0] === this.document[0].activeElement ?
  12500 				this.previous : this.element.val();
  12501 			function checkFocus() {
  12502 				var isActive = this.element[0] === this.document[0].activeElement;
  12503 				if ( !isActive ) {
  12504 					this.element.focus();
  12505 					this.previous = previous;
  12506 					// support: IE
  12507 					// IE sets focus asynchronously, so we need to check if focus
  12508 					// moved off of the input because the user clicked on the button.
  12509 					this._delay(function() {
  12510 						this.previous = previous;
  12511 					});
  12512 				}
  12513 			}
  12514 
  12515 			// ensure focus is on (or stays on) the text field
  12516 			event.preventDefault();
  12517 			checkFocus.call( this );
  12518 
  12519 			// support: IE
  12520 			// IE doesn't prevent moving focus even with event.preventDefault()
  12521 			// so we set a flag to know when we should ignore the blur event
  12522 			// and check (again) if focus moved off of the input.
  12523 			this.cancelBlur = true;
  12524 			this._delay(function() {
  12525 				delete this.cancelBlur;
  12526 				checkFocus.call( this );
  12527 			});
  12528 
  12529 			if ( this._start( event ) === false ) {
  12530 				return;
  12531 			}
  12532 
  12533 			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  12534 		},
  12535 		"mouseup .ui-spinner-button": "_stop",
  12536 		"mouseenter .ui-spinner-button": function( event ) {
  12537 			// button will add ui-state-active if mouse was down while mouseleave and kept down
  12538 			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
  12539 				return;
  12540 			}
  12541 
  12542 			if ( this._start( event ) === false ) {
  12543 				return false;
  12544 			}
  12545 			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  12546 		},
  12547 		// TODO: do we really want to consider this a stop?
  12548 		// shouldn't we just stop the repeater and wait until mouseup before
  12549 		// we trigger the stop event?
  12550 		"mouseleave .ui-spinner-button": "_stop"
  12551 	},
  12552 
  12553 	_draw: function() {
  12554 		var uiSpinner = this.uiSpinner = this.element
  12555 			.addClass( "ui-spinner-input" )
  12556 			.attr( "autocomplete", "off" )
  12557 			.wrap( this._uiSpinnerHtml() )
  12558 			.parent()
  12559 				// add buttons
  12560 				.append( this._buttonHtml() );
  12561 
  12562 		this.element.attr( "role", "spinbutton" );
  12563 
  12564 		// button bindings
  12565 		this.buttons = uiSpinner.find( ".ui-spinner-button" )
  12566 			.attr( "tabIndex", -1 )
  12567 			.button()
  12568 			.removeClass( "ui-corner-all" );
  12569 
  12570 		// IE 6 doesn't understand height: 50% for the buttons
  12571 		// unless the wrapper has an explicit height
  12572 		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
  12573 				uiSpinner.height() > 0 ) {
  12574 			uiSpinner.height( uiSpinner.height() );
  12575 		}
  12576 
  12577 		// disable spinner if element was already disabled
  12578 		if ( this.options.disabled ) {
  12579 			this.disable();
  12580 		}
  12581 	},
  12582 
  12583 	_keydown: function( event ) {
  12584 		var options = this.options,
  12585 			keyCode = $.ui.keyCode;
  12586 
  12587 		switch ( event.keyCode ) {
  12588 		case keyCode.UP:
  12589 			this._repeat( null, 1, event );
  12590 			return true;
  12591 		case keyCode.DOWN:
  12592 			this._repeat( null, -1, event );
  12593 			return true;
  12594 		case keyCode.PAGE_UP:
  12595 			this._repeat( null, options.page, event );
  12596 			return true;
  12597 		case keyCode.PAGE_DOWN:
  12598 			this._repeat( null, -options.page, event );
  12599 			return true;
  12600 		}
  12601 
  12602 		return false;
  12603 	},
  12604 
  12605 	_uiSpinnerHtml: function() {
  12606 		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
  12607 	},
  12608 
  12609 	_buttonHtml: function() {
  12610 		return "" +
  12611 			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
  12612 				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
  12613 			"</a>" +
  12614 			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
  12615 				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
  12616 			"</a>";
  12617 	},
  12618 
  12619 	_start: function( event ) {
  12620 		if ( !this.spinning && this._trigger( "start", event ) === false ) {
  12621 			return false;
  12622 		}
  12623 
  12624 		if ( !this.counter ) {
  12625 			this.counter = 1;
  12626 		}
  12627 		this.spinning = true;
  12628 		return true;
  12629 	},
  12630 
  12631 	_repeat: function( i, steps, event ) {
  12632 		i = i || 500;
  12633 
  12634 		clearTimeout( this.timer );
  12635 		this.timer = this._delay(function() {
  12636 			this._repeat( 40, steps, event );
  12637 		}, i );
  12638 
  12639 		this._spin( steps * this.options.step, event );
  12640 	},
  12641 
  12642 	_spin: function( step, event ) {
  12643 		var value = this.value() || 0;
  12644 
  12645 		if ( !this.counter ) {
  12646 			this.counter = 1;
  12647 		}
  12648 
  12649 		value = this._adjustValue( value + step * this._increment( this.counter ) );
  12650 
  12651 		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
  12652 			this._value( value );
  12653 			this.counter++;
  12654 		}
  12655 	},
  12656 
  12657 	_increment: function( i ) {
  12658 		var incremental = this.options.incremental;
  12659 
  12660 		if ( incremental ) {
  12661 			return $.isFunction( incremental ) ?
  12662 				incremental( i ) :
  12663 				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
  12664 		}
  12665 
  12666 		return 1;
  12667 	},
  12668 
  12669 	_precision: function() {
  12670 		var precision = this._precisionOf( this.options.step );
  12671 		if ( this.options.min !== null ) {
  12672 			precision = Math.max( precision, this._precisionOf( this.options.min ) );
  12673 		}
  12674 		return precision;
  12675 	},
  12676 
  12677 	_precisionOf: function( num ) {
  12678 		var str = num.toString(),
  12679 			decimal = str.indexOf( "." );
  12680 		return decimal === -1 ? 0 : str.length - decimal - 1;
  12681 	},
  12682 
  12683 	_adjustValue: function( value ) {
  12684 		var base, aboveMin,
  12685 			options = this.options;
  12686 
  12687 		// make sure we're at a valid step
  12688 		// - find out where we are relative to the base (min or 0)
  12689 		base = options.min !== null ? options.min : 0;
  12690 		aboveMin = value - base;
  12691 		// - round to the nearest step
  12692 		aboveMin = Math.round(aboveMin / options.step) * options.step;
  12693 		// - rounding is based on 0, so adjust back to our base
  12694 		value = base + aboveMin;
  12695 
  12696 		// fix precision from bad JS floating point math
  12697 		value = parseFloat( value.toFixed( this._precision() ) );
  12698 
  12699 		// clamp the value
  12700 		if ( options.max !== null && value > options.max) {
  12701 			return options.max;
  12702 		}
  12703 		if ( options.min !== null && value < options.min ) {
  12704 			return options.min;
  12705 		}
  12706 
  12707 		return value;
  12708 	},
  12709 
  12710 	_stop: function( event ) {
  12711 		if ( !this.spinning ) {
  12712 			return;
  12713 		}
  12714 
  12715 		clearTimeout( this.timer );
  12716 		clearTimeout( this.mousewheelTimer );
  12717 		this.counter = 0;
  12718 		this.spinning = false;
  12719 		this._trigger( "stop", event );
  12720 	},
  12721 
  12722 	_setOption: function( key, value ) {
  12723 		if ( key === "culture" || key === "numberFormat" ) {
  12724 			var prevValue = this._parse( this.element.val() );
  12725 			this.options[ key ] = value;
  12726 			this.element.val( this._format( prevValue ) );
  12727 			return;
  12728 		}
  12729 
  12730 		if ( key === "max" || key === "min" || key === "step" ) {
  12731 			if ( typeof value === "string" ) {
  12732 				value = this._parse( value );
  12733 			}
  12734 		}
  12735 		if ( key === "icons" ) {
  12736 			this.buttons.first().find( ".ui-icon" )
  12737 				.removeClass( this.options.icons.up )
  12738 				.addClass( value.up );
  12739 			this.buttons.last().find( ".ui-icon" )
  12740 				.removeClass( this.options.icons.down )
  12741 				.addClass( value.down );
  12742 		}
  12743 
  12744 		this._super( key, value );
  12745 
  12746 		if ( key === "disabled" ) {
  12747 			this.widget().toggleClass( "ui-state-disabled", !!value );
  12748 			this.element.prop( "disabled", !!value );
  12749 			this.buttons.button( value ? "disable" : "enable" );
  12750 		}
  12751 	},
  12752 
  12753 	_setOptions: spinner_modifier(function( options ) {
  12754 		this._super( options );
  12755 	}),
  12756 
  12757 	_parse: function( val ) {
  12758 		if ( typeof val === "string" && val !== "" ) {
  12759 			val = window.Globalize && this.options.numberFormat ?
  12760 				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
  12761 		}
  12762 		return val === "" || isNaN( val ) ? null : val;
  12763 	},
  12764 
  12765 	_format: function( value ) {
  12766 		if ( value === "" ) {
  12767 			return "";
  12768 		}
  12769 		return window.Globalize && this.options.numberFormat ?
  12770 			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
  12771 			value;
  12772 	},
  12773 
  12774 	_refresh: function() {
  12775 		this.element.attr({
  12776 			"aria-valuemin": this.options.min,
  12777 			"aria-valuemax": this.options.max,
  12778 			// TODO: what should we do with values that can't be parsed?
  12779 			"aria-valuenow": this._parse( this.element.val() )
  12780 		});
  12781 	},
  12782 
  12783 	isValid: function() {
  12784 		var value = this.value();
  12785 
  12786 		// null is invalid
  12787 		if ( value === null ) {
  12788 			return false;
  12789 		}
  12790 
  12791 		// if value gets adjusted, it's invalid
  12792 		return value === this._adjustValue( value );
  12793 	},
  12794 
  12795 	// update the value without triggering change
  12796 	_value: function( value, allowAny ) {
  12797 		var parsed;
  12798 		if ( value !== "" ) {
  12799 			parsed = this._parse( value );
  12800 			if ( parsed !== null ) {
  12801 				if ( !allowAny ) {
  12802 					parsed = this._adjustValue( parsed );
  12803 				}
  12804 				value = this._format( parsed );
  12805 			}
  12806 		}
  12807 		this.element.val( value );
  12808 		this._refresh();
  12809 	},
  12810 
  12811 	_destroy: function() {
  12812 		this.element
  12813 			.removeClass( "ui-spinner-input" )
  12814 			.prop( "disabled", false )
  12815 			.removeAttr( "autocomplete" )
  12816 			.removeAttr( "role" )
  12817 			.removeAttr( "aria-valuemin" )
  12818 			.removeAttr( "aria-valuemax" )
  12819 			.removeAttr( "aria-valuenow" );
  12820 		this.uiSpinner.replaceWith( this.element );
  12821 	},
  12822 
  12823 	stepUp: spinner_modifier(function( steps ) {
  12824 		this._stepUp( steps );
  12825 	}),
  12826 	_stepUp: function( steps ) {
  12827 		if ( this._start() ) {
  12828 			this._spin( (steps || 1) * this.options.step );
  12829 			this._stop();
  12830 		}
  12831 	},
  12832 
  12833 	stepDown: spinner_modifier(function( steps ) {
  12834 		this._stepDown( steps );
  12835 	}),
  12836 	_stepDown: function( steps ) {
  12837 		if ( this._start() ) {
  12838 			this._spin( (steps || 1) * -this.options.step );
  12839 			this._stop();
  12840 		}
  12841 	},
  12842 
  12843 	pageUp: spinner_modifier(function( pages ) {
  12844 		this._stepUp( (pages || 1) * this.options.page );
  12845 	}),
  12846 
  12847 	pageDown: spinner_modifier(function( pages ) {
  12848 		this._stepDown( (pages || 1) * this.options.page );
  12849 	}),
  12850 
  12851 	value: function( newVal ) {
  12852 		if ( !arguments.length ) {
  12853 			return this._parse( this.element.val() );
  12854 		}
  12855 		spinner_modifier( this._value ).call( this, newVal );
  12856 	},
  12857 
  12858 	widget: function() {
  12859 		return this.uiSpinner;
  12860 	}
  12861 });
  12862 
  12863 
  12864 /*!
  12865  * jQuery UI Tabs 1.11.4
  12866  * http://jqueryui.com
  12867  *
  12868  * Copyright jQuery Foundation and other contributors
  12869  * Released under the MIT license.
  12870  * http://jquery.org/license
  12871  *
  12872  * http://api.jqueryui.com/tabs/
  12873  */
  12874 
  12875 
  12876 var tabs = $.widget( "ui.tabs", {
  12877 	version: "1.11.4",
  12878 	delay: 300,
  12879 	options: {
  12880 		active: null,
  12881 		collapsible: false,
  12882 		event: "click",
  12883 		heightStyle: "content",
  12884 		hide: null,
  12885 		show: null,
  12886 
  12887 		// callbacks
  12888 		activate: null,
  12889 		beforeActivate: null,
  12890 		beforeLoad: null,
  12891 		load: null
  12892 	},
  12893 
  12894 	_isLocal: (function() {
  12895 		var rhash = /#.*$/;
  12896 
  12897 		return function( anchor ) {
  12898 			var anchorUrl, locationUrl;
  12899 
  12900 			// support: IE7
  12901 			// IE7 doesn't normalize the href property when set via script (#9317)
  12902 			anchor = anchor.cloneNode( false );
  12903 
  12904 			anchorUrl = anchor.href.replace( rhash, "" );
  12905 			locationUrl = location.href.replace( rhash, "" );
  12906 
  12907 			// decoding may throw an error if the URL isn't UTF-8 (#9518)
  12908 			try {
  12909 				anchorUrl = decodeURIComponent( anchorUrl );
  12910 			} catch ( error ) {}
  12911 			try {
  12912 				locationUrl = decodeURIComponent( locationUrl );
  12913 			} catch ( error ) {}
  12914 
  12915 			return anchor.hash.length > 1 && anchorUrl === locationUrl;
  12916 		};
  12917 	})(),
  12918 
  12919 	_create: function() {
  12920 		var that = this,
  12921 			options = this.options;
  12922 
  12923 		this.running = false;
  12924 
  12925 		this.element
  12926 			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
  12927 			.toggleClass( "ui-tabs-collapsible", options.collapsible );
  12928 
  12929 		this._processTabs();
  12930 		options.active = this._initialActive();
  12931 
  12932 		// Take disabling tabs via class attribute from HTML
  12933 		// into account and update option properly.
  12934 		if ( $.isArray( options.disabled ) ) {
  12935 			options.disabled = $.unique( options.disabled.concat(
  12936 				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
  12937 					return that.tabs.index( li );
  12938 				})
  12939 			) ).sort();
  12940 		}
  12941 
  12942 		// check for length avoids error when initializing empty list
  12943 		if ( this.options.active !== false && this.anchors.length ) {
  12944 			this.active = this._findActive( options.active );
  12945 		} else {
  12946 			this.active = $();
  12947 		}
  12948 
  12949 		this._refresh();
  12950 
  12951 		if ( this.active.length ) {
  12952 			this.load( options.active );
  12953 		}
  12954 	},
  12955 
  12956 	_initialActive: function() {
  12957 		var active = this.options.active,
  12958 			collapsible = this.options.collapsible,
  12959 			locationHash = location.hash.substring( 1 );
  12960 
  12961 		if ( active === null ) {
  12962 			// check the fragment identifier in the URL
  12963 			if ( locationHash ) {
  12964 				this.tabs.each(function( i, tab ) {
  12965 					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
  12966 						active = i;
  12967 						return false;
  12968 					}
  12969 				});
  12970 			}
  12971 
  12972 			// check for a tab marked active via a class
  12973 			if ( active === null ) {
  12974 				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
  12975 			}
  12976 
  12977 			// no active tab, set to false
  12978 			if ( active === null || active === -1 ) {
  12979 				active = this.tabs.length ? 0 : false;
  12980 			}
  12981 		}
  12982 
  12983 		// handle numbers: negative, out of range
  12984 		if ( active !== false ) {
  12985 			active = this.tabs.index( this.tabs.eq( active ) );
  12986 			if ( active === -1 ) {
  12987 				active = collapsible ? false : 0;
  12988 			}
  12989 		}
  12990 
  12991 		// don't allow collapsible: false and active: false
  12992 		if ( !collapsible && active === false && this.anchors.length ) {
  12993 			active = 0;
  12994 		}
  12995 
  12996 		return active;
  12997 	},
  12998 
  12999 	_getCreateEventData: function() {
  13000 		return {
  13001 			tab: this.active,
  13002 			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
  13003 		};
  13004 	},
  13005 
  13006 	_tabKeydown: function( event ) {
  13007 		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
  13008 			selectedIndex = this.tabs.index( focusedTab ),
  13009 			goingForward = true;
  13010 
  13011 		if ( this._handlePageNav( event ) ) {
  13012 			return;
  13013 		}
  13014 
  13015 		switch ( event.keyCode ) {
  13016 			case $.ui.keyCode.RIGHT:
  13017 			case $.ui.keyCode.DOWN:
  13018 				selectedIndex++;
  13019 				break;
  13020 			case $.ui.keyCode.UP:
  13021 			case $.ui.keyCode.LEFT:
  13022 				goingForward = false;
  13023 				selectedIndex--;
  13024 				break;
  13025 			case $.ui.keyCode.END:
  13026 				selectedIndex = this.anchors.length - 1;
  13027 				break;
  13028 			case $.ui.keyCode.HOME:
  13029 				selectedIndex = 0;
  13030 				break;
  13031 			case $.ui.keyCode.SPACE:
  13032 				// Activate only, no collapsing
  13033 				event.preventDefault();
  13034 				clearTimeout( this.activating );
  13035 				this._activate( selectedIndex );
  13036 				return;
  13037 			case $.ui.keyCode.ENTER:
  13038 				// Toggle (cancel delayed activation, allow collapsing)
  13039 				event.preventDefault();
  13040 				clearTimeout( this.activating );
  13041 				// Determine if we should collapse or activate
  13042 				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
  13043 				return;
  13044 			default:
  13045 				return;
  13046 		}
  13047 
  13048 		// Focus the appropriate tab, based on which key was pressed
  13049 		event.preventDefault();
  13050 		clearTimeout( this.activating );
  13051 		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
  13052 
  13053 		// Navigating with control/command key will prevent automatic activation
  13054 		if ( !event.ctrlKey && !event.metaKey ) {
  13055 
  13056 			// Update aria-selected immediately so that AT think the tab is already selected.
  13057 			// Otherwise AT may confuse the user by stating that they need to activate the tab,
  13058 			// but the tab will already be activated by the time the announcement finishes.
  13059 			focusedTab.attr( "aria-selected", "false" );
  13060 			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
  13061 
  13062 			this.activating = this._delay(function() {
  13063 				this.option( "active", selectedIndex );
  13064 			}, this.delay );
  13065 		}
  13066 	},
  13067 
  13068 	_panelKeydown: function( event ) {
  13069 		if ( this._handlePageNav( event ) ) {
  13070 			return;
  13071 		}
  13072 
  13073 		// Ctrl+up moves focus to the current tab
  13074 		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
  13075 			event.preventDefault();
  13076 			this.active.focus();
  13077 		}
  13078 	},
  13079 
  13080 	// Alt+page up/down moves focus to the previous/next tab (and activates)
  13081 	_handlePageNav: function( event ) {
  13082 		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
  13083 			this._activate( this._focusNextTab( this.options.active - 1, false ) );
  13084 			return true;
  13085 		}
  13086 		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
  13087 			this._activate( this._focusNextTab( this.options.active + 1, true ) );
  13088 			return true;
  13089 		}
  13090 	},
  13091 
  13092 	_findNextTab: function( index, goingForward ) {
  13093 		var lastTabIndex = this.tabs.length - 1;
  13094 
  13095 		function constrain() {
  13096 			if ( index > lastTabIndex ) {
  13097 				index = 0;
  13098 			}
  13099 			if ( index < 0 ) {
  13100 				index = lastTabIndex;
  13101 			}
  13102 			return index;
  13103 		}
  13104 
  13105 		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
  13106 			index = goingForward ? index + 1 : index - 1;
  13107 		}
  13108 
  13109 		return index;
  13110 	},
  13111 
  13112 	_focusNextTab: function( index, goingForward ) {
  13113 		index = this._findNextTab( index, goingForward );
  13114 		this.tabs.eq( index ).focus();
  13115 		return index;
  13116 	},
  13117 
  13118 	_setOption: function( key, value ) {
  13119 		if ( key === "active" ) {
  13120 			// _activate() will handle invalid values and update this.options
  13121 			this._activate( value );
  13122 			return;
  13123 		}
  13124 
  13125 		if ( key === "disabled" ) {
  13126 			// don't use the widget factory's disabled handling
  13127 			this._setupDisabled( value );
  13128 			return;
  13129 		}
  13130 
  13131 		this._super( key, value);
  13132 
  13133 		if ( key === "collapsible" ) {
  13134 			this.element.toggleClass( "ui-tabs-collapsible", value );
  13135 			// Setting collapsible: false while collapsed; open first panel
  13136 			if ( !value && this.options.active === false ) {
  13137 				this._activate( 0 );
  13138 			}
  13139 		}
  13140 
  13141 		if ( key === "event" ) {
  13142 			this._setupEvents( value );
  13143 		}
  13144 
  13145 		if ( key === "heightStyle" ) {
  13146 			this._setupHeightStyle( value );
  13147 		}
  13148 	},
  13149 
  13150 	_sanitizeSelector: function( hash ) {
  13151 		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
  13152 	},
  13153 
  13154 	refresh: function() {
  13155 		var options = this.options,
  13156 			lis = this.tablist.children( ":has(a[href])" );
  13157 
  13158 		// get disabled tabs from class attribute from HTML
  13159 		// this will get converted to a boolean if needed in _refresh()
  13160 		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
  13161 			return lis.index( tab );
  13162 		});
  13163 
  13164 		this._processTabs();
  13165 
  13166 		// was collapsed or no tabs
  13167 		if ( options.active === false || !this.anchors.length ) {
  13168 			options.active = false;
  13169 			this.active = $();
  13170 		// was active, but active tab is gone
  13171 		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
  13172 			// all remaining tabs are disabled
  13173 			if ( this.tabs.length === options.disabled.length ) {
  13174 				options.active = false;
  13175 				this.active = $();
  13176 			// activate previous tab
  13177 			} else {
  13178 				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
  13179 			}
  13180 		// was active, active tab still exists
  13181 		} else {
  13182 			// make sure active index is correct
  13183 			options.active = this.tabs.index( this.active );
  13184 		}
  13185 
  13186 		this._refresh();
  13187 	},
  13188 
  13189 	_refresh: function() {
  13190 		this._setupDisabled( this.options.disabled );
  13191 		this._setupEvents( this.options.event );
  13192 		this._setupHeightStyle( this.options.heightStyle );
  13193 
  13194 		this.tabs.not( this.active ).attr({
  13195 			"aria-selected": "false",
  13196 			"aria-expanded": "false",
  13197 			tabIndex: -1
  13198 		});
  13199 		this.panels.not( this._getPanelForTab( this.active ) )
  13200 			.hide()
  13201 			.attr({
  13202 				"aria-hidden": "true"
  13203 			});
  13204 
  13205 		// Make sure one tab is in the tab order
  13206 		if ( !this.active.length ) {
  13207 			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
  13208 		} else {
  13209 			this.active
  13210 				.addClass( "ui-tabs-active ui-state-active" )
  13211 				.attr({
  13212 					"aria-selected": "true",
  13213 					"aria-expanded": "true",
  13214 					tabIndex: 0
  13215 				});
  13216 			this._getPanelForTab( this.active )
  13217 				.show()
  13218 				.attr({
  13219 					"aria-hidden": "false"
  13220 				});
  13221 		}
  13222 	},
  13223 
  13224 	_processTabs: function() {
  13225 		var that = this,
  13226 			prevTabs = this.tabs,
  13227 			prevAnchors = this.anchors,
  13228 			prevPanels = this.panels;
  13229 
  13230 		this.tablist = this._getList()
  13231 			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
  13232 			.attr( "role", "tablist" )
  13233 
  13234 			// Prevent users from focusing disabled tabs via click
  13235 			.delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
  13236 				if ( $( this ).is( ".ui-state-disabled" ) ) {
  13237 					event.preventDefault();
  13238 				}
  13239 			})
  13240 
  13241 			// support: IE <9
  13242 			// Preventing the default action in mousedown doesn't prevent IE
  13243 			// from focusing the element, so if the anchor gets focused, blur.
  13244 			// We don't have to worry about focusing the previously focused
  13245 			// element since clicking on a non-focusable element should focus
  13246 			// the body anyway.
  13247 			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
  13248 				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
  13249 					this.blur();
  13250 				}
  13251 			});
  13252 
  13253 		this.tabs = this.tablist.find( "> li:has(a[href])" )
  13254 			.addClass( "ui-state-default ui-corner-top" )
  13255 			.attr({
  13256 				role: "tab",
  13257 				tabIndex: -1
  13258 			});
  13259 
  13260 		this.anchors = this.tabs.map(function() {
  13261 				return $( "a", this )[ 0 ];
  13262 			})
  13263 			.addClass( "ui-tabs-anchor" )
  13264 			.attr({
  13265 				role: "presentation",
  13266 				tabIndex: -1
  13267 			});
  13268 
  13269 		this.panels = $();
  13270 
  13271 		this.anchors.each(function( i, anchor ) {
  13272 			var selector, panel, panelId,
  13273 				anchorId = $( anchor ).uniqueId().attr( "id" ),
  13274 				tab = $( anchor ).closest( "li" ),
  13275 				originalAriaControls = tab.attr( "aria-controls" );
  13276 
  13277 			// inline tab
  13278 			if ( that._isLocal( anchor ) ) {
  13279 				selector = anchor.hash;
  13280 				panelId = selector.substring( 1 );
  13281 				panel = that.element.find( that._sanitizeSelector( selector ) );
  13282 			// remote tab
  13283 			} else {
  13284 				// If the tab doesn't already have aria-controls,
  13285 				// generate an id by using a throw-away element
  13286 				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
  13287 				selector = "#" + panelId;
  13288 				panel = that.element.find( selector );
  13289 				if ( !panel.length ) {
  13290 					panel = that._createPanel( panelId );
  13291 					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
  13292 				}
  13293 				panel.attr( "aria-live", "polite" );
  13294 			}
  13295 
  13296 			if ( panel.length) {
  13297 				that.panels = that.panels.add( panel );
  13298 			}
  13299 			if ( originalAriaControls ) {
  13300 				tab.data( "ui-tabs-aria-controls", originalAriaControls );
  13301 			}
  13302 			tab.attr({
  13303 				"aria-controls": panelId,
  13304 				"aria-labelledby": anchorId
  13305 			});
  13306 			panel.attr( "aria-labelledby", anchorId );
  13307 		});
  13308 
  13309 		this.panels
  13310 			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
  13311 			.attr( "role", "tabpanel" );
  13312 
  13313 		// Avoid memory leaks (#10056)
  13314 		if ( prevTabs ) {
  13315 			this._off( prevTabs.not( this.tabs ) );
  13316 			this._off( prevAnchors.not( this.anchors ) );
  13317 			this._off( prevPanels.not( this.panels ) );
  13318 		}
  13319 	},
  13320 
  13321 	// allow overriding how to find the list for rare usage scenarios (#7715)
  13322 	_getList: function() {
  13323 		return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
  13324 	},
  13325 
  13326 	_createPanel: function( id ) {
  13327 		return $( "<div>" )
  13328 			.attr( "id", id )
  13329 			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
  13330 			.data( "ui-tabs-destroy", true );
  13331 	},
  13332 
  13333 	_setupDisabled: function( disabled ) {
  13334 		if ( $.isArray( disabled ) ) {
  13335 			if ( !disabled.length ) {
  13336 				disabled = false;
  13337 			} else if ( disabled.length === this.anchors.length ) {
  13338 				disabled = true;
  13339 			}
  13340 		}
  13341 
  13342 		// disable tabs
  13343 		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
  13344 			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
  13345 				$( li )
  13346 					.addClass( "ui-state-disabled" )
  13347 					.attr( "aria-disabled", "true" );
  13348 			} else {
  13349 				$( li )
  13350 					.removeClass( "ui-state-disabled" )
  13351 					.removeAttr( "aria-disabled" );
  13352 			}
  13353 		}
  13354 
  13355 		this.options.disabled = disabled;
  13356 	},
  13357 
  13358 	_setupEvents: function( event ) {
  13359 		var events = {};
  13360 		if ( event ) {
  13361 			$.each( event.split(" "), function( index, eventName ) {
  13362 				events[ eventName ] = "_eventHandler";
  13363 			});
  13364 		}
  13365 
  13366 		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
  13367 		// Always prevent the default action, even when disabled
  13368 		this._on( true, this.anchors, {
  13369 			click: function( event ) {
  13370 				event.preventDefault();
  13371 			}
  13372 		});
  13373 		this._on( this.anchors, events );
  13374 		this._on( this.tabs, { keydown: "_tabKeydown" } );
  13375 		this._on( this.panels, { keydown: "_panelKeydown" } );
  13376 
  13377 		this._focusable( this.tabs );
  13378 		this._hoverable( this.tabs );
  13379 	},
  13380 
  13381 	_setupHeightStyle: function( heightStyle ) {
  13382 		var maxHeight,
  13383 			parent = this.element.parent();
  13384 
  13385 		if ( heightStyle === "fill" ) {
  13386 			maxHeight = parent.height();
  13387 			maxHeight -= this.element.outerHeight() - this.element.height();
  13388 
  13389 			this.element.siblings( ":visible" ).each(function() {
  13390 				var elem = $( this ),
  13391 					position = elem.css( "position" );
  13392 
  13393 				if ( position === "absolute" || position === "fixed" ) {
  13394 					return;
  13395 				}
  13396 				maxHeight -= elem.outerHeight( true );
  13397 			});
  13398 
  13399 			this.element.children().not( this.panels ).each(function() {
  13400 				maxHeight -= $( this ).outerHeight( true );
  13401 			});
  13402 
  13403 			this.panels.each(function() {
  13404 				$( this ).height( Math.max( 0, maxHeight -
  13405 					$( this ).innerHeight() + $( this ).height() ) );
  13406 			})
  13407 			.css( "overflow", "auto" );
  13408 		} else if ( heightStyle === "auto" ) {
  13409 			maxHeight = 0;
  13410 			this.panels.each(function() {
  13411 				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
  13412 			}).height( maxHeight );
  13413 		}
  13414 	},
  13415 
  13416 	_eventHandler: function( event ) {
  13417 		var options = this.options,
  13418 			active = this.active,
  13419 			anchor = $( event.currentTarget ),
  13420 			tab = anchor.closest( "li" ),
  13421 			clickedIsActive = tab[ 0 ] === active[ 0 ],
  13422 			collapsing = clickedIsActive && options.collapsible,
  13423 			toShow = collapsing ? $() : this._getPanelForTab( tab ),
  13424 			toHide = !active.length ? $() : this._getPanelForTab( active ),
  13425 			eventData = {
  13426 				oldTab: active,
  13427 				oldPanel: toHide,
  13428 				newTab: collapsing ? $() : tab,
  13429 				newPanel: toShow
  13430 			};
  13431 
  13432 		event.preventDefault();
  13433 
  13434 		if ( tab.hasClass( "ui-state-disabled" ) ||
  13435 				// tab is already loading
  13436 				tab.hasClass( "ui-tabs-loading" ) ||
  13437 				// can't switch durning an animation
  13438 				this.running ||
  13439 				// click on active header, but not collapsible
  13440 				( clickedIsActive && !options.collapsible ) ||
  13441 				// allow canceling activation
  13442 				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
  13443 			return;
  13444 		}
  13445 
  13446 		options.active = collapsing ? false : this.tabs.index( tab );
  13447 
  13448 		this.active = clickedIsActive ? $() : tab;
  13449 		if ( this.xhr ) {
  13450 			this.xhr.abort();
  13451 		}
  13452 
  13453 		if ( !toHide.length && !toShow.length ) {
  13454 			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
  13455 		}
  13456 
  13457 		if ( toShow.length ) {
  13458 			this.load( this.tabs.index( tab ), event );
  13459 		}
  13460 		this._toggle( event, eventData );
  13461 	},
  13462 
  13463 	// handles show/hide for selecting tabs
  13464 	_toggle: function( event, eventData ) {
  13465 		var that = this,
  13466 			toShow = eventData.newPanel,
  13467 			toHide = eventData.oldPanel;
  13468 
  13469 		this.running = true;
  13470 
  13471 		function complete() {
  13472 			that.running = false;
  13473 			that._trigger( "activate", event, eventData );
  13474 		}
  13475 
  13476 		function show() {
  13477 			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
  13478 
  13479 			if ( toShow.length && that.options.show ) {
  13480 				that._show( toShow, that.options.show, complete );
  13481 			} else {
  13482 				toShow.show();
  13483 				complete();
  13484 			}
  13485 		}
  13486 
  13487 		// start out by hiding, then showing, then completing
  13488 		if ( toHide.length && this.options.hide ) {
  13489 			this._hide( toHide, this.options.hide, function() {
  13490 				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  13491 				show();
  13492 			});
  13493 		} else {
  13494 			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
  13495 			toHide.hide();
  13496 			show();
  13497 		}
  13498 
  13499 		toHide.attr( "aria-hidden", "true" );
  13500 		eventData.oldTab.attr({
  13501 			"aria-selected": "false",
  13502 			"aria-expanded": "false"
  13503 		});
  13504 		// If we're switching tabs, remove the old tab from the tab order.
  13505 		// If we're opening from collapsed state, remove the previous tab from the tab order.
  13506 		// If we're collapsing, then keep the collapsing tab in the tab order.
  13507 		if ( toShow.length && toHide.length ) {
  13508 			eventData.oldTab.attr( "tabIndex", -1 );
  13509 		} else if ( toShow.length ) {
  13510 			this.tabs.filter(function() {
  13511 				return $( this ).attr( "tabIndex" ) === 0;
  13512 			})
  13513 			.attr( "tabIndex", -1 );
  13514 		}
  13515 
  13516 		toShow.attr( "aria-hidden", "false" );
  13517 		eventData.newTab.attr({
  13518 			"aria-selected": "true",
  13519 			"aria-expanded": "true",
  13520 			tabIndex: 0
  13521 		});
  13522 	},
  13523 
  13524 	_activate: function( index ) {
  13525 		var anchor,
  13526 			active = this._findActive( index );
  13527 
  13528 		// trying to activate the already active panel
  13529 		if ( active[ 0 ] === this.active[ 0 ] ) {
  13530 			return;
  13531 		}
  13532 
  13533 		// trying to collapse, simulate a click on the current active header
  13534 		if ( !active.length ) {
  13535 			active = this.active;
  13536 		}
  13537 
  13538 		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
  13539 		this._eventHandler({
  13540 			target: anchor,
  13541 			currentTarget: anchor,
  13542 			preventDefault: $.noop
  13543 		});
  13544 	},
  13545 
  13546 	_findActive: function( index ) {
  13547 		return index === false ? $() : this.tabs.eq( index );
  13548 	},
  13549 
  13550 	_getIndex: function( index ) {
  13551 		// meta-function to give users option to provide a href string instead of a numerical index.
  13552 		if ( typeof index === "string" ) {
  13553 			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
  13554 		}
  13555 
  13556 		return index;
  13557 	},
  13558 
  13559 	_destroy: function() {
  13560 		if ( this.xhr ) {
  13561 			this.xhr.abort();
  13562 		}
  13563 
  13564 		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
  13565 
  13566 		this.tablist
  13567 			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
  13568 			.removeAttr( "role" );
  13569 
  13570 		this.anchors
  13571 			.removeClass( "ui-tabs-anchor" )
  13572 			.removeAttr( "role" )
  13573 			.removeAttr( "tabIndex" )
  13574 			.removeUniqueId();
  13575 
  13576 		this.tablist.unbind( this.eventNamespace );
  13577 
  13578 		this.tabs.add( this.panels ).each(function() {
  13579 			if ( $.data( this, "ui-tabs-destroy" ) ) {
  13580 				$( this ).remove();
  13581 			} else {
  13582 				$( this )
  13583 					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
  13584 						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
  13585 					.removeAttr( "tabIndex" )
  13586 					.removeAttr( "aria-live" )
  13587 					.removeAttr( "aria-busy" )
  13588 					.removeAttr( "aria-selected" )
  13589 					.removeAttr( "aria-labelledby" )
  13590 					.removeAttr( "aria-hidden" )
  13591 					.removeAttr( "aria-expanded" )
  13592 					.removeAttr( "role" );
  13593 			}
  13594 		});
  13595 
  13596 		this.tabs.each(function() {
  13597 			var li = $( this ),
  13598 				prev = li.data( "ui-tabs-aria-controls" );
  13599 			if ( prev ) {
  13600 				li
  13601 					.attr( "aria-controls", prev )
  13602 					.removeData( "ui-tabs-aria-controls" );
  13603 			} else {
  13604 				li.removeAttr( "aria-controls" );
  13605 			}
  13606 		});
  13607 
  13608 		this.panels.show();
  13609 
  13610 		if ( this.options.heightStyle !== "content" ) {
  13611 			this.panels.css( "height", "" );
  13612 		}
  13613 	},
  13614 
  13615 	enable: function( index ) {
  13616 		var disabled = this.options.disabled;
  13617 		if ( disabled === false ) {
  13618 			return;
  13619 		}
  13620 
  13621 		if ( index === undefined ) {
  13622 			disabled = false;
  13623 		} else {
  13624 			index = this._getIndex( index );
  13625 			if ( $.isArray( disabled ) ) {
  13626 				disabled = $.map( disabled, function( num ) {
  13627 					return num !== index ? num : null;
  13628 				});
  13629 			} else {
  13630 				disabled = $.map( this.tabs, function( li, num ) {
  13631 					return num !== index ? num : null;
  13632 				});
  13633 			}
  13634 		}
  13635 		this._setupDisabled( disabled );
  13636 	},
  13637 
  13638 	disable: function( index ) {
  13639 		var disabled = this.options.disabled;
  13640 		if ( disabled === true ) {
  13641 			return;
  13642 		}
  13643 
  13644 		if ( index === undefined ) {
  13645 			disabled = true;
  13646 		} else {
  13647 			index = this._getIndex( index );
  13648 			if ( $.inArray( index, disabled ) !== -1 ) {
  13649 				return;
  13650 			}
  13651 			if ( $.isArray( disabled ) ) {
  13652 				disabled = $.merge( [ index ], disabled ).sort();
  13653 			} else {
  13654 				disabled = [ index ];
  13655 			}
  13656 		}
  13657 		this._setupDisabled( disabled );
  13658 	},
  13659 
  13660 	load: function( index, event ) {
  13661 		index = this._getIndex( index );
  13662 		var that = this,
  13663 			tab = this.tabs.eq( index ),
  13664 			anchor = tab.find( ".ui-tabs-anchor" ),
  13665 			panel = this._getPanelForTab( tab ),
  13666 			eventData = {
  13667 				tab: tab,
  13668 				panel: panel
  13669 			},
  13670 			complete = function( jqXHR, status ) {
  13671 				if ( status === "abort" ) {
  13672 					that.panels.stop( false, true );
  13673 				}
  13674 
  13675 				tab.removeClass( "ui-tabs-loading" );
  13676 				panel.removeAttr( "aria-busy" );
  13677 
  13678 				if ( jqXHR === that.xhr ) {
  13679 					delete that.xhr;
  13680 				}
  13681 			};
  13682 
  13683 		// not remote
  13684 		if ( this._isLocal( anchor[ 0 ] ) ) {
  13685 			return;
  13686 		}
  13687 
  13688 		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
  13689 
  13690 		// support: jQuery <1.8
  13691 		// jQuery <1.8 returns false if the request is canceled in beforeSend,
  13692 		// but as of 1.8, $.ajax() always returns a jqXHR object.
  13693 		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
  13694 			tab.addClass( "ui-tabs-loading" );
  13695 			panel.attr( "aria-busy", "true" );
  13696 
  13697 			this.xhr
  13698 				.done(function( response, status, jqXHR ) {
  13699 					// support: jQuery <1.8
  13700 					// http://bugs.jquery.com/ticket/11778
  13701 					setTimeout(function() {
  13702 						panel.html( response );
  13703 						that._trigger( "load", event, eventData );
  13704 
  13705 						complete( jqXHR, status );
  13706 					}, 1 );
  13707 				})
  13708 				.fail(function( jqXHR, status ) {
  13709 					// support: jQuery <1.8
  13710 					// http://bugs.jquery.com/ticket/11778
  13711 					setTimeout(function() {
  13712 						complete( jqXHR, status );
  13713 					}, 1 );
  13714 				});
  13715 		}
  13716 	},
  13717 
  13718 	_ajaxSettings: function( anchor, event, eventData ) {
  13719 		var that = this;
  13720 		return {
  13721 			url: anchor.attr( "href" ),
  13722 			beforeSend: function( jqXHR, settings ) {
  13723 				return that._trigger( "beforeLoad", event,
  13724 					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
  13725 			}
  13726 		};
  13727 	},
  13728 
  13729 	_getPanelForTab: function( tab ) {
  13730 		var id = $( tab ).attr( "aria-controls" );
  13731 		return this.element.find( this._sanitizeSelector( "#" + id ) );
  13732 	}
  13733 });
  13734 
  13735 
  13736 /*!
  13737  * jQuery UI Tooltip 1.11.4
  13738  * http://jqueryui.com
  13739  *
  13740  * Copyright jQuery Foundation and other contributors
  13741  * Released under the MIT license.
  13742  * http://jquery.org/license
  13743  *
  13744  * http://api.jqueryui.com/tooltip/
  13745  */
  13746 
  13747 
  13748 var tooltip = $.widget( "ui.tooltip", {
  13749 	version: "1.11.4",
  13750 	options: {
  13751 		content: function() {
  13752 			// support: IE<9, Opera in jQuery <1.7
  13753 			// .text() can't accept undefined, so coerce to a string
  13754 			var title = $( this ).attr( "title" ) || "";
  13755 			// Escape title, since we're going from an attribute to raw HTML
  13756 			return $( "<a>" ).text( title ).html();
  13757 		},
  13758 		hide: true,
  13759 		// Disabled elements have inconsistent behavior across browsers (#8661)
  13760 		items: "[title]:not([disabled])",
  13761 		position: {
  13762 			my: "left top+15",
  13763 			at: "left bottom",
  13764 			collision: "flipfit flip"
  13765 		},
  13766 		show: true,
  13767 		tooltipClass: null,
  13768 		track: false,
  13769 
  13770 		// callbacks
  13771 		close: null,
  13772 		open: null
  13773 	},
  13774 
  13775 	_addDescribedBy: function( elem, id ) {
  13776 		var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
  13777 		describedby.push( id );
  13778 		elem
  13779 			.data( "ui-tooltip-id", id )
  13780 			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
  13781 	},
  13782 
  13783 	_removeDescribedBy: function( elem ) {
  13784 		var id = elem.data( "ui-tooltip-id" ),
  13785 			describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
  13786 			index = $.inArray( id, describedby );
  13787 
  13788 		if ( index !== -1 ) {
  13789 			describedby.splice( index, 1 );
  13790 		}
  13791 
  13792 		elem.removeData( "ui-tooltip-id" );
  13793 		describedby = $.trim( describedby.join( " " ) );
  13794 		if ( describedby ) {
  13795 			elem.attr( "aria-describedby", describedby );
  13796 		} else {
  13797 			elem.removeAttr( "aria-describedby" );
  13798 		}
  13799 	},
  13800 
  13801 	_create: function() {
  13802 		this._on({
  13803 			mouseover: "open",
  13804 			focusin: "open"
  13805 		});
  13806 
  13807 		// IDs of generated tooltips, needed for destroy
  13808 		this.tooltips = {};
  13809 
  13810 		// IDs of parent tooltips where we removed the title attribute
  13811 		this.parents = {};
  13812 
  13813 		if ( this.options.disabled ) {
  13814 			this._disable();
  13815 		}
  13816 
  13817 		// Append the aria-live region so tooltips announce correctly
  13818 		this.liveRegion = $( "<div>" )
  13819 			.attr({
  13820 				role: "log",
  13821 				"aria-live": "assertive",
  13822 				"aria-relevant": "additions"
  13823 			})
  13824 			.addClass( "ui-helper-hidden-accessible" )
  13825 			.appendTo( this.document[ 0 ].body );
  13826 	},
  13827 
  13828 	_setOption: function( key, value ) {
  13829 		var that = this;
  13830 
  13831 		if ( key === "disabled" ) {
  13832 			this[ value ? "_disable" : "_enable" ]();
  13833 			this.options[ key ] = value;
  13834 			// disable element style changes
  13835 			return;
  13836 		}
  13837 
  13838 		this._super( key, value );
  13839 
  13840 		if ( key === "content" ) {
  13841 			$.each( this.tooltips, function( id, tooltipData ) {
  13842 				that._updateContent( tooltipData.element );
  13843 			});
  13844 		}
  13845 	},
  13846 
  13847 	_disable: function() {
  13848 		var that = this;
  13849 
  13850 		// close open tooltips
  13851 		$.each( this.tooltips, function( id, tooltipData ) {
  13852 			var event = $.Event( "blur" );
  13853 			event.target = event.currentTarget = tooltipData.element[ 0 ];
  13854 			that.close( event, true );
  13855 		});
  13856 
  13857 		// remove title attributes to prevent native tooltips
  13858 		this.element.find( this.options.items ).addBack().each(function() {
  13859 			var element = $( this );
  13860 			if ( element.is( "[title]" ) ) {
  13861 				element
  13862 					.data( "ui-tooltip-title", element.attr( "title" ) )
  13863 					.removeAttr( "title" );
  13864 			}
  13865 		});
  13866 	},
  13867 
  13868 	_enable: function() {
  13869 		// restore title attributes
  13870 		this.element.find( this.options.items ).addBack().each(function() {
  13871 			var element = $( this );
  13872 			if ( element.data( "ui-tooltip-title" ) ) {
  13873 				element.attr( "title", element.data( "ui-tooltip-title" ) );
  13874 			}
  13875 		});
  13876 	},
  13877 
  13878 	open: function( event ) {
  13879 		var that = this,
  13880 			target = $( event ? event.target : this.element )
  13881 				// we need closest here due to mouseover bubbling,
  13882 				// but always pointing at the same event target
  13883 				.closest( this.options.items );
  13884 
  13885 		// No element to show a tooltip for or the tooltip is already open
  13886 		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
  13887 			return;
  13888 		}
  13889 
  13890 		if ( target.attr( "title" ) ) {
  13891 			target.data( "ui-tooltip-title", target.attr( "title" ) );
  13892 		}
  13893 
  13894 		target.data( "ui-tooltip-open", true );
  13895 
  13896 		// kill parent tooltips, custom or native, for hover
  13897 		if ( event && event.type === "mouseover" ) {
  13898 			target.parents().each(function() {
  13899 				var parent = $( this ),
  13900 					blurEvent;
  13901 				if ( parent.data( "ui-tooltip-open" ) ) {
  13902 					blurEvent = $.Event( "blur" );
  13903 					blurEvent.target = blurEvent.currentTarget = this;
  13904 					that.close( blurEvent, true );
  13905 				}
  13906 				if ( parent.attr( "title" ) ) {
  13907 					parent.uniqueId();
  13908 					that.parents[ this.id ] = {
  13909 						element: this,
  13910 						title: parent.attr( "title" )
  13911 					};
  13912 					parent.attr( "title", "" );
  13913 				}
  13914 			});
  13915 		}
  13916 
  13917 		this._registerCloseHandlers( event, target );
  13918 		this._updateContent( target, event );
  13919 	},
  13920 
  13921 	_updateContent: function( target, event ) {
  13922 		var content,
  13923 			contentOption = this.options.content,
  13924 			that = this,
  13925 			eventType = event ? event.type : null;
  13926 
  13927 		if ( typeof contentOption === "string" ) {
  13928 			return this._open( event, target, contentOption );
  13929 		}
  13930 
  13931 		content = contentOption.call( target[0], function( response ) {
  13932 
  13933 			// IE may instantly serve a cached response for ajax requests
  13934 			// delay this call to _open so the other call to _open runs first
  13935 			that._delay(function() {
  13936 
  13937 				// Ignore async response if tooltip was closed already
  13938 				if ( !target.data( "ui-tooltip-open" ) ) {
  13939 					return;
  13940 				}
  13941 
  13942 				// jQuery creates a special event for focusin when it doesn't
  13943 				// exist natively. To improve performance, the native event
  13944 				// object is reused and the type is changed. Therefore, we can't
  13945 				// rely on the type being correct after the event finished
  13946 				// bubbling, so we set it back to the previous value. (#8740)
  13947 				if ( event ) {
  13948 					event.type = eventType;
  13949 				}
  13950 				this._open( event, target, response );
  13951 			});
  13952 		});
  13953 		if ( content ) {
  13954 			this._open( event, target, content );
  13955 		}
  13956 	},
  13957 
  13958 	_open: function( event, target, content ) {
  13959 		var tooltipData, tooltip, delayedShow, a11yContent,
  13960 			positionOption = $.extend( {}, this.options.position );
  13961 
  13962 		if ( !content ) {
  13963 			return;
  13964 		}
  13965 
  13966 		// Content can be updated multiple times. If the tooltip already
  13967 		// exists, then just update the content and bail.
  13968 		tooltipData = this._find( target );
  13969 		if ( tooltipData ) {
  13970 			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
  13971 			return;
  13972 		}
  13973 
  13974 		// if we have a title, clear it to prevent the native tooltip
  13975 		// we have to check first to avoid defining a title if none exists
  13976 		// (we don't want to cause an element to start matching [title])
  13977 		//
  13978 		// We use removeAttr only for key events, to allow IE to export the correct
  13979 		// accessible attributes. For mouse events, set to empty string to avoid
  13980 		// native tooltip showing up (happens only when removing inside mouseover).
  13981 		if ( target.is( "[title]" ) ) {
  13982 			if ( event && event.type === "mouseover" ) {
  13983 				target.attr( "title", "" );
  13984 			} else {
  13985 				target.removeAttr( "title" );
  13986 			}
  13987 		}
  13988 
  13989 		tooltipData = this._tooltip( target );
  13990 		tooltip = tooltipData.tooltip;
  13991 		this._addDescribedBy( target, tooltip.attr( "id" ) );
  13992 		tooltip.find( ".ui-tooltip-content" ).html( content );
  13993 
  13994 		// Support: Voiceover on OS X, JAWS on IE <= 9
  13995 		// JAWS announces deletions even when aria-relevant="additions"
  13996 		// Voiceover will sometimes re-read the entire log region's contents from the beginning
  13997 		this.liveRegion.children().hide();
  13998 		if ( content.clone ) {
  13999 			a11yContent = content.clone();
  14000 			a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
  14001 		} else {
  14002 			a11yContent = content;
  14003 		}
  14004 		$( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
  14005 
  14006 		function position( event ) {
  14007 			positionOption.of = event;
  14008 			if ( tooltip.is( ":hidden" ) ) {
  14009 				return;
  14010 			}
  14011 			tooltip.position( positionOption );
  14012 		}
  14013 		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
  14014 			this._on( this.document, {
  14015 				mousemove: position
  14016 			});
  14017 			// trigger once to override element-relative positioning
  14018 			position( event );
  14019 		} else {
  14020 			tooltip.position( $.extend({
  14021 				of: target
  14022 			}, this.options.position ) );
  14023 		}
  14024 
  14025 		tooltip.hide();
  14026 
  14027 		this._show( tooltip, this.options.show );
  14028 		// Handle tracking tooltips that are shown with a delay (#8644). As soon
  14029 		// as the tooltip is visible, position the tooltip using the most recent
  14030 		// event.
  14031 		if ( this.options.show && this.options.show.delay ) {
  14032 			delayedShow = this.delayedShow = setInterval(function() {
  14033 				if ( tooltip.is( ":visible" ) ) {
  14034 					position( positionOption.of );
  14035 					clearInterval( delayedShow );
  14036 				}
  14037 			}, $.fx.interval );
  14038 		}
  14039 
  14040 		this._trigger( "open", event, { tooltip: tooltip } );
  14041 	},
  14042 
  14043 	_registerCloseHandlers: function( event, target ) {
  14044 		var events = {
  14045 			keyup: function( event ) {
  14046 				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
  14047 					var fakeEvent = $.Event(event);
  14048 					fakeEvent.currentTarget = target[0];
  14049 					this.close( fakeEvent, true );
  14050 				}
  14051 			}
  14052 		};
  14053 
  14054 		// Only bind remove handler for delegated targets. Non-delegated
  14055 		// tooltips will handle this in destroy.
  14056 		if ( target[ 0 ] !== this.element[ 0 ] ) {
  14057 			events.remove = function() {
  14058 				this._removeTooltip( this._find( target ).tooltip );
  14059 			};
  14060 		}
  14061 
  14062 		if ( !event || event.type === "mouseover" ) {
  14063 			events.mouseleave = "close";
  14064 		}
  14065 		if ( !event || event.type === "focusin" ) {
  14066 			events.focusout = "close";
  14067 		}
  14068 		this._on( true, target, events );
  14069 	},
  14070 
  14071 	close: function( event ) {
  14072 		var tooltip,
  14073 			that = this,
  14074 			target = $( event ? event.currentTarget : this.element ),
  14075 			tooltipData = this._find( target );
  14076 
  14077 		// The tooltip may already be closed
  14078 		if ( !tooltipData ) {
  14079 
  14080 			// We set ui-tooltip-open immediately upon open (in open()), but only set the
  14081 			// additional data once there's actually content to show (in _open()). So even if the
  14082 			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
  14083 			// the period between open() and _open().
  14084 			target.removeData( "ui-tooltip-open" );
  14085 			return;
  14086 		}
  14087 
  14088 		tooltip = tooltipData.tooltip;
  14089 
  14090 		// disabling closes the tooltip, so we need to track when we're closing
  14091 		// to avoid an infinite loop in case the tooltip becomes disabled on close
  14092 		if ( tooltipData.closing ) {
  14093 			return;
  14094 		}
  14095 
  14096 		// Clear the interval for delayed tracking tooltips
  14097 		clearInterval( this.delayedShow );
  14098 
  14099 		// only set title if we had one before (see comment in _open())
  14100 		// If the title attribute has changed since open(), don't restore
  14101 		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
  14102 			target.attr( "title", target.data( "ui-tooltip-title" ) );
  14103 		}
  14104 
  14105 		this._removeDescribedBy( target );
  14106 
  14107 		tooltipData.hiding = true;
  14108 		tooltip.stop( true );
  14109 		this._hide( tooltip, this.options.hide, function() {
  14110 			that._removeTooltip( $( this ) );
  14111 		});
  14112 
  14113 		target.removeData( "ui-tooltip-open" );
  14114 		this._off( target, "mouseleave focusout keyup" );
  14115 
  14116 		// Remove 'remove' binding only on delegated targets
  14117 		if ( target[ 0 ] !== this.element[ 0 ] ) {
  14118 			this._off( target, "remove" );
  14119 		}
  14120 		this._off( this.document, "mousemove" );
  14121 
  14122 		if ( event && event.type === "mouseleave" ) {
  14123 			$.each( this.parents, function( id, parent ) {
  14124 				$( parent.element ).attr( "title", parent.title );
  14125 				delete that.parents[ id ];
  14126 			});
  14127 		}
  14128 
  14129 		tooltipData.closing = true;
  14130 		this._trigger( "close", event, { tooltip: tooltip } );
  14131 		if ( !tooltipData.hiding ) {
  14132 			tooltipData.closing = false;
  14133 		}
  14134 	},
  14135 
  14136 	_tooltip: function( element ) {
  14137 		var tooltip = $( "<div>" )
  14138 				.attr( "role", "tooltip" )
  14139 				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
  14140 					( this.options.tooltipClass || "" ) ),
  14141 			id = tooltip.uniqueId().attr( "id" );
  14142 
  14143 		$( "<div>" )
  14144 			.addClass( "ui-tooltip-content" )
  14145 			.appendTo( tooltip );
  14146 
  14147 		tooltip.appendTo( this.document[0].body );
  14148 
  14149 		return this.tooltips[ id ] = {
  14150 			element: element,
  14151 			tooltip: tooltip
  14152 		};
  14153 	},
  14154 
  14155 	_find: function( target ) {
  14156 		var id = target.data( "ui-tooltip-id" );
  14157 		return id ? this.tooltips[ id ] : null;
  14158 	},
  14159 
  14160 	_removeTooltip: function( tooltip ) {
  14161 		tooltip.remove();
  14162 		delete this.tooltips[ tooltip.attr( "id" ) ];
  14163 	},
  14164 
  14165 	_destroy: function() {
  14166 		var that = this;
  14167 
  14168 		// close open tooltips
  14169 		$.each( this.tooltips, function( id, tooltipData ) {
  14170 			// Delegate to close method to handle common cleanup
  14171 			var event = $.Event( "blur" ),
  14172 				element = tooltipData.element;
  14173 			event.target = event.currentTarget = element[ 0 ];
  14174 			that.close( event, true );
  14175 
  14176 			// Remove immediately; destroying an open tooltip doesn't use the
  14177 			// hide animation
  14178 			$( "#" + id ).remove();
  14179 
  14180 			// Restore the title
  14181 			if ( element.data( "ui-tooltip-title" ) ) {
  14182 				// If the title attribute has changed since open(), don't restore
  14183 				if ( !element.attr( "title" ) ) {
  14184 					element.attr( "title", element.data( "ui-tooltip-title" ) );
  14185 				}
  14186 				element.removeData( "ui-tooltip-title" );
  14187 			}
  14188 		});
  14189 		this.liveRegion.remove();
  14190 	}
  14191 });
  14192 
  14193 
  14194 /*!
  14195  * jQuery UI Effects 1.11.4
  14196  * http://jqueryui.com
  14197  *
  14198  * Copyright jQuery Foundation and other contributors
  14199  * Released under the MIT license.
  14200  * http://jquery.org/license
  14201  *
  14202  * http://api.jqueryui.com/category/effects-core/
  14203  */
  14204 
  14205 
  14206 var dataSpace = "ui-effects-",
  14207 
  14208 	// Create a local jQuery because jQuery Color relies on it and the
  14209 	// global may not exist with AMD and a custom build (#10199)
  14210 	jQuery = $;
  14211 
  14212 $.effects = {
  14213 	effect: {}
  14214 };
  14215 
  14216 /*!
  14217  * jQuery Color Animations v2.1.2
  14218  * https://github.com/jquery/jquery-color
  14219  *
  14220  * Copyright 2014 jQuery Foundation and other contributors
  14221  * Released under the MIT license.
  14222  * http://jquery.org/license
  14223  *
  14224  * Date: Wed Jan 16 08:47:09 2013 -0600
  14225  */
  14226 (function( jQuery, undefined ) {
  14227 
  14228 	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
  14229 
  14230 	// plusequals test for += 100 -= 100
  14231 	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
  14232 	// a set of RE's that can match strings and generate color tuples.
  14233 	stringParsers = [ {
  14234 			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  14235 			parse: function( execResult ) {
  14236 				return [
  14237 					execResult[ 1 ],
  14238 					execResult[ 2 ],
  14239 					execResult[ 3 ],
  14240 					execResult[ 4 ]
  14241 				];
  14242 			}
  14243 		}, {
  14244 			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  14245 			parse: function( execResult ) {
  14246 				return [
  14247 					execResult[ 1 ] * 2.55,
  14248 					execResult[ 2 ] * 2.55,
  14249 					execResult[ 3 ] * 2.55,
  14250 					execResult[ 4 ]
  14251 				];
  14252 			}
  14253 		}, {
  14254 			// this regex ignores A-F because it's compared against an already lowercased string
  14255 			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
  14256 			parse: function( execResult ) {
  14257 				return [
  14258 					parseInt( execResult[ 1 ], 16 ),
  14259 					parseInt( execResult[ 2 ], 16 ),
  14260 					parseInt( execResult[ 3 ], 16 )
  14261 				];
  14262 			}
  14263 		}, {
  14264 			// this regex ignores A-F because it's compared against an already lowercased string
  14265 			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
  14266 			parse: function( execResult ) {
  14267 				return [
  14268 					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
  14269 					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
  14270 					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
  14271 				];
  14272 			}
  14273 		}, {
  14274 			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  14275 			space: "hsla",
  14276 			parse: function( execResult ) {
  14277 				return [
  14278 					execResult[ 1 ],
  14279 					execResult[ 2 ] / 100,
  14280 					execResult[ 3 ] / 100,
  14281 					execResult[ 4 ]
  14282 				];
  14283 			}
  14284 		} ],
  14285 
  14286 	// jQuery.Color( )
  14287 	color = jQuery.Color = function( color, green, blue, alpha ) {
  14288 		return new jQuery.Color.fn.parse( color, green, blue, alpha );
  14289 	},
  14290 	spaces = {
  14291 		rgba: {
  14292 			props: {
  14293 				red: {
  14294 					idx: 0,
  14295 					type: "byte"
  14296 				},
  14297 				green: {
  14298 					idx: 1,
  14299 					type: "byte"
  14300 				},
  14301 				blue: {
  14302 					idx: 2,
  14303 					type: "byte"
  14304 				}
  14305 			}
  14306 		},
  14307 
  14308 		hsla: {
  14309 			props: {
  14310 				hue: {
  14311 					idx: 0,
  14312 					type: "degrees"
  14313 				},
  14314 				saturation: {
  14315 					idx: 1,
  14316 					type: "percent"
  14317 				},
  14318 				lightness: {
  14319 					idx: 2,
  14320 					type: "percent"
  14321 				}
  14322 			}
  14323 		}
  14324 	},
  14325 	propTypes = {
  14326 		"byte": {
  14327 			floor: true,
  14328 			max: 255
  14329 		},
  14330 		"percent": {
  14331 			max: 1
  14332 		},
  14333 		"degrees": {
  14334 			mod: 360,
  14335 			floor: true
  14336 		}
  14337 	},
  14338 	support = color.support = {},
  14339 
  14340 	// element for support tests
  14341 	supportElem = jQuery( "<p>" )[ 0 ],
  14342 
  14343 	// colors = jQuery.Color.names
  14344 	colors,
  14345 
  14346 	// local aliases of functions called often
  14347 	each = jQuery.each;
  14348 
  14349 // determine rgba support immediately
  14350 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
  14351 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
  14352 
  14353 // define cache name and alpha properties
  14354 // for rgba and hsla spaces
  14355 each( spaces, function( spaceName, space ) {
  14356 	space.cache = "_" + spaceName;
  14357 	space.props.alpha = {
  14358 		idx: 3,
  14359 		type: "percent",
  14360 		def: 1
  14361 	};
  14362 });
  14363 
  14364 function clamp( value, prop, allowEmpty ) {
  14365 	var type = propTypes[ prop.type ] || {};
  14366 
  14367 	if ( value == null ) {
  14368 		return (allowEmpty || !prop.def) ? null : prop.def;
  14369 	}
  14370 
  14371 	// ~~ is an short way of doing floor for positive numbers
  14372 	value = type.floor ? ~~value : parseFloat( value );
  14373 
  14374 	// IE will pass in empty strings as value for alpha,
  14375 	// which will hit this case
  14376 	if ( isNaN( value ) ) {
  14377 		return prop.def;
  14378 	}
  14379 
  14380 	if ( type.mod ) {
  14381 		// we add mod before modding to make sure that negatives values
  14382 		// get converted properly: -10 -> 350
  14383 		return (value + type.mod) % type.mod;
  14384 	}
  14385 
  14386 	// for now all property types without mod have min and max
  14387 	return 0 > value ? 0 : type.max < value ? type.max : value;
  14388 }
  14389 
  14390 function stringParse( string ) {
  14391 	var inst = color(),
  14392 		rgba = inst._rgba = [];
  14393 
  14394 	string = string.toLowerCase();
  14395 
  14396 	each( stringParsers, function( i, parser ) {
  14397 		var parsed,
  14398 			match = parser.re.exec( string ),
  14399 			values = match && parser.parse( match ),
  14400 			spaceName = parser.space || "rgba";
  14401 
  14402 		if ( values ) {
  14403 			parsed = inst[ spaceName ]( values );
  14404 
  14405 			// if this was an rgba parse the assignment might happen twice
  14406 			// oh well....
  14407 			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
  14408 			rgba = inst._rgba = parsed._rgba;
  14409 
  14410 			// exit each( stringParsers ) here because we matched
  14411 			return false;
  14412 		}
  14413 	});
  14414 
  14415 	// Found a stringParser that handled it
  14416 	if ( rgba.length ) {
  14417 
  14418 		// if this came from a parsed string, force "transparent" when alpha is 0
  14419 		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
  14420 		if ( rgba.join() === "0,0,0,0" ) {
  14421 			jQuery.extend( rgba, colors.transparent );
  14422 		}
  14423 		return inst;
  14424 	}
  14425 
  14426 	// named colors
  14427 	return colors[ string ];
  14428 }
  14429 
  14430 color.fn = jQuery.extend( color.prototype, {
  14431 	parse: function( red, green, blue, alpha ) {
  14432 		if ( red === undefined ) {
  14433 			this._rgba = [ null, null, null, null ];
  14434 			return this;
  14435 		}
  14436 		if ( red.jquery || red.nodeType ) {
  14437 			red = jQuery( red ).css( green );
  14438 			green = undefined;
  14439 		}
  14440 
  14441 		var inst = this,
  14442 			type = jQuery.type( red ),
  14443 			rgba = this._rgba = [];
  14444 
  14445 		// more than 1 argument specified - assume ( red, green, blue, alpha )
  14446 		if ( green !== undefined ) {
  14447 			red = [ red, green, blue, alpha ];
  14448 			type = "array";
  14449 		}
  14450 
  14451 		if ( type === "string" ) {
  14452 			return this.parse( stringParse( red ) || colors._default );
  14453 		}
  14454 
  14455 		if ( type === "array" ) {
  14456 			each( spaces.rgba.props, function( key, prop ) {
  14457 				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
  14458 			});
  14459 			return this;
  14460 		}
  14461 
  14462 		if ( type === "object" ) {
  14463 			if ( red instanceof color ) {
  14464 				each( spaces, function( spaceName, space ) {
  14465 					if ( red[ space.cache ] ) {
  14466 						inst[ space.cache ] = red[ space.cache ].slice();
  14467 					}
  14468 				});
  14469 			} else {
  14470 				each( spaces, function( spaceName, space ) {
  14471 					var cache = space.cache;
  14472 					each( space.props, function( key, prop ) {
  14473 
  14474 						// if the cache doesn't exist, and we know how to convert
  14475 						if ( !inst[ cache ] && space.to ) {
  14476 
  14477 							// if the value was null, we don't need to copy it
  14478 							// if the key was alpha, we don't need to copy it either
  14479 							if ( key === "alpha" || red[ key ] == null ) {
  14480 								return;
  14481 							}
  14482 							inst[ cache ] = space.to( inst._rgba );
  14483 						}
  14484 
  14485 						// this is the only case where we allow nulls for ALL properties.
  14486 						// call clamp with alwaysAllowEmpty
  14487 						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
  14488 					});
  14489 
  14490 					// everything defined but alpha?
  14491 					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
  14492 						// use the default of 1
  14493 						inst[ cache ][ 3 ] = 1;
  14494 						if ( space.from ) {
  14495 							inst._rgba = space.from( inst[ cache ] );
  14496 						}
  14497 					}
  14498 				});
  14499 			}
  14500 			return this;
  14501 		}
  14502 	},
  14503 	is: function( compare ) {
  14504 		var is = color( compare ),
  14505 			same = true,
  14506 			inst = this;
  14507 
  14508 		each( spaces, function( _, space ) {
  14509 			var localCache,
  14510 				isCache = is[ space.cache ];
  14511 			if (isCache) {
  14512 				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
  14513 				each( space.props, function( _, prop ) {
  14514 					if ( isCache[ prop.idx ] != null ) {
  14515 						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
  14516 						return same;
  14517 					}
  14518 				});
  14519 			}
  14520 			return same;
  14521 		});
  14522 		return same;
  14523 	},
  14524 	_space: function() {
  14525 		var used = [],
  14526 			inst = this;
  14527 		each( spaces, function( spaceName, space ) {
  14528 			if ( inst[ space.cache ] ) {
  14529 				used.push( spaceName );
  14530 			}
  14531 		});
  14532 		return used.pop();
  14533 	},
  14534 	transition: function( other, distance ) {
  14535 		var end = color( other ),
  14536 			spaceName = end._space(),
  14537 			space = spaces[ spaceName ],
  14538 			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
  14539 			start = startColor[ space.cache ] || space.to( startColor._rgba ),
  14540 			result = start.slice();
  14541 
  14542 		end = end[ space.cache ];
  14543 		each( space.props, function( key, prop ) {
  14544 			var index = prop.idx,
  14545 				startValue = start[ index ],
  14546 				endValue = end[ index ],
  14547 				type = propTypes[ prop.type ] || {};
  14548 
  14549 			// if null, don't override start value
  14550 			if ( endValue === null ) {
  14551 				return;
  14552 			}
  14553 			// if null - use end
  14554 			if ( startValue === null ) {
  14555 				result[ index ] = endValue;
  14556 			} else {
  14557 				if ( type.mod ) {
  14558 					if ( endValue - startValue > type.mod / 2 ) {
  14559 						startValue += type.mod;
  14560 					} else if ( startValue - endValue > type.mod / 2 ) {
  14561 						startValue -= type.mod;
  14562 					}
  14563 				}
  14564 				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
  14565 			}
  14566 		});
  14567 		return this[ spaceName ]( result );
  14568 	},
  14569 	blend: function( opaque ) {
  14570 		// if we are already opaque - return ourself
  14571 		if ( this._rgba[ 3 ] === 1 ) {
  14572 			return this;
  14573 		}
  14574 
  14575 		var rgb = this._rgba.slice(),
  14576 			a = rgb.pop(),
  14577 			blend = color( opaque )._rgba;
  14578 
  14579 		return color( jQuery.map( rgb, function( v, i ) {
  14580 			return ( 1 - a ) * blend[ i ] + a * v;
  14581 		}));
  14582 	},
  14583 	toRgbaString: function() {
  14584 		var prefix = "rgba(",
  14585 			rgba = jQuery.map( this._rgba, function( v, i ) {
  14586 				return v == null ? ( i > 2 ? 1 : 0 ) : v;
  14587 			});
  14588 
  14589 		if ( rgba[ 3 ] === 1 ) {
  14590 			rgba.pop();
  14591 			prefix = "rgb(";
  14592 		}
  14593 
  14594 		return prefix + rgba.join() + ")";
  14595 	},
  14596 	toHslaString: function() {
  14597 		var prefix = "hsla(",
  14598 			hsla = jQuery.map( this.hsla(), function( v, i ) {
  14599 				if ( v == null ) {
  14600 					v = i > 2 ? 1 : 0;
  14601 				}
  14602 
  14603 				// catch 1 and 2
  14604 				if ( i && i < 3 ) {
  14605 					v = Math.round( v * 100 ) + "%";
  14606 				}
  14607 				return v;
  14608 			});
  14609 
  14610 		if ( hsla[ 3 ] === 1 ) {
  14611 			hsla.pop();
  14612 			prefix = "hsl(";
  14613 		}
  14614 		return prefix + hsla.join() + ")";
  14615 	},
  14616 	toHexString: function( includeAlpha ) {
  14617 		var rgba = this._rgba.slice(),
  14618 			alpha = rgba.pop();
  14619 
  14620 		if ( includeAlpha ) {
  14621 			rgba.push( ~~( alpha * 255 ) );
  14622 		}
  14623 
  14624 		return "#" + jQuery.map( rgba, function( v ) {
  14625 
  14626 			// default to 0 when nulls exist
  14627 			v = ( v || 0 ).toString( 16 );
  14628 			return v.length === 1 ? "0" + v : v;
  14629 		}).join("");
  14630 	},
  14631 	toString: function() {
  14632 		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
  14633 	}
  14634 });
  14635 color.fn.parse.prototype = color.fn;
  14636 
  14637 // hsla conversions adapted from:
  14638 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
  14639 
  14640 function hue2rgb( p, q, h ) {
  14641 	h = ( h + 1 ) % 1;
  14642 	if ( h * 6 < 1 ) {
  14643 		return p + ( q - p ) * h * 6;
  14644 	}
  14645 	if ( h * 2 < 1) {
  14646 		return q;
  14647 	}
  14648 	if ( h * 3 < 2 ) {
  14649 		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
  14650 	}
  14651 	return p;
  14652 }
  14653 
  14654 spaces.hsla.to = function( rgba ) {
  14655 	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
  14656 		return [ null, null, null, rgba[ 3 ] ];
  14657 	}
  14658 	var r = rgba[ 0 ] / 255,
  14659 		g = rgba[ 1 ] / 255,
  14660 		b = rgba[ 2 ] / 255,
  14661 		a = rgba[ 3 ],
  14662 		max = Math.max( r, g, b ),
  14663 		min = Math.min( r, g, b ),
  14664 		diff = max - min,
  14665 		add = max + min,
  14666 		l = add * 0.5,
  14667 		h, s;
  14668 
  14669 	if ( min === max ) {
  14670 		h = 0;
  14671 	} else if ( r === max ) {
  14672 		h = ( 60 * ( g - b ) / diff ) + 360;
  14673 	} else if ( g === max ) {
  14674 		h = ( 60 * ( b - r ) / diff ) + 120;
  14675 	} else {
  14676 		h = ( 60 * ( r - g ) / diff ) + 240;
  14677 	}
  14678 
  14679 	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
  14680 	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
  14681 	if ( diff === 0 ) {
  14682 		s = 0;
  14683 	} else if ( l <= 0.5 ) {
  14684 		s = diff / add;
  14685 	} else {
  14686 		s = diff / ( 2 - add );
  14687 	}
  14688 	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
  14689 };
  14690 
  14691 spaces.hsla.from = function( hsla ) {
  14692 	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
  14693 		return [ null, null, null, hsla[ 3 ] ];
  14694 	}
  14695 	var h = hsla[ 0 ] / 360,
  14696 		s = hsla[ 1 ],
  14697 		l = hsla[ 2 ],
  14698 		a = hsla[ 3 ],
  14699 		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
  14700 		p = 2 * l - q;
  14701 
  14702 	return [
  14703 		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
  14704 		Math.round( hue2rgb( p, q, h ) * 255 ),
  14705 		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
  14706 		a
  14707 	];
  14708 };
  14709 
  14710 each( spaces, function( spaceName, space ) {
  14711 	var props = space.props,
  14712 		cache = space.cache,
  14713 		to = space.to,
  14714 		from = space.from;
  14715 
  14716 	// makes rgba() and hsla()
  14717 	color.fn[ spaceName ] = function( value ) {
  14718 
  14719 		// generate a cache for this space if it doesn't exist
  14720 		if ( to && !this[ cache ] ) {
  14721 			this[ cache ] = to( this._rgba );
  14722 		}
  14723 		if ( value === undefined ) {
  14724 			return this[ cache ].slice();
  14725 		}
  14726 
  14727 		var ret,
  14728 			type = jQuery.type( value ),
  14729 			arr = ( type === "array" || type === "object" ) ? value : arguments,
  14730 			local = this[ cache ].slice();
  14731 
  14732 		each( props, function( key, prop ) {
  14733 			var val = arr[ type === "object" ? key : prop.idx ];
  14734 			if ( val == null ) {
  14735 				val = local[ prop.idx ];
  14736 			}
  14737 			local[ prop.idx ] = clamp( val, prop );
  14738 		});
  14739 
  14740 		if ( from ) {
  14741 			ret = color( from( local ) );
  14742 			ret[ cache ] = local;
  14743 			return ret;
  14744 		} else {
  14745 			return color( local );
  14746 		}
  14747 	};
  14748 
  14749 	// makes red() green() blue() alpha() hue() saturation() lightness()
  14750 	each( props, function( key, prop ) {
  14751 		// alpha is included in more than one space
  14752 		if ( color.fn[ key ] ) {
  14753 			return;
  14754 		}
  14755 		color.fn[ key ] = function( value ) {
  14756 			var vtype = jQuery.type( value ),
  14757 				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
  14758 				local = this[ fn ](),
  14759 				cur = local[ prop.idx ],
  14760 				match;
  14761 
  14762 			if ( vtype === "undefined" ) {
  14763 				return cur;
  14764 			}
  14765 
  14766 			if ( vtype === "function" ) {
  14767 				value = value.call( this, cur );
  14768 				vtype = jQuery.type( value );
  14769 			}
  14770 			if ( value == null && prop.empty ) {
  14771 				return this;
  14772 			}
  14773 			if ( vtype === "string" ) {
  14774 				match = rplusequals.exec( value );
  14775 				if ( match ) {
  14776 					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
  14777 				}
  14778 			}
  14779 			local[ prop.idx ] = value;
  14780 			return this[ fn ]( local );
  14781 		};
  14782 	});
  14783 });
  14784 
  14785 // add cssHook and .fx.step function for each named hook.
  14786 // accept a space separated string of properties
  14787 color.hook = function( hook ) {
  14788 	var hooks = hook.split( " " );
  14789 	each( hooks, function( i, hook ) {
  14790 		jQuery.cssHooks[ hook ] = {
  14791 			set: function( elem, value ) {
  14792 				var parsed, curElem,
  14793 					backgroundColor = "";
  14794 
  14795 				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
  14796 					value = color( parsed || value );
  14797 					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
  14798 						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
  14799 						while (
  14800 							(backgroundColor === "" || backgroundColor === "transparent") &&
  14801 							curElem && curElem.style
  14802 						) {
  14803 							try {
  14804 								backgroundColor = jQuery.css( curElem, "backgroundColor" );
  14805 								curElem = curElem.parentNode;
  14806 							} catch ( e ) {
  14807 							}
  14808 						}
  14809 
  14810 						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
  14811 							backgroundColor :
  14812 							"_default" );
  14813 					}
  14814 
  14815 					value = value.toRgbaString();
  14816 				}
  14817 				try {
  14818 					elem.style[ hook ] = value;
  14819 				} catch ( e ) {
  14820 					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
  14821 				}
  14822 			}
  14823 		};
  14824 		jQuery.fx.step[ hook ] = function( fx ) {
  14825 			if ( !fx.colorInit ) {
  14826 				fx.start = color( fx.elem, hook );
  14827 				fx.end = color( fx.end );
  14828 				fx.colorInit = true;
  14829 			}
  14830 			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
  14831 		};
  14832 	});
  14833 
  14834 };
  14835 
  14836 color.hook( stepHooks );
  14837 
  14838 jQuery.cssHooks.borderColor = {
  14839 	expand: function( value ) {
  14840 		var expanded = {};
  14841 
  14842 		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
  14843 			expanded[ "border" + part + "Color" ] = value;
  14844 		});
  14845 		return expanded;
  14846 	}
  14847 };
  14848 
  14849 // Basic color names only.
  14850 // Usage of any of the other color names requires adding yourself or including
  14851 // jquery.color.svg-names.js.
  14852 colors = jQuery.Color.names = {
  14853 	// 4.1. Basic color keywords
  14854 	aqua: "#00ffff",
  14855 	black: "#000000",
  14856 	blue: "#0000ff",
  14857 	fuchsia: "#ff00ff",
  14858 	gray: "#808080",
  14859 	green: "#008000",
  14860 	lime: "#00ff00",
  14861 	maroon: "#800000",
  14862 	navy: "#000080",
  14863 	olive: "#808000",
  14864 	purple: "#800080",
  14865 	red: "#ff0000",
  14866 	silver: "#c0c0c0",
  14867 	teal: "#008080",
  14868 	white: "#ffffff",
  14869 	yellow: "#ffff00",
  14870 
  14871 	// 4.2.3. "transparent" color keyword
  14872 	transparent: [ null, null, null, 0 ],
  14873 
  14874 	_default: "#ffffff"
  14875 };
  14876 
  14877 })( jQuery );
  14878 
  14879 /******************************************************************************/
  14880 /****************************** CLASS ANIMATIONS ******************************/
  14881 /******************************************************************************/
  14882 (function() {
  14883 
  14884 var classAnimationActions = [ "add", "remove", "toggle" ],
  14885 	shorthandStyles = {
  14886 		border: 1,
  14887 		borderBottom: 1,
  14888 		borderColor: 1,
  14889 		borderLeft: 1,
  14890 		borderRight: 1,
  14891 		borderTop: 1,
  14892 		borderWidth: 1,
  14893 		margin: 1,
  14894 		padding: 1
  14895 	};
  14896 
  14897 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
  14898 	$.fx.step[ prop ] = function( fx ) {
  14899 		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
  14900 			jQuery.style( fx.elem, prop, fx.end );
  14901 			fx.setAttr = true;
  14902 		}
  14903 	};
  14904 });
  14905 
  14906 function getElementStyles( elem ) {
  14907 	var key, len,
  14908 		style = elem.ownerDocument.defaultView ?
  14909 			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
  14910 			elem.currentStyle,
  14911 		styles = {};
  14912 
  14913 	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
  14914 		len = style.length;
  14915 		while ( len-- ) {
  14916 			key = style[ len ];
  14917 			if ( typeof style[ key ] === "string" ) {
  14918 				styles[ $.camelCase( key ) ] = style[ key ];
  14919 			}
  14920 		}
  14921 	// support: Opera, IE <9
  14922 	} else {
  14923 		for ( key in style ) {
  14924 			if ( typeof style[ key ] === "string" ) {
  14925 				styles[ key ] = style[ key ];
  14926 			}
  14927 		}
  14928 	}
  14929 
  14930 	return styles;
  14931 }
  14932 
  14933 function styleDifference( oldStyle, newStyle ) {
  14934 	var diff = {},
  14935 		name, value;
  14936 
  14937 	for ( name in newStyle ) {
  14938 		value = newStyle[ name ];
  14939 		if ( oldStyle[ name ] !== value ) {
  14940 			if ( !shorthandStyles[ name ] ) {
  14941 				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
  14942 					diff[ name ] = value;
  14943 				}
  14944 			}
  14945 		}
  14946 	}
  14947 
  14948 	return diff;
  14949 }
  14950 
  14951 // support: jQuery <1.8
  14952 if ( !$.fn.addBack ) {
  14953 	$.fn.addBack = function( selector ) {
  14954 		return this.add( selector == null ?
  14955 			this.prevObject : this.prevObject.filter( selector )
  14956 		);
  14957 	};
  14958 }
  14959 
  14960 $.effects.animateClass = function( value, duration, easing, callback ) {
  14961 	var o = $.speed( duration, easing, callback );
  14962 
  14963 	return this.queue( function() {
  14964 		var animated = $( this ),
  14965 			baseClass = animated.attr( "class" ) || "",
  14966 			applyClassChange,
  14967 			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
  14968 
  14969 		// map the animated objects to store the original styles.
  14970 		allAnimations = allAnimations.map(function() {
  14971 			var el = $( this );
  14972 			return {
  14973 				el: el,
  14974 				start: getElementStyles( this )
  14975 			};
  14976 		});
  14977 
  14978 		// apply class change
  14979 		applyClassChange = function() {
  14980 			$.each( classAnimationActions, function(i, action) {
  14981 				if ( value[ action ] ) {
  14982 					animated[ action + "Class" ]( value[ action ] );
  14983 				}
  14984 			});
  14985 		};
  14986 		applyClassChange();
  14987 
  14988 		// map all animated objects again - calculate new styles and diff
  14989 		allAnimations = allAnimations.map(function() {
  14990 			this.end = getElementStyles( this.el[ 0 ] );
  14991 			this.diff = styleDifference( this.start, this.end );
  14992 			return this;
  14993 		});
  14994 
  14995 		// apply original class
  14996 		animated.attr( "class", baseClass );
  14997 
  14998 		// map all animated objects again - this time collecting a promise
  14999 		allAnimations = allAnimations.map(function() {
  15000 			var styleInfo = this,
  15001 				dfd = $.Deferred(),
  15002 				opts = $.extend({}, o, {
  15003 					queue: false,
  15004 					complete: function() {
  15005 						dfd.resolve( styleInfo );
  15006 					}
  15007 				});
  15008 
  15009 			this.el.animate( this.diff, opts );
  15010 			return dfd.promise();
  15011 		});
  15012 
  15013 		// once all animations have completed:
  15014 		$.when.apply( $, allAnimations.get() ).done(function() {
  15015 
  15016 			// set the final class
  15017 			applyClassChange();
  15018 
  15019 			// for each animated element,
  15020 			// clear all css properties that were animated
  15021 			$.each( arguments, function() {
  15022 				var el = this.el;
  15023 				$.each( this.diff, function(key) {
  15024 					el.css( key, "" );
  15025 				});
  15026 			});
  15027 
  15028 			// this is guarnteed to be there if you use jQuery.speed()
  15029 			// it also handles dequeuing the next anim...
  15030 			o.complete.call( animated[ 0 ] );
  15031 		});
  15032 	});
  15033 };
  15034 
  15035 $.fn.extend({
  15036 	addClass: (function( orig ) {
  15037 		return function( classNames, speed, easing, callback ) {
  15038 			return speed ?
  15039 				$.effects.animateClass.call( this,
  15040 					{ add: classNames }, speed, easing, callback ) :
  15041 				orig.apply( this, arguments );
  15042 		};
  15043 	})( $.fn.addClass ),
  15044 
  15045 	removeClass: (function( orig ) {
  15046 		return function( classNames, speed, easing, callback ) {
  15047 			return arguments.length > 1 ?
  15048 				$.effects.animateClass.call( this,
  15049 					{ remove: classNames }, speed, easing, callback ) :
  15050 				orig.apply( this, arguments );
  15051 		};
  15052 	})( $.fn.removeClass ),
  15053 
  15054 	toggleClass: (function( orig ) {
  15055 		return function( classNames, force, speed, easing, callback ) {
  15056 			if ( typeof force === "boolean" || force === undefined ) {
  15057 				if ( !speed ) {
  15058 					// without speed parameter
  15059 					return orig.apply( this, arguments );
  15060 				} else {
  15061 					return $.effects.animateClass.call( this,
  15062 						(force ? { add: classNames } : { remove: classNames }),
  15063 						speed, easing, callback );
  15064 				}
  15065 			} else {
  15066 				// without force parameter
  15067 				return $.effects.animateClass.call( this,
  15068 					{ toggle: classNames }, force, speed, easing );
  15069 			}
  15070 		};
  15071 	})( $.fn.toggleClass ),
  15072 
  15073 	switchClass: function( remove, add, speed, easing, callback) {
  15074 		return $.effects.animateClass.call( this, {
  15075 			add: add,
  15076 			remove: remove
  15077 		}, speed, easing, callback );
  15078 	}
  15079 });
  15080 
  15081 })();
  15082 
  15083 /******************************************************************************/
  15084 /*********************************** EFFECTS **********************************/
  15085 /******************************************************************************/
  15086 
  15087 (function() {
  15088 
  15089 $.extend( $.effects, {
  15090 	version: "1.11.4",
  15091 
  15092 	// Saves a set of properties in a data storage
  15093 	save: function( element, set ) {
  15094 		for ( var i = 0; i < set.length; i++ ) {
  15095 			if ( set[ i ] !== null ) {
  15096 				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
  15097 			}
  15098 		}
  15099 	},
  15100 
  15101 	// Restores a set of previously saved properties from a data storage
  15102 	restore: function( element, set ) {
  15103 		var val, i;
  15104 		for ( i = 0; i < set.length; i++ ) {
  15105 			if ( set[ i ] !== null ) {
  15106 				val = element.data( dataSpace + set[ i ] );
  15107 				// support: jQuery 1.6.2
  15108 				// http://bugs.jquery.com/ticket/9917
  15109 				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
  15110 				// We can't differentiate between "" and 0 here, so we just assume
  15111 				// empty string since it's likely to be a more common value...
  15112 				if ( val === undefined ) {
  15113 					val = "";
  15114 				}
  15115 				element.css( set[ i ], val );
  15116 			}
  15117 		}
  15118 	},
  15119 
  15120 	setMode: function( el, mode ) {
  15121 		if (mode === "toggle") {
  15122 			mode = el.is( ":hidden" ) ? "show" : "hide";
  15123 		}
  15124 		return mode;
  15125 	},
  15126 
  15127 	// Translates a [top,left] array into a baseline value
  15128 	// this should be a little more flexible in the future to handle a string & hash
  15129 	getBaseline: function( origin, original ) {
  15130 		var y, x;
  15131 		switch ( origin[ 0 ] ) {
  15132 			case "top": y = 0; break;
  15133 			case "middle": y = 0.5; break;
  15134 			case "bottom": y = 1; break;
  15135 			default: y = origin[ 0 ] / original.height;
  15136 		}
  15137 		switch ( origin[ 1 ] ) {
  15138 			case "left": x = 0; break;
  15139 			case "center": x = 0.5; break;
  15140 			case "right": x = 1; break;
  15141 			default: x = origin[ 1 ] / original.width;
  15142 		}
  15143 		return {
  15144 			x: x,
  15145 			y: y
  15146 		};
  15147 	},
  15148 
  15149 	// Wraps the element around a wrapper that copies position properties
  15150 	createWrapper: function( element ) {
  15151 
  15152 		// if the element is already wrapped, return it
  15153 		if ( element.parent().is( ".ui-effects-wrapper" )) {
  15154 			return element.parent();
  15155 		}
  15156 
  15157 		// wrap the element
  15158 		var props = {
  15159 				width: element.outerWidth(true),
  15160 				height: element.outerHeight(true),
  15161 				"float": element.css( "float" )
  15162 			},
  15163 			wrapper = $( "<div></div>" )
  15164 				.addClass( "ui-effects-wrapper" )
  15165 				.css({
  15166 					fontSize: "100%",
  15167 					background: "transparent",
  15168 					border: "none",
  15169 					margin: 0,
  15170 					padding: 0
  15171 				}),
  15172 			// Store the size in case width/height are defined in % - Fixes #5245
  15173 			size = {
  15174 				width: element.width(),
  15175 				height: element.height()
  15176 			},
  15177 			active = document.activeElement;
  15178 
  15179 		// support: Firefox
  15180 		// Firefox incorrectly exposes anonymous content
  15181 		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
  15182 		try {
  15183 			active.id;
  15184 		} catch ( e ) {
  15185 			active = document.body;
  15186 		}
  15187 
  15188 		element.wrap( wrapper );
  15189 
  15190 		// Fixes #7595 - Elements lose focus when wrapped.
  15191 		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  15192 			$( active ).focus();
  15193 		}
  15194 
  15195 		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
  15196 
  15197 		// transfer positioning properties to the wrapper
  15198 		if ( element.css( "position" ) === "static" ) {
  15199 			wrapper.css({ position: "relative" });
  15200 			element.css({ position: "relative" });
  15201 		} else {
  15202 			$.extend( props, {
  15203 				position: element.css( "position" ),
  15204 				zIndex: element.css( "z-index" )
  15205 			});
  15206 			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
  15207 				props[ pos ] = element.css( pos );
  15208 				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
  15209 					props[ pos ] = "auto";
  15210 				}
  15211 			});
  15212 			element.css({
  15213 				position: "relative",
  15214 				top: 0,
  15215 				left: 0,
  15216 				right: "auto",
  15217 				bottom: "auto"
  15218 			});
  15219 		}
  15220 		element.css(size);
  15221 
  15222 		return wrapper.css( props ).show();
  15223 	},
  15224 
  15225 	removeWrapper: function( element ) {
  15226 		var active = document.activeElement;
  15227 
  15228 		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
  15229 			element.parent().replaceWith( element );
  15230 
  15231 			// Fixes #7595 - Elements lose focus when wrapped.
  15232 			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  15233 				$( active ).focus();
  15234 			}
  15235 		}
  15236 
  15237 		return element;
  15238 	},
  15239 
  15240 	setTransition: function( element, list, factor, value ) {
  15241 		value = value || {};
  15242 		$.each( list, function( i, x ) {
  15243 			var unit = element.cssUnit( x );
  15244 			if ( unit[ 0 ] > 0 ) {
  15245 				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
  15246 			}
  15247 		});
  15248 		return value;
  15249 	}
  15250 });
  15251 
  15252 // return an effect options object for the given parameters:
  15253 function _normalizeArguments( effect, options, speed, callback ) {
  15254 
  15255 	// allow passing all options as the first parameter
  15256 	if ( $.isPlainObject( effect ) ) {
  15257 		options = effect;
  15258 		effect = effect.effect;
  15259 	}
  15260 
  15261 	// convert to an object
  15262 	effect = { effect: effect };
  15263 
  15264 	// catch (effect, null, ...)
  15265 	if ( options == null ) {
  15266 		options = {};
  15267 	}
  15268 
  15269 	// catch (effect, callback)
  15270 	if ( $.isFunction( options ) ) {
  15271 		callback = options;
  15272 		speed = null;
  15273 		options = {};
  15274 	}
  15275 
  15276 	// catch (effect, speed, ?)
  15277 	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
  15278 		callback = speed;
  15279 		speed = options;
  15280 		options = {};
  15281 	}
  15282 
  15283 	// catch (effect, options, callback)
  15284 	if ( $.isFunction( speed ) ) {
  15285 		callback = speed;
  15286 		speed = null;
  15287 	}
  15288 
  15289 	// add options to effect
  15290 	if ( options ) {
  15291 		$.extend( effect, options );
  15292 	}
  15293 
  15294 	speed = speed || options.duration;
  15295 	effect.duration = $.fx.off ? 0 :
  15296 		typeof speed === "number" ? speed :
  15297 		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
  15298 		$.fx.speeds._default;
  15299 
  15300 	effect.complete = callback || options.complete;
  15301 
  15302 	return effect;
  15303 }
  15304 
  15305 function standardAnimationOption( option ) {
  15306 	// Valid standard speeds (nothing, number, named speed)
  15307 	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
  15308 		return true;
  15309 	}
  15310 
  15311 	// Invalid strings - treat as "normal" speed
  15312 	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
  15313 		return true;
  15314 	}
  15315 
  15316 	// Complete callback
  15317 	if ( $.isFunction( option ) ) {
  15318 		return true;
  15319 	}
  15320 
  15321 	// Options hash (but not naming an effect)
  15322 	if ( typeof option === "object" && !option.effect ) {
  15323 		return true;
  15324 	}
  15325 
  15326 	// Didn't match any standard API
  15327 	return false;
  15328 }
  15329 
  15330 $.fn.extend({
  15331 	effect: function( /* effect, options, speed, callback */ ) {
  15332 		var args = _normalizeArguments.apply( this, arguments ),
  15333 			mode = args.mode,
  15334 			queue = args.queue,
  15335 			effectMethod = $.effects.effect[ args.effect ];
  15336 
  15337 		if ( $.fx.off || !effectMethod ) {
  15338 			// delegate to the original method (e.g., .show()) if possible
  15339 			if ( mode ) {
  15340 				return this[ mode ]( args.duration, args.complete );
  15341 			} else {
  15342 				return this.each( function() {
  15343 					if ( args.complete ) {
  15344 						args.complete.call( this );
  15345 					}
  15346 				});
  15347 			}
  15348 		}
  15349 
  15350 		function run( next ) {
  15351 			var elem = $( this ),
  15352 				complete = args.complete,
  15353 				mode = args.mode;
  15354 
  15355 			function done() {
  15356 				if ( $.isFunction( complete ) ) {
  15357 					complete.call( elem[0] );
  15358 				}
  15359 				if ( $.isFunction( next ) ) {
  15360 					next();
  15361 				}
  15362 			}
  15363 
  15364 			// If the element already has the correct final state, delegate to
  15365 			// the core methods so the internal tracking of "olddisplay" works.
  15366 			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
  15367 				elem[ mode ]();
  15368 				done();
  15369 			} else {
  15370 				effectMethod.call( elem[0], args, done );
  15371 			}
  15372 		}
  15373 
  15374 		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
  15375 	},
  15376 
  15377 	show: (function( orig ) {
  15378 		return function( option ) {
  15379 			if ( standardAnimationOption( option ) ) {
  15380 				return orig.apply( this, arguments );
  15381 			} else {
  15382 				var args = _normalizeArguments.apply( this, arguments );
  15383 				args.mode = "show";
  15384 				return this.effect.call( this, args );
  15385 			}
  15386 		};
  15387 	})( $.fn.show ),
  15388 
  15389 	hide: (function( orig ) {
  15390 		return function( option ) {
  15391 			if ( standardAnimationOption( option ) ) {
  15392 				return orig.apply( this, arguments );
  15393 			} else {
  15394 				var args = _normalizeArguments.apply( this, arguments );
  15395 				args.mode = "hide";
  15396 				return this.effect.call( this, args );
  15397 			}
  15398 		};
  15399 	})( $.fn.hide ),
  15400 
  15401 	toggle: (function( orig ) {
  15402 		return function( option ) {
  15403 			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
  15404 				return orig.apply( this, arguments );
  15405 			} else {
  15406 				var args = _normalizeArguments.apply( this, arguments );
  15407 				args.mode = "toggle";
  15408 				return this.effect.call( this, args );
  15409 			}
  15410 		};
  15411 	})( $.fn.toggle ),
  15412 
  15413 	// helper functions
  15414 	cssUnit: function(key) {
  15415 		var style = this.css( key ),
  15416 			val = [];
  15417 
  15418 		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
  15419 			if ( style.indexOf( unit ) > 0 ) {
  15420 				val = [ parseFloat( style ), unit ];
  15421 			}
  15422 		});
  15423 		return val;
  15424 	}
  15425 });
  15426 
  15427 })();
  15428 
  15429 /******************************************************************************/
  15430 /*********************************** EASING ***********************************/
  15431 /******************************************************************************/
  15432 
  15433 (function() {
  15434 
  15435 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
  15436 
  15437 var baseEasings = {};
  15438 
  15439 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
  15440 	baseEasings[ name ] = function( p ) {
  15441 		return Math.pow( p, i + 2 );
  15442 	};
  15443 });
  15444 
  15445 $.extend( baseEasings, {
  15446 	Sine: function( p ) {
  15447 		return 1 - Math.cos( p * Math.PI / 2 );
  15448 	},
  15449 	Circ: function( p ) {
  15450 		return 1 - Math.sqrt( 1 - p * p );
  15451 	},
  15452 	Elastic: function( p ) {
  15453 		return p === 0 || p === 1 ? p :
  15454 			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
  15455 	},
  15456 	Back: function( p ) {
  15457 		return p * p * ( 3 * p - 2 );
  15458 	},
  15459 	Bounce: function( p ) {
  15460 		var pow2,
  15461 			bounce = 4;
  15462 
  15463 		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
  15464 		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
  15465 	}
  15466 });
  15467 
  15468 $.each( baseEasings, function( name, easeIn ) {
  15469 	$.easing[ "easeIn" + name ] = easeIn;
  15470 	$.easing[ "easeOut" + name ] = function( p ) {
  15471 		return 1 - easeIn( 1 - p );
  15472 	};
  15473 	$.easing[ "easeInOut" + name ] = function( p ) {
  15474 		return p < 0.5 ?
  15475 			easeIn( p * 2 ) / 2 :
  15476 			1 - easeIn( p * -2 + 2 ) / 2;
  15477 	};
  15478 });
  15479 
  15480 })();
  15481 
  15482 var effect = $.effects;
  15483 
  15484 
  15485 /*!
  15486  * jQuery UI Effects Blind 1.11.4
  15487  * http://jqueryui.com
  15488  *
  15489  * Copyright jQuery Foundation and other contributors
  15490  * Released under the MIT license.
  15491  * http://jquery.org/license
  15492  *
  15493  * http://api.jqueryui.com/blind-effect/
  15494  */
  15495 
  15496 
  15497 var effectBlind = $.effects.effect.blind = function( o, done ) {
  15498 	// Create element
  15499 	var el = $( this ),
  15500 		rvertical = /up|down|vertical/,
  15501 		rpositivemotion = /up|left|vertical|horizontal/,
  15502 		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  15503 		mode = $.effects.setMode( el, o.mode || "hide" ),
  15504 		direction = o.direction || "up",
  15505 		vertical = rvertical.test( direction ),
  15506 		ref = vertical ? "height" : "width",
  15507 		ref2 = vertical ? "top" : "left",
  15508 		motion = rpositivemotion.test( direction ),
  15509 		animation = {},
  15510 		show = mode === "show",
  15511 		wrapper, distance, margin;
  15512 
  15513 	// if already wrapped, the wrapper's properties are my property. #6245
  15514 	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
  15515 		$.effects.save( el.parent(), props );
  15516 	} else {
  15517 		$.effects.save( el, props );
  15518 	}
  15519 	el.show();
  15520 	wrapper = $.effects.createWrapper( el ).css({
  15521 		overflow: "hidden"
  15522 	});
  15523 
  15524 	distance = wrapper[ ref ]();
  15525 	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
  15526 
  15527 	animation[ ref ] = show ? distance : 0;
  15528 	if ( !motion ) {
  15529 		el
  15530 			.css( vertical ? "bottom" : "right", 0 )
  15531 			.css( vertical ? "top" : "left", "auto" )
  15532 			.css({ position: "absolute" });
  15533 
  15534 		animation[ ref2 ] = show ? margin : distance + margin;
  15535 	}
  15536 
  15537 	// start at 0 if we are showing
  15538 	if ( show ) {
  15539 		wrapper.css( ref, 0 );
  15540 		if ( !motion ) {
  15541 			wrapper.css( ref2, margin + distance );
  15542 		}
  15543 	}
  15544 
  15545 	// Animate
  15546 	wrapper.animate( animation, {
  15547 		duration: o.duration,
  15548 		easing: o.easing,
  15549 		queue: false,
  15550 		complete: function() {
  15551 			if ( mode === "hide" ) {
  15552 				el.hide();
  15553 			}
  15554 			$.effects.restore( el, props );
  15555 			$.effects.removeWrapper( el );
  15556 			done();
  15557 		}
  15558 	});
  15559 };
  15560 
  15561 
  15562 /*!
  15563  * jQuery UI Effects Bounce 1.11.4
  15564  * http://jqueryui.com
  15565  *
  15566  * Copyright jQuery Foundation and other contributors
  15567  * Released under the MIT license.
  15568  * http://jquery.org/license
  15569  *
  15570  * http://api.jqueryui.com/bounce-effect/
  15571  */
  15572 
  15573 
  15574 var effectBounce = $.effects.effect.bounce = function( o, done ) {
  15575 	var el = $( this ),
  15576 		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  15577 
  15578 		// defaults:
  15579 		mode = $.effects.setMode( el, o.mode || "effect" ),
  15580 		hide = mode === "hide",
  15581 		show = mode === "show",
  15582 		direction = o.direction || "up",
  15583 		distance = o.distance,
  15584 		times = o.times || 5,
  15585 
  15586 		// number of internal animations
  15587 		anims = times * 2 + ( show || hide ? 1 : 0 ),
  15588 		speed = o.duration / anims,
  15589 		easing = o.easing,
  15590 
  15591 		// utility:
  15592 		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  15593 		motion = ( direction === "up" || direction === "left" ),
  15594 		i,
  15595 		upAnim,
  15596 		downAnim,
  15597 
  15598 		// we will need to re-assemble the queue to stack our animations in place
  15599 		queue = el.queue(),
  15600 		queuelen = queue.length;
  15601 
  15602 	// Avoid touching opacity to prevent clearType and PNG issues in IE
  15603 	if ( show || hide ) {
  15604 		props.push( "opacity" );
  15605 	}
  15606 
  15607 	$.effects.save( el, props );
  15608 	el.show();
  15609 	$.effects.createWrapper( el ); // Create Wrapper
  15610 
  15611 	// default distance for the BIGGEST bounce is the outer Distance / 3
  15612 	if ( !distance ) {
  15613 		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
  15614 	}
  15615 
  15616 	if ( show ) {
  15617 		downAnim = { opacity: 1 };
  15618 		downAnim[ ref ] = 0;
  15619 
  15620 		// if we are showing, force opacity 0 and set the initial position
  15621 		// then do the "first" animation
  15622 		el.css( "opacity", 0 )
  15623 			.css( ref, motion ? -distance * 2 : distance * 2 )
  15624 			.animate( downAnim, speed, easing );
  15625 	}
  15626 
  15627 	// start at the smallest distance if we are hiding
  15628 	if ( hide ) {
  15629 		distance = distance / Math.pow( 2, times - 1 );
  15630 	}
  15631 
  15632 	downAnim = {};
  15633 	downAnim[ ref ] = 0;
  15634 	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
  15635 	for ( i = 0; i < times; i++ ) {
  15636 		upAnim = {};
  15637 		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
  15638 
  15639 		el.animate( upAnim, speed, easing )
  15640 			.animate( downAnim, speed, easing );
  15641 
  15642 		distance = hide ? distance * 2 : distance / 2;
  15643 	}
  15644 
  15645 	// Last Bounce when Hiding
  15646 	if ( hide ) {
  15647 		upAnim = { opacity: 0 };
  15648 		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
  15649 
  15650 		el.animate( upAnim, speed, easing );
  15651 	}
  15652 
  15653 	el.queue(function() {
  15654 		if ( hide ) {
  15655 			el.hide();
  15656 		}
  15657 		$.effects.restore( el, props );
  15658 		$.effects.removeWrapper( el );
  15659 		done();
  15660 	});
  15661 
  15662 	// inject all the animations we just queued to be first in line (after "inprogress")
  15663 	if ( queuelen > 1) {
  15664 		queue.splice.apply( queue,
  15665 			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  15666 	}
  15667 	el.dequeue();
  15668 
  15669 };
  15670 
  15671 
  15672 /*!
  15673  * jQuery UI Effects Clip 1.11.4
  15674  * http://jqueryui.com
  15675  *
  15676  * Copyright jQuery Foundation and other contributors
  15677  * Released under the MIT license.
  15678  * http://jquery.org/license
  15679  *
  15680  * http://api.jqueryui.com/clip-effect/
  15681  */
  15682 
  15683 
  15684 var effectClip = $.effects.effect.clip = function( o, done ) {
  15685 	// Create element
  15686 	var el = $( this ),
  15687 		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  15688 		mode = $.effects.setMode( el, o.mode || "hide" ),
  15689 		show = mode === "show",
  15690 		direction = o.direction || "vertical",
  15691 		vert = direction === "vertical",
  15692 		size = vert ? "height" : "width",
  15693 		position = vert ? "top" : "left",
  15694 		animation = {},
  15695 		wrapper, animate, distance;
  15696 
  15697 	// Save & Show
  15698 	$.effects.save( el, props );
  15699 	el.show();
  15700 
  15701 	// Create Wrapper
  15702 	wrapper = $.effects.createWrapper( el ).css({
  15703 		overflow: "hidden"
  15704 	});
  15705 	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
  15706 	distance = animate[ size ]();
  15707 
  15708 	// Shift
  15709 	if ( show ) {
  15710 		animate.css( size, 0 );
  15711 		animate.css( position, distance / 2 );
  15712 	}
  15713 
  15714 	// Create Animation Object:
  15715 	animation[ size ] = show ? distance : 0;
  15716 	animation[ position ] = show ? 0 : distance / 2;
  15717 
  15718 	// Animate
  15719 	animate.animate( animation, {
  15720 		queue: false,
  15721 		duration: o.duration,
  15722 		easing: o.easing,
  15723 		complete: function() {
  15724 			if ( !show ) {
  15725 				el.hide();
  15726 			}
  15727 			$.effects.restore( el, props );
  15728 			$.effects.removeWrapper( el );
  15729 			done();
  15730 		}
  15731 	});
  15732 
  15733 };
  15734 
  15735 
  15736 /*!
  15737  * jQuery UI Effects Drop 1.11.4
  15738  * http://jqueryui.com
  15739  *
  15740  * Copyright jQuery Foundation and other contributors
  15741  * Released under the MIT license.
  15742  * http://jquery.org/license
  15743  *
  15744  * http://api.jqueryui.com/drop-effect/
  15745  */
  15746 
  15747 
  15748 var effectDrop = $.effects.effect.drop = function( o, done ) {
  15749 
  15750 	var el = $( this ),
  15751 		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
  15752 		mode = $.effects.setMode( el, o.mode || "hide" ),
  15753 		show = mode === "show",
  15754 		direction = o.direction || "left",
  15755 		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  15756 		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
  15757 		animation = {
  15758 			opacity: show ? 1 : 0
  15759 		},
  15760 		distance;
  15761 
  15762 	// Adjust
  15763 	$.effects.save( el, props );
  15764 	el.show();
  15765 	$.effects.createWrapper( el );
  15766 
  15767 	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
  15768 
  15769 	if ( show ) {
  15770 		el
  15771 			.css( "opacity", 0 )
  15772 			.css( ref, motion === "pos" ? -distance : distance );
  15773 	}
  15774 
  15775 	// Animation
  15776 	animation[ ref ] = ( show ?
  15777 		( motion === "pos" ? "+=" : "-=" ) :
  15778 		( motion === "pos" ? "-=" : "+=" ) ) +
  15779 		distance;
  15780 
  15781 	// Animate
  15782 	el.animate( animation, {
  15783 		queue: false,
  15784 		duration: o.duration,
  15785 		easing: o.easing,
  15786 		complete: function() {
  15787 			if ( mode === "hide" ) {
  15788 				el.hide();
  15789 			}
  15790 			$.effects.restore( el, props );
  15791 			$.effects.removeWrapper( el );
  15792 			done();
  15793 		}
  15794 	});
  15795 };
  15796 
  15797 
  15798 /*!
  15799  * jQuery UI Effects Explode 1.11.4
  15800  * http://jqueryui.com
  15801  *
  15802  * Copyright jQuery Foundation and other contributors
  15803  * Released under the MIT license.
  15804  * http://jquery.org/license
  15805  *
  15806  * http://api.jqueryui.com/explode-effect/
  15807  */
  15808 
  15809 
  15810 var effectExplode = $.effects.effect.explode = function( o, done ) {
  15811 
  15812 	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
  15813 		cells = rows,
  15814 		el = $( this ),
  15815 		mode = $.effects.setMode( el, o.mode || "hide" ),
  15816 		show = mode === "show",
  15817 
  15818 		// show and then visibility:hidden the element before calculating offset
  15819 		offset = el.show().css( "visibility", "hidden" ).offset(),
  15820 
  15821 		// width and height of a piece
  15822 		width = Math.ceil( el.outerWidth() / cells ),
  15823 		height = Math.ceil( el.outerHeight() / rows ),
  15824 		pieces = [],
  15825 
  15826 		// loop
  15827 		i, j, left, top, mx, my;
  15828 
  15829 	// children animate complete:
  15830 	function childComplete() {
  15831 		pieces.push( this );
  15832 		if ( pieces.length === rows * cells ) {
  15833 			animComplete();
  15834 		}
  15835 	}
  15836 
  15837 	// clone the element for each row and cell.
  15838 	for ( i = 0; i < rows ; i++ ) { // ===>
  15839 		top = offset.top + i * height;
  15840 		my = i - ( rows - 1 ) / 2 ;
  15841 
  15842 		for ( j = 0; j < cells ; j++ ) { // |||
  15843 			left = offset.left + j * width;
  15844 			mx = j - ( cells - 1 ) / 2 ;
  15845 
  15846 			// Create a clone of the now hidden main element that will be absolute positioned
  15847 			// within a wrapper div off the -left and -top equal to size of our pieces
  15848 			el
  15849 				.clone()
  15850 				.appendTo( "body" )
  15851 				.wrap( "<div></div>" )
  15852 				.css({
  15853 					position: "absolute",
  15854 					visibility: "visible",
  15855 					left: -j * width,
  15856 					top: -i * height
  15857 				})
  15858 
  15859 			// select the wrapper - make it overflow: hidden and absolute positioned based on
  15860 			// where the original was located +left and +top equal to the size of pieces
  15861 				.parent()
  15862 				.addClass( "ui-effects-explode" )
  15863 				.css({
  15864 					position: "absolute",
  15865 					overflow: "hidden",
  15866 					width: width,
  15867 					height: height,
  15868 					left: left + ( show ? mx * width : 0 ),
  15869 					top: top + ( show ? my * height : 0 ),
  15870 					opacity: show ? 0 : 1
  15871 				}).animate({
  15872 					left: left + ( show ? 0 : mx * width ),
  15873 					top: top + ( show ? 0 : my * height ),
  15874 					opacity: show ? 1 : 0
  15875 				}, o.duration || 500, o.easing, childComplete );
  15876 		}
  15877 	}
  15878 
  15879 	function animComplete() {
  15880 		el.css({
  15881 			visibility: "visible"
  15882 		});
  15883 		$( pieces ).remove();
  15884 		if ( !show ) {
  15885 			el.hide();
  15886 		}
  15887 		done();
  15888 	}
  15889 };
  15890 
  15891 
  15892 /*!
  15893  * jQuery UI Effects Fade 1.11.4
  15894  * http://jqueryui.com
  15895  *
  15896  * Copyright jQuery Foundation and other contributors
  15897  * Released under the MIT license.
  15898  * http://jquery.org/license
  15899  *
  15900  * http://api.jqueryui.com/fade-effect/
  15901  */
  15902 
  15903 
  15904 var effectFade = $.effects.effect.fade = function( o, done ) {
  15905 	var el = $( this ),
  15906 		mode = $.effects.setMode( el, o.mode || "toggle" );
  15907 
  15908 	el.animate({
  15909 		opacity: mode
  15910 	}, {
  15911 		queue: false,
  15912 		duration: o.duration,
  15913 		easing: o.easing,
  15914 		complete: done
  15915 	});
  15916 };
  15917 
  15918 
  15919 /*!
  15920  * jQuery UI Effects Fold 1.11.4
  15921  * http://jqueryui.com
  15922  *
  15923  * Copyright jQuery Foundation and other contributors
  15924  * Released under the MIT license.
  15925  * http://jquery.org/license
  15926  *
  15927  * http://api.jqueryui.com/fold-effect/
  15928  */
  15929 
  15930 
  15931 var effectFold = $.effects.effect.fold = function( o, done ) {
  15932 
  15933 	// Create element
  15934 	var el = $( this ),
  15935 		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  15936 		mode = $.effects.setMode( el, o.mode || "hide" ),
  15937 		show = mode === "show",
  15938 		hide = mode === "hide",
  15939 		size = o.size || 15,
  15940 		percent = /([0-9]+)%/.exec( size ),
  15941 		horizFirst = !!o.horizFirst,
  15942 		widthFirst = show !== horizFirst,
  15943 		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
  15944 		duration = o.duration / 2,
  15945 		wrapper, distance,
  15946 		animation1 = {},
  15947 		animation2 = {};
  15948 
  15949 	$.effects.save( el, props );
  15950 	el.show();
  15951 
  15952 	// Create Wrapper
  15953 	wrapper = $.effects.createWrapper( el ).css({
  15954 		overflow: "hidden"
  15955 	});
  15956 	distance = widthFirst ?
  15957 		[ wrapper.width(), wrapper.height() ] :
  15958 		[ wrapper.height(), wrapper.width() ];
  15959 
  15960 	if ( percent ) {
  15961 		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
  15962 	}
  15963 	if ( show ) {
  15964 		wrapper.css( horizFirst ? {
  15965 			height: 0,
  15966 			width: size
  15967 		} : {
  15968 			height: size,
  15969 			width: 0
  15970 		});
  15971 	}
  15972 
  15973 	// Animation
  15974 	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
  15975 	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
  15976 
  15977 	// Animate
  15978 	wrapper
  15979 		.animate( animation1, duration, o.easing )
  15980 		.animate( animation2, duration, o.easing, function() {
  15981 			if ( hide ) {
  15982 				el.hide();
  15983 			}
  15984 			$.effects.restore( el, props );
  15985 			$.effects.removeWrapper( el );
  15986 			done();
  15987 		});
  15988 
  15989 };
  15990 
  15991 
  15992 /*!
  15993  * jQuery UI Effects Highlight 1.11.4
  15994  * http://jqueryui.com
  15995  *
  15996  * Copyright jQuery Foundation and other contributors
  15997  * Released under the MIT license.
  15998  * http://jquery.org/license
  15999  *
  16000  * http://api.jqueryui.com/highlight-effect/
  16001  */
  16002 
  16003 
  16004 var effectHighlight = $.effects.effect.highlight = function( o, done ) {
  16005 	var elem = $( this ),
  16006 		props = [ "backgroundImage", "backgroundColor", "opacity" ],
  16007 		mode = $.effects.setMode( elem, o.mode || "show" ),
  16008 		animation = {
  16009 			backgroundColor: elem.css( "backgroundColor" )
  16010 		};
  16011 
  16012 	if (mode === "hide") {
  16013 		animation.opacity = 0;
  16014 	}
  16015 
  16016 	$.effects.save( elem, props );
  16017 
  16018 	elem
  16019 		.show()
  16020 		.css({
  16021 			backgroundImage: "none",
  16022 			backgroundColor: o.color || "#ffff99"
  16023 		})
  16024 		.animate( animation, {
  16025 			queue: false,
  16026 			duration: o.duration,
  16027 			easing: o.easing,
  16028 			complete: function() {
  16029 				if ( mode === "hide" ) {
  16030 					elem.hide();
  16031 				}
  16032 				$.effects.restore( elem, props );
  16033 				done();
  16034 			}
  16035 		});
  16036 };
  16037 
  16038 
  16039 /*!
  16040  * jQuery UI Effects Size 1.11.4
  16041  * http://jqueryui.com
  16042  *
  16043  * Copyright jQuery Foundation and other contributors
  16044  * Released under the MIT license.
  16045  * http://jquery.org/license
  16046  *
  16047  * http://api.jqueryui.com/size-effect/
  16048  */
  16049 
  16050 
  16051 var effectSize = $.effects.effect.size = function( o, done ) {
  16052 
  16053 	// Create element
  16054 	var original, baseline, factor,
  16055 		el = $( this ),
  16056 		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
  16057 
  16058 		// Always restore
  16059 		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
  16060 
  16061 		// Copy for children
  16062 		props2 = [ "width", "height", "overflow" ],
  16063 		cProps = [ "fontSize" ],
  16064 		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
  16065 		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
  16066 
  16067 		// Set options
  16068 		mode = $.effects.setMode( el, o.mode || "effect" ),
  16069 		restore = o.restore || mode !== "effect",
  16070 		scale = o.scale || "both",
  16071 		origin = o.origin || [ "middle", "center" ],
  16072 		position = el.css( "position" ),
  16073 		props = restore ? props0 : props1,
  16074 		zero = {
  16075 			height: 0,
  16076 			width: 0,
  16077 			outerHeight: 0,
  16078 			outerWidth: 0
  16079 		};
  16080 
  16081 	if ( mode === "show" ) {
  16082 		el.show();
  16083 	}
  16084 	original = {
  16085 		height: el.height(),
  16086 		width: el.width(),
  16087 		outerHeight: el.outerHeight(),
  16088 		outerWidth: el.outerWidth()
  16089 	};
  16090 
  16091 	if ( o.mode === "toggle" && mode === "show" ) {
  16092 		el.from = o.to || zero;
  16093 		el.to = o.from || original;
  16094 	} else {
  16095 		el.from = o.from || ( mode === "show" ? zero : original );
  16096 		el.to = o.to || ( mode === "hide" ? zero : original );
  16097 	}
  16098 
  16099 	// Set scaling factor
  16100 	factor = {
  16101 		from: {
  16102 			y: el.from.height / original.height,
  16103 			x: el.from.width / original.width
  16104 		},
  16105 		to: {
  16106 			y: el.to.height / original.height,
  16107 			x: el.to.width / original.width
  16108 		}
  16109 	};
  16110 
  16111 	// Scale the css box
  16112 	if ( scale === "box" || scale === "both" ) {
  16113 
  16114 		// Vertical props scaling
  16115 		if ( factor.from.y !== factor.to.y ) {
  16116 			props = props.concat( vProps );
  16117 			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
  16118 			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
  16119 		}
  16120 
  16121 		// Horizontal props scaling
  16122 		if ( factor.from.x !== factor.to.x ) {
  16123 			props = props.concat( hProps );
  16124 			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
  16125 			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
  16126 		}
  16127 	}
  16128 
  16129 	// Scale the content
  16130 	if ( scale === "content" || scale === "both" ) {
  16131 
  16132 		// Vertical props scaling
  16133 		if ( factor.from.y !== factor.to.y ) {
  16134 			props = props.concat( cProps ).concat( props2 );
  16135 			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
  16136 			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
  16137 		}
  16138 	}
  16139 
  16140 	$.effects.save( el, props );
  16141 	el.show();
  16142 	$.effects.createWrapper( el );
  16143 	el.css( "overflow", "hidden" ).css( el.from );
  16144 
  16145 	// Adjust
  16146 	if (origin) { // Calculate baseline shifts
  16147 		baseline = $.effects.getBaseline( origin, original );
  16148 		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
  16149 		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
  16150 		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
  16151 		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
  16152 	}
  16153 	el.css( el.from ); // set top & left
  16154 
  16155 	// Animate
  16156 	if ( scale === "content" || scale === "both" ) { // Scale the children
  16157 
  16158 		// Add margins/font-size
  16159 		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
  16160 		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
  16161 		props2 = props0.concat(vProps).concat(hProps);
  16162 
  16163 		el.find( "*[width]" ).each( function() {
  16164 			var child = $( this ),
  16165 				c_original = {
  16166 					height: child.height(),
  16167 					width: child.width(),
  16168 					outerHeight: child.outerHeight(),
  16169 					outerWidth: child.outerWidth()
  16170 				};
  16171 			if (restore) {
  16172 				$.effects.save(child, props2);
  16173 			}
  16174 
  16175 			child.from = {
  16176 				height: c_original.height * factor.from.y,
  16177 				width: c_original.width * factor.from.x,
  16178 				outerHeight: c_original.outerHeight * factor.from.y,
  16179 				outerWidth: c_original.outerWidth * factor.from.x
  16180 			};
  16181 			child.to = {
  16182 				height: c_original.height * factor.to.y,
  16183 				width: c_original.width * factor.to.x,
  16184 				outerHeight: c_original.height * factor.to.y,
  16185 				outerWidth: c_original.width * factor.to.x
  16186 			};
  16187 
  16188 			// Vertical props scaling
  16189 			if ( factor.from.y !== factor.to.y ) {
  16190 				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
  16191 				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
  16192 			}
  16193 
  16194 			// Horizontal props scaling
  16195 			if ( factor.from.x !== factor.to.x ) {
  16196 				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
  16197 				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
  16198 			}
  16199 
  16200 			// Animate children
  16201 			child.css( child.from );
  16202 			child.animate( child.to, o.duration, o.easing, function() {
  16203 
  16204 				// Restore children
  16205 				if ( restore ) {
  16206 					$.effects.restore( child, props2 );
  16207 				}
  16208 			});
  16209 		});
  16210 	}
  16211 
  16212 	// Animate
  16213 	el.animate( el.to, {
  16214 		queue: false,
  16215 		duration: o.duration,
  16216 		easing: o.easing,
  16217 		complete: function() {
  16218 			if ( el.to.opacity === 0 ) {
  16219 				el.css( "opacity", el.from.opacity );
  16220 			}
  16221 			if ( mode === "hide" ) {
  16222 				el.hide();
  16223 			}
  16224 			$.effects.restore( el, props );
  16225 			if ( !restore ) {
  16226 
  16227 				// we need to calculate our new positioning based on the scaling
  16228 				if ( position === "static" ) {
  16229 					el.css({
  16230 						position: "relative",
  16231 						top: el.to.top,
  16232 						left: el.to.left
  16233 					});
  16234 				} else {
  16235 					$.each([ "top", "left" ], function( idx, pos ) {
  16236 						el.css( pos, function( _, str ) {
  16237 							var val = parseInt( str, 10 ),
  16238 								toRef = idx ? el.to.left : el.to.top;
  16239 
  16240 							// if original was "auto", recalculate the new value from wrapper
  16241 							if ( str === "auto" ) {
  16242 								return toRef + "px";
  16243 							}
  16244 
  16245 							return val + toRef + "px";
  16246 						});
  16247 					});
  16248 				}
  16249 			}
  16250 
  16251 			$.effects.removeWrapper( el );
  16252 			done();
  16253 		}
  16254 	});
  16255 
  16256 };
  16257 
  16258 
  16259 /*!
  16260  * jQuery UI Effects Scale 1.11.4
  16261  * http://jqueryui.com
  16262  *
  16263  * Copyright jQuery Foundation and other contributors
  16264  * Released under the MIT license.
  16265  * http://jquery.org/license
  16266  *
  16267  * http://api.jqueryui.com/scale-effect/
  16268  */
  16269 
  16270 
  16271 var effectScale = $.effects.effect.scale = function( o, done ) {
  16272 
  16273 	// Create element
  16274 	var el = $( this ),
  16275 		options = $.extend( true, {}, o ),
  16276 		mode = $.effects.setMode( el, o.mode || "effect" ),
  16277 		percent = parseInt( o.percent, 10 ) ||
  16278 			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
  16279 		direction = o.direction || "both",
  16280 		origin = o.origin,
  16281 		original = {
  16282 			height: el.height(),
  16283 			width: el.width(),
  16284 			outerHeight: el.outerHeight(),
  16285 			outerWidth: el.outerWidth()
  16286 		},
  16287 		factor = {
  16288 			y: direction !== "horizontal" ? (percent / 100) : 1,
  16289 			x: direction !== "vertical" ? (percent / 100) : 1
  16290 		};
  16291 
  16292 	// We are going to pass this effect to the size effect:
  16293 	options.effect = "size";
  16294 	options.queue = false;
  16295 	options.complete = done;
  16296 
  16297 	// Set default origin and restore for show/hide
  16298 	if ( mode !== "effect" ) {
  16299 		options.origin = origin || [ "middle", "center" ];
  16300 		options.restore = true;
  16301 	}
  16302 
  16303 	options.from = o.from || ( mode === "show" ? {
  16304 		height: 0,
  16305 		width: 0,
  16306 		outerHeight: 0,
  16307 		outerWidth: 0
  16308 	} : original );
  16309 	options.to = {
  16310 		height: original.height * factor.y,
  16311 		width: original.width * factor.x,
  16312 		outerHeight: original.outerHeight * factor.y,
  16313 		outerWidth: original.outerWidth * factor.x
  16314 	};
  16315 
  16316 	// Fade option to support puff
  16317 	if ( options.fade ) {
  16318 		if ( mode === "show" ) {
  16319 			options.from.opacity = 0;
  16320 			options.to.opacity = 1;
  16321 		}
  16322 		if ( mode === "hide" ) {
  16323 			options.from.opacity = 1;
  16324 			options.to.opacity = 0;
  16325 		}
  16326 	}
  16327 
  16328 	// Animate
  16329 	el.effect( options );
  16330 
  16331 };
  16332 
  16333 
  16334 /*!
  16335  * jQuery UI Effects Puff 1.11.4
  16336  * http://jqueryui.com
  16337  *
  16338  * Copyright jQuery Foundation and other contributors
  16339  * Released under the MIT license.
  16340  * http://jquery.org/license
  16341  *
  16342  * http://api.jqueryui.com/puff-effect/
  16343  */
  16344 
  16345 
  16346 var effectPuff = $.effects.effect.puff = function( o, done ) {
  16347 	var elem = $( this ),
  16348 		mode = $.effects.setMode( elem, o.mode || "hide" ),
  16349 		hide = mode === "hide",
  16350 		percent = parseInt( o.percent, 10 ) || 150,
  16351 		factor = percent / 100,
  16352 		original = {
  16353 			height: elem.height(),
  16354 			width: elem.width(),
  16355 			outerHeight: elem.outerHeight(),
  16356 			outerWidth: elem.outerWidth()
  16357 		};
  16358 
  16359 	$.extend( o, {
  16360 		effect: "scale",
  16361 		queue: false,
  16362 		fade: true,
  16363 		mode: mode,
  16364 		complete: done,
  16365 		percent: hide ? percent : 100,
  16366 		from: hide ?
  16367 			original :
  16368 			{
  16369 				height: original.height * factor,
  16370 				width: original.width * factor,
  16371 				outerHeight: original.outerHeight * factor,
  16372 				outerWidth: original.outerWidth * factor
  16373 			}
  16374 	});
  16375 
  16376 	elem.effect( o );
  16377 };
  16378 
  16379 
  16380 /*!
  16381  * jQuery UI Effects Pulsate 1.11.4
  16382  * http://jqueryui.com
  16383  *
  16384  * Copyright jQuery Foundation and other contributors
  16385  * Released under the MIT license.
  16386  * http://jquery.org/license
  16387  *
  16388  * http://api.jqueryui.com/pulsate-effect/
  16389  */
  16390 
  16391 
  16392 var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
  16393 	var elem = $( this ),
  16394 		mode = $.effects.setMode( elem, o.mode || "show" ),
  16395 		show = mode === "show",
  16396 		hide = mode === "hide",
  16397 		showhide = ( show || mode === "hide" ),
  16398 
  16399 		// showing or hiding leaves of the "last" animation
  16400 		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
  16401 		duration = o.duration / anims,
  16402 		animateTo = 0,
  16403 		queue = elem.queue(),
  16404 		queuelen = queue.length,
  16405 		i;
  16406 
  16407 	if ( show || !elem.is(":visible")) {
  16408 		elem.css( "opacity", 0 ).show();
  16409 		animateTo = 1;
  16410 	}
  16411 
  16412 	// anims - 1 opacity "toggles"
  16413 	for ( i = 1; i < anims; i++ ) {
  16414 		elem.animate({
  16415 			opacity: animateTo
  16416 		}, duration, o.easing );
  16417 		animateTo = 1 - animateTo;
  16418 	}
  16419 
  16420 	elem.animate({
  16421 		opacity: animateTo
  16422 	}, duration, o.easing);
  16423 
  16424 	elem.queue(function() {
  16425 		if ( hide ) {
  16426 			elem.hide();
  16427 		}
  16428 		done();
  16429 	});
  16430 
  16431 	// We just queued up "anims" animations, we need to put them next in the queue
  16432 	if ( queuelen > 1 ) {
  16433 		queue.splice.apply( queue,
  16434 			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  16435 	}
  16436 	elem.dequeue();
  16437 };
  16438 
  16439 
  16440 /*!
  16441  * jQuery UI Effects Shake 1.11.4
  16442  * http://jqueryui.com
  16443  *
  16444  * Copyright jQuery Foundation and other contributors
  16445  * Released under the MIT license.
  16446  * http://jquery.org/license
  16447  *
  16448  * http://api.jqueryui.com/shake-effect/
  16449  */
  16450 
  16451 
  16452 var effectShake = $.effects.effect.shake = function( o, done ) {
  16453 
  16454 	var el = $( this ),
  16455 		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
  16456 		mode = $.effects.setMode( el, o.mode || "effect" ),
  16457 		direction = o.direction || "left",
  16458 		distance = o.distance || 20,
  16459 		times = o.times || 3,
  16460 		anims = times * 2 + 1,
  16461 		speed = Math.round( o.duration / anims ),
  16462 		ref = (direction === "up" || direction === "down") ? "top" : "left",
  16463 		positiveMotion = (direction === "up" || direction === "left"),
  16464 		animation = {},
  16465 		animation1 = {},
  16466 		animation2 = {},
  16467 		i,
  16468 
  16469 		// we will need to re-assemble the queue to stack our animations in place
  16470 		queue = el.queue(),
  16471 		queuelen = queue.length;
  16472 
  16473 	$.effects.save( el, props );
  16474 	el.show();
  16475 	$.effects.createWrapper( el );
  16476 
  16477 	// Animation
  16478 	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
  16479 	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
  16480 	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
  16481 
  16482 	// Animate
  16483 	el.animate( animation, speed, o.easing );
  16484 
  16485 	// Shakes
  16486 	for ( i = 1; i < times; i++ ) {
  16487 		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
  16488 	}
  16489 	el
  16490 		.animate( animation1, speed, o.easing )
  16491 		.animate( animation, speed / 2, o.easing )
  16492 		.queue(function() {
  16493 			if ( mode === "hide" ) {
  16494 				el.hide();
  16495 			}
  16496 			$.effects.restore( el, props );
  16497 			$.effects.removeWrapper( el );
  16498 			done();
  16499 		});
  16500 
  16501 	// inject all the animations we just queued to be first in line (after "inprogress")
  16502 	if ( queuelen > 1) {
  16503 		queue.splice.apply( queue,
  16504 			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
  16505 	}
  16506 	el.dequeue();
  16507 
  16508 };
  16509 
  16510 
  16511 /*!
  16512  * jQuery UI Effects Slide 1.11.4
  16513  * http://jqueryui.com
  16514  *
  16515  * Copyright jQuery Foundation and other contributors
  16516  * Released under the MIT license.
  16517  * http://jquery.org/license
  16518  *
  16519  * http://api.jqueryui.com/slide-effect/
  16520  */
  16521 
  16522 
  16523 var effectSlide = $.effects.effect.slide = function( o, done ) {
  16524 
  16525 	// Create element
  16526 	var el = $( this ),
  16527 		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
  16528 		mode = $.effects.setMode( el, o.mode || "show" ),
  16529 		show = mode === "show",
  16530 		direction = o.direction || "left",
  16531 		ref = (direction === "up" || direction === "down") ? "top" : "left",
  16532 		positiveMotion = (direction === "up" || direction === "left"),
  16533 		distance,
  16534 		animation = {};
  16535 
  16536 	// Adjust
  16537 	$.effects.save( el, props );
  16538 	el.show();
  16539 	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
  16540 
  16541 	$.effects.createWrapper( el ).css({
  16542 		overflow: "hidden"
  16543 	});
  16544 
  16545 	if ( show ) {
  16546 		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
  16547 	}
  16548 
  16549 	// Animation
  16550 	animation[ ref ] = ( show ?
  16551 		( positiveMotion ? "+=" : "-=") :
  16552 		( positiveMotion ? "-=" : "+=")) +
  16553 		distance;
  16554 
  16555 	// Animate
  16556 	el.animate( animation, {
  16557 		queue: false,
  16558 		duration: o.duration,
  16559 		easing: o.easing,
  16560 		complete: function() {
  16561 			if ( mode === "hide" ) {
  16562 				el.hide();
  16563 			}
  16564 			$.effects.restore( el, props );
  16565 			$.effects.removeWrapper( el );
  16566 			done();
  16567 		}
  16568 	});
  16569 };
  16570 
  16571 
  16572 /*!
  16573  * jQuery UI Effects Transfer 1.11.4
  16574  * http://jqueryui.com
  16575  *
  16576  * Copyright jQuery Foundation and other contributors
  16577  * Released under the MIT license.
  16578  * http://jquery.org/license
  16579  *
  16580  * http://api.jqueryui.com/transfer-effect/
  16581  */
  16582 
  16583 
  16584 var effectTransfer = $.effects.effect.transfer = function( o, done ) {
  16585 	var elem = $( this ),
  16586 		target = $( o.to ),
  16587 		targetFixed = target.css( "position" ) === "fixed",
  16588 		body = $("body"),
  16589 		fixTop = targetFixed ? body.scrollTop() : 0,
  16590 		fixLeft = targetFixed ? body.scrollLeft() : 0,
  16591 		endPosition = target.offset(),
  16592 		animation = {
  16593 			top: endPosition.top - fixTop,
  16594 			left: endPosition.left - fixLeft,
  16595 			height: target.innerHeight(),
  16596 			width: target.innerWidth()
  16597 		},
  16598 		startPosition = elem.offset(),
  16599 		transfer = $( "<div class='ui-effects-transfer'></div>" )
  16600 			.appendTo( document.body )
  16601 			.addClass( o.className )
  16602 			.css({
  16603 				top: startPosition.top - fixTop,
  16604 				left: startPosition.left - fixLeft,
  16605 				height: elem.innerHeight(),
  16606 				width: elem.innerWidth(),
  16607 				position: targetFixed ? "fixed" : "absolute"
  16608 			})
  16609 			.animate( animation, o.duration, o.easing, function() {
  16610 				transfer.remove();
  16611 				done();
  16612 			});
  16613 };
  16614 
  16615 
  16616 
  16617 }));