Subversion-Projekte lars-tiefland.nagios-php

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
/*! jQuery UI - v1.9.2 - 2012-11-23
2
* http://jqueryui.com
3
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
4
* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */
5
 
6
(function( $, undefined ) {
7
 
8
var uuid = 0,
9
	runiqueId = /^ui-id-\d+$/;
10
 
11
// prevent duplicate loading
12
// this is only a problem because we proxy existing functions
13
// and we don't want to double proxy them
14
$.ui = $.ui || {};
15
if ( $.ui.version ) {
16
	return;
17
}
18
 
19
$.extend( $.ui, {
20
	version: "1.9.2",
21
 
22
	keyCode: {
23
		BACKSPACE: 8,
24
		COMMA: 188,
25
		DELETE: 46,
26
		DOWN: 40,
27
		END: 35,
28
		ENTER: 13,
29
		ESCAPE: 27,
30
		HOME: 36,
31
		LEFT: 37,
32
		NUMPAD_ADD: 107,
33
		NUMPAD_DECIMAL: 110,
34
		NUMPAD_DIVIDE: 111,
35
		NUMPAD_ENTER: 108,
36
		NUMPAD_MULTIPLY: 106,
37
		NUMPAD_SUBTRACT: 109,
38
		PAGE_DOWN: 34,
39
		PAGE_UP: 33,
40
		PERIOD: 190,
41
		RIGHT: 39,
42
		SPACE: 32,
43
		TAB: 9,
44
		UP: 38
45
	}
46
});
47
 
48
// plugins
49
$.fn.extend({
50
	_focus: $.fn.focus,
51
	focus: function( delay, fn ) {
52
		return typeof delay === "number" ?
53
			this.each(function() {
54
				var elem = this;
55
				setTimeout(function() {
56
					$( elem ).focus();
57
					if ( fn ) {
58
						fn.call( elem );
59
					}
60
				}, delay );
61
			}) :
62
			this._focus.apply( this, arguments );
63
	},
64
 
65
	scrollParent: function() {
66
		var scrollParent;
67
		if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
68
			scrollParent = this.parents().filter(function() {
69
				return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
70
			}).eq(0);
71
		} else {
72
			scrollParent = this.parents().filter(function() {
73
				return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
74
			}).eq(0);
75
		}
76
 
77
		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
78
	},
79
 
80
	zIndex: function( zIndex ) {
81
		if ( zIndex !== undefined ) {
82
			return this.css( "zIndex", zIndex );
83
		}
84
 
85
		if ( this.length ) {
86
			var elem = $( this[ 0 ] ), position, value;
87
			while ( elem.length && elem[ 0 ] !== document ) {
88
				// Ignore z-index if position is set to a value where z-index is ignored by the browser
89
				// This makes behavior of this function consistent across browsers
90
				// WebKit always returns auto if the element is positioned
91
				position = elem.css( "position" );
92
				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
93
					// IE returns 0 when zIndex is not specified
94
					// other browsers return a string
95
					// we ignore the case of nested elements with an explicit value of 0
96
					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
97
					value = parseInt( elem.css( "zIndex" ), 10 );
98
					if ( !isNaN( value ) && value !== 0 ) {
99
						return value;
100
					}
101
				}
102
				elem = elem.parent();
103
			}
104
		}
105
 
106
		return 0;
107
	},
108
 
109
	uniqueId: function() {
110
		return this.each(function() {
111
			if ( !this.id ) {
112
				this.id = "ui-id-" + (++uuid);
113
			}
114
		});
115
	},
116
 
117
	removeUniqueId: function() {
118
		return this.each(function() {
119
			if ( runiqueId.test( this.id ) ) {
120
				$( this ).removeAttr( "id" );
121
			}
122
		});
123
	}
124
});
125
 
126
// selectors
127
function focusable( element, isTabIndexNotNaN ) {
128
	var map, mapName, img,
129
		nodeName = element.nodeName.toLowerCase();
130
	if ( "area" === nodeName ) {
131
		map = element.parentNode;
132
		mapName = map.name;
133
		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
134
			return false;
135
		}
136
		img = $( "img[usemap=#" + mapName + "]" )[0];
137
		return !!img && visible( img );
138
	}
139
	return ( /input|select|textarea|button|object/.test( nodeName ) ?
140
		!element.disabled :
141
		"a" === nodeName ?
142
			element.href || isTabIndexNotNaN :
143
			isTabIndexNotNaN) &&
144
		// the element and all of its ancestors must be visible
145
		visible( element );
146
}
147
 
148
function visible( element ) {
149
	return $.expr.filters.visible( element ) &&
150
		!$( element ).parents().andSelf().filter(function() {
151
			return $.css( this, "visibility" ) === "hidden";
152
		}).length;
153
}
154
 
155
$.extend( $.expr[ ":" ], {
156
	data: $.expr.createPseudo ?
157
		$.expr.createPseudo(function( dataName ) {
158
			return function( elem ) {
159
				return !!$.data( elem, dataName );
160
			};
161
		}) :
162
		// support: jQuery <1.8
163
		function( elem, i, match ) {
164
			return !!$.data( elem, match[ 3 ] );
165
		},
166
 
167
	focusable: function( element ) {
168
		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
169
	},
170
 
171
	tabbable: function( element ) {
172
		var tabIndex = $.attr( element, "tabindex" ),
173
			isTabIndexNaN = isNaN( tabIndex );
174
		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
175
	}
176
});
177
 
178
// support
179
$(function() {
180
	var body = document.body,
181
		div = body.appendChild( div = document.createElement( "div" ) );
182
 
183
	// access offsetHeight before setting the style to prevent a layout bug
184
	// in IE 9 which causes the element to continue to take up space even
185
	// after it is removed from the DOM (#8026)
186
	div.offsetHeight;
187
 
188
	$.extend( div.style, {
189
		minHeight: "100px",
190
		height: "auto",
191
		padding: 0,
192
		borderWidth: 0
193
	});
194
 
195
	$.support.minHeight = div.offsetHeight === 100;
196
	$.support.selectstart = "onselectstart" in div;
197
 
198
	// set display to none to avoid a layout bug in IE
199
	// http://dev.jquery.com/ticket/4014
200
	body.removeChild( div ).style.display = "none";
201
});
202
 
203
// support: jQuery <1.8
204
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
205
	$.each( [ "Width", "Height" ], function( i, name ) {
206
		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
207
			type = name.toLowerCase(),
208
			orig = {
209
				innerWidth: $.fn.innerWidth,
210
				innerHeight: $.fn.innerHeight,
211
				outerWidth: $.fn.outerWidth,
212
				outerHeight: $.fn.outerHeight
213
			};
214
 
215
		function reduce( elem, size, border, margin ) {
216
			$.each( side, function() {
217
				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
218
				if ( border ) {
219
					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
220
				}
221
				if ( margin ) {
222
					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
223
				}
224
			});
225
			return size;
226
		}
227
 
228
		$.fn[ "inner" + name ] = function( size ) {
229
			if ( size === undefined ) {
230
				return orig[ "inner" + name ].call( this );
231
			}
232
 
233
			return this.each(function() {
234
				$( this ).css( type, reduce( this, size ) + "px" );
235
			});
236
		};
237
 
238
		$.fn[ "outer" + name] = function( size, margin ) {
239
			if ( typeof size !== "number" ) {
240
				return orig[ "outer" + name ].call( this, size );
241
			}
242
 
243
			return this.each(function() {
244
				$( this).css( type, reduce( this, size, true, margin ) + "px" );
245
			});
246
		};
247
	});
248
}
249
 
250
// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
251
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
252
	$.fn.removeData = (function( removeData ) {
253
		return function( key ) {
254
			if ( arguments.length ) {
255
				return removeData.call( this, $.camelCase( key ) );
256
			} else {
257
				return removeData.call( this );
258
			}
259
		};
260
	})( $.fn.removeData );
261
}
262
 
263
 
264
 
265
 
266
 
267
// deprecated
268
 
269
(function() {
270
	var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
271
	$.ui.ie = uaMatch.length ? true : false;
272
	$.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
273
})();
274
 
275
$.fn.extend({
276
	disableSelection: function() {
277
		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
278
			".ui-disableSelection", function( event ) {
279
				event.preventDefault();
280
			});
281
	},
282
 
283
	enableSelection: function() {
284
		return this.unbind( ".ui-disableSelection" );
285
	}
286
});
287
 
288
$.extend( $.ui, {
289
	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
290
	plugin: {
291
		add: function( module, option, set ) {
292
			var i,
293
				proto = $.ui[ module ].prototype;
294
			for ( i in set ) {
295
				proto.plugins[ i ] = proto.plugins[ i ] || [];
296
				proto.plugins[ i ].push( [ option, set[ i ] ] );
297
			}
298
		},
299
		call: function( instance, name, args ) {
300
			var i,
301
				set = instance.plugins[ name ];
302
			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
303
				return;
304
			}
305
 
306
			for ( i = 0; i < set.length; i++ ) {
307
				if ( instance.options[ set[ i ][ 0 ] ] ) {
308
					set[ i ][ 1 ].apply( instance.element, args );
309
				}
310
			}
311
		}
312
	},
313
 
314
	contains: $.contains,
315
 
316
	// only used by resizable
317
	hasScroll: function( el, a ) {
318
 
319
		//If overflow is hidden, the element might have extra content, but the user wants to hide it
320
		if ( $( el ).css( "overflow" ) === "hidden") {
321
			return false;
322
		}
323
 
324
		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
325
			has = false;
326
 
327
		if ( el[ scroll ] > 0 ) {
328
			return true;
329
		}
330
 
331
		// TODO: determine which cases actually cause this to happen
332
		// if the element doesn't have the scroll set, see if it's possible to
333
		// set the scroll
334
		el[ scroll ] = 1;
335
		has = ( el[ scroll ] > 0 );
336
		el[ scroll ] = 0;
337
		return has;
338
	},
339
 
340
	// these are odd functions, fix the API or move into individual plugins
341
	isOverAxis: function( x, reference, size ) {
342
		//Determines when x coordinate is over "b" element axis
343
		return ( x > reference ) && ( x < ( reference + size ) );
344
	},
345
	isOver: function( y, x, top, left, height, width ) {
346
		//Determines when x, y coordinates is over "b" element
347
		return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
348
	}
349
});
350
 
351
})( jQuery );
352
 
353
(function( $, undefined ) {
354
 
355
var uuid = 0,
356
	slice = Array.prototype.slice,
357
	_cleanData = $.cleanData;
358
$.cleanData = function( elems ) {
359
	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
360
		try {
361
			$( elem ).triggerHandler( "remove" );
362
		// http://bugs.jquery.com/ticket/8235
363
		} catch( e ) {}
364
	}
365
	_cleanData( elems );
366
};
367
 
368
$.widget = function( name, base, prototype ) {
369
	var fullName, existingConstructor, constructor, basePrototype,
370
		namespace = name.split( "." )[ 0 ];
371
 
372
	name = name.split( "." )[ 1 ];
373
	fullName = namespace + "-" + name;
374
 
375
	if ( !prototype ) {
376
		prototype = base;
377
		base = $.Widget;
378
	}
379
 
380
	// create selector for plugin
381
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
382
		return !!$.data( elem, fullName );
383
	};
384
 
385
	$[ namespace ] = $[ namespace ] || {};
386
	existingConstructor = $[ namespace ][ name ];
387
	constructor = $[ namespace ][ name ] = function( options, element ) {
388
		// allow instantiation without "new" keyword
389
		if ( !this._createWidget ) {
390
			return new constructor( options, element );
391
		}
392
 
393
		// allow instantiation without initializing for simple inheritance
394
		// must use "new" keyword (the code above always passes args)
395
		if ( arguments.length ) {
396
			this._createWidget( options, element );
397
		}
398
	};
399
	// extend with the existing constructor to carry over any static properties
400
	$.extend( constructor, existingConstructor, {
401
		version: prototype.version,
402
		// copy the object used to create the prototype in case we need to
403
		// redefine the widget later
404
		_proto: $.extend( {}, prototype ),
405
		// track widgets that inherit from this widget in case this widget is
406
		// redefined after a widget inherits from it
407
		_childConstructors: []
408
	});
409
 
410
	basePrototype = new base();
411
	// we need to make the options hash a property directly on the new instance
412
	// otherwise we'll modify the options hash on the prototype that we're
413
	// inheriting from
414
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
415
	$.each( prototype, function( prop, value ) {
416
		if ( $.isFunction( value ) ) {
417
			prototype[ prop ] = (function() {
418
				var _super = function() {
419
						return base.prototype[ prop ].apply( this, arguments );
420
					},
421
					_superApply = function( args ) {
422
						return base.prototype[ prop ].apply( this, args );
423
					};
424
				return function() {
425
					var __super = this._super,
426
						__superApply = this._superApply,
427
						returnValue;
428
 
429
					this._super = _super;
430
					this._superApply = _superApply;
431
 
432
					returnValue = value.apply( this, arguments );
433
 
434
					this._super = __super;
435
					this._superApply = __superApply;
436
 
437
					return returnValue;
438
				};
439
			})();
440
		}
441
	});
442
	constructor.prototype = $.widget.extend( basePrototype, {
443
		// TODO: remove support for widgetEventPrefix
444
		// always use the name + a colon as the prefix, e.g., draggable:start
445
		// don't prefix for widgets that aren't DOM-based
446
		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
447
	}, prototype, {
448
		constructor: constructor,
449
		namespace: namespace,
450
		widgetName: name,
451
		// TODO remove widgetBaseClass, see #8155
452
		widgetBaseClass: fullName,
453
		widgetFullName: fullName
454
	});
455
 
456
	// If this widget is being redefined then we need to find all widgets that
457
	// are inheriting from it and redefine all of them so that they inherit from
458
	// the new version of this widget. We're essentially trying to replace one
459
	// level in the prototype chain.
460
	if ( existingConstructor ) {
461
		$.each( existingConstructor._childConstructors, function( i, child ) {
462
			var childPrototype = child.prototype;
463
 
464
			// redefine the child widget using the same prototype that was
465
			// originally used, but inherit from the new version of the base
466
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
467
		});
468
		// remove the list of existing child constructors from the old constructor
469
		// so the old child constructors can be garbage collected
470
		delete existingConstructor._childConstructors;
471
	} else {
472
		base._childConstructors.push( constructor );
473
	}
474
 
475
	$.widget.bridge( name, constructor );
476
};
477
 
478
$.widget.extend = function( target ) {
479
	var input = slice.call( arguments, 1 ),
480
		inputIndex = 0,
481
		inputLength = input.length,
482
		key,
483
		value;
484
	for ( ; inputIndex < inputLength; inputIndex++ ) {
485
		for ( key in input[ inputIndex ] ) {
486
			value = input[ inputIndex ][ key ];
487
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
488
				// Clone objects
489
				if ( $.isPlainObject( value ) ) {
490
					target[ key ] = $.isPlainObject( target[ key ] ) ?
491
						$.widget.extend( {}, target[ key ], value ) :
492
						// Don't extend strings, arrays, etc. with objects
493
						$.widget.extend( {}, value );
494
				// Copy everything else by reference
495
				} else {
496
					target[ key ] = value;
497
				}
498
			}
499
		}
500
	}
501
	return target;
502
};
503
 
504
$.widget.bridge = function( name, object ) {
505
	var fullName = object.prototype.widgetFullName || name;
506
	$.fn[ name ] = function( options ) {
507
		var isMethodCall = typeof options === "string",
508
			args = slice.call( arguments, 1 ),
509
			returnValue = this;
510
 
511
		// allow multiple hashes to be passed on init
512
		options = !isMethodCall && args.length ?
513
			$.widget.extend.apply( null, [ options ].concat(args) ) :
514
			options;
515
 
516
		if ( isMethodCall ) {
517
			this.each(function() {
518
				var methodValue,
519
					instance = $.data( this, fullName );
520
				if ( !instance ) {
521
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
522
						"attempted to call method '" + options + "'" );
523
				}
524
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
525
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
526
				}
527
				methodValue = instance[ options ].apply( instance, args );
528
				if ( methodValue !== instance && methodValue !== undefined ) {
529
					returnValue = methodValue && methodValue.jquery ?
530
						returnValue.pushStack( methodValue.get() ) :
531
						methodValue;
532
					return false;
533
				}
534
			});
535
		} else {
536
			this.each(function() {
537
				var instance = $.data( this, fullName );
538
				if ( instance ) {
539
					instance.option( options || {} )._init();
540
				} else {
541
					$.data( this, fullName, new object( options, this ) );
542
				}
543
			});
544
		}
545
 
546
		return returnValue;
547
	};
548
};
549
 
550
$.Widget = function( /* options, element */ ) {};
551
$.Widget._childConstructors = [];
552
 
553
$.Widget.prototype = {
554
	widgetName: "widget",
555
	widgetEventPrefix: "",
556
	defaultElement: "<div>",
557
	options: {
558
		disabled: false,
559
 
560
		// callbacks
561
		create: null
562
	},
563
	_createWidget: function( options, element ) {
564
		element = $( element || this.defaultElement || this )[ 0 ];
565
		this.element = $( element );
566
		this.uuid = uuid++;
567
		this.eventNamespace = "." + this.widgetName + this.uuid;
568
		this.options = $.widget.extend( {},
569
			this.options,
570
			this._getCreateOptions(),
571
			options );
572
 
573
		this.bindings = $();
574
		this.hoverable = $();
575
		this.focusable = $();
576
 
577
		if ( element !== this ) {
578
			// 1.9 BC for #7810
579
			// TODO remove dual storage
580
			$.data( element, this.widgetName, this );
581
			$.data( element, this.widgetFullName, this );
582
			this._on( true, this.element, {
583
				remove: function( event ) {
584
					if ( event.target === element ) {
585
						this.destroy();
586
					}
587
				}
588
			});
589
			this.document = $( element.style ?
590
				// element within the document
591
				element.ownerDocument :
592
				// element is window or document
593
				element.document || element );
594
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
595
		}
596
 
597
		this._create();
598
		this._trigger( "create", null, this._getCreateEventData() );
599
		this._init();
600
	},
601
	_getCreateOptions: $.noop,
602
	_getCreateEventData: $.noop,
603
	_create: $.noop,
604
	_init: $.noop,
605
 
606
	destroy: function() {
607
		this._destroy();
608
		// we can probably remove the unbind calls in 2.0
609
		// all event bindings should go through this._on()
610
		this.element
611
			.unbind( this.eventNamespace )
612
			// 1.9 BC for #7810
613
			// TODO remove dual storage
614
			.removeData( this.widgetName )
615
			.removeData( this.widgetFullName )
616
			// support: jquery <1.6.3
617
			// http://bugs.jquery.com/ticket/9413
618
			.removeData( $.camelCase( this.widgetFullName ) );
619
		this.widget()
620
			.unbind( this.eventNamespace )
621
			.removeAttr( "aria-disabled" )
622
			.removeClass(
623
				this.widgetFullName + "-disabled " +
624
				"ui-state-disabled" );
625
 
626
		// clean up events and states
627
		this.bindings.unbind( this.eventNamespace );
628
		this.hoverable.removeClass( "ui-state-hover" );
629
		this.focusable.removeClass( "ui-state-focus" );
630
	},
631
	_destroy: $.noop,
632
 
633
	widget: function() {
634
		return this.element;
635
	},
636
 
637
	option: function( key, value ) {
638
		var options = key,
639
			parts,
640
			curOption,
641
			i;
642
 
643
		if ( arguments.length === 0 ) {
644
			// don't return a reference to the internal hash
645
			return $.widget.extend( {}, this.options );
646
		}
647
 
648
		if ( typeof key === "string" ) {
649
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
650
			options = {};
651
			parts = key.split( "." );
652
			key = parts.shift();
653
			if ( parts.length ) {
654
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
655
				for ( i = 0; i < parts.length - 1; i++ ) {
656
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
657
					curOption = curOption[ parts[ i ] ];
658
				}
659
				key = parts.pop();
660
				if ( value === undefined ) {
661
					return curOption[ key ] === undefined ? null : curOption[ key ];
662
				}
663
				curOption[ key ] = value;
664
			} else {
665
				if ( value === undefined ) {
666
					return this.options[ key ] === undefined ? null : this.options[ key ];
667
				}
668
				options[ key ] = value;
669
			}
670
		}
671
 
672
		this._setOptions( options );
673
 
674
		return this;
675
	},
676
	_setOptions: function( options ) {
677
		var key;
678
 
679
		for ( key in options ) {
680
			this._setOption( key, options[ key ] );
681
		}
682
 
683
		return this;
684
	},
685
	_setOption: function( key, value ) {
686
		this.options[ key ] = value;
687
 
688
		if ( key === "disabled" ) {
689
			this.widget()
690
				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
691
				.attr( "aria-disabled", value );
692
			this.hoverable.removeClass( "ui-state-hover" );
693
			this.focusable.removeClass( "ui-state-focus" );
694
		}
695
 
696
		return this;
697
	},
698
 
699
	enable: function() {
700
		return this._setOption( "disabled", false );
701
	},
702
	disable: function() {
703
		return this._setOption( "disabled", true );
704
	},
705
 
706
	_on: function( suppressDisabledCheck, element, handlers ) {
707
		var delegateElement,
708
			instance = this;
709
 
710
		// no suppressDisabledCheck flag, shuffle arguments
711
		if ( typeof suppressDisabledCheck !== "boolean" ) {
712
			handlers = element;
713
			element = suppressDisabledCheck;
714
			suppressDisabledCheck = false;
715
		}
716
 
717
		// no element argument, shuffle and use this.element
718
		if ( !handlers ) {
719
			handlers = element;
720
			element = this.element;
721
			delegateElement = this.widget();
722
		} else {
723
			// accept selectors, DOM elements
724
			element = delegateElement = $( element );
725
			this.bindings = this.bindings.add( element );
726
		}
727
 
728
		$.each( handlers, function( event, handler ) {
729
			function handlerProxy() {
730
				// allow widgets to customize the disabled handling
731
				// - disabled as an array instead of boolean
732
				// - disabled class as method for disabling individual parts
733
				if ( !suppressDisabledCheck &&
734
						( instance.options.disabled === true ||
735
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
736
					return;
737
				}
738
				return ( typeof handler === "string" ? instance[ handler ] : handler )
739
					.apply( instance, arguments );
740
			}
741
 
742
			// copy the guid so direct unbinding works
743
			if ( typeof handler !== "string" ) {
744
				handlerProxy.guid = handler.guid =
745
					handler.guid || handlerProxy.guid || $.guid++;
746
			}
747
 
748
			var match = event.match( /^(\w+)\s*(.*)$/ ),
749
				eventName = match[1] + instance.eventNamespace,
750
				selector = match[2];
751
			if ( selector ) {
752
				delegateElement.delegate( selector, eventName, handlerProxy );
753
			} else {
754
				element.bind( eventName, handlerProxy );
755
			}
756
		});
757
	},
758
 
759
	_off: function( element, eventName ) {
760
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
761
		element.unbind( eventName ).undelegate( eventName );
762
	},
763
 
764
	_delay: function( handler, delay ) {
765
		function handlerProxy() {
766
			return ( typeof handler === "string" ? instance[ handler ] : handler )
767
				.apply( instance, arguments );
768
		}
769
		var instance = this;
770
		return setTimeout( handlerProxy, delay || 0 );
771
	},
772
 
773
	_hoverable: function( element ) {
774
		this.hoverable = this.hoverable.add( element );
775
		this._on( element, {
776
			mouseenter: function( event ) {
777
				$( event.currentTarget ).addClass( "ui-state-hover" );
778
			},
779
			mouseleave: function( event ) {
780
				$( event.currentTarget ).removeClass( "ui-state-hover" );
781
			}
782
		});
783
	},
784
 
785
	_focusable: function( element ) {
786
		this.focusable = this.focusable.add( element );
787
		this._on( element, {
788
			focusin: function( event ) {
789
				$( event.currentTarget ).addClass( "ui-state-focus" );
790
			},
791
			focusout: function( event ) {
792
				$( event.currentTarget ).removeClass( "ui-state-focus" );
793
			}
794
		});
795
	},
796
 
797
	_trigger: function( type, event, data ) {
798
		var prop, orig,
799
			callback = this.options[ type ];
800
 
801
		data = data || {};
802
		event = $.Event( event );
803
		event.type = ( type === this.widgetEventPrefix ?
804
			type :
805
			this.widgetEventPrefix + type ).toLowerCase();
806
		// the original event may come from any element
807
		// so we need to reset the target on the new event
808
		event.target = this.element[ 0 ];
809
 
810
		// copy original event properties over to the new event
811
		orig = event.originalEvent;
812
		if ( orig ) {
813
			for ( prop in orig ) {
814
				if ( !( prop in event ) ) {
815
					event[ prop ] = orig[ prop ];
816
				}
817
			}
818
		}
819
 
820
		this.element.trigger( event, data );
821
		return !( $.isFunction( callback ) &&
822
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
823
			event.isDefaultPrevented() );
824
	}
825
};
826
 
827
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
828
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
829
		if ( typeof options === "string" ) {
830
			options = { effect: options };
831
		}
832
		var hasOptions,
833
			effectName = !options ?
834
				method :
835
				options === true || typeof options === "number" ?
836
					defaultEffect :
837
					options.effect || defaultEffect;
838
		options = options || {};
839
		if ( typeof options === "number" ) {
840
			options = { duration: options };
841
		}
842
		hasOptions = !$.isEmptyObject( options );
843
		options.complete = callback;
844
		if ( options.delay ) {
845
			element.delay( options.delay );
846
		}
847
		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
848
			element[ method ]( options );
849
		} else if ( effectName !== method && element[ effectName ] ) {
850
			element[ effectName ]( options.duration, options.easing, callback );
851
		} else {
852
			element.queue(function( next ) {
853
				$( this )[ method ]();
854
				if ( callback ) {
855
					callback.call( element[ 0 ] );
856
				}
857
				next();
858
			});
859
		}
860
	};
861
});
862
 
863
// DEPRECATED
864
if ( $.uiBackCompat !== false ) {
865
	$.Widget.prototype._getCreateOptions = function() {
866
		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
867
	};
868
}
869
 
870
})( jQuery );
871
 
872
(function( $, undefined ) {
873
 
874
var mouseHandled = false;
875
$( document ).mouseup( function( e ) {
876
	mouseHandled = false;
877
});
878
 
879
$.widget("ui.mouse", {
880
	version: "1.9.2",
881
	options: {
882
		cancel: 'input,textarea,button,select,option',
883
		distance: 1,
884
		delay: 0
885
	},
886
	_mouseInit: function() {
887
		var that = this;
888
 
889
		this.element
890
			.bind('mousedown.'+this.widgetName, function(event) {
891
				return that._mouseDown(event);
892
			})
893
			.bind('click.'+this.widgetName, function(event) {
894
				if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
895
					$.removeData(event.target, that.widgetName + '.preventClickEvent');
896
					event.stopImmediatePropagation();
897
					return false;
898
				}
899
			});
900
 
901
		this.started = false;
902
	},
903
 
904
	// TODO: make sure destroying one instance of mouse doesn't mess with
905
	// other instances of mouse
906
	_mouseDestroy: function() {
907
		this.element.unbind('.'+this.widgetName);
908
		if ( this._mouseMoveDelegate ) {
909
			$(document)
910
				.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
911
				.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
912
		}
913
	},
914
 
915
	_mouseDown: function(event) {
916
		// don't let more than one widget handle mouseStart
917
		if( mouseHandled ) { return; }
918
 
919
		// we may have missed mouseup (out of window)
920
		(this._mouseStarted && this._mouseUp(event));
921
 
922
		this._mouseDownEvent = event;
923
 
924
		var that = this,
925
			btnIsLeft = (event.which === 1),
926
			// event.target.nodeName works around a bug in IE 8 with
927
			// disabled inputs (#7620)
928
			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
929
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
930
			return true;
931
		}
932
 
933
		this.mouseDelayMet = !this.options.delay;
934
		if (!this.mouseDelayMet) {
935
			this._mouseDelayTimer = setTimeout(function() {
936
				that.mouseDelayMet = true;
937
			}, this.options.delay);
938
		}
939
 
940
		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
941
			this._mouseStarted = (this._mouseStart(event) !== false);
942
			if (!this._mouseStarted) {
943
				event.preventDefault();
944
				return true;
945
			}
946
		}
947
 
948
		// Click event may never have fired (Gecko & Opera)
949
		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
950
			$.removeData(event.target, this.widgetName + '.preventClickEvent');
951
		}
952
 
953
		// these delegates are required to keep context
954
		this._mouseMoveDelegate = function(event) {
955
			return that._mouseMove(event);
956
		};
957
		this._mouseUpDelegate = function(event) {
958
			return that._mouseUp(event);
959
		};
960
		$(document)
961
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
962
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
963
 
964
		event.preventDefault();
965
 
966
		mouseHandled = true;
967
		return true;
968
	},
969
 
970
	_mouseMove: function(event) {
971
		// IE mouseup check - mouseup happened when mouse was out of window
972
		if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
973
			return this._mouseUp(event);
974
		}
975
 
976
		if (this._mouseStarted) {
977
			this._mouseDrag(event);
978
			return event.preventDefault();
979
		}
980
 
981
		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
982
			this._mouseStarted =
983
				(this._mouseStart(this._mouseDownEvent, event) !== false);
984
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
985
		}
986
 
987
		return !this._mouseStarted;
988
	},
989
 
990
	_mouseUp: function(event) {
991
		$(document)
992
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
993
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
994
 
995
		if (this._mouseStarted) {
996
			this._mouseStarted = false;
997
 
998
			if (event.target === this._mouseDownEvent.target) {
999
				$.data(event.target, this.widgetName + '.preventClickEvent', true);
1000
			}
1001
 
1002
			this._mouseStop(event);
1003
		}
1004
 
1005
		return false;
1006
	},
1007
 
1008
	_mouseDistanceMet: function(event) {
1009
		return (Math.max(
1010
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
1011
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
1012
			) >= this.options.distance
1013
		);
1014
	},
1015
 
1016
	_mouseDelayMet: function(event) {
1017
		return this.mouseDelayMet;
1018
	},
1019
 
1020
	// These are placeholder methods, to be overriden by extending plugin
1021
	_mouseStart: function(event) {},
1022
	_mouseDrag: function(event) {},
1023
	_mouseStop: function(event) {},
1024
	_mouseCapture: function(event) { return true; }
1025
});
1026
 
1027
})(jQuery);
1028
 
1029
(function( $, undefined ) {
1030
 
1031
$.widget("ui.draggable", $.ui.mouse, {
1032
	version: "1.9.2",
1033
	widgetEventPrefix: "drag",
1034
	options: {
1035
		addClasses: true,
1036
		appendTo: "parent",
1037
		axis: false,
1038
		connectToSortable: false,
1039
		containment: false,
1040
		cursor: "auto",
1041
		cursorAt: false,
1042
		grid: false,
1043
		handle: false,
1044
		helper: "original",
1045
		iframeFix: false,
1046
		opacity: false,
1047
		refreshPositions: false,
1048
		revert: false,
1049
		revertDuration: 500,
1050
		scope: "default",
1051
		scroll: true,
1052
		scrollSensitivity: 20,
1053
		scrollSpeed: 20,
1054
		snap: false,
1055
		snapMode: "both",
1056
		snapTolerance: 20,
1057
		stack: false,
1058
		zIndex: false
1059
	},
1060
	_create: function() {
1061
 
1062
		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1063
			this.element[0].style.position = 'relative';
1064
 
1065
		(this.options.addClasses && this.element.addClass("ui-draggable"));
1066
		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1067
 
1068
		this._mouseInit();
1069
 
1070
	},
1071
 
1072
	_destroy: function() {
1073
		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1074
		this._mouseDestroy();
1075
	},
1076
 
1077
	_mouseCapture: function(event) {
1078
 
1079
		var o = this.options;
1080
 
1081
		// among others, prevent a drag on a resizable-handle
1082
		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1083
			return false;
1084
 
1085
		//Quit if we're not on a valid handle
1086
		this.handle = this._getHandle(event);
1087
		if (!this.handle)
1088
			return false;
1089
 
1090
		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1091
			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1092
			.css({
1093
				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1094
				position: "absolute", opacity: "0.001", zIndex: 1000
1095
			})
1096
			.css($(this).offset())
1097
			.appendTo("body");
1098
		});
1099
 
1100
		return true;
1101
 
1102
	},
1103
 
1104
	_mouseStart: function(event) {
1105
 
1106
		var o = this.options;
1107
 
1108
		//Create and append the visible helper
1109
		this.helper = this._createHelper(event);
1110
 
1111
		this.helper.addClass("ui-draggable-dragging");
1112
 
1113
		//Cache the helper size
1114
		this._cacheHelperProportions();
1115
 
1116
		//If ddmanager is used for droppables, set the global draggable
1117
		if($.ui.ddmanager)
1118
			$.ui.ddmanager.current = this;
1119
 
1120
		/*
1121
		 * - Position generation -
1122
		 * This block generates everything position related - it's the core of draggables.
1123
		 */
1124
 
1125
		//Cache the margins of the original element
1126
		this._cacheMargins();
1127
 
1128
		//Store the helper's css position
1129
		this.cssPosition = this.helper.css("position");
1130
		this.scrollParent = this.helper.scrollParent();
1131
 
1132
		//The element's absolute position on the page minus margins
1133
		this.offset = this.positionAbs = this.element.offset();
1134
		this.offset = {
1135
			top: this.offset.top - this.margins.top,
1136
			left: this.offset.left - this.margins.left
1137
		};
1138
 
1139
		$.extend(this.offset, {
1140
			click: { //Where the click happened, relative to the element
1141
				left: event.pageX - this.offset.left,
1142
				top: event.pageY - this.offset.top
1143
			},
1144
			parent: this._getParentOffset(),
1145
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1146
		});
1147
 
1148
		//Generate the original position
1149
		this.originalPosition = this.position = this._generatePosition(event);
1150
		this.originalPageX = event.pageX;
1151
		this.originalPageY = event.pageY;
1152
 
1153
		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1154
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1155
 
1156
		//Set a containment if given in the options
1157
		if(o.containment)
1158
			this._setContainment();
1159
 
1160
		//Trigger event + callbacks
1161
		if(this._trigger("start", event) === false) {
1162
			this._clear();
1163
			return false;
1164
		}
1165
 
1166
		//Recache the helper size
1167
		this._cacheHelperProportions();
1168
 
1169
		//Prepare the droppable offsets
1170
		if ($.ui.ddmanager && !o.dropBehaviour)
1171
			$.ui.ddmanager.prepareOffsets(this, event);
1172
 
1173
 
1174
		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1175
 
1176
		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1177
		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1178
 
1179
		return true;
1180
	},
1181
 
1182
	_mouseDrag: function(event, noPropagation) {
1183
 
1184
		//Compute the helpers position
1185
		this.position = this._generatePosition(event);
1186
		this.positionAbs = this._convertPositionTo("absolute");
1187
 
1188
		//Call plugins and callbacks and use the resulting position if something is returned
1189
		if (!noPropagation) {
1190
			var ui = this._uiHash();
1191
			if(this._trigger('drag', event, ui) === false) {
1192
				this._mouseUp({});
1193
				return false;
1194
			}
1195
			this.position = ui.position;
1196
		}
1197
 
1198
		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1199
		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1200
		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1201
 
1202
		return false;
1203
	},
1204
 
1205
	_mouseStop: function(event) {
1206
 
1207
		//If we are using droppables, inform the manager about the drop
1208
		var dropped = false;
1209
		if ($.ui.ddmanager && !this.options.dropBehaviour)
1210
			dropped = $.ui.ddmanager.drop(this, event);
1211
 
1212
		//if a drop comes from outside (a sortable)
1213
		if(this.dropped) {
1214
			dropped = this.dropped;
1215
			this.dropped = false;
1216
		}
1217
 
1218
		//if the original element is no longer in the DOM don't bother to continue (see #8269)
1219
		var element = this.element[0], elementInDom = false;
1220
		while ( element && (element = element.parentNode) ) {
1221
			if (element == document ) {
1222
				elementInDom = true;
1223
			}
1224
		}
1225
		if ( !elementInDom && this.options.helper === "original" )
1226
			return false;
1227
 
1228
		if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1229
			var that = this;
1230
			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1231
				if(that._trigger("stop", event) !== false) {
1232
					that._clear();
1233
				}
1234
			});
1235
		} else {
1236
			if(this._trigger("stop", event) !== false) {
1237
				this._clear();
1238
			}
1239
		}
1240
 
1241
		return false;
1242
	},
1243
 
1244
	_mouseUp: function(event) {
1245
		//Remove frame helpers
1246
		$("div.ui-draggable-iframeFix").each(function() {
1247
			this.parentNode.removeChild(this);
1248
		});
1249
 
1250
		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1251
		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1252
 
1253
		return $.ui.mouse.prototype._mouseUp.call(this, event);
1254
	},
1255
 
1256
	cancel: function() {
1257
 
1258
		if(this.helper.is(".ui-draggable-dragging")) {
1259
			this._mouseUp({});
1260
		} else {
1261
			this._clear();
1262
		}
1263
 
1264
		return this;
1265
 
1266
	},
1267
 
1268
	_getHandle: function(event) {
1269
 
1270
		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1271
		$(this.options.handle, this.element)
1272
			.find("*")
1273
			.andSelf()
1274
			.each(function() {
1275
				if(this == event.target) handle = true;
1276
			});
1277
 
1278
		return handle;
1279
 
1280
	},
1281
 
1282
	_createHelper: function(event) {
1283
 
1284
		var o = this.options;
1285
		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1286
 
1287
		if(!helper.parents('body').length)
1288
			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1289
 
1290
		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1291
			helper.css("position", "absolute");
1292
 
1293
		return helper;
1294
 
1295
	},
1296
 
1297
	_adjustOffsetFromHelper: function(obj) {
1298
		if (typeof obj == 'string') {
1299
			obj = obj.split(' ');
1300
		}
1301
		if ($.isArray(obj)) {
1302
			obj = {left: +obj[0], top: +obj[1] || 0};
1303
		}
1304
		if ('left' in obj) {
1305
			this.offset.click.left = obj.left + this.margins.left;
1306
		}
1307
		if ('right' in obj) {
1308
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1309
		}
1310
		if ('top' in obj) {
1311
			this.offset.click.top = obj.top + this.margins.top;
1312
		}
1313
		if ('bottom' in obj) {
1314
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1315
		}
1316
	},
1317
 
1318
	_getParentOffset: function() {
1319
 
1320
		//Get the offsetParent and cache its position
1321
		this.offsetParent = this.helper.offsetParent();
1322
		var po = this.offsetParent.offset();
1323
 
1324
		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1325
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1326
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1327
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1328
		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1329
			po.left += this.scrollParent.scrollLeft();
1330
			po.top += this.scrollParent.scrollTop();
1331
		}
1332
 
1333
		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1334
		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
1335
			po = { top: 0, left: 0 };
1336
 
1337
		return {
1338
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1339
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1340
		};
1341
 
1342
	},
1343
 
1344
	_getRelativeOffset: function() {
1345
 
1346
		if(this.cssPosition == "relative") {
1347
			var p = this.element.position();
1348
			return {
1349
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1350
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1351
			};
1352
		} else {
1353
			return { top: 0, left: 0 };
1354
		}
1355
 
1356
	},
1357
 
1358
	_cacheMargins: function() {
1359
		this.margins = {
1360
			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1361
			top: (parseInt(this.element.css("marginTop"),10) || 0),
1362
			right: (parseInt(this.element.css("marginRight"),10) || 0),
1363
			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1364
		};
1365
	},
1366
 
1367
	_cacheHelperProportions: function() {
1368
		this.helperProportions = {
1369
			width: this.helper.outerWidth(),
1370
			height: this.helper.outerHeight()
1371
		};
1372
	},
1373
 
1374
	_setContainment: function() {
1375
 
1376
		var o = this.options;
1377
		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1378
		if(o.containment == 'document' || o.containment == 'window') this.containment = [
1379
			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1380
			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1381
			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1382
			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1383
		];
1384
 
1385
		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1386
			var c = $(o.containment);
1387
			var ce = c[0]; if(!ce) return;
1388
			var co = c.offset();
1389
			var over = ($(ce).css("overflow") != 'hidden');
1390
 
1391
			this.containment = [
1392
				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1393
				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1394
				(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1395
				(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1396
			];
1397
			this.relative_container = c;
1398
 
1399
		} else if(o.containment.constructor == Array) {
1400
			this.containment = o.containment;
1401
		}
1402
 
1403
	},
1404
 
1405
	_convertPositionTo: function(d, pos) {
1406
 
1407
		if(!pos) pos = this.position;
1408
		var mod = d == "absolute" ? 1 : -1;
1409
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1410
 
1411
		return {
1412
			top: (
1413
				pos.top																	// The absolute mouse position
1414
				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1415
				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
1416
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1417
			),
1418
			left: (
1419
				pos.left																// The absolute mouse position
1420
				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1421
				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
1422
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1423
			)
1424
		};
1425
 
1426
	},
1427
 
1428
	_generatePosition: function(event) {
1429
 
1430
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1431
		var pageX = event.pageX;
1432
		var pageY = event.pageY;
1433
 
1434
		/*
1435
		 * - Position constraining -
1436
		 * Constrain the position to a mix of grid, containment.
1437
		 */
1438
 
1439
		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1440
			var containment;
1441
			if(this.containment) {
1442
			if (this.relative_container){
1443
				var co = this.relative_container.offset();
1444
				containment = [ this.containment[0] + co.left,
1445
					this.containment[1] + co.top,
1446
					this.containment[2] + co.left,
1447
					this.containment[3] + co.top ];
1448
			}
1449
			else {
1450
				containment = this.containment;
1451
			}
1452
 
1453
				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1454
				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1455
				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1456
				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1457
			}
1458
 
1459
			if(o.grid) {
1460
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1461
				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1462
				pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1463
 
1464
				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1465
				pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1466
			}
1467
 
1468
		}
1469
 
1470
		return {
1471
			top: (
1472
				pageY																// The absolute mouse position
1473
				- this.offset.click.top													// Click offset (relative to the element)
1474
				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
1475
				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
1476
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1477
			),
1478
			left: (
1479
				pageX																// The absolute mouse position
1480
				- this.offset.click.left												// Click offset (relative to the element)
1481
				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
1482
				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
1483
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1484
			)
1485
		};
1486
 
1487
	},
1488
 
1489
	_clear: function() {
1490
		this.helper.removeClass("ui-draggable-dragging");
1491
		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1492
		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
1493
		this.helper = null;
1494
		this.cancelHelperRemoval = false;
1495
	},
1496
 
1497
	// From now on bulk stuff - mainly helpers
1498
 
1499
	_trigger: function(type, event, ui) {
1500
		ui = ui || this._uiHash();
1501
		$.ui.plugin.call(this, type, [event, ui]);
1502
		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1503
		return $.Widget.prototype._trigger.call(this, type, event, ui);
1504
	},
1505
 
1506
	plugins: {},
1507
 
1508
	_uiHash: function(event) {
1509
		return {
1510
			helper: this.helper,
1511
			position: this.position,
1512
			originalPosition: this.originalPosition,
1513
			offset: this.positionAbs
1514
		};
1515
	}
1516
 
1517
});
1518
 
1519
$.ui.plugin.add("draggable", "connectToSortable", {
1520
	start: function(event, ui) {
1521
 
1522
		var inst = $(this).data("draggable"), o = inst.options,
1523
			uiSortable = $.extend({}, ui, { item: inst.element });
1524
		inst.sortables = [];
1525
		$(o.connectToSortable).each(function() {
1526
			var sortable = $.data(this, 'sortable');
1527
			if (sortable && !sortable.options.disabled) {
1528
				inst.sortables.push({
1529
					instance: sortable,
1530
					shouldRevert: sortable.options.revert
1531
				});
1532
				sortable.refreshPositions();	// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
1533
				sortable._trigger("activate", event, uiSortable);
1534
			}
1535
		});
1536
 
1537
	},
1538
	stop: function(event, ui) {
1539
 
1540
		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1541
		var inst = $(this).data("draggable"),
1542
			uiSortable = $.extend({}, ui, { item: inst.element });
1543
 
1544
		$.each(inst.sortables, function() {
1545
			if(this.instance.isOver) {
1546
 
1547
				this.instance.isOver = 0;
1548
 
1549
				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1550
				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1551
 
1552
				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1553
				if(this.shouldRevert) this.instance.options.revert = true;
1554
 
1555
				//Trigger the stop of the sortable
1556
				this.instance._mouseStop(event);
1557
 
1558
				this.instance.options.helper = this.instance.options._helper;
1559
 
1560
				//If the helper has been the original item, restore properties in the sortable
1561
				if(inst.options.helper == 'original')
1562
					this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1563
 
1564
			} else {
1565
				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1566
				this.instance._trigger("deactivate", event, uiSortable);
1567
			}
1568
 
1569
		});
1570
 
1571
	},
1572
	drag: function(event, ui) {
1573
 
1574
		var inst = $(this).data("draggable"), that = this;
1575
 
1576
		var checkPos = function(o) {
1577
			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1578
			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1579
			var itemHeight = o.height, itemWidth = o.width;
1580
			var itemTop = o.top, itemLeft = o.left;
1581
 
1582
			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1583
		};
1584
 
1585
		$.each(inst.sortables, function(i) {
1586
 
1587
			var innermostIntersecting = false;
1588
			var thisSortable = this;
1589
			//Copy over some variables to allow calling the sortable's native _intersectsWith
1590
			this.instance.positionAbs = inst.positionAbs;
1591
			this.instance.helperProportions = inst.helperProportions;
1592
			this.instance.offset.click = inst.offset.click;
1593
 
1594
			if(this.instance._intersectsWith(this.instance.containerCache)) {
1595
				innermostIntersecting = true;
1596
				$.each(inst.sortables, function () {
1597
					this.instance.positionAbs = inst.positionAbs;
1598
					this.instance.helperProportions = inst.helperProportions;
1599
					this.instance.offset.click = inst.offset.click;
1600
					if  (this != thisSortable
1601
						&& this.instance._intersectsWith(this.instance.containerCache)
1602
						&& $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
1603
						innermostIntersecting = false;
1604
						return innermostIntersecting;
1605
				});
1606
			}
1607
 
1608
 
1609
			if(innermostIntersecting) {
1610
				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1611
				if(!this.instance.isOver) {
1612
 
1613
					this.instance.isOver = 1;
1614
					//Now we fake the start of dragging for the sortable instance,
1615
					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1616
					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1617
					this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1618
					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1619
					this.instance.options.helper = function() { return ui.helper[0]; };
1620
 
1621
					event.target = this.instance.currentItem[0];
1622
					this.instance._mouseCapture(event, true);
1623
					this.instance._mouseStart(event, true, true);
1624
 
1625
					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1626
					this.instance.offset.click.top = inst.offset.click.top;
1627
					this.instance.offset.click.left = inst.offset.click.left;
1628
					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1629
					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1630
 
1631
					inst._trigger("toSortable", event);
1632
					inst.dropped = this.instance.element; //draggable revert needs that
1633
					//hack so receive/update callbacks work (mostly)
1634
					inst.currentItem = inst.element;
1635
					this.instance.fromOutside = inst;
1636
 
1637
				}
1638
 
1639
				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1640
				if(this.instance.currentItem) this.instance._mouseDrag(event);
1641
 
1642
			} else {
1643
 
1644
				//If it doesn't intersect with the sortable, and it intersected before,
1645
				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1646
				if(this.instance.isOver) {
1647
 
1648
					this.instance.isOver = 0;
1649
					this.instance.cancelHelperRemoval = true;
1650
 
1651
					//Prevent reverting on this forced stop
1652
					this.instance.options.revert = false;
1653
 
1654
					// The out event needs to be triggered independently
1655
					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1656
 
1657
					this.instance._mouseStop(event, true);
1658
					this.instance.options.helper = this.instance.options._helper;
1659
 
1660
					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1661
					this.instance.currentItem.remove();
1662
					if(this.instance.placeholder) this.instance.placeholder.remove();
1663
 
1664
					inst._trigger("fromSortable", event);
1665
					inst.dropped = false; //draggable revert needs that
1666
				}
1667
 
1668
			};
1669
 
1670
		});
1671
 
1672
	}
1673
});
1674
 
1675
$.ui.plugin.add("draggable", "cursor", {
1676
	start: function(event, ui) {
1677
		var t = $('body'), o = $(this).data('draggable').options;
1678
		if (t.css("cursor")) o._cursor = t.css("cursor");
1679
		t.css("cursor", o.cursor);
1680
	},
1681
	stop: function(event, ui) {
1682
		var o = $(this).data('draggable').options;
1683
		if (o._cursor) $('body').css("cursor", o._cursor);
1684
	}
1685
});
1686
 
1687
$.ui.plugin.add("draggable", "opacity", {
1688
	start: function(event, ui) {
1689
		var t = $(ui.helper), o = $(this).data('draggable').options;
1690
		if(t.css("opacity")) o._opacity = t.css("opacity");
1691
		t.css('opacity', o.opacity);
1692
	},
1693
	stop: function(event, ui) {
1694
		var o = $(this).data('draggable').options;
1695
		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1696
	}
1697
});
1698
 
1699
$.ui.plugin.add("draggable", "scroll", {
1700
	start: function(event, ui) {
1701
		var i = $(this).data("draggable");
1702
		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1703
	},
1704
	drag: function(event, ui) {
1705
 
1706
		var i = $(this).data("draggable"), o = i.options, scrolled = false;
1707
 
1708
		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1709
 
1710
			if(!o.axis || o.axis != 'x') {
1711
				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1712
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1713
				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1714
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1715
			}
1716
 
1717
			if(!o.axis || o.axis != 'y') {
1718
				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1719
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1720
				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1721
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1722
			}
1723
 
1724
		} else {
1725
 
1726
			if(!o.axis || o.axis != 'x') {
1727
				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1728
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1729
				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1730
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1731
			}
1732
 
1733
			if(!o.axis || o.axis != 'y') {
1734
				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1735
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1736
				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1737
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1738
			}
1739
 
1740
		}
1741
 
1742
		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1743
			$.ui.ddmanager.prepareOffsets(i, event);
1744
 
1745
	}
1746
});
1747
 
1748
$.ui.plugin.add("draggable", "snap", {
1749
	start: function(event, ui) {
1750
 
1751
		var i = $(this).data("draggable"), o = i.options;
1752
		i.snapElements = [];
1753
 
1754
		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1755
			var $t = $(this); var $o = $t.offset();
1756
			if(this != i.element[0]) i.snapElements.push({
1757
				item: this,
1758
				width: $t.outerWidth(), height: $t.outerHeight(),
1759
				top: $o.top, left: $o.left
1760
			});
1761
		});
1762
 
1763
	},
1764
	drag: function(event, ui) {
1765
 
1766
		var inst = $(this).data("draggable"), o = inst.options;
1767
		var d = o.snapTolerance;
1768
 
1769
		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1770
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1771
 
1772
		for (var i = inst.snapElements.length - 1; i >= 0; i--){
1773
 
1774
			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1775
				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1776
 
1777
			//Yes, I know, this is insane ;)
1778
			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1779
				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1780
				inst.snapElements[i].snapping = false;
1781
				continue;
1782
			}
1783
 
1784
			if(o.snapMode != 'inner') {
1785
				var ts = Math.abs(t - y2) <= d;
1786
				var bs = Math.abs(b - y1) <= d;
1787
				var ls = Math.abs(l - x2) <= d;
1788
				var rs = Math.abs(r - x1) <= d;
1789
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1790
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1791
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1792
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1793
			}
1794
 
1795
			var first = (ts || bs || ls || rs);
1796
 
1797
			if(o.snapMode != 'outer') {
1798
				var ts = Math.abs(t - y1) <= d;
1799
				var bs = Math.abs(b - y2) <= d;
1800
				var ls = Math.abs(l - x1) <= d;
1801
				var rs = Math.abs(r - x2) <= d;
1802
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1803
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1804
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1805
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1806
			}
1807
 
1808
			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1809
				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1810
			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1811
 
1812
		};
1813
 
1814
	}
1815
});
1816
 
1817
$.ui.plugin.add("draggable", "stack", {
1818
	start: function(event, ui) {
1819
 
1820
		var o = $(this).data("draggable").options;
1821
 
1822
		var group = $.makeArray($(o.stack)).sort(function(a,b) {
1823
			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1824
		});
1825
		if (!group.length) { return; }
1826
 
1827
		var min = parseInt(group[0].style.zIndex) || 0;
1828
		$(group).each(function(i) {
1829
			this.style.zIndex = min + i;
1830
		});
1831
 
1832
		this[0].style.zIndex = min + group.length;
1833
 
1834
	}
1835
});
1836
 
1837
$.ui.plugin.add("draggable", "zIndex", {
1838
	start: function(event, ui) {
1839
		var t = $(ui.helper), o = $(this).data("draggable").options;
1840
		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1841
		t.css('zIndex', o.zIndex);
1842
	},
1843
	stop: function(event, ui) {
1844
		var o = $(this).data("draggable").options;
1845
		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1846
	}
1847
});
1848
 
1849
})(jQuery);
1850
 
1851
(function( $, undefined ) {
1852
 
1853
$.widget("ui.droppable", {
1854
	version: "1.9.2",
1855
	widgetEventPrefix: "drop",
1856
	options: {
1857
		accept: '*',
1858
		activeClass: false,
1859
		addClasses: true,
1860
		greedy: false,
1861
		hoverClass: false,
1862
		scope: 'default',
1863
		tolerance: 'intersect'
1864
	},
1865
	_create: function() {
1866
 
1867
		var o = this.options, accept = o.accept;
1868
		this.isover = 0; this.isout = 1;
1869
 
1870
		this.accept = $.isFunction(accept) ? accept : function(d) {
1871
			return d.is(accept);
1872
		};
1873
 
1874
		//Store the droppable's proportions
1875
		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1876
 
1877
		// Add the reference and positions to the manager
1878
		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1879
		$.ui.ddmanager.droppables[o.scope].push(this);
1880
 
1881
		(o.addClasses && this.element.addClass("ui-droppable"));
1882
 
1883
	},
1884
 
1885
	_destroy: function() {
1886
		var drop = $.ui.ddmanager.droppables[this.options.scope];
1887
		for ( var i = 0; i < drop.length; i++ )
1888
			if ( drop[i] == this )
1889
				drop.splice(i, 1);
1890
 
1891
		this.element.removeClass("ui-droppable ui-droppable-disabled");
1892
	},
1893
 
1894
	_setOption: function(key, value) {
1895
 
1896
		if(key == 'accept') {
1897
			this.accept = $.isFunction(value) ? value : function(d) {
1898
				return d.is(value);
1899
			};
1900
		}
1901
		$.Widget.prototype._setOption.apply(this, arguments);
1902
	},
1903
 
1904
	_activate: function(event) {
1905
		var draggable = $.ui.ddmanager.current;
1906
		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1907
		(draggable && this._trigger('activate', event, this.ui(draggable)));
1908
	},
1909
 
1910
	_deactivate: function(event) {
1911
		var draggable = $.ui.ddmanager.current;
1912
		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1913
		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
1914
	},
1915
 
1916
	_over: function(event) {
1917
 
1918
		var draggable = $.ui.ddmanager.current;
1919
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1920
 
1921
		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1922
			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1923
			this._trigger('over', event, this.ui(draggable));
1924
		}
1925
 
1926
	},
1927
 
1928
	_out: function(event) {
1929
 
1930
		var draggable = $.ui.ddmanager.current;
1931
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1932
 
1933
		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1934
			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1935
			this._trigger('out', event, this.ui(draggable));
1936
		}
1937
 
1938
	},
1939
 
1940
	_drop: function(event,custom) {
1941
 
1942
		var draggable = custom || $.ui.ddmanager.current;
1943
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1944
 
1945
		var childrenIntersection = false;
1946
		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1947
			var inst = $.data(this, 'droppable');
1948
			if(
1949
				inst.options.greedy
1950
				&& !inst.options.disabled
1951
				&& inst.options.scope == draggable.options.scope
1952
				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1953
				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1954
			) { childrenIntersection = true; return false; }
1955
		});
1956
		if(childrenIntersection) return false;
1957
 
1958
		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1959
			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1960
			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1961
			this._trigger('drop', event, this.ui(draggable));
1962
			return this.element;
1963
		}
1964
 
1965
		return false;
1966
 
1967
	},
1968
 
1969
	ui: function(c) {
1970
		return {
1971
			draggable: (c.currentItem || c.element),
1972
			helper: c.helper,
1973
			position: c.position,
1974
			offset: c.positionAbs
1975
		};
1976
	}
1977
 
1978
});
1979
 
1980
$.ui.intersect = function(draggable, droppable, toleranceMode) {
1981
 
1982
	if (!droppable.offset) return false;
1983
 
1984
	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1985
		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1986
	var l = droppable.offset.left, r = l + droppable.proportions.width,
1987
		t = droppable.offset.top, b = t + droppable.proportions.height;
1988
 
1989
	switch (toleranceMode) {
1990
		case 'fit':
1991
			return (l <= x1 && x2 <= r
1992
				&& t <= y1 && y2 <= b);
1993
			break;
1994
		case 'intersect':
1995
			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1996
				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
1997
				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1998
				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1999
			break;
2000
		case 'pointer':
2001
			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2002
				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2003
				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2004
			return isOver;
2005
			break;
2006
		case 'touch':
2007
			return (
2008
					(y1 >= t && y1 <= b) ||	// Top edge touching
2009
					(y2 >= t && y2 <= b) ||	// Bottom edge touching
2010
					(y1 < t && y2 > b)		// Surrounded vertically
2011
				) && (
2012
					(x1 >= l && x1 <= r) ||	// Left edge touching
2013
					(x2 >= l && x2 <= r) ||	// Right edge touching
2014
					(x1 < l && x2 > r)		// Surrounded horizontally
2015
				);
2016
			break;
2017
		default:
2018
			return false;
2019
			break;
2020
		}
2021
 
2022
};
2023
 
2024
/*
2025
	This manager tracks offsets of draggables and droppables
2026
*/
2027
$.ui.ddmanager = {
2028
	current: null,
2029
	droppables: { 'default': [] },
2030
	prepareOffsets: function(t, event) {
2031
 
2032
		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2033
		var type = event ? event.type : null; // workaround for #2317
2034
		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2035
 
2036
		droppablesLoop: for (var i = 0; i < m.length; i++) {
2037
 
2038
			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
2039
			for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
2040
			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue
2041
 
2042
			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2043
 
2044
			m[i].offset = m[i].element.offset();
2045
			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2046
 
2047
		}
2048
 
2049
	},
2050
	drop: function(draggable, event) {
2051
 
2052
		var dropped = false;
2053
		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2054
 
2055
			if(!this.options) return;
2056
			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2057
				dropped = this._drop.call(this, event) || dropped;
2058
 
2059
			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2060
				this.isout = 1; this.isover = 0;
2061
				this._deactivate.call(this, event);
2062
			}
2063
 
2064
		});
2065
		return dropped;
2066
 
2067
	},
2068
	dragStart: function( draggable, event ) {
2069
		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2070
		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2071
			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2072
		});
2073
	},
2074
	drag: function(draggable, event) {
2075
 
2076
		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2077
		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2078
 
2079
		//Run through all droppables and check their positions based on specific tolerance options
2080
		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2081
 
2082
			if(this.options.disabled || this.greedyChild || !this.visible) return;
2083
			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2084
 
2085
			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2086
			if(!c) return;
2087
 
2088
			var parentInstance;
2089
			if (this.options.greedy) {
2090
				// find droppable parents with same scope
2091
				var scope = this.options.scope;
2092
				var parent = this.element.parents(':data(droppable)').filter(function () {
2093
					return $.data(this, 'droppable').options.scope === scope;
2094
				});
2095
 
2096
				if (parent.length) {
2097
					parentInstance = $.data(parent[0], 'droppable');
2098
					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2099
				}
2100
			}
2101
 
2102
			// we just moved into a greedy child
2103
			if (parentInstance && c == 'isover') {
2104
				parentInstance['isover'] = 0;
2105
				parentInstance['isout'] = 1;
2106
				parentInstance._out.call(parentInstance, event);
2107
			}
2108
 
2109
			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2110
			this[c == "isover" ? "_over" : "_out"].call(this, event);
2111
 
2112
			// we just moved out of a greedy child
2113
			if (parentInstance && c == 'isout') {
2114
				parentInstance['isout'] = 0;
2115
				parentInstance['isover'] = 1;
2116
				parentInstance._over.call(parentInstance, event);
2117
			}
2118
		});
2119
 
2120
	},
2121
	dragStop: function( draggable, event ) {
2122
		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2123
		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2124
		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2125
	}
2126
};
2127
 
2128
})(jQuery);
2129
 
2130
(function( $, undefined ) {
2131
 
2132
$.widget("ui.resizable", $.ui.mouse, {
2133
	version: "1.9.2",
2134
	widgetEventPrefix: "resize",
2135
	options: {
2136
		alsoResize: false,
2137
		animate: false,
2138
		animateDuration: "slow",
2139
		animateEasing: "swing",
2140
		aspectRatio: false,
2141
		autoHide: false,
2142
		containment: false,
2143
		ghost: false,
2144
		grid: false,
2145
		handles: "e,s,se",
2146
		helper: false,
2147
		maxHeight: null,
2148
		maxWidth: null,
2149
		minHeight: 10,
2150
		minWidth: 10,
2151
		zIndex: 1000
2152
	},
2153
	_create: function() {
2154
 
2155
		var that = this, o = this.options;
2156
		this.element.addClass("ui-resizable");
2157
 
2158
		$.extend(this, {
2159
			_aspectRatio: !!(o.aspectRatio),
2160
			aspectRatio: o.aspectRatio,
2161
			originalElement: this.element,
2162
			_proportionallyResizeElements: [],
2163
			_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2164
		});
2165
 
2166
		//Wrap the element if it cannot hold child nodes
2167
		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2168
 
2169
			//Create a wrapper element and set the wrapper to the new current internal element
2170
			this.element.wrap(
2171
				$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2172
					position: this.element.css('position'),
2173
					width: this.element.outerWidth(),
2174
					height: this.element.outerHeight(),
2175
					top: this.element.css('top'),
2176
					left: this.element.css('left')
2177
				})
2178
			);
2179
 
2180
			//Overwrite the original this.element
2181
			this.element = this.element.parent().data(
2182
				"resizable", this.element.data('resizable')
2183
			);
2184
 
2185
			this.elementIsWrapper = true;
2186
 
2187
			//Move margins to the wrapper
2188
			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2189
			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2190
 
2191
			//Prevent Safari textarea resize
2192
			this.originalResizeStyle = this.originalElement.css('resize');
2193
			this.originalElement.css('resize', 'none');
2194
 
2195
			//Push the actual element to our proportionallyResize internal array
2196
			this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2197
 
2198
			// avoid IE jump (hard set the margin)
2199
			this.originalElement.css({ margin: this.originalElement.css('margin') });
2200
 
2201
			// fix handlers offset
2202
			this._proportionallyResize();
2203
 
2204
		}
2205
 
2206
		this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
2207
		if(this.handles.constructor == String) {
2208
 
2209
			if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2210
			var n = this.handles.split(","); this.handles = {};
2211
 
2212
			for(var i = 0; i < n.length; i++) {
2213
 
2214
				var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2215
				var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2216
 
2217
				// Apply zIndex to all handles - see #7960
2218
				axis.css({ zIndex: o.zIndex });
2219
 
2220
				//TODO : What's going on here?
2221
				if ('se' == handle) {
2222
					axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2223
				};
2224
 
2225
				//Insert into internal handles object and append to element
2226
				this.handles[handle] = '.ui-resizable-'+handle;
2227
				this.element.append(axis);
2228
			}
2229
 
2230
		}
2231
 
2232
		this._renderAxis = function(target) {
2233
 
2234
			target = target || this.element;
2235
 
2236
			for(var i in this.handles) {
2237
 
2238
				if(this.handles[i].constructor == String)
2239
					this.handles[i] = $(this.handles[i], this.element).show();
2240
 
2241
				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2242
				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2243
 
2244
					var axis = $(this.handles[i], this.element), padWrapper = 0;
2245
 
2246
					//Checking the correct pad and border
2247
					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2248
 
2249
					//The padding type i have to apply...
2250
					var padPos = [ 'padding',
2251
						/ne|nw|n/.test(i) ? 'Top' :
2252
						/se|sw|s/.test(i) ? 'Bottom' :
2253
						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
2254
 
2255
					target.css(padPos, padWrapper);
2256
 
2257
					this._proportionallyResize();
2258
 
2259
				}
2260
 
2261
				//TODO: What's that good for? There's not anything to be executed left
2262
				if(!$(this.handles[i]).length)
2263
					continue;
2264
 
2265
			}
2266
		};
2267
 
2268
		//TODO: make renderAxis a prototype function
2269
		this._renderAxis(this.element);
2270
 
2271
		this._handles = $('.ui-resizable-handle', this.element)
2272
			.disableSelection();
2273
 
2274
		//Matching axis name
2275
		this._handles.mouseover(function() {
2276
			if (!that.resizing) {
2277
				if (this.className)
2278
					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2279
				//Axis, default = se
2280
				that.axis = axis && axis[1] ? axis[1] : 'se';
2281
			}
2282
		});
2283
 
2284
		//If we want to auto hide the elements
2285
		if (o.autoHide) {
2286
			this._handles.hide();
2287
			$(this.element)
2288
				.addClass("ui-resizable-autohide")
2289
				.mouseenter(function() {
2290
					if (o.disabled) return;
2291
					$(this).removeClass("ui-resizable-autohide");
2292
					that._handles.show();
2293
				})
2294
				.mouseleave(function(){
2295
					if (o.disabled) return;
2296
					if (!that.resizing) {
2297
						$(this).addClass("ui-resizable-autohide");
2298
						that._handles.hide();
2299
					}
2300
				});
2301
		}
2302
 
2303
		//Initialize the mouse interaction
2304
		this._mouseInit();
2305
 
2306
	},
2307
 
2308
	_destroy: function() {
2309
 
2310
		this._mouseDestroy();
2311
 
2312
		var _destroy = function(exp) {
2313
			$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2314
				.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2315
		};
2316
 
2317
		//TODO: Unwrap at same DOM position
2318
		if (this.elementIsWrapper) {
2319
			_destroy(this.element);
2320
			var wrapper = this.element;
2321
			this.originalElement.css({
2322
				position: wrapper.css('position'),
2323
				width: wrapper.outerWidth(),
2324
				height: wrapper.outerHeight(),
2325
				top: wrapper.css('top'),
2326
				left: wrapper.css('left')
2327
			}).insertAfter( wrapper );
2328
			wrapper.remove();
2329
		}
2330
 
2331
		this.originalElement.css('resize', this.originalResizeStyle);
2332
		_destroy(this.originalElement);
2333
 
2334
		return this;
2335
	},
2336
 
2337
	_mouseCapture: function(event) {
2338
		var handle = false;
2339
		for (var i in this.handles) {
2340
			if ($(this.handles[i])[0] == event.target) {
2341
				handle = true;
2342
			}
2343
		}
2344
 
2345
		return !this.options.disabled && handle;
2346
	},
2347
 
2348
	_mouseStart: function(event) {
2349
 
2350
		var o = this.options, iniPos = this.element.position(), el = this.element;
2351
 
2352
		this.resizing = true;
2353
		this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2354
 
2355
		// bugfix for http://dev.jquery.com/ticket/1749
2356
		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2357
			el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2358
		}
2359
 
2360
		this._renderProxy();
2361
 
2362
		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2363
 
2364
		if (o.containment) {
2365
			curleft += $(o.containment).scrollLeft() || 0;
2366
			curtop += $(o.containment).scrollTop() || 0;
2367
		}
2368
 
2369
		//Store needed variables
2370
		this.offset = this.helper.offset();
2371
		this.position = { left: curleft, top: curtop };
2372
		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2373
		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2374
		this.originalPosition = { left: curleft, top: curtop };
2375
		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2376
		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2377
 
2378
		//Aspect Ratio
2379
		this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2380
 
2381
		var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2382
		$('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2383
 
2384
		el.addClass("ui-resizable-resizing");
2385
		this._propagate("start", event);
2386
		return true;
2387
	},
2388
 
2389
	_mouseDrag: function(event) {
2390
 
2391
		//Increase performance, avoid regex
2392
		var el = this.helper, o = this.options, props = {},
2393
			that = this, smp = this.originalMousePosition, a = this.axis;
2394
 
2395
		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2396
		var trigger = this._change[a];
2397
		if (!trigger) return false;
2398
 
2399
		// Calculate the attrs that will be change
2400
		var data = trigger.apply(this, [event, dx, dy]);
2401
 
2402
		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2403
		this._updateVirtualBoundaries(event.shiftKey);
2404
		if (this._aspectRatio || event.shiftKey)
2405
			data = this._updateRatio(data, event);
2406
 
2407
		data = this._respectSize(data, event);
2408
 
2409
		// plugins callbacks need to be called first
2410
		this._propagate("resize", event);
2411
 
2412
		el.css({
2413
			top: this.position.top + "px", left: this.position.left + "px",
2414
			width: this.size.width + "px", height: this.size.height + "px"
2415
		});
2416
 
2417
		if (!this._helper && this._proportionallyResizeElements.length)
2418
			this._proportionallyResize();
2419
 
2420
		this._updateCache(data);
2421
 
2422
		// calling the user callback at the end
2423
		this._trigger('resize', event, this.ui());
2424
 
2425
		return false;
2426
	},
2427
 
2428
	_mouseStop: function(event) {
2429
 
2430
		this.resizing = false;
2431
		var o = this.options, that = this;
2432
 
2433
		if(this._helper) {
2434
			var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2435
				soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2436
				soffsetw = ista ? 0 : that.sizeDiff.width;
2437
 
2438
			var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
2439
				left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
2440
				top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
2441
 
2442
			if (!o.animate)
2443
				this.element.css($.extend(s, { top: top, left: left }));
2444
 
2445
			that.helper.height(that.size.height);
2446
			that.helper.width(that.size.width);
2447
 
2448
			if (this._helper && !o.animate) this._proportionallyResize();
2449
		}
2450
 
2451
		$('body').css('cursor', 'auto');
2452
 
2453
		this.element.removeClass("ui-resizable-resizing");
2454
 
2455
		this._propagate("stop", event);
2456
 
2457
		if (this._helper) this.helper.remove();
2458
		return false;
2459
 
2460
	},
2461
 
2462
	_updateVirtualBoundaries: function(forceAspectRatio) {
2463
		var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2464
 
2465
		b = {
2466
			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2467
			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2468
			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2469
			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2470
		};
2471
 
2472
		if(this._aspectRatio || forceAspectRatio) {
2473
			// We want to create an enclosing box whose aspect ration is the requested one
2474
			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2475
			pMinWidth = b.minHeight * this.aspectRatio;
2476
			pMinHeight = b.minWidth / this.aspectRatio;
2477
			pMaxWidth = b.maxHeight * this.aspectRatio;
2478
			pMaxHeight = b.maxWidth / this.aspectRatio;
2479
 
2480
			if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2481
			if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2482
			if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2483
			if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2484
		}
2485
		this._vBoundaries = b;
2486
	},
2487
 
2488
	_updateCache: function(data) {
2489
		var o = this.options;
2490
		this.offset = this.helper.offset();
2491
		if (isNumber(data.left)) this.position.left = data.left;
2492
		if (isNumber(data.top)) this.position.top = data.top;
2493
		if (isNumber(data.height)) this.size.height = data.height;
2494
		if (isNumber(data.width)) this.size.width = data.width;
2495
	},
2496
 
2497
	_updateRatio: function(data, event) {
2498
 
2499
		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2500
 
2501
		if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2502
		else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2503
 
2504
		if (a == 'sw') {
2505
			data.left = cpos.left + (csize.width - data.width);
2506
			data.top = null;
2507
		}
2508
		if (a == 'nw') {
2509
			data.top = cpos.top + (csize.height - data.height);
2510
			data.left = cpos.left + (csize.width - data.width);
2511
		}
2512
 
2513
		return data;
2514
	},
2515
 
2516
	_respectSize: function(data, event) {
2517
 
2518
		var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2519
				ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2520
					isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2521
 
2522
		if (isminw) data.width = o.minWidth;
2523
		if (isminh) data.height = o.minHeight;
2524
		if (ismaxw) data.width = o.maxWidth;
2525
		if (ismaxh) data.height = o.maxHeight;
2526
 
2527
		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2528
		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2529
 
2530
		if (isminw && cw) data.left = dw - o.minWidth;
2531
		if (ismaxw && cw) data.left = dw - o.maxWidth;
2532
		if (isminh && ch)	data.top = dh - o.minHeight;
2533
		if (ismaxh && ch)	data.top = dh - o.maxHeight;
2534
 
2535
		// fixing jump error on top/left - bug #2330
2536
		var isNotwh = !data.width && !data.height;
2537
		if (isNotwh && !data.left && data.top) data.top = null;
2538
		else if (isNotwh && !data.top && data.left) data.left = null;
2539
 
2540
		return data;
2541
	},
2542
 
2543
	_proportionallyResize: function() {
2544
 
2545
		var o = this.options;
2546
		if (!this._proportionallyResizeElements.length) return;
2547
		var element = this.helper || this.element;
2548
 
2549
		for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2550
 
2551
			var prel = this._proportionallyResizeElements[i];
2552
 
2553
			if (!this.borderDif) {
2554
				var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2555
					p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2556
 
2557
				this.borderDif = $.map(b, function(v, i) {
2558
					var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2559
					return border + padding;
2560
				});
2561
			}
2562
 
2563
			prel.css({
2564
				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2565
				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2566
			});
2567
 
2568
		};
2569
 
2570
	},
2571
 
2572
	_renderProxy: function() {
2573
 
2574
		var el = this.element, o = this.options;
2575
		this.elementOffset = el.offset();
2576
 
2577
		if(this._helper) {
2578
 
2579
			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2580
 
2581
			// fix ie6 offset TODO: This seems broken
2582
			var ie6offset = ($.ui.ie6 ? 1 : 0),
2583
			pxyoffset = ( $.ui.ie6 ? 2 : -1 );
2584
 
2585
			this.helper.addClass(this._helper).css({
2586
				width: this.element.outerWidth() + pxyoffset,
2587
				height: this.element.outerHeight() + pxyoffset,
2588
				position: 'absolute',
2589
				left: this.elementOffset.left - ie6offset +'px',
2590
				top: this.elementOffset.top - ie6offset +'px',
2591
				zIndex: ++o.zIndex //TODO: Don't modify option
2592
			});
2593
 
2594
			this.helper
2595
				.appendTo("body")
2596
				.disableSelection();
2597
 
2598
		} else {
2599
			this.helper = this.element;
2600
		}
2601
 
2602
	},
2603
 
2604
	_change: {
2605
		e: function(event, dx, dy) {
2606
			return { width: this.originalSize.width + dx };
2607
		},
2608
		w: function(event, dx, dy) {
2609
			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2610
			return { left: sp.left + dx, width: cs.width - dx };
2611
		},
2612
		n: function(event, dx, dy) {
2613
			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2614
			return { top: sp.top + dy, height: cs.height - dy };
2615
		},
2616
		s: function(event, dx, dy) {
2617
			return { height: this.originalSize.height + dy };
2618
		},
2619
		se: function(event, dx, dy) {
2620
			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2621
		},
2622
		sw: function(event, dx, dy) {
2623
			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2624
		},
2625
		ne: function(event, dx, dy) {
2626
			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2627
		},
2628
		nw: function(event, dx, dy) {
2629
			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2630
		}
2631
	},
2632
 
2633
	_propagate: function(n, event) {
2634
		$.ui.plugin.call(this, n, [event, this.ui()]);
2635
		(n != "resize" && this._trigger(n, event, this.ui()));
2636
	},
2637
 
2638
	plugins: {},
2639
 
2640
	ui: function() {
2641
		return {
2642
			originalElement: this.originalElement,
2643
			element: this.element,
2644
			helper: this.helper,
2645
			position: this.position,
2646
			size: this.size,
2647
			originalSize: this.originalSize,
2648
			originalPosition: this.originalPosition
2649
		};
2650
	}
2651
 
2652
});
2653
 
2654
/*
2655
 * Resizable Extensions
2656
 */
2657
 
2658
$.ui.plugin.add("resizable", "alsoResize", {
2659
 
2660
	start: function (event, ui) {
2661
		var that = $(this).data("resizable"), o = that.options;
2662
 
2663
		var _store = function (exp) {
2664
			$(exp).each(function() {
2665
				var el = $(this);
2666
				el.data("resizable-alsoresize", {
2667
					width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2668
					left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
2669
				});
2670
			});
2671
		};
2672
 
2673
		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2674
			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2675
			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2676
		}else{
2677
			_store(o.alsoResize);
2678
		}
2679
	},
2680
 
2681
	resize: function (event, ui) {
2682
		var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
2683
 
2684
		var delta = {
2685
			height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
2686
			top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
2687
		},
2688
 
2689
		_alsoResize = function (exp, c) {
2690
			$(exp).each(function() {
2691
				var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
2692
					css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2693
 
2694
				$.each(css, function (i, prop) {
2695
					var sum = (start[prop]||0) + (delta[prop]||0);
2696
					if (sum && sum >= 0)
2697
						style[prop] = sum || null;
2698
				});
2699
 
2700
				el.css(style);
2701
			});
2702
		};
2703
 
2704
		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2705
			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2706
		}else{
2707
			_alsoResize(o.alsoResize);
2708
		}
2709
	},
2710
 
2711
	stop: function (event, ui) {
2712
		$(this).removeData("resizable-alsoresize");
2713
	}
2714
});
2715
 
2716
$.ui.plugin.add("resizable", "animate", {
2717
 
2718
	stop: function(event, ui) {
2719
		var that = $(this).data("resizable"), o = that.options;
2720
 
2721
		var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2722
					soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2723
						soffsetw = ista ? 0 : that.sizeDiff.width;
2724
 
2725
		var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2726
					left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
2727
						top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
2728
 
2729
		that.element.animate(
2730
			$.extend(style, top && left ? { top: top, left: left } : {}), {
2731
				duration: o.animateDuration,
2732
				easing: o.animateEasing,
2733
				step: function() {
2734
 
2735
					var data = {
2736
						width: parseInt(that.element.css('width'), 10),
2737
						height: parseInt(that.element.css('height'), 10),
2738
						top: parseInt(that.element.css('top'), 10),
2739
						left: parseInt(that.element.css('left'), 10)
2740
					};
2741
 
2742
					if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2743
 
2744
					// propagating resize, and updating values for each animation step
2745
					that._updateCache(data);
2746
					that._propagate("resize", event);
2747
 
2748
				}
2749
			}
2750
		);
2751
	}
2752
 
2753
});
2754
 
2755
$.ui.plugin.add("resizable", "containment", {
2756
 
2757
	start: function(event, ui) {
2758
		var that = $(this).data("resizable"), o = that.options, el = that.element;
2759
		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2760
		if (!ce) return;
2761
 
2762
		that.containerElement = $(ce);
2763
 
2764
		if (/document/.test(oc) || oc == document) {
2765
			that.containerOffset = { left: 0, top: 0 };
2766
			that.containerPosition = { left: 0, top: 0 };
2767
 
2768
			that.parentData = {
2769
				element: $(document), left: 0, top: 0,
2770
				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2771
			};
2772
		}
2773
 
2774
		// i'm a node, so compute top, left, right, bottom
2775
		else {
2776
			var element = $(ce), p = [];
2777
			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2778
 
2779
			that.containerOffset = element.offset();
2780
			that.containerPosition = element.position();
2781
			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2782
 
2783
			var co = that.containerOffset, ch = that.containerSize.height,	cw = that.containerSize.width,
2784
						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2785
 
2786
			that.parentData = {
2787
				element: ce, left: co.left, top: co.top, width: width, height: height
2788
			};
2789
		}
2790
	},
2791
 
2792
	resize: function(event, ui) {
2793
		var that = $(this).data("resizable"), o = that.options,
2794
				ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
2795
				pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
2796
 
2797
		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2798
 
2799
		if (cp.left < (that._helper ? co.left : 0)) {
2800
			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
2801
			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
2802
			that.position.left = o.helper ? co.left : 0;
2803
		}
2804
 
2805
		if (cp.top < (that._helper ? co.top : 0)) {
2806
			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
2807
			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
2808
			that.position.top = that._helper ? co.top : 0;
2809
		}
2810
 
2811
		that.offset.left = that.parentData.left+that.position.left;
2812
		that.offset.top = that.parentData.top+that.position.top;
2813
 
2814
		var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
2815
					hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
2816
 
2817
		var isParent = that.containerElement.get(0) == that.element.parent().get(0),
2818
			isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
2819
 
2820
		if(isParent && isOffsetRelative) woset -= that.parentData.left;
2821
 
2822
		if (woset + that.size.width >= that.parentData.width) {
2823
			that.size.width = that.parentData.width - woset;
2824
			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
2825
		}
2826
 
2827
		if (hoset + that.size.height >= that.parentData.height) {
2828
			that.size.height = that.parentData.height - hoset;
2829
			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
2830
		}
2831
	},
2832
 
2833
	stop: function(event, ui){
2834
		var that = $(this).data("resizable"), o = that.options, cp = that.position,
2835
				co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
2836
 
2837
		var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
2838
 
2839
		if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
2840
			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2841
 
2842
		if (that._helper && !o.animate && (/static/).test(ce.css('position')))
2843
			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2844
 
2845
	}
2846
});
2847
 
2848
$.ui.plugin.add("resizable", "ghost", {
2849
 
2850
	start: function(event, ui) {
2851
 
2852
		var that = $(this).data("resizable"), o = that.options, cs = that.size;
2853
 
2854
		that.ghost = that.originalElement.clone();
2855
		that.ghost
2856
			.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2857
			.addClass('ui-resizable-ghost')
2858
			.addClass(typeof o.ghost == 'string' ? o.ghost : '');
2859
 
2860
		that.ghost.appendTo(that.helper);
2861
 
2862
	},
2863
 
2864
	resize: function(event, ui){
2865
		var that = $(this).data("resizable"), o = that.options;
2866
		if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
2867
	},
2868
 
2869
	stop: function(event, ui){
2870
		var that = $(this).data("resizable"), o = that.options;
2871
		if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
2872
	}
2873
 
2874
});
2875
 
2876
$.ui.plugin.add("resizable", "grid", {
2877
 
2878
	resize: function(event, ui) {
2879
		var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
2880
		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2881
		var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
2882
 
2883
		if (/^(se|s|e)$/.test(a)) {
2884
			that.size.width = os.width + ox;
2885
			that.size.height = os.height + oy;
2886
		}
2887
		else if (/^(ne)$/.test(a)) {
2888
			that.size.width = os.width + ox;
2889
			that.size.height = os.height + oy;
2890
			that.position.top = op.top - oy;
2891
		}
2892
		else if (/^(sw)$/.test(a)) {
2893
			that.size.width = os.width + ox;
2894
			that.size.height = os.height + oy;
2895
			that.position.left = op.left - ox;
2896
		}
2897
		else {
2898
			that.size.width = os.width + ox;
2899
			that.size.height = os.height + oy;
2900
			that.position.top = op.top - oy;
2901
			that.position.left = op.left - ox;
2902
		}
2903
	}
2904
 
2905
});
2906
 
2907
var num = function(v) {
2908
	return parseInt(v, 10) || 0;
2909
};
2910
 
2911
var isNumber = function(value) {
2912
	return !isNaN(parseInt(value, 10));
2913
};
2914
 
2915
})(jQuery);
2916
 
2917
(function( $, undefined ) {
2918
 
2919
$.widget("ui.selectable", $.ui.mouse, {
2920
	version: "1.9.2",
2921
	options: {
2922
		appendTo: 'body',
2923
		autoRefresh: true,
2924
		distance: 0,
2925
		filter: '*',
2926
		tolerance: 'touch'
2927
	},
2928
	_create: function() {
2929
		var that = this;
2930
 
2931
		this.element.addClass("ui-selectable");
2932
 
2933
		this.dragged = false;
2934
 
2935
		// cache selectee children based on filter
2936
		var selectees;
2937
		this.refresh = function() {
2938
			selectees = $(that.options.filter, that.element[0]);
2939
			selectees.addClass("ui-selectee");
2940
			selectees.each(function() {
2941
				var $this = $(this);
2942
				var pos = $this.offset();
2943
				$.data(this, "selectable-item", {
2944
					element: this,
2945
					$element: $this,
2946
					left: pos.left,
2947
					top: pos.top,
2948
					right: pos.left + $this.outerWidth(),
2949
					bottom: pos.top + $this.outerHeight(),
2950
					startselected: false,
2951
					selected: $this.hasClass('ui-selected'),
2952
					selecting: $this.hasClass('ui-selecting'),
2953
					unselecting: $this.hasClass('ui-unselecting')
2954
				});
2955
			});
2956
		};
2957
		this.refresh();
2958
 
2959
		this.selectees = selectees.addClass("ui-selectee");
2960
 
2961
		this._mouseInit();
2962
 
2963
		this.helper = $("<div class='ui-selectable-helper'></div>");
2964
	},
2965
 
2966
	_destroy: function() {
2967
		this.selectees
2968
			.removeClass("ui-selectee")
2969
			.removeData("selectable-item");
2970
		this.element
2971
			.removeClass("ui-selectable ui-selectable-disabled");
2972
		this._mouseDestroy();
2973
	},
2974
 
2975
	_mouseStart: function(event) {
2976
		var that = this;
2977
 
2978
		this.opos = [event.pageX, event.pageY];
2979
 
2980
		if (this.options.disabled)
2981
			return;
2982
 
2983
		var options = this.options;
2984
 
2985
		this.selectees = $(options.filter, this.element[0]);
2986
 
2987
		this._trigger("start", event);
2988
 
2989
		$(options.appendTo).append(this.helper);
2990
		// position helper (lasso)
2991
		this.helper.css({
2992
			"left": event.clientX,
2993
			"top": event.clientY,
2994
			"width": 0,
2995
			"height": 0
2996
		});
2997
 
2998
		if (options.autoRefresh) {
2999
			this.refresh();
3000
		}
3001
 
3002
		this.selectees.filter('.ui-selected').each(function() {
3003
			var selectee = $.data(this, "selectable-item");
3004
			selectee.startselected = true;
3005
			if (!event.metaKey && !event.ctrlKey) {
3006
				selectee.$element.removeClass('ui-selected');
3007
				selectee.selected = false;
3008
				selectee.$element.addClass('ui-unselecting');
3009
				selectee.unselecting = true;
3010
				// selectable UNSELECTING callback
3011
				that._trigger("unselecting", event, {
3012
					unselecting: selectee.element
3013
				});
3014
			}
3015
		});
3016
 
3017
		$(event.target).parents().andSelf().each(function() {
3018
			var selectee = $.data(this, "selectable-item");
3019
			if (selectee) {
3020
				var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
3021
				selectee.$element
3022
					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3023
					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3024
				selectee.unselecting = !doSelect;
3025
				selectee.selecting = doSelect;
3026
				selectee.selected = doSelect;
3027
				// selectable (UN)SELECTING callback
3028
				if (doSelect) {
3029
					that._trigger("selecting", event, {
3030
						selecting: selectee.element
3031
					});
3032
				} else {
3033
					that._trigger("unselecting", event, {
3034
						unselecting: selectee.element
3035
					});
3036
				}
3037
				return false;
3038
			}
3039
		});
3040
 
3041
	},
3042
 
3043
	_mouseDrag: function(event) {
3044
		var that = this;
3045
		this.dragged = true;
3046
 
3047
		if (this.options.disabled)
3048
			return;
3049
 
3050
		var options = this.options;
3051
 
3052
		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3053
		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3054
		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3055
		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3056
 
3057
		this.selectees.each(function() {
3058
			var selectee = $.data(this, "selectable-item");
3059
			//prevent helper from being selected if appendTo: selectable
3060
			if (!selectee || selectee.element == that.element[0])
3061
				return;
3062
			var hit = false;
3063
			if (options.tolerance == 'touch') {
3064
				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3065
			} else if (options.tolerance == 'fit') {
3066
				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3067
			}
3068
 
3069
			if (hit) {
3070
				// SELECT
3071
				if (selectee.selected) {
3072
					selectee.$element.removeClass('ui-selected');
3073
					selectee.selected = false;
3074
				}
3075
				if (selectee.unselecting) {
3076
					selectee.$element.removeClass('ui-unselecting');
3077
					selectee.unselecting = false;
3078
				}
3079
				if (!selectee.selecting) {
3080
					selectee.$element.addClass('ui-selecting');
3081
					selectee.selecting = true;
3082
					// selectable SELECTING callback
3083
					that._trigger("selecting", event, {
3084
						selecting: selectee.element
3085
					});
3086
				}
3087
			} else {
3088
				// UNSELECT
3089
				if (selectee.selecting) {
3090
					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3091
						selectee.$element.removeClass('ui-selecting');
3092
						selectee.selecting = false;
3093
						selectee.$element.addClass('ui-selected');
3094
						selectee.selected = true;
3095
					} else {
3096
						selectee.$element.removeClass('ui-selecting');
3097
						selectee.selecting = false;
3098
						if (selectee.startselected) {
3099
							selectee.$element.addClass('ui-unselecting');
3100
							selectee.unselecting = true;
3101
						}
3102
						// selectable UNSELECTING callback
3103
						that._trigger("unselecting", event, {
3104
							unselecting: selectee.element
3105
						});
3106
					}
3107
				}
3108
				if (selectee.selected) {
3109
					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3110
						selectee.$element.removeClass('ui-selected');
3111
						selectee.selected = false;
3112
 
3113
						selectee.$element.addClass('ui-unselecting');
3114
						selectee.unselecting = true;
3115
						// selectable UNSELECTING callback
3116
						that._trigger("unselecting", event, {
3117
							unselecting: selectee.element
3118
						});
3119
					}
3120
				}
3121
			}
3122
		});
3123
 
3124
		return false;
3125
	},
3126
 
3127
	_mouseStop: function(event) {
3128
		var that = this;
3129
 
3130
		this.dragged = false;
3131
 
3132
		var options = this.options;
3133
 
3134
		$('.ui-unselecting', this.element[0]).each(function() {
3135
			var selectee = $.data(this, "selectable-item");
3136
			selectee.$element.removeClass('ui-unselecting');
3137
			selectee.unselecting = false;
3138
			selectee.startselected = false;
3139
			that._trigger("unselected", event, {
3140
				unselected: selectee.element
3141
			});
3142
		});
3143
		$('.ui-selecting', this.element[0]).each(function() {
3144
			var selectee = $.data(this, "selectable-item");
3145
			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3146
			selectee.selecting = false;
3147
			selectee.selected = true;
3148
			selectee.startselected = true;
3149
			that._trigger("selected", event, {
3150
				selected: selectee.element
3151
			});
3152
		});
3153
		this._trigger("stop", event);
3154
 
3155
		this.helper.remove();
3156
 
3157
		return false;
3158
	}
3159
 
3160
});
3161
 
3162
})(jQuery);
3163
 
3164
(function( $, undefined ) {
3165
 
3166
$.widget("ui.sortable", $.ui.mouse, {
3167
	version: "1.9.2",
3168
	widgetEventPrefix: "sort",
3169
	ready: false,
3170
	options: {
3171
		appendTo: "parent",
3172
		axis: false,
3173
		connectWith: false,
3174
		containment: false,
3175
		cursor: 'auto',
3176
		cursorAt: false,
3177
		dropOnEmpty: true,
3178
		forcePlaceholderSize: false,
3179
		forceHelperSize: false,
3180
		grid: false,
3181
		handle: false,
3182
		helper: "original",
3183
		items: '> *',
3184
		opacity: false,
3185
		placeholder: false,
3186
		revert: false,
3187
		scroll: true,
3188
		scrollSensitivity: 20,
3189
		scrollSpeed: 20,
3190
		scope: "default",
3191
		tolerance: "intersect",
3192
		zIndex: 1000
3193
	},
3194
	_create: function() {
3195
 
3196
		var o = this.options;
3197
		this.containerCache = {};
3198
		this.element.addClass("ui-sortable");
3199
 
3200
		//Get the items
3201
		this.refresh();
3202
 
3203
		//Let's determine if the items are being displayed horizontally
3204
		this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
3205
 
3206
		//Let's determine the parent's offset
3207
		this.offset = this.element.offset();
3208
 
3209
		//Initialize mouse events for interaction
3210
		this._mouseInit();
3211
 
3212
		//We're ready to go
3213
		this.ready = true
3214
 
3215
	},
3216
 
3217
	_destroy: function() {
3218
		this.element
3219
			.removeClass("ui-sortable ui-sortable-disabled");
3220
		this._mouseDestroy();
3221
 
3222
		for ( var i = this.items.length - 1; i >= 0; i-- )
3223
			this.items[i].item.removeData(this.widgetName + "-item");
3224
 
3225
		return this;
3226
	},
3227
 
3228
	_setOption: function(key, value){
3229
		if ( key === "disabled" ) {
3230
			this.options[ key ] = value;
3231
 
3232
			this.widget().toggleClass( "ui-sortable-disabled", !!value );
3233
		} else {
3234
			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3235
			$.Widget.prototype._setOption.apply(this, arguments);
3236
		}
3237
	},
3238
 
3239
	_mouseCapture: function(event, overrideHandle) {
3240
		var that = this;
3241
 
3242
		if (this.reverting) {
3243
			return false;
3244
		}
3245
 
3246
		if(this.options.disabled || this.options.type == 'static') return false;
3247
 
3248
		//We have to refresh the items data once first
3249
		this._refreshItems(event);
3250
 
3251
		//Find out if the clicked node (or one of its parents) is a actual item in this.items
3252
		var currentItem = null, nodes = $(event.target).parents().each(function() {
3253
			if($.data(this, that.widgetName + '-item') == that) {
3254
				currentItem = $(this);
3255
				return false;
3256
			}
3257
		});
3258
		if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
3259
 
3260
		if(!currentItem) return false;
3261
		if(this.options.handle && !overrideHandle) {
3262
			var validHandle = false;
3263
 
3264
			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3265
			if(!validHandle) return false;
3266
		}
3267
 
3268
		this.currentItem = currentItem;
3269
		this._removeCurrentsFromItems();
3270
		return true;
3271
 
3272
	},
3273
 
3274
	_mouseStart: function(event, overrideHandle, noActivation) {
3275
 
3276
		var o = this.options;
3277
		this.currentContainer = this;
3278
 
3279
		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3280
		this.refreshPositions();
3281
 
3282
		//Create and append the visible helper
3283
		this.helper = this._createHelper(event);
3284
 
3285
		//Cache the helper size
3286
		this._cacheHelperProportions();
3287
 
3288
		/*
3289
		 * - Position generation -
3290
		 * This block generates everything position related - it's the core of draggables.
3291
		 */
3292
 
3293
		//Cache the margins of the original element
3294
		this._cacheMargins();
3295
 
3296
		//Get the next scrolling parent
3297
		this.scrollParent = this.helper.scrollParent();
3298
 
3299
		//The element's absolute position on the page minus margins
3300
		this.offset = this.currentItem.offset();
3301
		this.offset = {
3302
			top: this.offset.top - this.margins.top,
3303
			left: this.offset.left - this.margins.left
3304
		};
3305
 
3306
		$.extend(this.offset, {
3307
			click: { //Where the click happened, relative to the element
3308
				left: event.pageX - this.offset.left,
3309
				top: event.pageY - this.offset.top
3310
			},
3311
			parent: this._getParentOffset(),
3312
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3313
		});
3314
 
3315
		// Only after we got the offset, we can change the helper's position to absolute
3316
		// TODO: Still need to figure out a way to make relative sorting possible
3317
		this.helper.css("position", "absolute");
3318
		this.cssPosition = this.helper.css("position");
3319
 
3320
		//Generate the original position
3321
		this.originalPosition = this._generatePosition(event);
3322
		this.originalPageX = event.pageX;
3323
		this.originalPageY = event.pageY;
3324
 
3325
		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3326
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3327
 
3328
		//Cache the former DOM position
3329
		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3330
 
3331
		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
3332
		if(this.helper[0] != this.currentItem[0]) {
3333
			this.currentItem.hide();
3334
		}
3335
 
3336
		//Create the placeholder
3337
		this._createPlaceholder();
3338
 
3339
		//Set a containment if given in the options
3340
		if(o.containment)
3341
			this._setContainment();
3342
 
3343
		if(o.cursor) { // cursor option
3344
			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3345
			$('body').css("cursor", o.cursor);
3346
		}
3347
 
3348
		if(o.opacity) { // opacity option
3349
			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3350
			this.helper.css("opacity", o.opacity);
3351
		}
3352
 
3353
		if(o.zIndex) { // zIndex option
3354
			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3355
			this.helper.css("zIndex", o.zIndex);
3356
		}
3357
 
3358
		//Prepare scrolling
3359
		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3360
			this.overflowOffset = this.scrollParent.offset();
3361
 
3362
		//Call callbacks
3363
		this._trigger("start", event, this._uiHash());
3364
 
3365
		//Recache the helper size
3366
		if(!this._preserveHelperProportions)
3367
			this._cacheHelperProportions();
3368
 
3369
 
3370
		//Post 'activate' events to possible containers
3371
		if(!noActivation) {
3372
			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
3373
		}
3374
 
3375
		//Prepare possible droppables
3376
		if($.ui.ddmanager)
3377
			$.ui.ddmanager.current = this;
3378
 
3379
		if ($.ui.ddmanager && !o.dropBehaviour)
3380
			$.ui.ddmanager.prepareOffsets(this, event);
3381
 
3382
		this.dragging = true;
3383
 
3384
		this.helper.addClass("ui-sortable-helper");
3385
		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3386
		return true;
3387
 
3388
	},
3389
 
3390
	_mouseDrag: function(event) {
3391
 
3392
		//Compute the helpers position
3393
		this.position = this._generatePosition(event);
3394
		this.positionAbs = this._convertPositionTo("absolute");
3395
 
3396
		if (!this.lastPositionAbs) {
3397
			this.lastPositionAbs = this.positionAbs;
3398
		}
3399
 
3400
		//Do scrolling
3401
		if(this.options.scroll) {
3402
			var o = this.options, scrolled = false;
3403
			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3404
 
3405
				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3406
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3407
				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3408
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3409
 
3410
				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3411
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3412
				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3413
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3414
 
3415
			} else {
3416
 
3417
				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3418
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3419
				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3420
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3421
 
3422
				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3423
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3424
				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3425
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3426
 
3427
			}
3428
 
3429
			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3430
				$.ui.ddmanager.prepareOffsets(this, event);
3431
		}
3432
 
3433
		//Regenerate the absolute position used for position checks
3434
		this.positionAbs = this._convertPositionTo("absolute");
3435
 
3436
		//Set the helper position
3437
		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3438
		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3439
 
3440
		//Rearrange
3441
		for (var i = this.items.length - 1; i >= 0; i--) {
3442
 
3443
			//Cache variables and intersection, continue if no intersection
3444
			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3445
			if (!intersection) continue;
3446
 
3447
			// Only put the placeholder inside the current Container, skip all
3448
			// items form other containers. This works because when moving
3449
			// an item from one container to another the
3450
			// currentContainer is switched before the placeholder is moved.
3451
			//
3452
			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
3453
			// beetween the outer and inner container.
3454
			if (item.instance !== this.currentContainer) continue;
3455
 
3456
			if (itemElement != this.currentItem[0] //cannot intersect with itself
3457
				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3458
				&&	!$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3459
				&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
3460
				//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3461
			) {
3462
 
3463
				this.direction = intersection == 1 ? "down" : "up";
3464
 
3465
				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3466
					this._rearrange(event, item);
3467
				} else {
3468
					break;
3469
				}
3470
 
3471
				this._trigger("change", event, this._uiHash());
3472
				break;
3473
			}
3474
		}
3475
 
3476
		//Post events to containers
3477
		this._contactContainers(event);
3478
 
3479
		//Interconnect with droppables
3480
		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3481
 
3482
		//Call callbacks
3483
		this._trigger('sort', event, this._uiHash());
3484
 
3485
		this.lastPositionAbs = this.positionAbs;
3486
		return false;
3487
 
3488
	},
3489
 
3490
	_mouseStop: function(event, noPropagation) {
3491
 
3492
		if(!event) return;
3493
 
3494
		//If we are using droppables, inform the manager about the drop
3495
		if ($.ui.ddmanager && !this.options.dropBehaviour)
3496
			$.ui.ddmanager.drop(this, event);
3497
 
3498
		if(this.options.revert) {
3499
			var that = this;
3500
			var cur = this.placeholder.offset();
3501
 
3502
			this.reverting = true;
3503
 
3504
			$(this.helper).animate({
3505
				left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3506
				top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3507
			}, parseInt(this.options.revert, 10) || 500, function() {
3508
				that._clear(event);
3509
			});
3510
		} else {
3511
			this._clear(event, noPropagation);
3512
		}
3513
 
3514
		return false;
3515
 
3516
	},
3517
 
3518
	cancel: function() {
3519
 
3520
		if(this.dragging) {
3521
 
3522
			this._mouseUp({ target: null });
3523
 
3524
			if(this.options.helper == "original")
3525
				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3526
			else
3527
				this.currentItem.show();
3528
 
3529
			//Post deactivating events to containers
3530
			for (var i = this.containers.length - 1; i >= 0; i--){
3531
				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3532
				if(this.containers[i].containerCache.over) {
3533
					this.containers[i]._trigger("out", null, this._uiHash(this));
3534
					this.containers[i].containerCache.over = 0;
3535
				}
3536
			}
3537
 
3538
		}
3539
 
3540
		if (this.placeholder) {
3541
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3542
			if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3543
			if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3544
 
3545
			$.extend(this, {
3546
				helper: null,
3547
				dragging: false,
3548
				reverting: false,
3549
				_noFinalSort: null
3550
			});
3551
 
3552
			if(this.domPosition.prev) {
3553
				$(this.domPosition.prev).after(this.currentItem);
3554
			} else {
3555
				$(this.domPosition.parent).prepend(this.currentItem);
3556
			}
3557
		}
3558
 
3559
		return this;
3560
 
3561
	},
3562
 
3563
	serialize: function(o) {
3564
 
3565
		var items = this._getItemsAsjQuery(o && o.connected);
3566
		var str = []; o = o || {};
3567
 
3568
		$(items).each(function() {
3569
			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3570
			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3571
		});
3572
 
3573
		if(!str.length && o.key) {
3574
			str.push(o.key + '=');
3575
		}
3576
 
3577
		return str.join('&');
3578
 
3579
	},
3580
 
3581
	toArray: function(o) {
3582
 
3583
		var items = this._getItemsAsjQuery(o && o.connected);
3584
		var ret = []; o = o || {};
3585
 
3586
		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3587
		return ret;
3588
 
3589
	},
3590
 
3591
	/* Be careful with the following core functions */
3592
	_intersectsWith: function(item) {
3593
 
3594
		var x1 = this.positionAbs.left,
3595
			x2 = x1 + this.helperProportions.width,
3596
			y1 = this.positionAbs.top,
3597
			y2 = y1 + this.helperProportions.height;
3598
 
3599
		var l = item.left,
3600
			r = l + item.width,
3601
			t = item.top,
3602
			b = t + item.height;
3603
 
3604
		var dyClick = this.offset.click.top,
3605
			dxClick = this.offset.click.left;
3606
 
3607
		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3608
 
3609
		if(	   this.options.tolerance == "pointer"
3610
			|| this.options.forcePointerForContainers
3611
			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3612
		) {
3613
			return isOverElement;
3614
		} else {
3615
 
3616
			return (l < x1 + (this.helperProportions.width / 2) // Right Half
3617
				&& x2 - (this.helperProportions.width / 2) < r // Left Half
3618
				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
3619
				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
3620
 
3621
		}
3622
	},
3623
 
3624
	_intersectsWithPointer: function(item) {
3625
 
3626
		var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3627
			isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3628
			isOverElement = isOverElementHeight && isOverElementWidth,
3629
			verticalDirection = this._getDragVerticalDirection(),
3630
			horizontalDirection = this._getDragHorizontalDirection();
3631
 
3632
		if (!isOverElement)
3633
			return false;
3634
 
3635
		return this.floating ?
3636
			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3637
			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3638
 
3639
	},
3640
 
3641
	_intersectsWithSides: function(item) {
3642
 
3643
		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3644
			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3645
			verticalDirection = this._getDragVerticalDirection(),
3646
			horizontalDirection = this._getDragHorizontalDirection();
3647
 
3648
		if (this.floating && horizontalDirection) {
3649
			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3650
		} else {
3651
			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3652
		}
3653
 
3654
	},
3655
 
3656
	_getDragVerticalDirection: function() {
3657
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
3658
		return delta != 0 && (delta > 0 ? "down" : "up");
3659
	},
3660
 
3661
	_getDragHorizontalDirection: function() {
3662
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
3663
		return delta != 0 && (delta > 0 ? "right" : "left");
3664
	},
3665
 
3666
	refresh: function(event) {
3667
		this._refreshItems(event);
3668
		this.refreshPositions();
3669
		return this;
3670
	},
3671
 
3672
	_connectWith: function() {
3673
		var options = this.options;
3674
		return options.connectWith.constructor == String
3675
			? [options.connectWith]
3676
			: options.connectWith;
3677
	},
3678
 
3679
	_getItemsAsjQuery: function(connected) {
3680
 
3681
		var items = [];
3682
		var queries = [];
3683
		var connectWith = this._connectWith();
3684
 
3685
		if(connectWith && connected) {
3686
			for (var i = connectWith.length - 1; i >= 0; i--){
3687
				var cur = $(connectWith[i]);
3688
				for (var j = cur.length - 1; j >= 0; j--){
3689
					var inst = $.data(cur[j], this.widgetName);
3690
					if(inst && inst != this && !inst.options.disabled) {
3691
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
3692
					}
3693
				};
3694
			};
3695
		}
3696
 
3697
		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
3698
 
3699
		for (var i = queries.length - 1; i >= 0; i--){
3700
			queries[i][0].each(function() {
3701
				items.push(this);
3702
			});
3703
		};
3704
 
3705
		return $(items);
3706
 
3707
	},
3708
 
3709
	_removeCurrentsFromItems: function() {
3710
 
3711
		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3712
 
3713
		this.items = $.grep(this.items, function (item) {
3714
			for (var j=0; j < list.length; j++) {
3715
				if(list[j] == item.item[0])
3716
					return false;
3717
			};
3718
			return true;
3719
		});
3720
 
3721
	},
3722
 
3723
	_refreshItems: function(event) {
3724
 
3725
		this.items = [];
3726
		this.containers = [this];
3727
		var items = this.items;
3728
		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3729
		var connectWith = this._connectWith();
3730
 
3731
		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
3732
			for (var i = connectWith.length - 1; i >= 0; i--){
3733
				var cur = $(connectWith[i]);
3734
				for (var j = cur.length - 1; j >= 0; j--){
3735
					var inst = $.data(cur[j], this.widgetName);
3736
					if(inst && inst != this && !inst.options.disabled) {
3737
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3738
						this.containers.push(inst);
3739
					}
3740
				};
3741
			};
3742
		}
3743
 
3744
		for (var i = queries.length - 1; i >= 0; i--) {
3745
			var targetData = queries[i][1];
3746
			var _queries = queries[i][0];
3747
 
3748
			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3749
				var item = $(_queries[j]);
3750
 
3751
				item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
3752
 
3753
				items.push({
3754
					item: item,
3755
					instance: targetData,
3756
					width: 0, height: 0,
3757
					left: 0, top: 0
3758
				});
3759
			};
3760
		};
3761
 
3762
	},
3763
 
3764
	refreshPositions: function(fast) {
3765
 
3766
		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3767
		if(this.offsetParent && this.helper) {
3768
			this.offset.parent = this._getParentOffset();
3769
		}
3770
 
3771
		for (var i = this.items.length - 1; i >= 0; i--){
3772
			var item = this.items[i];
3773
 
3774
			//We ignore calculating positions of all connected containers when we're not over them
3775
			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3776
				continue;
3777
 
3778
			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3779
 
3780
			if (!fast) {
3781
				item.width = t.outerWidth();
3782
				item.height = t.outerHeight();
3783
			}
3784
 
3785
			var p = t.offset();
3786
			item.left = p.left;
3787
			item.top = p.top;
3788
		};
3789
 
3790
		if(this.options.custom && this.options.custom.refreshContainers) {
3791
			this.options.custom.refreshContainers.call(this);
3792
		} else {
3793
			for (var i = this.containers.length - 1; i >= 0; i--){
3794
				var p = this.containers[i].element.offset();
3795
				this.containers[i].containerCache.left = p.left;
3796
				this.containers[i].containerCache.top = p.top;
3797
				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
3798
				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3799
			};
3800
		}
3801
 
3802
		return this;
3803
	},
3804
 
3805
	_createPlaceholder: function(that) {
3806
		that = that || this;
3807
		var o = that.options;
3808
 
3809
		if(!o.placeholder || o.placeholder.constructor == String) {
3810
			var className = o.placeholder;
3811
			o.placeholder = {
3812
				element: function() {
3813
 
3814
					var el = $(document.createElement(that.currentItem[0].nodeName))
3815
						.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
3816
						.removeClass("ui-sortable-helper")[0];
3817
 
3818
					if(!className)
3819
						el.style.visibility = "hidden";
3820
 
3821
					return el;
3822
				},
3823
				update: function(container, p) {
3824
 
3825
					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3826
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3827
					if(className && !o.forcePlaceholderSize) return;
3828
 
3829
					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
3830
					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
3831
					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
3832
				}
3833
			};
3834
		}
3835
 
3836
		//Create the placeholder
3837
		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
3838
 
3839
		//Append it after the actual current item
3840
		that.currentItem.after(that.placeholder);
3841
 
3842
		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3843
		o.placeholder.update(that, that.placeholder);
3844
 
3845
	},
3846
 
3847
	_contactContainers: function(event) {
3848
 
3849
		// get innermost container that intersects with item
3850
		var innermostContainer = null, innermostIndex = null;
3851
 
3852
 
3853
		for (var i = this.containers.length - 1; i >= 0; i--){
3854
 
3855
			// never consider a container that's located within the item itself
3856
			if($.contains(this.currentItem[0], this.containers[i].element[0]))
3857
				continue;
3858
 
3859
			if(this._intersectsWith(this.containers[i].containerCache)) {
3860
 
3861
				// if we've already found a container and it's more "inner" than this, then continue
3862
				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
3863
					continue;
3864
 
3865
				innermostContainer = this.containers[i];
3866
				innermostIndex = i;
3867
 
3868
			} else {
3869
				// container doesn't intersect. trigger "out" event if necessary
3870
				if(this.containers[i].containerCache.over) {
3871
					this.containers[i]._trigger("out", event, this._uiHash(this));
3872
					this.containers[i].containerCache.over = 0;
3873
				}
3874
			}
3875
 
3876
		}
3877
 
3878
		// if no intersecting containers found, return
3879
		if(!innermostContainer) return;
3880
 
3881
		// move the item into the container if it's not there already
3882
		if(this.containers.length === 1) {
3883
			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3884
			this.containers[innermostIndex].containerCache.over = 1;
3885
		} else {
3886
 
3887
			//When entering a new container, we will find the item with the least distance and append our item near it
3888
			var dist = 10000; var itemWithLeastDistance = null;
3889
			var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
3890
			var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
3891
			var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
3892
			for (var j = this.items.length - 1; j >= 0; j--) {
3893
				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
3894
				if(this.items[j].item[0] == this.currentItem[0]) continue;
3895
				var cur = this.items[j].item.offset()[posProperty];
3896
				var nearBottom = false;
3897
				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
3898
					nearBottom = true;
3899
					cur += this.items[j][sizeProperty];
3900
				}
3901
 
3902
				if(Math.abs(cur - base) < dist) {
3903
					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3904
					this.direction = nearBottom ? "up": "down";
3905
				}
3906
			}
3907
 
3908
			if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
3909
				return;
3910
 
3911
			this.currentContainer = this.containers[innermostIndex];
3912
			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
3913
			this._trigger("change", event, this._uiHash());
3914
			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
3915
 
3916
			//Update the placeholder
3917
			this.options.placeholder.update(this.currentContainer, this.placeholder);
3918
 
3919
			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3920
			this.containers[innermostIndex].containerCache.over = 1;
3921
		}
3922
 
3923
 
3924
	},
3925
 
3926
	_createHelper: function(event) {
3927
 
3928
		var o = this.options;
3929
		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3930
 
3931
		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3932
			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3933
 
3934
		if(helper[0] == this.currentItem[0])
3935
			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
3936
 
3937
		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3938
		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3939
 
3940
		return helper;
3941
 
3942
	},
3943
 
3944
	_adjustOffsetFromHelper: function(obj) {
3945
		if (typeof obj == 'string') {
3946
			obj = obj.split(' ');
3947
		}
3948
		if ($.isArray(obj)) {
3949
			obj = {left: +obj[0], top: +obj[1] || 0};
3950
		}
3951
		if ('left' in obj) {
3952
			this.offset.click.left = obj.left + this.margins.left;
3953
		}
3954
		if ('right' in obj) {
3955
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3956
		}
3957
		if ('top' in obj) {
3958
			this.offset.click.top = obj.top + this.margins.top;
3959
		}
3960
		if ('bottom' in obj) {
3961
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3962
		}
3963
	},
3964
 
3965
	_getParentOffset: function() {
3966
 
3967
 
3968
		//Get the offsetParent and cache its position
3969
		this.offsetParent = this.helper.offsetParent();
3970
		var po = this.offsetParent.offset();
3971
 
3972
		// This is a special case where we need to modify a offset calculated on start, since the following happened:
3973
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
3974
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
3975
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
3976
		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
3977
			po.left += this.scrollParent.scrollLeft();
3978
			po.top += this.scrollParent.scrollTop();
3979
		}
3980
 
3981
		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
3982
		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
3983
			po = { top: 0, left: 0 };
3984
 
3985
		return {
3986
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3987
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3988
		};
3989
 
3990
	},
3991
 
3992
	_getRelativeOffset: function() {
3993
 
3994
		if(this.cssPosition == "relative") {
3995
			var p = this.currentItem.position();
3996
			return {
3997
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
3998
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
3999
			};
4000
		} else {
4001
			return { top: 0, left: 0 };
4002
		}
4003
 
4004
	},
4005
 
4006
	_cacheMargins: function() {
4007
		this.margins = {
4008
			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4009
			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4010
		};
4011
	},
4012
 
4013
	_cacheHelperProportions: function() {
4014
		this.helperProportions = {
4015
			width: this.helper.outerWidth(),
4016
			height: this.helper.outerHeight()
4017
		};
4018
	},
4019
 
4020
	_setContainment: function() {
4021
 
4022
		var o = this.options;
4023
		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4024
		if(o.containment == 'document' || o.containment == 'window') this.containment = [
4025
 
4026
 
4027
			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4028
			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4029
		];
4030
 
4031
		if(!(/^(document|window|parent)$/).test(o.containment)) {
4032
			var ce = $(o.containment)[0];
4033
			var co = $(o.containment).offset();
4034
			var over = ($(ce).css("overflow") != 'hidden');
4035
 
4036
			this.containment = [
4037
				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4038
				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4039
				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
4040
				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4041
			];
4042
		}
4043
 
4044
	},
4045
 
4046
	_convertPositionTo: function(d, pos) {
4047
 
4048
		if(!pos) pos = this.position;
4049
		var mod = d == "absolute" ? 1 : -1;
4050
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4051
 
4052
		return {
4053
			top: (
4054
				pos.top																	// The absolute mouse position
4055
				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4056
				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
4057
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4058
			),
4059
			left: (
4060
				pos.left																// The absolute mouse position
4061
				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4062
				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
4063
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4064
			)
4065
		};
4066
 
4067
	},
4068
 
4069
	_generatePosition: function(event) {
4070
 
4071
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4072
 
4073
		// This is another very weird special case that only happens for relative elements:
4074
		// 1. If the css position is relative
4075
		// 2. and the scroll parent is the document or similar to the offset parent
4076
		// we have to refresh the relative offset during the scroll so there are no jumps
4077
		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4078
			this.offset.relative = this._getRelativeOffset();
4079
		}
4080
 
4081
		var pageX = event.pageX;
4082
		var pageY = event.pageY;
4083
 
4084
		/*
4085
		 * - Position constraining -
4086
		 * Constrain the position to a mix of grid, containment.
4087
		 */
4088
 
4089
		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4090
 
4091
			if(this.containment) {
4092
				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4093
				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4094
				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4095
				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4096
			}
4097
 
4098
			if(o.grid) {
4099
				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4100
				pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
4101
 
4102
				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4103
				pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
4104
			}
4105
 
4106
		}
4107
 
4108
		return {
4109
			top: (
4110
				pageY																// The absolute mouse position
4111
				- this.offset.click.top													// Click offset (relative to the element)
4112
				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
4113
				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
4114
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4115
			),
4116
			left: (
4117
				pageX																// The absolute mouse position
4118
				- this.offset.click.left												// Click offset (relative to the element)
4119
				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
4120
				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
4121
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4122
			)
4123
		};
4124
 
4125
	},
4126
 
4127
	_rearrange: function(event, i, a, hardRefresh) {
4128
 
4129
		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
4130
 
4131
		//Various things done here to improve the performance:
4132
		// 1. we create a setTimeout, that calls refreshPositions
4133
		// 2. on the instance, we have a counter variable, that get's higher after every append
4134
		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4135
		// 4. this lets only the last addition to the timeout stack through
4136
		this.counter = this.counter ? ++this.counter : 1;
4137
		var counter = this.counter;
4138
 
4139
		this._delay(function() {
4140
			if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4141
		});
4142
 
4143
	},
4144
 
4145
	_clear: function(event, noPropagation) {
4146
 
4147
		this.reverting = false;
4148
		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
4149
		// everything else normalized again
4150
		var delayedTriggers = [];
4151
 
4152
		// We first have to update the dom position of the actual currentItem
4153
		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4154
		if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4155
		this._noFinalSort = null;
4156
 
4157
		if(this.helper[0] == this.currentItem[0]) {
4158
			for(var i in this._storedCSS) {
4159
				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4160
			}
4161
			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4162
		} else {
4163
			this.currentItem.show();
4164
		}
4165
 
4166
		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4167
		if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4168
 
4169
		// Check if the items Container has Changed and trigger appropriate
4170
		// events.
4171
		if (this !== this.currentContainer) {
4172
			if(!noPropagation) {
4173
				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4174
				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4175
				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4176
			}
4177
		}
4178
 
4179
 
4180
		//Post events to containers
4181
		for (var i = this.containers.length - 1; i >= 0; i--){
4182
			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4183
			if(this.containers[i].containerCache.over) {
4184
				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4185
				this.containers[i].containerCache.over = 0;
4186
			}
4187
		}
4188
 
4189
		//Do what was originally in plugins
4190
		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4191
		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4192
		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4193
 
4194
		this.dragging = false;
4195
		if(this.cancelHelperRemoval) {
4196
			if(!noPropagation) {
4197
				this._trigger("beforeStop", event, this._uiHash());
4198
				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4199
				this._trigger("stop", event, this._uiHash());
4200
			}
4201
 
4202
			this.fromOutside = false;
4203
			return false;
4204
		}
4205
 
4206
		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4207
 
4208
		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4209
		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4210
 
4211
		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4212
 
4213
		if(!noPropagation) {
4214
			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4215
			this._trigger("stop", event, this._uiHash());
4216
		}
4217
 
4218
		this.fromOutside = false;
4219
		return true;
4220
 
4221
	},
4222
 
4223
	_trigger: function() {
4224
		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4225
			this.cancel();
4226
		}
4227
	},
4228
 
4229
	_uiHash: function(_inst) {
4230
		var inst = _inst || this;
4231
		return {
4232
			helper: inst.helper,
4233
			placeholder: inst.placeholder || $([]),
4234
			position: inst.position,
4235
			originalPosition: inst.originalPosition,
4236
			offset: inst.positionAbs,
4237
			item: inst.currentItem,
4238
			sender: _inst ? _inst.element : null
4239
		};
4240
	}
4241
 
4242
});
4243
 
4244
})(jQuery);
4245
 
4246
;(jQuery.effects || (function($, undefined) {
4247
 
4248
var backCompat = $.uiBackCompat !== false,
4249
	// prefix used for storing data on .data()
4250
	dataSpace = "ui-effects-";
4251
 
4252
$.effects = {
4253
	effect: {}
4254
};
4255
 
4256
/*!
4257
 * jQuery Color Animations v2.0.0
4258
 * http://jquery.com/
4259
 *
4260
 * Copyright 2012 jQuery Foundation and other contributors
4261
 * Released under the MIT license.
4262
 * http://jquery.org/license
4263
 *
4264
 * Date: Mon Aug 13 13:41:02 2012 -0500
4265
 */
4266
(function( jQuery, undefined ) {
4267
 
4268
	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
4269
 
4270
	// plusequals test for += 100 -= 100
4271
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4272
	// a set of RE's that can match strings and generate color tuples.
4273
	stringParsers = [{
4274
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
4275
			parse: function( execResult ) {
4276
				return [
4277
					execResult[ 1 ],
4278
					execResult[ 2 ],
4279
					execResult[ 3 ],
4280
					execResult[ 4 ]
4281
				];
4282
			}
4283
		}, {
4284
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
4285
			parse: function( execResult ) {
4286
				return [
4287
					execResult[ 1 ] * 2.55,
4288
					execResult[ 2 ] * 2.55,
4289
					execResult[ 3 ] * 2.55,
4290
					execResult[ 4 ]
4291
				];
4292
			}
4293
		}, {
4294
			// this regex ignores A-F because it's compared against an already lowercased string
4295
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4296
			parse: function( execResult ) {
4297
				return [
4298
					parseInt( execResult[ 1 ], 16 ),
4299
					parseInt( execResult[ 2 ], 16 ),
4300
					parseInt( execResult[ 3 ], 16 )
4301
				];
4302
			}
4303
		}, {
4304
			// this regex ignores A-F because it's compared against an already lowercased string
4305
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4306
			parse: function( execResult ) {
4307
				return [
4308
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4309
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4310
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4311
				];
4312
			}
4313
		}, {
4314
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
4315
			space: "hsla",
4316
			parse: function( execResult ) {
4317
				return [
4318
					execResult[ 1 ],
4319
					execResult[ 2 ] / 100,
4320
					execResult[ 3 ] / 100,
4321
					execResult[ 4 ]
4322
				];
4323
			}
4324
		}],
4325
 
4326
	// jQuery.Color( )
4327
	color = jQuery.Color = function( color, green, blue, alpha ) {
4328
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
4329
	},
4330
	spaces = {
4331
		rgba: {
4332
			props: {
4333
				red: {
4334
					idx: 0,
4335
					type: "byte"
4336
				},
4337
				green: {
4338
					idx: 1,
4339
					type: "byte"
4340
				},
4341
				blue: {
4342
					idx: 2,
4343
					type: "byte"
4344
				}
4345
			}
4346
		},
4347
 
4348
		hsla: {
4349
			props: {
4350
				hue: {
4351
					idx: 0,
4352
					type: "degrees"
4353
				},
4354
				saturation: {
4355
					idx: 1,
4356
					type: "percent"
4357
				},
4358
				lightness: {
4359
					idx: 2,
4360
					type: "percent"
4361
				}
4362
			}
4363
		}
4364
	},
4365
	propTypes = {
4366
		"byte": {
4367
			floor: true,
4368
			max: 255
4369
		},
4370
		"percent": {
4371
			max: 1
4372
		},
4373
		"degrees": {
4374
			mod: 360,
4375
			floor: true
4376
		}
4377
	},
4378
	support = color.support = {},
4379
 
4380
	// element for support tests
4381
	supportElem = jQuery( "<p>" )[ 0 ],
4382
 
4383
	// colors = jQuery.Color.names
4384
	colors,
4385
 
4386
	// local aliases of functions called often
4387
	each = jQuery.each;
4388
 
4389
// determine rgba support immediately
4390
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4391
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4392
 
4393
// define cache name and alpha properties
4394
// for rgba and hsla spaces
4395
each( spaces, function( spaceName, space ) {
4396
	space.cache = "_" + spaceName;
4397
	space.props.alpha = {
4398
		idx: 3,
4399
		type: "percent",
4400
		def: 1
4401
	};
4402
});
4403
 
4404
function clamp( value, prop, allowEmpty ) {
4405
	var type = propTypes[ prop.type ] || {};
4406
 
4407
	if ( value == null ) {
4408
		return (allowEmpty || !prop.def) ? null : prop.def;
4409
	}
4410
 
4411
	// ~~ is an short way of doing floor for positive numbers
4412
	value = type.floor ? ~~value : parseFloat( value );
4413
 
4414
	// IE will pass in empty strings as value for alpha,
4415
	// which will hit this case
4416
	if ( isNaN( value ) ) {
4417
		return prop.def;
4418
	}
4419
 
4420
	if ( type.mod ) {
4421
		// we add mod before modding to make sure that negatives values
4422
		// get converted properly: -10 -> 350
4423
		return (value + type.mod) % type.mod;
4424
	}
4425
 
4426
	// for now all property types without mod have min and max
4427
	return 0 > value ? 0 : type.max < value ? type.max : value;
4428
}
4429
 
4430
function stringParse( string ) {
4431
	var inst = color(),
4432
		rgba = inst._rgba = [];
4433
 
4434
	string = string.toLowerCase();
4435
 
4436
	each( stringParsers, function( i, parser ) {
4437
		var parsed,
4438
			match = parser.re.exec( string ),
4439
			values = match && parser.parse( match ),
4440
			spaceName = parser.space || "rgba";
4441
 
4442
		if ( values ) {
4443
			parsed = inst[ spaceName ]( values );
4444
 
4445
			// if this was an rgba parse the assignment might happen twice
4446
			// oh well....
4447
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
4448
			rgba = inst._rgba = parsed._rgba;
4449
 
4450
			// exit each( stringParsers ) here because we matched
4451
			return false;
4452
		}
4453
	});
4454
 
4455
	// Found a stringParser that handled it
4456
	if ( rgba.length ) {
4457
 
4458
		// if this came from a parsed string, force "transparent" when alpha is 0
4459
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
4460
		if ( rgba.join() === "0,0,0,0" ) {
4461
			jQuery.extend( rgba, colors.transparent );
4462
		}
4463
		return inst;
4464
	}
4465
 
4466
	// named colors
4467
	return colors[ string ];
4468
}
4469
 
4470
color.fn = jQuery.extend( color.prototype, {
4471
	parse: function( red, green, blue, alpha ) {
4472
		if ( red === undefined ) {
4473
			this._rgba = [ null, null, null, null ];
4474
			return this;
4475
		}
4476
		if ( red.jquery || red.nodeType ) {
4477
			red = jQuery( red ).css( green );
4478
			green = undefined;
4479
		}
4480
 
4481
		var inst = this,
4482
			type = jQuery.type( red ),
4483
			rgba = this._rgba = [];
4484
 
4485
		// more than 1 argument specified - assume ( red, green, blue, alpha )
4486
		if ( green !== undefined ) {
4487
			red = [ red, green, blue, alpha ];
4488
			type = "array";
4489
		}
4490
 
4491
		if ( type === "string" ) {
4492
			return this.parse( stringParse( red ) || colors._default );
4493
		}
4494
 
4495
		if ( type === "array" ) {
4496
			each( spaces.rgba.props, function( key, prop ) {
4497
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
4498
			});
4499
			return this;
4500
		}
4501
 
4502
		if ( type === "object" ) {
4503
			if ( red instanceof color ) {
4504
				each( spaces, function( spaceName, space ) {
4505
					if ( red[ space.cache ] ) {
4506
						inst[ space.cache ] = red[ space.cache ].slice();
4507
					}
4508
				});
4509
			} else {
4510
				each( spaces, function( spaceName, space ) {
4511
					var cache = space.cache;
4512
					each( space.props, function( key, prop ) {
4513
 
4514
						// if the cache doesn't exist, and we know how to convert
4515
						if ( !inst[ cache ] && space.to ) {
4516
 
4517
							// if the value was null, we don't need to copy it
4518
							// if the key was alpha, we don't need to copy it either
4519
							if ( key === "alpha" || red[ key ] == null ) {
4520
								return;
4521
							}
4522
							inst[ cache ] = space.to( inst._rgba );
4523
						}
4524
 
4525
						// this is the only case where we allow nulls for ALL properties.
4526
						// call clamp with alwaysAllowEmpty
4527
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
4528
					});
4529
 
4530
					// everything defined but alpha?
4531
					if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
4532
						// use the default of 1
4533
						inst[ cache ][ 3 ] = 1;
4534
						if ( space.from ) {
4535
							inst._rgba = space.from( inst[ cache ] );
4536
						}
4537
					}
4538
				});
4539
			}
4540
			return this;
4541
		}
4542
	},
4543
	is: function( compare ) {
4544
		var is = color( compare ),
4545
			same = true,
4546
			inst = this;
4547
 
4548
		each( spaces, function( _, space ) {
4549
			var localCache,
4550
				isCache = is[ space.cache ];
4551
			if (isCache) {
4552
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
4553
				each( space.props, function( _, prop ) {
4554
					if ( isCache[ prop.idx ] != null ) {
4555
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
4556
						return same;
4557
					}
4558
				});
4559
			}
4560
			return same;
4561
		});
4562
		return same;
4563
	},
4564
	_space: function() {
4565
		var used = [],
4566
			inst = this;
4567
		each( spaces, function( spaceName, space ) {
4568
			if ( inst[ space.cache ] ) {
4569
				used.push( spaceName );
4570
			}
4571
		});
4572
		return used.pop();
4573
	},
4574
	transition: function( other, distance ) {
4575
		var end = color( other ),
4576
			spaceName = end._space(),
4577
			space = spaces[ spaceName ],
4578
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
4579
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
4580
			result = start.slice();
4581
 
4582
		end = end[ space.cache ];
4583
		each( space.props, function( key, prop ) {
4584
			var index = prop.idx,
4585
				startValue = start[ index ],
4586
				endValue = end[ index ],
4587
				type = propTypes[ prop.type ] || {};
4588
 
4589
			// if null, don't override start value
4590
			if ( endValue === null ) {
4591
				return;
4592
			}
4593
			// if null - use end
4594
			if ( startValue === null ) {
4595
				result[ index ] = endValue;
4596
			} else {
4597
				if ( type.mod ) {
4598
					if ( endValue - startValue > type.mod / 2 ) {
4599
						startValue += type.mod;
4600
					} else if ( startValue - endValue > type.mod / 2 ) {
4601
						startValue -= type.mod;
4602
					}
4603
				}
4604
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
4605
			}
4606
		});
4607
		return this[ spaceName ]( result );
4608
	},
4609
	blend: function( opaque ) {
4610
		// if we are already opaque - return ourself
4611
		if ( this._rgba[ 3 ] === 1 ) {
4612
			return this;
4613
		}
4614
 
4615
		var rgb = this._rgba.slice(),
4616
			a = rgb.pop(),
4617
			blend = color( opaque )._rgba;
4618
 
4619
		return color( jQuery.map( rgb, function( v, i ) {
4620
			return ( 1 - a ) * blend[ i ] + a * v;
4621
		}));
4622
	},
4623
	toRgbaString: function() {
4624
		var prefix = "rgba(",
4625
			rgba = jQuery.map( this._rgba, function( v, i ) {
4626
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
4627
			});
4628
 
4629
		if ( rgba[ 3 ] === 1 ) {
4630
			rgba.pop();
4631
			prefix = "rgb(";
4632
		}
4633
 
4634
		return prefix + rgba.join() + ")";
4635
	},
4636
	toHslaString: function() {
4637
		var prefix = "hsla(",
4638
			hsla = jQuery.map( this.hsla(), function( v, i ) {
4639
				if ( v == null ) {
4640
					v = i > 2 ? 1 : 0;
4641
				}
4642
 
4643
				// catch 1 and 2
4644
				if ( i && i < 3 ) {
4645
					v = Math.round( v * 100 ) + "%";
4646
				}
4647
				return v;
4648
			});
4649
 
4650
		if ( hsla[ 3 ] === 1 ) {
4651
			hsla.pop();
4652
			prefix = "hsl(";
4653
		}
4654
		return prefix + hsla.join() + ")";
4655
	},
4656
	toHexString: function( includeAlpha ) {
4657
		var rgba = this._rgba.slice(),
4658
			alpha = rgba.pop();
4659
 
4660
		if ( includeAlpha ) {
4661
			rgba.push( ~~( alpha * 255 ) );
4662
		}
4663
 
4664
		return "#" + jQuery.map( rgba, function( v ) {
4665
 
4666
			// default to 0 when nulls exist
4667
			v = ( v || 0 ).toString( 16 );
4668
			return v.length === 1 ? "0" + v : v;
4669
		}).join("");
4670
	},
4671
	toString: function() {
4672
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
4673
	}
4674
});
4675
color.fn.parse.prototype = color.fn;
4676
 
4677
// hsla conversions adapted from:
4678
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
4679
 
4680
function hue2rgb( p, q, h ) {
4681
	h = ( h + 1 ) % 1;
4682
	if ( h * 6 < 1 ) {
4683
		return p + (q - p) * h * 6;
4684
	}
4685
	if ( h * 2 < 1) {
4686
		return q;
4687
	}
4688
	if ( h * 3 < 2 ) {
4689
		return p + (q - p) * ((2/3) - h) * 6;
4690
	}
4691
	return p;
4692
}
4693
 
4694
spaces.hsla.to = function ( rgba ) {
4695
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
4696
		return [ null, null, null, rgba[ 3 ] ];
4697
	}
4698
	var r = rgba[ 0 ] / 255,
4699
		g = rgba[ 1 ] / 255,
4700
		b = rgba[ 2 ] / 255,
4701
		a = rgba[ 3 ],
4702
		max = Math.max( r, g, b ),
4703
		min = Math.min( r, g, b ),
4704
		diff = max - min,
4705
		add = max + min,
4706
		l = add * 0.5,
4707
		h, s;
4708
 
4709
	if ( min === max ) {
4710
		h = 0;
4711
	} else if ( r === max ) {
4712
		h = ( 60 * ( g - b ) / diff ) + 360;
4713
	} else if ( g === max ) {
4714
		h = ( 60 * ( b - r ) / diff ) + 120;
4715
	} else {
4716
		h = ( 60 * ( r - g ) / diff ) + 240;
4717
	}
4718
 
4719
	if ( l === 0 || l === 1 ) {
4720
		s = l;
4721
	} else if ( l <= 0.5 ) {
4722
		s = diff / add;
4723
	} else {
4724
		s = diff / ( 2 - add );
4725
	}
4726
	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
4727
};
4728
 
4729
spaces.hsla.from = function ( hsla ) {
4730
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
4731
		return [ null, null, null, hsla[ 3 ] ];
4732
	}
4733
	var h = hsla[ 0 ] / 360,
4734
		s = hsla[ 1 ],
4735
		l = hsla[ 2 ],
4736
		a = hsla[ 3 ],
4737
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
4738
		p = 2 * l - q;
4739
 
4740
	return [
4741
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
4742
		Math.round( hue2rgb( p, q, h ) * 255 ),
4743
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
4744
		a
4745
	];
4746
};
4747
 
4748
 
4749
each( spaces, function( spaceName, space ) {
4750
	var props = space.props,
4751
		cache = space.cache,
4752
		to = space.to,
4753
		from = space.from;
4754
 
4755
	// makes rgba() and hsla()
4756
	color.fn[ spaceName ] = function( value ) {
4757
 
4758
		// generate a cache for this space if it doesn't exist
4759
		if ( to && !this[ cache ] ) {
4760
			this[ cache ] = to( this._rgba );
4761
		}
4762
		if ( value === undefined ) {
4763
			return this[ cache ].slice();
4764
		}
4765
 
4766
		var ret,
4767
			type = jQuery.type( value ),
4768
			arr = ( type === "array" || type === "object" ) ? value : arguments,
4769
			local = this[ cache ].slice();
4770
 
4771
		each( props, function( key, prop ) {
4772
			var val = arr[ type === "object" ? key : prop.idx ];
4773
			if ( val == null ) {
4774
				val = local[ prop.idx ];
4775
			}
4776
			local[ prop.idx ] = clamp( val, prop );
4777
		});
4778
 
4779
		if ( from ) {
4780
			ret = color( from( local ) );
4781
			ret[ cache ] = local;
4782
			return ret;
4783
		} else {
4784
			return color( local );
4785
		}
4786
	};
4787
 
4788
	// makes red() green() blue() alpha() hue() saturation() lightness()
4789
	each( props, function( key, prop ) {
4790
		// alpha is included in more than one space
4791
		if ( color.fn[ key ] ) {
4792
			return;
4793
		}
4794
		color.fn[ key ] = function( value ) {
4795
			var vtype = jQuery.type( value ),
4796
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
4797
				local = this[ fn ](),
4798
				cur = local[ prop.idx ],
4799
				match;
4800
 
4801
			if ( vtype === "undefined" ) {
4802
				return cur;
4803
			}
4804
 
4805
			if ( vtype === "function" ) {
4806
				value = value.call( this, cur );
4807
				vtype = jQuery.type( value );
4808
			}
4809
			if ( value == null && prop.empty ) {
4810
				return this;
4811
			}
4812
			if ( vtype === "string" ) {
4813
				match = rplusequals.exec( value );
4814
				if ( match ) {
4815
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
4816
				}
4817
			}
4818
			local[ prop.idx ] = value;
4819
			return this[ fn ]( local );
4820
		};
4821
	});
4822
});
4823
 
4824
// add .fx.step functions
4825
each( stepHooks, function( i, hook ) {
4826
	jQuery.cssHooks[ hook ] = {
4827
		set: function( elem, value ) {
4828
			var parsed, curElem,
4829
				backgroundColor = "";
4830
 
4831
			if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
4832
				value = color( parsed || value );
4833
				if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
4834
					curElem = hook === "backgroundColor" ? elem.parentNode : elem;
4835
					while (
4836
						(backgroundColor === "" || backgroundColor === "transparent") &&
4837
						curElem && curElem.style
4838
					) {
4839
						try {
4840
							backgroundColor = jQuery.css( curElem, "backgroundColor" );
4841
							curElem = curElem.parentNode;
4842
						} catch ( e ) {
4843
						}
4844
					}
4845
 
4846
					value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
4847
						backgroundColor :
4848
						"_default" );
4849
				}
4850
 
4851
				value = value.toRgbaString();
4852
			}
4853
			try {
4854
				elem.style[ hook ] = value;
4855
			} catch( error ) {
4856
				// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
4857
			}
4858
		}
4859
	};
4860
	jQuery.fx.step[ hook ] = function( fx ) {
4861
		if ( !fx.colorInit ) {
4862
			fx.start = color( fx.elem, hook );
4863
			fx.end = color( fx.end );
4864
			fx.colorInit = true;
4865
		}
4866
		jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
4867
	};
4868
});
4869
 
4870
jQuery.cssHooks.borderColor = {
4871
	expand: function( value ) {
4872
		var expanded = {};
4873
 
4874
		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
4875
			expanded[ "border" + part + "Color" ] = value;
4876
		});
4877
		return expanded;
4878
	}
4879
};
4880
 
4881
// Basic color names only.
4882
// Usage of any of the other color names requires adding yourself or including
4883
// jquery.color.svg-names.js.
4884
colors = jQuery.Color.names = {
4885
	// 4.1. Basic color keywords
4886
	aqua: "#00ffff",
4887
	black: "#000000",
4888
	blue: "#0000ff",
4889
	fuchsia: "#ff00ff",
4890
	gray: "#808080",
4891
	green: "#008000",
4892
	lime: "#00ff00",
4893
	maroon: "#800000",
4894
	navy: "#000080",
4895
	olive: "#808000",
4896
	purple: "#800080",
4897
	red: "#ff0000",
4898
	silver: "#c0c0c0",
4899
	teal: "#008080",
4900
	white: "#ffffff",
4901
	yellow: "#ffff00",
4902
 
4903
	// 4.2.3. "transparent" color keyword
4904
	transparent: [ null, null, null, 0 ],
4905
 
4906
	_default: "#ffffff"
4907
};
4908
 
4909
})( jQuery );
4910
 
4911
 
4912
 
4913
/******************************************************************************/
4914
/****************************** CLASS ANIMATIONS ******************************/
4915
/******************************************************************************/
4916
(function() {
4917
 
4918
var classAnimationActions = [ "add", "remove", "toggle" ],
4919
	shorthandStyles = {
4920
		border: 1,
4921
		borderBottom: 1,
4922
		borderColor: 1,
4923
		borderLeft: 1,
4924
		borderRight: 1,
4925
		borderTop: 1,
4926
		borderWidth: 1,
4927
		margin: 1,
4928
		padding: 1
4929
	};
4930
 
4931
$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
4932
	$.fx.step[ prop ] = function( fx ) {
4933
		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
4934
			jQuery.style( fx.elem, prop, fx.end );
4935
			fx.setAttr = true;
4936
		}
4937
	};
4938
});
4939
 
4940
function getElementStyles() {
4941
	var style = this.ownerDocument.defaultView ?
4942
			this.ownerDocument.defaultView.getComputedStyle( this, null ) :
4943
			this.currentStyle,
4944
		newStyle = {},
4945
		key,
4946
		len;
4947
 
4948
	// webkit enumerates style porperties
4949
	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
4950
		len = style.length;
4951
		while ( len-- ) {
4952
			key = style[ len ];
4953
			if ( typeof style[ key ] === "string" ) {
4954
				newStyle[ $.camelCase( key ) ] = style[ key ];
4955
			}
4956
		}
4957
	} else {
4958
		for ( key in style ) {
4959
			if ( typeof style[ key ] === "string" ) {
4960
				newStyle[ key ] = style[ key ];
4961
			}
4962
		}
4963
	}
4964
 
4965
	return newStyle;
4966
}
4967
 
4968
 
4969
function styleDifference( oldStyle, newStyle ) {
4970
	var diff = {},
4971
		name, value;
4972
 
4973
	for ( name in newStyle ) {
4974
		value = newStyle[ name ];
4975
		if ( oldStyle[ name ] !== value ) {
4976
			if ( !shorthandStyles[ name ] ) {
4977
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
4978
					diff[ name ] = value;
4979
				}
4980
			}
4981
		}
4982
	}
4983
 
4984
	return diff;
4985
}
4986
 
4987
$.effects.animateClass = function( value, duration, easing, callback ) {
4988
	var o = $.speed( duration, easing, callback );
4989
 
4990
	return this.queue( function() {
4991
		var animated = $( this ),
4992
			baseClass = animated.attr( "class" ) || "",
4993
			applyClassChange,
4994
			allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
4995
 
4996
		// map the animated objects to store the original styles.
4997
		allAnimations = allAnimations.map(function() {
4998
			var el = $( this );
4999
			return {
5000
				el: el,
5001
				start: getElementStyles.call( this )
5002
			};
5003
		});
5004
 
5005
		// apply class change
5006
		applyClassChange = function() {
5007
			$.each( classAnimationActions, function(i, action) {
5008
				if ( value[ action ] ) {
5009
					animated[ action + "Class" ]( value[ action ] );
5010
				}
5011
			});
5012
		};
5013
		applyClassChange();
5014
 
5015
		// map all animated objects again - calculate new styles and diff
5016
		allAnimations = allAnimations.map(function() {
5017
			this.end = getElementStyles.call( this.el[ 0 ] );
5018
			this.diff = styleDifference( this.start, this.end );
5019
			return this;
5020
		});
5021
 
5022
		// apply original class
5023
		animated.attr( "class", baseClass );
5024
 
5025
		// map all animated objects again - this time collecting a promise
5026
		allAnimations = allAnimations.map(function() {
5027
			var styleInfo = this,
5028
				dfd = $.Deferred(),
5029
				opts = jQuery.extend({}, o, {
5030
					queue: false,
5031
					complete: function() {
5032
						dfd.resolve( styleInfo );
5033
					}
5034
				});
5035
 
5036
			this.el.animate( this.diff, opts );
5037
			return dfd.promise();
5038
		});
5039
 
5040
		// once all animations have completed:
5041
		$.when.apply( $, allAnimations.get() ).done(function() {
5042
 
5043
			// set the final class
5044
			applyClassChange();
5045
 
5046
			// for each animated element,
5047
			// clear all css properties that were animated
5048
			$.each( arguments, function() {
5049
				var el = this.el;
5050
				$.each( this.diff, function(key) {
5051
					el.css( key, '' );
5052
				});
5053
			});
5054
 
5055
			// this is guarnteed to be there if you use jQuery.speed()
5056
			// it also handles dequeuing the next anim...
5057
			o.complete.call( animated[ 0 ] );
5058
		});
5059
	});
5060
};
5061
 
5062
$.fn.extend({
5063
	_addClass: $.fn.addClass,
5064
	addClass: function( classNames, speed, easing, callback ) {
5065
		return speed ?
5066
			$.effects.animateClass.call( this,
5067
				{ add: classNames }, speed, easing, callback ) :
5068
			this._addClass( classNames );
5069
	},
5070
 
5071
	_removeClass: $.fn.removeClass,
5072
	removeClass: function( classNames, speed, easing, callback ) {
5073
		return speed ?
5074
			$.effects.animateClass.call( this,
5075
				{ remove: classNames }, speed, easing, callback ) :
5076
			this._removeClass( classNames );
5077
	},
5078
 
5079
	_toggleClass: $.fn.toggleClass,
5080
	toggleClass: function( classNames, force, speed, easing, callback ) {
5081
		if ( typeof force === "boolean" || force === undefined ) {
5082
			if ( !speed ) {
5083
				// without speed parameter
5084
				return this._toggleClass( classNames, force );
5085
			} else {
5086
				return $.effects.animateClass.call( this,
5087
					(force ? { add: classNames } : { remove: classNames }),
5088
					speed, easing, callback );
5089
			}
5090
		} else {
5091
			// without force parameter
5092
			return $.effects.animateClass.call( this,
5093
				{ toggle: classNames }, force, speed, easing );
5094
		}
5095
	},
5096
 
5097
	switchClass: function( remove, add, speed, easing, callback) {
5098
		return $.effects.animateClass.call( this, {
5099
			add: add,
5100
			remove: remove
5101
		}, speed, easing, callback );
5102
	}
5103
});
5104
 
5105
})();
5106
 
5107
/******************************************************************************/
5108
/*********************************** EFFECTS **********************************/
5109
/******************************************************************************/
5110
 
5111
(function() {
5112
 
5113
$.extend( $.effects, {
5114
	version: "1.9.2",
5115
 
5116
	// Saves a set of properties in a data storage
5117
	save: function( element, set ) {
5118
		for( var i=0; i < set.length; i++ ) {
5119
			if ( set[ i ] !== null ) {
5120
				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5121
			}
5122
		}
5123
	},
5124
 
5125
	// Restores a set of previously saved properties from a data storage
5126
	restore: function( element, set ) {
5127
		var val, i;
5128
		for( i=0; i < set.length; i++ ) {
5129
			if ( set[ i ] !== null ) {
5130
				val = element.data( dataSpace + set[ i ] );
5131
				// support: jQuery 1.6.2
5132
				// http://bugs.jquery.com/ticket/9917
5133
				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5134
				// We can't differentiate between "" and 0 here, so we just assume
5135
				// empty string since it's likely to be a more common value...
5136
				if ( val === undefined ) {
5137
					val = "";
5138
				}
5139
				element.css( set[ i ], val );
5140
			}
5141
		}
5142
	},
5143
 
5144
	setMode: function( el, mode ) {
5145
		if (mode === "toggle") {
5146
			mode = el.is( ":hidden" ) ? "show" : "hide";
5147
		}
5148
		return mode;
5149
	},
5150
 
5151
	// Translates a [top,left] array into a baseline value
5152
	// this should be a little more flexible in the future to handle a string & hash
5153
	getBaseline: function( origin, original ) {
5154
		var y, x;
5155
		switch ( origin[ 0 ] ) {
5156
			case "top": y = 0; break;
5157
			case "middle": y = 0.5; break;
5158
			case "bottom": y = 1; break;
5159
			default: y = origin[ 0 ] / original.height;
5160
		}
5161
		switch ( origin[ 1 ] ) {
5162
			case "left": x = 0; break;
5163
			case "center": x = 0.5; break;
5164
			case "right": x = 1; break;
5165
			default: x = origin[ 1 ] / original.width;
5166
		}
5167
		return {
5168
			x: x,
5169
			y: y
5170
		};
5171
	},
5172
 
5173
	// Wraps the element around a wrapper that copies position properties
5174
	createWrapper: function( element ) {
5175
 
5176
		// if the element is already wrapped, return it
5177
		if ( element.parent().is( ".ui-effects-wrapper" )) {
5178
			return element.parent();
5179
		}
5180
 
5181
		// wrap the element
5182
		var props = {
5183
				width: element.outerWidth(true),
5184
				height: element.outerHeight(true),
5185
				"float": element.css( "float" )
5186
			},
5187
			wrapper = $( "<div></div>" )
5188
				.addClass( "ui-effects-wrapper" )
5189
				.css({
5190
					fontSize: "100%",
5191
					background: "transparent",
5192
					border: "none",
5193
					margin: 0,
5194
					padding: 0
5195
				}),
5196
			// Store the size in case width/height are defined in % - Fixes #5245
5197
			size = {
5198
				width: element.width(),
5199
				height: element.height()
5200
			},
5201
			active = document.activeElement;
5202
 
5203
		// support: Firefox
5204
		// Firefox incorrectly exposes anonymous content
5205
		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5206
		try {
5207
			active.id;
5208
		} catch( e ) {
5209
			active = document.body;
5210
		}
5211
 
5212
		element.wrap( wrapper );
5213
 
5214
		// Fixes #7595 - Elements lose focus when wrapped.
5215
		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5216
			$( active ).focus();
5217
		}
5218
 
5219
		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5220
 
5221
		// transfer positioning properties to the wrapper
5222
		if ( element.css( "position" ) === "static" ) {
5223
			wrapper.css({ position: "relative" });
5224
			element.css({ position: "relative" });
5225
		} else {
5226
			$.extend( props, {
5227
				position: element.css( "position" ),
5228
				zIndex: element.css( "z-index" )
5229
			});
5230
			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5231
				props[ pos ] = element.css( pos );
5232
				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5233
					props[ pos ] = "auto";
5234
				}
5235
			});
5236
			element.css({
5237
				position: "relative",
5238
				top: 0,
5239
				left: 0,
5240
				right: "auto",
5241
				bottom: "auto"
5242
			});
5243
		}
5244
		element.css(size);
5245
 
5246
		return wrapper.css( props ).show();
5247
	},
5248
 
5249
	removeWrapper: function( element ) {
5250
		var active = document.activeElement;
5251
 
5252
		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5253
			element.parent().replaceWith( element );
5254
 
5255
			// Fixes #7595 - Elements lose focus when wrapped.
5256
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5257
				$( active ).focus();
5258
			}
5259
		}
5260
 
5261
 
5262
		return element;
5263
	},
5264
 
5265
	setTransition: function( element, list, factor, value ) {
5266
		value = value || {};
5267
		$.each( list, function( i, x ) {
5268
			var unit = element.cssUnit( x );
5269
			if ( unit[ 0 ] > 0 ) {
5270
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5271
			}
5272
		});
5273
		return value;
5274
	}
5275
});
5276
 
5277
// return an effect options object for the given parameters:
5278
function _normalizeArguments( effect, options, speed, callback ) {
5279
 
5280
	// allow passing all options as the first parameter
5281
	if ( $.isPlainObject( effect ) ) {
5282
		options = effect;
5283
		effect = effect.effect;
5284
	}
5285
 
5286
	// convert to an object
5287
	effect = { effect: effect };
5288
 
5289
	// catch (effect, null, ...)
5290
	if ( options == null ) {
5291
		options = {};
5292
	}
5293
 
5294
	// catch (effect, callback)
5295
	if ( $.isFunction( options ) ) {
5296
		callback = options;
5297
		speed = null;
5298
		options = {};
5299
	}
5300
 
5301
	// catch (effect, speed, ?)
5302
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5303
		callback = speed;
5304
		speed = options;
5305
		options = {};
5306
	}
5307
 
5308
	// catch (effect, options, callback)
5309
	if ( $.isFunction( speed ) ) {
5310
		callback = speed;
5311
		speed = null;
5312
	}
5313
 
5314
	// add options to effect
5315
	if ( options ) {
5316
		$.extend( effect, options );
5317
	}
5318
 
5319
	speed = speed || options.duration;
5320
	effect.duration = $.fx.off ? 0 :
5321
		typeof speed === "number" ? speed :
5322
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5323
		$.fx.speeds._default;
5324
 
5325
	effect.complete = callback || options.complete;
5326
 
5327
	return effect;
5328
}
5329
 
5330
function standardSpeed( speed ) {
5331
	// valid standard speeds
5332
	if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
5333
		return true;
5334
	}
5335
 
5336
	// invalid strings - treat as "normal" speed
5337
	if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
5338
		// TODO: remove in 2.0 (#7115)
5339
		if ( backCompat && $.effects[ speed ] ) {
5340
			return false;
5341
		}
5342
		return true;
5343
	}
5344
 
5345
	return false;
5346
}
5347
 
5348
$.fn.extend({
5349
	effect: function( /* effect, options, speed, callback */ ) {
5350
		var args = _normalizeArguments.apply( this, arguments ),
5351
			mode = args.mode,
5352
			queue = args.queue,
5353
			effectMethod = $.effects.effect[ args.effect ],
5354
 
5355
			// DEPRECATED: remove in 2.0 (#7115)
5356
			oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
5357
 
5358
		if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
5359
			// delegate to the original method (e.g., .show()) if possible
5360
			if ( mode ) {
5361
				return this[ mode ]( args.duration, args.complete );
5362
			} else {
5363
				return this.each( function() {
5364
					if ( args.complete ) {
5365
						args.complete.call( this );
5366
					}
5367
				});
5368
			}
5369
		}
5370
 
5371
		function run( next ) {
5372
			var elem = $( this ),
5373
				complete = args.complete,
5374
				mode = args.mode;
5375
 
5376
			function done() {
5377
				if ( $.isFunction( complete ) ) {
5378
					complete.call( elem[0] );
5379
				}
5380
				if ( $.isFunction( next ) ) {
5381
					next();
5382
				}
5383
			}
5384
 
5385
			// if the element is hiddden and mode is hide,
5386
			// or element is visible and mode is show
5387
			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5388
				done();
5389
			} else {
5390
				effectMethod.call( elem[0], args, done );
5391
			}
5392
		}
5393
 
5394
		// TODO: remove this check in 2.0, effectMethod will always be true
5395
		if ( effectMethod ) {
5396
			return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5397
		} else {
5398
			// DEPRECATED: remove in 2.0 (#7115)
5399
			return oldEffectMethod.call(this, {
5400
				options: args,
5401
				duration: args.duration,
5402
				callback: args.complete,
5403
				mode: args.mode
5404
			});
5405
		}
5406
	},
5407
 
5408
	_show: $.fn.show,
5409
	show: function( speed ) {
5410
		if ( standardSpeed( speed ) ) {
5411
			return this._show.apply( this, arguments );
5412
		} else {
5413
			var args = _normalizeArguments.apply( this, arguments );
5414
			args.mode = "show";
5415
			return this.effect.call( this, args );
5416
		}
5417
	},
5418
 
5419
	_hide: $.fn.hide,
5420
	hide: function( speed ) {
5421
		if ( standardSpeed( speed ) ) {
5422
			return this._hide.apply( this, arguments );
5423
		} else {
5424
			var args = _normalizeArguments.apply( this, arguments );
5425
			args.mode = "hide";
5426
			return this.effect.call( this, args );
5427
		}
5428
	},
5429
 
5430
	// jQuery core overloads toggle and creates _toggle
5431
	__toggle: $.fn.toggle,
5432
	toggle: function( speed ) {
5433
		if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
5434
			return this.__toggle.apply( this, arguments );
5435
		} else {
5436
			var args = _normalizeArguments.apply( this, arguments );
5437
			args.mode = "toggle";
5438
			return this.effect.call( this, args );
5439
		}
5440
	},
5441
 
5442
	// helper functions
5443
	cssUnit: function(key) {
5444
		var style = this.css( key ),
5445
			val = [];
5446
 
5447
		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
5448
			if ( style.indexOf( unit ) > 0 ) {
5449
				val = [ parseFloat( style ), unit ];
5450
			}
5451
		});
5452
		return val;
5453
	}
5454
});
5455
 
5456
})();
5457
 
5458
/******************************************************************************/
5459
/*********************************** EASING ***********************************/
5460
/******************************************************************************/
5461
 
5462
(function() {
5463
 
5464
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
5465
 
5466
var baseEasings = {};
5467
 
5468
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
5469
	baseEasings[ name ] = function( p ) {
5470
		return Math.pow( p, i + 2 );
5471
	};
5472
});
5473
 
5474
$.extend( baseEasings, {
5475
	Sine: function ( p ) {
5476
		return 1 - Math.cos( p * Math.PI / 2 );
5477
	},
5478
	Circ: function ( p ) {
5479
		return 1 - Math.sqrt( 1 - p * p );
5480
	},
5481
	Elastic: function( p ) {
5482
		return p === 0 || p === 1 ? p :
5483
			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
5484
	},
5485
	Back: function( p ) {
5486
		return p * p * ( 3 * p - 2 );
5487
	},
5488
	Bounce: function ( p ) {
5489
		var pow2,
5490
			bounce = 4;
5491
 
5492
		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
5493
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
5494
	}
5495
});
5496
 
5497
$.each( baseEasings, function( name, easeIn ) {
5498
	$.easing[ "easeIn" + name ] = easeIn;
5499
	$.easing[ "easeOut" + name ] = function( p ) {
5500
		return 1 - easeIn( 1 - p );
5501
	};
5502
	$.easing[ "easeInOut" + name ] = function( p ) {
5503
		return p < 0.5 ?
5504
			easeIn( p * 2 ) / 2 :
5505
			1 - easeIn( p * -2 + 2 ) / 2;
5506
	};
5507
});
5508
 
5509
})();
5510
 
5511
})(jQuery));
5512
 
5513
(function( $, undefined ) {
5514
 
5515
var uid = 0,
5516
	hideProps = {},
5517
	showProps = {};
5518
 
5519
hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
5520
	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
5521
showProps.height = showProps.paddingTop = showProps.paddingBottom =
5522
	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
5523
 
5524
$.widget( "ui.accordion", {
5525
	version: "1.9.2",
5526
	options: {
5527
		active: 0,
5528
		animate: {},
5529
		collapsible: false,
5530
		event: "click",
5531
		header: "> li > :first-child,> :not(li):even",
5532
		heightStyle: "auto",
5533
		icons: {
5534
			activeHeader: "ui-icon-triangle-1-s",
5535
			header: "ui-icon-triangle-1-e"
5536
		},
5537
 
5538
		// callbacks
5539
		activate: null,
5540
		beforeActivate: null
5541
	},
5542
 
5543
	_create: function() {
5544
		var accordionId = this.accordionId = "ui-accordion-" +
5545
				(this.element.attr( "id" ) || ++uid),
5546
			options = this.options;
5547
 
5548
		this.prevShow = this.prevHide = $();
5549
		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
5550
 
5551
		this.headers = this.element.find( options.header )
5552
			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
5553
		this._hoverable( this.headers );
5554
		this._focusable( this.headers );
5555
 
5556
		this.headers.next()
5557
			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
5558
			.hide();
5559
 
5560
		// don't allow collapsible: false and active: false / null
5561
		if ( !options.collapsible && (options.active === false || options.active == null) ) {
5562
			options.active = 0;
5563
		}
5564
		// handle negative values
5565
		if ( options.active < 0 ) {
5566
			options.active += this.headers.length;
5567
		}
5568
		this.active = this._findActive( options.active )
5569
			.addClass( "ui-accordion-header-active ui-state-active" )
5570
			.toggleClass( "ui-corner-all ui-corner-top" );
5571
		this.active.next()
5572
			.addClass( "ui-accordion-content-active" )
5573
			.show();
5574
 
5575
		this._createIcons();
5576
		this.refresh();
5577
 
5578
		// ARIA
5579
		this.element.attr( "role", "tablist" );
5580
 
5581
		this.headers
5582
			.attr( "role", "tab" )
5583
			.each(function( i ) {
5584
				var header = $( this ),
5585
					headerId = header.attr( "id" ),
5586
					panel = header.next(),
5587
					panelId = panel.attr( "id" );
5588
				if ( !headerId ) {
5589
					headerId = accordionId + "-header-" + i;
5590
					header.attr( "id", headerId );
5591
				}
5592
				if ( !panelId ) {
5593
					panelId = accordionId + "-panel-" + i;
5594
					panel.attr( "id", panelId );
5595
				}
5596
				header.attr( "aria-controls", panelId );
5597
				panel.attr( "aria-labelledby", headerId );
5598
			})
5599
			.next()
5600
				.attr( "role", "tabpanel" );
5601
 
5602
		this.headers
5603
			.not( this.active )
5604
			.attr({
5605
				"aria-selected": "false",
5606
				tabIndex: -1
5607
			})
5608
			.next()
5609
				.attr({
5610
					"aria-expanded": "false",
5611
					"aria-hidden": "true"
5612
				})
5613
				.hide();
5614
 
5615
		// make sure at least one header is in the tab order
5616
		if ( !this.active.length ) {
5617
			this.headers.eq( 0 ).attr( "tabIndex", 0 );
5618
		} else {
5619
			this.active.attr({
5620
				"aria-selected": "true",
5621
				tabIndex: 0
5622
			})
5623
			.next()
5624
				.attr({
5625
					"aria-expanded": "true",
5626
					"aria-hidden": "false"
5627
				});
5628
		}
5629
 
5630
		this._on( this.headers, { keydown: "_keydown" });
5631
		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
5632
		this._setupEvents( options.event );
5633
	},
5634
 
5635
	_getCreateEventData: function() {
5636
		return {
5637
			header: this.active,
5638
			content: !this.active.length ? $() : this.active.next()
5639
		};
5640
	},
5641
 
5642
	_createIcons: function() {
5643
		var icons = this.options.icons;
5644
		if ( icons ) {
5645
			$( "<span>" )
5646
				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5647
				.prependTo( this.headers );
5648
			this.active.children( ".ui-accordion-header-icon" )
5649
				.removeClass( icons.header )
5650
				.addClass( icons.activeHeader );
5651
			this.headers.addClass( "ui-accordion-icons" );
5652
		}
5653
	},
5654
 
5655
	_destroyIcons: function() {
5656
		this.headers
5657
			.removeClass( "ui-accordion-icons" )
5658
			.children( ".ui-accordion-header-icon" )
5659
				.remove();
5660
	},
5661
 
5662
	_destroy: function() {
5663
		var contents;
5664
 
5665
		// clean up main element
5666
		this.element
5667
			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
5668
			.removeAttr( "role" );
5669
 
5670
		// clean up headers
5671
		this.headers
5672
			.removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5673
			.removeAttr( "role" )
5674
			.removeAttr( "aria-selected" )
5675
			.removeAttr( "aria-controls" )
5676
			.removeAttr( "tabIndex" )
5677
			.each(function() {
5678
				if ( /^ui-accordion/.test( this.id ) ) {
5679
					this.removeAttribute( "id" );
5680
				}
5681
			});
5682
		this._destroyIcons();
5683
 
5684
		// clean up content panels
5685
		contents = this.headers.next()
5686
			.css( "display", "" )
5687
			.removeAttr( "role" )
5688
			.removeAttr( "aria-expanded" )
5689
			.removeAttr( "aria-hidden" )
5690
			.removeAttr( "aria-labelledby" )
5691
			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5692
			.each(function() {
5693
				if ( /^ui-accordion/.test( this.id ) ) {
5694
					this.removeAttribute( "id" );
5695
				}
5696
			});
5697
		if ( this.options.heightStyle !== "content" ) {
5698
			contents.css( "height", "" );
5699
		}
5700
	},
5701
 
5702
	_setOption: function( key, value ) {
5703
		if ( key === "active" ) {
5704
			// _activate() will handle invalid values and update this.options
5705
			this._activate( value );
5706
			return;
5707
		}
5708
 
5709
		if ( key === "event" ) {
5710
			if ( this.options.event ) {
5711
				this._off( this.headers, this.options.event );
5712
			}
5713
			this._setupEvents( value );
5714
		}
5715
 
5716
		this._super( key, value );
5717
 
5718
		// setting collapsible: false while collapsed; open first panel
5719
		if ( key === "collapsible" && !value && this.options.active === false ) {
5720
			this._activate( 0 );
5721
		}
5722
 
5723
		if ( key === "icons" ) {
5724
			this._destroyIcons();
5725
			if ( value ) {
5726
				this._createIcons();
5727
			}
5728
		}
5729
 
5730
		// #5332 - opacity doesn't cascade to positioned elements in IE
5731
		// so we need to add the disabled class to the headers and panels
5732
		if ( key === "disabled" ) {
5733
			this.headers.add( this.headers.next() )
5734
				.toggleClass( "ui-state-disabled", !!value );
5735
		}
5736
	},
5737
 
5738
	_keydown: function( event ) {
5739
		if ( event.altKey || event.ctrlKey ) {
5740
			return;
5741
		}
5742
 
5743
		var keyCode = $.ui.keyCode,
5744
			length = this.headers.length,
5745
			currentIndex = this.headers.index( event.target ),
5746
			toFocus = false;
5747
 
5748
		switch ( event.keyCode ) {
5749
			case keyCode.RIGHT:
5750
			case keyCode.DOWN:
5751
				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5752
				break;
5753
			case keyCode.LEFT:
5754
			case keyCode.UP:
5755
				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5756
				break;
5757
			case keyCode.SPACE:
5758
			case keyCode.ENTER:
5759
				this._eventHandler( event );
5760
				break;
5761
			case keyCode.HOME:
5762
				toFocus = this.headers[ 0 ];
5763
				break;
5764
			case keyCode.END:
5765
				toFocus = this.headers[ length - 1 ];
5766
				break;
5767
		}
5768
 
5769
		if ( toFocus ) {
5770
			$( event.target ).attr( "tabIndex", -1 );
5771
			$( toFocus ).attr( "tabIndex", 0 );
5772
			toFocus.focus();
5773
			event.preventDefault();
5774
		}
5775
	},
5776
 
5777
	_panelKeyDown : function( event ) {
5778
		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5779
			$( event.currentTarget ).prev().focus();
5780
		}
5781
	},
5782
 
5783
	refresh: function() {
5784
		var maxHeight, overflow,
5785
			heightStyle = this.options.heightStyle,
5786
			parent = this.element.parent();
5787
 
5788
 
5789
		if ( heightStyle === "fill" ) {
5790
			// IE 6 treats height like minHeight, so we need to turn off overflow
5791
			// in order to get a reliable height
5792
			// we use the minHeight support test because we assume that only
5793
			// browsers that don't support minHeight will treat height as minHeight
5794
			if ( !$.support.minHeight ) {
5795
				overflow = parent.css( "overflow" );
5796
				parent.css( "overflow", "hidden");
5797
			}
5798
			maxHeight = parent.height();
5799
			this.element.siblings( ":visible" ).each(function() {
5800
				var elem = $( this ),
5801
					position = elem.css( "position" );
5802
 
5803
				if ( position === "absolute" || position === "fixed" ) {
5804
					return;
5805
				}
5806
				maxHeight -= elem.outerHeight( true );
5807
			});
5808
			if ( overflow ) {
5809
				parent.css( "overflow", overflow );
5810
			}
5811
 
5812
			this.headers.each(function() {
5813
				maxHeight -= $( this ).outerHeight( true );
5814
			});
5815
 
5816
			this.headers.next()
5817
				.each(function() {
5818
					$( this ).height( Math.max( 0, maxHeight -
5819
						$( this ).innerHeight() + $( this ).height() ) );
5820
				})
5821
				.css( "overflow", "auto" );
5822
		} else if ( heightStyle === "auto" ) {
5823
			maxHeight = 0;
5824
			this.headers.next()
5825
				.each(function() {
5826
					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5827
				})
5828
				.height( maxHeight );
5829
		}
5830
	},
5831
 
5832
	_activate: function( index ) {
5833
		var active = this._findActive( index )[ 0 ];
5834
 
5835
		// trying to activate the already active panel
5836
		if ( active === this.active[ 0 ] ) {
5837
			return;
5838
		}
5839
 
5840
		// trying to collapse, simulate a click on the currently active header
5841
		active = active || this.active[ 0 ];
5842
 
5843
		this._eventHandler({
5844
			target: active,
5845
			currentTarget: active,
5846
			preventDefault: $.noop
5847
		});
5848
	},
5849
 
5850
	_findActive: function( selector ) {
5851
		return typeof selector === "number" ? this.headers.eq( selector ) : $();
5852
	},
5853
 
5854
	_setupEvents: function( event ) {
5855
		var events = {};
5856
		if ( !event ) {
5857
			return;
5858
		}
5859
		$.each( event.split(" "), function( index, eventName ) {
5860
			events[ eventName ] = "_eventHandler";
5861
		});
5862
		this._on( this.headers, events );
5863
	},
5864
 
5865
	_eventHandler: function( event ) {
5866
		var options = this.options,
5867
			active = this.active,
5868
			clicked = $( event.currentTarget ),
5869
			clickedIsActive = clicked[ 0 ] === active[ 0 ],
5870
			collapsing = clickedIsActive && options.collapsible,
5871
			toShow = collapsing ? $() : clicked.next(),
5872
			toHide = active.next(),
5873
			eventData = {
5874
				oldHeader: active,
5875
				oldPanel: toHide,
5876
				newHeader: collapsing ? $() : clicked,
5877
				newPanel: toShow
5878
			};
5879
 
5880
		event.preventDefault();
5881
 
5882
		if (
5883
				// click on active header, but not collapsible
5884
				( clickedIsActive && !options.collapsible ) ||
5885
				// allow canceling activation
5886
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5887
			return;
5888
		}
5889
 
5890
		options.active = collapsing ? false : this.headers.index( clicked );
5891
 
5892
		// when the call to ._toggle() comes after the class changes
5893
		// it causes a very odd bug in IE 8 (see #6720)
5894
		this.active = clickedIsActive ? $() : clicked;
5895
		this._toggle( eventData );
5896
 
5897
		// switch classes
5898
		// corner classes on the previously active header stay after the animation
5899
		active.removeClass( "ui-accordion-header-active ui-state-active" );
5900
		if ( options.icons ) {
5901
			active.children( ".ui-accordion-header-icon" )
5902
				.removeClass( options.icons.activeHeader )
5903
				.addClass( options.icons.header );
5904
		}
5905
 
5906
		if ( !clickedIsActive ) {
5907
			clicked
5908
				.removeClass( "ui-corner-all" )
5909
				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5910
			if ( options.icons ) {
5911
				clicked.children( ".ui-accordion-header-icon" )
5912
					.removeClass( options.icons.header )
5913
					.addClass( options.icons.activeHeader );
5914
			}
5915
 
5916
			clicked
5917
				.next()
5918
				.addClass( "ui-accordion-content-active" );
5919
		}
5920
	},
5921
 
5922
	_toggle: function( data ) {
5923
		var toShow = data.newPanel,
5924
			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5925
 
5926
		// handle activating a panel during the animation for another activation
5927
		this.prevShow.add( this.prevHide ).stop( true, true );
5928
		this.prevShow = toShow;
5929
		this.prevHide = toHide;
5930
 
5931
		if ( this.options.animate ) {
5932
			this._animate( toShow, toHide, data );
5933
		} else {
5934
			toHide.hide();
5935
			toShow.show();
5936
			this._toggleComplete( data );
5937
		}
5938
 
5939
		toHide.attr({
5940
			"aria-expanded": "false",
5941
			"aria-hidden": "true"
5942
		});
5943
		toHide.prev().attr( "aria-selected", "false" );
5944
		// if we're switching panels, remove the old header from the tab order
5945
		// if we're opening from collapsed state, remove the previous header from the tab order
5946
		// if we're collapsing, then keep the collapsing header in the tab order
5947
		if ( toShow.length && toHide.length ) {
5948
			toHide.prev().attr( "tabIndex", -1 );
5949
		} else if ( toShow.length ) {
5950
			this.headers.filter(function() {
5951
				return $( this ).attr( "tabIndex" ) === 0;
5952
			})
5953
			.attr( "tabIndex", -1 );
5954
		}
5955
 
5956
		toShow
5957
			.attr({
5958
				"aria-expanded": "true",
5959
				"aria-hidden": "false"
5960
			})
5961
			.prev()
5962
				.attr({
5963
					"aria-selected": "true",
5964
					tabIndex: 0
5965
				});
5966
	},
5967
 
5968
	_animate: function( toShow, toHide, data ) {
5969
		var total, easing, duration,
5970
			that = this,
5971
			adjust = 0,
5972
			down = toShow.length &&
5973
				( !toHide.length || ( toShow.index() < toHide.index() ) ),
5974
			animate = this.options.animate || {},
5975
			options = down && animate.down || animate,
5976
			complete = function() {
5977
				that._toggleComplete( data );
5978
			};
5979
 
5980
		if ( typeof options === "number" ) {
5981
			duration = options;
5982
		}
5983
		if ( typeof options === "string" ) {
5984
			easing = options;
5985
		}
5986
		// fall back from options to animation in case of partial down settings
5987
		easing = easing || options.easing || animate.easing;
5988
		duration = duration || options.duration || animate.duration;
5989
 
5990
		if ( !toHide.length ) {
5991
			return toShow.animate( showProps, duration, easing, complete );
5992
		}
5993
		if ( !toShow.length ) {
5994
			return toHide.animate( hideProps, duration, easing, complete );
5995
		}
5996
 
5997
		total = toShow.show().outerHeight();
5998
		toHide.animate( hideProps, {
5999
			duration: duration,
6000
			easing: easing,
6001
			step: function( now, fx ) {
6002
				fx.now = Math.round( now );
6003
			}
6004
		});
6005
		toShow
6006
			.hide()
6007
			.animate( showProps, {
6008
				duration: duration,
6009
				easing: easing,
6010
				complete: complete,
6011
				step: function( now, fx ) {
6012
					fx.now = Math.round( now );
6013
					if ( fx.prop !== "height" ) {
6014
						adjust += fx.now;
6015
					} else if ( that.options.heightStyle !== "content" ) {
6016
						fx.now = Math.round( total - toHide.outerHeight() - adjust );
6017
						adjust = 0;
6018
					}
6019
				}
6020
			});
6021
	},
6022
 
6023
	_toggleComplete: function( data ) {
6024
		var toHide = data.oldPanel;
6025
 
6026
		toHide
6027
			.removeClass( "ui-accordion-content-active" )
6028
			.prev()
6029
				.removeClass( "ui-corner-top" )
6030
				.addClass( "ui-corner-all" );
6031
 
6032
		// Work around for rendering bug in IE (#5421)
6033
		if ( toHide.length ) {
6034
			toHide.parent()[0].className = toHide.parent()[0].className;
6035
		}
6036
 
6037
		this._trigger( "activate", null, data );
6038
	}
6039
});
6040
 
6041
 
6042
 
6043
// DEPRECATED
6044
if ( $.uiBackCompat !== false ) {
6045
	// navigation options
6046
	(function( $, prototype ) {
6047
		$.extend( prototype.options, {
6048
			navigation: false,
6049
			navigationFilter: function() {
6050
				return this.href.toLowerCase() === location.href.toLowerCase();
6051
			}
6052
		});
6053
 
6054
		var _create = prototype._create;
6055
		prototype._create = function() {
6056
			if ( this.options.navigation ) {
6057
				var that = this,
6058
					headers = this.element.find( this.options.header ),
6059
					content = headers.next(),
6060
					current = headers.add( content )
6061
						.find( "a" )
6062
						.filter( this.options.navigationFilter )
6063
						[ 0 ];
6064
				if ( current ) {
6065
					headers.add( content ).each( function( index ) {
6066
						if ( $.contains( this, current ) ) {
6067
							that.options.active = Math.floor( index / 2 );
6068
							return false;
6069
						}
6070
					});
6071
				}
6072
			}
6073
			_create.call( this );
6074
		};
6075
	}( jQuery, jQuery.ui.accordion.prototype ) );
6076
 
6077
	// height options
6078
	(function( $, prototype ) {
6079
		$.extend( prototype.options, {
6080
			heightStyle: null, // remove default so we fall back to old values
6081
			autoHeight: true, // use heightStyle: "auto"
6082
			clearStyle: false, // use heightStyle: "content"
6083
			fillSpace: false // use heightStyle: "fill"
6084
		});
6085
 
6086
		var _create = prototype._create,
6087
			_setOption = prototype._setOption;
6088
 
6089
		$.extend( prototype, {
6090
			_create: function() {
6091
				this.options.heightStyle = this.options.heightStyle ||
6092
					this._mergeHeightStyle();
6093
 
6094
				_create.call( this );
6095
			},
6096
 
6097
			_setOption: function( key ) {
6098
				if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
6099
					this.options.heightStyle = this._mergeHeightStyle();
6100
				}
6101
				_setOption.apply( this, arguments );
6102
			},
6103
 
6104
			_mergeHeightStyle: function() {
6105
				var options = this.options;
6106
 
6107
				if ( options.fillSpace ) {
6108
					return "fill";
6109
				}
6110
 
6111
				if ( options.clearStyle ) {
6112
					return "content";
6113
				}
6114
 
6115
				if ( options.autoHeight ) {
6116
					return "auto";
6117
				}
6118
			}
6119
		});
6120
	}( jQuery, jQuery.ui.accordion.prototype ) );
6121
 
6122
	// icon options
6123
	(function( $, prototype ) {
6124
		$.extend( prototype.options.icons, {
6125
			activeHeader: null, // remove default so we fall back to old values
6126
			headerSelected: "ui-icon-triangle-1-s"
6127
		});
6128
 
6129
		var _createIcons = prototype._createIcons;
6130
		prototype._createIcons = function() {
6131
			if ( this.options.icons ) {
6132
				this.options.icons.activeHeader = this.options.icons.activeHeader ||
6133
					this.options.icons.headerSelected;
6134
			}
6135
			_createIcons.call( this );
6136
		};
6137
	}( jQuery, jQuery.ui.accordion.prototype ) );
6138
 
6139
	// expanded active option, activate method
6140
	(function( $, prototype ) {
6141
		prototype.activate = prototype._activate;
6142
 
6143
		var _findActive = prototype._findActive;
6144
		prototype._findActive = function( index ) {
6145
			if ( index === -1 ) {
6146
				index = false;
6147
			}
6148
			if ( index && typeof index !== "number" ) {
6149
				index = this.headers.index( this.headers.filter( index ) );
6150
				if ( index === -1 ) {
6151
					index = false;
6152
				}
6153
			}
6154
			return _findActive.call( this, index );
6155
		};
6156
	}( jQuery, jQuery.ui.accordion.prototype ) );
6157
 
6158
	// resize method
6159
	jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
6160
 
6161
	// change events
6162
	(function( $, prototype ) {
6163
		$.extend( prototype.options, {
6164
			change: null,
6165
			changestart: null
6166
		});
6167
 
6168
		var _trigger = prototype._trigger;
6169
		prototype._trigger = function( type, event, data ) {
6170
			var ret = _trigger.apply( this, arguments );
6171
			if ( !ret ) {
6172
				return false;
6173
			}
6174
 
6175
			if ( type === "beforeActivate" ) {
6176
				ret = _trigger.call( this, "changestart", event, {
6177
					oldHeader: data.oldHeader,
6178
					oldContent: data.oldPanel,
6179
					newHeader: data.newHeader,
6180
					newContent: data.newPanel
6181
				});
6182
			} else if ( type === "activate" ) {
6183
				ret = _trigger.call( this, "change", event, {
6184
					oldHeader: data.oldHeader,
6185
					oldContent: data.oldPanel,
6186
					newHeader: data.newHeader,
6187
					newContent: data.newPanel
6188
				});
6189
			}
6190
			return ret;
6191
		};
6192
	}( jQuery, jQuery.ui.accordion.prototype ) );
6193
 
6194
	// animated option
6195
	// NOTE: this only provides support for "slide", "bounceslide", and easings
6196
	// not the full $.ui.accordion.animations API
6197
	(function( $, prototype ) {
6198
		$.extend( prototype.options, {
6199
			animate: null,
6200
			animated: "slide"
6201
		});
6202
 
6203
		var _create = prototype._create;
6204
		prototype._create = function() {
6205
			var options = this.options;
6206
			if ( options.animate === null ) {
6207
				if ( !options.animated ) {
6208
					options.animate = false;
6209
				} else if ( options.animated === "slide" ) {
6210
					options.animate = 300;
6211
				} else if ( options.animated === "bounceslide" ) {
6212
					options.animate = {
6213
						duration: 200,
6214
						down: {
6215
							easing: "easeOutBounce",
6216
							duration: 1000
6217
						}
6218
					};
6219
				} else {
6220
					options.animate = options.animated;
6221
				}
6222
			}
6223
 
6224
			_create.call( this );
6225
		};
6226
	}( jQuery, jQuery.ui.accordion.prototype ) );
6227
}
6228
 
6229
})( jQuery );
6230
 
6231
(function( $, undefined ) {
6232
 
6233
// used to prevent race conditions with remote data sources
6234
var requestIndex = 0;
6235
 
6236
$.widget( "ui.autocomplete", {
6237
	version: "1.9.2",
6238
	defaultElement: "<input>",
6239
	options: {
6240
		appendTo: "body",
6241
		autoFocus: false,
6242
		delay: 300,
6243
		minLength: 1,
6244
		position: {
6245
			my: "left top",
6246
			at: "left bottom",
6247
			collision: "none"
6248
		},
6249
		source: null,
6250
 
6251
		// callbacks
6252
		change: null,
6253
		close: null,
6254
		focus: null,
6255
		open: null,
6256
		response: null,
6257
		search: null,
6258
		select: null
6259
	},
6260
 
6261
	pending: 0,
6262
 
6263
	_create: function() {
6264
		// Some browsers only repeat keydown events, not keypress events,
6265
		// so we use the suppressKeyPress flag to determine if we've already
6266
		// handled the keydown event. #7269
6267
		// Unfortunately the code for & in keypress is the same as the up arrow,
6268
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
6269
		// events when we know the keydown event was used to modify the
6270
		// search term. #7799
6271
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
6272
 
6273
		this.isMultiLine = this._isMultiLine();
6274
		this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
6275
		this.isNewMenu = true;
6276
 
6277
		this.element
6278
			.addClass( "ui-autocomplete-input" )
6279
			.attr( "autocomplete", "off" );
6280
 
6281
		this._on( this.element, {
6282
			keydown: function( event ) {
6283
				if ( this.element.prop( "readOnly" ) ) {
6284
					suppressKeyPress = true;
6285
					suppressInput = true;
6286
					suppressKeyPressRepeat = true;
6287
					return;
6288
				}
6289
 
6290
				suppressKeyPress = false;
6291
				suppressInput = false;
6292
				suppressKeyPressRepeat = false;
6293
				var keyCode = $.ui.keyCode;
6294
				switch( event.keyCode ) {
6295
				case keyCode.PAGE_UP:
6296
					suppressKeyPress = true;
6297
					this._move( "previousPage", event );
6298
					break;
6299
				case keyCode.PAGE_DOWN:
6300
					suppressKeyPress = true;
6301
					this._move( "nextPage", event );
6302
					break;
6303
				case keyCode.UP:
6304
					suppressKeyPress = true;
6305
					this._keyEvent( "previous", event );
6306
					break;
6307
				case keyCode.DOWN:
6308
					suppressKeyPress = true;
6309
					this._keyEvent( "next", event );
6310
					break;
6311
				case keyCode.ENTER:
6312
				case keyCode.NUMPAD_ENTER:
6313
					// when menu is open and has focus
6314
					if ( this.menu.active ) {
6315
						// #6055 - Opera still allows the keypress to occur
6316
						// which causes forms to submit
6317
						suppressKeyPress = true;
6318
						event.preventDefault();
6319
						this.menu.select( event );
6320
					}
6321
					break;
6322
				case keyCode.TAB:
6323
					if ( this.menu.active ) {
6324
						this.menu.select( event );
6325
					}
6326
					break;
6327
				case keyCode.ESCAPE:
6328
					if ( this.menu.element.is( ":visible" ) ) {
6329
						this._value( this.term );
6330
						this.close( event );
6331
						// Different browsers have different default behavior for escape
6332
						// Single press can mean undo or clear
6333
						// Double press in IE means clear the whole form
6334
						event.preventDefault();
6335
					}
6336
					break;
6337
				default:
6338
					suppressKeyPressRepeat = true;
6339
					// search timeout should be triggered before the input value is changed
6340
					this._searchTimeout( event );
6341
					break;
6342
				}
6343
			},
6344
			keypress: function( event ) {
6345
				if ( suppressKeyPress ) {
6346
					suppressKeyPress = false;
6347
					event.preventDefault();
6348
					return;
6349
				}
6350
				if ( suppressKeyPressRepeat ) {
6351
					return;
6352
				}
6353
 
6354
				// replicate some key handlers to allow them to repeat in Firefox and Opera
6355
				var keyCode = $.ui.keyCode;
6356
				switch( event.keyCode ) {
6357
				case keyCode.PAGE_UP:
6358
					this._move( "previousPage", event );
6359
					break;
6360
				case keyCode.PAGE_DOWN:
6361
					this._move( "nextPage", event );
6362
					break;
6363
				case keyCode.UP:
6364
					this._keyEvent( "previous", event );
6365
					break;
6366
				case keyCode.DOWN:
6367
					this._keyEvent( "next", event );
6368
					break;
6369
				}
6370
			},
6371
			input: function( event ) {
6372
				if ( suppressInput ) {
6373
					suppressInput = false;
6374
					event.preventDefault();
6375
					return;
6376
				}
6377
				this._searchTimeout( event );
6378
			},
6379
			focus: function() {
6380
				this.selectedItem = null;
6381
				this.previous = this._value();
6382
			},
6383
			blur: function( event ) {
6384
				if ( this.cancelBlur ) {
6385
					delete this.cancelBlur;
6386
					return;
6387
				}
6388
 
6389
				clearTimeout( this.searching );
6390
				this.close( event );
6391
				this._change( event );
6392
			}
6393
		});
6394
 
6395
		this._initSource();
6396
		this.menu = $( "<ul>" )
6397
			.addClass( "ui-autocomplete" )
6398
			.appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
6399
			.menu({
6400
				// custom key handling for now
6401
				input: $(),
6402
				// disable ARIA support, the live region takes care of that
6403
				role: null
6404
			})
6405
			.zIndex( this.element.zIndex() + 1 )
6406
			.hide()
6407
			.data( "menu" );
6408
 
6409
		this._on( this.menu.element, {
6410
			mousedown: function( event ) {
6411
				// prevent moving focus out of the text field
6412
				event.preventDefault();
6413
 
6414
				// IE doesn't prevent moving focus even with event.preventDefault()
6415
				// so we set a flag to know when we should ignore the blur event
6416
				this.cancelBlur = true;
6417
				this._delay(function() {
6418
					delete this.cancelBlur;
6419
				});
6420
 
6421
				// clicking on the scrollbar causes focus to shift to the body
6422
				// but we can't detect a mouseup or a click immediately afterward
6423
				// so we have to track the next mousedown and close the menu if
6424
				// the user clicks somewhere outside of the autocomplete
6425
				var menuElement = this.menu.element[ 0 ];
6426
				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6427
					this._delay(function() {
6428
						var that = this;
6429
						this.document.one( "mousedown", function( event ) {
6430
							if ( event.target !== that.element[ 0 ] &&
6431
									event.target !== menuElement &&
6432
									!$.contains( menuElement, event.target ) ) {
6433
								that.close();
6434
							}
6435
						});
6436
					});
6437
				}
6438
			},
6439
			menufocus: function( event, ui ) {
6440
				// #7024 - Prevent accidental activation of menu items in Firefox
6441
				if ( this.isNewMenu ) {
6442
					this.isNewMenu = false;
6443
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6444
						this.menu.blur();
6445
 
6446
						this.document.one( "mousemove", function() {
6447
							$( event.target ).trigger( event.originalEvent );
6448
						});
6449
 
6450
						return;
6451
					}
6452
				}
6453
 
6454
				// back compat for _renderItem using item.autocomplete, via #7810
6455
				// TODO remove the fallback, see #8156
6456
				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
6457
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6458
					// use value to match what will end up in the input, if it was a key event
6459
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6460
						this._value( item.value );
6461
					}
6462
				} else {
6463
					// Normally the input is populated with the item's value as the
6464
					// menu is navigated, causing screen readers to notice a change and
6465
					// announce the item. Since the focus event was canceled, this doesn't
6466
					// happen, so we update the live region so that screen readers can
6467
					// still notice the change and announce it.
6468
					this.liveRegion.text( item.value );
6469
				}
6470
			},
6471
			menuselect: function( event, ui ) {
6472
				// back compat for _renderItem using item.autocomplete, via #7810
6473
				// TODO remove the fallback, see #8156
6474
				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
6475
					previous = this.previous;
6476
 
6477
				// only trigger when focus was lost (click on menu)
6478
				if ( this.element[0] !== this.document[0].activeElement ) {
6479
					this.element.focus();
6480
					this.previous = previous;
6481
					// #6109 - IE triggers two focus events and the second
6482
					// is asynchronous, so we need to reset the previous
6483
					// term synchronously and asynchronously :-(
6484
					this._delay(function() {
6485
						this.previous = previous;
6486
						this.selectedItem = item;
6487
					});
6488
				}
6489
 
6490
				if ( false !== this._trigger( "select", event, { item: item } ) ) {
6491
					this._value( item.value );
6492
				}
6493
				// reset the term after the select event
6494
				// this allows custom select handling to work properly
6495
				this.term = this._value();
6496
 
6497
				this.close( event );
6498
				this.selectedItem = item;
6499
			}
6500
		});
6501
 
6502
		this.liveRegion = $( "<span>", {
6503
				role: "status",
6504
				"aria-live": "polite"
6505
			})
6506
			.addClass( "ui-helper-hidden-accessible" )
6507
			.insertAfter( this.element );
6508
 
6509
		if ( $.fn.bgiframe ) {
6510
			this.menu.element.bgiframe();
6511
		}
6512
 
6513
		// turning off autocomplete prevents the browser from remembering the
6514
		// value when navigating through history, so we re-enable autocomplete
6515
		// if the page is unloaded before the widget is destroyed. #7790
6516
		this._on( this.window, {
6517
			beforeunload: function() {
6518
				this.element.removeAttr( "autocomplete" );
6519
			}
6520
		});
6521
	},
6522
 
6523
	_destroy: function() {
6524
		clearTimeout( this.searching );
6525
		this.element
6526
			.removeClass( "ui-autocomplete-input" )
6527
			.removeAttr( "autocomplete" );
6528
		this.menu.element.remove();
6529
		this.liveRegion.remove();
6530
	},
6531
 
6532
	_setOption: function( key, value ) {
6533
		this._super( key, value );
6534
		if ( key === "source" ) {
6535
			this._initSource();
6536
		}
6537
		if ( key === "appendTo" ) {
6538
			this.menu.element.appendTo( this.document.find( value || "body" )[0] );
6539
		}
6540
		if ( key === "disabled" && value && this.xhr ) {
6541
			this.xhr.abort();
6542
		}
6543
	},
6544
 
6545
	_isMultiLine: function() {
6546
		// Textareas are always multi-line
6547
		if ( this.element.is( "textarea" ) ) {
6548
			return true;
6549
		}
6550
		// Inputs are always single-line, even if inside a contentEditable element
6551
		// IE also treats inputs as contentEditable
6552
		if ( this.element.is( "input" ) ) {
6553
			return false;
6554
		}
6555
		// All other element types are determined by whether or not they're contentEditable
6556
		return this.element.prop( "isContentEditable" );
6557
	},
6558
 
6559
	_initSource: function() {
6560
		var array, url,
6561
			that = this;
6562
		if ( $.isArray(this.options.source) ) {
6563
			array = this.options.source;
6564
			this.source = function( request, response ) {
6565
				response( $.ui.autocomplete.filter( array, request.term ) );
6566
			};
6567
		} else if ( typeof this.options.source === "string" ) {
6568
			url = this.options.source;
6569
			this.source = function( request, response ) {
6570
				if ( that.xhr ) {
6571
					that.xhr.abort();
6572
				}
6573
				that.xhr = $.ajax({
6574
					url: url,
6575
					data: request,
6576
					dataType: "json",
6577
					success: function( data ) {
6578
						response( data );
6579
					},
6580
					error: function() {
6581
						response( [] );
6582
					}
6583
				});
6584
			};
6585
		} else {
6586
			this.source = this.options.source;
6587
		}
6588
	},
6589
 
6590
	_searchTimeout: function( event ) {
6591
		clearTimeout( this.searching );
6592
		this.searching = this._delay(function() {
6593
			// only search if the value has changed
6594
			if ( this.term !== this._value() ) {
6595
				this.selectedItem = null;
6596
				this.search( null, event );
6597
			}
6598
		}, this.options.delay );
6599
	},
6600
 
6601
	search: function( value, event ) {
6602
		value = value != null ? value : this._value();
6603
 
6604
		// always save the actual value, not the one passed as an argument
6605
		this.term = this._value();
6606
 
6607
		if ( value.length < this.options.minLength ) {
6608
			return this.close( event );
6609
		}
6610
 
6611
		if ( this._trigger( "search", event ) === false ) {
6612
			return;
6613
		}
6614
 
6615
		return this._search( value );
6616
	},
6617
 
6618
	_search: function( value ) {
6619
		this.pending++;
6620
		this.element.addClass( "ui-autocomplete-loading" );
6621
		this.cancelSearch = false;
6622
 
6623
		this.source( { term: value }, this._response() );
6624
	},
6625
 
6626
	_response: function() {
6627
		var that = this,
6628
			index = ++requestIndex;
6629
 
6630
		return function( content ) {
6631
			if ( index === requestIndex ) {
6632
				that.__response( content );
6633
			}
6634
 
6635
			that.pending--;
6636
			if ( !that.pending ) {
6637
				that.element.removeClass( "ui-autocomplete-loading" );
6638
			}
6639
		};
6640
	},
6641
 
6642
	__response: function( content ) {
6643
		if ( content ) {
6644
			content = this._normalize( content );
6645
		}
6646
		this._trigger( "response", null, { content: content } );
6647
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6648
			this._suggest( content );
6649
			this._trigger( "open" );
6650
		} else {
6651
			// use ._close() instead of .close() so we don't cancel future searches
6652
			this._close();
6653
		}
6654
	},
6655
 
6656
	close: function( event ) {
6657
		this.cancelSearch = true;
6658
		this._close( event );
6659
	},
6660
 
6661
	_close: function( event ) {
6662
		if ( this.menu.element.is( ":visible" ) ) {
6663
			this.menu.element.hide();
6664
			this.menu.blur();
6665
			this.isNewMenu = true;
6666
			this._trigger( "close", event );
6667
		}
6668
	},
6669
 
6670
	_change: function( event ) {
6671
		if ( this.previous !== this._value() ) {
6672
			this._trigger( "change", event, { item: this.selectedItem } );
6673
		}
6674
	},
6675
 
6676
	_normalize: function( items ) {
6677
		// assume all items have the right format when the first item is complete
6678
		if ( items.length && items[0].label && items[0].value ) {
6679
			return items;
6680
		}
6681
		return $.map( items, function( item ) {
6682
			if ( typeof item === "string" ) {
6683
				return {
6684
					label: item,
6685
					value: item
6686
				};
6687
			}
6688
			return $.extend({
6689
				label: item.label || item.value,
6690
				value: item.value || item.label
6691
			}, item );
6692
		});
6693
	},
6694
 
6695
	_suggest: function( items ) {
6696
		var ul = this.menu.element
6697
			.empty()
6698
			.zIndex( this.element.zIndex() + 1 );
6699
		this._renderMenu( ul, items );
6700
		this.menu.refresh();
6701
 
6702
		// size and position menu
6703
		ul.show();
6704
		this._resizeMenu();
6705
		ul.position( $.extend({
6706
			of: this.element
6707
		}, this.options.position ));
6708
 
6709
		if ( this.options.autoFocus ) {
6710
			this.menu.next();
6711
		}
6712
	},
6713
 
6714
	_resizeMenu: function() {
6715
		var ul = this.menu.element;
6716
		ul.outerWidth( Math.max(
6717
			// Firefox wraps long text (possibly a rounding bug)
6718
			// so we add 1px to avoid the wrapping (#7513)
6719
			ul.width( "" ).outerWidth() + 1,
6720
			this.element.outerWidth()
6721
		) );
6722
	},
6723
 
6724
	_renderMenu: function( ul, items ) {
6725
		var that = this;
6726
		$.each( items, function( index, item ) {
6727
			that._renderItemData( ul, item );
6728
		});
6729
	},
6730
 
6731
	_renderItemData: function( ul, item ) {
6732
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6733
	},
6734
 
6735
	_renderItem: function( ul, item ) {
6736
		return $( "<li>" )
6737
			.append( $( "<a>" ).text( item.label ) )
6738
			.appendTo( ul );
6739
	},
6740
 
6741
	_move: function( direction, event ) {
6742
		if ( !this.menu.element.is( ":visible" ) ) {
6743
			this.search( null, event );
6744
			return;
6745
		}
6746
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6747
				this.menu.isLastItem() && /^next/.test( direction ) ) {
6748
			this._value( this.term );
6749
			this.menu.blur();
6750
			return;
6751
		}
6752
		this.menu[ direction ]( event );
6753
	},
6754
 
6755
	widget: function() {
6756
		return this.menu.element;
6757
	},
6758
 
6759
	_value: function() {
6760
		return this.valueMethod.apply( this.element, arguments );
6761
	},
6762
 
6763
	_keyEvent: function( keyEvent, event ) {
6764
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6765
			this._move( keyEvent, event );
6766
 
6767
			// prevents moving cursor to beginning/end of the text field in some browsers
6768
			event.preventDefault();
6769
		}
6770
	}
6771
});
6772
 
6773
$.extend( $.ui.autocomplete, {
6774
	escapeRegex: function( value ) {
6775
		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
6776
	},
6777
	filter: function(array, term) {
6778
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6779
		return $.grep( array, function(value) {
6780
			return matcher.test( value.label || value.value || value );
6781
		});
6782
	}
6783
});
6784
 
6785
 
6786
// live region extension, adding a `messages` option
6787
// NOTE: This is an experimental API. We are still investigating
6788
// a full solution for string manipulation and internationalization.
6789
$.widget( "ui.autocomplete", $.ui.autocomplete, {
6790
	options: {
6791
		messages: {
6792
			noResults: "No search results.",
6793
			results: function( amount ) {
6794
				return amount + ( amount > 1 ? " results are" : " result is" ) +
6795
					" available, use up and down arrow keys to navigate.";
6796
			}
6797
		}
6798
	},
6799
 
6800
	__response: function( content ) {
6801
		var message;
6802
		this._superApply( arguments );
6803
		if ( this.options.disabled || this.cancelSearch ) {
6804
			return;
6805
		}
6806
		if ( content && content.length ) {
6807
			message = this.options.messages.results( content.length );
6808
		} else {
6809
			message = this.options.messages.noResults;
6810
		}
6811
		this.liveRegion.text( message );
6812
	}
6813
});
6814
 
6815
 
6816
}( jQuery ));
6817
 
6818
(function( $, undefined ) {
6819
 
6820
var lastActive, startXPos, startYPos, clickDragged,
6821
	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6822
	stateClasses = "ui-state-hover ui-state-active ",
6823
	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
6824
	formResetHandler = function() {
6825
		var buttons = $( this ).find( ":ui-button" );
6826
		setTimeout(function() {
6827
			buttons.button( "refresh" );
6828
		}, 1 );
6829
	},
6830
	radioGroup = function( radio ) {
6831
		var name = radio.name,
6832
			form = radio.form,
6833
			radios = $( [] );
6834
		if ( name ) {
6835
			if ( form ) {
6836
				radios = $( form ).find( "[name='" + name + "']" );
6837
			} else {
6838
				radios = $( "[name='" + name + "']", radio.ownerDocument )
6839
					.filter(function() {
6840
						return !this.form;
6841
					});
6842
			}
6843
		}
6844
		return radios;
6845
	};
6846
 
6847
$.widget( "ui.button", {
6848
	version: "1.9.2",
6849
	defaultElement: "<button>",
6850
	options: {
6851
		disabled: null,
6852
		text: true,
6853
		label: null,
6854
		icons: {
6855
			primary: null,
6856
			secondary: null
6857
		}
6858
	},
6859
	_create: function() {
6860
		this.element.closest( "form" )
6861
			.unbind( "reset" + this.eventNamespace )
6862
			.bind( "reset" + this.eventNamespace, formResetHandler );
6863
 
6864
		if ( typeof this.options.disabled !== "boolean" ) {
6865
			this.options.disabled = !!this.element.prop( "disabled" );
6866
		} else {
6867
			this.element.prop( "disabled", this.options.disabled );
6868
		}
6869
 
6870
		this._determineButtonType();
6871
		this.hasTitle = !!this.buttonElement.attr( "title" );
6872
 
6873
		var that = this,
6874
			options = this.options,
6875
			toggleButton = this.type === "checkbox" || this.type === "radio",
6876
			activeClass = !toggleButton ? "ui-state-active" : "",
6877
			focusClass = "ui-state-focus";
6878
 
6879
		if ( options.label === null ) {
6880
			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6881
		}
6882
 
6883
		this._hoverable( this.buttonElement );
6884
 
6885
		this.buttonElement
6886
			.addClass( baseClasses )
6887
			.attr( "role", "button" )
6888
			.bind( "mouseenter" + this.eventNamespace, function() {
6889
				if ( options.disabled ) {
6890
					return;
6891
				}
6892
				if ( this === lastActive ) {
6893
					$( this ).addClass( "ui-state-active" );
6894
				}
6895
			})
6896
			.bind( "mouseleave" + this.eventNamespace, function() {
6897
				if ( options.disabled ) {
6898
					return;
6899
				}
6900
				$( this ).removeClass( activeClass );
6901
			})
6902
			.bind( "click" + this.eventNamespace, function( event ) {
6903
				if ( options.disabled ) {
6904
					event.preventDefault();
6905
					event.stopImmediatePropagation();
6906
				}
6907
			});
6908
 
6909
		this.element
6910
			.bind( "focus" + this.eventNamespace, function() {
6911
				// no need to check disabled, focus won't be triggered anyway
6912
				that.buttonElement.addClass( focusClass );
6913
			})
6914
			.bind( "blur" + this.eventNamespace, function() {
6915
				that.buttonElement.removeClass( focusClass );
6916
			});
6917
 
6918
		if ( toggleButton ) {
6919
			this.element.bind( "change" + this.eventNamespace, function() {
6920
				if ( clickDragged ) {
6921
					return;
6922
				}
6923
				that.refresh();
6924
			});
6925
			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6926
			// prevents issue where button state changes but checkbox/radio checked state
6927
			// does not in Firefox (see ticket #6970)
6928
			this.buttonElement
6929
				.bind( "mousedown" + this.eventNamespace, function( event ) {
6930
					if ( options.disabled ) {
6931
						return;
6932
					}
6933
					clickDragged = false;
6934
					startXPos = event.pageX;
6935
					startYPos = event.pageY;
6936
				})
6937
				.bind( "mouseup" + this.eventNamespace, function( event ) {
6938
					if ( options.disabled ) {
6939
						return;
6940
					}
6941
					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6942
						clickDragged = true;
6943
					}
6944
			});
6945
		}
6946
 
6947
		if ( this.type === "checkbox" ) {
6948
			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6949
				if ( options.disabled || clickDragged ) {
6950
					return false;
6951
				}
6952
				$( this ).toggleClass( "ui-state-active" );
6953
				that.buttonElement.attr( "aria-pressed", that.element[0].checked );
6954
			});
6955
		} else if ( this.type === "radio" ) {
6956
			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6957
				if ( options.disabled || clickDragged ) {
6958
					return false;
6959
				}
6960
				$( this ).addClass( "ui-state-active" );
6961
				that.buttonElement.attr( "aria-pressed", "true" );
6962
 
6963
				var radio = that.element[ 0 ];
6964
				radioGroup( radio )
6965
					.not( radio )
6966
					.map(function() {
6967
						return $( this ).button( "widget" )[ 0 ];
6968
					})
6969
					.removeClass( "ui-state-active" )
6970
					.attr( "aria-pressed", "false" );
6971
			});
6972
		} else {
6973
			this.buttonElement
6974
				.bind( "mousedown" + this.eventNamespace, function() {
6975
					if ( options.disabled ) {
6976
						return false;
6977
					}
6978
					$( this ).addClass( "ui-state-active" );
6979
					lastActive = this;
6980
					that.document.one( "mouseup", function() {
6981
						lastActive = null;
6982
					});
6983
				})
6984
				.bind( "mouseup" + this.eventNamespace, function() {
6985
					if ( options.disabled ) {
6986
						return false;
6987
					}
6988
					$( this ).removeClass( "ui-state-active" );
6989
				})
6990
				.bind( "keydown" + this.eventNamespace, function(event) {
6991
					if ( options.disabled ) {
6992
						return false;
6993
					}
6994
					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6995
						$( this ).addClass( "ui-state-active" );
6996
					}
6997
				})
6998
				.bind( "keyup" + this.eventNamespace, function() {
6999
					$( this ).removeClass( "ui-state-active" );
7000
				});
7001
 
7002
			if ( this.buttonElement.is("a") ) {
7003
				this.buttonElement.keyup(function(event) {
7004
					if ( event.keyCode === $.ui.keyCode.SPACE ) {
7005
						// TODO pass through original event correctly (just as 2nd argument doesn't work)
7006
						$( this ).click();
7007
					}
7008
				});
7009
			}
7010
		}
7011
 
7012
		// TODO: pull out $.Widget's handling for the disabled option into
7013
		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7014
		// be overridden by individual plugins
7015
		this._setOption( "disabled", options.disabled );
7016
		this._resetButton();
7017
	},
7018
 
7019
	_determineButtonType: function() {
7020
		var ancestor, labelSelector, checked;
7021
 
7022
		if ( this.element.is("[type=checkbox]") ) {
7023
			this.type = "checkbox";
7024
		} else if ( this.element.is("[type=radio]") ) {
7025
			this.type = "radio";
7026
		} else if ( this.element.is("input") ) {
7027
			this.type = "input";
7028
		} else {
7029
			this.type = "button";
7030
		}
7031
 
7032
		if ( this.type === "checkbox" || this.type === "radio" ) {
7033
			// we don't search against the document in case the element
7034
			// is disconnected from the DOM
7035
			ancestor = this.element.parents().last();
7036
			labelSelector = "label[for='" + this.element.attr("id") + "']";
7037
			this.buttonElement = ancestor.find( labelSelector );
7038
			if ( !this.buttonElement.length ) {
7039
				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7040
				this.buttonElement = ancestor.filter( labelSelector );
7041
				if ( !this.buttonElement.length ) {
7042
					this.buttonElement = ancestor.find( labelSelector );
7043
				}
7044
			}
7045
			this.element.addClass( "ui-helper-hidden-accessible" );
7046
 
7047
			checked = this.element.is( ":checked" );
7048
			if ( checked ) {
7049
				this.buttonElement.addClass( "ui-state-active" );
7050
			}
7051
			this.buttonElement.prop( "aria-pressed", checked );
7052
		} else {
7053
			this.buttonElement = this.element;
7054
		}
7055
	},
7056
 
7057
	widget: function() {
7058
		return this.buttonElement;
7059
	},
7060
 
7061
	_destroy: function() {
7062
		this.element
7063
			.removeClass( "ui-helper-hidden-accessible" );
7064
		this.buttonElement
7065
			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7066
			.removeAttr( "role" )
7067
			.removeAttr( "aria-pressed" )
7068
			.html( this.buttonElement.find(".ui-button-text").html() );
7069
 
7070
		if ( !this.hasTitle ) {
7071
			this.buttonElement.removeAttr( "title" );
7072
		}
7073
	},
7074
 
7075
	_setOption: function( key, value ) {
7076
		this._super( key, value );
7077
		if ( key === "disabled" ) {
7078
			if ( value ) {
7079
				this.element.prop( "disabled", true );
7080
			} else {
7081
				this.element.prop( "disabled", false );
7082
			}
7083
			return;
7084
		}
7085
		this._resetButton();
7086
	},
7087
 
7088
	refresh: function() {
7089
		//See #8237 & #8828
7090
		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7091
 
7092
		if ( isDisabled !== this.options.disabled ) {
7093
			this._setOption( "disabled", isDisabled );
7094
		}
7095
		if ( this.type === "radio" ) {
7096
			radioGroup( this.element[0] ).each(function() {
7097
				if ( $( this ).is( ":checked" ) ) {
7098
					$( this ).button( "widget" )
7099
						.addClass( "ui-state-active" )
7100
						.attr( "aria-pressed", "true" );
7101
				} else {
7102
					$( this ).button( "widget" )
7103
						.removeClass( "ui-state-active" )
7104
						.attr( "aria-pressed", "false" );
7105
				}
7106
			});
7107
		} else if ( this.type === "checkbox" ) {
7108
			if ( this.element.is( ":checked" ) ) {
7109
				this.buttonElement
7110
					.addClass( "ui-state-active" )
7111
					.attr( "aria-pressed", "true" );
7112
			} else {
7113
				this.buttonElement
7114
					.removeClass( "ui-state-active" )
7115
					.attr( "aria-pressed", "false" );
7116
			}
7117
		}
7118
	},
7119
 
7120
	_resetButton: function() {
7121
		if ( this.type === "input" ) {
7122
			if ( this.options.label ) {
7123
				this.element.val( this.options.label );
7124
			}
7125
			return;
7126
		}
7127
		var buttonElement = this.buttonElement.removeClass( typeClasses ),
7128
			buttonText = $( "<span></span>", this.document[0] )
7129
				.addClass( "ui-button-text" )
7130
				.html( this.options.label )
7131
				.appendTo( buttonElement.empty() )
7132
				.text(),
7133
			icons = this.options.icons,
7134
			multipleIcons = icons.primary && icons.secondary,
7135
			buttonClasses = [];
7136
 
7137
		if ( icons.primary || icons.secondary ) {
7138
			if ( this.options.text ) {
7139
				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7140
			}
7141
 
7142
			if ( icons.primary ) {
7143
				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7144
			}
7145
 
7146
			if ( icons.secondary ) {
7147
				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7148
			}
7149
 
7150
			if ( !this.options.text ) {
7151
				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7152
 
7153
				if ( !this.hasTitle ) {
7154
					buttonElement.attr( "title", $.trim( buttonText ) );
7155
				}
7156
			}
7157
		} else {
7158
			buttonClasses.push( "ui-button-text-only" );
7159
		}
7160
		buttonElement.addClass( buttonClasses.join( " " ) );
7161
	}
7162
});
7163
 
7164
$.widget( "ui.buttonset", {
7165
	version: "1.9.2",
7166
	options: {
7167
		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
7168
	},
7169
 
7170
	_create: function() {
7171
		this.element.addClass( "ui-buttonset" );
7172
	},
7173
 
7174
	_init: function() {
7175
		this.refresh();
7176
	},
7177
 
7178
	_setOption: function( key, value ) {
7179
		if ( key === "disabled" ) {
7180
			this.buttons.button( "option", key, value );
7181
		}
7182
 
7183
		this._super( key, value );
7184
	},
7185
 
7186
	refresh: function() {
7187
		var rtl = this.element.css( "direction" ) === "rtl";
7188
 
7189
		this.buttons = this.element.find( this.options.items )
7190
			.filter( ":ui-button" )
7191
				.button( "refresh" )
7192
			.end()
7193
			.not( ":ui-button" )
7194
				.button()
7195
			.end()
7196
			.map(function() {
7197
				return $( this ).button( "widget" )[ 0 ];
7198
			})
7199
				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7200
				.filter( ":first" )
7201
					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7202
				.end()
7203
				.filter( ":last" )
7204
					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7205
				.end()
7206
			.end();
7207
	},
7208
 
7209
	_destroy: function() {
7210
		this.element.removeClass( "ui-buttonset" );
7211
		this.buttons
7212
			.map(function() {
7213
				return $( this ).button( "widget" )[ 0 ];
7214
			})
7215
				.removeClass( "ui-corner-left ui-corner-right" )
7216
			.end()
7217
			.button( "destroy" );
7218
	}
7219
});
7220
 
7221
}( jQuery ) );
7222
 
7223
(function( $, undefined ) {
7224
 
7225
$.extend($.ui, { datepicker: { version: "1.9.2" } });
7226
 
7227
var PROP_NAME = 'datepicker';
7228
var dpuuid = new Date().getTime();
7229
var instActive;
7230
 
7231
/* Date picker manager.
7232
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7233
   Settings for (groups of) date pickers are maintained in an instance object,
7234
   allowing multiple different settings on the same page. */
7235
 
7236
function Datepicker() {
7237
	this.debug = false; // Change this to true to start debugging
7238
	this._curInst = null; // The current instance in use
7239
	this._keyEvent = false; // If the last event was a key event
7240
	this._disabledInputs = []; // List of date picker inputs that have been disabled
7241
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7242
	this._inDialog = false; // True if showing within a "dialog", false if not
7243
	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
7244
	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
7245
	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
7246
	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
7247
	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
7248
	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
7249
	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
7250
	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
7251
	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
7252
	this.regional = []; // Available regional settings, indexed by language code
7253
	this.regional[''] = { // Default regional settings
7254
		closeText: 'Done', // Display text for close link
7255
		prevText: 'Prev', // Display text for previous month link
7256
		nextText: 'Next', // Display text for next month link
7257
		currentText: 'Today', // Display text for current month link
7258
		monthNames: ['January','February','March','April','May','June',
7259
			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
7260
		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
7261
		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
7262
		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
7263
		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
7264
		weekHeader: 'Wk', // Column header for week of the year
7265
		dateFormat: 'mm/dd/yy', // See format options on parseDate
7266
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7267
		isRTL: false, // True if right-to-left language, false if left-to-right
7268
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7269
		yearSuffix: '' // Additional text to append to the year in the month headers
7270
	};
7271
	this._defaults = { // Global defaults for all the date picker instances
7272
		showOn: 'focus', // 'focus' for popup on focus,
7273
			// 'button' for trigger button, or 'both' for either
7274
		showAnim: 'fadeIn', // Name of jQuery animation for popup
7275
		showOptions: {}, // Options for enhanced animations
7276
		defaultDate: null, // Used when field is blank: actual date,
7277
			// +/-number for offset from today, null for today
7278
		appendText: '', // Display text following the input box, e.g. showing the format
7279
		buttonText: '...', // Text for trigger button
7280
		buttonImage: '', // URL for trigger button image
7281
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7282
		hideIfNoPrevNext: false, // True to hide next/previous month links
7283
			// if not applicable, false to just disable them
7284
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7285
		gotoCurrent: false, // True if today link goes back to current selection instead
7286
		changeMonth: false, // True if month can be selected directly, false if only prev/next
7287
		changeYear: false, // True if year can be selected directly, false if only prev/next
7288
		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
7289
			// either relative to today's year (-nn:+nn), relative to currently displayed year
7290
			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7291
		showOtherMonths: false, // True to show dates in other months, false to leave blank
7292
		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7293
		showWeek: false, // True to show week of the year, false to not show it
7294
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7295
			// takes a Date and returns the number of the week for it
7296
		shortYearCutoff: '+10', // Short year values < this are in the current century,
7297
			// > this are in the previous century,
7298
			// string value starting with '+' for current year + value
7299
		minDate: null, // The earliest selectable date, or null for no limit
7300
		maxDate: null, // The latest selectable date, or null for no limit
7301
		duration: 'fast', // Duration of display/closure
7302
		beforeShowDay: null, // Function that takes a date and returns an array with
7303
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
7304
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7305
		beforeShow: null, // Function that takes an input field and
7306
			// returns a set of custom settings for the date picker
7307
		onSelect: null, // Define a callback function when a date is selected
7308
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7309
		onClose: null, // Define a callback function when the datepicker is closed
7310
		numberOfMonths: 1, // Number of months to show at a time
7311
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7312
		stepMonths: 1, // Number of months to step back/forward
7313
		stepBigMonths: 12, // Number of months to step back/forward for the big links
7314
		altField: '', // Selector for an alternate field to store selected dates into
7315
		altFormat: '', // The date format to use for the alternate field
7316
		constrainInput: true, // The input is constrained by the current date format
7317
		showButtonPanel: false, // True to show button panel, false to not show it
7318
		autoSize: false, // True to size the input for the date format, false to leave as is
7319
		disabled: false // The initial disabled state
7320
	};
7321
	$.extend(this._defaults, this.regional['']);
7322
	this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
7323
}
7324
 
7325
$.extend(Datepicker.prototype, {
7326
	/* Class name added to elements to indicate already configured with a date picker. */
7327
	markerClassName: 'hasDatepicker',
7328
 
7329
	//Keep track of the maximum number of rows displayed (see #7043)
7330
	maxRows: 4,
7331
 
7332
	/* Debug logging (if enabled). */
7333
	log: function () {
7334
		if (this.debug)
7335
			console.log.apply('', arguments);
7336
	},
7337
 
7338
	// TODO rename to "widget" when switching to widget factory
7339
	_widgetDatepicker: function() {
7340
		return this.dpDiv;
7341
	},
7342
 
7343
	/* Override the default settings for all instances of the date picker.
7344
	   @param  settings  object - the new settings to use as defaults (anonymous object)
7345
	   @return the manager object */
7346
	setDefaults: function(settings) {
7347
		extendRemove(this._defaults, settings || {});
7348
		return this;
7349
	},
7350
 
7351
	/* Attach the date picker to a jQuery selection.
7352
	   @param  target    element - the target input field or division or span
7353
	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
7354
	_attachDatepicker: function(target, settings) {
7355
		// check for settings on the control itself - in namespace 'date:'
7356
		var inlineSettings = null;
7357
		for (var attrName in this._defaults) {
7358
			var attrValue = target.getAttribute('date:' + attrName);
7359
			if (attrValue) {
7360
				inlineSettings = inlineSettings || {};
7361
				try {
7362
					inlineSettings[attrName] = eval(attrValue);
7363
				} catch (err) {
7364
					inlineSettings[attrName] = attrValue;
7365
				}
7366
			}
7367
		}
7368
		var nodeName = target.nodeName.toLowerCase();
7369
		var inline = (nodeName == 'div' || nodeName == 'span');
7370
		if (!target.id) {
7371
			this.uuid += 1;
7372
			target.id = 'dp' + this.uuid;
7373
		}
7374
		var inst = this._newInst($(target), inline);
7375
		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
7376
		if (nodeName == 'input') {
7377
			this._connectDatepicker(target, inst);
7378
		} else if (inline) {
7379
			this._inlineDatepicker(target, inst);
7380
		}
7381
	},
7382
 
7383
	/* Create a new instance object. */
7384
	_newInst: function(target, inline) {
7385
		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
7386
		return {id: id, input: target, // associated target
7387
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7388
			drawMonth: 0, drawYear: 0, // month being drawn
7389
			inline: inline, // is datepicker inline or not
7390
			dpDiv: (!inline ? this.dpDiv : // presentation div
7391
			bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
7392
	},
7393
 
7394
	/* Attach the date picker to an input field. */
7395
	_connectDatepicker: function(target, inst) {
7396
		var input = $(target);
7397
		inst.append = $([]);
7398
		inst.trigger = $([]);
7399
		if (input.hasClass(this.markerClassName))
7400
			return;
7401
		this._attachments(input, inst);
7402
		input.addClass(this.markerClassName).keydown(this._doKeyDown).
7403
			keypress(this._doKeyPress).keyup(this._doKeyUp).
7404
			bind("setData.datepicker", function(event, key, value) {
7405
				inst.settings[key] = value;
7406
			}).bind("getData.datepicker", function(event, key) {
7407
				return this._get(inst, key);
7408
			});
7409
		this._autoSize(inst);
7410
		$.data(target, PROP_NAME, inst);
7411
		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7412
		if( inst.settings.disabled ) {
7413
			this._disableDatepicker( target );
7414
		}
7415
	},
7416
 
7417
	/* Make attachments based on settings. */
7418
	_attachments: function(input, inst) {
7419
		var appendText = this._get(inst, 'appendText');
7420
		var isRTL = this._get(inst, 'isRTL');
7421
		if (inst.append)
7422
			inst.append.remove();
7423
		if (appendText) {
7424
			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
7425
			input[isRTL ? 'before' : 'after'](inst.append);
7426
		}
7427
		input.unbind('focus', this._showDatepicker);
7428
		if (inst.trigger)
7429
			inst.trigger.remove();
7430
		var showOn = this._get(inst, 'showOn');
7431
		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
7432
			input.focus(this._showDatepicker);
7433
		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
7434
			var buttonText = this._get(inst, 'buttonText');
7435
			var buttonImage = this._get(inst, 'buttonImage');
7436
			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
7437
				$('<img/>').addClass(this._triggerClass).
7438
					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7439
				$('<button type="button"></button>').addClass(this._triggerClass).
7440
					html(buttonImage == '' ? buttonText : $('<img/>').attr(
7441
					{ src:buttonImage, alt:buttonText, title:buttonText })));
7442
			input[isRTL ? 'before' : 'after'](inst.trigger);
7443
			inst.trigger.click(function() {
7444
				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
7445
					$.datepicker._hideDatepicker();
7446
				else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
7447
					$.datepicker._hideDatepicker();
7448
					$.datepicker._showDatepicker(input[0]);
7449
				} else
7450
					$.datepicker._showDatepicker(input[0]);
7451
				return false;
7452
			});
7453
		}
7454
	},
7455
 
7456
	/* Apply the maximum length for the date format. */
7457
	_autoSize: function(inst) {
7458
		if (this._get(inst, 'autoSize') && !inst.inline) {
7459
			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
7460
			var dateFormat = this._get(inst, 'dateFormat');
7461
			if (dateFormat.match(/[DM]/)) {
7462
				var findMax = function(names) {
7463
					var max = 0;
7464
					var maxI = 0;
7465
					for (var i = 0; i < names.length; i++) {
7466
						if (names[i].length > max) {
7467
							max = names[i].length;
7468
							maxI = i;
7469
						}
7470
					}
7471
					return maxI;
7472
				};
7473
				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7474
					'monthNames' : 'monthNamesShort'))));
7475
				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7476
					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
7477
			}
7478
			inst.input.attr('size', this._formatDate(inst, date).length);
7479
		}
7480
	},
7481
 
7482
	/* Attach an inline date picker to a div. */
7483
	_inlineDatepicker: function(target, inst) {
7484
		var divSpan = $(target);
7485
		if (divSpan.hasClass(this.markerClassName))
7486
			return;
7487
		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
7488
			bind("setData.datepicker", function(event, key, value){
7489
				inst.settings[key] = value;
7490
			}).bind("getData.datepicker", function(event, key){
7491
				return this._get(inst, key);
7492
			});
7493
		$.data(target, PROP_NAME, inst);
7494
		this._setDate(inst, this._getDefaultDate(inst), true);
7495
		this._updateDatepicker(inst);
7496
		this._updateAlternate(inst);
7497
		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7498
		if( inst.settings.disabled ) {
7499
			this._disableDatepicker( target );
7500
		}
7501
		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7502
		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7503
		inst.dpDiv.css( "display", "block" );
7504
	},
7505
 
7506
	/* Pop-up the date picker in a "dialog" box.
7507
	   @param  input     element - ignored
7508
	   @param  date      string or Date - the initial date to display
7509
	   @param  onSelect  function - the function to call when a date is selected
7510
	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7511
	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
7512
	                     event - with x/y coordinates or
7513
	                     leave empty for default (screen centre)
7514
	   @return the manager object */
7515
	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
7516
		var inst = this._dialogInst; // internal instance
7517
		if (!inst) {
7518
			this.uuid += 1;
7519
			var id = 'dp' + this.uuid;
7520
			this._dialogInput = $('<input type="text" id="' + id +
7521
				'" style="position: absolute; top: -100px; width: 0px;"/>');
7522
			this._dialogInput.keydown(this._doKeyDown);
7523
			$('body').append(this._dialogInput);
7524
			inst = this._dialogInst = this._newInst(this._dialogInput, false);
7525
			inst.settings = {};
7526
			$.data(this._dialogInput[0], PROP_NAME, inst);
7527
		}
7528
		extendRemove(inst.settings, settings || {});
7529
		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
7530
		this._dialogInput.val(date);
7531
 
7532
		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7533
		if (!this._pos) {
7534
			var browserWidth = document.documentElement.clientWidth;
7535
			var browserHeight = document.documentElement.clientHeight;
7536
			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7537
			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7538
			this._pos = // should use actual width/height below
7539
				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7540
		}
7541
 
7542
		// move input on screen for focus, but hidden behind dialog
7543
		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
7544
		inst.settings.onSelect = onSelect;
7545
		this._inDialog = true;
7546
		this.dpDiv.addClass(this._dialogClass);
7547
		this._showDatepicker(this._dialogInput[0]);
7548
		if ($.blockUI)
7549
			$.blockUI(this.dpDiv);
7550
		$.data(this._dialogInput[0], PROP_NAME, inst);
7551
		return this;
7552
	},
7553
 
7554
	/* Detach a datepicker from its control.
7555
	   @param  target    element - the target input field or division or span */
7556
	_destroyDatepicker: function(target) {
7557
		var $target = $(target);
7558
		var inst = $.data(target, PROP_NAME);
7559
		if (!$target.hasClass(this.markerClassName)) {
7560
			return;
7561
		}
7562
		var nodeName = target.nodeName.toLowerCase();
7563
		$.removeData(target, PROP_NAME);
7564
		if (nodeName == 'input') {
7565
			inst.append.remove();
7566
			inst.trigger.remove();
7567
			$target.removeClass(this.markerClassName).
7568
				unbind('focus', this._showDatepicker).
7569
				unbind('keydown', this._doKeyDown).
7570
				unbind('keypress', this._doKeyPress).
7571
				unbind('keyup', this._doKeyUp);
7572
		} else if (nodeName == 'div' || nodeName == 'span')
7573
			$target.removeClass(this.markerClassName).empty();
7574
	},
7575
 
7576
	/* Enable the date picker to a jQuery selection.
7577
	   @param  target    element - the target input field or division or span */
7578
	_enableDatepicker: function(target) {
7579
		var $target = $(target);
7580
		var inst = $.data(target, PROP_NAME);
7581
		if (!$target.hasClass(this.markerClassName)) {
7582
			return;
7583
		}
7584
		var nodeName = target.nodeName.toLowerCase();
7585
		if (nodeName == 'input') {
7586
			target.disabled = false;
7587
			inst.trigger.filter('button').
7588
				each(function() { this.disabled = false; }).end().
7589
				filter('img').css({opacity: '1.0', cursor: ''});
7590
		}
7591
		else if (nodeName == 'div' || nodeName == 'span') {
7592
			var inline = $target.children('.' + this._inlineClass);
7593
			inline.children().removeClass('ui-state-disabled');
7594
			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7595
				prop("disabled", false);
7596
		}
7597
		this._disabledInputs = $.map(this._disabledInputs,
7598
			function(value) { return (value == target ? null : value); }); // delete entry
7599
	},
7600
 
7601
	/* Disable the date picker to a jQuery selection.
7602
	   @param  target    element - the target input field or division or span */
7603
	_disableDatepicker: function(target) {
7604
		var $target = $(target);
7605
		var inst = $.data(target, PROP_NAME);
7606
		if (!$target.hasClass(this.markerClassName)) {
7607
			return;
7608
		}
7609
		var nodeName = target.nodeName.toLowerCase();
7610
		if (nodeName == 'input') {
7611
			target.disabled = true;
7612
			inst.trigger.filter('button').
7613
				each(function() { this.disabled = true; }).end().
7614
				filter('img').css({opacity: '0.5', cursor: 'default'});
7615
		}
7616
		else if (nodeName == 'div' || nodeName == 'span') {
7617
			var inline = $target.children('.' + this._inlineClass);
7618
			inline.children().addClass('ui-state-disabled');
7619
			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7620
				prop("disabled", true);
7621
		}
7622
		this._disabledInputs = $.map(this._disabledInputs,
7623
			function(value) { return (value == target ? null : value); }); // delete entry
7624
		this._disabledInputs[this._disabledInputs.length] = target;
7625
	},
7626
 
7627
	/* Is the first field in a jQuery collection disabled as a datepicker?
7628
	   @param  target    element - the target input field or division or span
7629
	   @return boolean - true if disabled, false if enabled */
7630
	_isDisabledDatepicker: function(target) {
7631
		if (!target) {
7632
			return false;
7633
		}
7634
		for (var i = 0; i < this._disabledInputs.length; i++) {
7635
			if (this._disabledInputs[i] == target)
7636
				return true;
7637
		}
7638
		return false;
7639
	},
7640
 
7641
	/* Retrieve the instance data for the target control.
7642
	   @param  target  element - the target input field or division or span
7643
	   @return  object - the associated instance data
7644
	   @throws  error if a jQuery problem getting data */
7645
	_getInst: function(target) {
7646
		try {
7647
			return $.data(target, PROP_NAME);
7648
		}
7649
		catch (err) {
7650
			throw 'Missing instance data for this datepicker';
7651
		}
7652
	},
7653
 
7654
	/* Update or retrieve the settings for a date picker attached to an input field or division.
7655
	   @param  target  element - the target input field or division or span
7656
	   @param  name    object - the new settings to update or
7657
	                   string - the name of the setting to change or retrieve,
7658
	                   when retrieving also 'all' for all instance settings or
7659
	                   'defaults' for all global defaults
7660
	   @param  value   any - the new value for the setting
7661
	                   (omit if above is an object or to retrieve a value) */
7662
	_optionDatepicker: function(target, name, value) {
7663
		var inst = this._getInst(target);
7664
		if (arguments.length == 2 && typeof name == 'string') {
7665
			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
7666
				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
7667
				this._get(inst, name)) : null));
7668
		}
7669
		var settings = name || {};
7670
		if (typeof name == 'string') {
7671
			settings = {};
7672
			settings[name] = value;
7673
		}
7674
		if (inst) {
7675
			if (this._curInst == inst) {
7676
				this._hideDatepicker();
7677
			}
7678
			var date = this._getDateDatepicker(target, true);
7679
			var minDate = this._getMinMaxDate(inst, 'min');
7680
			var maxDate = this._getMinMaxDate(inst, 'max');
7681
			extendRemove(inst.settings, settings);
7682
			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7683
			if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
7684
				inst.settings.minDate = this._formatDate(inst, minDate);
7685
			if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
7686
				inst.settings.maxDate = this._formatDate(inst, maxDate);
7687
			this._attachments($(target), inst);
7688
			this._autoSize(inst);
7689
			this._setDate(inst, date);
7690
			this._updateAlternate(inst);
7691
			this._updateDatepicker(inst);
7692
		}
7693
	},
7694
 
7695
	// change method deprecated
7696
	_changeDatepicker: function(target, name, value) {
7697
		this._optionDatepicker(target, name, value);
7698
	},
7699
 
7700
	/* Redraw the date picker attached to an input field or division.
7701
	   @param  target  element - the target input field or division or span */
7702
	_refreshDatepicker: function(target) {
7703
		var inst = this._getInst(target);
7704
		if (inst) {
7705
			this._updateDatepicker(inst);
7706
		}
7707
	},
7708
 
7709
	/* Set the dates for a jQuery selection.
7710
	   @param  target   element - the target input field or division or span
7711
	   @param  date     Date - the new date */
7712
	_setDateDatepicker: function(target, date) {
7713
		var inst = this._getInst(target);
7714
		if (inst) {
7715
			this._setDate(inst, date);
7716
			this._updateDatepicker(inst);
7717
			this._updateAlternate(inst);
7718
		}
7719
	},
7720
 
7721
	/* Get the date(s) for the first entry in a jQuery selection.
7722
	   @param  target     element - the target input field or division or span
7723
	   @param  noDefault  boolean - true if no default date is to be used
7724
	   @return Date - the current date */
7725
	_getDateDatepicker: function(target, noDefault) {
7726
		var inst = this._getInst(target);
7727
		if (inst && !inst.inline)
7728
			this._setDateFromField(inst, noDefault);
7729
		return (inst ? this._getDate(inst) : null);
7730
	},
7731
 
7732
	/* Handle keystrokes. */
7733
	_doKeyDown: function(event) {
7734
		var inst = $.datepicker._getInst(event.target);
7735
		var handled = true;
7736
		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
7737
		inst._keyEvent = true;
7738
		if ($.datepicker._datepickerShowing)
7739
			switch (event.keyCode) {
7740
				case 9: $.datepicker._hideDatepicker();
7741
						handled = false;
7742
						break; // hide on tab out
7743
				case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
7744
									$.datepicker._currentClass + ')', inst.dpDiv);
7745
						if (sel[0])
7746
							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7747
							var onSelect = $.datepicker._get(inst, 'onSelect');
7748
							if (onSelect) {
7749
								var dateStr = $.datepicker._formatDate(inst);
7750
 
7751
								// trigger custom callback
7752
								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7753
							}
7754
						else
7755
							$.datepicker._hideDatepicker();
7756
						return false; // don't submit the form
7757
						break; // select the value on enter
7758
				case 27: $.datepicker._hideDatepicker();
7759
						break; // hide on escape
7760
				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7761
							-$.datepicker._get(inst, 'stepBigMonths') :
7762
							-$.datepicker._get(inst, 'stepMonths')), 'M');
7763
						break; // previous month/year on page up/+ ctrl
7764
				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7765
							+$.datepicker._get(inst, 'stepBigMonths') :
7766
							+$.datepicker._get(inst, 'stepMonths')), 'M');
7767
						break; // next month/year on page down/+ ctrl
7768
				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
7769
						handled = event.ctrlKey || event.metaKey;
7770
						break; // clear on ctrl or command +end
7771
				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7772
						handled = event.ctrlKey || event.metaKey;
7773
						break; // current on ctrl or command +home
7774
				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7775
						handled = event.ctrlKey || event.metaKey;
7776
						// -1 day on ctrl or command +left
7777
						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7778
									-$.datepicker._get(inst, 'stepBigMonths') :
7779
									-$.datepicker._get(inst, 'stepMonths')), 'M');
7780
						// next month/year on alt +left on Mac
7781
						break;
7782
				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7783
						handled = event.ctrlKey || event.metaKey;
7784
						break; // -1 week on ctrl or command +up
7785
				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7786
						handled = event.ctrlKey || event.metaKey;
7787
						// +1 day on ctrl or command +right
7788
						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7789
									+$.datepicker._get(inst, 'stepBigMonths') :
7790
									+$.datepicker._get(inst, 'stepMonths')), 'M');
7791
						// next month/year on alt +right
7792
						break;
7793
				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7794
						handled = event.ctrlKey || event.metaKey;
7795
						break; // +1 week on ctrl or command +down
7796
				default: handled = false;
7797
			}
7798
		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7799
			$.datepicker._showDatepicker(this);
7800
		else {
7801
			handled = false;
7802
		}
7803
		if (handled) {
7804
			event.preventDefault();
7805
			event.stopPropagation();
7806
		}
7807
	},
7808
 
7809
	/* Filter entered characters - based on date format. */
7810
	_doKeyPress: function(event) {
7811
		var inst = $.datepicker._getInst(event.target);
7812
		if ($.datepicker._get(inst, 'constrainInput')) {
7813
			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7814
			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7815
			return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7816
		}
7817
	},
7818
 
7819
	/* Synchronise manual entry and field/alternate field. */
7820
	_doKeyUp: function(event) {
7821
		var inst = $.datepicker._getInst(event.target);
7822
		if (inst.input.val() != inst.lastVal) {
7823
			try {
7824
				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7825
					(inst.input ? inst.input.val() : null),
7826
					$.datepicker._getFormatConfig(inst));
7827
				if (date) { // only if valid
7828
					$.datepicker._setDateFromField(inst);
7829
					$.datepicker._updateAlternate(inst);
7830
					$.datepicker._updateDatepicker(inst);
7831
				}
7832
			}
7833
			catch (err) {
7834
				$.datepicker.log(err);
7835
			}
7836
		}
7837
		return true;
7838
	},
7839
 
7840
	/* Pop-up the date picker for a given input field.
7841
	   If false returned from beforeShow event handler do not show.
7842
	   @param  input  element - the input field attached to the date picker or
7843
	                  event - if triggered by focus */
7844
	_showDatepicker: function(input) {
7845
		input = input.target || input;
7846
		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7847
			input = $('input', input.parentNode)[0];
7848
		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7849
			return;
7850
		var inst = $.datepicker._getInst(input);
7851
		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7852
			$.datepicker._curInst.dpDiv.stop(true, true);
7853
			if ( inst && $.datepicker._datepickerShowing ) {
7854
				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7855
			}
7856
		}
7857
		var beforeShow = $.datepicker._get(inst, 'beforeShow');
7858
		var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7859
		if(beforeShowSettings === false){
7860
			//false
7861
			return;
7862
		}
7863
		extendRemove(inst.settings, beforeShowSettings);
7864
		inst.lastVal = null;
7865
		$.datepicker._lastInput = input;
7866
		$.datepicker._setDateFromField(inst);
7867
		if ($.datepicker._inDialog) // hide cursor
7868
			input.value = '';
7869
		if (!$.datepicker._pos) { // position below input
7870
			$.datepicker._pos = $.datepicker._findPos(input);
7871
			$.datepicker._pos[1] += input.offsetHeight; // add the height
7872
		}
7873
		var isFixed = false;
7874
		$(input).parents().each(function() {
7875
			isFixed |= $(this).css('position') == 'fixed';
7876
			return !isFixed;
7877
		});
7878
		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7879
		$.datepicker._pos = null;
7880
		//to avoid flashes on Firefox
7881
		inst.dpDiv.empty();
7882
		// determine sizing offscreen
7883
		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7884
		$.datepicker._updateDatepicker(inst);
7885
		// fix width for dynamic number of date pickers
7886
		// and adjust position before showing
7887
		offset = $.datepicker._checkOffset(inst, offset, isFixed);
7888
		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7889
			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7890
			left: offset.left + 'px', top: offset.top + 'px'});
7891
		if (!inst.inline) {
7892
			var showAnim = $.datepicker._get(inst, 'showAnim');
7893
			var duration = $.datepicker._get(inst, 'duration');
7894
			var postProcess = function() {
7895
				var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7896
				if( !! cover.length ){
7897
					var borders = $.datepicker._getBorders(inst.dpDiv);
7898
					cover.css({left: -borders[0], top: -borders[1],
7899
						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7900
				}
7901
			};
7902
			inst.dpDiv.zIndex($(input).zIndex()+1);
7903
			$.datepicker._datepickerShowing = true;
7904
 
7905
			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7906
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
7907
				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7908
			else
7909
				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7910
			if (!showAnim || !duration)
7911
				postProcess();
7912
			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7913
				inst.input.focus();
7914
			$.datepicker._curInst = inst;
7915
		}
7916
	},
7917
 
7918
	/* Generate the date picker content. */
7919
	_updateDatepicker: function(inst) {
7920
		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7921
		var borders = $.datepicker._getBorders(inst.dpDiv);
7922
		instActive = inst; // for delegate hover events
7923
		inst.dpDiv.empty().append(this._generateHTML(inst));
7924
		this._attachHandlers(inst);
7925
		var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7926
		if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7927
			cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7928
		}
7929
		inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
7930
		var numMonths = this._getNumberOfMonths(inst);
7931
		var cols = numMonths[1];
7932
		var width = 17;
7933
		inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
7934
		if (cols > 1)
7935
			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
7936
		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
7937
			'Class']('ui-datepicker-multi');
7938
		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
7939
			'Class']('ui-datepicker-rtl');
7940
		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
7941
				// #6694 - don't focus the input if it's already focused
7942
				// this breaks the change event in IE
7943
				inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
7944
			inst.input.focus();
7945
		// deffered render of the years select (to avoid flashes on Firefox)
7946
		if( inst.yearshtml ){
7947
			var origyearshtml = inst.yearshtml;
7948
			setTimeout(function(){
7949
				//assure that inst.yearshtml didn't change.
7950
				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7951
					inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
7952
				}
7953
				origyearshtml = inst.yearshtml = null;
7954
			}, 0);
7955
		}
7956
	},
7957
 
7958
	/* Retrieve the size of left and top borders for an element.
7959
	   @param  elem  (jQuery object) the element of interest
7960
	   @return  (number[2]) the left and top borders */
7961
	_getBorders: function(elem) {
7962
		var convert = function(value) {
7963
			return {thin: 1, medium: 2, thick: 3}[value] || value;
7964
		};
7965
		return [parseFloat(convert(elem.css('border-left-width'))),
7966
			parseFloat(convert(elem.css('border-top-width')))];
7967
	},
7968
 
7969
	/* Check positioning to remain on screen. */
7970
	_checkOffset: function(inst, offset, isFixed) {
7971
		var dpWidth = inst.dpDiv.outerWidth();
7972
		var dpHeight = inst.dpDiv.outerHeight();
7973
		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
7974
		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
7975
		var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
7976
		var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7977
 
7978
		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
7979
		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
7980
		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7981
 
7982
		// now check if datepicker is showing outside window viewport - move to a better place if so.
7983
		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7984
			Math.abs(offset.left + dpWidth - viewWidth) : 0);
7985
		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7986
			Math.abs(dpHeight + inputHeight) : 0);
7987
 
7988
		return offset;
7989
	},
7990
 
7991
	/* Find an object's position on the screen. */
7992
	_findPos: function(obj) {
7993
		var inst = this._getInst(obj);
7994
		var isRTL = this._get(inst, 'isRTL');
7995
		while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
7996
			obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
7997
		}
7998
		var position = $(obj).offset();
7999
		return [position.left, position.top];
8000
	},
8001
 
8002
	/* Hide the date picker from view.
8003
	   @param  input  element - the input field attached to the date picker */
8004
	_hideDatepicker: function(input) {
8005
		var inst = this._curInst;
8006
		if (!inst || (input && inst != $.data(input, PROP_NAME)))
8007
			return;
8008
		if (this._datepickerShowing) {
8009
			var showAnim = this._get(inst, 'showAnim');
8010
			var duration = this._get(inst, 'duration');
8011
			var postProcess = function() {
8012
				$.datepicker._tidyDialog(inst);
8013
			};
8014
 
8015
			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8016
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
8017
				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8018
			else
8019
				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
8020
					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
8021
			if (!showAnim)
8022
				postProcess();
8023
			this._datepickerShowing = false;
8024
			var onClose = this._get(inst, 'onClose');
8025
			if (onClose)
8026
				onClose.apply((inst.input ? inst.input[0] : null),
8027
					[(inst.input ? inst.input.val() : ''), inst]);
8028
			this._lastInput = null;
8029
			if (this._inDialog) {
8030
				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
8031
				if ($.blockUI) {
8032
					$.unblockUI();
8033
					$('body').append(this.dpDiv);
8034
				}
8035
			}
8036
			this._inDialog = false;
8037
		}
8038
	},
8039
 
8040
	/* Tidy up after a dialog display. */
8041
	_tidyDialog: function(inst) {
8042
		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
8043
	},
8044
 
8045
	/* Close date picker if clicked elsewhere. */
8046
	_checkExternalClick: function(event) {
8047
		if (!$.datepicker._curInst)
8048
			return;
8049
 
8050
		var $target = $(event.target),
8051
			inst = $.datepicker._getInst($target[0]);
8052
 
8053
		if ( ( ( $target[0].id != $.datepicker._mainDivId &&
8054
				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
8055
				!$target.hasClass($.datepicker.markerClassName) &&
8056
				!$target.closest("." + $.datepicker._triggerClass).length &&
8057
				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8058
			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
8059
			$.datepicker._hideDatepicker();
8060
	},
8061
 
8062
	/* Adjust one of the date sub-fields. */
8063
	_adjustDate: function(id, offset, period) {
8064
		var target = $(id);
8065
		var inst = this._getInst(target[0]);
8066
		if (this._isDisabledDatepicker(target[0])) {
8067
			return;
8068
		}
8069
		this._adjustInstDate(inst, offset +
8070
			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
8071
			period);
8072
		this._updateDatepicker(inst);
8073
	},
8074
 
8075
	/* Action for current link. */
8076
	_gotoToday: function(id) {
8077
		var target = $(id);
8078
		var inst = this._getInst(target[0]);
8079
		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
8080
			inst.selectedDay = inst.currentDay;
8081
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8082
			inst.drawYear = inst.selectedYear = inst.currentYear;
8083
		}
8084
		else {
8085
			var date = new Date();
8086
			inst.selectedDay = date.getDate();
8087
			inst.drawMonth = inst.selectedMonth = date.getMonth();
8088
			inst.drawYear = inst.selectedYear = date.getFullYear();
8089
		}
8090
		this._notifyChange(inst);
8091
		this._adjustDate(target);
8092
	},
8093
 
8094
	/* Action for selecting a new month/year. */
8095
	_selectMonthYear: function(id, select, period) {
8096
		var target = $(id);
8097
		var inst = this._getInst(target[0]);
8098
		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
8099
		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
8100
			parseInt(select.options[select.selectedIndex].value,10);
8101
		this._notifyChange(inst);
8102
		this._adjustDate(target);
8103
	},
8104
 
8105
	/* Action for selecting a day. */
8106
	_selectDay: function(id, month, year, td) {
8107
		var target = $(id);
8108
		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8109
			return;
8110
		}
8111
		var inst = this._getInst(target[0]);
8112
		inst.selectedDay = inst.currentDay = $('a', td).html();
8113
		inst.selectedMonth = inst.currentMonth = month;
8114
		inst.selectedYear = inst.currentYear = year;
8115
		this._selectDate(id, this._formatDate(inst,
8116
			inst.currentDay, inst.currentMonth, inst.currentYear));
8117
	},
8118
 
8119
	/* Erase the input field and hide the date picker. */
8120
	_clearDate: function(id) {
8121
		var target = $(id);
8122
		var inst = this._getInst(target[0]);
8123
		this._selectDate(target, '');
8124
	},
8125
 
8126
	/* Update the input field with the selected date. */
8127
	_selectDate: function(id, dateStr) {
8128
		var target = $(id);
8129
		var inst = this._getInst(target[0]);
8130
		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8131
		if (inst.input)
8132
			inst.input.val(dateStr);
8133
		this._updateAlternate(inst);
8134
		var onSelect = this._get(inst, 'onSelect');
8135
		if (onSelect)
8136
			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8137
		else if (inst.input)
8138
			inst.input.trigger('change'); // fire the change event
8139
		if (inst.inline)
8140
			this._updateDatepicker(inst);
8141
		else {
8142
			this._hideDatepicker();
8143
			this._lastInput = inst.input[0];
8144
			if (typeof(inst.input[0]) != 'object')
8145
				inst.input.focus(); // restore focus
8146
			this._lastInput = null;
8147
		}
8148
	},
8149
 
8150
	/* Update any alternate field to synchronise with the main field. */
8151
	_updateAlternate: function(inst) {
8152
		var altField = this._get(inst, 'altField');
8153
		if (altField) { // update alternate field too
8154
			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
8155
			var date = this._getDate(inst);
8156
			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8157
			$(altField).each(function() { $(this).val(dateStr); });
8158
		}
8159
	},
8160
 
8161
	/* Set as beforeShowDay function to prevent selection of weekends.
8162
	   @param  date  Date - the date to customise
8163
	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
8164
	noWeekends: function(date) {
8165
		var day = date.getDay();
8166
		return [(day > 0 && day < 6), ''];
8167
	},
8168
 
8169
	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8170
	   @param  date  Date - the date to get the week for
8171
	   @return  number - the number of the week within the year that contains this date */
8172
	iso8601Week: function(date) {
8173
		var checkDate = new Date(date.getTime());
8174
		// Find Thursday of this week starting on Monday
8175
		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8176
		var time = checkDate.getTime();
8177
		checkDate.setMonth(0); // Compare with Jan 1
8178
		checkDate.setDate(1);
8179
		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8180
	},
8181
 
8182
	/* Parse a string value into a date object.
8183
	   See formatDate below for the possible formats.
8184
 
8185
	   @param  format    string - the expected format of the date
8186
	   @param  value     string - the date in the above format
8187
	   @param  settings  Object - attributes include:
8188
	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
8189
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
8190
	                     dayNames         string[7] - names of the days from Sunday (optional)
8191
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
8192
	                     monthNames       string[12] - names of the months (optional)
8193
	   @return  Date - the extracted date value or null if value is blank */
8194
	parseDate: function (format, value, settings) {
8195
		if (format == null || value == null)
8196
			throw 'Invalid arguments';
8197
		value = (typeof value == 'object' ? value.toString() : value + '');
8198
		if (value == '')
8199
			return null;
8200
		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
8201
		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8202
				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8203
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8204
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8205
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8206
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8207
		var year = -1;
8208
		var month = -1;
8209
		var day = -1;
8210
		var doy = -1;
8211
		var literal = false;
8212
		// Check whether a format character is doubled
8213
		var lookAhead = function(match) {
8214
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8215
			if (matches)
8216
				iFormat++;
8217
			return matches;
8218
		};
8219
		// Extract a number from the string value
8220
		var getNumber = function(match) {
8221
			var isDoubled = lookAhead(match);
8222
			var size = (match == '@' ? 14 : (match == '!' ? 20 :
8223
				(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
8224
			var digits = new RegExp('^\\d{1,' + size + '}');
8225
			var num = value.substring(iValue).match(digits);
8226
			if (!num)
8227
				throw 'Missing number at position ' + iValue;
8228
			iValue += num[0].length;
8229
			return parseInt(num[0], 10);
8230
		};
8231
		// Extract a name from the string value and convert to an index
8232
		var getName = function(match, shortNames, longNames) {
8233
			var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8234
				return [ [k, v] ];
8235
			}).sort(function (a, b) {
8236
				return -(a[1].length - b[1].length);
8237
			});
8238
			var index = -1;
8239
			$.each(names, function (i, pair) {
8240
				var name = pair[1];
8241
				if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
8242
					index = pair[0];
8243
					iValue += name.length;
8244
					return false;
8245
				}
8246
			});
8247
			if (index != -1)
8248
				return index + 1;
8249
			else
8250
				throw 'Unknown name at position ' + iValue;
8251
		};
8252
		// Confirm that a literal character matches the string value
8253
		var checkLiteral = function() {
8254
			if (value.charAt(iValue) != format.charAt(iFormat))
8255
				throw 'Unexpected literal at position ' + iValue;
8256
			iValue++;
8257
		};
8258
		var iValue = 0;
8259
		for (var iFormat = 0; iFormat < format.length; iFormat++) {
8260
			if (literal)
8261
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8262
					literal = false;
8263
				else
8264
					checkLiteral();
8265
			else
8266
				switch (format.charAt(iFormat)) {
8267
					case 'd':
8268
						day = getNumber('d');
8269
						break;
8270
					case 'D':
8271
						getName('D', dayNamesShort, dayNames);
8272
						break;
8273
					case 'o':
8274
						doy = getNumber('o');
8275
						break;
8276
					case 'm':
8277
						month = getNumber('m');
8278
						break;
8279
					case 'M':
8280
						month = getName('M', monthNamesShort, monthNames);
8281
						break;
8282
					case 'y':
8283
						year = getNumber('y');
8284
						break;
8285
					case '@':
8286
						var date = new Date(getNumber('@'));
8287
						year = date.getFullYear();
8288
						month = date.getMonth() + 1;
8289
						day = date.getDate();
8290
						break;
8291
					case '!':
8292
						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
8293
						year = date.getFullYear();
8294
						month = date.getMonth() + 1;
8295
						day = date.getDate();
8296
						break;
8297
					case "'":
8298
						if (lookAhead("'"))
8299
							checkLiteral();
8300
						else
8301
							literal = true;
8302
						break;
8303
					default:
8304
						checkLiteral();
8305
				}
8306
		}
8307
		if (iValue < value.length){
8308
			var extra = value.substr(iValue);
8309
			if (!/^\s+/.test(extra)) {
8310
				throw "Extra/unparsed characters found in date: " + extra;
8311
			}
8312
		}
8313
		if (year == -1)
8314
			year = new Date().getFullYear();
8315
		else if (year < 100)
8316
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8317
				(year <= shortYearCutoff ? 0 : -100);
8318
		if (doy > -1) {
8319
			month = 1;
8320
			day = doy;
8321
			do {
8322
				var dim = this._getDaysInMonth(year, month - 1);
8323
				if (day <= dim)
8324
					break;
8325
				month++;
8326
				day -= dim;
8327
			} while (true);
8328
		}
8329
		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8330
		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
8331
			throw 'Invalid date'; // E.g. 31/02/00
8332
		return date;
8333
	},
8334
 
8335
	/* Standard date formats. */
8336
	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
8337
	COOKIE: 'D, dd M yy',
8338
	ISO_8601: 'yy-mm-dd',
8339
	RFC_822: 'D, d M y',
8340
	RFC_850: 'DD, dd-M-y',
8341
	RFC_1036: 'D, d M y',
8342
	RFC_1123: 'D, d M yy',
8343
	RFC_2822: 'D, d M yy',
8344
	RSS: 'D, d M y', // RFC 822
8345
	TICKS: '!',
8346
	TIMESTAMP: '@',
8347
	W3C: 'yy-mm-dd', // ISO 8601
8348
 
8349
	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8350
		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8351
 
8352
	/* Format a date object into a string value.
8353
	   The format can be combinations of the following:
8354
	   d  - day of month (no leading zero)
8355
	   dd - day of month (two digit)
8356
	   o  - day of year (no leading zeros)
8357
	   oo - day of year (three digit)
8358
	   D  - day name short
8359
	   DD - day name long
8360
	   m  - month of year (no leading zero)
8361
	   mm - month of year (two digit)
8362
	   M  - month name short
8363
	   MM - month name long
8364
	   y  - year (two digit)
8365
	   yy - year (four digit)
8366
	   @ - Unix timestamp (ms since 01/01/1970)
8367
	   ! - Windows ticks (100ns since 01/01/0001)
8368
	   '...' - literal text
8369
	   '' - single quote
8370
 
8371
	   @param  format    string - the desired format of the date
8372
	   @param  date      Date - the date value to format
8373
	   @param  settings  Object - attributes include:
8374
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
8375
	                     dayNames         string[7] - names of the days from Sunday (optional)
8376
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
8377
	                     monthNames       string[12] - names of the months (optional)
8378
	   @return  string - the date in the above format */
8379
	formatDate: function (format, date, settings) {
8380
		if (!date)
8381
			return '';
8382
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8383
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8384
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8385
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8386
		// Check whether a format character is doubled
8387
		var lookAhead = function(match) {
8388
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8389
			if (matches)
8390
				iFormat++;
8391
			return matches;
8392
		};
8393
		// Format a number, with leading zero if necessary
8394
		var formatNumber = function(match, value, len) {
8395
			var num = '' + value;
8396
			if (lookAhead(match))
8397
				while (num.length < len)
8398
					num = '0' + num;
8399
			return num;
8400
		};
8401
		// Format a name, short or long as requested
8402
		var formatName = function(match, value, shortNames, longNames) {
8403
			return (lookAhead(match) ? longNames[value] : shortNames[value]);
8404
		};
8405
		var output = '';
8406
		var literal = false;
8407
		if (date)
8408
			for (var iFormat = 0; iFormat < format.length; iFormat++) {
8409
				if (literal)
8410
					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8411
						literal = false;
8412
					else
8413
						output += format.charAt(iFormat);
8414
				else
8415
					switch (format.charAt(iFormat)) {
8416
						case 'd':
8417
							output += formatNumber('d', date.getDate(), 2);
8418
							break;
8419
						case 'D':
8420
							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
8421
							break;
8422
						case 'o':
8423
							output += formatNumber('o',
8424
								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8425
							break;
8426
						case 'm':
8427
							output += formatNumber('m', date.getMonth() + 1, 2);
8428
							break;
8429
						case 'M':
8430
							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
8431
							break;
8432
						case 'y':
8433
							output += (lookAhead('y') ? date.getFullYear() :
8434
								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
8435
							break;
8436
						case '@':
8437
							output += date.getTime();
8438
							break;
8439
						case '!':
8440
							output += date.getTime() * 10000 + this._ticksTo1970;
8441
							break;
8442
						case "'":
8443
							if (lookAhead("'"))
8444
								output += "'";
8445
							else
8446
								literal = true;
8447
							break;
8448
						default:
8449
							output += format.charAt(iFormat);
8450
					}
8451
			}
8452
		return output;
8453
	},
8454
 
8455
	/* Extract all possible characters from the date format. */
8456
	_possibleChars: function (format) {
8457
		var chars = '';
8458
		var literal = false;
8459
		// Check whether a format character is doubled
8460
		var lookAhead = function(match) {
8461
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8462
			if (matches)
8463
				iFormat++;
8464
			return matches;
8465
		};
8466
		for (var iFormat = 0; iFormat < format.length; iFormat++)
8467
			if (literal)
8468
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8469
					literal = false;
8470
				else
8471
					chars += format.charAt(iFormat);
8472
			else
8473
				switch (format.charAt(iFormat)) {
8474
					case 'd': case 'm': case 'y': case '@':
8475
						chars += '0123456789';
8476
						break;
8477
					case 'D': case 'M':
8478
						return null; // Accept anything
8479
					case "'":
8480
						if (lookAhead("'"))
8481
							chars += "'";
8482
						else
8483
							literal = true;
8484
						break;
8485
					default:
8486
						chars += format.charAt(iFormat);
8487
				}
8488
		return chars;
8489
	},
8490
 
8491
	/* Get a setting value, defaulting if necessary. */
8492
	_get: function(inst, name) {
8493
		return inst.settings[name] !== undefined ?
8494
			inst.settings[name] : this._defaults[name];
8495
	},
8496
 
8497
	/* Parse existing date and initialise date picker. */
8498
	_setDateFromField: function(inst, noDefault) {
8499
		if (inst.input.val() == inst.lastVal) {
8500
			return;
8501
		}
8502
		var dateFormat = this._get(inst, 'dateFormat');
8503
		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
8504
		var date, defaultDate;
8505
		date = defaultDate = this._getDefaultDate(inst);
8506
		var settings = this._getFormatConfig(inst);
8507
		try {
8508
			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8509
		} catch (event) {
8510
			this.log(event);
8511
			dates = (noDefault ? '' : dates);
8512
		}
8513
		inst.selectedDay = date.getDate();
8514
		inst.drawMonth = inst.selectedMonth = date.getMonth();
8515
		inst.drawYear = inst.selectedYear = date.getFullYear();
8516
		inst.currentDay = (dates ? date.getDate() : 0);
8517
		inst.currentMonth = (dates ? date.getMonth() : 0);
8518
		inst.currentYear = (dates ? date.getFullYear() : 0);
8519
		this._adjustInstDate(inst);
8520
	},
8521
 
8522
	/* Retrieve the default date shown on opening. */
8523
	_getDefaultDate: function(inst) {
8524
		return this._restrictMinMax(inst,
8525
			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
8526
	},
8527
 
8528
	/* A date may be specified as an exact value or a relative one. */
8529
	_determineDate: function(inst, date, defaultDate) {
8530
		var offsetNumeric = function(offset) {
8531
			var date = new Date();
8532
			date.setDate(date.getDate() + offset);
8533
			return date;
8534
		};
8535
		var offsetString = function(offset) {
8536
			try {
8537
				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8538
					offset, $.datepicker._getFormatConfig(inst));
8539
			}
8540
			catch (e) {
8541
				// Ignore
8542
			}
8543
			var date = (offset.toLowerCase().match(/^c/) ?
8544
				$.datepicker._getDate(inst) : null) || new Date();
8545
			var year = date.getFullYear();
8546
			var month = date.getMonth();
8547
			var day = date.getDate();
8548
			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
8549
			var matches = pattern.exec(offset);
8550
			while (matches) {
8551
				switch (matches[2] || 'd') {
8552
					case 'd' : case 'D' :
8553
						day += parseInt(matches[1],10); break;
8554
					case 'w' : case 'W' :
8555
						day += parseInt(matches[1],10) * 7; break;
8556
					case 'm' : case 'M' :
8557
						month += parseInt(matches[1],10);
8558
						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8559
						break;
8560
					case 'y': case 'Y' :
8561
						year += parseInt(matches[1],10);
8562
						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8563
						break;
8564
				}
8565
				matches = pattern.exec(offset);
8566
			}
8567
			return new Date(year, month, day);
8568
		};
8569
		var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
8570
			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8571
		newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
8572
		if (newDate) {
8573
			newDate.setHours(0);
8574
			newDate.setMinutes(0);
8575
			newDate.setSeconds(0);
8576
			newDate.setMilliseconds(0);
8577
		}
8578
		return this._daylightSavingAdjust(newDate);
8579
	},
8580
 
8581
	/* Handle switch to/from daylight saving.
8582
	   Hours may be non-zero on daylight saving cut-over:
8583
	   > 12 when midnight changeover, but then cannot generate
8584
	   midnight datetime, so jump to 1AM, otherwise reset.
8585
	   @param  date  (Date) the date to check
8586
	   @return  (Date) the corrected date */
8587
	_daylightSavingAdjust: function(date) {
8588
		if (!date) return null;
8589
		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8590
		return date;
8591
	},
8592
 
8593
	/* Set the date(s) directly. */
8594
	_setDate: function(inst, date, noChange) {
8595
		var clear = !date;
8596
		var origMonth = inst.selectedMonth;
8597
		var origYear = inst.selectedYear;
8598
		var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8599
		inst.selectedDay = inst.currentDay = newDate.getDate();
8600
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8601
		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8602
		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
8603
			this._notifyChange(inst);
8604
		this._adjustInstDate(inst);
8605
		if (inst.input) {
8606
			inst.input.val(clear ? '' : this._formatDate(inst));
8607
		}
8608
	},
8609
 
8610
	/* Retrieve the date(s) directly. */
8611
	_getDate: function(inst) {
8612
		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
8613
			this._daylightSavingAdjust(new Date(
8614
			inst.currentYear, inst.currentMonth, inst.currentDay)));
8615
			return startDate;
8616
	},
8617
 
8618
	/* Attach the onxxx handlers.  These are declared statically so
8619
	 * they work with static code transformers like Caja.
8620
	 */
8621
	_attachHandlers: function(inst) {
8622
		var stepMonths = this._get(inst, 'stepMonths');
8623
		var id = '#' + inst.id.replace( /\\\\/g, "\\" );
8624
		inst.dpDiv.find('[data-handler]').map(function () {
8625
			var handler = {
8626
				prev: function () {
8627
					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
8628
				},
8629
				next: function () {
8630
					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
8631
				},
8632
				hide: function () {
8633
					window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
8634
				},
8635
				today: function () {
8636
					window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
8637
				},
8638
				selectDay: function () {
8639
					window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
8640
					return false;
8641
				},
8642
				selectMonth: function () {
8643
					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
8644
					return false;
8645
				},
8646
				selectYear: function () {
8647
					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
8648
					return false;
8649
				}
8650
			};
8651
			$(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
8652
		});
8653
	},
8654
 
8655
	/* Generate the HTML for the current state of the date picker. */
8656
	_generateHTML: function(inst) {
8657
		var today = new Date();
8658
		today = this._daylightSavingAdjust(
8659
			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
8660
		var isRTL = this._get(inst, 'isRTL');
8661
		var showButtonPanel = this._get(inst, 'showButtonPanel');
8662
		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
8663
		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
8664
		var numMonths = this._getNumberOfMonths(inst);
8665
		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
8666
		var stepMonths = this._get(inst, 'stepMonths');
8667
		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
8668
		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8669
			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8670
		var minDate = this._getMinMaxDate(inst, 'min');
8671
		var maxDate = this._getMinMaxDate(inst, 'max');
8672
		var drawMonth = inst.drawMonth - showCurrentAtPos;
8673
		var drawYear = inst.drawYear;
8674
		if (drawMonth < 0) {
8675
			drawMonth += 12;
8676
			drawYear--;
8677
		}
8678
		if (maxDate) {
8679
			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8680
				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8681
			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8682
			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8683
				drawMonth--;
8684
				if (drawMonth < 0) {
8685
					drawMonth = 11;
8686
					drawYear--;
8687
				}
8688
			}
8689
		}
8690
		inst.drawMonth = drawMonth;
8691
		inst.drawYear = drawYear;
8692
		var prevText = this._get(inst, 'prevText');
8693
		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8694
			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8695
			this._getFormatConfig(inst)));
8696
		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8697
			'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
8698
			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
8699
			(hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
8700
		var nextText = this._get(inst, 'nextText');
8701
		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8702
			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8703
			this._getFormatConfig(inst)));
8704
		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8705
			'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
8706
			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
8707
			(hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
8708
		var currentText = this._get(inst, 'currentText');
8709
		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
8710
		currentText = (!navigationAsDateFormat ? currentText :
8711
			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8712
		var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">' +
8713
			this._get(inst, 'closeText') + '</button>' : '');
8714
		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
8715
			(this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click"' +
8716
			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
8717
		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
8718
		firstDay = (isNaN(firstDay) ? 0 : firstDay);
8719
		var showWeek = this._get(inst, 'showWeek');
8720
		var dayNames = this._get(inst, 'dayNames');
8721
		var dayNamesShort = this._get(inst, 'dayNamesShort');
8722
		var dayNamesMin = this._get(inst, 'dayNamesMin');
8723
		var monthNames = this._get(inst, 'monthNames');
8724
		var monthNamesShort = this._get(inst, 'monthNamesShort');
8725
		var beforeShowDay = this._get(inst, 'beforeShowDay');
8726
		var showOtherMonths = this._get(inst, 'showOtherMonths');
8727
		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
8728
		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
8729
		var defaultDate = this._getDefaultDate(inst);
8730
		var html = '';
8731
		for (var row = 0; row < numMonths[0]; row++) {
8732
			var group = '';
8733
			this.maxRows = 4;
8734
			for (var col = 0; col < numMonths[1]; col++) {
8735
				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8736
				var cornerClass = ' ui-corner-all';
8737
				var calender = '';
8738
				if (isMultiMonth) {
8739
					calender += '<div class="ui-datepicker-group';
8740
					if (numMonths[1] > 1)
8741
						switch (col) {
8742
							case 0: calender += ' ui-datepicker-group-first';
8743
								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
8744
							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
8745
								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
8746
							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
8747
						}
8748
					calender += '">';
8749
				}
8750
				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
8751
					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
8752
					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
8753
					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8754
					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8755
					'</div><table class="ui-datepicker-calendar"><thead>' +
8756
					'<tr>';
8757
				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
8758
				for (var dow = 0; dow < 7; dow++) { // days of the week
8759
					var day = (dow + firstDay) % 7;
8760
					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
8761
						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
8762
				}
8763
				calender += thead + '</tr></thead><tbody>';
8764
				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8765
				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
8766
					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8767
				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8768
				var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8769
				var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8770
				this.maxRows = numRows;
8771
				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8772
				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8773
					calender += '<tr>';
8774
					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8775
						this._get(inst, 'calculateWeek')(printDate) + '</td>');
8776
					for (var dow = 0; dow < 7; dow++) { // create date picker days
8777
						var daySettings = (beforeShowDay ?
8778
							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8779
						var otherMonth = (printDate.getMonth() != drawMonth);
8780
						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8781
							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8782
						tbody += '<td class="' +
8783
							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8784
							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8785
							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8786
							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8787
							// or defaultDate is current printedDate and defaultDate is selectedDate
8788
							' ' + this._dayOverClass : '') + // highlight selected day
8789
							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
8790
							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8791
							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8792
							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8793
							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8794
							(unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
8795
							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
8796
							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8797
							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8798
							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8799
							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8800
							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8801
						printDate.setDate(printDate.getDate() + 1);
8802
						printDate = this._daylightSavingAdjust(printDate);
8803
					}
8804
					calender += tbody + '</tr>';
8805
				}
8806
				drawMonth++;
8807
				if (drawMonth > 11) {
8808
					drawMonth = 0;
8809
					drawYear++;
8810
				}
8811
				calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
8812
							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8813
				group += calender;
8814
			}
8815
			html += group;
8816
		}
8817
		html += buttonPanel + ($.ui.ie6 && !inst.inline ?
8818
			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8819
		inst._keyEvent = false;
8820
		return html;
8821
	},
8822
 
8823
	/* Generate the month and year header. */
8824
	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8825
			secondary, monthNames, monthNamesShort) {
8826
		var changeMonth = this._get(inst, 'changeMonth');
8827
		var changeYear = this._get(inst, 'changeYear');
8828
		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8829
		var html = '<div class="ui-datepicker-title">';
8830
		var monthHtml = '';
8831
		// month selection
8832
		if (secondary || !changeMonth)
8833
			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8834
		else {
8835
			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8836
			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8837
			monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
8838
			for (var month = 0; month < 12; month++) {
8839
				if ((!inMinYear || month >= minDate.getMonth()) &&
8840
						(!inMaxYear || month <= maxDate.getMonth()))
8841
					monthHtml += '<option value="' + month + '"' +
8842
						(month == drawMonth ? ' selected="selected"' : '') +
8843
						'>' + monthNamesShort[month] + '</option>';
8844
			}
8845
			monthHtml += '</select>';
8846
		}
8847
		if (!showMonthAfterYear)
8848
			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
8849
		// year selection
8850
		if ( !inst.yearshtml ) {
8851
			inst.yearshtml = '';
8852
			if (secondary || !changeYear)
8853
				html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
8854
			else {
8855
				// determine range of years to display
8856
				var years = this._get(inst, 'yearRange').split(':');
8857
				var thisYear = new Date().getFullYear();
8858
				var determineYear = function(value) {
8859
					var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8860
						(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8861
						parseInt(value, 10)));
8862
					return (isNaN(year) ? thisYear : year);
8863
				};
8864
				var year = determineYear(years[0]);
8865
				var endYear = Math.max(year, determineYear(years[1] || ''));
8866
				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8867
				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8868
				inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
8869
				for (; year <= endYear; year++) {
8870
					inst.yearshtml += '<option value="' + year + '"' +
8871
						(year == drawYear ? ' selected="selected"' : '') +
8872
						'>' + year + '</option>';
8873
				}
8874
				inst.yearshtml += '</select>';
8875
 
8876
				html += inst.yearshtml;
8877
				inst.yearshtml = null;
8878
			}
8879
		}
8880
		html += this._get(inst, 'yearSuffix');
8881
		if (showMonthAfterYear)
8882
			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
8883
		html += '</div>'; // Close datepicker_header
8884
		return html;
8885
	},
8886
 
8887
	/* Adjust one of the date sub-fields. */
8888
	_adjustInstDate: function(inst, offset, period) {
8889
		var year = inst.drawYear + (period == 'Y' ? offset : 0);
8890
		var month = inst.drawMonth + (period == 'M' ? offset : 0);
8891
		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8892
			(period == 'D' ? offset : 0);
8893
		var date = this._restrictMinMax(inst,
8894
			this._daylightSavingAdjust(new Date(year, month, day)));
8895
		inst.selectedDay = date.getDate();
8896
		inst.drawMonth = inst.selectedMonth = date.getMonth();
8897
		inst.drawYear = inst.selectedYear = date.getFullYear();
8898
		if (period == 'M' || period == 'Y')
8899
			this._notifyChange(inst);
8900
	},
8901
 
8902
	/* Ensure a date is within any min/max bounds. */
8903
	_restrictMinMax: function(inst, date) {
8904
		var minDate = this._getMinMaxDate(inst, 'min');
8905
		var maxDate = this._getMinMaxDate(inst, 'max');
8906
		var newDate = (minDate && date < minDate ? minDate : date);
8907
		newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8908
		return newDate;
8909
	},
8910
 
8911
	/* Notify change of month/year. */
8912
	_notifyChange: function(inst) {
8913
		var onChange = this._get(inst, 'onChangeMonthYear');
8914
		if (onChange)
8915
			onChange.apply((inst.input ? inst.input[0] : null),
8916
				[inst.selectedYear, inst.selectedMonth + 1, inst]);
8917
	},
8918
 
8919
	/* Determine the number of months to show. */
8920
	_getNumberOfMonths: function(inst) {
8921
		var numMonths = this._get(inst, 'numberOfMonths');
8922
		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8923
	},
8924
 
8925
	/* Determine the current maximum date - ensure no time components are set. */
8926
	_getMinMaxDate: function(inst, minMax) {
8927
		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8928
	},
8929
 
8930
	/* Find the number of days in a given month. */
8931
	_getDaysInMonth: function(year, month) {
8932
		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8933
	},
8934
 
8935
	/* Find the day of the week of the first of a month. */
8936
	_getFirstDayOfMonth: function(year, month) {
8937
		return new Date(year, month, 1).getDay();
8938
	},
8939
 
8940
	/* Determines if we should allow a "next/prev" month display change. */
8941
	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
8942
		var numMonths = this._getNumberOfMonths(inst);
8943
		var date = this._daylightSavingAdjust(new Date(curYear,
8944
			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8945
		if (offset < 0)
8946
			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8947
		return this._isInRange(inst, date);
8948
	},
8949
 
8950
	/* Is the given date in the accepted range? */
8951
	_isInRange: function(inst, date) {
8952
		var minDate = this._getMinMaxDate(inst, 'min');
8953
		var maxDate = this._getMinMaxDate(inst, 'max');
8954
		return ((!minDate || date.getTime() >= minDate.getTime()) &&
8955
			(!maxDate || date.getTime() <= maxDate.getTime()));
8956
	},
8957
 
8958
	/* Provide the configuration settings for formatting/parsing. */
8959
	_getFormatConfig: function(inst) {
8960
		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8961
		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8962
			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8963
		return {shortYearCutoff: shortYearCutoff,
8964
			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
8965
			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
8966
	},
8967
 
8968
	/* Format the given date for display. */
8969
	_formatDate: function(inst, day, month, year) {
8970
		if (!day) {
8971
			inst.currentDay = inst.selectedDay;
8972
			inst.currentMonth = inst.selectedMonth;
8973
			inst.currentYear = inst.selectedYear;
8974
		}
8975
		var date = (day ? (typeof day == 'object' ? day :
8976
			this._daylightSavingAdjust(new Date(year, month, day))) :
8977
			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8978
		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
8979
	}
8980
});
8981
 
8982
/*
8983
 * Bind hover events for datepicker elements.
8984
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8985
 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8986
 */
8987
function bindHover(dpDiv) {
8988
	var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
8989
	return dpDiv.delegate(selector, 'mouseout', function() {
8990
			$(this).removeClass('ui-state-hover');
8991
			if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
8992
			if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
8993
		})
8994
		.delegate(selector, 'mouseover', function(){
8995
			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
8996
				$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
8997
				$(this).addClass('ui-state-hover');
8998
				if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
8999
				if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
9000
			}
9001
		});
9002
}
9003
 
9004
/* jQuery extend now ignores nulls! */
9005
function extendRemove(target, props) {
9006
	$.extend(target, props);
9007
	for (var name in props)
9008
		if (props[name] == null || props[name] == undefined)
9009
			target[name] = props[name];
9010
	return target;
9011
};
9012
 
9013
/* Invoke the datepicker functionality.
9014
   @param  options  string - a command, optionally followed by additional parameters or
9015
	                Object - settings for attaching new datepicker functionality
9016
   @return  jQuery object */
9017
$.fn.datepicker = function(options){
9018
 
9019
	/* Verify an empty collection wasn't passed - Fixes #6976 */
9020
	if ( !this.length ) {
9021
		return this;
9022
	}
9023
 
9024
	/* Initialise the date picker. */
9025
	if (!$.datepicker.initialized) {
9026
		$(document).mousedown($.datepicker._checkExternalClick).
9027
			find(document.body).append($.datepicker.dpDiv);
9028
		$.datepicker.initialized = true;
9029
	}
9030
 
9031
	var otherArgs = Array.prototype.slice.call(arguments, 1);
9032
	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
9033
		return $.datepicker['_' + options + 'Datepicker'].
9034
			apply($.datepicker, [this[0]].concat(otherArgs));
9035
	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
9036
		return $.datepicker['_' + options + 'Datepicker'].
9037
			apply($.datepicker, [this[0]].concat(otherArgs));
9038
	return this.each(function() {
9039
		typeof options == 'string' ?
9040
			$.datepicker['_' + options + 'Datepicker'].
9041
				apply($.datepicker, [this].concat(otherArgs)) :
9042
			$.datepicker._attachDatepicker(this, options);
9043
	});
9044
};
9045
 
9046
$.datepicker = new Datepicker(); // singleton instance
9047
$.datepicker.initialized = false;
9048
$.datepicker.uuid = new Date().getTime();
9049
$.datepicker.version = "1.9.2";
9050
 
9051
// Workaround for #4055
9052
// Add another global to avoid noConflict issues with inline event handlers
9053
window['DP_jQuery_' + dpuuid] = $;
9054
 
9055
})(jQuery);
9056
 
9057
(function( $, undefined ) {
9058
 
9059
var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
9060
	sizeRelatedOptions = {
9061
		buttons: true,
9062
		height: true,
9063
		maxHeight: true,
9064
		maxWidth: true,
9065
		minHeight: true,
9066
		minWidth: true,
9067
		width: true
9068
	},
9069
	resizableRelatedOptions = {
9070
		maxHeight: true,
9071
		maxWidth: true,
9072
		minHeight: true,
9073
		minWidth: true
9074
	};
9075
 
9076
$.widget("ui.dialog", {
9077
	version: "1.9.2",
9078
	options: {
9079
		autoOpen: true,
9080
		buttons: {},
9081
		closeOnEscape: true,
9082
		closeText: "close",
9083
		dialogClass: "",
9084
		draggable: true,
9085
		hide: null,
9086
		height: "auto",
9087
		maxHeight: false,
9088
		maxWidth: false,
9089
		minHeight: 150,
9090
		minWidth: 150,
9091
		modal: false,
9092
		position: {
9093
			my: "center",
9094
			at: "center",
9095
			of: window,
9096
			collision: "fit",
9097
			// ensure that the titlebar is never outside the document
9098
			using: function( pos ) {
9099
				var topOffset = $( this ).css( pos ).offset().top;
9100
				if ( topOffset < 0 ) {
9101
					$( this ).css( "top", pos.top - topOffset );
9102
				}
9103
			}
9104
		},
9105
		resizable: true,
9106
		show: null,
9107
		stack: true,
9108
		title: "",
9109
		width: 300,
9110
		zIndex: 1000
9111
	},
9112
 
9113
	_create: function() {
9114
		this.originalTitle = this.element.attr( "title" );
9115
		// #5742 - .attr() might return a DOMElement
9116
		if ( typeof this.originalTitle !== "string" ) {
9117
			this.originalTitle = "";
9118
		}
9119
		this.oldPosition = {
9120
			parent: this.element.parent(),
9121
			index: this.element.parent().children().index( this.element )
9122
		};
9123
		this.options.title = this.options.title || this.originalTitle;
9124
		var that = this,
9125
			options = this.options,
9126
 
9127
			title = options.title || "&#160;",
9128
			uiDialog,
9129
			uiDialogTitlebar,
9130
			uiDialogTitlebarClose,
9131
			uiDialogTitle,
9132
			uiDialogButtonPane;
9133
 
9134
			uiDialog = ( this.uiDialog = $( "<div>" ) )
9135
				.addClass( uiDialogClasses + options.dialogClass )
9136
				.css({
9137
					display: "none",
9138
					outline: 0, // TODO: move to stylesheet
9139
					zIndex: options.zIndex
9140
				})
9141
				// setting tabIndex makes the div focusable
9142
				.attr( "tabIndex", -1)
9143
				.keydown(function( event ) {
9144
					if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9145
							event.keyCode === $.ui.keyCode.ESCAPE ) {
9146
						that.close( event );
9147
						event.preventDefault();
9148
					}
9149
				})
9150
				.mousedown(function( event ) {
9151
					that.moveToTop( false, event );
9152
				})
9153
				.appendTo( "body" );
9154
 
9155
			this.element
9156
				.show()
9157
				.removeAttr( "title" )
9158
				.addClass( "ui-dialog-content ui-widget-content" )
9159
				.appendTo( uiDialog );
9160
 
9161
			uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
9162
				.addClass( "ui-dialog-titlebar  ui-widget-header  " +
9163
					"ui-corner-all  ui-helper-clearfix" )
9164
				.bind( "mousedown", function() {
9165
					// Dialog isn't getting focus when dragging (#8063)
9166
					uiDialog.focus();
9167
				})
9168
				.prependTo( uiDialog );
9169
 
9170
			uiDialogTitlebarClose = $( "<a href='#'></a>" )
9171
				.addClass( "ui-dialog-titlebar-close  ui-corner-all" )
9172
				.attr( "role", "button" )
9173
				.click(function( event ) {
9174
					event.preventDefault();
9175
					that.close( event );
9176
				})
9177
				.appendTo( uiDialogTitlebar );
9178
 
9179
			( this.uiDialogTitlebarCloseText = $( "<span>" ) )
9180
				.addClass( "ui-icon ui-icon-closethick" )
9181
				.text( options.closeText )
9182
				.appendTo( uiDialogTitlebarClose );
9183
 
9184
			uiDialogTitle = $( "<span>" )
9185
				.uniqueId()
9186
				.addClass( "ui-dialog-title" )
9187
				.html( title )
9188
				.prependTo( uiDialogTitlebar );
9189
 
9190
			uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
9191
				.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
9192
 
9193
			( this.uiButtonSet = $( "<div>" ) )
9194
				.addClass( "ui-dialog-buttonset" )
9195
				.appendTo( uiDialogButtonPane );
9196
 
9197
		uiDialog.attr({
9198
			role: "dialog",
9199
			"aria-labelledby": uiDialogTitle.attr( "id" )
9200
		});
9201
 
9202
		uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
9203
		this._hoverable( uiDialogTitlebarClose );
9204
		this._focusable( uiDialogTitlebarClose );
9205
 
9206
		if ( options.draggable && $.fn.draggable ) {
9207
			this._makeDraggable();
9208
		}
9209
		if ( options.resizable && $.fn.resizable ) {
9210
			this._makeResizable();
9211
		}
9212
 
9213
		this._createButtons( options.buttons );
9214
		this._isOpen = false;
9215
 
9216
		if ( $.fn.bgiframe ) {
9217
			uiDialog.bgiframe();
9218
		}
9219
 
9220
		// prevent tabbing out of modal dialogs
9221
		this._on( uiDialog, { keydown: function( event ) {
9222
			if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
9223
				return;
9224
			}
9225
 
9226
			var tabbables = $( ":tabbable", uiDialog ),
9227
				first = tabbables.filter( ":first" ),
9228
				last  = tabbables.filter( ":last" );
9229
 
9230
			if ( event.target === last[0] && !event.shiftKey ) {
9231
				first.focus( 1 );
9232
				return false;
9233
			} else if ( event.target === first[0] && event.shiftKey ) {
9234
				last.focus( 1 );
9235
				return false;
9236
			}
9237
		}});
9238
	},
9239
 
9240
	_init: function() {
9241
		if ( this.options.autoOpen ) {
9242
			this.open();
9243
		}
9244
	},
9245
 
9246
	_destroy: function() {
9247
		var next,
9248
			oldPosition = this.oldPosition;
9249
 
9250
		if ( this.overlay ) {
9251
			this.overlay.destroy();
9252
		}
9253
		this.uiDialog.hide();
9254
		this.element
9255
			.removeClass( "ui-dialog-content ui-widget-content" )
9256
			.hide()
9257
			.appendTo( "body" );
9258
		this.uiDialog.remove();
9259
 
9260
		if ( this.originalTitle ) {
9261
			this.element.attr( "title", this.originalTitle );
9262
		}
9263
 
9264
		next = oldPosition.parent.children().eq( oldPosition.index );
9265
		// Don't try to place the dialog next to itself (#8613)
9266
		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
9267
			next.before( this.element );
9268
		} else {
9269
			oldPosition.parent.append( this.element );
9270
		}
9271
	},
9272
 
9273
	widget: function() {
9274
		return this.uiDialog;
9275
	},
9276
 
9277
	close: function( event ) {
9278
		var that = this,
9279
			maxZ, thisZ;
9280
 
9281
		if ( !this._isOpen ) {
9282
			return;
9283
		}
9284
 
9285
		if ( false === this._trigger( "beforeClose", event ) ) {
9286
			return;
9287
		}
9288
 
9289
		this._isOpen = false;
9290
 
9291
		if ( this.overlay ) {
9292
			this.overlay.destroy();
9293
		}
9294
 
9295
		if ( this.options.hide ) {
9296
			this._hide( this.uiDialog, this.options.hide, function() {
9297
				that._trigger( "close", event );
9298
			});
9299
		} else {
9300
			this.uiDialog.hide();
9301
			this._trigger( "close", event );
9302
		}
9303
 
9304
		$.ui.dialog.overlay.resize();
9305
 
9306
		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9307
		if ( this.options.modal ) {
9308
			maxZ = 0;
9309
			$( ".ui-dialog" ).each(function() {
9310
				if ( this !== that.uiDialog[0] ) {
9311
					thisZ = $( this ).css( "z-index" );
9312
					if ( !isNaN( thisZ ) ) {
9313
						maxZ = Math.max( maxZ, thisZ );
9314
					}
9315
				}
9316
			});
9317
			$.ui.dialog.maxZ = maxZ;
9318
		}
9319
 
9320
		return this;
9321
	},
9322
 
9323
	isOpen: function() {
9324
		return this._isOpen;
9325
	},
9326
 
9327
	// the force parameter allows us to move modal dialogs to their correct
9328
	// position on open
9329
	moveToTop: function( force, event ) {
9330
		var options = this.options,
9331
			saveScroll;
9332
 
9333
		if ( ( options.modal && !force ) ||
9334
				( !options.stack && !options.modal ) ) {
9335
			return this._trigger( "focus", event );
9336
		}
9337
 
9338
		if ( options.zIndex > $.ui.dialog.maxZ ) {
9339
			$.ui.dialog.maxZ = options.zIndex;
9340
		}
9341
		if ( this.overlay ) {
9342
			$.ui.dialog.maxZ += 1;
9343
			$.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
9344
			this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
9345
		}
9346
 
9347
		// Save and then restore scroll
9348
		// Opera 9.5+ resets when parent z-index is changed.
9349
		// http://bugs.jqueryui.com/ticket/3193
9350
		saveScroll = {
9351
			scrollTop: this.element.scrollTop(),
9352
			scrollLeft: this.element.scrollLeft()
9353
		};
9354
		$.ui.dialog.maxZ += 1;
9355
		this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
9356
		this.element.attr( saveScroll );
9357
		this._trigger( "focus", event );
9358
 
9359
		return this;
9360
	},
9361
 
9362
	open: function() {
9363
		if ( this._isOpen ) {
9364
			return;
9365
		}
9366
 
9367
		var hasFocus,
9368
			options = this.options,
9369
			uiDialog = this.uiDialog;
9370
 
9371
		this._size();
9372
		this._position( options.position );
9373
		uiDialog.show( options.show );
9374
		this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
9375
		this.moveToTop( true );
9376
 
9377
		// set focus to the first tabbable element in the content area or the first button
9378
		// if there are no tabbable elements, set focus on the dialog itself
9379
		hasFocus = this.element.find( ":tabbable" );
9380
		if ( !hasFocus.length ) {
9381
			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
9382
			if ( !hasFocus.length ) {
9383
				hasFocus = uiDialog;
9384
			}
9385
		}
9386
		hasFocus.eq( 0 ).focus();
9387
 
9388
		this._isOpen = true;
9389
		this._trigger( "open" );
9390
 
9391
		return this;
9392
	},
9393
 
9394
	_createButtons: function( buttons ) {
9395
		var that = this,
9396
			hasButtons = false;
9397
 
9398
		// if we already have a button pane, remove it
9399
		this.uiDialogButtonPane.remove();
9400
		this.uiButtonSet.empty();
9401
 
9402
		if ( typeof buttons === "object" && buttons !== null ) {
9403
			$.each( buttons, function() {
9404
				return !(hasButtons = true);
9405
			});
9406
		}
9407
		if ( hasButtons ) {
9408
			$.each( buttons, function( name, props ) {
9409
				var button, click;
9410
				props = $.isFunction( props ) ?
9411
					{ click: props, text: name } :
9412
					props;
9413
				// Default to a non-submitting button
9414
				props = $.extend( { type: "button" }, props );
9415
				// Change the context for the click callback to be the main element
9416
				click = props.click;
9417
				props.click = function() {
9418
					click.apply( that.element[0], arguments );
9419
				};
9420
				button = $( "<button></button>", props )
9421
					.appendTo( that.uiButtonSet );
9422
				if ( $.fn.button ) {
9423
					button.button();
9424
				}
9425
			});
9426
			this.uiDialog.addClass( "ui-dialog-buttons" );
9427
			this.uiDialogButtonPane.appendTo( this.uiDialog );
9428
		} else {
9429
			this.uiDialog.removeClass( "ui-dialog-buttons" );
9430
		}
9431
	},
9432
 
9433
	_makeDraggable: function() {
9434
		var that = this,
9435
			options = this.options;
9436
 
9437
		function filteredUi( ui ) {
9438
			return {
9439
				position: ui.position,
9440
				offset: ui.offset
9441
			};
9442
		}
9443
 
9444
		this.uiDialog.draggable({
9445
			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
9446
			handle: ".ui-dialog-titlebar",
9447
			containment: "document",
9448
			start: function( event, ui ) {
9449
				$( this )
9450
					.addClass( "ui-dialog-dragging" );
9451
				that._trigger( "dragStart", event, filteredUi( ui ) );
9452
			},
9453
			drag: function( event, ui ) {
9454
				that._trigger( "drag", event, filteredUi( ui ) );
9455
			},
9456
			stop: function( event, ui ) {
9457
				options.position = [
9458
					ui.position.left - that.document.scrollLeft(),
9459
					ui.position.top - that.document.scrollTop()
9460
				];
9461
				$( this )
9462
					.removeClass( "ui-dialog-dragging" );
9463
				that._trigger( "dragStop", event, filteredUi( ui ) );
9464
				$.ui.dialog.overlay.resize();
9465
			}
9466
		});
9467
	},
9468
 
9469
	_makeResizable: function( handles ) {
9470
		handles = (handles === undefined ? this.options.resizable : handles);
9471
		var that = this,
9472
			options = this.options,
9473
			// .ui-resizable has position: relative defined in the stylesheet
9474
			// but dialogs have to use absolute or fixed positioning
9475
			position = this.uiDialog.css( "position" ),
9476
			resizeHandles = typeof handles === 'string' ?
9477
				handles	:
9478
				"n,e,s,w,se,sw,ne,nw";
9479
 
9480
		function filteredUi( ui ) {
9481
			return {
9482
				originalPosition: ui.originalPosition,
9483
				originalSize: ui.originalSize,
9484
				position: ui.position,
9485
				size: ui.size
9486
			};
9487
		}
9488
 
9489
		this.uiDialog.resizable({
9490
			cancel: ".ui-dialog-content",
9491
			containment: "document",
9492
			alsoResize: this.element,
9493
			maxWidth: options.maxWidth,
9494
			maxHeight: options.maxHeight,
9495
			minWidth: options.minWidth,
9496
			minHeight: this._minHeight(),
9497
			handles: resizeHandles,
9498
			start: function( event, ui ) {
9499
				$( this ).addClass( "ui-dialog-resizing" );
9500
				that._trigger( "resizeStart", event, filteredUi( ui ) );
9501
			},
9502
			resize: function( event, ui ) {
9503
				that._trigger( "resize", event, filteredUi( ui ) );
9504
			},
9505
			stop: function( event, ui ) {
9506
				$( this ).removeClass( "ui-dialog-resizing" );
9507
				options.height = $( this ).height();
9508
				options.width = $( this ).width();
9509
				that._trigger( "resizeStop", event, filteredUi( ui ) );
9510
				$.ui.dialog.overlay.resize();
9511
			}
9512
		})
9513
		.css( "position", position )
9514
		.find( ".ui-resizable-se" )
9515
			.addClass( "ui-icon ui-icon-grip-diagonal-se" );
9516
	},
9517
 
9518
	_minHeight: function() {
9519
		var options = this.options;
9520
 
9521
		if ( options.height === "auto" ) {
9522
			return options.minHeight;
9523
		} else {
9524
			return Math.min( options.minHeight, options.height );
9525
		}
9526
	},
9527
 
9528
	_position: function( position ) {
9529
		var myAt = [],
9530
			offset = [ 0, 0 ],
9531
			isVisible;
9532
 
9533
		if ( position ) {
9534
			// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
9535
	//		if (typeof position == 'string' || $.isArray(position)) {
9536
	//			myAt = $.isArray(position) ? position : position.split(' ');
9537
 
9538
			if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
9539
				myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
9540
				if ( myAt.length === 1 ) {
9541
					myAt[ 1 ] = myAt[ 0 ];
9542
				}
9543
 
9544
				$.each( [ "left", "top" ], function( i, offsetPosition ) {
9545
					if ( +myAt[ i ] === myAt[ i ] ) {
9546
						offset[ i ] = myAt[ i ];
9547
						myAt[ i ] = offsetPosition;
9548
					}
9549
				});
9550
 
9551
				position = {
9552
					my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
9553
						myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
9554
					at: myAt.join( " " )
9555
				};
9556
			}
9557
 
9558
			position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
9559
		} else {
9560
			position = $.ui.dialog.prototype.options.position;
9561
		}
9562
 
9563
		// need to show the dialog to get the actual offset in the position plugin
9564
		isVisible = this.uiDialog.is( ":visible" );
9565
		if ( !isVisible ) {
9566
			this.uiDialog.show();
9567
		}
9568
		this.uiDialog.position( position );
9569
		if ( !isVisible ) {
9570
			this.uiDialog.hide();
9571
		}
9572
	},
9573
 
9574
	_setOptions: function( options ) {
9575
		var that = this,
9576
			resizableOptions = {},
9577
			resize = false;
9578
 
9579
		$.each( options, function( key, value ) {
9580
			that._setOption( key, value );
9581
 
9582
			if ( key in sizeRelatedOptions ) {
9583
				resize = true;
9584
			}
9585
			if ( key in resizableRelatedOptions ) {
9586
				resizableOptions[ key ] = value;
9587
			}
9588
		});
9589
 
9590
		if ( resize ) {
9591
			this._size();
9592
		}
9593
		if ( this.uiDialog.is( ":data(resizable)" ) ) {
9594
			this.uiDialog.resizable( "option", resizableOptions );
9595
		}
9596
	},
9597
 
9598
	_setOption: function( key, value ) {
9599
		var isDraggable, isResizable,
9600
			uiDialog = this.uiDialog;
9601
 
9602
		switch ( key ) {
9603
			case "buttons":
9604
				this._createButtons( value );
9605
				break;
9606
			case "closeText":
9607
				// ensure that we always pass a string
9608
				this.uiDialogTitlebarCloseText.text( "" + value );
9609
				break;
9610
			case "dialogClass":
9611
				uiDialog
9612
					.removeClass( this.options.dialogClass )
9613
					.addClass( uiDialogClasses + value );
9614
				break;
9615
			case "disabled":
9616
				if ( value ) {
9617
					uiDialog.addClass( "ui-dialog-disabled" );
9618
				} else {
9619
					uiDialog.removeClass( "ui-dialog-disabled" );
9620
				}
9621
				break;
9622
			case "draggable":
9623
				isDraggable = uiDialog.is( ":data(draggable)" );
9624
				if ( isDraggable && !value ) {
9625
					uiDialog.draggable( "destroy" );
9626
				}
9627
 
9628
				if ( !isDraggable && value ) {
9629
					this._makeDraggable();
9630
				}
9631
				break;
9632
			case "position":
9633
				this._position( value );
9634
				break;
9635
			case "resizable":
9636
				// currently resizable, becoming non-resizable
9637
				isResizable = uiDialog.is( ":data(resizable)" );
9638
				if ( isResizable && !value ) {
9639
					uiDialog.resizable( "destroy" );
9640
				}
9641
 
9642
				// currently resizable, changing handles
9643
				if ( isResizable && typeof value === "string" ) {
9644
					uiDialog.resizable( "option", "handles", value );
9645
				}
9646
 
9647
				// currently non-resizable, becoming resizable
9648
				if ( !isResizable && value !== false ) {
9649
					this._makeResizable( value );
9650
				}
9651
				break;
9652
			case "title":
9653
				// convert whatever was passed in o a string, for html() to not throw up
9654
				$( ".ui-dialog-title", this.uiDialogTitlebar )
9655
					.html( "" + ( value || "&#160;" ) );
9656
				break;
9657
		}
9658
 
9659
		this._super( key, value );
9660
	},
9661
 
9662
	_size: function() {
9663
		/* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9664
		 * divs will both have width and height set, so we need to reset them
9665
		 */
9666
		var nonContentHeight, minContentHeight, autoHeight,
9667
			options = this.options,
9668
			isVisible = this.uiDialog.is( ":visible" );
9669
 
9670
		// reset content sizing
9671
		this.element.show().css({
9672
			width: "auto",
9673
			minHeight: 0,
9674
			height: 0
9675
		});
9676
 
9677
		if ( options.minWidth > options.width ) {
9678
			options.width = options.minWidth;
9679
		}
9680
 
9681
		// reset wrapper sizing
9682
		// determine the height of all the non-content elements
9683
		nonContentHeight = this.uiDialog.css({
9684
				height: "auto",
9685
				width: options.width
9686
			})
9687
			.outerHeight();
9688
		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9689
 
9690
		if ( options.height === "auto" ) {
9691
			// only needed for IE6 support
9692
			if ( $.support.minHeight ) {
9693
				this.element.css({
9694
					minHeight: minContentHeight,
9695
					height: "auto"
9696
				});
9697
			} else {
9698
				this.uiDialog.show();
9699
				autoHeight = this.element.css( "height", "auto" ).height();
9700
				if ( !isVisible ) {
9701
					this.uiDialog.hide();
9702
				}
9703
				this.element.height( Math.max( autoHeight, minContentHeight ) );
9704
			}
9705
		} else {
9706
			this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
9707
		}
9708
 
9709
		if (this.uiDialog.is( ":data(resizable)" ) ) {
9710
			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
9711
		}
9712
	}
9713
});
9714
 
9715
$.extend($.ui.dialog, {
9716
	uuid: 0,
9717
	maxZ: 0,
9718
 
9719
	getTitleId: function($el) {
9720
		var id = $el.attr( "id" );
9721
		if ( !id ) {
9722
			this.uuid += 1;
9723
			id = this.uuid;
9724
		}
9725
		return "ui-dialog-title-" + id;
9726
	},
9727
 
9728
	overlay: function( dialog ) {
9729
		this.$el = $.ui.dialog.overlay.create( dialog );
9730
	}
9731
});
9732
 
9733
$.extend( $.ui.dialog.overlay, {
9734
	instances: [],
9735
	// reuse old instances due to IE memory leak with alpha transparency (see #5185)
9736
	oldInstances: [],
9737
	maxZ: 0,
9738
	events: $.map(
9739
		"focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
9740
		function( event ) {
9741
			return event + ".dialog-overlay";
9742
		}
9743
	).join( " " ),
9744
	create: function( dialog ) {
9745
		if ( this.instances.length === 0 ) {
9746
			// prevent use of anchors and inputs
9747
			// we use a setTimeout in case the overlay is created from an
9748
			// event that we're going to be cancelling (see #2804)
9749
			setTimeout(function() {
9750
				// handle $(el).dialog().dialog('close') (see #4065)
9751
				if ( $.ui.dialog.overlay.instances.length ) {
9752
					$( document ).bind( $.ui.dialog.overlay.events, function( event ) {
9753
						// stop events if the z-index of the target is < the z-index of the overlay
9754
						// we cannot return true when we don't want to cancel the event (#3523)
9755
						if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
9756
							return false;
9757
						}
9758
					});
9759
				}
9760
			}, 1 );
9761
 
9762
			// handle window resize
9763
			$( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
9764
		}
9765
 
9766
		var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
9767
 
9768
		// allow closing by pressing the escape key
9769
		$( document ).bind( "keydown.dialog-overlay", function( event ) {
9770
			var instances = $.ui.dialog.overlay.instances;
9771
			// only react to the event if we're the top overlay
9772
			if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
9773
				dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9774
				event.keyCode === $.ui.keyCode.ESCAPE ) {
9775
 
9776
				dialog.close( event );
9777
				event.preventDefault();
9778
			}
9779
		});
9780
 
9781
		$el.appendTo( document.body ).css({
9782
			width: this.width(),
9783
			height: this.height()
9784
		});
9785
 
9786
		if ( $.fn.bgiframe ) {
9787
			$el.bgiframe();
9788
		}
9789
 
9790
		this.instances.push( $el );
9791
		return $el;
9792
	},
9793
 
9794
	destroy: function( $el ) {
9795
		var indexOf = $.inArray( $el, this.instances ),
9796
			maxZ = 0;
9797
 
9798
		if ( indexOf !== -1 ) {
9799
			this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
9800
		}
9801
 
9802
		if ( this.instances.length === 0 ) {
9803
			$( [ document, window ] ).unbind( ".dialog-overlay" );
9804
		}
9805
 
9806
		$el.height( 0 ).width( 0 ).remove();
9807
 
9808
		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9809
		$.each( this.instances, function() {
9810
			maxZ = Math.max( maxZ, this.css( "z-index" ) );
9811
		});
9812
		this.maxZ = maxZ;
9813
	},
9814
 
9815
	height: function() {
9816
		var scrollHeight,
9817
			offsetHeight;
9818
		// handle IE
9819
		if ( $.ui.ie ) {
9820
			scrollHeight = Math.max(
9821
				document.documentElement.scrollHeight,
9822
				document.body.scrollHeight
9823
			);
9824
			offsetHeight = Math.max(
9825
				document.documentElement.offsetHeight,
9826
				document.body.offsetHeight
9827
			);
9828
 
9829
			if ( scrollHeight < offsetHeight ) {
9830
				return $( window ).height() + "px";
9831
			} else {
9832
				return scrollHeight + "px";
9833
			}
9834
		// handle "good" browsers
9835
		} else {
9836
			return $( document ).height() + "px";
9837
		}
9838
	},
9839
 
9840
	width: function() {
9841
		var scrollWidth,
9842
			offsetWidth;
9843
		// handle IE
9844
		if ( $.ui.ie ) {
9845
			scrollWidth = Math.max(
9846
				document.documentElement.scrollWidth,
9847
				document.body.scrollWidth
9848
			);
9849
			offsetWidth = Math.max(
9850
				document.documentElement.offsetWidth,
9851
				document.body.offsetWidth
9852
			);
9853
 
9854
			if ( scrollWidth < offsetWidth ) {
9855
				return $( window ).width() + "px";
9856
			} else {
9857
				return scrollWidth + "px";
9858
			}
9859
		// handle "good" browsers
9860
		} else {
9861
			return $( document ).width() + "px";
9862
		}
9863
	},
9864
 
9865
	resize: function() {
9866
		/* If the dialog is draggable and the user drags it past the
9867
		 * right edge of the window, the document becomes wider so we
9868
		 * need to stretch the overlay. If the user then drags the
9869
		 * dialog back to the left, the document will become narrower,
9870
		 * so we need to shrink the overlay to the appropriate size.
9871
		 * This is handled by shrinking the overlay before setting it
9872
		 * to the full document size.
9873
		 */
9874
		var $overlays = $( [] );
9875
		$.each( $.ui.dialog.overlay.instances, function() {
9876
			$overlays = $overlays.add( this );
9877
		});
9878
 
9879
		$overlays.css({
9880
			width: 0,
9881
			height: 0
9882
		}).css({
9883
			width: $.ui.dialog.overlay.width(),
9884
			height: $.ui.dialog.overlay.height()
9885
		});
9886
	}
9887
});
9888
 
9889
$.extend( $.ui.dialog.overlay.prototype, {
9890
	destroy: function() {
9891
		$.ui.dialog.overlay.destroy( this.$el );
9892
	}
9893
});
9894
 
9895
}( jQuery ) );
9896
 
9897
(function( $, undefined ) {
9898
 
9899
var rvertical = /up|down|vertical/,
9900
	rpositivemotion = /up|left|vertical|horizontal/;
9901
 
9902
$.effects.effect.blind = function( o, done ) {
9903
	// Create element
9904
	var el = $( this ),
9905
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9906
		mode = $.effects.setMode( el, o.mode || "hide" ),
9907
		direction = o.direction || "up",
9908
		vertical = rvertical.test( direction ),
9909
		ref = vertical ? "height" : "width",
9910
		ref2 = vertical ? "top" : "left",
9911
		motion = rpositivemotion.test( direction ),
9912
		animation = {},
9913
		show = mode === "show",
9914
		wrapper, distance, margin;
9915
 
9916
	// if already wrapped, the wrapper's properties are my property. #6245
9917
	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
9918
		$.effects.save( el.parent(), props );
9919
	} else {
9920
		$.effects.save( el, props );
9921
	}
9922
	el.show();
9923
	wrapper = $.effects.createWrapper( el ).css({
9924
		overflow: "hidden"
9925
	});
9926
 
9927
	distance = wrapper[ ref ]();
9928
	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
9929
 
9930
	animation[ ref ] = show ? distance : 0;
9931
	if ( !motion ) {
9932
		el
9933
			.css( vertical ? "bottom" : "right", 0 )
9934
			.css( vertical ? "top" : "left", "auto" )
9935
			.css({ position: "absolute" });
9936
 
9937
		animation[ ref2 ] = show ? margin : distance + margin;
9938
	}
9939
 
9940
	// start at 0 if we are showing
9941
	if ( show ) {
9942
		wrapper.css( ref, 0 );
9943
		if ( ! motion ) {
9944
			wrapper.css( ref2, margin + distance );
9945
		}
9946
	}
9947
 
9948
	// Animate
9949
	wrapper.animate( animation, {
9950
		duration: o.duration,
9951
		easing: o.easing,
9952
		queue: false,
9953
		complete: function() {
9954
			if ( mode === "hide" ) {
9955
				el.hide();
9956
			}
9957
			$.effects.restore( el, props );
9958
			$.effects.removeWrapper( el );
9959
			done();
9960
		}
9961
	});
9962
 
9963
};
9964
 
9965
})(jQuery);
9966
 
9967
(function( $, undefined ) {
9968
 
9969
$.effects.effect.bounce = function( o, done ) {
9970
	var el = $( this ),
9971
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9972
 
9973
		// defaults:
9974
		mode = $.effects.setMode( el, o.mode || "effect" ),
9975
		hide = mode === "hide",
9976
		show = mode === "show",
9977
		direction = o.direction || "up",
9978
		distance = o.distance,
9979
		times = o.times || 5,
9980
 
9981
		// number of internal animations
9982
		anims = times * 2 + ( show || hide ? 1 : 0 ),
9983
		speed = o.duration / anims,
9984
		easing = o.easing,
9985
 
9986
		// utility:
9987
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
9988
		motion = ( direction === "up" || direction === "left" ),
9989
		i,
9990
		upAnim,
9991
		downAnim,
9992
 
9993
		// we will need to re-assemble the queue to stack our animations in place
9994
		queue = el.queue(),
9995
		queuelen = queue.length;
9996
 
9997
	// Avoid touching opacity to prevent clearType and PNG issues in IE
9998
	if ( show || hide ) {
9999
		props.push( "opacity" );
10000
	}
10001
 
10002
	$.effects.save( el, props );
10003
	el.show();
10004
	$.effects.createWrapper( el ); // Create Wrapper
10005
 
10006
	// default distance for the BIGGEST bounce is the outer Distance / 3
10007
	if ( !distance ) {
10008
		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10009
	}
10010
 
10011
	if ( show ) {
10012
		downAnim = { opacity: 1 };
10013
		downAnim[ ref ] = 0;
10014
 
10015
		// if we are showing, force opacity 0 and set the initial position
10016
		// then do the "first" animation
10017
		el.css( "opacity", 0 )
10018
			.css( ref, motion ? -distance * 2 : distance * 2 )
10019
			.animate( downAnim, speed, easing );
10020
	}
10021
 
10022
	// start at the smallest distance if we are hiding
10023
	if ( hide ) {
10024
		distance = distance / Math.pow( 2, times - 1 );
10025
	}
10026
 
10027
	downAnim = {};
10028
	downAnim[ ref ] = 0;
10029
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10030
	for ( i = 0; i < times; i++ ) {
10031
		upAnim = {};
10032
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10033
 
10034
		el.animate( upAnim, speed, easing )
10035
			.animate( downAnim, speed, easing );
10036
 
10037
		distance = hide ? distance * 2 : distance / 2;
10038
	}
10039
 
10040
	// Last Bounce when Hiding
10041
	if ( hide ) {
10042
		upAnim = { opacity: 0 };
10043
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10044
 
10045
		el.animate( upAnim, speed, easing );
10046
	}
10047
 
10048
	el.queue(function() {
10049
		if ( hide ) {
10050
			el.hide();
10051
		}
10052
		$.effects.restore( el, props );
10053
		$.effects.removeWrapper( el );
10054
		done();
10055
	});
10056
 
10057
	// inject all the animations we just queued to be first in line (after "inprogress")
10058
	if ( queuelen > 1) {
10059
		queue.splice.apply( queue,
10060
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10061
	}
10062
	el.dequeue();
10063
 
10064
};
10065
 
10066
})(jQuery);
10067
 
10068
(function( $, undefined ) {
10069
 
10070
$.effects.effect.clip = function( o, done ) {
10071
	// Create element
10072
	var el = $( this ),
10073
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10074
		mode = $.effects.setMode( el, o.mode || "hide" ),
10075
		show = mode === "show",
10076
		direction = o.direction || "vertical",
10077
		vert = direction === "vertical",
10078
		size = vert ? "height" : "width",
10079
		position = vert ? "top" : "left",
10080
		animation = {},
10081
		wrapper, animate, distance;
10082
 
10083
	// Save & Show
10084
	$.effects.save( el, props );
10085
	el.show();
10086
 
10087
	// Create Wrapper
10088
	wrapper = $.effects.createWrapper( el ).css({
10089
		overflow: "hidden"
10090
	});
10091
	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10092
	distance = animate[ size ]();
10093
 
10094
	// Shift
10095
	if ( show ) {
10096
		animate.css( size, 0 );
10097
		animate.css( position, distance / 2 );
10098
	}
10099
 
10100
	// Create Animation Object:
10101
	animation[ size ] = show ? distance : 0;
10102
	animation[ position ] = show ? 0 : distance / 2;
10103
 
10104
	// Animate
10105
	animate.animate( animation, {
10106
		queue: false,
10107
		duration: o.duration,
10108
		easing: o.easing,
10109
		complete: function() {
10110
			if ( !show ) {
10111
				el.hide();
10112
			}
10113
			$.effects.restore( el, props );
10114
			$.effects.removeWrapper( el );
10115
			done();
10116
		}
10117
	});
10118
 
10119
};
10120
 
10121
})(jQuery);
10122
 
10123
(function( $, undefined ) {
10124
 
10125
$.effects.effect.drop = function( o, done ) {
10126
 
10127
	var el = $( this ),
10128
		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10129
		mode = $.effects.setMode( el, o.mode || "hide" ),
10130
		show = mode === "show",
10131
		direction = o.direction || "left",
10132
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10133
		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10134
		animation = {
10135
			opacity: show ? 1 : 0
10136
		},
10137
		distance;
10138
 
10139
	// Adjust
10140
	$.effects.save( el, props );
10141
	el.show();
10142
	$.effects.createWrapper( el );
10143
 
10144
	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10145
 
10146
	if ( show ) {
10147
		el
10148
			.css( "opacity", 0 )
10149
			.css( ref, motion === "pos" ? -distance : distance );
10150
	}
10151
 
10152
	// Animation
10153
	animation[ ref ] = ( show ?
10154
		( motion === "pos" ? "+=" : "-=" ) :
10155
		( motion === "pos" ? "-=" : "+=" ) ) +
10156
		distance;
10157
 
10158
	// Animate
10159
	el.animate( animation, {
10160
		queue: false,
10161
		duration: o.duration,
10162
		easing: o.easing,
10163
		complete: function() {
10164
			if ( mode === "hide" ) {
10165
				el.hide();
10166
			}
10167
			$.effects.restore( el, props );
10168
			$.effects.removeWrapper( el );
10169
			done();
10170
		}
10171
	});
10172
};
10173
 
10174
})(jQuery);
10175
 
10176
(function( $, undefined ) {
10177
 
10178
$.effects.effect.explode = function( o, done ) {
10179
 
10180
	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10181
		cells = rows,
10182
		el = $( this ),
10183
		mode = $.effects.setMode( el, o.mode || "hide" ),
10184
		show = mode === "show",
10185
 
10186
		// show and then visibility:hidden the element before calculating offset
10187
		offset = el.show().css( "visibility", "hidden" ).offset(),
10188
 
10189
		// width and height of a piece
10190
		width = Math.ceil( el.outerWidth() / cells ),
10191
		height = Math.ceil( el.outerHeight() / rows ),
10192
		pieces = [],
10193
 
10194
		// loop
10195
		i, j, left, top, mx, my;
10196
 
10197
	// children animate complete:
10198
	function childComplete() {
10199
		pieces.push( this );
10200
		if ( pieces.length === rows * cells ) {
10201
			animComplete();
10202
		}
10203
	}
10204
 
10205
	// clone the element for each row and cell.
10206
	for( i = 0; i < rows ; i++ ) { // ===>
10207
		top = offset.top + i * height;
10208
		my = i - ( rows - 1 ) / 2 ;
10209
 
10210
		for( j = 0; j < cells ; j++ ) { // |||
10211
			left = offset.left + j * width;
10212
			mx = j - ( cells - 1 ) / 2 ;
10213
 
10214
			// Create a clone of the now hidden main element that will be absolute positioned
10215
			// within a wrapper div off the -left and -top equal to size of our pieces
10216
			el
10217
				.clone()
10218
				.appendTo( "body" )
10219
				.wrap( "<div></div>" )
10220
				.css({
10221
					position: "absolute",
10222
					visibility: "visible",
10223
					left: -j * width,
10224
					top: -i * height
10225
				})
10226
 
10227
			// select the wrapper - make it overflow: hidden and absolute positioned based on
10228
			// where the original was located +left and +top equal to the size of pieces
10229
				.parent()
10230
				.addClass( "ui-effects-explode" )
10231
				.css({
10232
					position: "absolute",
10233
					overflow: "hidden",
10234
					width: width,
10235
					height: height,
10236
					left: left + ( show ? mx * width : 0 ),
10237
					top: top + ( show ? my * height : 0 ),
10238
					opacity: show ? 0 : 1
10239
				}).animate({
10240
					left: left + ( show ? 0 : mx * width ),
10241
					top: top + ( show ? 0 : my * height ),
10242
					opacity: show ? 1 : 0
10243
				}, o.duration || 500, o.easing, childComplete );
10244
		}
10245
	}
10246
 
10247
	function animComplete() {
10248
		el.css({
10249
			visibility: "visible"
10250
		});
10251
		$( pieces ).remove();
10252
		if ( !show ) {
10253
			el.hide();
10254
		}
10255
		done();
10256
	}
10257
};
10258
 
10259
})(jQuery);
10260
 
10261
(function( $, undefined ) {
10262
 
10263
$.effects.effect.fade = function( o, done ) {
10264
	var el = $( this ),
10265
		mode = $.effects.setMode( el, o.mode || "toggle" );
10266
 
10267
	el.animate({
10268
		opacity: mode
10269
	}, {
10270
		queue: false,
10271
		duration: o.duration,
10272
		easing: o.easing,
10273
		complete: done
10274
	});
10275
};
10276
 
10277
})( jQuery );
10278
 
10279
(function( $, undefined ) {
10280
 
10281
$.effects.effect.fold = function( o, done ) {
10282
 
10283
	// Create element
10284
	var el = $( this ),
10285
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10286
		mode = $.effects.setMode( el, o.mode || "hide" ),
10287
		show = mode === "show",
10288
		hide = mode === "hide",
10289
		size = o.size || 15,
10290
		percent = /([0-9]+)%/.exec( size ),
10291
		horizFirst = !!o.horizFirst,
10292
		widthFirst = show !== horizFirst,
10293
		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10294
		duration = o.duration / 2,
10295
		wrapper, distance,
10296
		animation1 = {},
10297
		animation2 = {};
10298
 
10299
	$.effects.save( el, props );
10300
	el.show();
10301
 
10302
	// Create Wrapper
10303
	wrapper = $.effects.createWrapper( el ).css({
10304
		overflow: "hidden"
10305
	});
10306
	distance = widthFirst ?
10307
		[ wrapper.width(), wrapper.height() ] :
10308
		[ wrapper.height(), wrapper.width() ];
10309
 
10310
	if ( percent ) {
10311
		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10312
	}
10313
	if ( show ) {
10314
		wrapper.css( horizFirst ? {
10315
			height: 0,
10316
			width: size
10317
		} : {
10318
			height: size,
10319
			width: 0
10320
		});
10321
	}
10322
 
10323
	// Animation
10324
	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10325
	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10326
 
10327
	// Animate
10328
	wrapper
10329
		.animate( animation1, duration, o.easing )
10330
		.animate( animation2, duration, o.easing, function() {
10331
			if ( hide ) {
10332
				el.hide();
10333
			}
10334
			$.effects.restore( el, props );
10335
			$.effects.removeWrapper( el );
10336
			done();
10337
		});
10338
 
10339
};
10340
 
10341
})(jQuery);
10342
 
10343
(function( $, undefined ) {
10344
 
10345
$.effects.effect.highlight = function( o, done ) {
10346
	var elem = $( this ),
10347
		props = [ "backgroundImage", "backgroundColor", "opacity" ],
10348
		mode = $.effects.setMode( elem, o.mode || "show" ),
10349
		animation = {
10350
			backgroundColor: elem.css( "backgroundColor" )
10351
		};
10352
 
10353
	if (mode === "hide") {
10354
		animation.opacity = 0;
10355
	}
10356
 
10357
	$.effects.save( elem, props );
10358
 
10359
	elem
10360
		.show()
10361
		.css({
10362
			backgroundImage: "none",
10363
			backgroundColor: o.color || "#ffff99"
10364
		})
10365
		.animate( animation, {
10366
			queue: false,
10367
			duration: o.duration,
10368
			easing: o.easing,
10369
			complete: function() {
10370
				if ( mode === "hide" ) {
10371
					elem.hide();
10372
				}
10373
				$.effects.restore( elem, props );
10374
				done();
10375
			}
10376
		});
10377
};
10378
 
10379
})(jQuery);
10380
 
10381
(function( $, undefined ) {
10382
 
10383
$.effects.effect.pulsate = function( o, done ) {
10384
	var elem = $( this ),
10385
		mode = $.effects.setMode( elem, o.mode || "show" ),
10386
		show = mode === "show",
10387
		hide = mode === "hide",
10388
		showhide = ( show || mode === "hide" ),
10389
 
10390
		// showing or hiding leaves of the "last" animation
10391
		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10392
		duration = o.duration / anims,
10393
		animateTo = 0,
10394
		queue = elem.queue(),
10395
		queuelen = queue.length,
10396
		i;
10397
 
10398
	if ( show || !elem.is(":visible")) {
10399
		elem.css( "opacity", 0 ).show();
10400
		animateTo = 1;
10401
	}
10402
 
10403
	// anims - 1 opacity "toggles"
10404
	for ( i = 1; i < anims; i++ ) {
10405
		elem.animate({
10406
			opacity: animateTo
10407
		}, duration, o.easing );
10408
		animateTo = 1 - animateTo;
10409
	}
10410
 
10411
	elem.animate({
10412
		opacity: animateTo
10413
	}, duration, o.easing);
10414
 
10415
	elem.queue(function() {
10416
		if ( hide ) {
10417
			elem.hide();
10418
		}
10419
		done();
10420
	});
10421
 
10422
	// We just queued up "anims" animations, we need to put them next in the queue
10423
	if ( queuelen > 1 ) {
10424
		queue.splice.apply( queue,
10425
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10426
	}
10427
	elem.dequeue();
10428
};
10429
 
10430
})(jQuery);
10431
 
10432
(function( $, undefined ) {
10433
 
10434
$.effects.effect.puff = function( o, done ) {
10435
	var elem = $( this ),
10436
		mode = $.effects.setMode( elem, o.mode || "hide" ),
10437
		hide = mode === "hide",
10438
		percent = parseInt( o.percent, 10 ) || 150,
10439
		factor = percent / 100,
10440
		original = {
10441
			height: elem.height(),
10442
			width: elem.width(),
10443
			outerHeight: elem.outerHeight(),
10444
			outerWidth: elem.outerWidth()
10445
		};
10446
 
10447
	$.extend( o, {
10448
		effect: "scale",
10449
		queue: false,
10450
		fade: true,
10451
		mode: mode,
10452
		complete: done,
10453
		percent: hide ? percent : 100,
10454
		from: hide ?
10455
			original :
10456
			{
10457
				height: original.height * factor,
10458
				width: original.width * factor,
10459
				outerHeight: original.outerHeight * factor,
10460
				outerWidth: original.outerWidth * factor
10461
			}
10462
	});
10463
 
10464
	elem.effect( o );
10465
};
10466
 
10467
$.effects.effect.scale = function( o, done ) {
10468
 
10469
	// Create element
10470
	var el = $( this ),
10471
		options = $.extend( true, {}, o ),
10472
		mode = $.effects.setMode( el, o.mode || "effect" ),
10473
		percent = parseInt( o.percent, 10 ) ||
10474
			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
10475
		direction = o.direction || "both",
10476
		origin = o.origin,
10477
		original = {
10478
			height: el.height(),
10479
			width: el.width(),
10480
			outerHeight: el.outerHeight(),
10481
			outerWidth: el.outerWidth()
10482
		},
10483
		factor = {
10484
			y: direction !== "horizontal" ? (percent / 100) : 1,
10485
			x: direction !== "vertical" ? (percent / 100) : 1
10486
		};
10487
 
10488
	// We are going to pass this effect to the size effect:
10489
	options.effect = "size";
10490
	options.queue = false;
10491
	options.complete = done;
10492
 
10493
	// Set default origin and restore for show/hide
10494
	if ( mode !== "effect" ) {
10495
		options.origin = origin || ["middle","center"];
10496
		options.restore = true;
10497
	}
10498
 
10499
	options.from = o.from || ( mode === "show" ? {
10500
		height: 0,
10501
		width: 0,
10502
		outerHeight: 0,
10503
		outerWidth: 0
10504
	} : original );
10505
	options.to = {
10506
		height: original.height * factor.y,
10507
		width: original.width * factor.x,
10508
		outerHeight: original.outerHeight * factor.y,
10509
		outerWidth: original.outerWidth * factor.x
10510
	};
10511
 
10512
	// Fade option to support puff
10513
	if ( options.fade ) {
10514
		if ( mode === "show" ) {
10515
			options.from.opacity = 0;
10516
			options.to.opacity = 1;
10517
		}
10518
		if ( mode === "hide" ) {
10519
			options.from.opacity = 1;
10520
			options.to.opacity = 0;
10521
		}
10522
	}
10523
 
10524
	// Animate
10525
	el.effect( options );
10526
 
10527
};
10528
 
10529
$.effects.effect.size = function( o, done ) {
10530
 
10531
	// Create element
10532
	var original, baseline, factor,
10533
		el = $( this ),
10534
		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
10535
 
10536
		// Always restore
10537
		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
10538
 
10539
		// Copy for children
10540
		props2 = [ "width", "height", "overflow" ],
10541
		cProps = [ "fontSize" ],
10542
		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
10543
		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
10544
 
10545
		// Set options
10546
		mode = $.effects.setMode( el, o.mode || "effect" ),
10547
		restore = o.restore || mode !== "effect",
10548
		scale = o.scale || "both",
10549
		origin = o.origin || [ "middle", "center" ],
10550
		position = el.css( "position" ),
10551
		props = restore ? props0 : props1,
10552
		zero = {
10553
			height: 0,
10554
			width: 0,
10555
			outerHeight: 0,
10556
			outerWidth: 0
10557
		};
10558
 
10559
	if ( mode === "show" ) {
10560
		el.show();
10561
	}
10562
	original = {
10563
		height: el.height(),
10564
		width: el.width(),
10565
		outerHeight: el.outerHeight(),
10566
		outerWidth: el.outerWidth()
10567
	};
10568
 
10569
	if ( o.mode === "toggle" && mode === "show" ) {
10570
		el.from = o.to || zero;
10571
		el.to = o.from || original;
10572
	} else {
10573
		el.from = o.from || ( mode === "show" ? zero : original );
10574
		el.to = o.to || ( mode === "hide" ? zero : original );
10575
	}
10576
 
10577
	// Set scaling factor
10578
	factor = {
10579
		from: {
10580
			y: el.from.height / original.height,
10581
			x: el.from.width / original.width
10582
		},
10583
		to: {
10584
			y: el.to.height / original.height,
10585
			x: el.to.width / original.width
10586
		}
10587
	};
10588
 
10589
	// Scale the css box
10590
	if ( scale === "box" || scale === "both" ) {
10591
 
10592
		// Vertical props scaling
10593
		if ( factor.from.y !== factor.to.y ) {
10594
			props = props.concat( vProps );
10595
			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
10596
			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
10597
		}
10598
 
10599
		// Horizontal props scaling
10600
		if ( factor.from.x !== factor.to.x ) {
10601
			props = props.concat( hProps );
10602
			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
10603
			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
10604
		}
10605
	}
10606
 
10607
	// Scale the content
10608
	if ( scale === "content" || scale === "both" ) {
10609
 
10610
		// Vertical props scaling
10611
		if ( factor.from.y !== factor.to.y ) {
10612
			props = props.concat( cProps ).concat( props2 );
10613
			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
10614
			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
10615
		}
10616
	}
10617
 
10618
	$.effects.save( el, props );
10619
	el.show();
10620
	$.effects.createWrapper( el );
10621
	el.css( "overflow", "hidden" ).css( el.from );
10622
 
10623
	// Adjust
10624
	if (origin) { // Calculate baseline shifts
10625
		baseline = $.effects.getBaseline( origin, original );
10626
		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
10627
		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
10628
		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
10629
		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
10630
	}
10631
	el.css( el.from ); // set top & left
10632
 
10633
	// Animate
10634
	if ( scale === "content" || scale === "both" ) { // Scale the children
10635
 
10636
		// Add margins/font-size
10637
		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
10638
		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
10639
		props2 = props0.concat(vProps).concat(hProps);
10640
 
10641
		el.find( "*[width]" ).each( function(){
10642
			var child = $( this ),
10643
				c_original = {
10644
					height: child.height(),
10645
					width: child.width(),
10646
					outerHeight: child.outerHeight(),
10647
					outerWidth: child.outerWidth()
10648
				};
10649
			if (restore) {
10650
				$.effects.save(child, props2);
10651
			}
10652
 
10653
			child.from = {
10654
				height: c_original.height * factor.from.y,
10655
				width: c_original.width * factor.from.x,
10656
				outerHeight: c_original.outerHeight * factor.from.y,
10657
				outerWidth: c_original.outerWidth * factor.from.x
10658
			};
10659
			child.to = {
10660
				height: c_original.height * factor.to.y,
10661
				width: c_original.width * factor.to.x,
10662
				outerHeight: c_original.height * factor.to.y,
10663
				outerWidth: c_original.width * factor.to.x
10664
			};
10665
 
10666
			// Vertical props scaling
10667
			if ( factor.from.y !== factor.to.y ) {
10668
				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
10669
				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
10670
			}
10671
 
10672
			// Horizontal props scaling
10673
			if ( factor.from.x !== factor.to.x ) {
10674
				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
10675
				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
10676
			}
10677
 
10678
			// Animate children
10679
			child.css( child.from );
10680
			child.animate( child.to, o.duration, o.easing, function() {
10681
 
10682
				// Restore children
10683
				if ( restore ) {
10684
					$.effects.restore( child, props2 );
10685
				}
10686
			});
10687
		});
10688
	}
10689
 
10690
	// Animate
10691
	el.animate( el.to, {
10692
		queue: false,
10693
		duration: o.duration,
10694
		easing: o.easing,
10695
		complete: function() {
10696
			if ( el.to.opacity === 0 ) {
10697
				el.css( "opacity", el.from.opacity );
10698
			}
10699
			if( mode === "hide" ) {
10700
				el.hide();
10701
			}
10702
			$.effects.restore( el, props );
10703
			if ( !restore ) {
10704
 
10705
				// we need to calculate our new positioning based on the scaling
10706
				if ( position === "static" ) {
10707
					el.css({
10708
						position: "relative",
10709
						top: el.to.top,
10710
						left: el.to.left
10711
					});
10712
				} else {
10713
					$.each([ "top", "left" ], function( idx, pos ) {
10714
						el.css( pos, function( _, str ) {
10715
							var val = parseInt( str, 10 ),
10716
								toRef = idx ? el.to.left : el.to.top;
10717
 
10718
							// if original was "auto", recalculate the new value from wrapper
10719
							if ( str === "auto" ) {
10720
								return toRef + "px";
10721
							}
10722
 
10723
							return val + toRef + "px";
10724
						});
10725
					});
10726
				}
10727
			}
10728
 
10729
			$.effects.removeWrapper( el );
10730
			done();
10731
		}
10732
	});
10733
 
10734
};
10735
 
10736
})(jQuery);
10737
 
10738
(function( $, undefined ) {
10739
 
10740
$.effects.effect.shake = function( o, done ) {
10741
 
10742
	var el = $( this ),
10743
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10744
		mode = $.effects.setMode( el, o.mode || "effect" ),
10745
		direction = o.direction || "left",
10746
		distance = o.distance || 20,
10747
		times = o.times || 3,
10748
		anims = times * 2 + 1,
10749
		speed = Math.round(o.duration/anims),
10750
		ref = (direction === "up" || direction === "down") ? "top" : "left",
10751
		positiveMotion = (direction === "up" || direction === "left"),
10752
		animation = {},
10753
		animation1 = {},
10754
		animation2 = {},
10755
		i,
10756
 
10757
		// we will need to re-assemble the queue to stack our animations in place
10758
		queue = el.queue(),
10759
		queuelen = queue.length;
10760
 
10761
	$.effects.save( el, props );
10762
	el.show();
10763
	$.effects.createWrapper( el );
10764
 
10765
	// Animation
10766
	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
10767
	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
10768
	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
10769
 
10770
	// Animate
10771
	el.animate( animation, speed, o.easing );
10772
 
10773
	// Shakes
10774
	for ( i = 1; i < times; i++ ) {
10775
		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
10776
	}
10777
	el
10778
		.animate( animation1, speed, o.easing )
10779
		.animate( animation, speed / 2, o.easing )
10780
		.queue(function() {
10781
			if ( mode === "hide" ) {
10782
				el.hide();
10783
			}
10784
			$.effects.restore( el, props );
10785
			$.effects.removeWrapper( el );
10786
			done();
10787
		});
10788
 
10789
	// inject all the animations we just queued to be first in line (after "inprogress")
10790
	if ( queuelen > 1) {
10791
		queue.splice.apply( queue,
10792
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10793
	}
10794
	el.dequeue();
10795
 
10796
};
10797
 
10798
})(jQuery);
10799
 
10800
(function( $, undefined ) {
10801
 
10802
$.effects.effect.slide = function( o, done ) {
10803
 
10804
	// Create element
10805
	var el = $( this ),
10806
		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
10807
		mode = $.effects.setMode( el, o.mode || "show" ),
10808
		show = mode === "show",
10809
		direction = o.direction || "left",
10810
		ref = (direction === "up" || direction === "down") ? "top" : "left",
10811
		positiveMotion = (direction === "up" || direction === "left"),
10812
		distance,
10813
		animation = {};
10814
 
10815
	// Adjust
10816
	$.effects.save( el, props );
10817
	el.show();
10818
	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
10819
 
10820
	$.effects.createWrapper( el ).css({
10821
		overflow: "hidden"
10822
	});
10823
 
10824
	if ( show ) {
10825
		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
10826
	}
10827
 
10828
	// Animation
10829
	animation[ ref ] = ( show ?
10830
		( positiveMotion ? "+=" : "-=") :
10831
		( positiveMotion ? "-=" : "+=")) +
10832
		distance;
10833
 
10834
	// Animate
10835
	el.animate( animation, {
10836
		queue: false,
10837
		duration: o.duration,
10838
		easing: o.easing,
10839
		complete: function() {
10840
			if ( mode === "hide" ) {
10841
				el.hide();
10842
			}
10843
			$.effects.restore( el, props );
10844
			$.effects.removeWrapper( el );
10845
			done();
10846
		}
10847
	});
10848
};
10849
 
10850
})(jQuery);
10851
 
10852
(function( $, undefined ) {
10853
 
10854
$.effects.effect.transfer = function( o, done ) {
10855
	var elem = $( this ),
10856
		target = $( o.to ),
10857
		targetFixed = target.css( "position" ) === "fixed",
10858
		body = $("body"),
10859
		fixTop = targetFixed ? body.scrollTop() : 0,
10860
		fixLeft = targetFixed ? body.scrollLeft() : 0,
10861
		endPosition = target.offset(),
10862
		animation = {
10863
			top: endPosition.top - fixTop ,
10864
			left: endPosition.left - fixLeft ,
10865
			height: target.innerHeight(),
10866
			width: target.innerWidth()
10867
		},
10868
		startPosition = elem.offset(),
10869
		transfer = $( '<div class="ui-effects-transfer"></div>' )
10870
			.appendTo( document.body )
10871
			.addClass( o.className )
10872
			.css({
10873
				top: startPosition.top - fixTop ,
10874
				left: startPosition.left - fixLeft ,
10875
				height: elem.innerHeight(),
10876
				width: elem.innerWidth(),
10877
				position: targetFixed ? "fixed" : "absolute"
10878
			})
10879
			.animate( animation, o.duration, o.easing, function() {
10880
				transfer.remove();
10881
				done();
10882
			});
10883
};
10884
 
10885
})(jQuery);
10886
 
10887
(function( $, undefined ) {
10888
 
10889
var mouseHandled = false;
10890
 
10891
$.widget( "ui.menu", {
10892
	version: "1.9.2",
10893
	defaultElement: "<ul>",
10894
	delay: 300,
10895
	options: {
10896
		icons: {
10897
			submenu: "ui-icon-carat-1-e"
10898
		},
10899
		menus: "ul",
10900
		position: {
10901
			my: "left top",
10902
			at: "right top"
10903
		},
10904
		role: "menu",
10905
 
10906
		// callbacks
10907
		blur: null,
10908
		focus: null,
10909
		select: null
10910
	},
10911
 
10912
	_create: function() {
10913
		this.activeMenu = this.element;
10914
		this.element
10915
			.uniqueId()
10916
			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
10917
			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
10918
			.attr({
10919
				role: this.options.role,
10920
				tabIndex: 0
10921
			})
10922
			// need to catch all clicks on disabled menu
10923
			// not possible through _on
10924
			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
10925
				if ( this.options.disabled ) {
10926
					event.preventDefault();
10927
				}
10928
			}, this ));
10929
 
10930
		if ( this.options.disabled ) {
10931
			this.element
10932
				.addClass( "ui-state-disabled" )
10933
				.attr( "aria-disabled", "true" );
10934
		}
10935
 
10936
		this._on({
10937
			// Prevent focus from sticking to links inside menu after clicking
10938
			// them (focus should always stay on UL during navigation).
10939
			"mousedown .ui-menu-item > a": function( event ) {
10940
				event.preventDefault();
10941
			},
10942
			"click .ui-state-disabled > a": function( event ) {
10943
				event.preventDefault();
10944
			},
10945
			"click .ui-menu-item:has(a)": function( event ) {
10946
				var target = $( event.target ).closest( ".ui-menu-item" );
10947
				if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
10948
					mouseHandled = true;
10949
 
10950
					this.select( event );
10951
					// Open submenu on click
10952
					if ( target.has( ".ui-menu" ).length ) {
10953
						this.expand( event );
10954
					} else if ( !this.element.is( ":focus" ) ) {
10955
						// Redirect focus to the menu
10956
						this.element.trigger( "focus", [ true ] );
10957
 
10958
						// If the active item is on the top level, let it stay active.
10959
						// Otherwise, blur the active item since it is no longer visible.
10960
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
10961
							clearTimeout( this.timer );
10962
						}
10963
					}
10964
				}
10965
			},
10966
			"mouseenter .ui-menu-item": function( event ) {
10967
				var target = $( event.currentTarget );
10968
				// Remove ui-state-active class from siblings of the newly focused menu item
10969
				// to avoid a jump caused by adjacent elements both having a class with a border
10970
				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
10971
				this.focus( event, target );
10972
			},
10973
			mouseleave: "collapseAll",
10974
			"mouseleave .ui-menu": "collapseAll",
10975
			focus: function( event, keepActiveItem ) {
10976
				// If there's already an active item, keep it active
10977
				// If not, activate the first item
10978
				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
10979
 
10980
				if ( !keepActiveItem ) {
10981
					this.focus( event, item );
10982
				}
10983
			},
10984
			blur: function( event ) {
10985
				this._delay(function() {
10986
					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
10987
						this.collapseAll( event );
10988
					}
10989
				});
10990
			},
10991
			keydown: "_keydown"
10992
		});
10993
 
10994
		this.refresh();
10995
 
10996
		// Clicks outside of a menu collapse any open menus
10997
		this._on( this.document, {
10998
			click: function( event ) {
10999
				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11000
					this.collapseAll( event );
11001
				}
11002
 
11003
				// Reset the mouseHandled flag
11004
				mouseHandled = false;
11005
			}
11006
		});
11007
	},
11008
 
11009
	_destroy: function() {
11010
		// Destroy (sub)menus
11011
		this.element
11012
			.removeAttr( "aria-activedescendant" )
11013
			.find( ".ui-menu" ).andSelf()
11014
				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11015
				.removeAttr( "role" )
11016
				.removeAttr( "tabIndex" )
11017
				.removeAttr( "aria-labelledby" )
11018
				.removeAttr( "aria-expanded" )
11019
				.removeAttr( "aria-hidden" )
11020
				.removeAttr( "aria-disabled" )
11021
				.removeUniqueId()
11022
				.show();
11023
 
11024
		// Destroy menu items
11025
		this.element.find( ".ui-menu-item" )
11026
			.removeClass( "ui-menu-item" )
11027
			.removeAttr( "role" )
11028
			.removeAttr( "aria-disabled" )
11029
			.children( "a" )
11030
				.removeUniqueId()
11031
				.removeClass( "ui-corner-all ui-state-hover" )
11032
				.removeAttr( "tabIndex" )
11033
				.removeAttr( "role" )
11034
				.removeAttr( "aria-haspopup" )
11035
				.children().each( function() {
11036
					var elem = $( this );
11037
					if ( elem.data( "ui-menu-submenu-carat" ) ) {
11038
						elem.remove();
11039
					}
11040
				});
11041
 
11042
		// Destroy menu dividers
11043
		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11044
	},
11045
 
11046
	_keydown: function( event ) {
11047
		var match, prev, character, skip, regex,
11048
			preventDefault = true;
11049
 
11050
		function escape( value ) {
11051
			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11052
		}
11053
 
11054
		switch ( event.keyCode ) {
11055
		case $.ui.keyCode.PAGE_UP:
11056
			this.previousPage( event );
11057
			break;
11058
		case $.ui.keyCode.PAGE_DOWN:
11059
			this.nextPage( event );
11060
			break;
11061
		case $.ui.keyCode.HOME:
11062
			this._move( "first", "first", event );
11063
			break;
11064
		case $.ui.keyCode.END:
11065
			this._move( "last", "last", event );
11066
			break;
11067
		case $.ui.keyCode.UP:
11068
			this.previous( event );
11069
			break;
11070
		case $.ui.keyCode.DOWN:
11071
			this.next( event );
11072
			break;
11073
		case $.ui.keyCode.LEFT:
11074
			this.collapse( event );
11075
			break;
11076
		case $.ui.keyCode.RIGHT:
11077
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11078
				this.expand( event );
11079
			}
11080
			break;
11081
		case $.ui.keyCode.ENTER:
11082
		case $.ui.keyCode.SPACE:
11083
			this._activate( event );
11084
			break;
11085
		case $.ui.keyCode.ESCAPE:
11086
			this.collapse( event );
11087
			break;
11088
		default:
11089
			preventDefault = false;
11090
			prev = this.previousFilter || "";
11091
			character = String.fromCharCode( event.keyCode );
11092
			skip = false;
11093
 
11094
			clearTimeout( this.filterTimer );
11095
 
11096
			if ( character === prev ) {
11097
				skip = true;
11098
			} else {
11099
				character = prev + character;
11100
			}
11101
 
11102
			regex = new RegExp( "^" + escape( character ), "i" );
11103
			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11104
				return regex.test( $( this ).children( "a" ).text() );
11105
			});
11106
			match = skip && match.index( this.active.next() ) !== -1 ?
11107
				this.active.nextAll( ".ui-menu-item" ) :
11108
				match;
11109
 
11110
			// If no matches on the current filter, reset to the last character pressed
11111
			// to move down the menu to the first item that starts with that character
11112
			if ( !match.length ) {
11113
				character = String.fromCharCode( event.keyCode );
11114
				regex = new RegExp( "^" + escape( character ), "i" );
11115
				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11116
					return regex.test( $( this ).children( "a" ).text() );
11117
				});
11118
			}
11119
 
11120
			if ( match.length ) {
11121
				this.focus( event, match );
11122
				if ( match.length > 1 ) {
11123
					this.previousFilter = character;
11124
					this.filterTimer = this._delay(function() {
11125
						delete this.previousFilter;
11126
					}, 1000 );
11127
				} else {
11128
					delete this.previousFilter;
11129
				}
11130
			} else {
11131
				delete this.previousFilter;
11132
			}
11133
		}
11134
 
11135
		if ( preventDefault ) {
11136
			event.preventDefault();
11137
		}
11138
	},
11139
 
11140
	_activate: function( event ) {
11141
		if ( !this.active.is( ".ui-state-disabled" ) ) {
11142
			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11143
				this.expand( event );
11144
			} else {
11145
				this.select( event );
11146
			}
11147
		}
11148
	},
11149
 
11150
	refresh: function() {
11151
		var menus,
11152
			icon = this.options.icons.submenu,
11153
			submenus = this.element.find( this.options.menus );
11154
 
11155
		// Initialize nested menus
11156
		submenus.filter( ":not(.ui-menu)" )
11157
			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11158
			.hide()
11159
			.attr({
11160
				role: this.options.role,
11161
				"aria-hidden": "true",
11162
				"aria-expanded": "false"
11163
			})
11164
			.each(function() {
11165
				var menu = $( this ),
11166
					item = menu.prev( "a" ),
11167
					submenuCarat = $( "<span>" )
11168
						.addClass( "ui-menu-icon ui-icon " + icon )
11169
						.data( "ui-menu-submenu-carat", true );
11170
 
11171
				item
11172
					.attr( "aria-haspopup", "true" )
11173
					.prepend( submenuCarat );
11174
				menu.attr( "aria-labelledby", item.attr( "id" ) );
11175
			});
11176
 
11177
		menus = submenus.add( this.element );
11178
 
11179
		// Don't refresh list items that are already adapted
11180
		menus.children( ":not(.ui-menu-item):has(a)" )
11181
			.addClass( "ui-menu-item" )
11182
			.attr( "role", "presentation" )
11183
			.children( "a" )
11184
				.uniqueId()
11185
				.addClass( "ui-corner-all" )
11186
				.attr({
11187
					tabIndex: -1,
11188
					role: this._itemRole()
11189
				});
11190
 
11191
		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11192
		menus.children( ":not(.ui-menu-item)" ).each(function() {
11193
			var item = $( this );
11194
			// hyphen, em dash, en dash
11195
			if ( !/[^\-—–\s]/.test( item.text() ) ) {
11196
				item.addClass( "ui-widget-content ui-menu-divider" );
11197
			}
11198
		});
11199
 
11200
		// Add aria-disabled attribute to any disabled menu item
11201
		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11202
 
11203
		// If the active item has been removed, blur the menu
11204
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11205
			this.blur();
11206
		}
11207
	},
11208
 
11209
	_itemRole: function() {
11210
		return {
11211
			menu: "menuitem",
11212
			listbox: "option"
11213
		}[ this.options.role ];
11214
	},
11215
 
11216
	focus: function( event, item ) {
11217
		var nested, focused;
11218
		this.blur( event, event && event.type === "focus" );
11219
 
11220
		this._scrollIntoView( item );
11221
 
11222
		this.active = item.first();
11223
		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11224
		// Only update aria-activedescendant if there's a role
11225
		// otherwise we assume focus is managed elsewhere
11226
		if ( this.options.role ) {
11227
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11228
		}
11229
 
11230
		// Highlight active parent menu item, if any
11231
		this.active
11232
			.parent()
11233
			.closest( ".ui-menu-item" )
11234
			.children( "a:first" )
11235
			.addClass( "ui-state-active" );
11236
 
11237
		if ( event && event.type === "keydown" ) {
11238
			this._close();
11239
		} else {
11240
			this.timer = this._delay(function() {
11241
				this._close();
11242
			}, this.delay );
11243
		}
11244
 
11245
		nested = item.children( ".ui-menu" );
11246
		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
11247
			this._startOpening(nested);
11248
		}
11249
		this.activeMenu = item.parent();
11250
 
11251
		this._trigger( "focus", event, { item: item } );
11252
	},
11253
 
11254
	_scrollIntoView: function( item ) {
11255
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11256
		if ( this._hasScroll() ) {
11257
			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11258
			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11259
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11260
			scroll = this.activeMenu.scrollTop();
11261
			elementHeight = this.activeMenu.height();
11262
			itemHeight = item.height();
11263
 
11264
			if ( offset < 0 ) {
11265
				this.activeMenu.scrollTop( scroll + offset );
11266
			} else if ( offset + itemHeight > elementHeight ) {
11267
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11268
			}
11269
		}
11270
	},
11271
 
11272
	blur: function( event, fromFocus ) {
11273
		if ( !fromFocus ) {
11274
			clearTimeout( this.timer );
11275
		}
11276
 
11277
		if ( !this.active ) {
11278
			return;
11279
		}
11280
 
11281
		this.active.children( "a" ).removeClass( "ui-state-focus" );
11282
		this.active = null;
11283
 
11284
		this._trigger( "blur", event, { item: this.active } );
11285
	},
11286
 
11287
	_startOpening: function( submenu ) {
11288
		clearTimeout( this.timer );
11289
 
11290
		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
11291
		// shift in the submenu position when mousing over the carat icon
11292
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11293
			return;
11294
		}
11295
 
11296
		this.timer = this._delay(function() {
11297
			this._close();
11298
			this._open( submenu );
11299
		}, this.delay );
11300
	},
11301
 
11302
	_open: function( submenu ) {
11303
		var position = $.extend({
11304
			of: this.active
11305
		}, this.options.position );
11306
 
11307
		clearTimeout( this.timer );
11308
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11309
			.hide()
11310
			.attr( "aria-hidden", "true" );
11311
 
11312
		submenu
11313
			.show()
11314
			.removeAttr( "aria-hidden" )
11315
			.attr( "aria-expanded", "true" )
11316
			.position( position );
11317
	},
11318
 
11319
	collapseAll: function( event, all ) {
11320
		clearTimeout( this.timer );
11321
		this.timer = this._delay(function() {
11322
			// If we were passed an event, look for the submenu that contains the event
11323
			var currentMenu = all ? this.element :
11324
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11325
 
11326
			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11327
			if ( !currentMenu.length ) {
11328
				currentMenu = this.element;
11329
			}
11330
 
11331
			this._close( currentMenu );
11332
 
11333
			this.blur( event );
11334
			this.activeMenu = currentMenu;
11335
		}, this.delay );
11336
	},
11337
 
11338
	// With no arguments, closes the currently active menu - if nothing is active
11339
	// it closes all menus.  If passed an argument, it will search for menus BELOW
11340
	_close: function( startMenu ) {
11341
		if ( !startMenu ) {
11342
			startMenu = this.active ? this.active.parent() : this.element;
11343
		}
11344
 
11345
		startMenu
11346
			.find( ".ui-menu" )
11347
				.hide()
11348
				.attr( "aria-hidden", "true" )
11349
				.attr( "aria-expanded", "false" )
11350
			.end()
11351
			.find( "a.ui-state-active" )
11352
				.removeClass( "ui-state-active" );
11353
	},
11354
 
11355
	collapse: function( event ) {
11356
		var newItem = this.active &&
11357
			this.active.parent().closest( ".ui-menu-item", this.element );
11358
		if ( newItem && newItem.length ) {
11359
			this._close();
11360
			this.focus( event, newItem );
11361
		}
11362
	},
11363
 
11364
	expand: function( event ) {
11365
		var newItem = this.active &&
11366
			this.active
11367
				.children( ".ui-menu " )
11368
				.children( ".ui-menu-item" )
11369
				.first();
11370
 
11371
		if ( newItem && newItem.length ) {
11372
			this._open( newItem.parent() );
11373
 
11374
			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11375
			this._delay(function() {
11376
				this.focus( event, newItem );
11377
			});
11378
		}
11379
	},
11380
 
11381
	next: function( event ) {
11382
		this._move( "next", "first", event );
11383
	},
11384
 
11385
	previous: function( event ) {
11386
		this._move( "prev", "last", event );
11387
	},
11388
 
11389
	isFirstItem: function() {
11390
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11391
	},
11392
 
11393
	isLastItem: function() {
11394
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11395
	},
11396
 
11397
	_move: function( direction, filter, event ) {
11398
		var next;
11399
		if ( this.active ) {
11400
			if ( direction === "first" || direction === "last" ) {
11401
				next = this.active
11402
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11403
					.eq( -1 );
11404
			} else {
11405
				next = this.active
11406
					[ direction + "All" ]( ".ui-menu-item" )
11407
					.eq( 0 );
11408
			}
11409
		}
11410
		if ( !next || !next.length || !this.active ) {
11411
			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11412
		}
11413
 
11414
		this.focus( event, next );
11415
	},
11416
 
11417
	nextPage: function( event ) {
11418
		var item, base, height;
11419
 
11420
		if ( !this.active ) {
11421
			this.next( event );
11422
			return;
11423
		}
11424
		if ( this.isLastItem() ) {
11425
			return;
11426
		}
11427
		if ( this._hasScroll() ) {
11428
			base = this.active.offset().top;
11429
			height = this.element.height();
11430
			this.active.nextAll( ".ui-menu-item" ).each(function() {
11431
				item = $( this );
11432
				return item.offset().top - base - height < 0;
11433
			});
11434
 
11435
			this.focus( event, item );
11436
		} else {
11437
			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
11438
				[ !this.active ? "first" : "last" ]() );
11439
		}
11440
	},
11441
 
11442
	previousPage: function( event ) {
11443
		var item, base, height;
11444
		if ( !this.active ) {
11445
			this.next( event );
11446
			return;
11447
		}
11448
		if ( this.isFirstItem() ) {
11449
			return;
11450
		}
11451
		if ( this._hasScroll() ) {
11452
			base = this.active.offset().top;
11453
			height = this.element.height();
11454
			this.active.prevAll( ".ui-menu-item" ).each(function() {
11455
				item = $( this );
11456
				return item.offset().top - base + height > 0;
11457
			});
11458
 
11459
			this.focus( event, item );
11460
		} else {
11461
			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
11462
		}
11463
	},
11464
 
11465
	_hasScroll: function() {
11466
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
11467
	},
11468
 
11469
	select: function( event ) {
11470
		// TODO: It should never be possible to not have an active item at this
11471
		// point, but the tests don't trigger mouseenter before click.
11472
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
11473
		var ui = { item: this.active };
11474
		if ( !this.active.has( ".ui-menu" ).length ) {
11475
			this.collapseAll( event, true );
11476
		}
11477
		this._trigger( "select", event, ui );
11478
	}
11479
});
11480
 
11481
}( jQuery ));
11482
 
11483
(function( $, undefined ) {
11484
 
11485
$.ui = $.ui || {};
11486
 
11487
var cachedScrollbarWidth,
11488
	max = Math.max,
11489
	abs = Math.abs,
11490
	round = Math.round,
11491
	rhorizontal = /left|center|right/,
11492
	rvertical = /top|center|bottom/,
11493
	roffset = /[\+\-]\d+%?/,
11494
	rposition = /^\w+/,
11495
	rpercent = /%$/,
11496
	_position = $.fn.position;
11497
 
11498
function getOffsets( offsets, width, height ) {
11499
	return [
11500
		parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
11501
		parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
11502
	];
11503
}
11504
function parseCss( element, property ) {
11505
	return parseInt( $.css( element, property ), 10 ) || 0;
11506
}
11507
 
11508
$.position = {
11509
	scrollbarWidth: function() {
11510
		if ( cachedScrollbarWidth !== undefined ) {
11511
			return cachedScrollbarWidth;
11512
		}
11513
		var w1, w2,
11514
			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
11515
			innerDiv = div.children()[0];
11516
 
11517
		$( "body" ).append( div );
11518
		w1 = innerDiv.offsetWidth;
11519
		div.css( "overflow", "scroll" );
11520
 
11521
		w2 = innerDiv.offsetWidth;
11522
 
11523
		if ( w1 === w2 ) {
11524
			w2 = div[0].clientWidth;
11525
		}
11526
 
11527
		div.remove();
11528
 
11529
		return (cachedScrollbarWidth = w1 - w2);
11530
	},
11531
	getScrollInfo: function( within ) {
11532
		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
11533
			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
11534
			hasOverflowX = overflowX === "scroll" ||
11535
				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
11536
			hasOverflowY = overflowY === "scroll" ||
11537
				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
11538
		return {
11539
			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
11540
			height: hasOverflowY ? $.position.scrollbarWidth() : 0
11541
		};
11542
	},
11543
	getWithinInfo: function( element ) {
11544
		var withinElement = $( element || window ),
11545
			isWindow = $.isWindow( withinElement[0] );
11546
		return {
11547
			element: withinElement,
11548
			isWindow: isWindow,
11549
			offset: withinElement.offset() || { left: 0, top: 0 },
11550
			scrollLeft: withinElement.scrollLeft(),
11551
			scrollTop: withinElement.scrollTop(),
11552
			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
11553
			height: isWindow ? withinElement.height() : withinElement.outerHeight()
11554
		};
11555
	}
11556
};
11557
 
11558
$.fn.position = function( options ) {
11559
	if ( !options || !options.of ) {
11560
		return _position.apply( this, arguments );
11561
	}
11562
 
11563
	// make a copy, we don't want to modify arguments
11564
	options = $.extend( {}, options );
11565
 
11566
	var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
11567
		target = $( options.of ),
11568
		within = $.position.getWithinInfo( options.within ),
11569
		scrollInfo = $.position.getScrollInfo( within ),
11570
		targetElem = target[0],
11571
		collision = ( options.collision || "flip" ).split( " " ),
11572
		offsets = {};
11573
 
11574
	if ( targetElem.nodeType === 9 ) {
11575
		targetWidth = target.width();
11576
		targetHeight = target.height();
11577
		targetOffset = { top: 0, left: 0 };
11578
	} else if ( $.isWindow( targetElem ) ) {
11579
		targetWidth = target.width();
11580
		targetHeight = target.height();
11581
		targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
11582
	} else if ( targetElem.preventDefault ) {
11583
		// force left top to allow flipping
11584
		options.at = "left top";
11585
		targetWidth = targetHeight = 0;
11586
		targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
11587
	} else {
11588
		targetWidth = target.outerWidth();
11589
		targetHeight = target.outerHeight();
11590
		targetOffset = target.offset();
11591
	}
11592
	// clone to reuse original targetOffset later
11593
	basePosition = $.extend( {}, targetOffset );
11594
 
11595
	// force my and at to have valid horizontal and vertical positions
11596
	// if a value is missing or invalid, it will be converted to center
11597
	$.each( [ "my", "at" ], function() {
11598
		var pos = ( options[ this ] || "" ).split( " " ),
11599
			horizontalOffset,
11600
			verticalOffset;
11601
 
11602
		if ( pos.length === 1) {
11603
			pos = rhorizontal.test( pos[ 0 ] ) ?
11604
				pos.concat( [ "center" ] ) :
11605
				rvertical.test( pos[ 0 ] ) ?
11606
					[ "center" ].concat( pos ) :
11607
					[ "center", "center" ];
11608
		}
11609
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
11610
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
11611
 
11612
		// calculate offsets
11613
		horizontalOffset = roffset.exec( pos[ 0 ] );
11614
		verticalOffset = roffset.exec( pos[ 1 ] );
11615
		offsets[ this ] = [
11616
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
11617
			verticalOffset ? verticalOffset[ 0 ] : 0
11618
		];
11619
 
11620
		// reduce to just the positions without the offsets
11621
		options[ this ] = [
11622
			rposition.exec( pos[ 0 ] )[ 0 ],
11623
			rposition.exec( pos[ 1 ] )[ 0 ]
11624
		];
11625
	});
11626
 
11627
	// normalize collision option
11628
	if ( collision.length === 1 ) {
11629
		collision[ 1 ] = collision[ 0 ];
11630
	}
11631
 
11632
	if ( options.at[ 0 ] === "right" ) {
11633
		basePosition.left += targetWidth;
11634
	} else if ( options.at[ 0 ] === "center" ) {
11635
		basePosition.left += targetWidth / 2;
11636
	}
11637
 
11638
	if ( options.at[ 1 ] === "bottom" ) {
11639
		basePosition.top += targetHeight;
11640
	} else if ( options.at[ 1 ] === "center" ) {
11641
		basePosition.top += targetHeight / 2;
11642
	}
11643
 
11644
	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
11645
	basePosition.left += atOffset[ 0 ];
11646
	basePosition.top += atOffset[ 1 ];
11647
 
11648
	return this.each(function() {
11649
		var collisionPosition, using,
11650
			elem = $( this ),
11651
			elemWidth = elem.outerWidth(),
11652
			elemHeight = elem.outerHeight(),
11653
			marginLeft = parseCss( this, "marginLeft" ),
11654
			marginTop = parseCss( this, "marginTop" ),
11655
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
11656
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
11657
			position = $.extend( {}, basePosition ),
11658
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
11659
 
11660
		if ( options.my[ 0 ] === "right" ) {
11661
			position.left -= elemWidth;
11662
		} else if ( options.my[ 0 ] === "center" ) {
11663
			position.left -= elemWidth / 2;
11664
		}
11665
 
11666
		if ( options.my[ 1 ] === "bottom" ) {
11667
			position.top -= elemHeight;
11668
		} else if ( options.my[ 1 ] === "center" ) {
11669
			position.top -= elemHeight / 2;
11670
		}
11671
 
11672
		position.left += myOffset[ 0 ];
11673
		position.top += myOffset[ 1 ];
11674
 
11675
		// if the browser doesn't support fractions, then round for consistent results
11676
		if ( !$.support.offsetFractions ) {
11677
			position.left = round( position.left );
11678
			position.top = round( position.top );
11679
		}
11680
 
11681
		collisionPosition = {
11682
			marginLeft: marginLeft,
11683
			marginTop: marginTop
11684
		};
11685
 
11686
		$.each( [ "left", "top" ], function( i, dir ) {
11687
			if ( $.ui.position[ collision[ i ] ] ) {
11688
				$.ui.position[ collision[ i ] ][ dir ]( position, {
11689
					targetWidth: targetWidth,
11690
					targetHeight: targetHeight,
11691
					elemWidth: elemWidth,
11692
					elemHeight: elemHeight,
11693
					collisionPosition: collisionPosition,
11694
					collisionWidth: collisionWidth,
11695
					collisionHeight: collisionHeight,
11696
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
11697
					my: options.my,
11698
					at: options.at,
11699
					within: within,
11700
					elem : elem
11701
				});
11702
			}
11703
		});
11704
 
11705
		if ( $.fn.bgiframe ) {
11706
			elem.bgiframe();
11707
		}
11708
 
11709
		if ( options.using ) {
11710
			// adds feedback as second argument to using callback, if present
11711
			using = function( props ) {
11712
				var left = targetOffset.left - position.left,
11713
					right = left + targetWidth - elemWidth,
11714
					top = targetOffset.top - position.top,
11715
					bottom = top + targetHeight - elemHeight,
11716
					feedback = {
11717
						target: {
11718
							element: target,
11719
							left: targetOffset.left,
11720
							top: targetOffset.top,
11721
							width: targetWidth,
11722
							height: targetHeight
11723
						},
11724
						element: {
11725
							element: elem,
11726
							left: position.left,
11727
							top: position.top,
11728
							width: elemWidth,
11729
							height: elemHeight
11730
						},
11731
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
11732
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
11733
					};
11734
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
11735
					feedback.horizontal = "center";
11736
				}
11737
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
11738
					feedback.vertical = "middle";
11739
				}
11740
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
11741
					feedback.important = "horizontal";
11742
				} else {
11743
					feedback.important = "vertical";
11744
				}
11745
				options.using.call( this, props, feedback );
11746
			};
11747
		}
11748
 
11749
		elem.offset( $.extend( position, { using: using } ) );
11750
	});
11751
};
11752
 
11753
$.ui.position = {
11754
	fit: {
11755
		left: function( position, data ) {
11756
			var within = data.within,
11757
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
11758
				outerWidth = within.width,
11759
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
11760
				overLeft = withinOffset - collisionPosLeft,
11761
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
11762
				newOverRight;
11763
 
11764
			// element is wider than within
11765
			if ( data.collisionWidth > outerWidth ) {
11766
				// element is initially over the left side of within
11767
				if ( overLeft > 0 && overRight <= 0 ) {
11768
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
11769
					position.left += overLeft - newOverRight;
11770
				// element is initially over right side of within
11771
				} else if ( overRight > 0 && overLeft <= 0 ) {
11772
					position.left = withinOffset;
11773
				// element is initially over both left and right sides of within
11774
				} else {
11775
					if ( overLeft > overRight ) {
11776
						position.left = withinOffset + outerWidth - data.collisionWidth;
11777
					} else {
11778
						position.left = withinOffset;
11779
					}
11780
				}
11781
			// too far left -> align with left edge
11782
			} else if ( overLeft > 0 ) {
11783
				position.left += overLeft;
11784
			// too far right -> align with right edge
11785
			} else if ( overRight > 0 ) {
11786
				position.left -= overRight;
11787
			// adjust based on position and margin
11788
			} else {
11789
				position.left = max( position.left - collisionPosLeft, position.left );
11790
			}
11791
		},
11792
		top: function( position, data ) {
11793
			var within = data.within,
11794
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
11795
				outerHeight = data.within.height,
11796
				collisionPosTop = position.top - data.collisionPosition.marginTop,
11797
				overTop = withinOffset - collisionPosTop,
11798
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
11799
				newOverBottom;
11800
 
11801
			// element is taller than within
11802
			if ( data.collisionHeight > outerHeight ) {
11803
				// element is initially over the top of within
11804
				if ( overTop > 0 && overBottom <= 0 ) {
11805
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
11806
					position.top += overTop - newOverBottom;
11807
				// element is initially over bottom of within
11808
				} else if ( overBottom > 0 && overTop <= 0 ) {
11809
					position.top = withinOffset;
11810
				// element is initially over both top and bottom of within
11811
				} else {
11812
					if ( overTop > overBottom ) {
11813
						position.top = withinOffset + outerHeight - data.collisionHeight;
11814
					} else {
11815
						position.top = withinOffset;
11816
					}
11817
				}
11818
			// too far up -> align with top
11819
			} else if ( overTop > 0 ) {
11820
				position.top += overTop;
11821
			// too far down -> align with bottom edge
11822
			} else if ( overBottom > 0 ) {
11823
				position.top -= overBottom;
11824
			// adjust based on position and margin
11825
			} else {
11826
				position.top = max( position.top - collisionPosTop, position.top );
11827
			}
11828
		}
11829
	},
11830
	flip: {
11831
		left: function( position, data ) {
11832
			var within = data.within,
11833
				withinOffset = within.offset.left + within.scrollLeft,
11834
				outerWidth = within.width,
11835
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
11836
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
11837
				overLeft = collisionPosLeft - offsetLeft,
11838
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
11839
				myOffset = data.my[ 0 ] === "left" ?
11840
					-data.elemWidth :
11841
					data.my[ 0 ] === "right" ?
11842
						data.elemWidth :
11843
						0,
11844
				atOffset = data.at[ 0 ] === "left" ?
11845
					data.targetWidth :
11846
					data.at[ 0 ] === "right" ?
11847
						-data.targetWidth :
11848
						0,
11849
				offset = -2 * data.offset[ 0 ],
11850
				newOverRight,
11851
				newOverLeft;
11852
 
11853
			if ( overLeft < 0 ) {
11854
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
11855
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
11856
					position.left += myOffset + atOffset + offset;
11857
				}
11858
			}
11859
			else if ( overRight > 0 ) {
11860
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
11861
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
11862
					position.left += myOffset + atOffset + offset;
11863
				}
11864
			}
11865
		},
11866
		top: function( position, data ) {
11867
			var within = data.within,
11868
				withinOffset = within.offset.top + within.scrollTop,
11869
				outerHeight = within.height,
11870
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
11871
				collisionPosTop = position.top - data.collisionPosition.marginTop,
11872
				overTop = collisionPosTop - offsetTop,
11873
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
11874
				top = data.my[ 1 ] === "top",
11875
				myOffset = top ?
11876
					-data.elemHeight :
11877
					data.my[ 1 ] === "bottom" ?
11878
						data.elemHeight :
11879
						0,
11880
				atOffset = data.at[ 1 ] === "top" ?
11881
					data.targetHeight :
11882
					data.at[ 1 ] === "bottom" ?
11883
						-data.targetHeight :
11884
						0,
11885
				offset = -2 * data.offset[ 1 ],
11886
				newOverTop,
11887
				newOverBottom;
11888
			if ( overTop < 0 ) {
11889
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
11890
				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
11891
					position.top += myOffset + atOffset + offset;
11892
				}
11893
			}
11894
			else if ( overBottom > 0 ) {
11895
				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
11896
				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
11897
					position.top += myOffset + atOffset + offset;
11898
				}
11899
			}
11900
		}
11901
	},
11902
	flipfit: {
11903
		left: function() {
11904
			$.ui.position.flip.left.apply( this, arguments );
11905
			$.ui.position.fit.left.apply( this, arguments );
11906
		},
11907
		top: function() {
11908
			$.ui.position.flip.top.apply( this, arguments );
11909
			$.ui.position.fit.top.apply( this, arguments );
11910
		}
11911
	}
11912
};
11913
 
11914
// fraction support test
11915
(function () {
11916
	var testElement, testElementParent, testElementStyle, offsetLeft, i,
11917
		body = document.getElementsByTagName( "body" )[ 0 ],
11918
		div = document.createElement( "div" );
11919
 
11920
	//Create a "fake body" for testing based on method used in jQuery.support
11921
	testElement = document.createElement( body ? "div" : "body" );
11922
	testElementStyle = {
11923
		visibility: "hidden",
11924
		width: 0,
11925
		height: 0,
11926
		border: 0,
11927
		margin: 0,
11928
		background: "none"
11929
	};
11930
	if ( body ) {
11931
		$.extend( testElementStyle, {
11932
			position: "absolute",
11933
			left: "-1000px",
11934
			top: "-1000px"
11935
		});
11936
	}
11937
	for ( i in testElementStyle ) {
11938
		testElement.style[ i ] = testElementStyle[ i ];
11939
	}
11940
	testElement.appendChild( div );
11941
	testElementParent = body || document.documentElement;
11942
	testElementParent.insertBefore( testElement, testElementParent.firstChild );
11943
 
11944
	div.style.cssText = "position: absolute; left: 10.7432222px;";
11945
 
11946
	offsetLeft = $( div ).offset().left;
11947
	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
11948
 
11949
	testElement.innerHTML = "";
11950
	testElementParent.removeChild( testElement );
11951
})();
11952
 
11953
// DEPRECATED
11954
if ( $.uiBackCompat !== false ) {
11955
	// offset option
11956
	(function( $ ) {
11957
		var _position = $.fn.position;
11958
		$.fn.position = function( options ) {
11959
			if ( !options || !options.offset ) {
11960
				return _position.call( this, options );
11961
			}
11962
			var offset = options.offset.split( " " ),
11963
				at = options.at.split( " " );
11964
			if ( offset.length === 1 ) {
11965
				offset[ 1 ] = offset[ 0 ];
11966
			}
11967
			if ( /^\d/.test( offset[ 0 ] ) ) {
11968
				offset[ 0 ] = "+" + offset[ 0 ];
11969
			}
11970
			if ( /^\d/.test( offset[ 1 ] ) ) {
11971
				offset[ 1 ] = "+" + offset[ 1 ];
11972
			}
11973
			if ( at.length === 1 ) {
11974
				if ( /left|center|right/.test( at[ 0 ] ) ) {
11975
					at[ 1 ] = "center";
11976
				} else {
11977
					at[ 1 ] = at[ 0 ];
11978
					at[ 0 ] = "center";
11979
				}
11980
			}
11981
			return _position.call( this, $.extend( options, {
11982
				at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
11983
				offset: undefined
11984
			} ) );
11985
		};
11986
	}( jQuery ) );
11987
}
11988
 
11989
}( jQuery ) );
11990
 
11991
(function( $, undefined ) {
11992
 
11993
$.widget( "ui.progressbar", {
11994
	version: "1.9.2",
11995
	options: {
11996
		value: 0,
11997
		max: 100
11998
	},
11999
 
12000
	min: 0,
12001
 
12002
	_create: function() {
12003
		this.element
12004
			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12005
			.attr({
12006
				role: "progressbar",
12007
				"aria-valuemin": this.min,
12008
				"aria-valuemax": this.options.max,
12009
				"aria-valuenow": this._value()
12010
			});
12011
 
12012
		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12013
			.appendTo( this.element );
12014
 
12015
		this.oldValue = this._value();
12016
		this._refreshValue();
12017
	},
12018
 
12019
	_destroy: function() {
12020
		this.element
12021
			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12022
			.removeAttr( "role" )
12023
			.removeAttr( "aria-valuemin" )
12024
			.removeAttr( "aria-valuemax" )
12025
			.removeAttr( "aria-valuenow" );
12026
 
12027
		this.valueDiv.remove();
12028
	},
12029
 
12030
	value: function( newValue ) {
12031
		if ( newValue === undefined ) {
12032
			return this._value();
12033
		}
12034
 
12035
		this._setOption( "value", newValue );
12036
		return this;
12037
	},
12038
 
12039
	_setOption: function( key, value ) {
12040
		if ( key === "value" ) {
12041
			this.options.value = value;
12042
			this._refreshValue();
12043
			if ( this._value() === this.options.max ) {
12044
				this._trigger( "complete" );
12045
			}
12046
		}
12047
 
12048
		this._super( key, value );
12049
	},
12050
 
12051
	_value: function() {
12052
		var val = this.options.value;
12053
		// normalize invalid value
12054
		if ( typeof val !== "number" ) {
12055
			val = 0;
12056
		}
12057
		return Math.min( this.options.max, Math.max( this.min, val ) );
12058
	},
12059
 
12060
	_percentage: function() {
12061
		return 100 * this._value() / this.options.max;
12062
	},
12063
 
12064
	_refreshValue: function() {
12065
		var value = this.value(),
12066
			percentage = this._percentage();
12067
 
12068
		if ( this.oldValue !== value ) {
12069
			this.oldValue = value;
12070
			this._trigger( "change" );
12071
		}
12072
 
12073
		this.valueDiv
12074
			.toggle( value > this.min )
12075
			.toggleClass( "ui-corner-right", value === this.options.max )
12076
			.width( percentage.toFixed(0) + "%" );
12077
		this.element.attr( "aria-valuenow", value );
12078
	}
12079
});
12080
 
12081
})( jQuery );
12082
 
12083
(function( $, undefined ) {
12084
 
12085
// number of pages in a slider
12086
// (how many times can you page up/down to go through the whole range)
12087
var numPages = 5;
12088
 
12089
$.widget( "ui.slider", $.ui.mouse, {
12090
	version: "1.9.2",
12091
	widgetEventPrefix: "slide",
12092
 
12093
	options: {
12094
		animate: false,
12095
		distance: 0,
12096
		max: 100,
12097
		min: 0,
12098
		orientation: "horizontal",
12099
		range: false,
12100
		step: 1,
12101
		value: 0,
12102
		values: null
12103
	},
12104
 
12105
	_create: function() {
12106
		var i, handleCount,
12107
			o = this.options,
12108
			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12109
			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12110
			handles = [];
12111
 
12112
		this._keySliding = false;
12113
		this._mouseSliding = false;
12114
		this._animateOff = true;
12115
		this._handleIndex = null;
12116
		this._detectOrientation();
12117
		this._mouseInit();
12118
 
12119
		this.element
12120
			.addClass( "ui-slider" +
12121
				" ui-slider-" + this.orientation +
12122
				" ui-widget" +
12123
				" ui-widget-content" +
12124
				" ui-corner-all" +
12125
				( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
12126
 
12127
		this.range = $([]);
12128
 
12129
		if ( o.range ) {
12130
			if ( o.range === true ) {
12131
				if ( !o.values ) {
12132
					o.values = [ this._valueMin(), this._valueMin() ];
12133
				}
12134
				if ( o.values.length && o.values.length !== 2 ) {
12135
					o.values = [ o.values[0], o.values[0] ];
12136
				}
12137
			}
12138
 
12139
			this.range = $( "<div></div>" )
12140
				.appendTo( this.element )
12141
				.addClass( "ui-slider-range" +
12142
				// note: this isn't the most fittingly semantic framework class for this element,
12143
				// but worked best visually with a variety of themes
12144
				" ui-widget-header" +
12145
				( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
12146
		}
12147
 
12148
		handleCount = ( o.values && o.values.length ) || 1;
12149
 
12150
		for ( i = existingHandles.length; i < handleCount; i++ ) {
12151
			handles.push( handle );
12152
		}
12153
 
12154
		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12155
 
12156
		this.handle = this.handles.eq( 0 );
12157
 
12158
		this.handles.add( this.range ).filter( "a" )
12159
			.click(function( event ) {
12160
				event.preventDefault();
12161
			})
12162
			.mouseenter(function() {
12163
				if ( !o.disabled ) {
12164
					$( this ).addClass( "ui-state-hover" );
12165
				}
12166
			})
12167
			.mouseleave(function() {
12168
				$( this ).removeClass( "ui-state-hover" );
12169
			})
12170
			.focus(function() {
12171
				if ( !o.disabled ) {
12172
					$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
12173
					$( this ).addClass( "ui-state-focus" );
12174
				} else {
12175
					$( this ).blur();
12176
				}
12177
			})
12178
			.blur(function() {
12179
				$( this ).removeClass( "ui-state-focus" );
12180
			});
12181
 
12182
		this.handles.each(function( i ) {
12183
			$( this ).data( "ui-slider-handle-index", i );
12184
		});
12185
 
12186
		this._on( this.handles, {
12187
			keydown: function( event ) {
12188
				var allowed, curVal, newVal, step,
12189
					index = $( event.target ).data( "ui-slider-handle-index" );
12190
 
12191
				switch ( event.keyCode ) {
12192
					case $.ui.keyCode.HOME:
12193
					case $.ui.keyCode.END:
12194
					case $.ui.keyCode.PAGE_UP:
12195
					case $.ui.keyCode.PAGE_DOWN:
12196
					case $.ui.keyCode.UP:
12197
					case $.ui.keyCode.RIGHT:
12198
					case $.ui.keyCode.DOWN:
12199
					case $.ui.keyCode.LEFT:
12200
						event.preventDefault();
12201
						if ( !this._keySliding ) {
12202
							this._keySliding = true;
12203
							$( event.target ).addClass( "ui-state-active" );
12204
							allowed = this._start( event, index );
12205
							if ( allowed === false ) {
12206
								return;
12207
							}
12208
						}
12209
						break;
12210
				}
12211
 
12212
				step = this.options.step;
12213
				if ( this.options.values && this.options.values.length ) {
12214
					curVal = newVal = this.values( index );
12215
				} else {
12216
					curVal = newVal = this.value();
12217
				}
12218
 
12219
				switch ( event.keyCode ) {
12220
					case $.ui.keyCode.HOME:
12221
						newVal = this._valueMin();
12222
						break;
12223
					case $.ui.keyCode.END:
12224
						newVal = this._valueMax();
12225
						break;
12226
					case $.ui.keyCode.PAGE_UP:
12227
						newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
12228
						break;
12229
					case $.ui.keyCode.PAGE_DOWN:
12230
						newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
12231
						break;
12232
					case $.ui.keyCode.UP:
12233
					case $.ui.keyCode.RIGHT:
12234
						if ( curVal === this._valueMax() ) {
12235
							return;
12236
						}
12237
						newVal = this._trimAlignValue( curVal + step );
12238
						break;
12239
					case $.ui.keyCode.DOWN:
12240
					case $.ui.keyCode.LEFT:
12241
						if ( curVal === this._valueMin() ) {
12242
							return;
12243
						}
12244
						newVal = this._trimAlignValue( curVal - step );
12245
						break;
12246
				}
12247
 
12248
				this._slide( event, index, newVal );
12249
			},
12250
			keyup: function( event ) {
12251
				var index = $( event.target ).data( "ui-slider-handle-index" );
12252
 
12253
				if ( this._keySliding ) {
12254
					this._keySliding = false;
12255
					this._stop( event, index );
12256
					this._change( event, index );
12257
					$( event.target ).removeClass( "ui-state-active" );
12258
				}
12259
			}
12260
		});
12261
 
12262
		this._refreshValue();
12263
 
12264
		this._animateOff = false;
12265
	},
12266
 
12267
	_destroy: function() {
12268
		this.handles.remove();
12269
		this.range.remove();
12270
 
12271
		this.element
12272
			.removeClass( "ui-slider" +
12273
				" ui-slider-horizontal" +
12274
				" ui-slider-vertical" +
12275
				" ui-slider-disabled" +
12276
				" ui-widget" +
12277
				" ui-widget-content" +
12278
				" ui-corner-all" );
12279
 
12280
		this._mouseDestroy();
12281
	},
12282
 
12283
	_mouseCapture: function( event ) {
12284
		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12285
			that = this,
12286
			o = this.options;
12287
 
12288
		if ( o.disabled ) {
12289
			return false;
12290
		}
12291
 
12292
		this.elementSize = {
12293
			width: this.element.outerWidth(),
12294
			height: this.element.outerHeight()
12295
		};
12296
		this.elementOffset = this.element.offset();
12297
 
12298
		position = { x: event.pageX, y: event.pageY };
12299
		normValue = this._normValueFromMouse( position );
12300
		distance = this._valueMax() - this._valueMin() + 1;
12301
		this.handles.each(function( i ) {
12302
			var thisDistance = Math.abs( normValue - that.values(i) );
12303
			if ( distance > thisDistance ) {
12304
				distance = thisDistance;
12305
				closestHandle = $( this );
12306
				index = i;
12307
			}
12308
		});
12309
 
12310
		// workaround for bug #3736 (if both handles of a range are at 0,
12311
		// the first is always used as the one with least distance,
12312
		// and moving it is obviously prevented by preventing negative ranges)
12313
		if( o.range === true && this.values(1) === o.min ) {
12314
			index += 1;
12315
			closestHandle = $( this.handles[index] );
12316
		}
12317
 
12318
		allowed = this._start( event, index );
12319
		if ( allowed === false ) {
12320
			return false;
12321
		}
12322
		this._mouseSliding = true;
12323
 
12324
		this._handleIndex = index;
12325
 
12326
		closestHandle
12327
			.addClass( "ui-state-active" )
12328
			.focus();
12329
 
12330
		offset = closestHandle.offset();
12331
		mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
12332
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12333
			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12334
			top: event.pageY - offset.top -
12335
				( closestHandle.height() / 2 ) -
12336
				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12337
				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12338
				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12339
		};
12340
 
12341
		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12342
			this._slide( event, index, normValue );
12343
		}
12344
		this._animateOff = true;
12345
		return true;
12346
	},
12347
 
12348
	_mouseStart: function() {
12349
		return true;
12350
	},
12351
 
12352
	_mouseDrag: function( event ) {
12353
		var position = { x: event.pageX, y: event.pageY },
12354
			normValue = this._normValueFromMouse( position );
12355
 
12356
		this._slide( event, this._handleIndex, normValue );
12357
 
12358
		return false;
12359
	},
12360
 
12361
	_mouseStop: function( event ) {
12362
		this.handles.removeClass( "ui-state-active" );
12363
		this._mouseSliding = false;
12364
 
12365
		this._stop( event, this._handleIndex );
12366
		this._change( event, this._handleIndex );
12367
 
12368
		this._handleIndex = null;
12369
		this._clickOffset = null;
12370
		this._animateOff = false;
12371
 
12372
		return false;
12373
	},
12374
 
12375
	_detectOrientation: function() {
12376
		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12377
	},
12378
 
12379
	_normValueFromMouse: function( position ) {
12380
		var pixelTotal,
12381
			pixelMouse,
12382
			percentMouse,
12383
			valueTotal,
12384
			valueMouse;
12385
 
12386
		if ( this.orientation === "horizontal" ) {
12387
			pixelTotal = this.elementSize.width;
12388
			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12389
		} else {
12390
			pixelTotal = this.elementSize.height;
12391
			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12392
		}
12393
 
12394
		percentMouse = ( pixelMouse / pixelTotal );
12395
		if ( percentMouse > 1 ) {
12396
			percentMouse = 1;
12397
		}
12398
		if ( percentMouse < 0 ) {
12399
			percentMouse = 0;
12400
		}
12401
		if ( this.orientation === "vertical" ) {
12402
			percentMouse = 1 - percentMouse;
12403
		}
12404
 
12405
		valueTotal = this._valueMax() - this._valueMin();
12406
		valueMouse = this._valueMin() + percentMouse * valueTotal;
12407
 
12408
		return this._trimAlignValue( valueMouse );
12409
	},
12410
 
12411
	_start: function( event, index ) {
12412
		var uiHash = {
12413
			handle: this.handles[ index ],
12414
			value: this.value()
12415
		};
12416
		if ( this.options.values && this.options.values.length ) {
12417
			uiHash.value = this.values( index );
12418
			uiHash.values = this.values();
12419
		}
12420
		return this._trigger( "start", event, uiHash );
12421
	},
12422
 
12423
	_slide: function( event, index, newVal ) {
12424
		var otherVal,
12425
			newValues,
12426
			allowed;
12427
 
12428
		if ( this.options.values && this.options.values.length ) {
12429
			otherVal = this.values( index ? 0 : 1 );
12430
 
12431
			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12432
					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12433
				) {
12434
				newVal = otherVal;
12435
			}
12436
 
12437
			if ( newVal !== this.values( index ) ) {
12438
				newValues = this.values();
12439
				newValues[ index ] = newVal;
12440
				// A slide can be canceled by returning false from the slide callback
12441
				allowed = this._trigger( "slide", event, {
12442
					handle: this.handles[ index ],
12443
					value: newVal,
12444
					values: newValues
12445
				} );
12446
				otherVal = this.values( index ? 0 : 1 );
12447
				if ( allowed !== false ) {
12448
					this.values( index, newVal, true );
12449
				}
12450
			}
12451
		} else {
12452
			if ( newVal !== this.value() ) {
12453
				// A slide can be canceled by returning false from the slide callback
12454
				allowed = this._trigger( "slide", event, {
12455
					handle: this.handles[ index ],
12456
					value: newVal
12457
				} );
12458
				if ( allowed !== false ) {
12459
					this.value( newVal );
12460
				}
12461
			}
12462
		}
12463
	},
12464
 
12465
	_stop: function( event, index ) {
12466
		var uiHash = {
12467
			handle: this.handles[ index ],
12468
			value: this.value()
12469
		};
12470
		if ( this.options.values && this.options.values.length ) {
12471
			uiHash.value = this.values( index );
12472
			uiHash.values = this.values();
12473
		}
12474
 
12475
		this._trigger( "stop", event, uiHash );
12476
	},
12477
 
12478
	_change: function( event, index ) {
12479
		if ( !this._keySliding && !this._mouseSliding ) {
12480
			var uiHash = {
12481
				handle: this.handles[ index ],
12482
				value: this.value()
12483
			};
12484
			if ( this.options.values && this.options.values.length ) {
12485
				uiHash.value = this.values( index );
12486
				uiHash.values = this.values();
12487
			}
12488
 
12489
			this._trigger( "change", event, uiHash );
12490
		}
12491
	},
12492
 
12493
	value: function( newValue ) {
12494
		if ( arguments.length ) {
12495
			this.options.value = this._trimAlignValue( newValue );
12496
			this._refreshValue();
12497
			this._change( null, 0 );
12498
			return;
12499
		}
12500
 
12501
		return this._value();
12502
	},
12503
 
12504
	values: function( index, newValue ) {
12505
		var vals,
12506
			newValues,
12507
			i;
12508
 
12509
		if ( arguments.length > 1 ) {
12510
			this.options.values[ index ] = this._trimAlignValue( newValue );
12511
			this._refreshValue();
12512
			this._change( null, index );
12513
			return;
12514
		}
12515
 
12516
		if ( arguments.length ) {
12517
			if ( $.isArray( arguments[ 0 ] ) ) {
12518
				vals = this.options.values;
12519
				newValues = arguments[ 0 ];
12520
				for ( i = 0; i < vals.length; i += 1 ) {
12521
					vals[ i ] = this._trimAlignValue( newValues[ i ] );
12522
					this._change( null, i );
12523
				}
12524
				this._refreshValue();
12525
			} else {
12526
				if ( this.options.values && this.options.values.length ) {
12527
					return this._values( index );
12528
				} else {
12529
					return this.value();
12530
				}
12531
			}
12532
		} else {
12533
			return this._values();
12534
		}
12535
	},
12536
 
12537
	_setOption: function( key, value ) {
12538
		var i,
12539
			valsLength = 0;
12540
 
12541
		if ( $.isArray( this.options.values ) ) {
12542
			valsLength = this.options.values.length;
12543
		}
12544
 
12545
		$.Widget.prototype._setOption.apply( this, arguments );
12546
 
12547
		switch ( key ) {
12548
			case "disabled":
12549
				if ( value ) {
12550
					this.handles.filter( ".ui-state-focus" ).blur();
12551
					this.handles.removeClass( "ui-state-hover" );
12552
					this.handles.prop( "disabled", true );
12553
					this.element.addClass( "ui-disabled" );
12554
				} else {
12555
					this.handles.prop( "disabled", false );
12556
					this.element.removeClass( "ui-disabled" );
12557
				}
12558
				break;
12559
			case "orientation":
12560
				this._detectOrientation();
12561
				this.element
12562
					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
12563
					.addClass( "ui-slider-" + this.orientation );
12564
				this._refreshValue();
12565
				break;
12566
			case "value":
12567
				this._animateOff = true;
12568
				this._refreshValue();
12569
				this._change( null, 0 );
12570
				this._animateOff = false;
12571
				break;
12572
			case "values":
12573
				this._animateOff = true;
12574
				this._refreshValue();
12575
				for ( i = 0; i < valsLength; i += 1 ) {
12576
					this._change( null, i );
12577
				}
12578
				this._animateOff = false;
12579
				break;
12580
			case "min":
12581
			case "max":
12582
				this._animateOff = true;
12583
				this._refreshValue();
12584
				this._animateOff = false;
12585
				break;
12586
		}
12587
	},
12588
 
12589
	//internal value getter
12590
	// _value() returns value trimmed by min and max, aligned by step
12591
	_value: function() {
12592
		var val = this.options.value;
12593
		val = this._trimAlignValue( val );
12594
 
12595
		return val;
12596
	},
12597
 
12598
	//internal values getter
12599
	// _values() returns array of values trimmed by min and max, aligned by step
12600
	// _values( index ) returns single value trimmed by min and max, aligned by step
12601
	_values: function( index ) {
12602
		var val,
12603
			vals,
12604
			i;
12605
 
12606
		if ( arguments.length ) {
12607
			val = this.options.values[ index ];
12608
			val = this._trimAlignValue( val );
12609
 
12610
			return val;
12611
		} else {
12612
			// .slice() creates a copy of the array
12613
			// this copy gets trimmed by min and max and then returned
12614
			vals = this.options.values.slice();
12615
			for ( i = 0; i < vals.length; i+= 1) {
12616
				vals[ i ] = this._trimAlignValue( vals[ i ] );
12617
			}
12618
 
12619
			return vals;
12620
		}
12621
	},
12622
 
12623
	// returns the step-aligned value that val is closest to, between (inclusive) min and max
12624
	_trimAlignValue: function( val ) {
12625
		if ( val <= this._valueMin() ) {
12626
			return this._valueMin();
12627
		}
12628
		if ( val >= this._valueMax() ) {
12629
			return this._valueMax();
12630
		}
12631
		var step = ( this.options.step > 0 ) ? this.options.step : 1,
12632
			valModStep = (val - this._valueMin()) % step,
12633
			alignValue = val - valModStep;
12634
 
12635
		if ( Math.abs(valModStep) * 2 >= step ) {
12636
			alignValue += ( valModStep > 0 ) ? step : ( -step );
12637
		}
12638
 
12639
		// Since JavaScript has problems with large floats, round
12640
		// the final value to 5 digits after the decimal point (see #4124)
12641
		return parseFloat( alignValue.toFixed(5) );
12642
	},
12643
 
12644
	_valueMin: function() {
12645
		return this.options.min;
12646
	},
12647
 
12648
	_valueMax: function() {
12649
		return this.options.max;
12650
	},
12651
 
12652
	_refreshValue: function() {
12653
		var lastValPercent, valPercent, value, valueMin, valueMax,
12654
			oRange = this.options.range,
12655
			o = this.options,
12656
			that = this,
12657
			animate = ( !this._animateOff ) ? o.animate : false,
12658
			_set = {};
12659
 
12660
		if ( this.options.values && this.options.values.length ) {
12661
			this.handles.each(function( i ) {
12662
				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
12663
				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12664
				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12665
				if ( that.options.range === true ) {
12666
					if ( that.orientation === "horizontal" ) {
12667
						if ( i === 0 ) {
12668
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
12669
						}
12670
						if ( i === 1 ) {
12671
							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12672
						}
12673
					} else {
12674
						if ( i === 0 ) {
12675
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
12676
						}
12677
						if ( i === 1 ) {
12678
							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12679
						}
12680
					}
12681
				}
12682
				lastValPercent = valPercent;
12683
			});
12684
		} else {
12685
			value = this.value();
12686
			valueMin = this._valueMin();
12687
			valueMax = this._valueMax();
12688
			valPercent = ( valueMax !== valueMin ) ?
12689
					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
12690
					0;
12691
			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12692
			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12693
 
12694
			if ( oRange === "min" && this.orientation === "horizontal" ) {
12695
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
12696
			}
12697
			if ( oRange === "max" && this.orientation === "horizontal" ) {
12698
				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12699
			}
12700
			if ( oRange === "min" && this.orientation === "vertical" ) {
12701
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
12702
			}
12703
			if ( oRange === "max" && this.orientation === "vertical" ) {
12704
				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12705
			}
12706
		}
12707
	}
12708
 
12709
});
12710
 
12711
}(jQuery));
12712
 
12713
(function( $ ) {
12714
 
12715
function modifier( fn ) {
12716
	return function() {
12717
		var previous = this.element.val();
12718
		fn.apply( this, arguments );
12719
		this._refresh();
12720
		if ( previous !== this.element.val() ) {
12721
			this._trigger( "change" );
12722
		}
12723
	};
12724
}
12725
 
12726
$.widget( "ui.spinner", {
12727
	version: "1.9.2",
12728
	defaultElement: "<input>",
12729
	widgetEventPrefix: "spin",
12730
	options: {
12731
		culture: null,
12732
		icons: {
12733
			down: "ui-icon-triangle-1-s",
12734
			up: "ui-icon-triangle-1-n"
12735
		},
12736
		incremental: true,
12737
		max: null,
12738
		min: null,
12739
		numberFormat: null,
12740
		page: 10,
12741
		step: 1,
12742
 
12743
		change: null,
12744
		spin: null,
12745
		start: null,
12746
		stop: null
12747
	},
12748
 
12749
	_create: function() {
12750
		// handle string values that need to be parsed
12751
		this._setOption( "max", this.options.max );
12752
		this._setOption( "min", this.options.min );
12753
		this._setOption( "step", this.options.step );
12754
 
12755
		// format the value, but don't constrain
12756
		this._value( this.element.val(), true );
12757
 
12758
		this._draw();
12759
		this._on( this._events );
12760
		this._refresh();
12761
 
12762
		// turning off autocomplete prevents the browser from remembering the
12763
		// value when navigating through history, so we re-enable autocomplete
12764
		// if the page is unloaded before the widget is destroyed. #7790
12765
		this._on( this.window, {
12766
			beforeunload: function() {
12767
				this.element.removeAttr( "autocomplete" );
12768
			}
12769
		});
12770
	},
12771
 
12772
	_getCreateOptions: function() {
12773
		var options = {},
12774
			element = this.element;
12775
 
12776
		$.each( [ "min", "max", "step" ], function( i, option ) {
12777
			var value = element.attr( option );
12778
			if ( value !== undefined && value.length ) {
12779
				options[ option ] = value;
12780
			}
12781
		});
12782
 
12783
		return options;
12784
	},
12785
 
12786
	_events: {
12787
		keydown: function( event ) {
12788
			if ( this._start( event ) && this._keydown( event ) ) {
12789
				event.preventDefault();
12790
			}
12791
		},
12792
		keyup: "_stop",
12793
		focus: function() {
12794
			this.previous = this.element.val();
12795
		},
12796
		blur: function( event ) {
12797
			if ( this.cancelBlur ) {
12798
				delete this.cancelBlur;
12799
				return;
12800
			}
12801
 
12802
			this._refresh();
12803
			if ( this.previous !== this.element.val() ) {
12804
				this._trigger( "change", event );
12805
			}
12806
		},
12807
		mousewheel: function( event, delta ) {
12808
			if ( !delta ) {
12809
				return;
12810
			}
12811
			if ( !this.spinning && !this._start( event ) ) {
12812
				return false;
12813
			}
12814
 
12815
			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
12816
			clearTimeout( this.mousewheelTimer );
12817
			this.mousewheelTimer = this._delay(function() {
12818
				if ( this.spinning ) {
12819
					this._stop( event );
12820
				}
12821
			}, 100 );
12822
			event.preventDefault();
12823
		},
12824
		"mousedown .ui-spinner-button": function( event ) {
12825
			var previous;
12826
 
12827
			// We never want the buttons to have focus; whenever the user is
12828
			// interacting with the spinner, the focus should be on the input.
12829
			// If the input is focused then this.previous is properly set from
12830
			// when the input first received focus. If the input is not focused
12831
			// then we need to set this.previous based on the value before spinning.
12832
			previous = this.element[0] === this.document[0].activeElement ?
12833
				this.previous : this.element.val();
12834
			function checkFocus() {
12835
				var isActive = this.element[0] === this.document[0].activeElement;
12836
				if ( !isActive ) {
12837
					this.element.focus();
12838
					this.previous = previous;
12839
					// support: IE
12840
					// IE sets focus asynchronously, so we need to check if focus
12841
					// moved off of the input because the user clicked on the button.
12842
					this._delay(function() {
12843
						this.previous = previous;
12844
					});
12845
				}
12846
			}
12847
 
12848
			// ensure focus is on (or stays on) the text field
12849
			event.preventDefault();
12850
			checkFocus.call( this );
12851
 
12852
			// support: IE
12853
			// IE doesn't prevent moving focus even with event.preventDefault()
12854
			// so we set a flag to know when we should ignore the blur event
12855
			// and check (again) if focus moved off of the input.
12856
			this.cancelBlur = true;
12857
			this._delay(function() {
12858
				delete this.cancelBlur;
12859
				checkFocus.call( this );
12860
			});
12861
 
12862
			if ( this._start( event ) === false ) {
12863
				return;
12864
			}
12865
 
12866
			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12867
		},
12868
		"mouseup .ui-spinner-button": "_stop",
12869
		"mouseenter .ui-spinner-button": function( event ) {
12870
			// button will add ui-state-active if mouse was down while mouseleave and kept down
12871
			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
12872
				return;
12873
			}
12874
 
12875
			if ( this._start( event ) === false ) {
12876
				return false;
12877
			}
12878
			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12879
		},
12880
		// TODO: do we really want to consider this a stop?
12881
		// shouldn't we just stop the repeater and wait until mouseup before
12882
		// we trigger the stop event?
12883
		"mouseleave .ui-spinner-button": "_stop"
12884
	},
12885
 
12886
	_draw: function() {
12887
		var uiSpinner = this.uiSpinner = this.element
12888
			.addClass( "ui-spinner-input" )
12889
			.attr( "autocomplete", "off" )
12890
			.wrap( this._uiSpinnerHtml() )
12891
			.parent()
12892
				// add buttons
12893
				.append( this._buttonHtml() );
12894
 
12895
		this.element.attr( "role", "spinbutton" );
12896
 
12897
		// button bindings
12898
		this.buttons = uiSpinner.find( ".ui-spinner-button" )
12899
			.attr( "tabIndex", -1 )
12900
			.button()
12901
			.removeClass( "ui-corner-all" );
12902
 
12903
		// IE 6 doesn't understand height: 50% for the buttons
12904
		// unless the wrapper has an explicit height
12905
		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
12906
				uiSpinner.height() > 0 ) {
12907
			uiSpinner.height( uiSpinner.height() );
12908
		}
12909
 
12910
		// disable spinner if element was already disabled
12911
		if ( this.options.disabled ) {
12912
			this.disable();
12913
		}
12914
	},
12915
 
12916
	_keydown: function( event ) {
12917
		var options = this.options,
12918
			keyCode = $.ui.keyCode;
12919
 
12920
		switch ( event.keyCode ) {
12921
		case keyCode.UP:
12922
			this._repeat( null, 1, event );
12923
			return true;
12924
		case keyCode.DOWN:
12925
			this._repeat( null, -1, event );
12926
			return true;
12927
		case keyCode.PAGE_UP:
12928
			this._repeat( null, options.page, event );
12929
			return true;
12930
		case keyCode.PAGE_DOWN:
12931
			this._repeat( null, -options.page, event );
12932
			return true;
12933
		}
12934
 
12935
		return false;
12936
	},
12937
 
12938
	_uiSpinnerHtml: function() {
12939
		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
12940
	},
12941
 
12942
	_buttonHtml: function() {
12943
		return "" +
12944
			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
12945
				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
12946
			"</a>" +
12947
			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
12948
				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
12949
			"</a>";
12950
	},
12951
 
12952
	_start: function( event ) {
12953
		if ( !this.spinning && this._trigger( "start", event ) === false ) {
12954
			return false;
12955
		}
12956
 
12957
		if ( !this.counter ) {
12958
			this.counter = 1;
12959
		}
12960
		this.spinning = true;
12961
		return true;
12962
	},
12963
 
12964
	_repeat: function( i, steps, event ) {
12965
		i = i || 500;
12966
 
12967
		clearTimeout( this.timer );
12968
		this.timer = this._delay(function() {
12969
			this._repeat( 40, steps, event );
12970
		}, i );
12971
 
12972
		this._spin( steps * this.options.step, event );
12973
	},
12974
 
12975
	_spin: function( step, event ) {
12976
		var value = this.value() || 0;
12977
 
12978
		if ( !this.counter ) {
12979
			this.counter = 1;
12980
		}
12981
 
12982
		value = this._adjustValue( value + step * this._increment( this.counter ) );
12983
 
12984
		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
12985
			this._value( value );
12986
			this.counter++;
12987
		}
12988
	},
12989
 
12990
	_increment: function( i ) {
12991
		var incremental = this.options.incremental;
12992
 
12993
		if ( incremental ) {
12994
			return $.isFunction( incremental ) ?
12995
				incremental( i ) :
12996
				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
12997
		}
12998
 
12999
		return 1;
13000
	},
13001
 
13002
	_precision: function() {
13003
		var precision = this._precisionOf( this.options.step );
13004
		if ( this.options.min !== null ) {
13005
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13006
		}
13007
		return precision;
13008
	},
13009
 
13010
	_precisionOf: function( num ) {
13011
		var str = num.toString(),
13012
			decimal = str.indexOf( "." );
13013
		return decimal === -1 ? 0 : str.length - decimal - 1;
13014
	},
13015
 
13016
	_adjustValue: function( value ) {
13017
		var base, aboveMin,
13018
			options = this.options;
13019
 
13020
		// make sure we're at a valid step
13021
		// - find out where we are relative to the base (min or 0)
13022
		base = options.min !== null ? options.min : 0;
13023
		aboveMin = value - base;
13024
		// - round to the nearest step
13025
		aboveMin = Math.round(aboveMin / options.step) * options.step;
13026
		// - rounding is based on 0, so adjust back to our base
13027
		value = base + aboveMin;
13028
 
13029
		// fix precision from bad JS floating point math
13030
		value = parseFloat( value.toFixed( this._precision() ) );
13031
 
13032
		// clamp the value
13033
		if ( options.max !== null && value > options.max) {
13034
			return options.max;
13035
		}
13036
		if ( options.min !== null && value < options.min ) {
13037
			return options.min;
13038
		}
13039
 
13040
		return value;
13041
	},
13042
 
13043
	_stop: function( event ) {
13044
		if ( !this.spinning ) {
13045
			return;
13046
		}
13047
 
13048
		clearTimeout( this.timer );
13049
		clearTimeout( this.mousewheelTimer );
13050
		this.counter = 0;
13051
		this.spinning = false;
13052
		this._trigger( "stop", event );
13053
	},
13054
 
13055
	_setOption: function( key, value ) {
13056
		if ( key === "culture" || key === "numberFormat" ) {
13057
			var prevValue = this._parse( this.element.val() );
13058
			this.options[ key ] = value;
13059
			this.element.val( this._format( prevValue ) );
13060
			return;
13061
		}
13062
 
13063
		if ( key === "max" || key === "min" || key === "step" ) {
13064
			if ( typeof value === "string" ) {
13065
				value = this._parse( value );
13066
			}
13067
		}
13068
 
13069
		this._super( key, value );
13070
 
13071
		if ( key === "disabled" ) {
13072
			if ( value ) {
13073
				this.element.prop( "disabled", true );
13074
				this.buttons.button( "disable" );
13075
			} else {
13076
				this.element.prop( "disabled", false );
13077
				this.buttons.button( "enable" );
13078
			}
13079
		}
13080
	},
13081
 
13082
	_setOptions: modifier(function( options ) {
13083
		this._super( options );
13084
		this._value( this.element.val() );
13085
	}),
13086
 
13087
	_parse: function( val ) {
13088
		if ( typeof val === "string" && val !== "" ) {
13089
			val = window.Globalize && this.options.numberFormat ?
13090
				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13091
		}
13092
		return val === "" || isNaN( val ) ? null : val;
13093
	},
13094
 
13095
	_format: function( value ) {
13096
		if ( value === "" ) {
13097
			return "";
13098
		}
13099
		return window.Globalize && this.options.numberFormat ?
13100
			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13101
			value;
13102
	},
13103
 
13104
	_refresh: function() {
13105
		this.element.attr({
13106
			"aria-valuemin": this.options.min,
13107
			"aria-valuemax": this.options.max,
13108
			// TODO: what should we do with values that can't be parsed?
13109
			"aria-valuenow": this._parse( this.element.val() )
13110
		});
13111
	},
13112
 
13113
	// update the value without triggering change
13114
	_value: function( value, allowAny ) {
13115
		var parsed;
13116
		if ( value !== "" ) {
13117
			parsed = this._parse( value );
13118
			if ( parsed !== null ) {
13119
				if ( !allowAny ) {
13120
					parsed = this._adjustValue( parsed );
13121
				}
13122
				value = this._format( parsed );
13123
			}
13124
		}
13125
		this.element.val( value );
13126
		this._refresh();
13127
	},
13128
 
13129
	_destroy: function() {
13130
		this.element
13131
			.removeClass( "ui-spinner-input" )
13132
			.prop( "disabled", false )
13133
			.removeAttr( "autocomplete" )
13134
			.removeAttr( "role" )
13135
			.removeAttr( "aria-valuemin" )
13136
			.removeAttr( "aria-valuemax" )
13137
			.removeAttr( "aria-valuenow" );
13138
		this.uiSpinner.replaceWith( this.element );
13139
	},
13140
 
13141
	stepUp: modifier(function( steps ) {
13142
		this._stepUp( steps );
13143
	}),
13144
	_stepUp: function( steps ) {
13145
		this._spin( (steps || 1) * this.options.step );
13146
	},
13147
 
13148
	stepDown: modifier(function( steps ) {
13149
		this._stepDown( steps );
13150
	}),
13151
	_stepDown: function( steps ) {
13152
		this._spin( (steps || 1) * -this.options.step );
13153
	},
13154
 
13155
	pageUp: modifier(function( pages ) {
13156
		this._stepUp( (pages || 1) * this.options.page );
13157
	}),
13158
 
13159
	pageDown: modifier(function( pages ) {
13160
		this._stepDown( (pages || 1) * this.options.page );
13161
	}),
13162
 
13163
	value: function( newVal ) {
13164
		if ( !arguments.length ) {
13165
			return this._parse( this.element.val() );
13166
		}
13167
		modifier( this._value ).call( this, newVal );
13168
	},
13169
 
13170
	widget: function() {
13171
		return this.uiSpinner;
13172
	}
13173
});
13174
 
13175
}( jQuery ) );
13176
 
13177
(function( $, undefined ) {
13178
 
13179
var tabId = 0,
13180
	rhash = /#.*$/;
13181
 
13182
function getNextTabId() {
13183
	return ++tabId;
13184
}
13185
 
13186
function isLocal( anchor ) {
13187
	return anchor.hash.length > 1 &&
13188
		anchor.href.replace( rhash, "" ) ===
13189
			location.href.replace( rhash, "" )
13190
				// support: Safari 5.1
13191
				// Safari 5.1 doesn't encode spaces in window.location
13192
				// but it does encode spaces from anchors (#8777)
13193
				.replace( /\s/g, "%20" );
13194
}
13195
 
13196
$.widget( "ui.tabs", {
13197
	version: "1.9.2",
13198
	delay: 300,
13199
	options: {
13200
		active: null,
13201
		collapsible: false,
13202
		event: "click",
13203
		heightStyle: "content",
13204
		hide: null,
13205
		show: null,
13206
 
13207
		// callbacks
13208
		activate: null,
13209
		beforeActivate: null,
13210
		beforeLoad: null,
13211
		load: null
13212
	},
13213
 
13214
	_create: function() {
13215
		var that = this,
13216
			options = this.options,
13217
			active = options.active,
13218
			locationHash = location.hash.substring( 1 );
13219
 
13220
		this.running = false;
13221
 
13222
		this.element
13223
			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13224
			.toggleClass( "ui-tabs-collapsible", options.collapsible )
13225
			// Prevent users from focusing disabled tabs via click
13226
			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13227
				if ( $( this ).is( ".ui-state-disabled" ) ) {
13228
					event.preventDefault();
13229
				}
13230
			})
13231
			// support: IE <9
13232
			// Preventing the default action in mousedown doesn't prevent IE
13233
			// from focusing the element, so if the anchor gets focused, blur.
13234
			// We don't have to worry about focusing the previously focused
13235
			// element since clicking on a non-focusable element should focus
13236
			// the body anyway.
13237
			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13238
				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13239
					this.blur();
13240
				}
13241
			});
13242
 
13243
		this._processTabs();
13244
 
13245
		if ( active === null ) {
13246
			// check the fragment identifier in the URL
13247
			if ( locationHash ) {
13248
				this.tabs.each(function( i, tab ) {
13249
					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13250
						active = i;
13251
						return false;
13252
					}
13253
				});
13254
			}
13255
 
13256
			// check for a tab marked active via a class
13257
			if ( active === null ) {
13258
				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13259
			}
13260
 
13261
			// no active tab, set to false
13262
			if ( active === null || active === -1 ) {
13263
				active = this.tabs.length ? 0 : false;
13264
			}
13265
		}
13266
 
13267
		// handle numbers: negative, out of range
13268
		if ( active !== false ) {
13269
			active = this.tabs.index( this.tabs.eq( active ) );
13270
			if ( active === -1 ) {
13271
				active = options.collapsible ? false : 0;
13272
			}
13273
		}
13274
		options.active = active;
13275
 
13276
		// don't allow collapsible: false and active: false
13277
		if ( !options.collapsible && options.active === false && this.anchors.length ) {
13278
			options.active = 0;
13279
		}
13280
 
13281
		// Take disabling tabs via class attribute from HTML
13282
		// into account and update option properly.
13283
		if ( $.isArray( options.disabled ) ) {
13284
			options.disabled = $.unique( options.disabled.concat(
13285
				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13286
					return that.tabs.index( li );
13287
				})
13288
			) ).sort();
13289
		}
13290
 
13291
		// check for length avoids error when initializing empty list
13292
		if ( this.options.active !== false && this.anchors.length ) {
13293
			this.active = this._findActive( this.options.active );
13294
		} else {
13295
			this.active = $();
13296
		}
13297
 
13298
		this._refresh();
13299
 
13300
		if ( this.active.length ) {
13301
			this.load( options.active );
13302
		}
13303
	},
13304
 
13305
	_getCreateEventData: function() {
13306
		return {
13307
			tab: this.active,
13308
			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13309
		};
13310
	},
13311
 
13312
	_tabKeydown: function( event ) {
13313
		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13314
			selectedIndex = this.tabs.index( focusedTab ),
13315
			goingForward = true;
13316
 
13317
		if ( this._handlePageNav( event ) ) {
13318
			return;
13319
		}
13320
 
13321
		switch ( event.keyCode ) {
13322
			case $.ui.keyCode.RIGHT:
13323
			case $.ui.keyCode.DOWN:
13324
				selectedIndex++;
13325
				break;
13326
			case $.ui.keyCode.UP:
13327
			case $.ui.keyCode.LEFT:
13328
				goingForward = false;
13329
				selectedIndex--;
13330
				break;
13331
			case $.ui.keyCode.END:
13332
				selectedIndex = this.anchors.length - 1;
13333
				break;
13334
			case $.ui.keyCode.HOME:
13335
				selectedIndex = 0;
13336
				break;
13337
			case $.ui.keyCode.SPACE:
13338
				// Activate only, no collapsing
13339
				event.preventDefault();
13340
				clearTimeout( this.activating );
13341
				this._activate( selectedIndex );
13342
				return;
13343
			case $.ui.keyCode.ENTER:
13344
				// Toggle (cancel delayed activation, allow collapsing)
13345
				event.preventDefault();
13346
				clearTimeout( this.activating );
13347
				// Determine if we should collapse or activate
13348
				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13349
				return;
13350
			default:
13351
				return;
13352
		}
13353
 
13354
		// Focus the appropriate tab, based on which key was pressed
13355
		event.preventDefault();
13356
		clearTimeout( this.activating );
13357
		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13358
 
13359
		// Navigating with control key will prevent automatic activation
13360
		if ( !event.ctrlKey ) {
13361
			// Update aria-selected immediately so that AT think the tab is already selected.
13362
			// Otherwise AT may confuse the user by stating that they need to activate the tab,
13363
			// but the tab will already be activated by the time the announcement finishes.
13364
			focusedTab.attr( "aria-selected", "false" );
13365
			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13366
 
13367
			this.activating = this._delay(function() {
13368
				this.option( "active", selectedIndex );
13369
			}, this.delay );
13370
		}
13371
	},
13372
 
13373
	_panelKeydown: function( event ) {
13374
		if ( this._handlePageNav( event ) ) {
13375
			return;
13376
		}
13377
 
13378
		// Ctrl+up moves focus to the current tab
13379
		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13380
			event.preventDefault();
13381
			this.active.focus();
13382
		}
13383
	},
13384
 
13385
	// Alt+page up/down moves focus to the previous/next tab (and activates)
13386
	_handlePageNav: function( event ) {
13387
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13388
			this._activate( this._focusNextTab( this.options.active - 1, false ) );
13389
			return true;
13390
		}
13391
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13392
			this._activate( this._focusNextTab( this.options.active + 1, true ) );
13393
			return true;
13394
		}
13395
	},
13396
 
13397
	_findNextTab: function( index, goingForward ) {
13398
		var lastTabIndex = this.tabs.length - 1;
13399
 
13400
		function constrain() {
13401
			if ( index > lastTabIndex ) {
13402
				index = 0;
13403
			}
13404
			if ( index < 0 ) {
13405
				index = lastTabIndex;
13406
			}
13407
			return index;
13408
		}
13409
 
13410
		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
13411
			index = goingForward ? index + 1 : index - 1;
13412
		}
13413
 
13414
		return index;
13415
	},
13416
 
13417
	_focusNextTab: function( index, goingForward ) {
13418
		index = this._findNextTab( index, goingForward );
13419
		this.tabs.eq( index ).focus();
13420
		return index;
13421
	},
13422
 
13423
	_setOption: function( key, value ) {
13424
		if ( key === "active" ) {
13425
			// _activate() will handle invalid values and update this.options
13426
			this._activate( value );
13427
			return;
13428
		}
13429
 
13430
		if ( key === "disabled" ) {
13431
			// don't use the widget factory's disabled handling
13432
			this._setupDisabled( value );
13433
			return;
13434
		}
13435
 
13436
		this._super( key, value);
13437
 
13438
		if ( key === "collapsible" ) {
13439
			this.element.toggleClass( "ui-tabs-collapsible", value );
13440
			// Setting collapsible: false while collapsed; open first panel
13441
			if ( !value && this.options.active === false ) {
13442
				this._activate( 0 );
13443
			}
13444
		}
13445
 
13446
		if ( key === "event" ) {
13447
			this._setupEvents( value );
13448
		}
13449
 
13450
		if ( key === "heightStyle" ) {
13451
			this._setupHeightStyle( value );
13452
		}
13453
	},
13454
 
13455
	_tabId: function( tab ) {
13456
		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
13457
	},
13458
 
13459
	_sanitizeSelector: function( hash ) {
13460
		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
13461
	},
13462
 
13463
	refresh: function() {
13464
		var options = this.options,
13465
			lis = this.tablist.children( ":has(a[href])" );
13466
 
13467
		// get disabled tabs from class attribute from HTML
13468
		// this will get converted to a boolean if needed in _refresh()
13469
		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
13470
			return lis.index( tab );
13471
		});
13472
 
13473
		this._processTabs();
13474
 
13475
		// was collapsed or no tabs
13476
		if ( options.active === false || !this.anchors.length ) {
13477
			options.active = false;
13478
			this.active = $();
13479
		// was active, but active tab is gone
13480
		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
13481
			// all remaining tabs are disabled
13482
			if ( this.tabs.length === options.disabled.length ) {
13483
				options.active = false;
13484
				this.active = $();
13485
			// activate previous tab
13486
			} else {
13487
				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
13488
			}
13489
		// was active, active tab still exists
13490
		} else {
13491
			// make sure active index is correct
13492
			options.active = this.tabs.index( this.active );
13493
		}
13494
 
13495
		this._refresh();
13496
	},
13497
 
13498
	_refresh: function() {
13499
		this._setupDisabled( this.options.disabled );
13500
		this._setupEvents( this.options.event );
13501
		this._setupHeightStyle( this.options.heightStyle );
13502
 
13503
		this.tabs.not( this.active ).attr({
13504
			"aria-selected": "false",
13505
			tabIndex: -1
13506
		});
13507
		this.panels.not( this._getPanelForTab( this.active ) )
13508
			.hide()
13509
			.attr({
13510
				"aria-expanded": "false",
13511
				"aria-hidden": "true"
13512
			});
13513
 
13514
		// Make sure one tab is in the tab order
13515
		if ( !this.active.length ) {
13516
			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
13517
		} else {
13518
			this.active
13519
				.addClass( "ui-tabs-active ui-state-active" )
13520
				.attr({
13521
					"aria-selected": "true",
13522
					tabIndex: 0
13523
				});
13524
			this._getPanelForTab( this.active )
13525
				.show()
13526
				.attr({
13527
					"aria-expanded": "true",
13528
					"aria-hidden": "false"
13529
				});
13530
		}
13531
	},
13532
 
13533
	_processTabs: function() {
13534
		var that = this;
13535
 
13536
		this.tablist = this._getList()
13537
			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13538
			.attr( "role", "tablist" );
13539
 
13540
		this.tabs = this.tablist.find( "> li:has(a[href])" )
13541
			.addClass( "ui-state-default ui-corner-top" )
13542
			.attr({
13543
				role: "tab",
13544
				tabIndex: -1
13545
			});
13546
 
13547
		this.anchors = this.tabs.map(function() {
13548
				return $( "a", this )[ 0 ];
13549
			})
13550
			.addClass( "ui-tabs-anchor" )
13551
			.attr({
13552
				role: "presentation",
13553
				tabIndex: -1
13554
			});
13555
 
13556
		this.panels = $();
13557
 
13558
		this.anchors.each(function( i, anchor ) {
13559
			var selector, panel, panelId,
13560
				anchorId = $( anchor ).uniqueId().attr( "id" ),
13561
				tab = $( anchor ).closest( "li" ),
13562
				originalAriaControls = tab.attr( "aria-controls" );
13563
 
13564
			// inline tab
13565
			if ( isLocal( anchor ) ) {
13566
				selector = anchor.hash;
13567
				panel = that.element.find( that._sanitizeSelector( selector ) );
13568
			// remote tab
13569
			} else {
13570
				panelId = that._tabId( tab );
13571
				selector = "#" + panelId;
13572
				panel = that.element.find( selector );
13573
				if ( !panel.length ) {
13574
					panel = that._createPanel( panelId );
13575
					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
13576
				}
13577
				panel.attr( "aria-live", "polite" );
13578
			}
13579
 
13580
			if ( panel.length) {
13581
				that.panels = that.panels.add( panel );
13582
			}
13583
			if ( originalAriaControls ) {
13584
				tab.data( "ui-tabs-aria-controls", originalAriaControls );
13585
			}
13586
			tab.attr({
13587
				"aria-controls": selector.substring( 1 ),
13588
				"aria-labelledby": anchorId
13589
			});
13590
			panel.attr( "aria-labelledby", anchorId );
13591
		});
13592
 
13593
		this.panels
13594
			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13595
			.attr( "role", "tabpanel" );
13596
	},
13597
 
13598
	// allow overriding how to find the list for rare usage scenarios (#7715)
13599
	_getList: function() {
13600
		return this.element.find( "ol,ul" ).eq( 0 );
13601
	},
13602
 
13603
	_createPanel: function( id ) {
13604
		return $( "<div>" )
13605
			.attr( "id", id )
13606
			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13607
			.data( "ui-tabs-destroy", true );
13608
	},
13609
 
13610
	_setupDisabled: function( disabled ) {
13611
		if ( $.isArray( disabled ) ) {
13612
			if ( !disabled.length ) {
13613
				disabled = false;
13614
			} else if ( disabled.length === this.anchors.length ) {
13615
				disabled = true;
13616
			}
13617
		}
13618
 
13619
		// disable tabs
13620
		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
13621
			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
13622
				$( li )
13623
					.addClass( "ui-state-disabled" )
13624
					.attr( "aria-disabled", "true" );
13625
			} else {
13626
				$( li )
13627
					.removeClass( "ui-state-disabled" )
13628
					.removeAttr( "aria-disabled" );
13629
			}
13630
		}
13631
 
13632
		this.options.disabled = disabled;
13633
	},
13634
 
13635
	_setupEvents: function( event ) {
13636
		var events = {
13637
			click: function( event ) {
13638
				event.preventDefault();
13639
			}
13640
		};
13641
		if ( event ) {
13642
			$.each( event.split(" "), function( index, eventName ) {
13643
				events[ eventName ] = "_eventHandler";
13644
			});
13645
		}
13646
 
13647
		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
13648
		this._on( this.anchors, events );
13649
		this._on( this.tabs, { keydown: "_tabKeydown" } );
13650
		this._on( this.panels, { keydown: "_panelKeydown" } );
13651
 
13652
		this._focusable( this.tabs );
13653
		this._hoverable( this.tabs );
13654
	},
13655
 
13656
	_setupHeightStyle: function( heightStyle ) {
13657
		var maxHeight, overflow,
13658
			parent = this.element.parent();
13659
 
13660
		if ( heightStyle === "fill" ) {
13661
			// IE 6 treats height like minHeight, so we need to turn off overflow
13662
			// in order to get a reliable height
13663
			// we use the minHeight support test because we assume that only
13664
			// browsers that don't support minHeight will treat height as minHeight
13665
			if ( !$.support.minHeight ) {
13666
				overflow = parent.css( "overflow" );
13667
				parent.css( "overflow", "hidden");
13668
			}
13669
			maxHeight = parent.height();
13670
			this.element.siblings( ":visible" ).each(function() {
13671
				var elem = $( this ),
13672
					position = elem.css( "position" );
13673
 
13674
				if ( position === "absolute" || position === "fixed" ) {
13675
					return;
13676
				}
13677
				maxHeight -= elem.outerHeight( true );
13678
			});
13679
			if ( overflow ) {
13680
				parent.css( "overflow", overflow );
13681
			}
13682
 
13683
			this.element.children().not( this.panels ).each(function() {
13684
				maxHeight -= $( this ).outerHeight( true );
13685
			});
13686
 
13687
			this.panels.each(function() {
13688
				$( this ).height( Math.max( 0, maxHeight -
13689
					$( this ).innerHeight() + $( this ).height() ) );
13690
			})
13691
			.css( "overflow", "auto" );
13692
		} else if ( heightStyle === "auto" ) {
13693
			maxHeight = 0;
13694
			this.panels.each(function() {
13695
				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
13696
			}).height( maxHeight );
13697
		}
13698
	},
13699
 
13700
	_eventHandler: function( event ) {
13701
		var options = this.options,
13702
			active = this.active,
13703
			anchor = $( event.currentTarget ),
13704
			tab = anchor.closest( "li" ),
13705
			clickedIsActive = tab[ 0 ] === active[ 0 ],
13706
			collapsing = clickedIsActive && options.collapsible,
13707
			toShow = collapsing ? $() : this._getPanelForTab( tab ),
13708
			toHide = !active.length ? $() : this._getPanelForTab( active ),
13709
			eventData = {
13710
				oldTab: active,
13711
				oldPanel: toHide,
13712
				newTab: collapsing ? $() : tab,
13713
				newPanel: toShow
13714
			};
13715
 
13716
		event.preventDefault();
13717
 
13718
		if ( tab.hasClass( "ui-state-disabled" ) ||
13719
				// tab is already loading
13720
				tab.hasClass( "ui-tabs-loading" ) ||
13721
				// can't switch durning an animation
13722
				this.running ||
13723
				// click on active header, but not collapsible
13724
				( clickedIsActive && !options.collapsible ) ||
13725
				// allow canceling activation
13726
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
13727
			return;
13728
		}
13729
 
13730
		options.active = collapsing ? false : this.tabs.index( tab );
13731
 
13732
		this.active = clickedIsActive ? $() : tab;
13733
		if ( this.xhr ) {
13734
			this.xhr.abort();
13735
		}
13736
 
13737
		if ( !toHide.length && !toShow.length ) {
13738
			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
13739
		}
13740
 
13741
		if ( toShow.length ) {
13742
			this.load( this.tabs.index( tab ), event );
13743
		}
13744
		this._toggle( event, eventData );
13745
	},
13746
 
13747
	// handles show/hide for selecting tabs
13748
	_toggle: function( event, eventData ) {
13749
		var that = this,
13750
			toShow = eventData.newPanel,
13751
			toHide = eventData.oldPanel;
13752
 
13753
		this.running = true;
13754
 
13755
		function complete() {
13756
			that.running = false;
13757
			that._trigger( "activate", event, eventData );
13758
		}
13759
 
13760
		function show() {
13761
			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
13762
 
13763
			if ( toShow.length && that.options.show ) {
13764
				that._show( toShow, that.options.show, complete );
13765
			} else {
13766
				toShow.show();
13767
				complete();
13768
			}
13769
		}
13770
 
13771
		// start out by hiding, then showing, then completing
13772
		if ( toHide.length && this.options.hide ) {
13773
			this._hide( toHide, this.options.hide, function() {
13774
				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13775
				show();
13776
			});
13777
		} else {
13778
			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13779
			toHide.hide();
13780
			show();
13781
		}
13782
 
13783
		toHide.attr({
13784
			"aria-expanded": "false",
13785
			"aria-hidden": "true"
13786
		});
13787
		eventData.oldTab.attr( "aria-selected", "false" );
13788
		// If we're switching tabs, remove the old tab from the tab order.
13789
		// If we're opening from collapsed state, remove the previous tab from the tab order.
13790
		// If we're collapsing, then keep the collapsing tab in the tab order.
13791
		if ( toShow.length && toHide.length ) {
13792
			eventData.oldTab.attr( "tabIndex", -1 );
13793
		} else if ( toShow.length ) {
13794
			this.tabs.filter(function() {
13795
				return $( this ).attr( "tabIndex" ) === 0;
13796
			})
13797
			.attr( "tabIndex", -1 );
13798
		}
13799
 
13800
		toShow.attr({
13801
			"aria-expanded": "true",
13802
			"aria-hidden": "false"
13803
		});
13804
		eventData.newTab.attr({
13805
			"aria-selected": "true",
13806
			tabIndex: 0
13807
		});
13808
	},
13809
 
13810
	_activate: function( index ) {
13811
		var anchor,
13812
			active = this._findActive( index );
13813
 
13814
		// trying to activate the already active panel
13815
		if ( active[ 0 ] === this.active[ 0 ] ) {
13816
			return;
13817
		}
13818
 
13819
		// trying to collapse, simulate a click on the current active header
13820
		if ( !active.length ) {
13821
			active = this.active;
13822
		}
13823
 
13824
		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
13825
		this._eventHandler({
13826
			target: anchor,
13827
			currentTarget: anchor,
13828
			preventDefault: $.noop
13829
		});
13830
	},
13831
 
13832
	_findActive: function( index ) {
13833
		return index === false ? $() : this.tabs.eq( index );
13834
	},
13835
 
13836
	_getIndex: function( index ) {
13837
		// meta-function to give users option to provide a href string instead of a numerical index.
13838
		if ( typeof index === "string" ) {
13839
			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
13840
		}
13841
 
13842
		return index;
13843
	},
13844
 
13845
	_destroy: function() {
13846
		if ( this.xhr ) {
13847
			this.xhr.abort();
13848
		}
13849
 
13850
		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
13851
 
13852
		this.tablist
13853
			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13854
			.removeAttr( "role" );
13855
 
13856
		this.anchors
13857
			.removeClass( "ui-tabs-anchor" )
13858
			.removeAttr( "role" )
13859
			.removeAttr( "tabIndex" )
13860
			.removeData( "href.tabs" )
13861
			.removeData( "load.tabs" )
13862
			.removeUniqueId();
13863
 
13864
		this.tabs.add( this.panels ).each(function() {
13865
			if ( $.data( this, "ui-tabs-destroy" ) ) {
13866
				$( this ).remove();
13867
			} else {
13868
				$( this )
13869
					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
13870
						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
13871
					.removeAttr( "tabIndex" )
13872
					.removeAttr( "aria-live" )
13873
					.removeAttr( "aria-busy" )
13874
					.removeAttr( "aria-selected" )
13875
					.removeAttr( "aria-labelledby" )
13876
					.removeAttr( "aria-hidden" )
13877
					.removeAttr( "aria-expanded" )
13878
					.removeAttr( "role" );
13879
			}
13880
		});
13881
 
13882
		this.tabs.each(function() {
13883
			var li = $( this ),
13884
				prev = li.data( "ui-tabs-aria-controls" );
13885
			if ( prev ) {
13886
				li.attr( "aria-controls", prev );
13887
			} else {
13888
				li.removeAttr( "aria-controls" );
13889
			}
13890
		});
13891
 
13892
		this.panels.show();
13893
 
13894
		if ( this.options.heightStyle !== "content" ) {
13895
			this.panels.css( "height", "" );
13896
		}
13897
	},
13898
 
13899
	enable: function( index ) {
13900
		var disabled = this.options.disabled;
13901
		if ( disabled === false ) {
13902
			return;
13903
		}
13904
 
13905
		if ( index === undefined ) {
13906
			disabled = false;
13907
		} else {
13908
			index = this._getIndex( index );
13909
			if ( $.isArray( disabled ) ) {
13910
				disabled = $.map( disabled, function( num ) {
13911
					return num !== index ? num : null;
13912
				});
13913
			} else {
13914
				disabled = $.map( this.tabs, function( li, num ) {
13915
					return num !== index ? num : null;
13916
				});
13917
			}
13918
		}
13919
		this._setupDisabled( disabled );
13920
	},
13921
 
13922
	disable: function( index ) {
13923
		var disabled = this.options.disabled;
13924
		if ( disabled === true ) {
13925
			return;
13926
		}
13927
 
13928
		if ( index === undefined ) {
13929
			disabled = true;
13930
		} else {
13931
			index = this._getIndex( index );
13932
			if ( $.inArray( index, disabled ) !== -1 ) {
13933
				return;
13934
			}
13935
			if ( $.isArray( disabled ) ) {
13936
				disabled = $.merge( [ index ], disabled ).sort();
13937
			} else {
13938
				disabled = [ index ];
13939
			}
13940
		}
13941
		this._setupDisabled( disabled );
13942
	},
13943
 
13944
	load: function( index, event ) {
13945
		index = this._getIndex( index );
13946
		var that = this,
13947
			tab = this.tabs.eq( index ),
13948
			anchor = tab.find( ".ui-tabs-anchor" ),
13949
			panel = this._getPanelForTab( tab ),
13950
			eventData = {
13951
				tab: tab,
13952
				panel: panel
13953
			};
13954
 
13955
		// not remote
13956
		if ( isLocal( anchor[ 0 ] ) ) {
13957
			return;
13958
		}
13959
 
13960
		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
13961
 
13962
		// support: jQuery <1.8
13963
		// jQuery <1.8 returns false if the request is canceled in beforeSend,
13964
		// but as of 1.8, $.ajax() always returns a jqXHR object.
13965
		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
13966
			tab.addClass( "ui-tabs-loading" );
13967
			panel.attr( "aria-busy", "true" );
13968
 
13969
			this.xhr
13970
				.success(function( response ) {
13971
					// support: jQuery <1.8
13972
					// http://bugs.jquery.com/ticket/11778
13973
					setTimeout(function() {
13974
						panel.html( response );
13975
						that._trigger( "load", event, eventData );
13976
					}, 1 );
13977
				})
13978
				.complete(function( jqXHR, status ) {
13979
					// support: jQuery <1.8
13980
					// http://bugs.jquery.com/ticket/11778
13981
					setTimeout(function() {
13982
						if ( status === "abort" ) {
13983
							that.panels.stop( false, true );
13984
						}
13985
 
13986
						tab.removeClass( "ui-tabs-loading" );
13987
						panel.removeAttr( "aria-busy" );
13988
 
13989
						if ( jqXHR === that.xhr ) {
13990
							delete that.xhr;
13991
						}
13992
					}, 1 );
13993
				});
13994
		}
13995
	},
13996
 
13997
	// TODO: Remove this function in 1.10 when ajaxOptions is removed
13998
	_ajaxSettings: function( anchor, event, eventData ) {
13999
		var that = this;
14000
		return {
14001
			url: anchor.attr( "href" ),
14002
			beforeSend: function( jqXHR, settings ) {
14003
				return that._trigger( "beforeLoad", event,
14004
					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14005
			}
14006
		};
14007
	},
14008
 
14009
	_getPanelForTab: function( tab ) {
14010
		var id = $( tab ).attr( "aria-controls" );
14011
		return this.element.find( this._sanitizeSelector( "#" + id ) );
14012
	}
14013
});
14014
 
14015
// DEPRECATED
14016
if ( $.uiBackCompat !== false ) {
14017
 
14018
	// helper method for a lot of the back compat extensions
14019
	$.ui.tabs.prototype._ui = function( tab, panel ) {
14020
		return {
14021
			tab: tab,
14022
			panel: panel,
14023
			index: this.anchors.index( tab )
14024
		};
14025
	};
14026
 
14027
	// url method
14028
	$.widget( "ui.tabs", $.ui.tabs, {
14029
		url: function( index, url ) {
14030
			this.anchors.eq( index ).attr( "href", url );
14031
		}
14032
	});
14033
 
14034
	// TODO: Remove _ajaxSettings() method when removing this extension
14035
	// ajaxOptions and cache options
14036
	$.widget( "ui.tabs", $.ui.tabs, {
14037
		options: {
14038
			ajaxOptions: null,
14039
			cache: false
14040
		},
14041
 
14042
		_create: function() {
14043
			this._super();
14044
 
14045
			var that = this;
14046
 
14047
			this._on({ tabsbeforeload: function( event, ui ) {
14048
				// tab is already cached
14049
				if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
14050
					event.preventDefault();
14051
					return;
14052
				}
14053
 
14054
				ui.jqXHR.success(function() {
14055
					if ( that.options.cache ) {
14056
						$.data( ui.tab[ 0 ], "cache.tabs", true );
14057
					}
14058
				});
14059
			}});
14060
		},
14061
 
14062
		_ajaxSettings: function( anchor, event, ui ) {
14063
			var ajaxOptions = this.options.ajaxOptions;
14064
			return $.extend( {}, ajaxOptions, {
14065
				error: function( xhr, status ) {
14066
					try {
14067
						// Passing index avoid a race condition when this method is
14068
						// called after the user has selected another tab.
14069
						// Pass the anchor that initiated this request allows
14070
						// loadError to manipulate the tab content panel via $(a.hash)
14071
						ajaxOptions.error(
14072
							xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
14073
					}
14074
					catch ( error ) {}
14075
				}
14076
			}, this._superApply( arguments ) );
14077
		},
14078
 
14079
		_setOption: function( key, value ) {
14080
			// reset cache if switching from cached to not cached
14081
			if ( key === "cache" && value === false ) {
14082
				this.anchors.removeData( "cache.tabs" );
14083
			}
14084
			this._super( key, value );
14085
		},
14086
 
14087
		_destroy: function() {
14088
			this.anchors.removeData( "cache.tabs" );
14089
			this._super();
14090
		},
14091
 
14092
		url: function( index ){
14093
			this.anchors.eq( index ).removeData( "cache.tabs" );
14094
			this._superApply( arguments );
14095
		}
14096
	});
14097
 
14098
	// abort method
14099
	$.widget( "ui.tabs", $.ui.tabs, {
14100
		abort: function() {
14101
			if ( this.xhr ) {
14102
				this.xhr.abort();
14103
			}
14104
		}
14105
	});
14106
 
14107
	// spinner
14108
	$.widget( "ui.tabs", $.ui.tabs, {
14109
		options: {
14110
			spinner: "<em>Loading&#8230;</em>"
14111
		},
14112
		_create: function() {
14113
			this._super();
14114
			this._on({
14115
				tabsbeforeload: function( event, ui ) {
14116
					// Don't react to nested tabs or tabs that don't use a spinner
14117
					if ( event.target !== this.element[ 0 ] ||
14118
							!this.options.spinner ) {
14119
						return;
14120
					}
14121
 
14122
					var span = ui.tab.find( "span" ),
14123
						html = span.html();
14124
					span.html( this.options.spinner );
14125
					ui.jqXHR.complete(function() {
14126
						span.html( html );
14127
					});
14128
				}
14129
			});
14130
		}
14131
	});
14132
 
14133
	// enable/disable events
14134
	$.widget( "ui.tabs", $.ui.tabs, {
14135
		options: {
14136
			enable: null,
14137
			disable: null
14138
		},
14139
 
14140
		enable: function( index ) {
14141
			var options = this.options,
14142
				trigger;
14143
 
14144
			if ( index && options.disabled === true ||
14145
					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
14146
				trigger = true;
14147
			}
14148
 
14149
			this._superApply( arguments );
14150
 
14151
			if ( trigger ) {
14152
				this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14153
			}
14154
		},
14155
 
14156
		disable: function( index ) {
14157
			var options = this.options,
14158
				trigger;
14159
 
14160
			if ( index && options.disabled === false ||
14161
					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
14162
				trigger = true;
14163
			}
14164
 
14165
			this._superApply( arguments );
14166
 
14167
			if ( trigger ) {
14168
				this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14169
			}
14170
		}
14171
	});
14172
 
14173
	// add/remove methods and events
14174
	$.widget( "ui.tabs", $.ui.tabs, {
14175
		options: {
14176
			add: null,
14177
			remove: null,
14178
			tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
14179
		},
14180
 
14181
		add: function( url, label, index ) {
14182
			if ( index === undefined ) {
14183
				index = this.anchors.length;
14184
			}
14185
 
14186
			var doInsertAfter, panel,
14187
				options = this.options,
14188
				li = $( options.tabTemplate
14189
					.replace( /#\{href\}/g, url )
14190
					.replace( /#\{label\}/g, label ) ),
14191
				id = !url.indexOf( "#" ) ?
14192
					url.replace( "#", "" ) :
14193
					this._tabId( li );
14194
 
14195
			li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
14196
			li.attr( "aria-controls", id );
14197
 
14198
			doInsertAfter = index >= this.tabs.length;
14199
 
14200
			// try to find an existing element before creating a new one
14201
			panel = this.element.find( "#" + id );
14202
			if ( !panel.length ) {
14203
				panel = this._createPanel( id );
14204
				if ( doInsertAfter ) {
14205
					if ( index > 0 ) {
14206
						panel.insertAfter( this.panels.eq( -1 ) );
14207
					} else {
14208
						panel.appendTo( this.element );
14209
					}
14210
				} else {
14211
					panel.insertBefore( this.panels[ index ] );
14212
				}
14213
			}
14214
			panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
14215
 
14216
			if ( doInsertAfter ) {
14217
				li.appendTo( this.tablist );
14218
			} else {
14219
				li.insertBefore( this.tabs[ index ] );
14220
			}
14221
 
14222
			options.disabled = $.map( options.disabled, function( n ) {
14223
				return n >= index ? ++n : n;
14224
			});
14225
 
14226
			this.refresh();
14227
			if ( this.tabs.length === 1 && options.active === false ) {
14228
				this.option( "active", 0 );
14229
			}
14230
 
14231
			this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
14232
			return this;
14233
		},
14234
 
14235
		remove: function( index ) {
14236
			index = this._getIndex( index );
14237
			var options = this.options,
14238
				tab = this.tabs.eq( index ).remove(),
14239
				panel = this._getPanelForTab( tab ).remove();
14240
 
14241
			// If selected tab was removed focus tab to the right or
14242
			// in case the last tab was removed the tab to the left.
14243
			// We check for more than 2 tabs, because if there are only 2,
14244
			// then when we remove this tab, there will only be one tab left
14245
			// so we don't need to detect which tab to activate.
14246
			if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
14247
				this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
14248
			}
14249
 
14250
			options.disabled = $.map(
14251
				$.grep( options.disabled, function( n ) {
14252
					return n !== index;
14253
				}),
14254
				function( n ) {
14255
					return n >= index ? --n : n;
14256
				});
14257
 
14258
			this.refresh();
14259
 
14260
			this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
14261
			return this;
14262
		}
14263
	});
14264
 
14265
	// length method
14266
	$.widget( "ui.tabs", $.ui.tabs, {
14267
		length: function() {
14268
			return this.anchors.length;
14269
		}
14270
	});
14271
 
14272
	// panel ids (idPrefix option + title attribute)
14273
	$.widget( "ui.tabs", $.ui.tabs, {
14274
		options: {
14275
			idPrefix: "ui-tabs-"
14276
		},
14277
 
14278
		_tabId: function( tab ) {
14279
			var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
14280
			a = a[0];
14281
			return $( a ).closest( "li" ).attr( "aria-controls" ) ||
14282
				a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
14283
				this.options.idPrefix + getNextTabId();
14284
		}
14285
	});
14286
 
14287
	// _createPanel method
14288
	$.widget( "ui.tabs", $.ui.tabs, {
14289
		options: {
14290
			panelTemplate: "<div></div>"
14291
		},
14292
 
14293
		_createPanel: function( id ) {
14294
			return $( this.options.panelTemplate )
14295
				.attr( "id", id )
14296
				.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14297
				.data( "ui-tabs-destroy", true );
14298
		}
14299
	});
14300
 
14301
	// selected option
14302
	$.widget( "ui.tabs", $.ui.tabs, {
14303
		_create: function() {
14304
			var options = this.options;
14305
			if ( options.active === null && options.selected !== undefined ) {
14306
				options.active = options.selected === -1 ? false : options.selected;
14307
			}
14308
			this._super();
14309
			options.selected = options.active;
14310
			if ( options.selected === false ) {
14311
				options.selected = -1;
14312
			}
14313
		},
14314
 
14315
		_setOption: function( key, value ) {
14316
			if ( key !== "selected" ) {
14317
				return this._super( key, value );
14318
			}
14319
 
14320
			var options = this.options;
14321
			this._super( "active", value === -1 ? false : value );
14322
			options.selected = options.active;
14323
			if ( options.selected === false ) {
14324
				options.selected = -1;
14325
			}
14326
		},
14327
 
14328
		_eventHandler: function() {
14329
			this._superApply( arguments );
14330
			this.options.selected = this.options.active;
14331
			if ( this.options.selected === false ) {
14332
				this.options.selected = -1;
14333
			}
14334
		}
14335
	});
14336
 
14337
	// show and select event
14338
	$.widget( "ui.tabs", $.ui.tabs, {
14339
		options: {
14340
			show: null,
14341
			select: null
14342
		},
14343
		_create: function() {
14344
			this._super();
14345
			if ( this.options.active !== false ) {
14346
				this._trigger( "show", null, this._ui(
14347
					this.active.find( ".ui-tabs-anchor" )[ 0 ],
14348
					this._getPanelForTab( this.active )[ 0 ] ) );
14349
			}
14350
		},
14351
		_trigger: function( type, event, data ) {
14352
			var tab, panel,
14353
				ret = this._superApply( arguments );
14354
 
14355
			if ( !ret ) {
14356
				return false;
14357
			}
14358
 
14359
			if ( type === "beforeActivate" ) {
14360
				tab = data.newTab.length ? data.newTab : data.oldTab;
14361
				panel = data.newPanel.length ? data.newPanel : data.oldPanel;
14362
				ret = this._super( "select", event, {
14363
					tab: tab.find( ".ui-tabs-anchor" )[ 0],
14364
					panel: panel[ 0 ],
14365
					index: tab.closest( "li" ).index()
14366
				});
14367
			} else if ( type === "activate" && data.newTab.length ) {
14368
				ret = this._super( "show", event, {
14369
					tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
14370
					panel: data.newPanel[ 0 ],
14371
					index: data.newTab.closest( "li" ).index()
14372
				});
14373
			}
14374
			return ret;
14375
		}
14376
	});
14377
 
14378
	// select method
14379
	$.widget( "ui.tabs", $.ui.tabs, {
14380
		select: function( index ) {
14381
			index = this._getIndex( index );
14382
			if ( index === -1 ) {
14383
				if ( this.options.collapsible && this.options.selected !== -1 ) {
14384
					index = this.options.selected;
14385
				} else {
14386
					return;
14387
				}
14388
			}
14389
			this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
14390
		}
14391
	});
14392
 
14393
	// cookie option
14394
	(function() {
14395
 
14396
	var listId = 0;
14397
 
14398
	$.widget( "ui.tabs", $.ui.tabs, {
14399
		options: {
14400
			cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
14401
		},
14402
		_create: function() {
14403
			var options = this.options,
14404
				active;
14405
			if ( options.active == null && options.cookie ) {
14406
				active = parseInt( this._cookie(), 10 );
14407
				if ( active === -1 ) {
14408
					active = false;
14409
				}
14410
				options.active = active;
14411
			}
14412
			this._super();
14413
		},
14414
		_cookie: function( active ) {
14415
			var cookie = [ this.cookie ||
14416
				( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
14417
			if ( arguments.length ) {
14418
				cookie.push( active === false ? -1 : active );
14419
				cookie.push( this.options.cookie );
14420
			}
14421
			return $.cookie.apply( null, cookie );
14422
		},
14423
		_refresh: function() {
14424
			this._super();
14425
			if ( this.options.cookie ) {
14426
				this._cookie( this.options.active, this.options.cookie );
14427
			}
14428
		},
14429
		_eventHandler: function() {
14430
			this._superApply( arguments );
14431
			if ( this.options.cookie ) {
14432
				this._cookie( this.options.active, this.options.cookie );
14433
			}
14434
		},
14435
		_destroy: function() {
14436
			this._super();
14437
			if ( this.options.cookie ) {
14438
				this._cookie( null, this.options.cookie );
14439
			}
14440
		}
14441
	});
14442
 
14443
	})();
14444
 
14445
	// load event
14446
	$.widget( "ui.tabs", $.ui.tabs, {
14447
		_trigger: function( type, event, data ) {
14448
			var _data = $.extend( {}, data );
14449
			if ( type === "load" ) {
14450
				_data.panel = _data.panel[ 0 ];
14451
				_data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
14452
			}
14453
			return this._super( type, event, _data );
14454
		}
14455
	});
14456
 
14457
	// fx option
14458
	// The new animation options (show, hide) conflict with the old show callback.
14459
	// The old fx option wins over show/hide anyway (always favor back-compat).
14460
	// If a user wants to use the new animation API, they must give up the old API.
14461
	$.widget( "ui.tabs", $.ui.tabs, {
14462
		options: {
14463
			fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
14464
		},
14465
 
14466
		_getFx: function() {
14467
			var hide, show,
14468
				fx = this.options.fx;
14469
 
14470
			if ( fx ) {
14471
				if ( $.isArray( fx ) ) {
14472
					hide = fx[ 0 ];
14473
					show = fx[ 1 ];
14474
				} else {
14475
					hide = show = fx;
14476
				}
14477
			}
14478
 
14479
			return fx ? { show: show, hide: hide } : null;
14480
		},
14481
 
14482
		_toggle: function( event, eventData ) {
14483
			var that = this,
14484
				toShow = eventData.newPanel,
14485
				toHide = eventData.oldPanel,
14486
				fx = this._getFx();
14487
 
14488
			if ( !fx ) {
14489
				return this._super( event, eventData );
14490
			}
14491
 
14492
			that.running = true;
14493
 
14494
			function complete() {
14495
				that.running = false;
14496
				that._trigger( "activate", event, eventData );
14497
			}
14498
 
14499
			function show() {
14500
				eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14501
 
14502
				if ( toShow.length && fx.show ) {
14503
					toShow
14504
						.animate( fx.show, fx.show.duration, function() {
14505
							complete();
14506
						});
14507
				} else {
14508
					toShow.show();
14509
					complete();
14510
				}
14511
			}
14512
 
14513
			// start out by hiding, then showing, then completing
14514
			if ( toHide.length && fx.hide ) {
14515
				toHide.animate( fx.hide, fx.hide.duration, function() {
14516
					eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14517
					show();
14518
				});
14519
			} else {
14520
				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14521
				toHide.hide();
14522
				show();
14523
			}
14524
		}
14525
	});
14526
}
14527
 
14528
})( jQuery );
14529
 
14530
(function( $ ) {
14531
 
14532
var increments = 0;
14533
 
14534
function addDescribedBy( elem, id ) {
14535
	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14536
	describedby.push( id );
14537
	elem
14538
		.data( "ui-tooltip-id", id )
14539
		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14540
}
14541
 
14542
function removeDescribedBy( elem ) {
14543
	var id = elem.data( "ui-tooltip-id" ),
14544
		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14545
		index = $.inArray( id, describedby );
14546
	if ( index !== -1 ) {
14547
		describedby.splice( index, 1 );
14548
	}
14549
 
14550
	elem.removeData( "ui-tooltip-id" );
14551
	describedby = $.trim( describedby.join( " " ) );
14552
	if ( describedby ) {
14553
		elem.attr( "aria-describedby", describedby );
14554
	} else {
14555
		elem.removeAttr( "aria-describedby" );
14556
	}
14557
}
14558
 
14559
$.widget( "ui.tooltip", {
14560
	version: "1.9.2",
14561
	options: {
14562
		content: function() {
14563
			return $( this ).attr( "title" );
14564
		},
14565
		hide: true,
14566
		// Disabled elements have inconsistent behavior across browsers (#8661)
14567
		items: "[title]:not([disabled])",
14568
		position: {
14569
			my: "left top+15",
14570
			at: "left bottom",
14571
			collision: "flipfit flip"
14572
		},
14573
		show: true,
14574
		tooltipClass: null,
14575
		track: false,
14576
 
14577
		// callbacks
14578
		close: null,
14579
		open: null
14580
	},
14581
 
14582
	_create: function() {
14583
		this._on({
14584
			mouseover: "open",
14585
			focusin: "open"
14586
		});
14587
 
14588
		// IDs of generated tooltips, needed for destroy
14589
		this.tooltips = {};
14590
		// IDs of parent tooltips where we removed the title attribute
14591
		this.parents = {};
14592
 
14593
		if ( this.options.disabled ) {
14594
			this._disable();
14595
		}
14596
	},
14597
 
14598
	_setOption: function( key, value ) {
14599
		var that = this;
14600
 
14601
		if ( key === "disabled" ) {
14602
			this[ value ? "_disable" : "_enable" ]();
14603
			this.options[ key ] = value;
14604
			// disable element style changes
14605
			return;
14606
		}
14607
 
14608
		this._super( key, value );
14609
 
14610
		if ( key === "content" ) {
14611
			$.each( this.tooltips, function( id, element ) {
14612
				that._updateContent( element );
14613
			});
14614
		}
14615
	},
14616
 
14617
	_disable: function() {
14618
		var that = this;
14619
 
14620
		// close open tooltips
14621
		$.each( this.tooltips, function( id, element ) {
14622
			var event = $.Event( "blur" );
14623
			event.target = event.currentTarget = element[0];
14624
			that.close( event, true );
14625
		});
14626
 
14627
		// remove title attributes to prevent native tooltips
14628
		this.element.find( this.options.items ).andSelf().each(function() {
14629
			var element = $( this );
14630
			if ( element.is( "[title]" ) ) {
14631
				element
14632
					.data( "ui-tooltip-title", element.attr( "title" ) )
14633
					.attr( "title", "" );
14634
			}
14635
		});
14636
	},
14637
 
14638
	_enable: function() {
14639
		// restore title attributes
14640
		this.element.find( this.options.items ).andSelf().each(function() {
14641
			var element = $( this );
14642
			if ( element.data( "ui-tooltip-title" ) ) {
14643
				element.attr( "title", element.data( "ui-tooltip-title" ) );
14644
			}
14645
		});
14646
	},
14647
 
14648
	open: function( event ) {
14649
		var that = this,
14650
			target = $( event ? event.target : this.element )
14651
				// we need closest here due to mouseover bubbling,
14652
				// but always pointing at the same event target
14653
				.closest( this.options.items );
14654
 
14655
		// No element to show a tooltip for or the tooltip is already open
14656
		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14657
			return;
14658
		}
14659
 
14660
		if ( target.attr( "title" ) ) {
14661
			target.data( "ui-tooltip-title", target.attr( "title" ) );
14662
		}
14663
 
14664
		target.data( "ui-tooltip-open", true );
14665
 
14666
		// kill parent tooltips, custom or native, for hover
14667
		if ( event && event.type === "mouseover" ) {
14668
			target.parents().each(function() {
14669
				var parent = $( this ),
14670
					blurEvent;
14671
				if ( parent.data( "ui-tooltip-open" ) ) {
14672
					blurEvent = $.Event( "blur" );
14673
					blurEvent.target = blurEvent.currentTarget = this;
14674
					that.close( blurEvent, true );
14675
				}
14676
				if ( parent.attr( "title" ) ) {
14677
					parent.uniqueId();
14678
					that.parents[ this.id ] = {
14679
						element: this,
14680
						title: parent.attr( "title" )
14681
					};
14682
					parent.attr( "title", "" );
14683
				}
14684
			});
14685
		}
14686
 
14687
		this._updateContent( target, event );
14688
	},
14689
 
14690
	_updateContent: function( target, event ) {
14691
		var content,
14692
			contentOption = this.options.content,
14693
			that = this,
14694
			eventType = event ? event.type : null;
14695
 
14696
		if ( typeof contentOption === "string" ) {
14697
			return this._open( event, target, contentOption );
14698
		}
14699
 
14700
		content = contentOption.call( target[0], function( response ) {
14701
			// ignore async response if tooltip was closed already
14702
			if ( !target.data( "ui-tooltip-open" ) ) {
14703
				return;
14704
			}
14705
			// IE may instantly serve a cached response for ajax requests
14706
			// delay this call to _open so the other call to _open runs first
14707
			that._delay(function() {
14708
				// jQuery creates a special event for focusin when it doesn't
14709
				// exist natively. To improve performance, the native event
14710
				// object is reused and the type is changed. Therefore, we can't
14711
				// rely on the type being correct after the event finished
14712
				// bubbling, so we set it back to the previous value. (#8740)
14713
				if ( event ) {
14714
					event.type = eventType;
14715
				}
14716
				this._open( event, target, response );
14717
			});
14718
		});
14719
		if ( content ) {
14720
			this._open( event, target, content );
14721
		}
14722
	},
14723
 
14724
	_open: function( event, target, content ) {
14725
		var tooltip, events, delayedShow,
14726
			positionOption = $.extend( {}, this.options.position );
14727
 
14728
		if ( !content ) {
14729
			return;
14730
		}
14731
 
14732
		// Content can be updated multiple times. If the tooltip already
14733
		// exists, then just update the content and bail.
14734
		tooltip = this._find( target );
14735
		if ( tooltip.length ) {
14736
			tooltip.find( ".ui-tooltip-content" ).html( content );
14737
			return;
14738
		}
14739
 
14740
		// if we have a title, clear it to prevent the native tooltip
14741
		// we have to check first to avoid defining a title if none exists
14742
		// (we don't want to cause an element to start matching [title])
14743
		//
14744
		// We use removeAttr only for key events, to allow IE to export the correct
14745
		// accessible attributes. For mouse events, set to empty string to avoid
14746
		// native tooltip showing up (happens only when removing inside mouseover).
14747
		if ( target.is( "[title]" ) ) {
14748
			if ( event && event.type === "mouseover" ) {
14749
				target.attr( "title", "" );
14750
			} else {
14751
				target.removeAttr( "title" );
14752
			}
14753
		}
14754
 
14755
		tooltip = this._tooltip( target );
14756
		addDescribedBy( target, tooltip.attr( "id" ) );
14757
		tooltip.find( ".ui-tooltip-content" ).html( content );
14758
 
14759
		function position( event ) {
14760
			positionOption.of = event;
14761
			if ( tooltip.is( ":hidden" ) ) {
14762
				return;
14763
			}
14764
			tooltip.position( positionOption );
14765
		}
14766
		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14767
			this._on( this.document, {
14768
				mousemove: position
14769
			});
14770
			// trigger once to override element-relative positioning
14771
			position( event );
14772
		} else {
14773
			tooltip.position( $.extend({
14774
				of: target
14775
			}, this.options.position ) );
14776
		}
14777
 
14778
		tooltip.hide();
14779
 
14780
		this._show( tooltip, this.options.show );
14781
		// Handle tracking tooltips that are shown with a delay (#8644). As soon
14782
		// as the tooltip is visible, position the tooltip using the most recent
14783
		// event.
14784
		if ( this.options.show && this.options.show.delay ) {
14785
			delayedShow = setInterval(function() {
14786
				if ( tooltip.is( ":visible" ) ) {
14787
					position( positionOption.of );
14788
					clearInterval( delayedShow );
14789
				}
14790
			}, $.fx.interval );
14791
		}
14792
 
14793
		this._trigger( "open", event, { tooltip: tooltip } );
14794
 
14795
		events = {
14796
			keyup: function( event ) {
14797
				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14798
					var fakeEvent = $.Event(event);
14799
					fakeEvent.currentTarget = target[0];
14800
					this.close( fakeEvent, true );
14801
				}
14802
			},
14803
			remove: function() {
14804
				this._removeTooltip( tooltip );
14805
			}
14806
		};
14807
		if ( !event || event.type === "mouseover" ) {
14808
			events.mouseleave = "close";
14809
		}
14810
		if ( !event || event.type === "focusin" ) {
14811
			events.focusout = "close";
14812
		}
14813
		this._on( true, target, events );
14814
	},
14815
 
14816
	close: function( event ) {
14817
		var that = this,
14818
			target = $( event ? event.currentTarget : this.element ),
14819
			tooltip = this._find( target );
14820
 
14821
		// disabling closes the tooltip, so we need to track when we're closing
14822
		// to avoid an infinite loop in case the tooltip becomes disabled on close
14823
		if ( this.closing ) {
14824
			return;
14825
		}
14826
 
14827
		// only set title if we had one before (see comment in _open())
14828
		if ( target.data( "ui-tooltip-title" ) ) {
14829
			target.attr( "title", target.data( "ui-tooltip-title" ) );
14830
		}
14831
 
14832
		removeDescribedBy( target );
14833
 
14834
		tooltip.stop( true );
14835
		this._hide( tooltip, this.options.hide, function() {
14836
			that._removeTooltip( $( this ) );
14837
		});
14838
 
14839
		target.removeData( "ui-tooltip-open" );
14840
		this._off( target, "mouseleave focusout keyup" );
14841
		// Remove 'remove' binding only on delegated targets
14842
		if ( target[0] !== this.element[0] ) {
14843
			this._off( target, "remove" );
14844
		}
14845
		this._off( this.document, "mousemove" );
14846
 
14847
		if ( event && event.type === "mouseleave" ) {
14848
			$.each( this.parents, function( id, parent ) {
14849
				$( parent.element ).attr( "title", parent.title );
14850
				delete that.parents[ id ];
14851
			});
14852
		}
14853
 
14854
		this.closing = true;
14855
		this._trigger( "close", event, { tooltip: tooltip } );
14856
		this.closing = false;
14857
	},
14858
 
14859
	_tooltip: function( element ) {
14860
		var id = "ui-tooltip-" + increments++,
14861
			tooltip = $( "<div>" )
14862
				.attr({
14863
					id: id,
14864
					role: "tooltip"
14865
				})
14866
				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14867
					( this.options.tooltipClass || "" ) );
14868
		$( "<div>" )
14869
			.addClass( "ui-tooltip-content" )
14870
			.appendTo( tooltip );
14871
		tooltip.appendTo( this.document[0].body );
14872
		if ( $.fn.bgiframe ) {
14873
			tooltip.bgiframe();
14874
		}
14875
		this.tooltips[ id ] = element;
14876
		return tooltip;
14877
	},
14878
 
14879
	_find: function( target ) {
14880
		var id = target.data( "ui-tooltip-id" );
14881
		return id ? $( "#" + id ) : $();
14882
	},
14883
 
14884
	_removeTooltip: function( tooltip ) {
14885
		tooltip.remove();
14886
		delete this.tooltips[ tooltip.attr( "id" ) ];
14887
	},
14888
 
14889
	_destroy: function() {
14890
		var that = this;
14891
 
14892
		// close open tooltips
14893
		$.each( this.tooltips, function( id, element ) {
14894
			// Delegate to close method to handle common cleanup
14895
			var event = $.Event( "blur" );
14896
			event.target = event.currentTarget = element[0];
14897
			that.close( event, true );
14898
 
14899
			// Remove immediately; destroying an open tooltip doesn't use the
14900
			// hide animation
14901
			$( "#" + id ).remove();
14902
 
14903
			// Restore the title
14904
			if ( element.data( "ui-tooltip-title" ) ) {
14905
				element.attr( "title", element.data( "ui-tooltip-title" ) );
14906
				element.removeData( "ui-tooltip-title" );
14907
			}
14908
		});
14909
	}
14910
});
14911
 
14912
}( jQuery ) );