Projekt

Obecné

Profil

Stáhnout (70.4 KB) Statistiky
| Větev: | Tag: | Revize:
1
/*! jQuery UI - v1.11.4 - 2015-05-20
2
* http://jqueryui.com
3
* Includes: core.js, widget.js, position.js, autocomplete.js, menu.js
4
* Copyright 2015 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 Position 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/position/
868
 */
869

    
870
(function() {
871

    
872
$.ui = $.ui || {};
873

    
874
var cachedScrollbarWidth, supportsOffsetFractions,
875
	max = Math.max,
876
	abs = Math.abs,
877
	round = Math.round,
878
	rhorizontal = /left|center|right/,
879
	rvertical = /top|center|bottom/,
880
	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
881
	rposition = /^\w+/,
882
	rpercent = /%$/,
883
	_position = $.fn.position;
884

    
885
function getOffsets( offsets, width, height ) {
886
	return [
887
		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
888
		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
889
	];
890
}
891

    
892
function parseCss( element, property ) {
893
	return parseInt( $.css( element, property ), 10 ) || 0;
894
}
895

    
896
function getDimensions( elem ) {
897
	var raw = elem[0];
898
	if ( raw.nodeType === 9 ) {
899
		return {
900
			width: elem.width(),
901
			height: elem.height(),
902
			offset: { top: 0, left: 0 }
903
		};
904
	}
905
	if ( $.isWindow( raw ) ) {
906
		return {
907
			width: elem.width(),
908
			height: elem.height(),
909
			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
910
		};
911
	}
912
	if ( raw.preventDefault ) {
913
		return {
914
			width: 0,
915
			height: 0,
916
			offset: { top: raw.pageY, left: raw.pageX }
917
		};
918
	}
919
	return {
920
		width: elem.outerWidth(),
921
		height: elem.outerHeight(),
922
		offset: elem.offset()
923
	};
924
}
925

    
926
$.position = {
927
	scrollbarWidth: function() {
928
		if ( cachedScrollbarWidth !== undefined ) {
929
			return cachedScrollbarWidth;
930
		}
931
		var w1, w2,
932
			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
933
			innerDiv = div.children()[0];
934

    
935
		$( "body" ).append( div );
936
		w1 = innerDiv.offsetWidth;
937
		div.css( "overflow", "scroll" );
938

    
939
		w2 = innerDiv.offsetWidth;
940

    
941
		if ( w1 === w2 ) {
942
			w2 = div[0].clientWidth;
943
		}
944

    
945
		div.remove();
946

    
947
		return (cachedScrollbarWidth = w1 - w2);
948
	},
949
	getScrollInfo: function( within ) {
950
		var overflowX = within.isWindow || within.isDocument ? "" :
951
				within.element.css( "overflow-x" ),
952
			overflowY = within.isWindow || within.isDocument ? "" :
953
				within.element.css( "overflow-y" ),
954
			hasOverflowX = overflowX === "scroll" ||
955
				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
956
			hasOverflowY = overflowY === "scroll" ||
957
				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
958
		return {
959
			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
960
			height: hasOverflowX ? $.position.scrollbarWidth() : 0
961
		};
962
	},
963
	getWithinInfo: function( element ) {
964
		var withinElement = $( element || window ),
965
			isWindow = $.isWindow( withinElement[0] ),
966
			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
967
		return {
968
			element: withinElement,
969
			isWindow: isWindow,
970
			isDocument: isDocument,
971
			offset: withinElement.offset() || { left: 0, top: 0 },
972
			scrollLeft: withinElement.scrollLeft(),
973
			scrollTop: withinElement.scrollTop(),
974

    
975
			// support: jQuery 1.6.x
976
			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
977
			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
978
			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
979
		};
980
	}
981
};
982

    
983
$.fn.position = function( options ) {
984
	if ( !options || !options.of ) {
985
		return _position.apply( this, arguments );
986
	}
987

    
988
	// make a copy, we don't want to modify arguments
989
	options = $.extend( {}, options );
990

    
991
	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
992
		target = $( options.of ),
993
		within = $.position.getWithinInfo( options.within ),
994
		scrollInfo = $.position.getScrollInfo( within ),
995
		collision = ( options.collision || "flip" ).split( " " ),
996
		offsets = {};
997

    
998
	dimensions = getDimensions( target );
999
	if ( target[0].preventDefault ) {
1000
		// force left top to allow flipping
1001
		options.at = "left top";
1002
	}
1003
	targetWidth = dimensions.width;
1004
	targetHeight = dimensions.height;
1005
	targetOffset = dimensions.offset;
1006
	// clone to reuse original targetOffset later
1007
	basePosition = $.extend( {}, targetOffset );
1008

    
1009
	// force my and at to have valid horizontal and vertical positions
1010
	// if a value is missing or invalid, it will be converted to center
1011
	$.each( [ "my", "at" ], function() {
1012
		var pos = ( options[ this ] || "" ).split( " " ),
1013
			horizontalOffset,
1014
			verticalOffset;
1015

    
1016
		if ( pos.length === 1) {
1017
			pos = rhorizontal.test( pos[ 0 ] ) ?
1018
				pos.concat( [ "center" ] ) :
1019
				rvertical.test( pos[ 0 ] ) ?
1020
					[ "center" ].concat( pos ) :
1021
					[ "center", "center" ];
1022
		}
1023
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1024
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1025

    
1026
		// calculate offsets
1027
		horizontalOffset = roffset.exec( pos[ 0 ] );
1028
		verticalOffset = roffset.exec( pos[ 1 ] );
1029
		offsets[ this ] = [
1030
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1031
			verticalOffset ? verticalOffset[ 0 ] : 0
1032
		];
1033

    
1034
		// reduce to just the positions without the offsets
1035
		options[ this ] = [
1036
			rposition.exec( pos[ 0 ] )[ 0 ],
1037
			rposition.exec( pos[ 1 ] )[ 0 ]
1038
		];
1039
	});
1040

    
1041
	// normalize collision option
1042
	if ( collision.length === 1 ) {
1043
		collision[ 1 ] = collision[ 0 ];
1044
	}
1045

    
1046
	if ( options.at[ 0 ] === "right" ) {
1047
		basePosition.left += targetWidth;
1048
	} else if ( options.at[ 0 ] === "center" ) {
1049
		basePosition.left += targetWidth / 2;
1050
	}
1051

    
1052
	if ( options.at[ 1 ] === "bottom" ) {
1053
		basePosition.top += targetHeight;
1054
	} else if ( options.at[ 1 ] === "center" ) {
1055
		basePosition.top += targetHeight / 2;
1056
	}
1057

    
1058
	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1059
	basePosition.left += atOffset[ 0 ];
1060
	basePosition.top += atOffset[ 1 ];
1061

    
1062
	return this.each(function() {
1063
		var collisionPosition, using,
1064
			elem = $( this ),
1065
			elemWidth = elem.outerWidth(),
1066
			elemHeight = elem.outerHeight(),
1067
			marginLeft = parseCss( this, "marginLeft" ),
1068
			marginTop = parseCss( this, "marginTop" ),
1069
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1070
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1071
			position = $.extend( {}, basePosition ),
1072
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1073

    
1074
		if ( options.my[ 0 ] === "right" ) {
1075
			position.left -= elemWidth;
1076
		} else if ( options.my[ 0 ] === "center" ) {
1077
			position.left -= elemWidth / 2;
1078
		}
1079

    
1080
		if ( options.my[ 1 ] === "bottom" ) {
1081
			position.top -= elemHeight;
1082
		} else if ( options.my[ 1 ] === "center" ) {
1083
			position.top -= elemHeight / 2;
1084
		}
1085

    
1086
		position.left += myOffset[ 0 ];
1087
		position.top += myOffset[ 1 ];
1088

    
1089
		// if the browser doesn't support fractions, then round for consistent results
1090
		if ( !supportsOffsetFractions ) {
1091
			position.left = round( position.left );
1092
			position.top = round( position.top );
1093
		}
1094

    
1095
		collisionPosition = {
1096
			marginLeft: marginLeft,
1097
			marginTop: marginTop
1098
		};
1099

    
1100
		$.each( [ "left", "top" ], function( i, dir ) {
1101
			if ( $.ui.position[ collision[ i ] ] ) {
1102
				$.ui.position[ collision[ i ] ][ dir ]( position, {
1103
					targetWidth: targetWidth,
1104
					targetHeight: targetHeight,
1105
					elemWidth: elemWidth,
1106
					elemHeight: elemHeight,
1107
					collisionPosition: collisionPosition,
1108
					collisionWidth: collisionWidth,
1109
					collisionHeight: collisionHeight,
1110
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1111
					my: options.my,
1112
					at: options.at,
1113
					within: within,
1114
					elem: elem
1115
				});
1116
			}
1117
		});
1118

    
1119
		if ( options.using ) {
1120
			// adds feedback as second argument to using callback, if present
1121
			using = function( props ) {
1122
				var left = targetOffset.left - position.left,
1123
					right = left + targetWidth - elemWidth,
1124
					top = targetOffset.top - position.top,
1125
					bottom = top + targetHeight - elemHeight,
1126
					feedback = {
1127
						target: {
1128
							element: target,
1129
							left: targetOffset.left,
1130
							top: targetOffset.top,
1131
							width: targetWidth,
1132
							height: targetHeight
1133
						},
1134
						element: {
1135
							element: elem,
1136
							left: position.left,
1137
							top: position.top,
1138
							width: elemWidth,
1139
							height: elemHeight
1140
						},
1141
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1142
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1143
					};
1144
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1145
					feedback.horizontal = "center";
1146
				}
1147
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1148
					feedback.vertical = "middle";
1149
				}
1150
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1151
					feedback.important = "horizontal";
1152
				} else {
1153
					feedback.important = "vertical";
1154
				}
1155
				options.using.call( this, props, feedback );
1156
			};
1157
		}
1158

    
1159
		elem.offset( $.extend( position, { using: using } ) );
1160
	});
1161
};
1162

    
1163
$.ui.position = {
1164
	fit: {
1165
		left: function( position, data ) {
1166
			var within = data.within,
1167
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1168
				outerWidth = within.width,
1169
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1170
				overLeft = withinOffset - collisionPosLeft,
1171
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1172
				newOverRight;
1173

    
1174
			// element is wider than within
1175
			if ( data.collisionWidth > outerWidth ) {
1176
				// element is initially over the left side of within
1177
				if ( overLeft > 0 && overRight <= 0 ) {
1178
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1179
					position.left += overLeft - newOverRight;
1180
				// element is initially over right side of within
1181
				} else if ( overRight > 0 && overLeft <= 0 ) {
1182
					position.left = withinOffset;
1183
				// element is initially over both left and right sides of within
1184
				} else {
1185
					if ( overLeft > overRight ) {
1186
						position.left = withinOffset + outerWidth - data.collisionWidth;
1187
					} else {
1188
						position.left = withinOffset;
1189
					}
1190
				}
1191
			// too far left -> align with left edge
1192
			} else if ( overLeft > 0 ) {
1193
				position.left += overLeft;
1194
			// too far right -> align with right edge
1195
			} else if ( overRight > 0 ) {
1196
				position.left -= overRight;
1197
			// adjust based on position and margin
1198
			} else {
1199
				position.left = max( position.left - collisionPosLeft, position.left );
1200
			}
1201
		},
1202
		top: function( position, data ) {
1203
			var within = data.within,
1204
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1205
				outerHeight = data.within.height,
1206
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1207
				overTop = withinOffset - collisionPosTop,
1208
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1209
				newOverBottom;
1210

    
1211
			// element is taller than within
1212
			if ( data.collisionHeight > outerHeight ) {
1213
				// element is initially over the top of within
1214
				if ( overTop > 0 && overBottom <= 0 ) {
1215
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1216
					position.top += overTop - newOverBottom;
1217
				// element is initially over bottom of within
1218
				} else if ( overBottom > 0 && overTop <= 0 ) {
1219
					position.top = withinOffset;
1220
				// element is initially over both top and bottom of within
1221
				} else {
1222
					if ( overTop > overBottom ) {
1223
						position.top = withinOffset + outerHeight - data.collisionHeight;
1224
					} else {
1225
						position.top = withinOffset;
1226
					}
1227
				}
1228
			// too far up -> align with top
1229
			} else if ( overTop > 0 ) {
1230
				position.top += overTop;
1231
			// too far down -> align with bottom edge
1232
			} else if ( overBottom > 0 ) {
1233
				position.top -= overBottom;
1234
			// adjust based on position and margin
1235
			} else {
1236
				position.top = max( position.top - collisionPosTop, position.top );
1237
			}
1238
		}
1239
	},
1240
	flip: {
1241
		left: function( position, data ) {
1242
			var within = data.within,
1243
				withinOffset = within.offset.left + within.scrollLeft,
1244
				outerWidth = within.width,
1245
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1246
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1247
				overLeft = collisionPosLeft - offsetLeft,
1248
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1249
				myOffset = data.my[ 0 ] === "left" ?
1250
					-data.elemWidth :
1251
					data.my[ 0 ] === "right" ?
1252
						data.elemWidth :
1253
						0,
1254
				atOffset = data.at[ 0 ] === "left" ?
1255
					data.targetWidth :
1256
					data.at[ 0 ] === "right" ?
1257
						-data.targetWidth :
1258
						0,
1259
				offset = -2 * data.offset[ 0 ],
1260
				newOverRight,
1261
				newOverLeft;
1262

    
1263
			if ( overLeft < 0 ) {
1264
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1265
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1266
					position.left += myOffset + atOffset + offset;
1267
				}
1268
			} else if ( overRight > 0 ) {
1269
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1270
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1271
					position.left += myOffset + atOffset + offset;
1272
				}
1273
			}
1274
		},
1275
		top: function( position, data ) {
1276
			var within = data.within,
1277
				withinOffset = within.offset.top + within.scrollTop,
1278
				outerHeight = within.height,
1279
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1280
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1281
				overTop = collisionPosTop - offsetTop,
1282
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1283
				top = data.my[ 1 ] === "top",
1284
				myOffset = top ?
1285
					-data.elemHeight :
1286
					data.my[ 1 ] === "bottom" ?
1287
						data.elemHeight :
1288
						0,
1289
				atOffset = data.at[ 1 ] === "top" ?
1290
					data.targetHeight :
1291
					data.at[ 1 ] === "bottom" ?
1292
						-data.targetHeight :
1293
						0,
1294
				offset = -2 * data.offset[ 1 ],
1295
				newOverTop,
1296
				newOverBottom;
1297
			if ( overTop < 0 ) {
1298
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1299
				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1300
					position.top += myOffset + atOffset + offset;
1301
				}
1302
			} else if ( overBottom > 0 ) {
1303
				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1304
				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1305
					position.top += myOffset + atOffset + offset;
1306
				}
1307
			}
1308
		}
1309
	},
1310
	flipfit: {
1311
		left: function() {
1312
			$.ui.position.flip.left.apply( this, arguments );
1313
			$.ui.position.fit.left.apply( this, arguments );
1314
		},
1315
		top: function() {
1316
			$.ui.position.flip.top.apply( this, arguments );
1317
			$.ui.position.fit.top.apply( this, arguments );
1318
		}
1319
	}
1320
};
1321

    
1322
// fraction support test
1323
(function() {
1324
	var testElement, testElementParent, testElementStyle, offsetLeft, i,
1325
		body = document.getElementsByTagName( "body" )[ 0 ],
1326
		div = document.createElement( "div" );
1327

    
1328
	//Create a "fake body" for testing based on method used in jQuery.support
1329
	testElement = document.createElement( body ? "div" : "body" );
1330
	testElementStyle = {
1331
		visibility: "hidden",
1332
		width: 0,
1333
		height: 0,
1334
		border: 0,
1335
		margin: 0,
1336
		background: "none"
1337
	};
1338
	if ( body ) {
1339
		$.extend( testElementStyle, {
1340
			position: "absolute",
1341
			left: "-1000px",
1342
			top: "-1000px"
1343
		});
1344
	}
1345
	for ( i in testElementStyle ) {
1346
		testElement.style[ i ] = testElementStyle[ i ];
1347
	}
1348
	testElement.appendChild( div );
1349
	testElementParent = body || document.documentElement;
1350
	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1351

    
1352
	div.style.cssText = "position: absolute; left: 10.7432222px;";
1353

    
1354
	offsetLeft = $( div ).offset().left;
1355
	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1356

    
1357
	testElement.innerHTML = "";
1358
	testElementParent.removeChild( testElement );
1359
})();
1360

    
1361
})();
1362

    
1363
var position = $.ui.position;
1364

    
1365

    
1366
/*!
1367
 * jQuery UI Menu 1.11.4
1368
 * http://jqueryui.com
1369
 *
1370
 * Copyright jQuery Foundation and other contributors
1371
 * Released under the MIT license.
1372
 * http://jquery.org/license
1373
 *
1374
 * http://api.jqueryui.com/menu/
1375
 */
1376

    
1377

    
1378
var menu = $.widget( "ui.menu", {
1379
	version: "1.11.4",
1380
	defaultElement: "<ul>",
1381
	delay: 300,
1382
	options: {
1383
		icons: {
1384
			submenu: "ui-icon-carat-1-e"
1385
		},
1386
		items: "> *",
1387
		menus: "ul",
1388
		position: {
1389
			my: "left-1 top",
1390
			at: "right top"
1391
		},
1392
		role: "menu",
1393

    
1394
		// callbacks
1395
		blur: null,
1396
		focus: null,
1397
		select: null
1398
	},
1399

    
1400
	_create: function() {
1401
		this.activeMenu = this.element;
1402

    
1403
		// Flag used to prevent firing of the click handler
1404
		// as the event bubbles up through nested menus
1405
		this.mouseHandled = false;
1406
		this.element
1407
			.uniqueId()
1408
			.addClass( "ui-menu ui-widget ui-widget-content" )
1409
			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
1410
			.attr({
1411
				role: this.options.role,
1412
				tabIndex: 0
1413
			});
1414

    
1415
		if ( this.options.disabled ) {
1416
			this.element
1417
				.addClass( "ui-state-disabled" )
1418
				.attr( "aria-disabled", "true" );
1419
		}
1420

    
1421
		this._on({
1422
			// Prevent focus from sticking to links inside menu after clicking
1423
			// them (focus should always stay on UL during navigation).
1424
			"mousedown .ui-menu-item": function( event ) {
1425
				event.preventDefault();
1426
			},
1427
			"click .ui-menu-item": function( event ) {
1428
				var target = $( event.target );
1429
				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
1430
					this.select( event );
1431

    
1432
					// Only set the mouseHandled flag if the event will bubble, see #9469.
1433
					if ( !event.isPropagationStopped() ) {
1434
						this.mouseHandled = true;
1435
					}
1436

    
1437
					// Open submenu on click
1438
					if ( target.has( ".ui-menu" ).length ) {
1439
						this.expand( event );
1440
					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
1441

    
1442
						// Redirect focus to the menu
1443
						this.element.trigger( "focus", [ true ] );
1444

    
1445
						// If the active item is on the top level, let it stay active.
1446
						// Otherwise, blur the active item since it is no longer visible.
1447
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
1448
							clearTimeout( this.timer );
1449
						}
1450
					}
1451
				}
1452
			},
1453
			"mouseenter .ui-menu-item": function( event ) {
1454
				// Ignore mouse events while typeahead is active, see #10458.
1455
				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
1456
				// is over an item in the menu
1457
				if ( this.previousFilter ) {
1458
					return;
1459
				}
1460
				var target = $( event.currentTarget );
1461
				// Remove ui-state-active class from siblings of the newly focused menu item
1462
				// to avoid a jump caused by adjacent elements both having a class with a border
1463
				target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
1464
				this.focus( event, target );
1465
			},
1466
			mouseleave: "collapseAll",
1467
			"mouseleave .ui-menu": "collapseAll",
1468
			focus: function( event, keepActiveItem ) {
1469
				// If there's already an active item, keep it active
1470
				// If not, activate the first item
1471
				var item = this.active || this.element.find( this.options.items ).eq( 0 );
1472

    
1473
				if ( !keepActiveItem ) {
1474
					this.focus( event, item );
1475
				}
1476
			},
1477
			blur: function( event ) {
1478
				this._delay(function() {
1479
					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
1480
						this.collapseAll( event );
1481
					}
1482
				});
1483
			},
1484
			keydown: "_keydown"
1485
		});
1486

    
1487
		this.refresh();
1488

    
1489
		// Clicks outside of a menu collapse any open menus
1490
		this._on( this.document, {
1491
			click: function( event ) {
1492
				if ( this._closeOnDocumentClick( event ) ) {
1493
					this.collapseAll( event );
1494
				}
1495

    
1496
				// Reset the mouseHandled flag
1497
				this.mouseHandled = false;
1498
			}
1499
		});
1500
	},
1501

    
1502
	_destroy: function() {
1503
		// Destroy (sub)menus
1504
		this.element
1505
			.removeAttr( "aria-activedescendant" )
1506
			.find( ".ui-menu" ).addBack()
1507
				.removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
1508
				.removeAttr( "role" )
1509
				.removeAttr( "tabIndex" )
1510
				.removeAttr( "aria-labelledby" )
1511
				.removeAttr( "aria-expanded" )
1512
				.removeAttr( "aria-hidden" )
1513
				.removeAttr( "aria-disabled" )
1514
				.removeUniqueId()
1515
				.show();
1516

    
1517
		// Destroy menu items
1518
		this.element.find( ".ui-menu-item" )
1519
			.removeClass( "ui-menu-item" )
1520
			.removeAttr( "role" )
1521
			.removeAttr( "aria-disabled" )
1522
			.removeUniqueId()
1523
			.removeClass( "ui-state-hover" )
1524
			.removeAttr( "tabIndex" )
1525
			.removeAttr( "role" )
1526
			.removeAttr( "aria-haspopup" )
1527
			.children().each( function() {
1528
				var elem = $( this );
1529
				if ( elem.data( "ui-menu-submenu-carat" ) ) {
1530
					elem.remove();
1531
				}
1532
			});
1533

    
1534
		// Destroy menu dividers
1535
		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
1536
	},
1537

    
1538
	_keydown: function( event ) {
1539
		var match, prev, character, skip,
1540
			preventDefault = true;
1541

    
1542
		switch ( event.keyCode ) {
1543
		case $.ui.keyCode.PAGE_UP:
1544
			this.previousPage( event );
1545
			break;
1546
		case $.ui.keyCode.PAGE_DOWN:
1547
			this.nextPage( event );
1548
			break;
1549
		case $.ui.keyCode.HOME:
1550
			this._move( "first", "first", event );
1551
			break;
1552
		case $.ui.keyCode.END:
1553
			this._move( "last", "last", event );
1554
			break;
1555
		case $.ui.keyCode.UP:
1556
			this.previous( event );
1557
			break;
1558
		case $.ui.keyCode.DOWN:
1559
			this.next( event );
1560
			break;
1561
		case $.ui.keyCode.LEFT:
1562
			this.collapse( event );
1563
			break;
1564
		case $.ui.keyCode.RIGHT:
1565
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
1566
				this.expand( event );
1567
			}
1568
			break;
1569
		case $.ui.keyCode.ENTER:
1570
		case $.ui.keyCode.SPACE:
1571
			this._activate( event );
1572
			break;
1573
		case $.ui.keyCode.ESCAPE:
1574
			this.collapse( event );
1575
			break;
1576
		default:
1577
			preventDefault = false;
1578
			prev = this.previousFilter || "";
1579
			character = String.fromCharCode( event.keyCode );
1580
			skip = false;
1581

    
1582
			clearTimeout( this.filterTimer );
1583

    
1584
			if ( character === prev ) {
1585
				skip = true;
1586
			} else {
1587
				character = prev + character;
1588
			}
1589

    
1590
			match = this._filterMenuItems( character );
1591
			match = skip && match.index( this.active.next() ) !== -1 ?
1592
				this.active.nextAll( ".ui-menu-item" ) :
1593
				match;
1594

    
1595
			// If no matches on the current filter, reset to the last character pressed
1596
			// to move down the menu to the first item that starts with that character
1597
			if ( !match.length ) {
1598
				character = String.fromCharCode( event.keyCode );
1599
				match = this._filterMenuItems( character );
1600
			}
1601

    
1602
			if ( match.length ) {
1603
				this.focus( event, match );
1604
				this.previousFilter = character;
1605
				this.filterTimer = this._delay(function() {
1606
					delete this.previousFilter;
1607
				}, 1000 );
1608
			} else {
1609
				delete this.previousFilter;
1610
			}
1611
		}
1612

    
1613
		if ( preventDefault ) {
1614
			event.preventDefault();
1615
		}
1616
	},
1617

    
1618
	_activate: function( event ) {
1619
		if ( !this.active.is( ".ui-state-disabled" ) ) {
1620
			if ( this.active.is( "[aria-haspopup='true']" ) ) {
1621
				this.expand( event );
1622
			} else {
1623
				this.select( event );
1624
			}
1625
		}
1626
	},
1627

    
1628
	refresh: function() {
1629
		var menus, items,
1630
			that = this,
1631
			icon = this.options.icons.submenu,
1632
			submenus = this.element.find( this.options.menus );
1633

    
1634
		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
1635

    
1636
		// Initialize nested menus
1637
		submenus.filter( ":not(.ui-menu)" )
1638
			.addClass( "ui-menu ui-widget ui-widget-content ui-front" )
1639
			.hide()
1640
			.attr({
1641
				role: this.options.role,
1642
				"aria-hidden": "true",
1643
				"aria-expanded": "false"
1644
			})
1645
			.each(function() {
1646
				var menu = $( this ),
1647
					item = menu.parent(),
1648
					submenuCarat = $( "<span>" )
1649
						.addClass( "ui-menu-icon ui-icon " + icon )
1650
						.data( "ui-menu-submenu-carat", true );
1651

    
1652
				item
1653
					.attr( "aria-haspopup", "true" )
1654
					.prepend( submenuCarat );
1655
				menu.attr( "aria-labelledby", item.attr( "id" ) );
1656
			});
1657

    
1658
		menus = submenus.add( this.element );
1659
		items = menus.find( this.options.items );
1660

    
1661
		// Initialize menu-items containing spaces and/or dashes only as dividers
1662
		items.not( ".ui-menu-item" ).each(function() {
1663
			var item = $( this );
1664
			if ( that._isDivider( item ) ) {
1665
				item.addClass( "ui-widget-content ui-menu-divider" );
1666
			}
1667
		});
1668

    
1669
		// Don't refresh list items that are already adapted
1670
		items.not( ".ui-menu-item, .ui-menu-divider" )
1671
			.addClass( "ui-menu-item" )
1672
			.uniqueId()
1673
			.attr({
1674
				tabIndex: -1,
1675
				role: this._itemRole()
1676
			});
1677

    
1678
		// Add aria-disabled attribute to any disabled menu item
1679
		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
1680

    
1681
		// If the active item has been removed, blur the menu
1682
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
1683
			this.blur();
1684
		}
1685
	},
1686

    
1687
	_itemRole: function() {
1688
		return {
1689
			menu: "menuitem",
1690
			listbox: "option"
1691
		}[ this.options.role ];
1692
	},
1693

    
1694
	_setOption: function( key, value ) {
1695
		if ( key === "icons" ) {
1696
			this.element.find( ".ui-menu-icon" )
1697
				.removeClass( this.options.icons.submenu )
1698
				.addClass( value.submenu );
1699
		}
1700
		if ( key === "disabled" ) {
1701
			this.element
1702
				.toggleClass( "ui-state-disabled", !!value )
1703
				.attr( "aria-disabled", value );
1704
		}
1705
		this._super( key, value );
1706
	},
1707

    
1708
	focus: function( event, item ) {
1709
		var nested, focused;
1710
		this.blur( event, event && event.type === "focus" );
1711

    
1712
		this._scrollIntoView( item );
1713

    
1714
		this.active = item.first();
1715
		focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
1716
		// Only update aria-activedescendant if there's a role
1717
		// otherwise we assume focus is managed elsewhere
1718
		if ( this.options.role ) {
1719
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
1720
		}
1721

    
1722
		// Highlight active parent menu item, if any
1723
		this.active
1724
			.parent()
1725
			.closest( ".ui-menu-item" )
1726
			.addClass( "ui-state-active" );
1727

    
1728
		if ( event && event.type === "keydown" ) {
1729
			this._close();
1730
		} else {
1731
			this.timer = this._delay(function() {
1732
				this._close();
1733
			}, this.delay );
1734
		}
1735

    
1736
		nested = item.children( ".ui-menu" );
1737
		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
1738
			this._startOpening(nested);
1739
		}
1740
		this.activeMenu = item.parent();
1741

    
1742
		this._trigger( "focus", event, { item: item } );
1743
	},
1744

    
1745
	_scrollIntoView: function( item ) {
1746
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
1747
		if ( this._hasScroll() ) {
1748
			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
1749
			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
1750
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
1751
			scroll = this.activeMenu.scrollTop();
1752
			elementHeight = this.activeMenu.height();
1753
			itemHeight = item.outerHeight();
1754

    
1755
			if ( offset < 0 ) {
1756
				this.activeMenu.scrollTop( scroll + offset );
1757
			} else if ( offset + itemHeight > elementHeight ) {
1758
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
1759
			}
1760
		}
1761
	},
1762

    
1763
	blur: function( event, fromFocus ) {
1764
		if ( !fromFocus ) {
1765
			clearTimeout( this.timer );
1766
		}
1767

    
1768
		if ( !this.active ) {
1769
			return;
1770
		}
1771

    
1772
		this.active.removeClass( "ui-state-focus" );
1773
		this.active = null;
1774

    
1775
		this._trigger( "blur", event, { item: this.active } );
1776
	},
1777

    
1778
	_startOpening: function( submenu ) {
1779
		clearTimeout( this.timer );
1780

    
1781
		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
1782
		// shift in the submenu position when mousing over the carat icon
1783
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
1784
			return;
1785
		}
1786

    
1787
		this.timer = this._delay(function() {
1788
			this._close();
1789
			this._open( submenu );
1790
		}, this.delay );
1791
	},
1792

    
1793
	_open: function( submenu ) {
1794
		var position = $.extend({
1795
			of: this.active
1796
		}, this.options.position );
1797

    
1798
		clearTimeout( this.timer );
1799
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
1800
			.hide()
1801
			.attr( "aria-hidden", "true" );
1802

    
1803
		submenu
1804
			.show()
1805
			.removeAttr( "aria-hidden" )
1806
			.attr( "aria-expanded", "true" )
1807
			.position( position );
1808
	},
1809

    
1810
	collapseAll: function( event, all ) {
1811
		clearTimeout( this.timer );
1812
		this.timer = this._delay(function() {
1813
			// If we were passed an event, look for the submenu that contains the event
1814
			var currentMenu = all ? this.element :
1815
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
1816

    
1817
			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
1818
			if ( !currentMenu.length ) {
1819
				currentMenu = this.element;
1820
			}
1821

    
1822
			this._close( currentMenu );
1823

    
1824
			this.blur( event );
1825
			this.activeMenu = currentMenu;
1826
		}, this.delay );
1827
	},
1828

    
1829
	// With no arguments, closes the currently active menu - if nothing is active
1830
	// it closes all menus.  If passed an argument, it will search for menus BELOW
1831
	_close: function( startMenu ) {
1832
		if ( !startMenu ) {
1833
			startMenu = this.active ? this.active.parent() : this.element;
1834
		}
1835

    
1836
		startMenu
1837
			.find( ".ui-menu" )
1838
				.hide()
1839
				.attr( "aria-hidden", "true" )
1840
				.attr( "aria-expanded", "false" )
1841
			.end()
1842
			.find( ".ui-state-active" ).not( ".ui-state-focus" )
1843
				.removeClass( "ui-state-active" );
1844
	},
1845

    
1846
	_closeOnDocumentClick: function( event ) {
1847
		return !$( event.target ).closest( ".ui-menu" ).length;
1848
	},
1849

    
1850
	_isDivider: function( item ) {
1851

    
1852
		// Match hyphen, em dash, en dash
1853
		return !/[^\-\u2014\u2013\s]/.test( item.text() );
1854
	},
1855

    
1856
	collapse: function( event ) {
1857
		var newItem = this.active &&
1858
			this.active.parent().closest( ".ui-menu-item", this.element );
1859
		if ( newItem && newItem.length ) {
1860
			this._close();
1861
			this.focus( event, newItem );
1862
		}
1863
	},
1864

    
1865
	expand: function( event ) {
1866
		var newItem = this.active &&
1867
			this.active
1868
				.children( ".ui-menu " )
1869
				.find( this.options.items )
1870
				.first();
1871

    
1872
		if ( newItem && newItem.length ) {
1873
			this._open( newItem.parent() );
1874

    
1875
			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
1876
			this._delay(function() {
1877
				this.focus( event, newItem );
1878
			});
1879
		}
1880
	},
1881

    
1882
	next: function( event ) {
1883
		this._move( "next", "first", event );
1884
	},
1885

    
1886
	previous: function( event ) {
1887
		this._move( "prev", "last", event );
1888
	},
1889

    
1890
	isFirstItem: function() {
1891
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
1892
	},
1893

    
1894
	isLastItem: function() {
1895
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
1896
	},
1897

    
1898
	_move: function( direction, filter, event ) {
1899
		var next;
1900
		if ( this.active ) {
1901
			if ( direction === "first" || direction === "last" ) {
1902
				next = this.active
1903
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
1904
					.eq( -1 );
1905
			} else {
1906
				next = this.active
1907
					[ direction + "All" ]( ".ui-menu-item" )
1908
					.eq( 0 );
1909
			}
1910
		}
1911
		if ( !next || !next.length || !this.active ) {
1912
			next = this.activeMenu.find( this.options.items )[ filter ]();
1913
		}
1914

    
1915
		this.focus( event, next );
1916
	},
1917

    
1918
	nextPage: function( event ) {
1919
		var item, base, height;
1920

    
1921
		if ( !this.active ) {
1922
			this.next( event );
1923
			return;
1924
		}
1925
		if ( this.isLastItem() ) {
1926
			return;
1927
		}
1928
		if ( this._hasScroll() ) {
1929
			base = this.active.offset().top;
1930
			height = this.element.height();
1931
			this.active.nextAll( ".ui-menu-item" ).each(function() {
1932
				item = $( this );
1933
				return item.offset().top - base - height < 0;
1934
			});
1935

    
1936
			this.focus( event, item );
1937
		} else {
1938
			this.focus( event, this.activeMenu.find( this.options.items )
1939
				[ !this.active ? "first" : "last" ]() );
1940
		}
1941
	},
1942

    
1943
	previousPage: function( event ) {
1944
		var item, base, height;
1945
		if ( !this.active ) {
1946
			this.next( event );
1947
			return;
1948
		}
1949
		if ( this.isFirstItem() ) {
1950
			return;
1951
		}
1952
		if ( this._hasScroll() ) {
1953
			base = this.active.offset().top;
1954
			height = this.element.height();
1955
			this.active.prevAll( ".ui-menu-item" ).each(function() {
1956
				item = $( this );
1957
				return item.offset().top - base + height > 0;
1958
			});
1959

    
1960
			this.focus( event, item );
1961
		} else {
1962
			this.focus( event, this.activeMenu.find( this.options.items ).first() );
1963
		}
1964
	},
1965

    
1966
	_hasScroll: function() {
1967
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
1968
	},
1969

    
1970
	select: function( event ) {
1971
		// TODO: It should never be possible to not have an active item at this
1972
		// point, but the tests don't trigger mouseenter before click.
1973
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
1974
		var ui = { item: this.active };
1975
		if ( !this.active.has( ".ui-menu" ).length ) {
1976
			this.collapseAll( event, true );
1977
		}
1978
		this._trigger( "select", event, ui );
1979
	},
1980

    
1981
	_filterMenuItems: function(character) {
1982
		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
1983
			regex = new RegExp( "^" + escapedCharacter, "i" );
1984

    
1985
		return this.activeMenu
1986
			.find( this.options.items )
1987

    
1988
			// Only match on items, not dividers or other content (#10571)
1989
			.filter( ".ui-menu-item" )
1990
			.filter(function() {
1991
				return regex.test( $.trim( $( this ).text() ) );
1992
			});
1993
	}
1994
});
1995

    
1996

    
1997
/*!
1998
 * jQuery UI Autocomplete 1.11.4
1999
 * http://jqueryui.com
2000
 *
2001
 * Copyright jQuery Foundation and other contributors
2002
 * Released under the MIT license.
2003
 * http://jquery.org/license
2004
 *
2005
 * http://api.jqueryui.com/autocomplete/
2006
 */
2007

    
2008

    
2009
$.widget( "ui.autocomplete", {
2010
	version: "1.11.4",
2011
	defaultElement: "<input>",
2012
	options: {
2013
		appendTo: null,
2014
		autoFocus: false,
2015
		delay: 300,
2016
		minLength: 1,
2017
		position: {
2018
			my: "left top",
2019
			at: "left bottom",
2020
			collision: "none"
2021
		},
2022
		source: null,
2023

    
2024
		// callbacks
2025
		change: null,
2026
		close: null,
2027
		focus: null,
2028
		open: null,
2029
		response: null,
2030
		search: null,
2031
		select: null
2032
	},
2033

    
2034
	requestIndex: 0,
2035
	pending: 0,
2036

    
2037
	_create: function() {
2038
		// Some browsers only repeat keydown events, not keypress events,
2039
		// so we use the suppressKeyPress flag to determine if we've already
2040
		// handled the keydown event. #7269
2041
		// Unfortunately the code for & in keypress is the same as the up arrow,
2042
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
2043
		// events when we know the keydown event was used to modify the
2044
		// search term. #7799
2045
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
2046
			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
2047
			isTextarea = nodeName === "textarea",
2048
			isInput = nodeName === "input";
2049

    
2050
		this.isMultiLine =
2051
			// Textareas are always multi-line
2052
			isTextarea ? true :
2053
			// Inputs are always single-line, even if inside a contentEditable element
2054
			// IE also treats inputs as contentEditable
2055
			isInput ? false :
2056
			// All other element types are determined by whether or not they're contentEditable
2057
			this.element.prop( "isContentEditable" );
2058

    
2059
		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
2060
		this.isNewMenu = true;
2061

    
2062
		this.element
2063
			.addClass( "ui-autocomplete-input" )
2064
			.attr( "autocomplete", "off" );
2065

    
2066
		this._on( this.element, {
2067
			keydown: function( event ) {
2068
				if ( this.element.prop( "readOnly" ) ) {
2069
					suppressKeyPress = true;
2070
					suppressInput = true;
2071
					suppressKeyPressRepeat = true;
2072
					return;
2073
				}
2074

    
2075
				suppressKeyPress = false;
2076
				suppressInput = false;
2077
				suppressKeyPressRepeat = false;
2078
				var keyCode = $.ui.keyCode;
2079
				switch ( event.keyCode ) {
2080
				case keyCode.PAGE_UP:
2081
					suppressKeyPress = true;
2082
					this._move( "previousPage", event );
2083
					break;
2084
				case keyCode.PAGE_DOWN:
2085
					suppressKeyPress = true;
2086
					this._move( "nextPage", event );
2087
					break;
2088
				case keyCode.UP:
2089
					suppressKeyPress = true;
2090
					this._keyEvent( "previous", event );
2091
					break;
2092
				case keyCode.DOWN:
2093
					suppressKeyPress = true;
2094
					this._keyEvent( "next", event );
2095
					break;
2096
				case keyCode.ENTER:
2097
					// when menu is open and has focus
2098
					if ( this.menu.active ) {
2099
						// #6055 - Opera still allows the keypress to occur
2100
						// which causes forms to submit
2101
						suppressKeyPress = true;
2102
						event.preventDefault();
2103
						this.menu.select( event );
2104
					}
2105
					break;
2106
				case keyCode.TAB:
2107
					if ( this.menu.active ) {
2108
						this.menu.select( event );
2109
					}
2110
					break;
2111
				case keyCode.ESCAPE:
2112
					if ( this.menu.element.is( ":visible" ) ) {
2113
						if ( !this.isMultiLine ) {
2114
							this._value( this.term );
2115
						}
2116
						this.close( event );
2117
						// Different browsers have different default behavior for escape
2118
						// Single press can mean undo or clear
2119
						// Double press in IE means clear the whole form
2120
						event.preventDefault();
2121
					}
2122
					break;
2123
				default:
2124
					suppressKeyPressRepeat = true;
2125
					// search timeout should be triggered before the input value is changed
2126
					this._searchTimeout( event );
2127
					break;
2128
				}
2129
			},
2130
			keypress: function( event ) {
2131
				if ( suppressKeyPress ) {
2132
					suppressKeyPress = false;
2133
					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2134
						event.preventDefault();
2135
					}
2136
					return;
2137
				}
2138
				if ( suppressKeyPressRepeat ) {
2139
					return;
2140
				}
2141

    
2142
				// replicate some key handlers to allow them to repeat in Firefox and Opera
2143
				var keyCode = $.ui.keyCode;
2144
				switch ( event.keyCode ) {
2145
				case keyCode.PAGE_UP:
2146
					this._move( "previousPage", event );
2147
					break;
2148
				case keyCode.PAGE_DOWN:
2149
					this._move( "nextPage", event );
2150
					break;
2151
				case keyCode.UP:
2152
					this._keyEvent( "previous", event );
2153
					break;
2154
				case keyCode.DOWN:
2155
					this._keyEvent( "next", event );
2156
					break;
2157
				}
2158
			},
2159
			input: function( event ) {
2160
				if ( suppressInput ) {
2161
					suppressInput = false;
2162
					event.preventDefault();
2163
					return;
2164
				}
2165
				this._searchTimeout( event );
2166
			},
2167
			focus: function() {
2168
				this.selectedItem = null;
2169
				this.previous = this._value();
2170
			},
2171
			blur: function( event ) {
2172
				if ( this.cancelBlur ) {
2173
					delete this.cancelBlur;
2174
					return;
2175
				}
2176

    
2177
				clearTimeout( this.searching );
2178
				this.close( event );
2179
				this._change( event );
2180
			}
2181
		});
2182

    
2183
		this._initSource();
2184
		this.menu = $( "<ul>" )
2185
			.addClass( "ui-autocomplete ui-front" )
2186
			.appendTo( this._appendTo() )
2187
			.menu({
2188
				// disable ARIA support, the live region takes care of that
2189
				role: null
2190
			})
2191
			.hide()
2192
			.menu( "instance" );
2193

    
2194
		this._on( this.menu.element, {
2195
			mousedown: function( event ) {
2196
				// prevent moving focus out of the text field
2197
				event.preventDefault();
2198

    
2199
				// IE doesn't prevent moving focus even with event.preventDefault()
2200
				// so we set a flag to know when we should ignore the blur event
2201
				this.cancelBlur = true;
2202
				this._delay(function() {
2203
					delete this.cancelBlur;
2204
				});
2205

    
2206
				// clicking on the scrollbar causes focus to shift to the body
2207
				// but we can't detect a mouseup or a click immediately afterward
2208
				// so we have to track the next mousedown and close the menu if
2209
				// the user clicks somewhere outside of the autocomplete
2210
				var menuElement = this.menu.element[ 0 ];
2211
				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2212
					this._delay(function() {
2213
						var that = this;
2214
						this.document.one( "mousedown", function( event ) {
2215
							if ( event.target !== that.element[ 0 ] &&
2216
									event.target !== menuElement &&
2217
									!$.contains( menuElement, event.target ) ) {
2218
								that.close();
2219
							}
2220
						});
2221
					});
2222
				}
2223
			},
2224
			menufocus: function( event, ui ) {
2225
				var label, item;
2226
				// support: Firefox
2227
				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
2228
				if ( this.isNewMenu ) {
2229
					this.isNewMenu = false;
2230
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2231
						this.menu.blur();
2232

    
2233
						this.document.one( "mousemove", function() {
2234
							$( event.target ).trigger( event.originalEvent );
2235
						});
2236

    
2237
						return;
2238
					}
2239
				}
2240

    
2241
				item = ui.item.data( "ui-autocomplete-item" );
2242
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
2243
					// use value to match what will end up in the input, if it was a key event
2244
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
2245
						this._value( item.value );
2246
					}
2247
				}
2248

    
2249
				// Announce the value in the liveRegion
2250
				label = ui.item.attr( "aria-label" ) || item.value;
2251
				if ( label && $.trim( label ).length ) {
2252
					this.liveRegion.children().hide();
2253
					$( "<div>" ).text( label ).appendTo( this.liveRegion );
2254
				}
2255
			},
2256
			menuselect: function( event, ui ) {
2257
				var item = ui.item.data( "ui-autocomplete-item" ),
2258
					previous = this.previous;
2259

    
2260
				// only trigger when focus was lost (click on menu)
2261
				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
2262
					this.element.focus();
2263
					this.previous = previous;
2264
					// #6109 - IE triggers two focus events and the second
2265
					// is asynchronous, so we need to reset the previous
2266
					// term synchronously and asynchronously :-(
2267
					this._delay(function() {
2268
						this.previous = previous;
2269
						this.selectedItem = item;
2270
					});
2271
				}
2272

    
2273
				if ( false !== this._trigger( "select", event, { item: item } ) ) {
2274
					this._value( item.value );
2275
				}
2276
				// reset the term after the select event
2277
				// this allows custom select handling to work properly
2278
				this.term = this._value();
2279

    
2280
				this.close( event );
2281
				this.selectedItem = item;
2282
			}
2283
		});
2284

    
2285
		this.liveRegion = $( "<span>", {
2286
				role: "status",
2287
				"aria-live": "assertive",
2288
				"aria-relevant": "additions"
2289
			})
2290
			.addClass( "ui-helper-hidden-accessible" )
2291
			.appendTo( this.document[ 0 ].body );
2292

    
2293
		// turning off autocomplete prevents the browser from remembering the
2294
		// value when navigating through history, so we re-enable autocomplete
2295
		// if the page is unloaded before the widget is destroyed. #7790
2296
		this._on( this.window, {
2297
			beforeunload: function() {
2298
				this.element.removeAttr( "autocomplete" );
2299
			}
2300
		});
2301
	},
2302

    
2303
	_destroy: function() {
2304
		clearTimeout( this.searching );
2305
		this.element
2306
			.removeClass( "ui-autocomplete-input" )
2307
			.removeAttr( "autocomplete" );
2308
		this.menu.element.remove();
2309
		this.liveRegion.remove();
2310
	},
2311

    
2312
	_setOption: function( key, value ) {
2313
		this._super( key, value );
2314
		if ( key === "source" ) {
2315
			this._initSource();
2316
		}
2317
		if ( key === "appendTo" ) {
2318
			this.menu.element.appendTo( this._appendTo() );
2319
		}
2320
		if ( key === "disabled" && value && this.xhr ) {
2321
			this.xhr.abort();
2322
		}
2323
	},
2324

    
2325
	_appendTo: function() {
2326
		var element = this.options.appendTo;
2327

    
2328
		if ( element ) {
2329
			element = element.jquery || element.nodeType ?
2330
				$( element ) :
2331
				this.document.find( element ).eq( 0 );
2332
		}
2333

    
2334
		if ( !element || !element[ 0 ] ) {
2335
			element = this.element.closest( ".ui-front" );
2336
		}
2337

    
2338
		if ( !element.length ) {
2339
			element = this.document[ 0 ].body;
2340
		}
2341

    
2342
		return element;
2343
	},
2344

    
2345
	_initSource: function() {
2346
		var array, url,
2347
			that = this;
2348
		if ( $.isArray( this.options.source ) ) {
2349
			array = this.options.source;
2350
			this.source = function( request, response ) {
2351
				response( $.ui.autocomplete.filter( array, request.term ) );
2352
			};
2353
		} else if ( typeof this.options.source === "string" ) {
2354
			url = this.options.source;
2355
			this.source = function( request, response ) {
2356
				if ( that.xhr ) {
2357
					that.xhr.abort();
2358
				}
2359
				that.xhr = $.ajax({
2360
					url: url,
2361
					data: request,
2362
					dataType: "json",
2363
					success: function( data ) {
2364
						response( data );
2365
					},
2366
					error: function() {
2367
						response([]);
2368
					}
2369
				});
2370
			};
2371
		} else {
2372
			this.source = this.options.source;
2373
		}
2374
	},
2375

    
2376
	_searchTimeout: function( event ) {
2377
		clearTimeout( this.searching );
2378
		this.searching = this._delay(function() {
2379

    
2380
			// Search if the value has changed, or if the user retypes the same value (see #7434)
2381
			var equalValues = this.term === this._value(),
2382
				menuVisible = this.menu.element.is( ":visible" ),
2383
				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
2384

    
2385
			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
2386
				this.selectedItem = null;
2387
				this.search( null, event );
2388
			}
2389
		}, this.options.delay );
2390
	},
2391

    
2392
	search: function( value, event ) {
2393
		value = value != null ? value : this._value();
2394

    
2395
		// always save the actual value, not the one passed as an argument
2396
		this.term = this._value();
2397

    
2398
		if ( value.length < this.options.minLength ) {
2399
			return this.close( event );
2400
		}
2401

    
2402
		if ( this._trigger( "search", event ) === false ) {
2403
			return;
2404
		}
2405

    
2406
		return this._search( value );
2407
	},
2408

    
2409
	_search: function( value ) {
2410
		this.pending++;
2411
		this.element.addClass( "ui-autocomplete-loading" );
2412
		this.cancelSearch = false;
2413

    
2414
		this.source( { term: value }, this._response() );
2415
	},
2416

    
2417
	_response: function() {
2418
		var index = ++this.requestIndex;
2419

    
2420
		return $.proxy(function( content ) {
2421
			if ( index === this.requestIndex ) {
2422
				this.__response( content );
2423
			}
2424

    
2425
			this.pending--;
2426
			if ( !this.pending ) {
2427
				this.element.removeClass( "ui-autocomplete-loading" );
2428
			}
2429
		}, this );
2430
	},
2431

    
2432
	__response: function( content ) {
2433
		if ( content ) {
2434
			content = this._normalize( content );
2435
		}
2436
		this._trigger( "response", null, { content: content } );
2437
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
2438
			this._suggest( content );
2439
			this._trigger( "open" );
2440
		} else {
2441
			// use ._close() instead of .close() so we don't cancel future searches
2442
			this._close();
2443
		}
2444
	},
2445

    
2446
	close: function( event ) {
2447
		this.cancelSearch = true;
2448
		this._close( event );
2449
	},
2450

    
2451
	_close: function( event ) {
2452
		if ( this.menu.element.is( ":visible" ) ) {
2453
			this.menu.element.hide();
2454
			this.menu.blur();
2455
			this.isNewMenu = true;
2456
			this._trigger( "close", event );
2457
		}
2458
	},
2459

    
2460
	_change: function( event ) {
2461
		if ( this.previous !== this._value() ) {
2462
			this._trigger( "change", event, { item: this.selectedItem } );
2463
		}
2464
	},
2465

    
2466
	_normalize: function( items ) {
2467
		// assume all items have the right format when the first item is complete
2468
		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
2469
			return items;
2470
		}
2471
		return $.map( items, function( item ) {
2472
			if ( typeof item === "string" ) {
2473
				return {
2474
					label: item,
2475
					value: item
2476
				};
2477
			}
2478
			return $.extend( {}, item, {
2479
				label: item.label || item.value,
2480
				value: item.value || item.label
2481
			});
2482
		});
2483
	},
2484

    
2485
	_suggest: function( items ) {
2486
		var ul = this.menu.element.empty();
2487
		this._renderMenu( ul, items );
2488
		this.isNewMenu = true;
2489
		this.menu.refresh();
2490

    
2491
		// size and position menu
2492
		ul.show();
2493
		this._resizeMenu();
2494
		ul.position( $.extend({
2495
			of: this.element
2496
		}, this.options.position ) );
2497

    
2498
		if ( this.options.autoFocus ) {
2499
			this.menu.next();
2500
		}
2501
	},
2502

    
2503
	_resizeMenu: function() {
2504
		var ul = this.menu.element;
2505
		ul.outerWidth( Math.max(
2506
			// Firefox wraps long text (possibly a rounding bug)
2507
			// so we add 1px to avoid the wrapping (#7513)
2508
			ul.width( "" ).outerWidth() + 1,
2509
			this.element.outerWidth()
2510
		) );
2511
	},
2512

    
2513
	_renderMenu: function( ul, items ) {
2514
		var that = this;
2515
		$.each( items, function( index, item ) {
2516
			that._renderItemData( ul, item );
2517
		});
2518
	},
2519

    
2520
	_renderItemData: function( ul, item ) {
2521
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
2522
	},
2523

    
2524
	_renderItem: function( ul, item ) {
2525
		return $( "<li>" ).text( item.label ).appendTo( ul );
2526
	},
2527

    
2528
	_move: function( direction, event ) {
2529
		if ( !this.menu.element.is( ":visible" ) ) {
2530
			this.search( null, event );
2531
			return;
2532
		}
2533
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
2534
				this.menu.isLastItem() && /^next/.test( direction ) ) {
2535

    
2536
			if ( !this.isMultiLine ) {
2537
				this._value( this.term );
2538
			}
2539

    
2540
			this.menu.blur();
2541
			return;
2542
		}
2543
		this.menu[ direction ]( event );
2544
	},
2545

    
2546
	widget: function() {
2547
		return this.menu.element;
2548
	},
2549

    
2550
	_value: function() {
2551
		return this.valueMethod.apply( this.element, arguments );
2552
	},
2553

    
2554
	_keyEvent: function( keyEvent, event ) {
2555
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2556
			this._move( keyEvent, event );
2557

    
2558
			// prevents moving cursor to beginning/end of the text field in some browsers
2559
			event.preventDefault();
2560
		}
2561
	}
2562
});
2563

    
2564
$.extend( $.ui.autocomplete, {
2565
	escapeRegex: function( value ) {
2566
		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
2567
	},
2568
	filter: function( array, term ) {
2569
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
2570
		return $.grep( array, function( value ) {
2571
			return matcher.test( value.label || value.value || value );
2572
		});
2573
	}
2574
});
2575

    
2576
// live region extension, adding a `messages` option
2577
// NOTE: This is an experimental API. We are still investigating
2578
// a full solution for string manipulation and internationalization.
2579
$.widget( "ui.autocomplete", $.ui.autocomplete, {
2580
	options: {
2581
		messages: {
2582
			noResults: "No search results.",
2583
			results: function( amount ) {
2584
				return amount + ( amount > 1 ? " results are" : " result is" ) +
2585
					" available, use up and down arrow keys to navigate.";
2586
			}
2587
		}
2588
	},
2589

    
2590
	__response: function( content ) {
2591
		var message;
2592
		this._superApply( arguments );
2593
		if ( this.options.disabled || this.cancelSearch ) {
2594
			return;
2595
		}
2596
		if ( content && content.length ) {
2597
			message = this.options.messages.results( content.length );
2598
		} else {
2599
			message = this.options.messages.noResults;
2600
		}
2601
		this.liveRegion.children().hide();
2602
		$( "<div>" ).text( message ).appendTo( this.liveRegion );
2603
	}
2604
});
2605

    
2606
var autocomplete = $.ui.autocomplete;
2607

    
2608

    
2609

    
2610
}));
(4-4/8)