angelovcom.net

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

core.js (48955B)


      1 /*! jQuery UI - v1.12.1 - 2020-09-25
      2 * http://jqueryui.com
      3 * Includes: data.js, disable-selection.js, escape-selector.js, focusable.js, form-reset-mixin.js, form.js, ie.js, jquery-1-7.js, keycode.js, labels.js, plugin.js, position.js, safe-active-element.js, safe-blur.js, scroll-parent.js, tabbable.js, unique-id.js, version.js, widget.js
      4 * Copyright jQuery Foundation and other contributors; Licensed  */
      5 ( function( factory ) {
      6 	if ( typeof define === "function" && define.amd ) {
      7 
      8 		// AMD. Register as an anonymous module.
      9 		define( [ "jquery" ], factory );
     10 	} else {
     11 
     12 		// Browser globals
     13 		factory( jQuery );
     14 	}
     15 } ( function( $ ) {
     16 
     17 // Source: version.js
     18 $.ui = $.ui || {};
     19 
     20 $.ui.version = "1.12.1";
     21 
     22 // Source: data.js
     23 /*!
     24  * jQuery UI :data 1.12.1
     25  * http://jqueryui.com
     26  *
     27  * Copyright jQuery Foundation and other contributors
     28  * Released under the MIT license.
     29  * http://jquery.org/license
     30  */
     31 
     32 //>>label: :data Selector
     33 //>>group: Core
     34 //>>description: Selects elements which have data stored under the specified key.
     35 //>>docs: http://api.jqueryui.com/data-selector/
     36 
     37 $.extend( $.expr[ ":" ], {
     38 	data: $.expr.createPseudo ?
     39 		$.expr.createPseudo( function( dataName ) {
     40 			return function( elem ) {
     41 				return !!$.data( elem, dataName );
     42 			};
     43 		} ) :
     44 
     45 		// Support: jQuery <1.8
     46 		function( elem, i, match ) {
     47 			return !!$.data( elem, match[ 3 ] );
     48 		}
     49 } );
     50 
     51 
     52 // Source: disable-selection.js
     53 /*!
     54  * jQuery UI Disable Selection 1.12.1
     55  * http://jqueryui.com
     56  *
     57  * Copyright jQuery Foundation and other contributors
     58  * Released under the MIT license.
     59  * http://jquery.org/license
     60  */
     61 
     62 //>>label: disableSelection
     63 //>>group: Core
     64 //>>description: Disable selection of text content within the set of matched elements.
     65 //>>docs: http://api.jqueryui.com/disableSelection/
     66 
     67 // This file is deprecated
     68 $.fn.extend( {
     69 	disableSelection: ( function() {
     70 		var eventType = "onselectstart" in document.createElement( "div" ) ?
     71 			"selectstart" :
     72 			"mousedown";
     73 
     74 		return function() {
     75 			return this.on( eventType + ".ui-disableSelection", function( event ) {
     76 				event.preventDefault();
     77 			} );
     78 		};
     79 	} )(),
     80 
     81 	enableSelection: function() {
     82 		return this.off( ".ui-disableSelection" );
     83 	}
     84 } );
     85 
     86 // Source: escape-selector.js
     87 // Internal use only
     88 $.ui.escapeSelector = ( function() {
     89 	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
     90 	return function( selector ) {
     91 		return selector.replace( selectorEscape, "\\$1" );
     92 	};
     93 } )();
     94 
     95 // Source: focusable.js
     96 /*!
     97  * jQuery UI Focusable 1.12.1
     98  * http://jqueryui.com
     99  *
    100  * Copyright jQuery Foundation and other contributors
    101  * Released under the MIT license.
    102  * http://jquery.org/license
    103  */
    104 
    105 //>>label: :focusable Selector
    106 //>>group: Core
    107 //>>description: Selects elements which can be focused.
    108 //>>docs: http://api.jqueryui.com/focusable-selector/
    109 
    110 // Selectors
    111 $.ui.focusable = function( element, hasTabindex ) {
    112 	var map, mapName, img, focusableIfVisible, fieldset,
    113 		nodeName = element.nodeName.toLowerCase();
    114 
    115 	if ( "area" === nodeName ) {
    116 		map = element.parentNode;
    117 		mapName = map.name;
    118 		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
    119 			return false;
    120 		}
    121 		img = $( "img[usemap='#" + mapName + "']" );
    122 		return img.length > 0 && img.is( ":visible" );
    123 	}
    124 
    125 	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
    126 		focusableIfVisible = !element.disabled;
    127 
    128 		if ( focusableIfVisible ) {
    129 
    130 			// Form controls within a disabled fieldset are disabled.
    131 			// However, controls within the fieldset's legend do not get disabled.
    132 			// Since controls generally aren't placed inside legends, we skip
    133 			// this portion of the check.
    134 			fieldset = $( element ).closest( "fieldset" )[ 0 ];
    135 			if ( fieldset ) {
    136 				focusableIfVisible = !fieldset.disabled;
    137 			}
    138 		}
    139 	} else if ( "a" === nodeName ) {
    140 		focusableIfVisible = element.href || hasTabindex;
    141 	} else {
    142 		focusableIfVisible = hasTabindex;
    143 	}
    144 
    145 	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
    146 };
    147 
    148 // Support: IE 8 only
    149 // IE 8 doesn't resolve inherit to visible/hidden for computed values
    150 function visible( element ) {
    151 	var visibility = element.css( "visibility" );
    152 	while ( visibility === "inherit" ) {
    153 		element = element.parent();
    154 		visibility = element.css( "visibility" );
    155 	}
    156 	return visibility !== "hidden";
    157 }
    158 
    159 $.extend( $.expr[ ":" ], {
    160 	focusable: function( element ) {
    161 		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
    162 	}
    163 } );
    164 
    165 // Source: form.js
    166 // Support: IE8 Only
    167 // IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
    168 // with a string, so we need to find the proper form.
    169 $.fn.form = function() {
    170 	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
    171 };
    172 
    173 // Source: form-reset-mixin.js
    174 /*!
    175  * jQuery UI Form Reset Mixin 1.12.1
    176  * http://jqueryui.com
    177  *
    178  * Copyright jQuery Foundation and other contributors
    179  * Released under the MIT license.
    180  * http://jquery.org/license
    181  */
    182 
    183 //>>label: Form Reset Mixin
    184 //>>group: Core
    185 //>>description: Refresh input widgets when their form is reset
    186 //>>docs: http://api.jqueryui.com/form-reset-mixin/
    187 
    188 $.ui.formResetMixin = {
    189 	_formResetHandler: function() {
    190 		var form = $( this );
    191 
    192 		// Wait for the form reset to actually happen before refreshing
    193 		setTimeout( function() {
    194 			var instances = form.data( "ui-form-reset-instances" );
    195 			$.each( instances, function() {
    196 				this.refresh();
    197 			} );
    198 		} );
    199 	},
    200 
    201 	_bindFormResetHandler: function() {
    202 		this.form = this.element.form();
    203 		if ( !this.form.length ) {
    204 			return;
    205 		}
    206 
    207 		var instances = this.form.data( "ui-form-reset-instances" ) || [];
    208 		if ( !instances.length ) {
    209 
    210 			// We don't use _on() here because we use a single event handler per form
    211 			this.form.on( "reset.ui-form-reset", this._formResetHandler );
    212 		}
    213 		instances.push( this );
    214 		this.form.data( "ui-form-reset-instances", instances );
    215 	},
    216 
    217 	_unbindFormResetHandler: function() {
    218 		if ( !this.form.length ) {
    219 			return;
    220 		}
    221 
    222 		var instances = this.form.data( "ui-form-reset-instances" );
    223 		instances.splice( $.inArray( this, instances ), 1 );
    224 		if ( instances.length ) {
    225 			this.form.data( "ui-form-reset-instances", instances );
    226 		} else {
    227 			this.form
    228 				.removeData( "ui-form-reset-instances" )
    229 				.off( "reset.ui-form-reset" );
    230 		}
    231 	}
    232 };
    233 
    234 // Source: ie.js
    235 // This file is deprecated
    236 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
    237 
    238 // Source: jquery-1-7.js
    239 /*!
    240  * jQuery UI Support for jQuery core 1.7.x 1.12.1
    241  * http://jqueryui.com
    242  *
    243  * Copyright jQuery Foundation and other contributors
    244  * Released under the MIT license.
    245  * http://jquery.org/license
    246  *
    247  */
    248 
    249 //>>label: jQuery 1.7 Support
    250 //>>group: Core
    251 //>>description: Support version 1.7.x of jQuery core
    252 
    253 // Support: jQuery 1.7 only
    254 // Not a great way to check versions, but since we only support 1.7+ and only
    255 // need to detect <1.8, this is a simple check that should suffice. Checking
    256 // for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
    257 // and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
    258 // 1.7 anymore). See #11197 for why we're not using feature detection.
    259 if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
    260 
    261 	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
    262 	// Unlike jQuery Core 1.8+, these only support numeric values to set the
    263 	// dimensions in pixels
    264 	$.each( [ "Width", "Height" ], function( i, name ) {
    265 		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
    266 			type = name.toLowerCase(),
    267 			orig = {
    268 				innerWidth: $.fn.innerWidth,
    269 				innerHeight: $.fn.innerHeight,
    270 				outerWidth: $.fn.outerWidth,
    271 				outerHeight: $.fn.outerHeight
    272 			};
    273 
    274 		function reduce( elem, size, border, margin ) {
    275 			$.each( side, function() {
    276 				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
    277 				if ( border ) {
    278 					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
    279 				}
    280 				if ( margin ) {
    281 					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
    282 				}
    283 			} );
    284 			return size;
    285 		}
    286 
    287 		$.fn[ "inner" + name ] = function( size ) {
    288 			if ( size === undefined ) {
    289 				return orig[ "inner" + name ].call( this );
    290 			}
    291 
    292 			return this.each( function() {
    293 				$( this ).css( type, reduce( this, size ) + "px" );
    294 			} );
    295 		};
    296 
    297 		$.fn[ "outer" + name ] = function( size, margin ) {
    298 			if ( typeof size !== "number" ) {
    299 				return orig[ "outer" + name ].call( this, size );
    300 			}
    301 
    302 			return this.each( function() {
    303 				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
    304 			} );
    305 		};
    306 	} );
    307 
    308 	$.fn.addBack = function( selector ) {
    309 		return this.add( selector == null ?
    310 			this.prevObject : this.prevObject.filter( selector )
    311 		);
    312 	};
    313 }
    314 
    315 // Source: keycode.js
    316 /*!
    317  * jQuery UI Keycode 1.12.1
    318  * http://jqueryui.com
    319  *
    320  * Copyright jQuery Foundation and other contributors
    321  * Released under the MIT license.
    322  * http://jquery.org/license
    323  */
    324 
    325 //>>label: Keycode
    326 //>>group: Core
    327 //>>description: Provide keycodes as keynames
    328 //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
    329 
    330 $.ui.keyCode = {
    331 	BACKSPACE: 8,
    332 	COMMA: 188,
    333 	DELETE: 46,
    334 	DOWN: 40,
    335 	END: 35,
    336 	ENTER: 13,
    337 	ESCAPE: 27,
    338 	HOME: 36,
    339 	LEFT: 37,
    340 	PAGE_DOWN: 34,
    341 	PAGE_UP: 33,
    342 	PERIOD: 190,
    343 	RIGHT: 39,
    344 	SPACE: 32,
    345 	TAB: 9,
    346 	UP: 38
    347 };
    348 
    349 // Source: labels.js
    350 /*!
    351  * jQuery UI Labels 1.12.1
    352  * http://jqueryui.com
    353  *
    354  * Copyright jQuery Foundation and other contributors
    355  * Released under the MIT license.
    356  * http://jquery.org/license
    357  */
    358 
    359 //>>label: labels
    360 //>>group: Core
    361 //>>description: Find all the labels associated with a given input
    362 //>>docs: http://api.jqueryui.com/labels/
    363 
    364 $.fn.labels = function() {
    365 	var ancestor, selector, id, labels, ancestors;
    366 
    367 	// Check control.labels first
    368 	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
    369 		return this.pushStack( this[ 0 ].labels );
    370 	}
    371 
    372 	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
    373 	// Above browsers do not support control.labels. Everything below is to support them
    374 	// as well as document fragments. control.labels does not work on document fragments
    375 	labels = this.eq( 0 ).parents( "label" );
    376 
    377 	// Look for the label based on the id
    378 	id = this.attr( "id" );
    379 	if ( id ) {
    380 
    381 		// We don't search against the document in case the element
    382 		// is disconnected from the DOM
    383 		ancestor = this.eq( 0 ).parents().last();
    384 
    385 		// Get a full set of top level ancestors
    386 		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
    387 
    388 		// Create a selector for the label based on the id
    389 		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
    390 
    391 		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
    392 
    393 	}
    394 
    395 	// Return whatever we have found for labels
    396 	return this.pushStack( labels );
    397 };
    398 
    399 // Source: plugin.js
    400 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
    401 $.ui.plugin = {
    402 	add: function( module, option, set ) {
    403 		var i,
    404 			proto = $.ui[ module ].prototype;
    405 		for ( i in set ) {
    406 			proto.plugins[ i ] = proto.plugins[ i ] || [];
    407 			proto.plugins[ i ].push( [ option, set[ i ] ] );
    408 		}
    409 	},
    410 	call: function( instance, name, args, allowDisconnected ) {
    411 		var i,
    412 			set = instance.plugins[ name ];
    413 
    414 		if ( !set ) {
    415 			return;
    416 		}
    417 
    418 		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
    419 				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
    420 			return;
    421 		}
    422 
    423 		for ( i = 0; i < set.length; i++ ) {
    424 			if ( instance.options[ set[ i ][ 0 ] ] ) {
    425 				set[ i ][ 1 ].apply( instance.element, args );
    426 			}
    427 		}
    428 	}
    429 };
    430 
    431 // Source: position.js
    432 /*!
    433  * jQuery UI Position 1.12.1
    434  * http://jqueryui.com
    435  *
    436  * Copyright jQuery Foundation and other contributors
    437  * Released under the MIT license.
    438  * http://jquery.org/license
    439  *
    440  * http://api.jqueryui.com/position/
    441  */
    442 
    443 //>>label: Position
    444 //>>group: Core
    445 //>>description: Positions elements relative to other elements.
    446 //>>docs: http://api.jqueryui.com/position/
    447 //>>demos: http://jqueryui.com/position/
    448 
    449 ( function() {
    450 var cachedScrollbarWidth,
    451 	max = Math.max,
    452 	abs = Math.abs,
    453 	rhorizontal = /left|center|right/,
    454 	rvertical = /top|center|bottom/,
    455 	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
    456 	rposition = /^\w+/,
    457 	rpercent = /%$/,
    458 	_position = $.fn.position;
    459 
    460 function getOffsets( offsets, width, height ) {
    461 	return [
    462 		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
    463 		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
    464 	];
    465 }
    466 
    467 function parseCss( element, property ) {
    468 	return parseInt( $.css( element, property ), 10 ) || 0;
    469 }
    470 
    471 function getDimensions( elem ) {
    472 	var raw = elem[ 0 ];
    473 	if ( raw.nodeType === 9 ) {
    474 		return {
    475 			width: elem.width(),
    476 			height: elem.height(),
    477 			offset: { top: 0, left: 0 }
    478 		};
    479 	}
    480 	if ( $.isWindow( raw ) ) {
    481 		return {
    482 			width: elem.width(),
    483 			height: elem.height(),
    484 			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
    485 		};
    486 	}
    487 	if ( raw.preventDefault ) {
    488 		return {
    489 			width: 0,
    490 			height: 0,
    491 			offset: { top: raw.pageY, left: raw.pageX }
    492 		};
    493 	}
    494 	return {
    495 		width: elem.outerWidth(),
    496 		height: elem.outerHeight(),
    497 		offset: elem.offset()
    498 	};
    499 }
    500 
    501 $.position = {
    502 	scrollbarWidth: function() {
    503 		if ( cachedScrollbarWidth !== undefined ) {
    504 			return cachedScrollbarWidth;
    505 		}
    506 		var w1, w2,
    507 			div = $( "<div " +
    508 				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
    509 				"<div style='height:100px;width:auto;'></div></div>" ),
    510 			innerDiv = div.children()[ 0 ];
    511 
    512 		$( "body" ).append( div );
    513 		w1 = innerDiv.offsetWidth;
    514 		div.css( "overflow", "scroll" );
    515 
    516 		w2 = innerDiv.offsetWidth;
    517 
    518 		if ( w1 === w2 ) {
    519 			w2 = div[ 0 ].clientWidth;
    520 		}
    521 
    522 		div.remove();
    523 
    524 		return ( cachedScrollbarWidth = w1 - w2 );
    525 	},
    526 	getScrollInfo: function( within ) {
    527 		var overflowX = within.isWindow || within.isDocument ? "" :
    528 				within.element.css( "overflow-x" ),
    529 			overflowY = within.isWindow || within.isDocument ? "" :
    530 				within.element.css( "overflow-y" ),
    531 			hasOverflowX = overflowX === "scroll" ||
    532 				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
    533 			hasOverflowY = overflowY === "scroll" ||
    534 				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
    535 		return {
    536 			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
    537 			height: hasOverflowX ? $.position.scrollbarWidth() : 0
    538 		};
    539 	},
    540 	getWithinInfo: function( element ) {
    541 		var withinElement = $( element || window ),
    542 			isWindow = $.isWindow( withinElement[ 0 ] ),
    543 			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
    544 			hasOffset = !isWindow && !isDocument;
    545 		return {
    546 			element: withinElement,
    547 			isWindow: isWindow,
    548 			isDocument: isDocument,
    549 			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
    550 			scrollLeft: withinElement.scrollLeft(),
    551 			scrollTop: withinElement.scrollTop(),
    552 			width: withinElement.outerWidth(),
    553 			height: withinElement.outerHeight()
    554 		};
    555 	}
    556 };
    557 
    558 $.fn.position = function( options ) {
    559 	if ( !options || !options.of ) {
    560 		return _position.apply( this, arguments );
    561 	}
    562 
    563 	// Make a copy, we don't want to modify arguments
    564 	options = $.extend( {}, options );
    565 
    566 	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
    567 		target = $( options.of ),
    568 		within = $.position.getWithinInfo( options.within ),
    569 		scrollInfo = $.position.getScrollInfo( within ),
    570 		collision = ( options.collision || "flip" ).split( " " ),
    571 		offsets = {};
    572 
    573 	dimensions = getDimensions( target );
    574 	if ( target[ 0 ].preventDefault ) {
    575 
    576 		// Force left top to allow flipping
    577 		options.at = "left top";
    578 	}
    579 	targetWidth = dimensions.width;
    580 	targetHeight = dimensions.height;
    581 	targetOffset = dimensions.offset;
    582 
    583 	// Clone to reuse original targetOffset later
    584 	basePosition = $.extend( {}, targetOffset );
    585 
    586 	// Force my and at to have valid horizontal and vertical positions
    587 	// if a value is missing or invalid, it will be converted to center
    588 	$.each( [ "my", "at" ], function() {
    589 		var pos = ( options[ this ] || "" ).split( " " ),
    590 			horizontalOffset,
    591 			verticalOffset;
    592 
    593 		if ( pos.length === 1 ) {
    594 			pos = rhorizontal.test( pos[ 0 ] ) ?
    595 				pos.concat( [ "center" ] ) :
    596 				rvertical.test( pos[ 0 ] ) ?
    597 					[ "center" ].concat( pos ) :
    598 					[ "center", "center" ];
    599 		}
    600 		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
    601 		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
    602 
    603 		// Calculate offsets
    604 		horizontalOffset = roffset.exec( pos[ 0 ] );
    605 		verticalOffset = roffset.exec( pos[ 1 ] );
    606 		offsets[ this ] = [
    607 			horizontalOffset ? horizontalOffset[ 0 ] : 0,
    608 			verticalOffset ? verticalOffset[ 0 ] : 0
    609 		];
    610 
    611 		// Reduce to just the positions without the offsets
    612 		options[ this ] = [
    613 			rposition.exec( pos[ 0 ] )[ 0 ],
    614 			rposition.exec( pos[ 1 ] )[ 0 ]
    615 		];
    616 	} );
    617 
    618 	// Normalize collision option
    619 	if ( collision.length === 1 ) {
    620 		collision[ 1 ] = collision[ 0 ];
    621 	}
    622 
    623 	if ( options.at[ 0 ] === "right" ) {
    624 		basePosition.left += targetWidth;
    625 	} else if ( options.at[ 0 ] === "center" ) {
    626 		basePosition.left += targetWidth / 2;
    627 	}
    628 
    629 	if ( options.at[ 1 ] === "bottom" ) {
    630 		basePosition.top += targetHeight;
    631 	} else if ( options.at[ 1 ] === "center" ) {
    632 		basePosition.top += targetHeight / 2;
    633 	}
    634 
    635 	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
    636 	basePosition.left += atOffset[ 0 ];
    637 	basePosition.top += atOffset[ 1 ];
    638 
    639 	return this.each( function() {
    640 		var collisionPosition, using,
    641 			elem = $( this ),
    642 			elemWidth = elem.outerWidth(),
    643 			elemHeight = elem.outerHeight(),
    644 			marginLeft = parseCss( this, "marginLeft" ),
    645 			marginTop = parseCss( this, "marginTop" ),
    646 			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
    647 				scrollInfo.width,
    648 			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
    649 				scrollInfo.height,
    650 			position = $.extend( {}, basePosition ),
    651 			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
    652 
    653 		if ( options.my[ 0 ] === "right" ) {
    654 			position.left -= elemWidth;
    655 		} else if ( options.my[ 0 ] === "center" ) {
    656 			position.left -= elemWidth / 2;
    657 		}
    658 
    659 		if ( options.my[ 1 ] === "bottom" ) {
    660 			position.top -= elemHeight;
    661 		} else if ( options.my[ 1 ] === "center" ) {
    662 			position.top -= elemHeight / 2;
    663 		}
    664 
    665 		position.left += myOffset[ 0 ];
    666 		position.top += myOffset[ 1 ];
    667 
    668 		collisionPosition = {
    669 			marginLeft: marginLeft,
    670 			marginTop: marginTop
    671 		};
    672 
    673 		$.each( [ "left", "top" ], function( i, dir ) {
    674 			if ( $.ui.position[ collision[ i ] ] ) {
    675 				$.ui.position[ collision[ i ] ][ dir ]( position, {
    676 					targetWidth: targetWidth,
    677 					targetHeight: targetHeight,
    678 					elemWidth: elemWidth,
    679 					elemHeight: elemHeight,
    680 					collisionPosition: collisionPosition,
    681 					collisionWidth: collisionWidth,
    682 					collisionHeight: collisionHeight,
    683 					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
    684 					my: options.my,
    685 					at: options.at,
    686 					within: within,
    687 					elem: elem
    688 				} );
    689 			}
    690 		} );
    691 
    692 		if ( options.using ) {
    693 
    694 			// Adds feedback as second argument to using callback, if present
    695 			using = function( props ) {
    696 				var left = targetOffset.left - position.left,
    697 					right = left + targetWidth - elemWidth,
    698 					top = targetOffset.top - position.top,
    699 					bottom = top + targetHeight - elemHeight,
    700 					feedback = {
    701 						target: {
    702 							element: target,
    703 							left: targetOffset.left,
    704 							top: targetOffset.top,
    705 							width: targetWidth,
    706 							height: targetHeight
    707 						},
    708 						element: {
    709 							element: elem,
    710 							left: position.left,
    711 							top: position.top,
    712 							width: elemWidth,
    713 							height: elemHeight
    714 						},
    715 						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
    716 						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
    717 					};
    718 				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
    719 					feedback.horizontal = "center";
    720 				}
    721 				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
    722 					feedback.vertical = "middle";
    723 				}
    724 				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
    725 					feedback.important = "horizontal";
    726 				} else {
    727 					feedback.important = "vertical";
    728 				}
    729 				options.using.call( this, props, feedback );
    730 			};
    731 		}
    732 
    733 		elem.offset( $.extend( position, { using: using } ) );
    734 	} );
    735 };
    736 
    737 $.ui.position = {
    738 	fit: {
    739 		left: function( position, data ) {
    740 			var within = data.within,
    741 				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
    742 				outerWidth = within.width,
    743 				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
    744 				overLeft = withinOffset - collisionPosLeft,
    745 				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
    746 				newOverRight;
    747 
    748 			// Element is wider than within
    749 			if ( data.collisionWidth > outerWidth ) {
    750 
    751 				// Element is initially over the left side of within
    752 				if ( overLeft > 0 && overRight <= 0 ) {
    753 					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
    754 						withinOffset;
    755 					position.left += overLeft - newOverRight;
    756 
    757 				// Element is initially over right side of within
    758 				} else if ( overRight > 0 && overLeft <= 0 ) {
    759 					position.left = withinOffset;
    760 
    761 				// Element is initially over both left and right sides of within
    762 				} else {
    763 					if ( overLeft > overRight ) {
    764 						position.left = withinOffset + outerWidth - data.collisionWidth;
    765 					} else {
    766 						position.left = withinOffset;
    767 					}
    768 				}
    769 
    770 			// Too far left -> align with left edge
    771 			} else if ( overLeft > 0 ) {
    772 				position.left += overLeft;
    773 
    774 			// Too far right -> align with right edge
    775 			} else if ( overRight > 0 ) {
    776 				position.left -= overRight;
    777 
    778 			// Adjust based on position and margin
    779 			} else {
    780 				position.left = max( position.left - collisionPosLeft, position.left );
    781 			}
    782 		},
    783 		top: function( position, data ) {
    784 			var within = data.within,
    785 				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
    786 				outerHeight = data.within.height,
    787 				collisionPosTop = position.top - data.collisionPosition.marginTop,
    788 				overTop = withinOffset - collisionPosTop,
    789 				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
    790 				newOverBottom;
    791 
    792 			// Element is taller than within
    793 			if ( data.collisionHeight > outerHeight ) {
    794 
    795 				// Element is initially over the top of within
    796 				if ( overTop > 0 && overBottom <= 0 ) {
    797 					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
    798 						withinOffset;
    799 					position.top += overTop - newOverBottom;
    800 
    801 				// Element is initially over bottom of within
    802 				} else if ( overBottom > 0 && overTop <= 0 ) {
    803 					position.top = withinOffset;
    804 
    805 				// Element is initially over both top and bottom of within
    806 				} else {
    807 					if ( overTop > overBottom ) {
    808 						position.top = withinOffset + outerHeight - data.collisionHeight;
    809 					} else {
    810 						position.top = withinOffset;
    811 					}
    812 				}
    813 
    814 			// Too far up -> align with top
    815 			} else if ( overTop > 0 ) {
    816 				position.top += overTop;
    817 
    818 			// Too far down -> align with bottom edge
    819 			} else if ( overBottom > 0 ) {
    820 				position.top -= overBottom;
    821 
    822 			// Adjust based on position and margin
    823 			} else {
    824 				position.top = max( position.top - collisionPosTop, position.top );
    825 			}
    826 		}
    827 	},
    828 	flip: {
    829 		left: function( position, data ) {
    830 			var within = data.within,
    831 				withinOffset = within.offset.left + within.scrollLeft,
    832 				outerWidth = within.width,
    833 				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
    834 				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
    835 				overLeft = collisionPosLeft - offsetLeft,
    836 				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
    837 				myOffset = data.my[ 0 ] === "left" ?
    838 					-data.elemWidth :
    839 					data.my[ 0 ] === "right" ?
    840 						data.elemWidth :
    841 						0,
    842 				atOffset = data.at[ 0 ] === "left" ?
    843 					data.targetWidth :
    844 					data.at[ 0 ] === "right" ?
    845 						-data.targetWidth :
    846 						0,
    847 				offset = -2 * data.offset[ 0 ],
    848 				newOverRight,
    849 				newOverLeft;
    850 
    851 			if ( overLeft < 0 ) {
    852 				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
    853 					outerWidth - withinOffset;
    854 				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
    855 					position.left += myOffset + atOffset + offset;
    856 				}
    857 			} else if ( overRight > 0 ) {
    858 				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
    859 					atOffset + offset - offsetLeft;
    860 				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
    861 					position.left += myOffset + atOffset + offset;
    862 				}
    863 			}
    864 		},
    865 		top: function( position, data ) {
    866 			var within = data.within,
    867 				withinOffset = within.offset.top + within.scrollTop,
    868 				outerHeight = within.height,
    869 				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
    870 				collisionPosTop = position.top - data.collisionPosition.marginTop,
    871 				overTop = collisionPosTop - offsetTop,
    872 				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
    873 				top = data.my[ 1 ] === "top",
    874 				myOffset = top ?
    875 					-data.elemHeight :
    876 					data.my[ 1 ] === "bottom" ?
    877 						data.elemHeight :
    878 						0,
    879 				atOffset = data.at[ 1 ] === "top" ?
    880 					data.targetHeight :
    881 					data.at[ 1 ] === "bottom" ?
    882 						-data.targetHeight :
    883 						0,
    884 				offset = -2 * data.offset[ 1 ],
    885 				newOverTop,
    886 				newOverBottom;
    887 			if ( overTop < 0 ) {
    888 				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
    889 					outerHeight - withinOffset;
    890 				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
    891 					position.top += myOffset + atOffset + offset;
    892 				}
    893 			} else if ( overBottom > 0 ) {
    894 				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
    895 					offset - offsetTop;
    896 				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
    897 					position.top += myOffset + atOffset + offset;
    898 				}
    899 			}
    900 		}
    901 	},
    902 	flipfit: {
    903 		left: function() {
    904 			$.ui.position.flip.left.apply( this, arguments );
    905 			$.ui.position.fit.left.apply( this, arguments );
    906 		},
    907 		top: function() {
    908 			$.ui.position.flip.top.apply( this, arguments );
    909 			$.ui.position.fit.top.apply( this, arguments );
    910 		}
    911 	}
    912 };
    913 
    914 } )();
    915 
    916 // Source: safe-active-element.js
    917 $.ui.safeActiveElement = function( document ) {
    918 	var activeElement;
    919 
    920 	// Support: IE 9 only
    921 	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
    922 	try {
    923 		activeElement = document.activeElement;
    924 	} catch ( error ) {
    925 		activeElement = document.body;
    926 	}
    927 
    928 	// Support: IE 9 - 11 only
    929 	// IE may return null instead of an element
    930 	// Interestingly, this only seems to occur when NOT in an iframe
    931 	if ( !activeElement ) {
    932 		activeElement = document.body;
    933 	}
    934 
    935 	// Support: IE 11 only
    936 	// IE11 returns a seemingly empty object in some cases when accessing
    937 	// document.activeElement from an <iframe>
    938 	if ( !activeElement.nodeName ) {
    939 		activeElement = document.body;
    940 	}
    941 
    942 	return activeElement;
    943 };
    944 
    945 // Source: safe-blur.js
    946 $.ui.safeBlur = function( element ) {
    947 
    948 	// Support: IE9 - 10 only
    949 	// If the <body> is blurred, IE will switch windows, see #9420
    950 	if ( element && element.nodeName.toLowerCase() !== "body" ) {
    951 		$( element ).trigger( "blur" );
    952 	}
    953 };
    954 
    955 // Source: scroll-parent.js
    956 /*!
    957  * jQuery UI Scroll Parent 1.12.1
    958  * http://jqueryui.com
    959  *
    960  * Copyright jQuery Foundation and other contributors
    961  * Released under the MIT license.
    962  * http://jquery.org/license
    963  */
    964 
    965 //>>label: scrollParent
    966 //>>group: Core
    967 //>>description: Get the closest ancestor element that is scrollable.
    968 //>>docs: http://api.jqueryui.com/scrollParent/
    969 
    970 $.fn.scrollParent = function( includeHidden ) {
    971 	var position = this.css( "position" ),
    972 		excludeStaticParent = position === "absolute",
    973 		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
    974 		scrollParent = this.parents().filter( function() {
    975 			var parent = $( this );
    976 			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
    977 				return false;
    978 			}
    979 			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
    980 				parent.css( "overflow-x" ) );
    981 		} ).eq( 0 );
    982 
    983 	return position === "fixed" || !scrollParent.length ?
    984 		$( this[ 0 ].ownerDocument || document ) :
    985 		scrollParent;
    986 };
    987 
    988 // Source: tabbable.js
    989 /*!
    990  * jQuery UI Tabbable 1.12.1
    991  * http://jqueryui.com
    992  *
    993  * Copyright jQuery Foundation and other contributors
    994  * Released under the MIT license.
    995  * http://jquery.org/license
    996  */
    997 
    998 //>>label: :tabbable Selector
    999 //>>group: Core
   1000 //>>description: Selects elements which can be tabbed to.
   1001 //>>docs: http://api.jqueryui.com/tabbable-selector/
   1002 
   1003 $.extend( $.expr[ ":" ], {
   1004 	tabbable: function( element ) {
   1005 		var tabIndex = $.attr( element, "tabindex" ),
   1006 			hasTabindex = tabIndex != null;
   1007 		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
   1008 	}
   1009 } );
   1010 
   1011 // Source: unique-id.js
   1012 /*!
   1013  * jQuery UI Unique ID 1.12.1
   1014  * http://jqueryui.com
   1015  *
   1016  * Copyright jQuery Foundation and other contributors
   1017  * Released under the MIT license.
   1018  * http://jquery.org/license
   1019  */
   1020 
   1021 //>>label: uniqueId
   1022 //>>group: Core
   1023 //>>description: Functions to generate and remove uniqueId's
   1024 //>>docs: http://api.jqueryui.com/uniqueId/
   1025 
   1026 $.fn.extend( {
   1027 	uniqueId: ( function() {
   1028 		var uuid = 0;
   1029 
   1030 		return function() {
   1031 			return this.each( function() {
   1032 				if ( !this.id ) {
   1033 					this.id = "ui-id-" + ( ++uuid );
   1034 				}
   1035 			} );
   1036 		};
   1037 	} )(),
   1038 
   1039 	removeUniqueId: function() {
   1040 		return this.each( function() {
   1041 			if ( /^ui-id-\d+$/.test( this.id ) ) {
   1042 				$( this ).removeAttr( "id" );
   1043 			}
   1044 		} );
   1045 	}
   1046 } );
   1047 
   1048 // Source: widget.js
   1049 /*!
   1050  * jQuery UI Widget 1.12.1
   1051  * http://jqueryui.com
   1052  *
   1053  * Copyright jQuery Foundation and other contributors
   1054  * Released under the MIT license.
   1055  * http://jquery.org/license
   1056  */
   1057 
   1058 //>>label: Widget
   1059 //>>group: Core
   1060 //>>description: Provides a factory for creating stateful widgets with a common API.
   1061 //>>docs: http://api.jqueryui.com/jQuery.widget/
   1062 //>>demos: http://jqueryui.com/widget/
   1063 
   1064 var widgetUuid = 0;
   1065 var widgetSlice = Array.prototype.slice;
   1066 
   1067 $.cleanData = ( function( orig ) {
   1068 	return function( elems ) {
   1069 		var events, elem, i;
   1070 		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
   1071 			try {
   1072 
   1073 				// Only trigger remove when necessary to save time
   1074 				events = $._data( elem, "events" );
   1075 				if ( events && events.remove ) {
   1076 					$( elem ).triggerHandler( "remove" );
   1077 				}
   1078 
   1079 			// Http://bugs.jquery.com/ticket/8235
   1080 			} catch ( e ) {}
   1081 		}
   1082 		orig( elems );
   1083 	};
   1084 } )( $.cleanData );
   1085 
   1086 $.widget = function( name, base, prototype ) {
   1087 	var existingConstructor, constructor, basePrototype;
   1088 
   1089 	// ProxiedPrototype allows the provided prototype to remain unmodified
   1090 	// so that it can be used as a mixin for multiple widgets (#8876)
   1091 	var proxiedPrototype = {};
   1092 
   1093 	var namespace = name.split( "." )[ 0 ];
   1094 	name = name.split( "." )[ 1 ];
   1095 	var fullName = namespace + "-" + name;
   1096 
   1097 	if ( !prototype ) {
   1098 		prototype = base;
   1099 		base = $.Widget;
   1100 	}
   1101 
   1102 	if ( $.isArray( prototype ) ) {
   1103 		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
   1104 	}
   1105 
   1106 	// Create selector for plugin
   1107 	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
   1108 		return !!$.data( elem, fullName );
   1109 	};
   1110 
   1111 	$[ namespace ] = $[ namespace ] || {};
   1112 	existingConstructor = $[ namespace ][ name ];
   1113 	constructor = $[ namespace ][ name ] = function( options, element ) {
   1114 
   1115 		// Allow instantiation without "new" keyword
   1116 		if ( !this._createWidget ) {
   1117 			return new constructor( options, element );
   1118 		}
   1119 
   1120 		// Allow instantiation without initializing for simple inheritance
   1121 		// must use "new" keyword (the code above always passes args)
   1122 		if ( arguments.length ) {
   1123 			this._createWidget( options, element );
   1124 		}
   1125 	};
   1126 
   1127 	// Extend with the existing constructor to carry over any static properties
   1128 	$.extend( constructor, existingConstructor, {
   1129 		version: prototype.version,
   1130 
   1131 		// Copy the object used to create the prototype in case we need to
   1132 		// redefine the widget later
   1133 		_proto: $.extend( {}, prototype ),
   1134 
   1135 		// Track widgets that inherit from this widget in case this widget is
   1136 		// redefined after a widget inherits from it
   1137 		_childConstructors: []
   1138 	} );
   1139 
   1140 	basePrototype = new base();
   1141 
   1142 	// We need to make the options hash a property directly on the new instance
   1143 	// otherwise we'll modify the options hash on the prototype that we're
   1144 	// inheriting from
   1145 	basePrototype.options = $.widget.extend( {}, basePrototype.options );
   1146 	$.each( prototype, function( prop, value ) {
   1147 		if ( !$.isFunction( value ) ) {
   1148 			proxiedPrototype[ prop ] = value;
   1149 			return;
   1150 		}
   1151 		proxiedPrototype[ prop ] = ( function() {
   1152 			function _super() {
   1153 				return base.prototype[ prop ].apply( this, arguments );
   1154 			}
   1155 
   1156 			function _superApply( args ) {
   1157 				return base.prototype[ prop ].apply( this, args );
   1158 			}
   1159 
   1160 			return function() {
   1161 				var __super = this._super;
   1162 				var __superApply = this._superApply;
   1163 				var returnValue;
   1164 
   1165 				this._super = _super;
   1166 				this._superApply = _superApply;
   1167 
   1168 				returnValue = value.apply( this, arguments );
   1169 
   1170 				this._super = __super;
   1171 				this._superApply = __superApply;
   1172 
   1173 				return returnValue;
   1174 			};
   1175 		} )();
   1176 	} );
   1177 	constructor.prototype = $.widget.extend( basePrototype, {
   1178 
   1179 		// TODO: remove support for widgetEventPrefix
   1180 		// always use the name + a colon as the prefix, e.g., draggable:start
   1181 		// don't prefix for widgets that aren't DOM-based
   1182 		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
   1183 	}, proxiedPrototype, {
   1184 		constructor: constructor,
   1185 		namespace: namespace,
   1186 		widgetName: name,
   1187 		widgetFullName: fullName
   1188 	} );
   1189 
   1190 	// If this widget is being redefined then we need to find all widgets that
   1191 	// are inheriting from it and redefine all of them so that they inherit from
   1192 	// the new version of this widget. We're essentially trying to replace one
   1193 	// level in the prototype chain.
   1194 	if ( existingConstructor ) {
   1195 		$.each( existingConstructor._childConstructors, function( i, child ) {
   1196 			var childPrototype = child.prototype;
   1197 
   1198 			// Redefine the child widget using the same prototype that was
   1199 			// originally used, but inherit from the new version of the base
   1200 			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
   1201 				child._proto );
   1202 		} );
   1203 
   1204 		// Remove the list of existing child constructors from the old constructor
   1205 		// so the old child constructors can be garbage collected
   1206 		delete existingConstructor._childConstructors;
   1207 	} else {
   1208 		base._childConstructors.push( constructor );
   1209 	}
   1210 
   1211 	$.widget.bridge( name, constructor );
   1212 
   1213 	return constructor;
   1214 };
   1215 
   1216 $.widget.extend = function( target ) {
   1217 	var input = widgetSlice.call( arguments, 1 );
   1218 	var inputIndex = 0;
   1219 	var inputLength = input.length;
   1220 	var key;
   1221 	var value;
   1222 
   1223 	for ( ; inputIndex < inputLength; inputIndex++ ) {
   1224 		for ( key in input[ inputIndex ] ) {
   1225 			value = input[ inputIndex ][ key ];
   1226 			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
   1227 
   1228 				// Clone objects
   1229 				if ( $.isPlainObject( value ) ) {
   1230 					target[ key ] = $.isPlainObject( target[ key ] ) ?
   1231 						$.widget.extend( {}, target[ key ], value ) :
   1232 
   1233 						// Don't extend strings, arrays, etc. with objects
   1234 						$.widget.extend( {}, value );
   1235 
   1236 				// Copy everything else by reference
   1237 				} else {
   1238 					target[ key ] = value;
   1239 				}
   1240 			}
   1241 		}
   1242 	}
   1243 	return target;
   1244 };
   1245 
   1246 $.widget.bridge = function( name, object ) {
   1247 	var fullName = object.prototype.widgetFullName || name;
   1248 	$.fn[ name ] = function( options ) {
   1249 		var isMethodCall = typeof options === "string";
   1250 		var args = widgetSlice.call( arguments, 1 );
   1251 		var returnValue = this;
   1252 
   1253 		if ( isMethodCall ) {
   1254 
   1255 			// If this is an empty collection, we need to have the instance method
   1256 			// return undefined instead of the jQuery instance
   1257 			if ( !this.length && options === "instance" ) {
   1258 				returnValue = undefined;
   1259 			} else {
   1260 				this.each( function() {
   1261 					var methodValue;
   1262 					var instance = $.data( this, fullName );
   1263 
   1264 					if ( options === "instance" ) {
   1265 						returnValue = instance;
   1266 						return false;
   1267 					}
   1268 
   1269 					if ( !instance ) {
   1270 						return $.error( "cannot call methods on " + name +
   1271 							" prior to initialization; " +
   1272 							"attempted to call method '" + options + "'" );
   1273 					}
   1274 
   1275 					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
   1276 						return $.error( "no such method '" + options + "' for " + name +
   1277 							" widget instance" );
   1278 					}
   1279 
   1280 					methodValue = instance[ options ].apply( instance, args );
   1281 
   1282 					if ( methodValue !== instance && methodValue !== undefined ) {
   1283 						returnValue = methodValue && methodValue.jquery ?
   1284 							returnValue.pushStack( methodValue.get() ) :
   1285 							methodValue;
   1286 						return false;
   1287 					}
   1288 				} );
   1289 			}
   1290 		} else {
   1291 
   1292 			// Allow multiple hashes to be passed on init
   1293 			if ( args.length ) {
   1294 				options = $.widget.extend.apply( null, [ options ].concat( args ) );
   1295 			}
   1296 
   1297 			this.each( function() {
   1298 				var instance = $.data( this, fullName );
   1299 				if ( instance ) {
   1300 					instance.option( options || {} );
   1301 					if ( instance._init ) {
   1302 						instance._init();
   1303 					}
   1304 				} else {
   1305 					$.data( this, fullName, new object( options, this ) );
   1306 				}
   1307 			} );
   1308 		}
   1309 
   1310 		return returnValue;
   1311 	};
   1312 };
   1313 
   1314 $.Widget = function( /* options, element */ ) {};
   1315 $.Widget._childConstructors = [];
   1316 
   1317 $.Widget.prototype = {
   1318 	widgetName: "widget",
   1319 	widgetEventPrefix: "",
   1320 	defaultElement: "<div>",
   1321 
   1322 	options: {
   1323 		classes: {},
   1324 		disabled: false,
   1325 
   1326 		// Callbacks
   1327 		create: null
   1328 	},
   1329 
   1330 	_createWidget: function( options, element ) {
   1331 		element = $( element || this.defaultElement || this )[ 0 ];
   1332 		this.element = $( element );
   1333 		this.uuid = widgetUuid++;
   1334 		this.eventNamespace = "." + this.widgetName + this.uuid;
   1335 
   1336 		this.bindings = $();
   1337 		this.hoverable = $();
   1338 		this.focusable = $();
   1339 		this.classesElementLookup = {};
   1340 
   1341 		if ( element !== this ) {
   1342 			$.data( element, this.widgetFullName, this );
   1343 			this._on( true, this.element, {
   1344 				remove: function( event ) {
   1345 					if ( event.target === element ) {
   1346 						this.destroy();
   1347 					}
   1348 				}
   1349 			} );
   1350 			this.document = $( element.style ?
   1351 
   1352 				// Element within the document
   1353 				element.ownerDocument :
   1354 
   1355 				// Element is window or document
   1356 				element.document || element );
   1357 			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
   1358 		}
   1359 
   1360 		this.options = $.widget.extend( {},
   1361 			this.options,
   1362 			this._getCreateOptions(),
   1363 			options );
   1364 
   1365 		this._create();
   1366 
   1367 		if ( this.options.disabled ) {
   1368 			this._setOptionDisabled( this.options.disabled );
   1369 		}
   1370 
   1371 		this._trigger( "create", null, this._getCreateEventData() );
   1372 		this._init();
   1373 	},
   1374 
   1375 	_getCreateOptions: function() {
   1376 		return {};
   1377 	},
   1378 
   1379 	_getCreateEventData: $.noop,
   1380 
   1381 	_create: $.noop,
   1382 
   1383 	_init: $.noop,
   1384 
   1385 	destroy: function() {
   1386 		var that = this;
   1387 
   1388 		this._destroy();
   1389 		$.each( this.classesElementLookup, function( key, value ) {
   1390 			that._removeClass( value, key );
   1391 		} );
   1392 
   1393 		// We can probably remove the unbind calls in 2.0
   1394 		// all event bindings should go through this._on()
   1395 		this.element
   1396 			.off( this.eventNamespace )
   1397 			.removeData( this.widgetFullName );
   1398 		this.widget()
   1399 			.off( this.eventNamespace )
   1400 			.removeAttr( "aria-disabled" );
   1401 
   1402 		// Clean up events and states
   1403 		this.bindings.off( this.eventNamespace );
   1404 	},
   1405 
   1406 	_destroy: $.noop,
   1407 
   1408 	widget: function() {
   1409 		return this.element;
   1410 	},
   1411 
   1412 	option: function( key, value ) {
   1413 		var options = key;
   1414 		var parts;
   1415 		var curOption;
   1416 		var i;
   1417 
   1418 		if ( arguments.length === 0 ) {
   1419 
   1420 			// Don't return a reference to the internal hash
   1421 			return $.widget.extend( {}, this.options );
   1422 		}
   1423 
   1424 		if ( typeof key === "string" ) {
   1425 
   1426 			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
   1427 			options = {};
   1428 			parts = key.split( "." );
   1429 			key = parts.shift();
   1430 			if ( parts.length ) {
   1431 				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
   1432 				for ( i = 0; i < parts.length - 1; i++ ) {
   1433 					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
   1434 					curOption = curOption[ parts[ i ] ];
   1435 				}
   1436 				key = parts.pop();
   1437 				if ( arguments.length === 1 ) {
   1438 					return curOption[ key ] === undefined ? null : curOption[ key ];
   1439 				}
   1440 				curOption[ key ] = value;
   1441 			} else {
   1442 				if ( arguments.length === 1 ) {
   1443 					return this.options[ key ] === undefined ? null : this.options[ key ];
   1444 				}
   1445 				options[ key ] = value;
   1446 			}
   1447 		}
   1448 
   1449 		this._setOptions( options );
   1450 
   1451 		return this;
   1452 	},
   1453 
   1454 	_setOptions: function( options ) {
   1455 		var key;
   1456 
   1457 		for ( key in options ) {
   1458 			this._setOption( key, options[ key ] );
   1459 		}
   1460 
   1461 		return this;
   1462 	},
   1463 
   1464 	_setOption: function( key, value ) {
   1465 		if ( key === "classes" ) {
   1466 			this._setOptionClasses( value );
   1467 		}
   1468 
   1469 		this.options[ key ] = value;
   1470 
   1471 		if ( key === "disabled" ) {
   1472 			this._setOptionDisabled( value );
   1473 		}
   1474 
   1475 		return this;
   1476 	},
   1477 
   1478 	_setOptionClasses: function( value ) {
   1479 		var classKey, elements, currentElements;
   1480 
   1481 		for ( classKey in value ) {
   1482 			currentElements = this.classesElementLookup[ classKey ];
   1483 			if ( value[ classKey ] === this.options.classes[ classKey ] ||
   1484 					!currentElements ||
   1485 					!currentElements.length ) {
   1486 				continue;
   1487 			}
   1488 
   1489 			// We are doing this to create a new jQuery object because the _removeClass() call
   1490 			// on the next line is going to destroy the reference to the current elements being
   1491 			// tracked. We need to save a copy of this collection so that we can add the new classes
   1492 			// below.
   1493 			elements = $( currentElements.get() );
   1494 			this._removeClass( currentElements, classKey );
   1495 
   1496 			// We don't use _addClass() here, because that uses this.options.classes
   1497 			// for generating the string of classes. We want to use the value passed in from
   1498 			// _setOption(), this is the new value of the classes option which was passed to
   1499 			// _setOption(). We pass this value directly to _classes().
   1500 			elements.addClass( this._classes( {
   1501 				element: elements,
   1502 				keys: classKey,
   1503 				classes: value,
   1504 				add: true
   1505 			} ) );
   1506 		}
   1507 	},
   1508 
   1509 	_setOptionDisabled: function( value ) {
   1510 		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
   1511 
   1512 		// If the widget is becoming disabled, then nothing is interactive
   1513 		if ( value ) {
   1514 			this._removeClass( this.hoverable, null, "ui-state-hover" );
   1515 			this._removeClass( this.focusable, null, "ui-state-focus" );
   1516 		}
   1517 	},
   1518 
   1519 	enable: function() {
   1520 		return this._setOptions( { disabled: false } );
   1521 	},
   1522 
   1523 	disable: function() {
   1524 		return this._setOptions( { disabled: true } );
   1525 	},
   1526 
   1527 	_classes: function( options ) {
   1528 		var full = [];
   1529 		var that = this;
   1530 
   1531 		options = $.extend( {
   1532 			element: this.element,
   1533 			classes: this.options.classes || {}
   1534 		}, options );
   1535 
   1536 		function processClassString( classes, checkOption ) {
   1537 			var current, i;
   1538 			for ( i = 0; i < classes.length; i++ ) {
   1539 				current = that.classesElementLookup[ classes[ i ] ] || $();
   1540 				if ( options.add ) {
   1541 					current = $( $.unique( current.get().concat( options.element.get() ) ) );
   1542 				} else {
   1543 					current = $( current.not( options.element ).get() );
   1544 				}
   1545 				that.classesElementLookup[ classes[ i ] ] = current;
   1546 				full.push( classes[ i ] );
   1547 				if ( checkOption && options.classes[ classes[ i ] ] ) {
   1548 					full.push( options.classes[ classes[ i ] ] );
   1549 				}
   1550 			}
   1551 		}
   1552 
   1553 		this._on( options.element, {
   1554 			"remove": "_untrackClassesElement"
   1555 		} );
   1556 
   1557 		if ( options.keys ) {
   1558 			processClassString( options.keys.match( /\S+/g ) || [], true );
   1559 		}
   1560 		if ( options.extra ) {
   1561 			processClassString( options.extra.match( /\S+/g ) || [] );
   1562 		}
   1563 
   1564 		return full.join( " " );
   1565 	},
   1566 
   1567 	_untrackClassesElement: function( event ) {
   1568 		var that = this;
   1569 		$.each( that.classesElementLookup, function( key, value ) {
   1570 			if ( $.inArray( event.target, value ) !== -1 ) {
   1571 				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
   1572 			}
   1573 		} );
   1574 	},
   1575 
   1576 	_removeClass: function( element, keys, extra ) {
   1577 		return this._toggleClass( element, keys, extra, false );
   1578 	},
   1579 
   1580 	_addClass: function( element, keys, extra ) {
   1581 		return this._toggleClass( element, keys, extra, true );
   1582 	},
   1583 
   1584 	_toggleClass: function( element, keys, extra, add ) {
   1585 		add = ( typeof add === "boolean" ) ? add : extra;
   1586 		var shift = ( typeof element === "string" || element === null ),
   1587 			options = {
   1588 				extra: shift ? keys : extra,
   1589 				keys: shift ? element : keys,
   1590 				element: shift ? this.element : element,
   1591 				add: add
   1592 			};
   1593 		options.element.toggleClass( this._classes( options ), add );
   1594 		return this;
   1595 	},
   1596 
   1597 	_on: function( suppressDisabledCheck, element, handlers ) {
   1598 		var delegateElement;
   1599 		var instance = this;
   1600 
   1601 		// No suppressDisabledCheck flag, shuffle arguments
   1602 		if ( typeof suppressDisabledCheck !== "boolean" ) {
   1603 			handlers = element;
   1604 			element = suppressDisabledCheck;
   1605 			suppressDisabledCheck = false;
   1606 		}
   1607 
   1608 		// No element argument, shuffle and use this.element
   1609 		if ( !handlers ) {
   1610 			handlers = element;
   1611 			element = this.element;
   1612 			delegateElement = this.widget();
   1613 		} else {
   1614 			element = delegateElement = $( element );
   1615 			this.bindings = this.bindings.add( element );
   1616 		}
   1617 
   1618 		$.each( handlers, function( event, handler ) {
   1619 			function handlerProxy() {
   1620 
   1621 				// Allow widgets to customize the disabled handling
   1622 				// - disabled as an array instead of boolean
   1623 				// - disabled class as method for disabling individual parts
   1624 				if ( !suppressDisabledCheck &&
   1625 						( instance.options.disabled === true ||
   1626 						$( this ).hasClass( "ui-state-disabled" ) ) ) {
   1627 					return;
   1628 				}
   1629 				return ( typeof handler === "string" ? instance[ handler ] : handler )
   1630 					.apply( instance, arguments );
   1631 			}
   1632 
   1633 			// Copy the guid so direct unbinding works
   1634 			if ( typeof handler !== "string" ) {
   1635 				handlerProxy.guid = handler.guid =
   1636 					handler.guid || handlerProxy.guid || $.guid++;
   1637 			}
   1638 
   1639 			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
   1640 			var eventName = match[ 1 ] + instance.eventNamespace;
   1641 			var selector = match[ 2 ];
   1642 
   1643 			if ( selector ) {
   1644 				delegateElement.on( eventName, selector, handlerProxy );
   1645 			} else {
   1646 				element.on( eventName, handlerProxy );
   1647 			}
   1648 		} );
   1649 	},
   1650 
   1651 	_off: function( element, eventName ) {
   1652 		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
   1653 			this.eventNamespace;
   1654 		element.off( eventName ).off( eventName );
   1655 
   1656 		// Clear the stack to avoid memory leaks (#10056)
   1657 		this.bindings = $( this.bindings.not( element ).get() );
   1658 		this.focusable = $( this.focusable.not( element ).get() );
   1659 		this.hoverable = $( this.hoverable.not( element ).get() );
   1660 	},
   1661 
   1662 	_delay: function( handler, delay ) {
   1663 		function handlerProxy() {
   1664 			return ( typeof handler === "string" ? instance[ handler ] : handler )
   1665 				.apply( instance, arguments );
   1666 		}
   1667 		var instance = this;
   1668 		return setTimeout( handlerProxy, delay || 0 );
   1669 	},
   1670 
   1671 	_hoverable: function( element ) {
   1672 		this.hoverable = this.hoverable.add( element );
   1673 		this._on( element, {
   1674 			mouseenter: function( event ) {
   1675 				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
   1676 			},
   1677 			mouseleave: function( event ) {
   1678 				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
   1679 			}
   1680 		} );
   1681 	},
   1682 
   1683 	_focusable: function( element ) {
   1684 		this.focusable = this.focusable.add( element );
   1685 		this._on( element, {
   1686 			focusin: function( event ) {
   1687 				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
   1688 			},
   1689 			focusout: function( event ) {
   1690 				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
   1691 			}
   1692 		} );
   1693 	},
   1694 
   1695 	_trigger: function( type, event, data ) {
   1696 		var prop, orig;
   1697 		var callback = this.options[ type ];
   1698 
   1699 		data = data || {};
   1700 		event = $.Event( event );
   1701 		event.type = ( type === this.widgetEventPrefix ?
   1702 			type :
   1703 			this.widgetEventPrefix + type ).toLowerCase();
   1704 
   1705 		// The original event may come from any element
   1706 		// so we need to reset the target on the new event
   1707 		event.target = this.element[ 0 ];
   1708 
   1709 		// Copy original event properties over to the new event
   1710 		orig = event.originalEvent;
   1711 		if ( orig ) {
   1712 			for ( prop in orig ) {
   1713 				if ( !( prop in event ) ) {
   1714 					event[ prop ] = orig[ prop ];
   1715 				}
   1716 			}
   1717 		}
   1718 
   1719 		this.element.trigger( event, data );
   1720 		return !( $.isFunction( callback ) &&
   1721 			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
   1722 			event.isDefaultPrevented() );
   1723 	}
   1724 };
   1725 
   1726 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
   1727 	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
   1728 		if ( typeof options === "string" ) {
   1729 			options = { effect: options };
   1730 		}
   1731 
   1732 		var hasOptions;
   1733 		var effectName = !options ?
   1734 			method :
   1735 			options === true || typeof options === "number" ?
   1736 				defaultEffect :
   1737 				options.effect || defaultEffect;
   1738 
   1739 		options = options || {};
   1740 		if ( typeof options === "number" ) {
   1741 			options = { duration: options };
   1742 		}
   1743 
   1744 		hasOptions = !$.isEmptyObject( options );
   1745 		options.complete = callback;
   1746 
   1747 		if ( options.delay ) {
   1748 			element.delay( options.delay );
   1749 		}
   1750 
   1751 		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
   1752 			element[ method ]( options );
   1753 		} else if ( effectName !== method && element[ effectName ] ) {
   1754 			element[ effectName ]( options.duration, options.easing, callback );
   1755 		} else {
   1756 			element.queue( function( next ) {
   1757 				$( this )[ method ]();
   1758 				if ( callback ) {
   1759 					callback.call( element[ 0 ] );
   1760 				}
   1761 				next();
   1762 			} );
   1763 		}
   1764 	};
   1765 } );
   1766 
   1767 
   1768 } ) );