Subversion-Projekte lars-tiefland.cienc

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
9 lars 1
/*! jQuery UI - v1.9.2 - 2016-02-05
2
* http://jqueryui.com
3
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.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
4
* Copyright 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
(function( $, undefined ) {
353
 
354
var uuid = 0,
355
	slice = Array.prototype.slice,
356
	_cleanData = $.cleanData;
357
$.cleanData = function( elems ) {
358
	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
359
		try {
360
			$( elem ).triggerHandler( "remove" );
361
		// http://bugs.jquery.com/ticket/8235
362
		} catch( e ) {}
363
	}
364
	_cleanData( elems );
365
};
366
 
367
$.widget = function( name, base, prototype ) {
368
	var fullName, existingConstructor, constructor, basePrototype,
369
		namespace = name.split( "." )[ 0 ];
370
 
371
	name = name.split( "." )[ 1 ];
372
	fullName = namespace + "-" + name;
373
 
374
	if ( !prototype ) {
375
		prototype = base;
376
		base = $.Widget;
377
	}
378
 
379
	// create selector for plugin
380
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
381
		return !!$.data( elem, fullName );
382
	};
383
 
384
	$[ namespace ] = $[ namespace ] || {};
385
	existingConstructor = $[ namespace ][ name ];
386
	constructor = $[ namespace ][ name ] = function( options, element ) {
387
		// allow instantiation without "new" keyword
388
		if ( !this._createWidget ) {
389
			return new constructor( options, element );
390
		}
391
 
392
		// allow instantiation without initializing for simple inheritance
393
		// must use "new" keyword (the code above always passes args)
394
		if ( arguments.length ) {
395
			this._createWidget( options, element );
396
		}
397
	};
398
	// extend with the existing constructor to carry over any static properties
399
	$.extend( constructor, existingConstructor, {
400
		version: prototype.version,
401
		// copy the object used to create the prototype in case we need to
402
		// redefine the widget later
403
		_proto: $.extend( {}, prototype ),
404
		// track widgets that inherit from this widget in case this widget is
405
		// redefined after a widget inherits from it
406
		_childConstructors: []
407
	});
408
 
409
	basePrototype = new base();
410
	// we need to make the options hash a property directly on the new instance
411
	// otherwise we'll modify the options hash on the prototype that we're
412
	// inheriting from
413
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
414
	$.each( prototype, function( prop, value ) {
415
		if ( $.isFunction( value ) ) {
416
			prototype[ prop ] = (function() {
417
				var _super = function() {
418
						return base.prototype[ prop ].apply( this, arguments );
419
					},
420
					_superApply = function( args ) {
421
						return base.prototype[ prop ].apply( this, args );
422
					};
423
				return function() {
424
					var __super = this._super,
425
						__superApply = this._superApply,
426
						returnValue;
427
 
428
					this._super = _super;
429
					this._superApply = _superApply;
430
 
431
					returnValue = value.apply( this, arguments );
432
 
433
					this._super = __super;
434
					this._superApply = __superApply;
435
 
436
					return returnValue;
437
				};
438
			})();
439
		}
440
	});
441
	constructor.prototype = $.widget.extend( basePrototype, {
442
		// TODO: remove support for widgetEventPrefix
443
		// always use the name + a colon as the prefix, e.g., draggable:start
444
		// don't prefix for widgets that aren't DOM-based
445
		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
446
	}, prototype, {
447
		constructor: constructor,
448
		namespace: namespace,
449
		widgetName: name,
450
		// TODO remove widgetBaseClass, see #8155
451
		widgetBaseClass: fullName,
452
		widgetFullName: fullName
453
	});
454
 
455
	// If this widget is being redefined then we need to find all widgets that
456
	// are inheriting from it and redefine all of them so that they inherit from
457
	// the new version of this widget. We're essentially trying to replace one
458
	// level in the prototype chain.
459
	if ( existingConstructor ) {
460
		$.each( existingConstructor._childConstructors, function( i, child ) {
461
			var childPrototype = child.prototype;
462
 
463
			// redefine the child widget using the same prototype that was
464
			// originally used, but inherit from the new version of the base
465
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
466
		});
467
		// remove the list of existing child constructors from the old constructor
468
		// so the old child constructors can be garbage collected
469
		delete existingConstructor._childConstructors;
470
	} else {
471
		base._childConstructors.push( constructor );
472
	}
473
 
474
	$.widget.bridge( name, constructor );
475
};
476
 
477
$.widget.extend = function( target ) {
478
	var input = slice.call( arguments, 1 ),
479
		inputIndex = 0,
480
		inputLength = input.length,
481
		key,
482
		value;
483
	for ( ; inputIndex < inputLength; inputIndex++ ) {
484
		for ( key in input[ inputIndex ] ) {
485
			value = input[ inputIndex ][ key ];
486
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
487
				// Clone objects
488
				if ( $.isPlainObject( value ) ) {
489
					target[ key ] = $.isPlainObject( target[ key ] ) ?
490
						$.widget.extend( {}, target[ key ], value ) :
491
						// Don't extend strings, arrays, etc. with objects
492
						$.widget.extend( {}, value );
493
				// Copy everything else by reference
494
				} else {
495
					target[ key ] = value;
496
				}
497
			}
498
		}
499
	}
500
	return target;
501
};
502
 
503
$.widget.bridge = function( name, object ) {
504
	var fullName = object.prototype.widgetFullName || name;
505
	$.fn[ name ] = function( options ) {
506
		var isMethodCall = typeof options === "string",
507
			args = slice.call( arguments, 1 ),
508
			returnValue = this;
509
 
510
		// allow multiple hashes to be passed on init
511
		options = !isMethodCall && args.length ?
512
			$.widget.extend.apply( null, [ options ].concat(args) ) :
513
			options;
514
 
515
		if ( isMethodCall ) {
516
			this.each(function() {
517
				var methodValue,
518
					instance = $.data( this, fullName );
519
				if ( !instance ) {
520
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
521
						"attempted to call method '" + options + "'" );
522
				}
523
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
524
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
525
				}
526
				methodValue = instance[ options ].apply( instance, args );
527
				if ( methodValue !== instance && methodValue !== undefined ) {
528
					returnValue = methodValue && methodValue.jquery ?
529
						returnValue.pushStack( methodValue.get() ) :
530
						methodValue;
531
					return false;
532
				}
533
			});
534
		} else {
535
			this.each(function() {
536
				var instance = $.data( this, fullName );
537
				if ( instance ) {
538
					instance.option( options || {} )._init();
539
				} else {
540
					$.data( this, fullName, new object( options, this ) );
541
				}
542
			});
543
		}
544
 
545
		return returnValue;
546
	};
547
};
548
 
549
$.Widget = function( /* options, element */ ) {};
550
$.Widget._childConstructors = [];
551
 
552
$.Widget.prototype = {
553
	widgetName: "widget",
554
	widgetEventPrefix: "",
555
	defaultElement: "<div>",
556
	options: {
557
		disabled: false,
558
 
559
		// callbacks
560
		create: null
561
	},
562
	_createWidget: function( options, element ) {
563
		element = $( element || this.defaultElement || this )[ 0 ];
564
		this.element = $( element );
565
		this.uuid = uuid++;
566
		this.eventNamespace = "." + this.widgetName + this.uuid;
567
		this.options = $.widget.extend( {},
568
			this.options,
569
			this._getCreateOptions(),
570
			options );
571
 
572
		this.bindings = $();
573
		this.hoverable = $();
574
		this.focusable = $();
575
 
576
		if ( element !== this ) {
577
			// 1.9 BC for #7810
578
			// TODO remove dual storage
579
			$.data( element, this.widgetName, this );
580
			$.data( element, this.widgetFullName, this );
581
			this._on( true, this.element, {
582
				remove: function( event ) {
583
					if ( event.target === element ) {
584
						this.destroy();
585
					}
586
				}
587
			});
588
			this.document = $( element.style ?
589
				// element within the document
590
				element.ownerDocument :
591
				// element is window or document
592
				element.document || element );
593
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
594
		}
595
 
596
		this._create();
597
		this._trigger( "create", null, this._getCreateEventData() );
598
		this._init();
599
	},
600
	_getCreateOptions: $.noop,
601
	_getCreateEventData: $.noop,
602
	_create: $.noop,
603
	_init: $.noop,
604
 
605
	destroy: function() {
606
		this._destroy();
607
		// we can probably remove the unbind calls in 2.0
608
		// all event bindings should go through this._on()
609
		this.element
610
			.unbind( this.eventNamespace )
611
			// 1.9 BC for #7810
612
			// TODO remove dual storage
613
			.removeData( this.widgetName )
614
			.removeData( this.widgetFullName )
615
			// support: jquery <1.6.3
616
			// http://bugs.jquery.com/ticket/9413
617
			.removeData( $.camelCase( this.widgetFullName ) );
618
		this.widget()
619
			.unbind( this.eventNamespace )
620
			.removeAttr( "aria-disabled" )
621
			.removeClass(
622
				this.widgetFullName + "-disabled " +
623
				"ui-state-disabled" );
624
 
625
		// clean up events and states
626
		this.bindings.unbind( this.eventNamespace );
627
		this.hoverable.removeClass( "ui-state-hover" );
628
		this.focusable.removeClass( "ui-state-focus" );
629
	},
630
	_destroy: $.noop,
631
 
632
	widget: function() {
633
		return this.element;
634
	},
635
 
636
	option: function( key, value ) {
637
		var options = key,
638
			parts,
639
			curOption,
640
			i;
641
 
642
		if ( arguments.length === 0 ) {
643
			// don't return a reference to the internal hash
644
			return $.widget.extend( {}, this.options );
645
		}
646
 
647
		if ( typeof key === "string" ) {
648
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
649
			options = {};
650
			parts = key.split( "." );
651
			key = parts.shift();
652
			if ( parts.length ) {
653
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
654
				for ( i = 0; i < parts.length - 1; i++ ) {
655
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
656
					curOption = curOption[ parts[ i ] ];
657
				}
658
				key = parts.pop();
659
				if ( value === undefined ) {
660
					return curOption[ key ] === undefined ? null : curOption[ key ];
661
				}
662
				curOption[ key ] = value;
663
			} else {
664
				if ( value === undefined ) {
665
					return this.options[ key ] === undefined ? null : this.options[ key ];
666
				}
667
				options[ key ] = value;
668
			}
669
		}
670
 
671
		this._setOptions( options );
672
 
673
		return this;
674
	},
675
	_setOptions: function( options ) {
676
		var key;
677
 
678
		for ( key in options ) {
679
			this._setOption( key, options[ key ] );
680
		}
681
 
682
		return this;
683
	},
684
	_setOption: function( key, value ) {
685
		this.options[ key ] = value;
686
 
687
		if ( key === "disabled" ) {
688
			this.widget()
689
				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
690
				.attr( "aria-disabled", value );
691
			this.hoverable.removeClass( "ui-state-hover" );
692
			this.focusable.removeClass( "ui-state-focus" );
693
		}
694
 
695
		return this;
696
	},
697
 
698
	enable: function() {
699
		return this._setOption( "disabled", false );
700
	},
701
	disable: function() {
702
		return this._setOption( "disabled", true );
703
	},
704
 
705
	_on: function( suppressDisabledCheck, element, handlers ) {
706
		var delegateElement,
707
			instance = this;
708
 
709
		// no suppressDisabledCheck flag, shuffle arguments
710
		if ( typeof suppressDisabledCheck !== "boolean" ) {
711
			handlers = element;
712
			element = suppressDisabledCheck;
713
			suppressDisabledCheck = false;
714
		}
715
 
716
		// no element argument, shuffle and use this.element
717
		if ( !handlers ) {
718
			handlers = element;
719
			element = this.element;
720
			delegateElement = this.widget();
721
		} else {
722
			// accept selectors, DOM elements
723
			element = delegateElement = $( element );
724
			this.bindings = this.bindings.add( element );
725
		}
726
 
727
		$.each( handlers, function( event, handler ) {
728
			function handlerProxy() {
729
				// allow widgets to customize the disabled handling
730
				// - disabled as an array instead of boolean
731
				// - disabled class as method for disabling individual parts
732
				if ( !suppressDisabledCheck &&
733
						( instance.options.disabled === true ||
734
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
735
					return;
736
				}
737
				return ( typeof handler === "string" ? instance[ handler ] : handler )
738
					.apply( instance, arguments );
739
			}
740
 
741
			// copy the guid so direct unbinding works
742
			if ( typeof handler !== "string" ) {
743
				handlerProxy.guid = handler.guid =
744
					handler.guid || handlerProxy.guid || $.guid++;
745
			}
746
 
747
			var match = event.match( /^(\w+)\s*(.*)$/ ),
748
				eventName = match[1] + instance.eventNamespace,
749
				selector = match[2];
750
			if ( selector ) {
751
				delegateElement.delegate( selector, eventName, handlerProxy );
752
			} else {
753
				element.bind( eventName, handlerProxy );
754
			}
755
		});
756
	},
757
 
758
	_off: function( element, eventName ) {
759
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
760
		element.unbind( eventName ).undelegate( eventName );
761
	},
762
 
763
	_delay: function( handler, delay ) {
764
		function handlerProxy() {
765
			return ( typeof handler === "string" ? instance[ handler ] : handler )
766
				.apply( instance, arguments );
767
		}
768
		var instance = this;
769
		return setTimeout( handlerProxy, delay || 0 );
770
	},
771
 
772
	_hoverable: function( element ) {
773
		this.hoverable = this.hoverable.add( element );
774
		this._on( element, {
775
			mouseenter: function( event ) {
776
				$( event.currentTarget ).addClass( "ui-state-hover" );
777
			},
778
			mouseleave: function( event ) {
779
				$( event.currentTarget ).removeClass( "ui-state-hover" );
780
			}
781
		});
782
	},
783
 
784
	_focusable: function( element ) {
785
		this.focusable = this.focusable.add( element );
786
		this._on( element, {
787
			focusin: function( event ) {
788
				$( event.currentTarget ).addClass( "ui-state-focus" );
789
			},
790
			focusout: function( event ) {
791
				$( event.currentTarget ).removeClass( "ui-state-focus" );
792
			}
793
		});
794
	},
795
 
796
	_trigger: function( type, event, data ) {
797
		var prop, orig,
798
			callback = this.options[ type ];
799
 
800
		data = data || {};
801
		event = $.Event( event );
802
		event.type = ( type === this.widgetEventPrefix ?
803
			type :
804
			this.widgetEventPrefix + type ).toLowerCase();
805
		// the original event may come from any element
806
		// so we need to reset the target on the new event
807
		event.target = this.element[ 0 ];
808
 
809
		// copy original event properties over to the new event
810
		orig = event.originalEvent;
811
		if ( orig ) {
812
			for ( prop in orig ) {
813
				if ( !( prop in event ) ) {
814
					event[ prop ] = orig[ prop ];
815
				}
816
			}
817
		}
818
 
819
		this.element.trigger( event, data );
820
		return !( $.isFunction( callback ) &&
821
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
822
			event.isDefaultPrevented() );
823
	}
824
};
825
 
826
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
827
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
828
		if ( typeof options === "string" ) {
829
			options = { effect: options };
830
		}
831
		var hasOptions,
832
			effectName = !options ?
833
				method :
834
				options === true || typeof options === "number" ?
835
					defaultEffect :
836
					options.effect || defaultEffect;
837
		options = options || {};
838
		if ( typeof options === "number" ) {
839
			options = { duration: options };
840
		}
841
		hasOptions = !$.isEmptyObject( options );
842
		options.complete = callback;
843
		if ( options.delay ) {
844
			element.delay( options.delay );
845
		}
846
		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
847
			element[ method ]( options );
848
		} else if ( effectName !== method && element[ effectName ] ) {
849
			element[ effectName ]( options.duration, options.easing, callback );
850
		} else {
851
			element.queue(function( next ) {
852
				$( this )[ method ]();
853
				if ( callback ) {
854
					callback.call( element[ 0 ] );
855
				}
856
				next();
857
			});
858
		}
859
	};
860
});
861
 
862
// DEPRECATED
863
if ( $.uiBackCompat !== false ) {
864
	$.Widget.prototype._getCreateOptions = function() {
865
		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
866
	};
867
}
868
 
869
})( jQuery );
870
(function( $, undefined ) {
871
 
872
var mouseHandled = false;
873
$( document ).mouseup( function( e ) {
874
	mouseHandled = false;
875
});
876
 
877
$.widget("ui.mouse", {
878
	version: "1.9.2",
879
	options: {
880
		cancel: 'input,textarea,button,select,option',
881
		distance: 1,
882
		delay: 0
883
	},
884
	_mouseInit: function() {
885
		var that = this;
886
 
887
		this.element
888
			.bind('mousedown.'+this.widgetName, function(event) {
889
				return that._mouseDown(event);
890
			})
891
			.bind('click.'+this.widgetName, function(event) {
892
				if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
893
					$.removeData(event.target, that.widgetName + '.preventClickEvent');
894
					event.stopImmediatePropagation();
895
					return false;
896
				}
897
			});
898
 
899
		this.started = false;
900
	},
901
 
902
	// TODO: make sure destroying one instance of mouse doesn't mess with
903
	// other instances of mouse
904
	_mouseDestroy: function() {
905
		this.element.unbind('.'+this.widgetName);
906
		if ( this._mouseMoveDelegate ) {
907
			$(document)
908
				.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
909
				.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
910
		}
911
	},
912
 
913
	_mouseDown: function(event) {
914
		// don't let more than one widget handle mouseStart
915
		if( mouseHandled ) { return; }
916
 
917
		// we may have missed mouseup (out of window)
918
		(this._mouseStarted && this._mouseUp(event));
919
 
920
		this._mouseDownEvent = event;
921
 
922
		var that = this,
923
			btnIsLeft = (event.which === 1),
924
			// event.target.nodeName works around a bug in IE 8 with
925
			// disabled inputs (#7620)
926
			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
927
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
928
			return true;
929
		}
930
 
931
		this.mouseDelayMet = !this.options.delay;
932
		if (!this.mouseDelayMet) {
933
			this._mouseDelayTimer = setTimeout(function() {
934
				that.mouseDelayMet = true;
935
			}, this.options.delay);
936
		}
937
 
938
		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
939
			this._mouseStarted = (this._mouseStart(event) !== false);
940
			if (!this._mouseStarted) {
941
				event.preventDefault();
942
				return true;
943
			}
944
		}
945
 
946
		// Click event may never have fired (Gecko & Opera)
947
		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
948
			$.removeData(event.target, this.widgetName + '.preventClickEvent');
949
		}
950
 
951
		// these delegates are required to keep context
952
		this._mouseMoveDelegate = function(event) {
953
			return that._mouseMove(event);
954
		};
955
		this._mouseUpDelegate = function(event) {
956
			return that._mouseUp(event);
957
		};
958
		$(document)
959
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
960
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
961
 
962
		event.preventDefault();
963
 
964
		mouseHandled = true;
965
		return true;
966
	},
967
 
968
	_mouseMove: function(event) {
969
		// IE mouseup check - mouseup happened when mouse was out of window
970
		if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
971
			return this._mouseUp(event);
972
		}
973
 
974
		if (this._mouseStarted) {
975
			this._mouseDrag(event);
976
			return event.preventDefault();
977
		}
978
 
979
		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
980
			this._mouseStarted =
981
				(this._mouseStart(this._mouseDownEvent, event) !== false);
982
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
983
		}
984
 
985
		return !this._mouseStarted;
986
	},
987
 
988
	_mouseUp: function(event) {
989
		$(document)
990
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
991
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
992
 
993
		if (this._mouseStarted) {
994
			this._mouseStarted = false;
995
 
996
			if (event.target === this._mouseDownEvent.target) {
997
				$.data(event.target, this.widgetName + '.preventClickEvent', true);
998
			}
999
 
1000
			this._mouseStop(event);
1001
		}
1002
 
1003
		return false;
1004
	},
1005
 
1006
	_mouseDistanceMet: function(event) {
1007
		return (Math.max(
1008
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
1009
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
1010
			) >= this.options.distance
1011
		);
1012
	},
1013
 
1014
	_mouseDelayMet: function(event) {
1015
		return this.mouseDelayMet;
1016
	},
1017
 
1018
	// These are placeholder methods, to be overriden by extending plugin
1019
	_mouseStart: function(event) {},
1020
	_mouseDrag: function(event) {},
1021
	_mouseStop: function(event) {},
1022
	_mouseCapture: function(event) { return true; }
1023
});
1024
 
1025
})(jQuery);
1026
(function( $, undefined ) {
1027
 
1028
$.ui = $.ui || {};
1029
 
1030
var cachedScrollbarWidth,
1031
	max = Math.max,
1032
	abs = Math.abs,
1033
	round = Math.round,
1034
	rhorizontal = /left|center|right/,
1035
	rvertical = /top|center|bottom/,
1036
	roffset = /[\+\-]\d+%?/,
1037
	rposition = /^\w+/,
1038
	rpercent = /%$/,
1039
	_position = $.fn.position;
1040
 
1041
function getOffsets( offsets, width, height ) {
1042
	return [
1043
		parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1044
		parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1045
	];
1046
}
1047
function parseCss( element, property ) {
1048
	return parseInt( $.css( element, property ), 10 ) || 0;
1049
}
1050
 
1051
$.position = {
1052
	scrollbarWidth: function() {
1053
		if ( cachedScrollbarWidth !== undefined ) {
1054
			return cachedScrollbarWidth;
1055
		}
1056
		var w1, w2,
1057
			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1058
			innerDiv = div.children()[0];
1059
 
1060
		$( "body" ).append( div );
1061
		w1 = innerDiv.offsetWidth;
1062
		div.css( "overflow", "scroll" );
1063
 
1064
		w2 = innerDiv.offsetWidth;
1065
 
1066
		if ( w1 === w2 ) {
1067
			w2 = div[0].clientWidth;
1068
		}
1069
 
1070
		div.remove();
1071
 
1072
		return (cachedScrollbarWidth = w1 - w2);
1073
	},
1074
	getScrollInfo: function( within ) {
1075
		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
1076
			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
1077
			hasOverflowX = overflowX === "scroll" ||
1078
				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1079
			hasOverflowY = overflowY === "scroll" ||
1080
				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1081
		return {
1082
			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
1083
			height: hasOverflowY ? $.position.scrollbarWidth() : 0
1084
		};
1085
	},
1086
	getWithinInfo: function( element ) {
1087
		var withinElement = $( element || window ),
1088
			isWindow = $.isWindow( withinElement[0] );
1089
		return {
1090
			element: withinElement,
1091
			isWindow: isWindow,
1092
			offset: withinElement.offset() || { left: 0, top: 0 },
1093
			scrollLeft: withinElement.scrollLeft(),
1094
			scrollTop: withinElement.scrollTop(),
1095
			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1096
			height: isWindow ? withinElement.height() : withinElement.outerHeight()
1097
		};
1098
	}
1099
};
1100
 
1101
$.fn.position = function( options ) {
1102
	if ( !options || !options.of ) {
1103
		return _position.apply( this, arguments );
1104
	}
1105
 
1106
	// make a copy, we don't want to modify arguments
1107
	options = $.extend( {}, options );
1108
 
1109
	var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
1110
		target = $( options.of ),
1111
		within = $.position.getWithinInfo( options.within ),
1112
		scrollInfo = $.position.getScrollInfo( within ),
1113
		targetElem = target[0],
1114
		collision = ( options.collision || "flip" ).split( " " ),
1115
		offsets = {};
1116
 
1117
	if ( targetElem.nodeType === 9 ) {
1118
		targetWidth = target.width();
1119
		targetHeight = target.height();
1120
		targetOffset = { top: 0, left: 0 };
1121
	} else if ( $.isWindow( targetElem ) ) {
1122
		targetWidth = target.width();
1123
		targetHeight = target.height();
1124
		targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
1125
	} else if ( targetElem.preventDefault ) {
1126
		// force left top to allow flipping
1127
		options.at = "left top";
1128
		targetWidth = targetHeight = 0;
1129
		targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
1130
	} else {
1131
		targetWidth = target.outerWidth();
1132
		targetHeight = target.outerHeight();
1133
		targetOffset = target.offset();
1134
	}
1135
	// clone to reuse original targetOffset later
1136
	basePosition = $.extend( {}, targetOffset );
1137
 
1138
	// force my and at to have valid horizontal and vertical positions
1139
	// if a value is missing or invalid, it will be converted to center
1140
	$.each( [ "my", "at" ], function() {
1141
		var pos = ( options[ this ] || "" ).split( " " ),
1142
			horizontalOffset,
1143
			verticalOffset;
1144
 
1145
		if ( pos.length === 1) {
1146
			pos = rhorizontal.test( pos[ 0 ] ) ?
1147
				pos.concat( [ "center" ] ) :
1148
				rvertical.test( pos[ 0 ] ) ?
1149
					[ "center" ].concat( pos ) :
1150
					[ "center", "center" ];
1151
		}
1152
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1153
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1154
 
1155
		// calculate offsets
1156
		horizontalOffset = roffset.exec( pos[ 0 ] );
1157
		verticalOffset = roffset.exec( pos[ 1 ] );
1158
		offsets[ this ] = [
1159
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
1160
			verticalOffset ? verticalOffset[ 0 ] : 0
1161
		];
1162
 
1163
		// reduce to just the positions without the offsets
1164
		options[ this ] = [
1165
			rposition.exec( pos[ 0 ] )[ 0 ],
1166
			rposition.exec( pos[ 1 ] )[ 0 ]
1167
		];
1168
	});
1169
 
1170
	// normalize collision option
1171
	if ( collision.length === 1 ) {
1172
		collision[ 1 ] = collision[ 0 ];
1173
	}
1174
 
1175
	if ( options.at[ 0 ] === "right" ) {
1176
		basePosition.left += targetWidth;
1177
	} else if ( options.at[ 0 ] === "center" ) {
1178
		basePosition.left += targetWidth / 2;
1179
	}
1180
 
1181
	if ( options.at[ 1 ] === "bottom" ) {
1182
		basePosition.top += targetHeight;
1183
	} else if ( options.at[ 1 ] === "center" ) {
1184
		basePosition.top += targetHeight / 2;
1185
	}
1186
 
1187
	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1188
	basePosition.left += atOffset[ 0 ];
1189
	basePosition.top += atOffset[ 1 ];
1190
 
1191
	return this.each(function() {
1192
		var collisionPosition, using,
1193
			elem = $( this ),
1194
			elemWidth = elem.outerWidth(),
1195
			elemHeight = elem.outerHeight(),
1196
			marginLeft = parseCss( this, "marginLeft" ),
1197
			marginTop = parseCss( this, "marginTop" ),
1198
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1199
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1200
			position = $.extend( {}, basePosition ),
1201
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1202
 
1203
		if ( options.my[ 0 ] === "right" ) {
1204
			position.left -= elemWidth;
1205
		} else if ( options.my[ 0 ] === "center" ) {
1206
			position.left -= elemWidth / 2;
1207
		}
1208
 
1209
		if ( options.my[ 1 ] === "bottom" ) {
1210
			position.top -= elemHeight;
1211
		} else if ( options.my[ 1 ] === "center" ) {
1212
			position.top -= elemHeight / 2;
1213
		}
1214
 
1215
		position.left += myOffset[ 0 ];
1216
		position.top += myOffset[ 1 ];
1217
 
1218
		// if the browser doesn't support fractions, then round for consistent results
1219
		if ( !$.support.offsetFractions ) {
1220
			position.left = round( position.left );
1221
			position.top = round( position.top );
1222
		}
1223
 
1224
		collisionPosition = {
1225
			marginLeft: marginLeft,
1226
			marginTop: marginTop
1227
		};
1228
 
1229
		$.each( [ "left", "top" ], function( i, dir ) {
1230
			if ( $.ui.position[ collision[ i ] ] ) {
1231
				$.ui.position[ collision[ i ] ][ dir ]( position, {
1232
					targetWidth: targetWidth,
1233
					targetHeight: targetHeight,
1234
					elemWidth: elemWidth,
1235
					elemHeight: elemHeight,
1236
					collisionPosition: collisionPosition,
1237
					collisionWidth: collisionWidth,
1238
					collisionHeight: collisionHeight,
1239
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1240
					my: options.my,
1241
					at: options.at,
1242
					within: within,
1243
					elem : elem
1244
				});
1245
			}
1246
		});
1247
 
1248
		if ( $.fn.bgiframe ) {
1249
			elem.bgiframe();
1250
		}
1251
 
1252
		if ( options.using ) {
1253
			// adds feedback as second argument to using callback, if present
1254
			using = function( props ) {
1255
				var left = targetOffset.left - position.left,
1256
					right = left + targetWidth - elemWidth,
1257
					top = targetOffset.top - position.top,
1258
					bottom = top + targetHeight - elemHeight,
1259
					feedback = {
1260
						target: {
1261
							element: target,
1262
							left: targetOffset.left,
1263
							top: targetOffset.top,
1264
							width: targetWidth,
1265
							height: targetHeight
1266
						},
1267
						element: {
1268
							element: elem,
1269
							left: position.left,
1270
							top: position.top,
1271
							width: elemWidth,
1272
							height: elemHeight
1273
						},
1274
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1275
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1276
					};
1277
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1278
					feedback.horizontal = "center";
1279
				}
1280
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1281
					feedback.vertical = "middle";
1282
				}
1283
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1284
					feedback.important = "horizontal";
1285
				} else {
1286
					feedback.important = "vertical";
1287
				}
1288
				options.using.call( this, props, feedback );
1289
			};
1290
		}
1291
 
1292
		elem.offset( $.extend( position, { using: using } ) );
1293
	});
1294
};
1295
 
1296
$.ui.position = {
1297
	fit: {
1298
		left: function( position, data ) {
1299
			var within = data.within,
1300
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1301
				outerWidth = within.width,
1302
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1303
				overLeft = withinOffset - collisionPosLeft,
1304
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1305
				newOverRight;
1306
 
1307
			// element is wider than within
1308
			if ( data.collisionWidth > outerWidth ) {
1309
				// element is initially over the left side of within
1310
				if ( overLeft > 0 && overRight <= 0 ) {
1311
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1312
					position.left += overLeft - newOverRight;
1313
				// element is initially over right side of within
1314
				} else if ( overRight > 0 && overLeft <= 0 ) {
1315
					position.left = withinOffset;
1316
				// element is initially over both left and right sides of within
1317
				} else {
1318
					if ( overLeft > overRight ) {
1319
						position.left = withinOffset + outerWidth - data.collisionWidth;
1320
					} else {
1321
						position.left = withinOffset;
1322
					}
1323
				}
1324
			// too far left -> align with left edge
1325
			} else if ( overLeft > 0 ) {
1326
				position.left += overLeft;
1327
			// too far right -> align with right edge
1328
			} else if ( overRight > 0 ) {
1329
				position.left -= overRight;
1330
			// adjust based on position and margin
1331
			} else {
1332
				position.left = max( position.left - collisionPosLeft, position.left );
1333
			}
1334
		},
1335
		top: function( position, data ) {
1336
			var within = data.within,
1337
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1338
				outerHeight = data.within.height,
1339
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1340
				overTop = withinOffset - collisionPosTop,
1341
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1342
				newOverBottom;
1343
 
1344
			// element is taller than within
1345
			if ( data.collisionHeight > outerHeight ) {
1346
				// element is initially over the top of within
1347
				if ( overTop > 0 && overBottom <= 0 ) {
1348
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1349
					position.top += overTop - newOverBottom;
1350
				// element is initially over bottom of within
1351
				} else if ( overBottom > 0 && overTop <= 0 ) {
1352
					position.top = withinOffset;
1353
				// element is initially over both top and bottom of within
1354
				} else {
1355
					if ( overTop > overBottom ) {
1356
						position.top = withinOffset + outerHeight - data.collisionHeight;
1357
					} else {
1358
						position.top = withinOffset;
1359
					}
1360
				}
1361
			// too far up -> align with top
1362
			} else if ( overTop > 0 ) {
1363
				position.top += overTop;
1364
			// too far down -> align with bottom edge
1365
			} else if ( overBottom > 0 ) {
1366
				position.top -= overBottom;
1367
			// adjust based on position and margin
1368
			} else {
1369
				position.top = max( position.top - collisionPosTop, position.top );
1370
			}
1371
		}
1372
	},
1373
	flip: {
1374
		left: function( position, data ) {
1375
			var within = data.within,
1376
				withinOffset = within.offset.left + within.scrollLeft,
1377
				outerWidth = within.width,
1378
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1379
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1380
				overLeft = collisionPosLeft - offsetLeft,
1381
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1382
				myOffset = data.my[ 0 ] === "left" ?
1383
					-data.elemWidth :
1384
					data.my[ 0 ] === "right" ?
1385
						data.elemWidth :
1386
						0,
1387
				atOffset = data.at[ 0 ] === "left" ?
1388
					data.targetWidth :
1389
					data.at[ 0 ] === "right" ?
1390
						-data.targetWidth :
1391
						0,
1392
				offset = -2 * data.offset[ 0 ],
1393
				newOverRight,
1394
				newOverLeft;
1395
 
1396
			if ( overLeft < 0 ) {
1397
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1398
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1399
					position.left += myOffset + atOffset + offset;
1400
				}
1401
			}
1402
			else if ( overRight > 0 ) {
1403
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1404
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1405
					position.left += myOffset + atOffset + offset;
1406
				}
1407
			}
1408
		},
1409
		top: function( position, data ) {
1410
			var within = data.within,
1411
				withinOffset = within.offset.top + within.scrollTop,
1412
				outerHeight = within.height,
1413
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1414
				collisionPosTop = position.top - data.collisionPosition.marginTop,
1415
				overTop = collisionPosTop - offsetTop,
1416
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1417
				top = data.my[ 1 ] === "top",
1418
				myOffset = top ?
1419
					-data.elemHeight :
1420
					data.my[ 1 ] === "bottom" ?
1421
						data.elemHeight :
1422
						0,
1423
				atOffset = data.at[ 1 ] === "top" ?
1424
					data.targetHeight :
1425
					data.at[ 1 ] === "bottom" ?
1426
						-data.targetHeight :
1427
						0,
1428
				offset = -2 * data.offset[ 1 ],
1429
				newOverTop,
1430
				newOverBottom;
1431
			if ( overTop < 0 ) {
1432
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1433
				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1434
					position.top += myOffset + atOffset + offset;
1435
				}
1436
			}
1437
			else if ( overBottom > 0 ) {
1438
				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1439
				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1440
					position.top += myOffset + atOffset + offset;
1441
				}
1442
			}
1443
		}
1444
	},
1445
	flipfit: {
1446
		left: function() {
1447
			$.ui.position.flip.left.apply( this, arguments );
1448
			$.ui.position.fit.left.apply( this, arguments );
1449
		},
1450
		top: function() {
1451
			$.ui.position.flip.top.apply( this, arguments );
1452
			$.ui.position.fit.top.apply( this, arguments );
1453
		}
1454
	}
1455
};
1456
 
1457
// fraction support test
1458
(function () {
1459
	var testElement, testElementParent, testElementStyle, offsetLeft, i,
1460
		body = document.getElementsByTagName( "body" )[ 0 ],
1461
		div = document.createElement( "div" );
1462
 
1463
	//Create a "fake body" for testing based on method used in jQuery.support
1464
	testElement = document.createElement( body ? "div" : "body" );
1465
	testElementStyle = {
1466
		visibility: "hidden",
1467
		width: 0,
1468
		height: 0,
1469
		border: 0,
1470
		margin: 0,
1471
		background: "none"
1472
	};
1473
	if ( body ) {
1474
		$.extend( testElementStyle, {
1475
			position: "absolute",
1476
			left: "-1000px",
1477
			top: "-1000px"
1478
		});
1479
	}
1480
	for ( i in testElementStyle ) {
1481
		testElement.style[ i ] = testElementStyle[ i ];
1482
	}
1483
	testElement.appendChild( div );
1484
	testElementParent = body || document.documentElement;
1485
	testElementParent.insertBefore( testElement, testElementParent.firstChild );
1486
 
1487
	div.style.cssText = "position: absolute; left: 10.7432222px;";
1488
 
1489
	offsetLeft = $( div ).offset().left;
1490
	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1491
 
1492
	testElement.innerHTML = "";
1493
	testElementParent.removeChild( testElement );
1494
})();
1495
 
1496
// DEPRECATED
1497
if ( $.uiBackCompat !== false ) {
1498
	// offset option
1499
	(function( $ ) {
1500
		var _position = $.fn.position;
1501
		$.fn.position = function( options ) {
1502
			if ( !options || !options.offset ) {
1503
				return _position.call( this, options );
1504
			}
1505
			var offset = options.offset.split( " " ),
1506
				at = options.at.split( " " );
1507
			if ( offset.length === 1 ) {
1508
				offset[ 1 ] = offset[ 0 ];
1509
			}
1510
			if ( /^\d/.test( offset[ 0 ] ) ) {
1511
				offset[ 0 ] = "+" + offset[ 0 ];
1512
			}
1513
			if ( /^\d/.test( offset[ 1 ] ) ) {
1514
				offset[ 1 ] = "+" + offset[ 1 ];
1515
			}
1516
			if ( at.length === 1 ) {
1517
				if ( /left|center|right/.test( at[ 0 ] ) ) {
1518
					at[ 1 ] = "center";
1519
				} else {
1520
					at[ 1 ] = at[ 0 ];
1521
					at[ 0 ] = "center";
1522
				}
1523
			}
1524
			return _position.call( this, $.extend( options, {
1525
				at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
1526
				offset: undefined
1527
			} ) );
1528
		};
1529
	}( jQuery ) );
1530
}
1531
 
1532
}( jQuery ) );
1533
(function( $, undefined ) {
1534
 
1535
$.widget("ui.draggable", $.ui.mouse, {
1536
	version: "1.9.2",
1537
	widgetEventPrefix: "drag",
1538
	options: {
1539
		addClasses: true,
1540
		appendTo: "parent",
1541
		axis: false,
1542
		connectToSortable: false,
1543
		containment: false,
1544
		cursor: "auto",
1545
		cursorAt: false,
1546
		grid: false,
1547
		handle: false,
1548
		helper: "original",
1549
		iframeFix: false,
1550
		opacity: false,
1551
		refreshPositions: false,
1552
		revert: false,
1553
		revertDuration: 500,
1554
		scope: "default",
1555
		scroll: true,
1556
		scrollSensitivity: 20,
1557
		scrollSpeed: 20,
1558
		snap: false,
1559
		snapMode: "both",
1560
		snapTolerance: 20,
1561
		stack: false,
1562
		zIndex: false
1563
	},
1564
	_create: function() {
1565
 
1566
		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1567
			this.element[0].style.position = 'relative';
1568
 
1569
		(this.options.addClasses && this.element.addClass("ui-draggable"));
1570
		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1571
 
1572
		this._mouseInit();
1573
 
1574
	},
1575
 
1576
	_destroy: function() {
1577
		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1578
		this._mouseDestroy();
1579
	},
1580
 
1581
	_mouseCapture: function(event) {
1582
 
1583
		var o = this.options;
1584
 
1585
		// among others, prevent a drag on a resizable-handle
1586
		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1587
			return false;
1588
 
1589
		//Quit if we're not on a valid handle
1590
		this.handle = this._getHandle(event);
1591
		if (!this.handle)
1592
			return false;
1593
 
1594
		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1595
			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1596
			.css({
1597
				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1598
				position: "absolute", opacity: "0.001", zIndex: 1000
1599
			})
1600
			.css($(this).offset())
1601
			.appendTo("body");
1602
		});
1603
 
1604
		return true;
1605
 
1606
	},
1607
 
1608
	_mouseStart: function(event) {
1609
 
1610
		var o = this.options;
1611
 
1612
		//Create and append the visible helper
1613
		this.helper = this._createHelper(event);
1614
 
1615
		this.helper.addClass("ui-draggable-dragging");
1616
 
1617
		//Cache the helper size
1618
		this._cacheHelperProportions();
1619
 
1620
		//If ddmanager is used for droppables, set the global draggable
1621
		if($.ui.ddmanager)
1622
			$.ui.ddmanager.current = this;
1623
 
1624
		/*
1625
		 * - Position generation -
1626
		 * This block generates everything position related - it's the core of draggables.
1627
		 */
1628
 
1629
		//Cache the margins of the original element
1630
		this._cacheMargins();
1631
 
1632
		//Store the helper's css position
1633
		this.cssPosition = this.helper.css("position");
1634
		this.scrollParent = this.helper.scrollParent();
1635
 
1636
		//The element's absolute position on the page minus margins
1637
		this.offset = this.positionAbs = this.element.offset();
1638
		this.offset = {
1639
			top: this.offset.top - this.margins.top,
1640
			left: this.offset.left - this.margins.left
1641
		};
1642
 
1643
		$.extend(this.offset, {
1644
			click: { //Where the click happened, relative to the element
1645
				left: event.pageX - this.offset.left,
1646
				top: event.pageY - this.offset.top
1647
			},
1648
			parent: this._getParentOffset(),
1649
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1650
		});
1651
 
1652
		//Generate the original position
1653
		this.originalPosition = this.position = this._generatePosition(event);
1654
		this.originalPageX = event.pageX;
1655
		this.originalPageY = event.pageY;
1656
 
1657
		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1658
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1659
 
1660
		//Set a containment if given in the options
1661
		if(o.containment)
1662
			this._setContainment();
1663
 
1664
		//Trigger event + callbacks
1665
		if(this._trigger("start", event) === false) {
1666
			this._clear();
1667
			return false;
1668
		}
1669
 
1670
		//Recache the helper size
1671
		this._cacheHelperProportions();
1672
 
1673
		//Prepare the droppable offsets
1674
		if ($.ui.ddmanager && !o.dropBehaviour)
1675
			$.ui.ddmanager.prepareOffsets(this, event);
1676
 
1677
 
1678
		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1679
 
1680
		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1681
		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1682
 
1683
		return true;
1684
	},
1685
 
1686
	_mouseDrag: function(event, noPropagation) {
1687
 
1688
		//Compute the helpers position
1689
		this.position = this._generatePosition(event);
1690
		this.positionAbs = this._convertPositionTo("absolute");
1691
 
1692
		//Call plugins and callbacks and use the resulting position if something is returned
1693
		if (!noPropagation) {
1694
			var ui = this._uiHash();
1695
			if(this._trigger('drag', event, ui) === false) {
1696
				this._mouseUp({});
1697
				return false;
1698
			}
1699
			this.position = ui.position;
1700
		}
1701
 
1702
		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1703
		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1704
		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1705
 
1706
		return false;
1707
	},
1708
 
1709
	_mouseStop: function(event) {
1710
 
1711
		//If we are using droppables, inform the manager about the drop
1712
		var dropped = false;
1713
		if ($.ui.ddmanager && !this.options.dropBehaviour)
1714
			dropped = $.ui.ddmanager.drop(this, event);
1715
 
1716
		//if a drop comes from outside (a sortable)
1717
		if(this.dropped) {
1718
			dropped = this.dropped;
1719
			this.dropped = false;
1720
		}
1721
 
1722
		//if the original element is no longer in the DOM don't bother to continue (see #8269)
1723
		var element = this.element[0], elementInDom = false;
1724
		while ( element && (element = element.parentNode) ) {
1725
			if (element == document ) {
1726
				elementInDom = true;
1727
			}
1728
		}
1729
		if ( !elementInDom && this.options.helper === "original" )
1730
			return false;
1731
 
1732
		if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1733
			var that = this;
1734
			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1735
				if(that._trigger("stop", event) !== false) {
1736
					that._clear();
1737
				}
1738
			});
1739
		} else {
1740
			if(this._trigger("stop", event) !== false) {
1741
				this._clear();
1742
			}
1743
		}
1744
 
1745
		return false;
1746
	},
1747
 
1748
	_mouseUp: function(event) {
1749
		//Remove frame helpers
1750
		$("div.ui-draggable-iframeFix").each(function() {
1751
			this.parentNode.removeChild(this);
1752
		});
1753
 
1754
		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1755
		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1756
 
1757
		return $.ui.mouse.prototype._mouseUp.call(this, event);
1758
	},
1759
 
1760
	cancel: function() {
1761
 
1762
		if(this.helper.is(".ui-draggable-dragging")) {
1763
			this._mouseUp({});
1764
		} else {
1765
			this._clear();
1766
		}
1767
 
1768
		return this;
1769
 
1770
	},
1771
 
1772
	_getHandle: function(event) {
1773
 
1774
		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1775
		$(this.options.handle, this.element)
1776
			.find("*")
1777
			.andSelf()
1778
			.each(function() {
1779
				if(this == event.target) handle = true;
1780
			});
1781
 
1782
		return handle;
1783
 
1784
	},
1785
 
1786
	_createHelper: function(event) {
1787
 
1788
		var o = this.options;
1789
		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1790
 
1791
		if(!helper.parents('body').length)
1792
			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1793
 
1794
		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1795
			helper.css("position", "absolute");
1796
 
1797
		return helper;
1798
 
1799
	},
1800
 
1801
	_adjustOffsetFromHelper: function(obj) {
1802
		if (typeof obj == 'string') {
1803
			obj = obj.split(' ');
1804
		}
1805
		if ($.isArray(obj)) {
1806
			obj = {left: +obj[0], top: +obj[1] || 0};
1807
		}
1808
		if ('left' in obj) {
1809
			this.offset.click.left = obj.left + this.margins.left;
1810
		}
1811
		if ('right' in obj) {
1812
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1813
		}
1814
		if ('top' in obj) {
1815
			this.offset.click.top = obj.top + this.margins.top;
1816
		}
1817
		if ('bottom' in obj) {
1818
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1819
		}
1820
	},
1821
 
1822
	_getParentOffset: function() {
1823
 
1824
		//Get the offsetParent and cache its position
1825
		this.offsetParent = this.helper.offsetParent();
1826
		var po = this.offsetParent.offset();
1827
 
1828
		// This is a special case where we need to modify a offset calculated on start, since the following happened:
1829
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1830
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1831
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1832
		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1833
			po.left += this.scrollParent.scrollLeft();
1834
			po.top += this.scrollParent.scrollTop();
1835
		}
1836
 
1837
		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1838
		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
1839
			po = { top: 0, left: 0 };
1840
 
1841
		return {
1842
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1843
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1844
		};
1845
 
1846
	},
1847
 
1848
	_getRelativeOffset: function() {
1849
 
1850
		if(this.cssPosition == "relative") {
1851
			var p = this.element.position();
1852
			return {
1853
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1854
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1855
			};
1856
		} else {
1857
			return { top: 0, left: 0 };
1858
		}
1859
 
1860
	},
1861
 
1862
	_cacheMargins: function() {
1863
		this.margins = {
1864
			left: (parseInt(this.element.css("marginLeft"),10) || 0),
1865
			top: (parseInt(this.element.css("marginTop"),10) || 0),
1866
			right: (parseInt(this.element.css("marginRight"),10) || 0),
1867
			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1868
		};
1869
	},
1870
 
1871
	_cacheHelperProportions: function() {
1872
		this.helperProportions = {
1873
			width: this.helper.outerWidth(),
1874
			height: this.helper.outerHeight()
1875
		};
1876
	},
1877
 
1878
	_setContainment: function() {
1879
 
1880
		var o = this.options;
1881
		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1882
		if(o.containment == 'document' || o.containment == 'window') this.containment = [
1883
			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1884
			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1885
			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1886
			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1887
		];
1888
 
1889
		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1890
			var c = $(o.containment);
1891
			var ce = c[0]; if(!ce) return;
1892
			var co = c.offset();
1893
			var over = ($(ce).css("overflow") != 'hidden');
1894
 
1895
			this.containment = [
1896
				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1897
				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1898
				(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1899
				(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
1900
			];
1901
			this.relative_container = c;
1902
 
1903
		} else if(o.containment.constructor == Array) {
1904
			this.containment = o.containment;
1905
		}
1906
 
1907
	},
1908
 
1909
	_convertPositionTo: function(d, pos) {
1910
 
1911
		if(!pos) pos = this.position;
1912
		var mod = d == "absolute" ? 1 : -1;
1913
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1914
 
1915
		return {
1916
			top: (
1917
				pos.top																	// The absolute mouse position
1918
				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1919
				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
1920
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1921
			),
1922
			left: (
1923
				pos.left																// The absolute mouse position
1924
				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
1925
				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
1926
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1927
			)
1928
		};
1929
 
1930
	},
1931
 
1932
	_generatePosition: function(event) {
1933
 
1934
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1935
		var pageX = event.pageX;
1936
		var pageY = event.pageY;
1937
 
1938
		/*
1939
		 * - Position constraining -
1940
		 * Constrain the position to a mix of grid, containment.
1941
		 */
1942
 
1943
		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1944
			var containment;
1945
			if(this.containment) {
1946
			if (this.relative_container){
1947
				var co = this.relative_container.offset();
1948
				containment = [ this.containment[0] + co.left,
1949
					this.containment[1] + co.top,
1950
					this.containment[2] + co.left,
1951
					this.containment[3] + co.top ];
1952
			}
1953
			else {
1954
				containment = this.containment;
1955
			}
1956
 
1957
				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1958
				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1959
				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1960
				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1961
			}
1962
 
1963
			if(o.grid) {
1964
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1965
				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1966
				pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1967
 
1968
				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1969
				pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1970
			}
1971
 
1972
		}
1973
 
1974
		return {
1975
			top: (
1976
				pageY																// The absolute mouse position
1977
				- this.offset.click.top													// Click offset (relative to the element)
1978
				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
1979
				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
1980
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1981
			),
1982
			left: (
1983
				pageX																// The absolute mouse position
1984
				- this.offset.click.left												// Click offset (relative to the element)
1985
				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
1986
				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
1987
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1988
			)
1989
		};
1990
 
1991
	},
1992
 
1993
	_clear: function() {
1994
		this.helper.removeClass("ui-draggable-dragging");
1995
		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1996
		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
1997
		this.helper = null;
1998
		this.cancelHelperRemoval = false;
1999
	},
2000
 
2001
	// From now on bulk stuff - mainly helpers
2002
 
2003
	_trigger: function(type, event, ui) {
2004
		ui = ui || this._uiHash();
2005
		$.ui.plugin.call(this, type, [event, ui]);
2006
		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
2007
		return $.Widget.prototype._trigger.call(this, type, event, ui);
2008
	},
2009
 
2010
	plugins: {},
2011
 
2012
	_uiHash: function(event) {
2013
		return {
2014
			helper: this.helper,
2015
			position: this.position,
2016
			originalPosition: this.originalPosition,
2017
			offset: this.positionAbs
2018
		};
2019
	}
2020
 
2021
});
2022
 
2023
$.ui.plugin.add("draggable", "connectToSortable", {
2024
	start: function(event, ui) {
2025
 
2026
		var inst = $(this).data("draggable"), o = inst.options,
2027
			uiSortable = $.extend({}, ui, { item: inst.element });
2028
		inst.sortables = [];
2029
		$(o.connectToSortable).each(function() {
2030
			var sortable = $.data(this, 'sortable');
2031
			if (sortable && !sortable.options.disabled) {
2032
				inst.sortables.push({
2033
					instance: sortable,
2034
					shouldRevert: sortable.options.revert
2035
				});
2036
				sortable.refreshPositions();	// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
2037
				sortable._trigger("activate", event, uiSortable);
2038
			}
2039
		});
2040
 
2041
	},
2042
	stop: function(event, ui) {
2043
 
2044
		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2045
		var inst = $(this).data("draggable"),
2046
			uiSortable = $.extend({}, ui, { item: inst.element });
2047
 
2048
		$.each(inst.sortables, function() {
2049
			if(this.instance.isOver) {
2050
 
2051
				this.instance.isOver = 0;
2052
 
2053
				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2054
				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2055
 
2056
				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
2057
				if(this.shouldRevert) this.instance.options.revert = true;
2058
 
2059
				//Trigger the stop of the sortable
2060
				this.instance._mouseStop(event);
2061
 
2062
				this.instance.options.helper = this.instance.options._helper;
2063
 
2064
				//If the helper has been the original item, restore properties in the sortable
2065
				if(inst.options.helper == 'original')
2066
					this.instance.currentItem.css({ top: 'auto', left: 'auto' });
2067
 
2068
			} else {
2069
				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2070
				this.instance._trigger("deactivate", event, uiSortable);
2071
			}
2072
 
2073
		});
2074
 
2075
	},
2076
	drag: function(event, ui) {
2077
 
2078
		var inst = $(this).data("draggable"), that = this;
2079
 
2080
		var checkPos = function(o) {
2081
			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
2082
			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
2083
			var itemHeight = o.height, itemWidth = o.width;
2084
			var itemTop = o.top, itemLeft = o.left;
2085
 
2086
			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
2087
		};
2088
 
2089
		$.each(inst.sortables, function(i) {
2090
 
2091
			var innermostIntersecting = false;
2092
			var thisSortable = this;
2093
			//Copy over some variables to allow calling the sortable's native _intersectsWith
2094
			this.instance.positionAbs = inst.positionAbs;
2095
			this.instance.helperProportions = inst.helperProportions;
2096
			this.instance.offset.click = inst.offset.click;
2097
 
2098
			if(this.instance._intersectsWith(this.instance.containerCache)) {
2099
				innermostIntersecting = true;
2100
				$.each(inst.sortables, function () {
2101
					this.instance.positionAbs = inst.positionAbs;
2102
					this.instance.helperProportions = inst.helperProportions;
2103
					this.instance.offset.click = inst.offset.click;
2104
					if  (this != thisSortable
2105
						&& this.instance._intersectsWith(this.instance.containerCache)
2106
						&& $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
2107
						innermostIntersecting = false;
2108
						return innermostIntersecting;
2109
				});
2110
			}
2111
 
2112
 
2113
			if(innermostIntersecting) {
2114
				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2115
				if(!this.instance.isOver) {
2116
 
2117
					this.instance.isOver = 1;
2118
					//Now we fake the start of dragging for the sortable instance,
2119
					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2120
					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
2121
					this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
2122
					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2123
					this.instance.options.helper = function() { return ui.helper[0]; };
2124
 
2125
					event.target = this.instance.currentItem[0];
2126
					this.instance._mouseCapture(event, true);
2127
					this.instance._mouseStart(event, true, true);
2128
 
2129
					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2130
					this.instance.offset.click.top = inst.offset.click.top;
2131
					this.instance.offset.click.left = inst.offset.click.left;
2132
					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2133
					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2134
 
2135
					inst._trigger("toSortable", event);
2136
					inst.dropped = this.instance.element; //draggable revert needs that
2137
					//hack so receive/update callbacks work (mostly)
2138
					inst.currentItem = inst.element;
2139
					this.instance.fromOutside = inst;
2140
 
2141
				}
2142
 
2143
				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
2144
				if(this.instance.currentItem) this.instance._mouseDrag(event);
2145
 
2146
			} else {
2147
 
2148
				//If it doesn't intersect with the sortable, and it intersected before,
2149
				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2150
				if(this.instance.isOver) {
2151
 
2152
					this.instance.isOver = 0;
2153
					this.instance.cancelHelperRemoval = true;
2154
 
2155
					//Prevent reverting on this forced stop
2156
					this.instance.options.revert = false;
2157
 
2158
					// The out event needs to be triggered independently
2159
					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
2160
 
2161
					this.instance._mouseStop(event, true);
2162
					this.instance.options.helper = this.instance.options._helper;
2163
 
2164
					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2165
					this.instance.currentItem.remove();
2166
					if(this.instance.placeholder) this.instance.placeholder.remove();
2167
 
2168
					inst._trigger("fromSortable", event);
2169
					inst.dropped = false; //draggable revert needs that
2170
				}
2171
 
2172
			};
2173
 
2174
		});
2175
 
2176
	}
2177
});
2178
 
2179
$.ui.plugin.add("draggable", "cursor", {
2180
	start: function(event, ui) {
2181
		var t = $('body'), o = $(this).data('draggable').options;
2182
		if (t.css("cursor")) o._cursor = t.css("cursor");
2183
		t.css("cursor", o.cursor);
2184
	},
2185
	stop: function(event, ui) {
2186
		var o = $(this).data('draggable').options;
2187
		if (o._cursor) $('body').css("cursor", o._cursor);
2188
	}
2189
});
2190
 
2191
$.ui.plugin.add("draggable", "opacity", {
2192
	start: function(event, ui) {
2193
		var t = $(ui.helper), o = $(this).data('draggable').options;
2194
		if(t.css("opacity")) o._opacity = t.css("opacity");
2195
		t.css('opacity', o.opacity);
2196
	},
2197
	stop: function(event, ui) {
2198
		var o = $(this).data('draggable').options;
2199
		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
2200
	}
2201
});
2202
 
2203
$.ui.plugin.add("draggable", "scroll", {
2204
	start: function(event, ui) {
2205
		var i = $(this).data("draggable");
2206
		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
2207
	},
2208
	drag: function(event, ui) {
2209
 
2210
		var i = $(this).data("draggable"), o = i.options, scrolled = false;
2211
 
2212
		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
2213
 
2214
			if(!o.axis || o.axis != 'x') {
2215
				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
2216
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2217
				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
2218
					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2219
			}
2220
 
2221
			if(!o.axis || o.axis != 'y') {
2222
				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
2223
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2224
				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
2225
					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2226
			}
2227
 
2228
		} else {
2229
 
2230
			if(!o.axis || o.axis != 'x') {
2231
				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
2232
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2233
				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
2234
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2235
			}
2236
 
2237
			if(!o.axis || o.axis != 'y') {
2238
				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
2239
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2240
				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
2241
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2242
			}
2243
 
2244
		}
2245
 
2246
		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
2247
			$.ui.ddmanager.prepareOffsets(i, event);
2248
 
2249
	}
2250
});
2251
 
2252
$.ui.plugin.add("draggable", "snap", {
2253
	start: function(event, ui) {
2254
 
2255
		var i = $(this).data("draggable"), o = i.options;
2256
		i.snapElements = [];
2257
 
2258
		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
2259
			var $t = $(this); var $o = $t.offset();
2260
			if(this != i.element[0]) i.snapElements.push({
2261
				item: this,
2262
				width: $t.outerWidth(), height: $t.outerHeight(),
2263
				top: $o.top, left: $o.left
2264
			});
2265
		});
2266
 
2267
	},
2268
	drag: function(event, ui) {
2269
 
2270
		var inst = $(this).data("draggable"), o = inst.options;
2271
		var d = o.snapTolerance;
2272
 
2273
		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2274
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2275
 
2276
		for (var i = inst.snapElements.length - 1; i >= 0; i--){
2277
 
2278
			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
2279
				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
2280
 
2281
			//Yes, I know, this is insane ;)
2282
			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
2283
				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2284
				inst.snapElements[i].snapping = false;
2285
				continue;
2286
			}
2287
 
2288
			if(o.snapMode != 'inner') {
2289
				var ts = Math.abs(t - y2) <= d;
2290
				var bs = Math.abs(b - y1) <= d;
2291
				var ls = Math.abs(l - x2) <= d;
2292
				var rs = Math.abs(r - x1) <= d;
2293
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2294
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2295
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2296
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2297
			}
2298
 
2299
			var first = (ts || bs || ls || rs);
2300
 
2301
			if(o.snapMode != 'outer') {
2302
				var ts = Math.abs(t - y1) <= d;
2303
				var bs = Math.abs(b - y2) <= d;
2304
				var ls = Math.abs(l - x1) <= d;
2305
				var rs = Math.abs(r - x2) <= d;
2306
				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2307
				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2308
				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2309
				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2310
			}
2311
 
2312
			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
2313
				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2314
			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2315
 
2316
		};
2317
 
2318
	}
2319
});
2320
 
2321
$.ui.plugin.add("draggable", "stack", {
2322
	start: function(event, ui) {
2323
 
2324
		var o = $(this).data("draggable").options;
2325
 
2326
		var group = $.makeArray($(o.stack)).sort(function(a,b) {
2327
			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2328
		});
2329
		if (!group.length) { return; }
2330
 
2331
		var min = parseInt(group[0].style.zIndex) || 0;
2332
		$(group).each(function(i) {
2333
			this.style.zIndex = min + i;
2334
		});
2335
 
2336
		this[0].style.zIndex = min + group.length;
2337
 
2338
	}
2339
});
2340
 
2341
$.ui.plugin.add("draggable", "zIndex", {
2342
	start: function(event, ui) {
2343
		var t = $(ui.helper), o = $(this).data("draggable").options;
2344
		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
2345
		t.css('zIndex', o.zIndex);
2346
	},
2347
	stop: function(event, ui) {
2348
		var o = $(this).data("draggable").options;
2349
		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
2350
	}
2351
});
2352
 
2353
})(jQuery);
2354
(function( $, undefined ) {
2355
 
2356
$.widget("ui.droppable", {
2357
	version: "1.9.2",
2358
	widgetEventPrefix: "drop",
2359
	options: {
2360
		accept: '*',
2361
		activeClass: false,
2362
		addClasses: true,
2363
		greedy: false,
2364
		hoverClass: false,
2365
		scope: 'default',
2366
		tolerance: 'intersect'
2367
	},
2368
	_create: function() {
2369
 
2370
		var o = this.options, accept = o.accept;
2371
		this.isover = 0; this.isout = 1;
2372
 
2373
		this.accept = $.isFunction(accept) ? accept : function(d) {
2374
			return d.is(accept);
2375
		};
2376
 
2377
		//Store the droppable's proportions
2378
		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
2379
 
2380
		// Add the reference and positions to the manager
2381
		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
2382
		$.ui.ddmanager.droppables[o.scope].push(this);
2383
 
2384
		(o.addClasses && this.element.addClass("ui-droppable"));
2385
 
2386
	},
2387
 
2388
	_destroy: function() {
2389
		var drop = $.ui.ddmanager.droppables[this.options.scope];
2390
		for ( var i = 0; i < drop.length; i++ )
2391
			if ( drop[i] == this )
2392
				drop.splice(i, 1);
2393
 
2394
		this.element.removeClass("ui-droppable ui-droppable-disabled");
2395
	},
2396
 
2397
	_setOption: function(key, value) {
2398
 
2399
		if(key == 'accept') {
2400
			this.accept = $.isFunction(value) ? value : function(d) {
2401
				return d.is(value);
2402
			};
2403
		}
2404
		$.Widget.prototype._setOption.apply(this, arguments);
2405
	},
2406
 
2407
	_activate: function(event) {
2408
		var draggable = $.ui.ddmanager.current;
2409
		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
2410
		(draggable && this._trigger('activate', event, this.ui(draggable)));
2411
	},
2412
 
2413
	_deactivate: function(event) {
2414
		var draggable = $.ui.ddmanager.current;
2415
		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2416
		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
2417
	},
2418
 
2419
	_over: function(event) {
2420
 
2421
		var draggable = $.ui.ddmanager.current;
2422
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2423
 
2424
		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2425
			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
2426
			this._trigger('over', event, this.ui(draggable));
2427
		}
2428
 
2429
	},
2430
 
2431
	_out: function(event) {
2432
 
2433
		var draggable = $.ui.ddmanager.current;
2434
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
2435
 
2436
		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2437
			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2438
			this._trigger('out', event, this.ui(draggable));
2439
		}
2440
 
2441
	},
2442
 
2443
	_drop: function(event,custom) {
2444
 
2445
		var draggable = custom || $.ui.ddmanager.current;
2446
		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
2447
 
2448
		var childrenIntersection = false;
2449
		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
2450
			var inst = $.data(this, 'droppable');
2451
			if(
2452
				inst.options.greedy
2453
				&& !inst.options.disabled
2454
				&& inst.options.scope == draggable.options.scope
2455
				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
2456
				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2457
			) { childrenIntersection = true; return false; }
2458
		});
2459
		if(childrenIntersection) return false;
2460
 
2461
		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2462
			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2463
			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2464
			this._trigger('drop', event, this.ui(draggable));
2465
			return this.element;
2466
		}
2467
 
2468
		return false;
2469
 
2470
	},
2471
 
2472
	ui: function(c) {
2473
		return {
2474
			draggable: (c.currentItem || c.element),
2475
			helper: c.helper,
2476
			position: c.position,
2477
			offset: c.positionAbs
2478
		};
2479
	}
2480
 
2481
});
2482
 
2483
$.ui.intersect = function(draggable, droppable, toleranceMode) {
2484
 
2485
	if (!droppable.offset) return false;
2486
 
2487
	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2488
		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
2489
	var l = droppable.offset.left, r = l + droppable.proportions.width,
2490
		t = droppable.offset.top, b = t + droppable.proportions.height;
2491
 
2492
	switch (toleranceMode) {
2493
		case 'fit':
2494
			return (l <= x1 && x2 <= r
2495
				&& t <= y1 && y2 <= b);
2496
			break;
2497
		case 'intersect':
2498
			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
2499
				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
2500
				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
2501
				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2502
			break;
2503
		case 'pointer':
2504
			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2505
				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2506
				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2507
			return isOver;
2508
			break;
2509
		case 'touch':
2510
			return (
2511
					(y1 >= t && y1 <= b) ||	// Top edge touching
2512
					(y2 >= t && y2 <= b) ||	// Bottom edge touching
2513
					(y1 < t && y2 > b)		// Surrounded vertically
2514
				) && (
2515
					(x1 >= l && x1 <= r) ||	// Left edge touching
2516
					(x2 >= l && x2 <= r) ||	// Right edge touching
2517
					(x1 < l && x2 > r)		// Surrounded horizontally
2518
				);
2519
			break;
2520
		default:
2521
			return false;
2522
			break;
2523
		}
2524
 
2525
};
2526
 
2527
/*
2528
	This manager tracks offsets of draggables and droppables
2529
*/
2530
$.ui.ddmanager = {
2531
	current: null,
2532
	droppables: { 'default': [] },
2533
	prepareOffsets: function(t, event) {
2534
 
2535
		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2536
		var type = event ? event.type : null; // workaround for #2317
2537
		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2538
 
2539
		droppablesLoop: for (var i = 0; i < m.length; i++) {
2540
 
2541
			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
2542
			for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
2543
			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue
2544
 
2545
			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2546
 
2547
			m[i].offset = m[i].element.offset();
2548
			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2549
 
2550
		}
2551
 
2552
	},
2553
	drop: function(draggable, event) {
2554
 
2555
		var dropped = false;
2556
		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2557
 
2558
			if(!this.options) return;
2559
			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2560
				dropped = this._drop.call(this, event) || dropped;
2561
 
2562
			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2563
				this.isout = 1; this.isover = 0;
2564
				this._deactivate.call(this, event);
2565
			}
2566
 
2567
		});
2568
		return dropped;
2569
 
2570
	},
2571
	dragStart: function( draggable, event ) {
2572
		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2573
		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2574
			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2575
		});
2576
	},
2577
	drag: function(draggable, event) {
2578
 
2579
		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2580
		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2581
 
2582
		//Run through all droppables and check their positions based on specific tolerance options
2583
		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2584
 
2585
			if(this.options.disabled || this.greedyChild || !this.visible) return;
2586
			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2587
 
2588
			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2589
			if(!c) return;
2590
 
2591
			var parentInstance;
2592
			if (this.options.greedy) {
2593
				// find droppable parents with same scope
2594
				var scope = this.options.scope;
2595
				var parent = this.element.parents(':data(droppable)').filter(function () {
2596
					return $.data(this, 'droppable').options.scope === scope;
2597
				});
2598
 
2599
				if (parent.length) {
2600
					parentInstance = $.data(parent[0], 'droppable');
2601
					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2602
				}
2603
			}
2604
 
2605
			// we just moved into a greedy child
2606
			if (parentInstance && c == 'isover') {
2607
				parentInstance['isover'] = 0;
2608
				parentInstance['isout'] = 1;
2609
				parentInstance._out.call(parentInstance, event);
2610
			}
2611
 
2612
			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2613
			this[c == "isover" ? "_over" : "_out"].call(this, event);
2614
 
2615
			// we just moved out of a greedy child
2616
			if (parentInstance && c == 'isout') {
2617
				parentInstance['isout'] = 0;
2618
				parentInstance['isover'] = 1;
2619
				parentInstance._over.call(parentInstance, event);
2620
			}
2621
		});
2622
 
2623
	},
2624
	dragStop: function( draggable, event ) {
2625
		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2626
		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2627
		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2628
	}
2629
};
2630
 
2631
})(jQuery);
2632
(function( $, undefined ) {
2633
 
2634
$.widget("ui.resizable", $.ui.mouse, {
2635
	version: "1.9.2",
2636
	widgetEventPrefix: "resize",
2637
	options: {
2638
		alsoResize: false,
2639
		animate: false,
2640
		animateDuration: "slow",
2641
		animateEasing: "swing",
2642
		aspectRatio: false,
2643
		autoHide: false,
2644
		containment: false,
2645
		ghost: false,
2646
		grid: false,
2647
		handles: "e,s,se",
2648
		helper: false,
2649
		maxHeight: null,
2650
		maxWidth: null,
2651
		minHeight: 10,
2652
		minWidth: 10,
2653
		zIndex: 1000
2654
	},
2655
	_create: function() {
2656
 
2657
		var that = this, o = this.options;
2658
		this.element.addClass("ui-resizable");
2659
 
2660
		$.extend(this, {
2661
			_aspectRatio: !!(o.aspectRatio),
2662
			aspectRatio: o.aspectRatio,
2663
			originalElement: this.element,
2664
			_proportionallyResizeElements: [],
2665
			_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2666
		});
2667
 
2668
		//Wrap the element if it cannot hold child nodes
2669
		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2670
 
2671
			//Create a wrapper element and set the wrapper to the new current internal element
2672
			this.element.wrap(
2673
				$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2674
					position: this.element.css('position'),
2675
					width: this.element.outerWidth(),
2676
					height: this.element.outerHeight(),
2677
					top: this.element.css('top'),
2678
					left: this.element.css('left')
2679
				})
2680
			);
2681
 
2682
			//Overwrite the original this.element
2683
			this.element = this.element.parent().data(
2684
				"resizable", this.element.data('resizable')
2685
			);
2686
 
2687
			this.elementIsWrapper = true;
2688
 
2689
			//Move margins to the wrapper
2690
			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2691
			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2692
 
2693
			//Prevent Safari textarea resize
2694
			this.originalResizeStyle = this.originalElement.css('resize');
2695
			this.originalElement.css('resize', 'none');
2696
 
2697
			//Push the actual element to our proportionallyResize internal array
2698
			this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2699
 
2700
			// avoid IE jump (hard set the margin)
2701
			this.originalElement.css({ margin: this.originalElement.css('margin') });
2702
 
2703
			// fix handlers offset
2704
			this._proportionallyResize();
2705
 
2706
		}
2707
 
2708
		this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
2709
		if(this.handles.constructor == String) {
2710
 
2711
			if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2712
			var n = this.handles.split(","); this.handles = {};
2713
 
2714
			for(var i = 0; i < n.length; i++) {
2715
 
2716
				var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2717
				var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2718
 
2719
				// Apply zIndex to all handles - see #7960
2720
				axis.css({ zIndex: o.zIndex });
2721
 
2722
				//TODO : What's going on here?
2723
				if ('se' == handle) {
2724
					axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2725
				};
2726
 
2727
				//Insert into internal handles object and append to element
2728
				this.handles[handle] = '.ui-resizable-'+handle;
2729
				this.element.append(axis);
2730
			}
2731
 
2732
		}
2733
 
2734
		this._renderAxis = function(target) {
2735
 
2736
			target = target || this.element;
2737
 
2738
			for(var i in this.handles) {
2739
 
2740
				if(this.handles[i].constructor == String)
2741
					this.handles[i] = $(this.handles[i], this.element).show();
2742
 
2743
				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2744
				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2745
 
2746
					var axis = $(this.handles[i], this.element), padWrapper = 0;
2747
 
2748
					//Checking the correct pad and border
2749
					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2750
 
2751
					//The padding type i have to apply...
2752
					var padPos = [ 'padding',
2753
						/ne|nw|n/.test(i) ? 'Top' :
2754
						/se|sw|s/.test(i) ? 'Bottom' :
2755
						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
2756
 
2757
					target.css(padPos, padWrapper);
2758
 
2759
					this._proportionallyResize();
2760
 
2761
				}
2762
 
2763
				//TODO: What's that good for? There's not anything to be executed left
2764
				if(!$(this.handles[i]).length)
2765
					continue;
2766
 
2767
			}
2768
		};
2769
 
2770
		//TODO: make renderAxis a prototype function
2771
		this._renderAxis(this.element);
2772
 
2773
		this._handles = $('.ui-resizable-handle', this.element)
2774
			.disableSelection();
2775
 
2776
		//Matching axis name
2777
		this._handles.mouseover(function() {
2778
			if (!that.resizing) {
2779
				if (this.className)
2780
					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2781
				//Axis, default = se
2782
				that.axis = axis && axis[1] ? axis[1] : 'se';
2783
			}
2784
		});
2785
 
2786
		//If we want to auto hide the elements
2787
		if (o.autoHide) {
2788
			this._handles.hide();
2789
			$(this.element)
2790
				.addClass("ui-resizable-autohide")
2791
				.mouseenter(function() {
2792
					if (o.disabled) return;
2793
					$(this).removeClass("ui-resizable-autohide");
2794
					that._handles.show();
2795
				})
2796
				.mouseleave(function(){
2797
					if (o.disabled) return;
2798
					if (!that.resizing) {
2799
						$(this).addClass("ui-resizable-autohide");
2800
						that._handles.hide();
2801
					}
2802
				});
2803
		}
2804
 
2805
		//Initialize the mouse interaction
2806
		this._mouseInit();
2807
 
2808
	},
2809
 
2810
	_destroy: function() {
2811
 
2812
		this._mouseDestroy();
2813
 
2814
		var _destroy = function(exp) {
2815
			$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2816
				.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2817
		};
2818
 
2819
		//TODO: Unwrap at same DOM position
2820
		if (this.elementIsWrapper) {
2821
			_destroy(this.element);
2822
			var wrapper = this.element;
2823
			this.originalElement.css({
2824
				position: wrapper.css('position'),
2825
				width: wrapper.outerWidth(),
2826
				height: wrapper.outerHeight(),
2827
				top: wrapper.css('top'),
2828
				left: wrapper.css('left')
2829
			}).insertAfter( wrapper );
2830
			wrapper.remove();
2831
		}
2832
 
2833
		this.originalElement.css('resize', this.originalResizeStyle);
2834
		_destroy(this.originalElement);
2835
 
2836
		return this;
2837
	},
2838
 
2839
	_mouseCapture: function(event) {
2840
		var handle = false;
2841
		for (var i in this.handles) {
2842
			if ($(this.handles[i])[0] == event.target) {
2843
				handle = true;
2844
			}
2845
		}
2846
 
2847
		return !this.options.disabled && handle;
2848
	},
2849
 
2850
	_mouseStart: function(event) {
2851
 
2852
		var o = this.options, iniPos = this.element.position(), el = this.element;
2853
 
2854
		this.resizing = true;
2855
		this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2856
 
2857
		// bugfix for http://dev.jquery.com/ticket/1749
2858
		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2859
			el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2860
		}
2861
 
2862
		this._renderProxy();
2863
 
2864
		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2865
 
2866
		if (o.containment) {
2867
			curleft += $(o.containment).scrollLeft() || 0;
2868
			curtop += $(o.containment).scrollTop() || 0;
2869
		}
2870
 
2871
		//Store needed variables
2872
		this.offset = this.helper.offset();
2873
		this.position = { left: curleft, top: curtop };
2874
		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2875
		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2876
		this.originalPosition = { left: curleft, top: curtop };
2877
		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2878
		this.originalMousePosition = { left: event.pageX, top: event.pageY };
2879
 
2880
		//Aspect Ratio
2881
		this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2882
 
2883
		var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2884
		$('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2885
 
2886
		el.addClass("ui-resizable-resizing");
2887
		this._propagate("start", event);
2888
		return true;
2889
	},
2890
 
2891
	_mouseDrag: function(event) {
2892
 
2893
		//Increase performance, avoid regex
2894
		var el = this.helper, o = this.options, props = {},
2895
			that = this, smp = this.originalMousePosition, a = this.axis;
2896
 
2897
		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2898
		var trigger = this._change[a];
2899
		if (!trigger) return false;
2900
 
2901
		// Calculate the attrs that will be change
2902
		var data = trigger.apply(this, [event, dx, dy]);
2903
 
2904
		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2905
		this._updateVirtualBoundaries(event.shiftKey);
2906
		if (this._aspectRatio || event.shiftKey)
2907
			data = this._updateRatio(data, event);
2908
 
2909
		data = this._respectSize(data, event);
2910
 
2911
		// plugins callbacks need to be called first
2912
		this._propagate("resize", event);
2913
 
2914
		el.css({
2915
			top: this.position.top + "px", left: this.position.left + "px",
2916
			width: this.size.width + "px", height: this.size.height + "px"
2917
		});
2918
 
2919
		if (!this._helper && this._proportionallyResizeElements.length)
2920
			this._proportionallyResize();
2921
 
2922
		this._updateCache(data);
2923
 
2924
		// calling the user callback at the end
2925
		this._trigger('resize', event, this.ui());
2926
 
2927
		return false;
2928
	},
2929
 
2930
	_mouseStop: function(event) {
2931
 
2932
		this.resizing = false;
2933
		var o = this.options, that = this;
2934
 
2935
		if(this._helper) {
2936
			var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2937
				soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2938
				soffsetw = ista ? 0 : that.sizeDiff.width;
2939
 
2940
			var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
2941
				left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
2942
				top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
2943
 
2944
			if (!o.animate)
2945
				this.element.css($.extend(s, { top: top, left: left }));
2946
 
2947
			that.helper.height(that.size.height);
2948
			that.helper.width(that.size.width);
2949
 
2950
			if (this._helper && !o.animate) this._proportionallyResize();
2951
		}
2952
 
2953
		$('body').css('cursor', 'auto');
2954
 
2955
		this.element.removeClass("ui-resizable-resizing");
2956
 
2957
		this._propagate("stop", event);
2958
 
2959
		if (this._helper) this.helper.remove();
2960
		return false;
2961
 
2962
	},
2963
 
2964
	_updateVirtualBoundaries: function(forceAspectRatio) {
2965
		var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2966
 
2967
		b = {
2968
			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2969
			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2970
			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2971
			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2972
		};
2973
 
2974
		if(this._aspectRatio || forceAspectRatio) {
2975
			// We want to create an enclosing box whose aspect ration is the requested one
2976
			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2977
			pMinWidth = b.minHeight * this.aspectRatio;
2978
			pMinHeight = b.minWidth / this.aspectRatio;
2979
			pMaxWidth = b.maxHeight * this.aspectRatio;
2980
			pMaxHeight = b.maxWidth / this.aspectRatio;
2981
 
2982
			if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2983
			if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2984
			if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2985
			if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2986
		}
2987
		this._vBoundaries = b;
2988
	},
2989
 
2990
	_updateCache: function(data) {
2991
		var o = this.options;
2992
		this.offset = this.helper.offset();
2993
		if (isNumber(data.left)) this.position.left = data.left;
2994
		if (isNumber(data.top)) this.position.top = data.top;
2995
		if (isNumber(data.height)) this.size.height = data.height;
2996
		if (isNumber(data.width)) this.size.width = data.width;
2997
	},
2998
 
2999
	_updateRatio: function(data, event) {
3000
 
3001
		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
3002
 
3003
		if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
3004
		else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
3005
 
3006
		if (a == 'sw') {
3007
			data.left = cpos.left + (csize.width - data.width);
3008
			data.top = null;
3009
		}
3010
		if (a == 'nw') {
3011
			data.top = cpos.top + (csize.height - data.height);
3012
			data.left = cpos.left + (csize.width - data.width);
3013
		}
3014
 
3015
		return data;
3016
	},
3017
 
3018
	_respectSize: function(data, event) {
3019
 
3020
		var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
3021
				ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3022
					isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
3023
 
3024
		if (isminw) data.width = o.minWidth;
3025
		if (isminh) data.height = o.minHeight;
3026
		if (ismaxw) data.width = o.maxWidth;
3027
		if (ismaxh) data.height = o.maxHeight;
3028
 
3029
		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
3030
		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3031
 
3032
		if (isminw && cw) data.left = dw - o.minWidth;
3033
		if (ismaxw && cw) data.left = dw - o.maxWidth;
3034
		if (isminh && ch)	data.top = dh - o.minHeight;
3035
		if (ismaxh && ch)	data.top = dh - o.maxHeight;
3036
 
3037
		// fixing jump error on top/left - bug #2330
3038
		var isNotwh = !data.width && !data.height;
3039
		if (isNotwh && !data.left && data.top) data.top = null;
3040
		else if (isNotwh && !data.top && data.left) data.left = null;
3041
 
3042
		return data;
3043
	},
3044
 
3045
	_proportionallyResize: function() {
3046
 
3047
		var o = this.options;
3048
		if (!this._proportionallyResizeElements.length) return;
3049
		var element = this.helper || this.element;
3050
 
3051
		for (var i=0; i < this._proportionallyResizeElements.length; i++) {
3052
 
3053
			var prel = this._proportionallyResizeElements[i];
3054
 
3055
			if (!this.borderDif) {
3056
				var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
3057
					p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
3058
 
3059
				this.borderDif = $.map(b, function(v, i) {
3060
					var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
3061
					return border + padding;
3062
				});
3063
			}
3064
 
3065
			prel.css({
3066
				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
3067
				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
3068
			});
3069
 
3070
		};
3071
 
3072
	},
3073
 
3074
	_renderProxy: function() {
3075
 
3076
		var el = this.element, o = this.options;
3077
		this.elementOffset = el.offset();
3078
 
3079
		if(this._helper) {
3080
 
3081
			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
3082
 
3083
			// fix ie6 offset TODO: This seems broken
3084
			var ie6offset = ($.ui.ie6 ? 1 : 0),
3085
			pxyoffset = ( $.ui.ie6 ? 2 : -1 );
3086
 
3087
			this.helper.addClass(this._helper).css({
3088
				width: this.element.outerWidth() + pxyoffset,
3089
				height: this.element.outerHeight() + pxyoffset,
3090
				position: 'absolute',
3091
				left: this.elementOffset.left - ie6offset +'px',
3092
				top: this.elementOffset.top - ie6offset +'px',
3093
				zIndex: ++o.zIndex //TODO: Don't modify option
3094
			});
3095
 
3096
			this.helper
3097
				.appendTo("body")
3098
				.disableSelection();
3099
 
3100
		} else {
3101
			this.helper = this.element;
3102
		}
3103
 
3104
	},
3105
 
3106
	_change: {
3107
		e: function(event, dx, dy) {
3108
			return { width: this.originalSize.width + dx };
3109
		},
3110
		w: function(event, dx, dy) {
3111
			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
3112
			return { left: sp.left + dx, width: cs.width - dx };
3113
		},
3114
		n: function(event, dx, dy) {
3115
			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
3116
			return { top: sp.top + dy, height: cs.height - dy };
3117
		},
3118
		s: function(event, dx, dy) {
3119
			return { height: this.originalSize.height + dy };
3120
		},
3121
		se: function(event, dx, dy) {
3122
			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3123
		},
3124
		sw: function(event, dx, dy) {
3125
			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3126
		},
3127
		ne: function(event, dx, dy) {
3128
			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3129
		},
3130
		nw: function(event, dx, dy) {
3131
			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3132
		}
3133
	},
3134
 
3135
	_propagate: function(n, event) {
3136
		$.ui.plugin.call(this, n, [event, this.ui()]);
3137
		(n != "resize" && this._trigger(n, event, this.ui()));
3138
	},
3139
 
3140
	plugins: {},
3141
 
3142
	ui: function() {
3143
		return {
3144
			originalElement: this.originalElement,
3145
			element: this.element,
3146
			helper: this.helper,
3147
			position: this.position,
3148
			size: this.size,
3149
			originalSize: this.originalSize,
3150
			originalPosition: this.originalPosition
3151
		};
3152
	}
3153
 
3154
});
3155
 
3156
/*
3157
 * Resizable Extensions
3158
 */
3159
 
3160
$.ui.plugin.add("resizable", "alsoResize", {
3161
 
3162
	start: function (event, ui) {
3163
		var that = $(this).data("resizable"), o = that.options;
3164
 
3165
		var _store = function (exp) {
3166
			$(exp).each(function() {
3167
				var el = $(this);
3168
				el.data("resizable-alsoresize", {
3169
					width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3170
					left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
3171
				});
3172
			});
3173
		};
3174
 
3175
		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
3176
			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3177
			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3178
		}else{
3179
			_store(o.alsoResize);
3180
		}
3181
	},
3182
 
3183
	resize: function (event, ui) {
3184
		var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
3185
 
3186
		var delta = {
3187
			height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3188
			top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3189
		},
3190
 
3191
		_alsoResize = function (exp, c) {
3192
			$(exp).each(function() {
3193
				var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
3194
					css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
3195
 
3196
				$.each(css, function (i, prop) {
3197
					var sum = (start[prop]||0) + (delta[prop]||0);
3198
					if (sum && sum >= 0)
3199
						style[prop] = sum || null;
3200
				});
3201
 
3202
				el.css(style);
3203
			});
3204
		};
3205
 
3206
		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
3207
			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3208
		}else{
3209
			_alsoResize(o.alsoResize);
3210
		}
3211
	},
3212
 
3213
	stop: function (event, ui) {
3214
		$(this).removeData("resizable-alsoresize");
3215
	}
3216
});
3217
 
3218
$.ui.plugin.add("resizable", "animate", {
3219
 
3220
	stop: function(event, ui) {
3221
		var that = $(this).data("resizable"), o = that.options;
3222
 
3223
		var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3224
					soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
3225
						soffsetw = ista ? 0 : that.sizeDiff.width;
3226
 
3227
		var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3228
					left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
3229
						top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
3230
 
3231
		that.element.animate(
3232
			$.extend(style, top && left ? { top: top, left: left } : {}), {
3233
				duration: o.animateDuration,
3234
				easing: o.animateEasing,
3235
				step: function() {
3236
 
3237
					var data = {
3238
						width: parseInt(that.element.css('width'), 10),
3239
						height: parseInt(that.element.css('height'), 10),
3240
						top: parseInt(that.element.css('top'), 10),
3241
						left: parseInt(that.element.css('left'), 10)
3242
					};
3243
 
3244
					if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
3245
 
3246
					// propagating resize, and updating values for each animation step
3247
					that._updateCache(data);
3248
					that._propagate("resize", event);
3249
 
3250
				}
3251
			}
3252
		);
3253
	}
3254
 
3255
});
3256
 
3257
$.ui.plugin.add("resizable", "containment", {
3258
 
3259
	start: function(event, ui) {
3260
		var that = $(this).data("resizable"), o = that.options, el = that.element;
3261
		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
3262
		if (!ce) return;
3263
 
3264
		that.containerElement = $(ce);
3265
 
3266
		if (/document/.test(oc) || oc == document) {
3267
			that.containerOffset = { left: 0, top: 0 };
3268
			that.containerPosition = { left: 0, top: 0 };
3269
 
3270
			that.parentData = {
3271
				element: $(document), left: 0, top: 0,
3272
				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3273
			};
3274
		}
3275
 
3276
		// i'm a node, so compute top, left, right, bottom
3277
		else {
3278
			var element = $(ce), p = [];
3279
			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3280
 
3281
			that.containerOffset = element.offset();
3282
			that.containerPosition = element.position();
3283
			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3284
 
3285
			var co = that.containerOffset, ch = that.containerSize.height,	cw = that.containerSize.width,
3286
						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3287
 
3288
			that.parentData = {
3289
				element: ce, left: co.left, top: co.top, width: width, height: height
3290
			};
3291
		}
3292
	},
3293
 
3294
	resize: function(event, ui) {
3295
		var that = $(this).data("resizable"), o = that.options,
3296
				ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
3297
				pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
3298
 
3299
		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
3300
 
3301
		if (cp.left < (that._helper ? co.left : 0)) {
3302
			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3303
			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
3304
			that.position.left = o.helper ? co.left : 0;
3305
		}
3306
 
3307
		if (cp.top < (that._helper ? co.top : 0)) {
3308
			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3309
			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
3310
			that.position.top = that._helper ? co.top : 0;
3311
		}
3312
 
3313
		that.offset.left = that.parentData.left+that.position.left;
3314
		that.offset.top = that.parentData.top+that.position.top;
3315
 
3316
		var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
3317
					hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3318
 
3319
		var isParent = that.containerElement.get(0) == that.element.parent().get(0),
3320
			isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
3321
 
3322
		if(isParent && isOffsetRelative) woset -= that.parentData.left;
3323
 
3324
		if (woset + that.size.width >= that.parentData.width) {
3325
			that.size.width = that.parentData.width - woset;
3326
			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
3327
		}
3328
 
3329
		if (hoset + that.size.height >= that.parentData.height) {
3330
			that.size.height = that.parentData.height - hoset;
3331
			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
3332
		}
3333
	},
3334
 
3335
	stop: function(event, ui){
3336
		var that = $(this).data("resizable"), o = that.options, cp = that.position,
3337
				co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
3338
 
3339
		var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
3340
 
3341
		if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
3342
			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3343
 
3344
		if (that._helper && !o.animate && (/static/).test(ce.css('position')))
3345
			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3346
 
3347
	}
3348
});
3349
 
3350
$.ui.plugin.add("resizable", "ghost", {
3351
 
3352
	start: function(event, ui) {
3353
 
3354
		var that = $(this).data("resizable"), o = that.options, cs = that.size;
3355
 
3356
		that.ghost = that.originalElement.clone();
3357
		that.ghost
3358
			.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3359
			.addClass('ui-resizable-ghost')
3360
			.addClass(typeof o.ghost == 'string' ? o.ghost : '');
3361
 
3362
		that.ghost.appendTo(that.helper);
3363
 
3364
	},
3365
 
3366
	resize: function(event, ui){
3367
		var that = $(this).data("resizable"), o = that.options;
3368
		if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
3369
	},
3370
 
3371
	stop: function(event, ui){
3372
		var that = $(this).data("resizable"), o = that.options;
3373
		if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
3374
	}
3375
 
3376
});
3377
 
3378
$.ui.plugin.add("resizable", "grid", {
3379
 
3380
	resize: function(event, ui) {
3381
		var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
3382
		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
3383
		var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
3384
 
3385
		if (/^(se|s|e)$/.test(a)) {
3386
			that.size.width = os.width + ox;
3387
			that.size.height = os.height + oy;
3388
		}
3389
		else if (/^(ne)$/.test(a)) {
3390
			that.size.width = os.width + ox;
3391
			that.size.height = os.height + oy;
3392
			that.position.top = op.top - oy;
3393
		}
3394
		else if (/^(sw)$/.test(a)) {
3395
			that.size.width = os.width + ox;
3396
			that.size.height = os.height + oy;
3397
			that.position.left = op.left - ox;
3398
		}
3399
		else {
3400
			that.size.width = os.width + ox;
3401
			that.size.height = os.height + oy;
3402
			that.position.top = op.top - oy;
3403
			that.position.left = op.left - ox;
3404
		}
3405
	}
3406
 
3407
});
3408
 
3409
var num = function(v) {
3410
	return parseInt(v, 10) || 0;
3411
};
3412
 
3413
var isNumber = function(value) {
3414
	return !isNaN(parseInt(value, 10));
3415
};
3416
 
3417
})(jQuery);
3418
(function( $, undefined ) {
3419
 
3420
$.widget("ui.selectable", $.ui.mouse, {
3421
	version: "1.9.2",
3422
	options: {
3423
		appendTo: 'body',
3424
		autoRefresh: true,
3425
		distance: 0,
3426
		filter: '*',
3427
		tolerance: 'touch'
3428
	},
3429
	_create: function() {
3430
		var that = this;
3431
 
3432
		this.element.addClass("ui-selectable");
3433
 
3434
		this.dragged = false;
3435
 
3436
		// cache selectee children based on filter
3437
		var selectees;
3438
		this.refresh = function() {
3439
			selectees = $(that.options.filter, that.element[0]);
3440
			selectees.addClass("ui-selectee");
3441
			selectees.each(function() {
3442
				var $this = $(this);
3443
				var pos = $this.offset();
3444
				$.data(this, "selectable-item", {
3445
					element: this,
3446
					$element: $this,
3447
					left: pos.left,
3448
					top: pos.top,
3449
					right: pos.left + $this.outerWidth(),
3450
					bottom: pos.top + $this.outerHeight(),
3451
					startselected: false,
3452
					selected: $this.hasClass('ui-selected'),
3453
					selecting: $this.hasClass('ui-selecting'),
3454
					unselecting: $this.hasClass('ui-unselecting')
3455
				});
3456
			});
3457
		};
3458
		this.refresh();
3459
 
3460
		this.selectees = selectees.addClass("ui-selectee");
3461
 
3462
		this._mouseInit();
3463
 
3464
		this.helper = $("<div class='ui-selectable-helper'></div>");
3465
	},
3466
 
3467
	_destroy: function() {
3468
		this.selectees
3469
			.removeClass("ui-selectee")
3470
			.removeData("selectable-item");
3471
		this.element
3472
			.removeClass("ui-selectable ui-selectable-disabled");
3473
		this._mouseDestroy();
3474
	},
3475
 
3476
	_mouseStart: function(event) {
3477
		var that = this;
3478
 
3479
		this.opos = [event.pageX, event.pageY];
3480
 
3481
		if (this.options.disabled)
3482
			return;
3483
 
3484
		var options = this.options;
3485
 
3486
		this.selectees = $(options.filter, this.element[0]);
3487
 
3488
		this._trigger("start", event);
3489
 
3490
		$(options.appendTo).append(this.helper);
3491
		// position helper (lasso)
3492
		this.helper.css({
3493
			"left": event.clientX,
3494
			"top": event.clientY,
3495
			"width": 0,
3496
			"height": 0
3497
		});
3498
 
3499
		if (options.autoRefresh) {
3500
			this.refresh();
3501
		}
3502
 
3503
		this.selectees.filter('.ui-selected').each(function() {
3504
			var selectee = $.data(this, "selectable-item");
3505
			selectee.startselected = true;
3506
			if (!event.metaKey && !event.ctrlKey) {
3507
				selectee.$element.removeClass('ui-selected');
3508
				selectee.selected = false;
3509
				selectee.$element.addClass('ui-unselecting');
3510
				selectee.unselecting = true;
3511
				// selectable UNSELECTING callback
3512
				that._trigger("unselecting", event, {
3513
					unselecting: selectee.element
3514
				});
3515
			}
3516
		});
3517
 
3518
		$(event.target).parents().andSelf().each(function() {
3519
			var selectee = $.data(this, "selectable-item");
3520
			if (selectee) {
3521
				var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
3522
				selectee.$element
3523
					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3524
					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3525
				selectee.unselecting = !doSelect;
3526
				selectee.selecting = doSelect;
3527
				selectee.selected = doSelect;
3528
				// selectable (UN)SELECTING callback
3529
				if (doSelect) {
3530
					that._trigger("selecting", event, {
3531
						selecting: selectee.element
3532
					});
3533
				} else {
3534
					that._trigger("unselecting", event, {
3535
						unselecting: selectee.element
3536
					});
3537
				}
3538
				return false;
3539
			}
3540
		});
3541
 
3542
	},
3543
 
3544
	_mouseDrag: function(event) {
3545
		var that = this;
3546
		this.dragged = true;
3547
 
3548
		if (this.options.disabled)
3549
			return;
3550
 
3551
		var options = this.options;
3552
 
3553
		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3554
		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3555
		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3556
		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3557
 
3558
		this.selectees.each(function() {
3559
			var selectee = $.data(this, "selectable-item");
3560
			//prevent helper from being selected if appendTo: selectable
3561
			if (!selectee || selectee.element == that.element[0])
3562
				return;
3563
			var hit = false;
3564
			if (options.tolerance == 'touch') {
3565
				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3566
			} else if (options.tolerance == 'fit') {
3567
				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3568
			}
3569
 
3570
			if (hit) {
3571
				// SELECT
3572
				if (selectee.selected) {
3573
					selectee.$element.removeClass('ui-selected');
3574
					selectee.selected = false;
3575
				}
3576
				if (selectee.unselecting) {
3577
					selectee.$element.removeClass('ui-unselecting');
3578
					selectee.unselecting = false;
3579
				}
3580
				if (!selectee.selecting) {
3581
					selectee.$element.addClass('ui-selecting');
3582
					selectee.selecting = true;
3583
					// selectable SELECTING callback
3584
					that._trigger("selecting", event, {
3585
						selecting: selectee.element
3586
					});
3587
				}
3588
			} else {
3589
				// UNSELECT
3590
				if (selectee.selecting) {
3591
					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3592
						selectee.$element.removeClass('ui-selecting');
3593
						selectee.selecting = false;
3594
						selectee.$element.addClass('ui-selected');
3595
						selectee.selected = true;
3596
					} else {
3597
						selectee.$element.removeClass('ui-selecting');
3598
						selectee.selecting = false;
3599
						if (selectee.startselected) {
3600
							selectee.$element.addClass('ui-unselecting');
3601
							selectee.unselecting = true;
3602
						}
3603
						// selectable UNSELECTING callback
3604
						that._trigger("unselecting", event, {
3605
							unselecting: selectee.element
3606
						});
3607
					}
3608
				}
3609
				if (selectee.selected) {
3610
					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3611
						selectee.$element.removeClass('ui-selected');
3612
						selectee.selected = false;
3613
 
3614
						selectee.$element.addClass('ui-unselecting');
3615
						selectee.unselecting = true;
3616
						// selectable UNSELECTING callback
3617
						that._trigger("unselecting", event, {
3618
							unselecting: selectee.element
3619
						});
3620
					}
3621
				}
3622
			}
3623
		});
3624
 
3625
		return false;
3626
	},
3627
 
3628
	_mouseStop: function(event) {
3629
		var that = this;
3630
 
3631
		this.dragged = false;
3632
 
3633
		var options = this.options;
3634
 
3635
		$('.ui-unselecting', this.element[0]).each(function() {
3636
			var selectee = $.data(this, "selectable-item");
3637
			selectee.$element.removeClass('ui-unselecting');
3638
			selectee.unselecting = false;
3639
			selectee.startselected = false;
3640
			that._trigger("unselected", event, {
3641
				unselected: selectee.element
3642
			});
3643
		});
3644
		$('.ui-selecting', this.element[0]).each(function() {
3645
			var selectee = $.data(this, "selectable-item");
3646
			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3647
			selectee.selecting = false;
3648
			selectee.selected = true;
3649
			selectee.startselected = true;
3650
			that._trigger("selected", event, {
3651
				selected: selectee.element
3652
			});
3653
		});
3654
		this._trigger("stop", event);
3655
 
3656
		this.helper.remove();
3657
 
3658
		return false;
3659
	}
3660
 
3661
});
3662
 
3663
})(jQuery);
3664
(function( $, undefined ) {
3665
 
3666
$.widget("ui.sortable", $.ui.mouse, {
3667
	version: "1.9.2",
3668
	widgetEventPrefix: "sort",
3669
	ready: false,
3670
	options: {
3671
		appendTo: "parent",
3672
		axis: false,
3673
		connectWith: false,
3674
		containment: false,
3675
		cursor: 'auto',
3676
		cursorAt: false,
3677
		dropOnEmpty: true,
3678
		forcePlaceholderSize: false,
3679
		forceHelperSize: false,
3680
		grid: false,
3681
		handle: false,
3682
		helper: "original",
3683
		items: '> *',
3684
		opacity: false,
3685
		placeholder: false,
3686
		revert: false,
3687
		scroll: true,
3688
		scrollSensitivity: 20,
3689
		scrollSpeed: 20,
3690
		scope: "default",
3691
		tolerance: "intersect",
3692
		zIndex: 1000
3693
	},
3694
	_create: function() {
3695
 
3696
		var o = this.options;
3697
		this.containerCache = {};
3698
		this.element.addClass("ui-sortable");
3699
 
3700
		//Get the items
3701
		this.refresh();
3702
 
3703
		//Let's determine if the items are being displayed horizontally
3704
		this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
3705
 
3706
		//Let's determine the parent's offset
3707
		this.offset = this.element.offset();
3708
 
3709
		//Initialize mouse events for interaction
3710
		this._mouseInit();
3711
 
3712
		//We're ready to go
3713
		this.ready = true
3714
 
3715
	},
3716
 
3717
	_destroy: function() {
3718
		this.element
3719
			.removeClass("ui-sortable ui-sortable-disabled");
3720
		this._mouseDestroy();
3721
 
3722
		for ( var i = this.items.length - 1; i >= 0; i-- )
3723
			this.items[i].item.removeData(this.widgetName + "-item");
3724
 
3725
		return this;
3726
	},
3727
 
3728
	_setOption: function(key, value){
3729
		if ( key === "disabled" ) {
3730
			this.options[ key ] = value;
3731
 
3732
			this.widget().toggleClass( "ui-sortable-disabled", !!value );
3733
		} else {
3734
			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3735
			$.Widget.prototype._setOption.apply(this, arguments);
3736
		}
3737
	},
3738
 
3739
	_mouseCapture: function(event, overrideHandle) {
3740
		var that = this;
3741
 
3742
		if (this.reverting) {
3743
			return false;
3744
		}
3745
 
3746
		if(this.options.disabled || this.options.type == 'static') return false;
3747
 
3748
		//We have to refresh the items data once first
3749
		this._refreshItems(event);
3750
 
3751
		//Find out if the clicked node (or one of its parents) is a actual item in this.items
3752
		var currentItem = null, nodes = $(event.target).parents().each(function() {
3753
			if($.data(this, that.widgetName + '-item') == that) {
3754
				currentItem = $(this);
3755
				return false;
3756
			}
3757
		});
3758
		if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
3759
 
3760
		if(!currentItem) return false;
3761
		if(this.options.handle && !overrideHandle) {
3762
			var validHandle = false;
3763
 
3764
			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3765
			if(!validHandle) return false;
3766
		}
3767
 
3768
		this.currentItem = currentItem;
3769
		this._removeCurrentsFromItems();
3770
		return true;
3771
 
3772
	},
3773
 
3774
	_mouseStart: function(event, overrideHandle, noActivation) {
3775
 
3776
		var o = this.options;
3777
		this.currentContainer = this;
3778
 
3779
		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3780
		this.refreshPositions();
3781
 
3782
		//Create and append the visible helper
3783
		this.helper = this._createHelper(event);
3784
 
3785
		//Cache the helper size
3786
		this._cacheHelperProportions();
3787
 
3788
		/*
3789
		 * - Position generation -
3790
		 * This block generates everything position related - it's the core of draggables.
3791
		 */
3792
 
3793
		//Cache the margins of the original element
3794
		this._cacheMargins();
3795
 
3796
		//Get the next scrolling parent
3797
		this.scrollParent = this.helper.scrollParent();
3798
 
3799
		//The element's absolute position on the page minus margins
3800
		this.offset = this.currentItem.offset();
3801
		this.offset = {
3802
			top: this.offset.top - this.margins.top,
3803
			left: this.offset.left - this.margins.left
3804
		};
3805
 
3806
		$.extend(this.offset, {
3807
			click: { //Where the click happened, relative to the element
3808
				left: event.pageX - this.offset.left,
3809
				top: event.pageY - this.offset.top
3810
			},
3811
			parent: this._getParentOffset(),
3812
			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3813
		});
3814
 
3815
		// Only after we got the offset, we can change the helper's position to absolute
3816
		// TODO: Still need to figure out a way to make relative sorting possible
3817
		this.helper.css("position", "absolute");
3818
		this.cssPosition = this.helper.css("position");
3819
 
3820
		//Generate the original position
3821
		this.originalPosition = this._generatePosition(event);
3822
		this.originalPageX = event.pageX;
3823
		this.originalPageY = event.pageY;
3824
 
3825
		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3826
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3827
 
3828
		//Cache the former DOM position
3829
		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3830
 
3831
		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
3832
		if(this.helper[0] != this.currentItem[0]) {
3833
			this.currentItem.hide();
3834
		}
3835
 
3836
		//Create the placeholder
3837
		this._createPlaceholder();
3838
 
3839
		//Set a containment if given in the options
3840
		if(o.containment)
3841
			this._setContainment();
3842
 
3843
		if(o.cursor) { // cursor option
3844
			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3845
			$('body').css("cursor", o.cursor);
3846
		}
3847
 
3848
		if(o.opacity) { // opacity option
3849
			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3850
			this.helper.css("opacity", o.opacity);
3851
		}
3852
 
3853
		if(o.zIndex) { // zIndex option
3854
			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3855
			this.helper.css("zIndex", o.zIndex);
3856
		}
3857
 
3858
		//Prepare scrolling
3859
		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3860
			this.overflowOffset = this.scrollParent.offset();
3861
 
3862
		//Call callbacks
3863
		this._trigger("start", event, this._uiHash());
3864
 
3865
		//Recache the helper size
3866
		if(!this._preserveHelperProportions)
3867
			this._cacheHelperProportions();
3868
 
3869
 
3870
		//Post 'activate' events to possible containers
3871
		if(!noActivation) {
3872
			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
3873
		}
3874
 
3875
		//Prepare possible droppables
3876
		if($.ui.ddmanager)
3877
			$.ui.ddmanager.current = this;
3878
 
3879
		if ($.ui.ddmanager && !o.dropBehaviour)
3880
			$.ui.ddmanager.prepareOffsets(this, event);
3881
 
3882
		this.dragging = true;
3883
 
3884
		this.helper.addClass("ui-sortable-helper");
3885
		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3886
		return true;
3887
 
3888
	},
3889
 
3890
	_mouseDrag: function(event) {
3891
 
3892
		//Compute the helpers position
3893
		this.position = this._generatePosition(event);
3894
		this.positionAbs = this._convertPositionTo("absolute");
3895
 
3896
		if (!this.lastPositionAbs) {
3897
			this.lastPositionAbs = this.positionAbs;
3898
		}
3899
 
3900
		//Do scrolling
3901
		if(this.options.scroll) {
3902
			var o = this.options, scrolled = false;
3903
			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3904
 
3905
				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3906
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3907
				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3908
					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3909
 
3910
				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3911
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3912
				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3913
					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3914
 
3915
			} else {
3916
 
3917
				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3918
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3919
				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3920
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3921
 
3922
				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3923
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3924
				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3925
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3926
 
3927
			}
3928
 
3929
			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3930
				$.ui.ddmanager.prepareOffsets(this, event);
3931
		}
3932
 
3933
		//Regenerate the absolute position used for position checks
3934
		this.positionAbs = this._convertPositionTo("absolute");
3935
 
3936
		//Set the helper position
3937
		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3938
		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3939
 
3940
		//Rearrange
3941
		for (var i = this.items.length - 1; i >= 0; i--) {
3942
 
3943
			//Cache variables and intersection, continue if no intersection
3944
			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3945
			if (!intersection) continue;
3946
 
3947
			// Only put the placeholder inside the current Container, skip all
3948
			// items form other containers. This works because when moving
3949
			// an item from one container to another the
3950
			// currentContainer is switched before the placeholder is moved.
3951
			//
3952
			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
3953
			// beetween the outer and inner container.
3954
			if (item.instance !== this.currentContainer) continue;
3955
 
3956
			if (itemElement != this.currentItem[0] //cannot intersect with itself
3957
				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3958
				&&	!$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3959
				&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
3960
				//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3961
			) {
3962
 
3963
				this.direction = intersection == 1 ? "down" : "up";
3964
 
3965
				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3966
					this._rearrange(event, item);
3967
				} else {
3968
					break;
3969
				}
3970
 
3971
				this._trigger("change", event, this._uiHash());
3972
				break;
3973
			}
3974
		}
3975
 
3976
		//Post events to containers
3977
		this._contactContainers(event);
3978
 
3979
		//Interconnect with droppables
3980
		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3981
 
3982
		//Call callbacks
3983
		this._trigger('sort', event, this._uiHash());
3984
 
3985
		this.lastPositionAbs = this.positionAbs;
3986
		return false;
3987
 
3988
	},
3989
 
3990
	_mouseStop: function(event, noPropagation) {
3991
 
3992
		if(!event) return;
3993
 
3994
		//If we are using droppables, inform the manager about the drop
3995
		if ($.ui.ddmanager && !this.options.dropBehaviour)
3996
			$.ui.ddmanager.drop(this, event);
3997
 
3998
		if(this.options.revert) {
3999
			var that = this;
4000
			var cur = this.placeholder.offset();
4001
 
4002
			this.reverting = true;
4003
 
4004
			$(this.helper).animate({
4005
				left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
4006
				top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
4007
			}, parseInt(this.options.revert, 10) || 500, function() {
4008
				that._clear(event);
4009
			});
4010
		} else {
4011
			this._clear(event, noPropagation);
4012
		}
4013
 
4014
		return false;
4015
 
4016
	},
4017
 
4018
	cancel: function() {
4019
 
4020
		if(this.dragging) {
4021
 
4022
			this._mouseUp({ target: null });
4023
 
4024
			if(this.options.helper == "original")
4025
				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4026
			else
4027
				this.currentItem.show();
4028
 
4029
			//Post deactivating events to containers
4030
			for (var i = this.containers.length - 1; i >= 0; i--){
4031
				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4032
				if(this.containers[i].containerCache.over) {
4033
					this.containers[i]._trigger("out", null, this._uiHash(this));
4034
					this.containers[i].containerCache.over = 0;
4035
				}
4036
			}
4037
 
4038
		}
4039
 
4040
		if (this.placeholder) {
4041
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4042
			if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4043
			if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
4044
 
4045
			$.extend(this, {
4046
				helper: null,
4047
				dragging: false,
4048
				reverting: false,
4049
				_noFinalSort: null
4050
			});
4051
 
4052
			if(this.domPosition.prev) {
4053
				$(this.domPosition.prev).after(this.currentItem);
4054
			} else {
4055
				$(this.domPosition.parent).prepend(this.currentItem);
4056
			}
4057
		}
4058
 
4059
		return this;
4060
 
4061
	},
4062
 
4063
	serialize: function(o) {
4064
 
4065
		var items = this._getItemsAsjQuery(o && o.connected);
4066
		var str = []; o = o || {};
4067
 
4068
		$(items).each(function() {
4069
			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
4070
			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
4071
		});
4072
 
4073
		if(!str.length && o.key) {
4074
			str.push(o.key + '=');
4075
		}
4076
 
4077
		return str.join('&');
4078
 
4079
	},
4080
 
4081
	toArray: function(o) {
4082
 
4083
		var items = this._getItemsAsjQuery(o && o.connected);
4084
		var ret = []; o = o || {};
4085
 
4086
		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
4087
		return ret;
4088
 
4089
	},
4090
 
4091
	/* Be careful with the following core functions */
4092
	_intersectsWith: function(item) {
4093
 
4094
		var x1 = this.positionAbs.left,
4095
			x2 = x1 + this.helperProportions.width,
4096
			y1 = this.positionAbs.top,
4097
			y2 = y1 + this.helperProportions.height;
4098
 
4099
		var l = item.left,
4100
			r = l + item.width,
4101
			t = item.top,
4102
			b = t + item.height;
4103
 
4104
		var dyClick = this.offset.click.top,
4105
			dxClick = this.offset.click.left;
4106
 
4107
		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
4108
 
4109
		if(	   this.options.tolerance == "pointer"
4110
			|| this.options.forcePointerForContainers
4111
			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
4112
		) {
4113
			return isOverElement;
4114
		} else {
4115
 
4116
			return (l < x1 + (this.helperProportions.width / 2) // Right Half
4117
				&& x2 - (this.helperProportions.width / 2) < r // Left Half
4118
				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
4119
				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
4120
 
4121
		}
4122
	},
4123
 
4124
	_intersectsWithPointer: function(item) {
4125
 
4126
		var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4127
			isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4128
			isOverElement = isOverElementHeight && isOverElementWidth,
4129
			verticalDirection = this._getDragVerticalDirection(),
4130
			horizontalDirection = this._getDragHorizontalDirection();
4131
 
4132
		if (!isOverElement)
4133
			return false;
4134
 
4135
		return this.floating ?
4136
			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
4137
			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
4138
 
4139
	},
4140
 
4141
	_intersectsWithSides: function(item) {
4142
 
4143
		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4144
			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4145
			verticalDirection = this._getDragVerticalDirection(),
4146
			horizontalDirection = this._getDragHorizontalDirection();
4147
 
4148
		if (this.floating && horizontalDirection) {
4149
			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
4150
		} else {
4151
			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
4152
		}
4153
 
4154
	},
4155
 
4156
	_getDragVerticalDirection: function() {
4157
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
4158
		return delta != 0 && (delta > 0 ? "down" : "up");
4159
	},
4160
 
4161
	_getDragHorizontalDirection: function() {
4162
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
4163
		return delta != 0 && (delta > 0 ? "right" : "left");
4164
	},
4165
 
4166
	refresh: function(event) {
4167
		this._refreshItems(event);
4168
		this.refreshPositions();
4169
		return this;
4170
	},
4171
 
4172
	_connectWith: function() {
4173
		var options = this.options;
4174
		return options.connectWith.constructor == String
4175
			? [options.connectWith]
4176
			: options.connectWith;
4177
	},
4178
 
4179
	_getItemsAsjQuery: function(connected) {
4180
 
4181
		var items = [];
4182
		var queries = [];
4183
		var connectWith = this._connectWith();
4184
 
4185
		if(connectWith && connected) {
4186
			for (var i = connectWith.length - 1; i >= 0; i--){
4187
				var cur = $(connectWith[i]);
4188
				for (var j = cur.length - 1; j >= 0; j--){
4189
					var inst = $.data(cur[j], this.widgetName);
4190
					if(inst && inst != this && !inst.options.disabled) {
4191
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
4192
					}
4193
				};
4194
			};
4195
		}
4196
 
4197
		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
4198
 
4199
		for (var i = queries.length - 1; i >= 0; i--){
4200
			queries[i][0].each(function() {
4201
				items.push(this);
4202
			});
4203
		};
4204
 
4205
		return $(items);
4206
 
4207
	},
4208
 
4209
	_removeCurrentsFromItems: function() {
4210
 
4211
		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4212
 
4213
		this.items = $.grep(this.items, function (item) {
4214
			for (var j=0; j < list.length; j++) {
4215
				if(list[j] == item.item[0])
4216
					return false;
4217
			};
4218
			return true;
4219
		});
4220
 
4221
	},
4222
 
4223
	_refreshItems: function(event) {
4224
 
4225
		this.items = [];
4226
		this.containers = [this];
4227
		var items = this.items;
4228
		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
4229
		var connectWith = this._connectWith();
4230
 
4231
		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4232
			for (var i = connectWith.length - 1; i >= 0; i--){
4233
				var cur = $(connectWith[i]);
4234
				for (var j = cur.length - 1; j >= 0; j--){
4235
					var inst = $.data(cur[j], this.widgetName);
4236
					if(inst && inst != this && !inst.options.disabled) {
4237
						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4238
						this.containers.push(inst);
4239
					}
4240
				};
4241
			};
4242
		}
4243
 
4244
		for (var i = queries.length - 1; i >= 0; i--) {
4245
			var targetData = queries[i][1];
4246
			var _queries = queries[i][0];
4247
 
4248
			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4249
				var item = $(_queries[j]);
4250
 
4251
				item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
4252
 
4253
				items.push({
4254
					item: item,
4255
					instance: targetData,
4256
					width: 0, height: 0,
4257
					left: 0, top: 0
4258
				});
4259
			};
4260
		};
4261
 
4262
	},
4263
 
4264
	refreshPositions: function(fast) {
4265
 
4266
		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4267
		if(this.offsetParent && this.helper) {
4268
			this.offset.parent = this._getParentOffset();
4269
		}
4270
 
4271
		for (var i = this.items.length - 1; i >= 0; i--){
4272
			var item = this.items[i];
4273
 
4274
			//We ignore calculating positions of all connected containers when we're not over them
4275
			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
4276
				continue;
4277
 
4278
			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4279
 
4280
			if (!fast) {
4281
				item.width = t.outerWidth();
4282
				item.height = t.outerHeight();
4283
			}
4284
 
4285
			var p = t.offset();
4286
			item.left = p.left;
4287
			item.top = p.top;
4288
		};
4289
 
4290
		if(this.options.custom && this.options.custom.refreshContainers) {
4291
			this.options.custom.refreshContainers.call(this);
4292
		} else {
4293
			for (var i = this.containers.length - 1; i >= 0; i--){
4294
				var p = this.containers[i].element.offset();
4295
				this.containers[i].containerCache.left = p.left;
4296
				this.containers[i].containerCache.top = p.top;
4297
				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
4298
				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4299
			};
4300
		}
4301
 
4302
		return this;
4303
	},
4304
 
4305
	_createPlaceholder: function(that) {
4306
		that = that || this;
4307
		var o = that.options;
4308
 
4309
		if(!o.placeholder || o.placeholder.constructor == String) {
4310
			var className = o.placeholder;
4311
			o.placeholder = {
4312
				element: function() {
4313
 
4314
					var el = $(document.createElement(that.currentItem[0].nodeName))
4315
						.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4316
						.removeClass("ui-sortable-helper")[0];
4317
 
4318
					if(!className)
4319
						el.style.visibility = "hidden";
4320
 
4321
					return el;
4322
				},
4323
				update: function(container, p) {
4324
 
4325
					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4326
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4327
					if(className && !o.forcePlaceholderSize) return;
4328
 
4329
					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
4330
					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
4331
					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
4332
				}
4333
			};
4334
		}
4335
 
4336
		//Create the placeholder
4337
		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4338
 
4339
		//Append it after the actual current item
4340
		that.currentItem.after(that.placeholder);
4341
 
4342
		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4343
		o.placeholder.update(that, that.placeholder);
4344
 
4345
	},
4346
 
4347
	_contactContainers: function(event) {
4348
 
4349
		// get innermost container that intersects with item
4350
		var innermostContainer = null, innermostIndex = null;
4351
 
4352
 
4353
		for (var i = this.containers.length - 1; i >= 0; i--){
4354
 
4355
			// never consider a container that's located within the item itself
4356
			if($.contains(this.currentItem[0], this.containers[i].element[0]))
4357
				continue;
4358
 
4359
			if(this._intersectsWith(this.containers[i].containerCache)) {
4360
 
4361
				// if we've already found a container and it's more "inner" than this, then continue
4362
				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
4363
					continue;
4364
 
4365
				innermostContainer = this.containers[i];
4366
				innermostIndex = i;
4367
 
4368
			} else {
4369
				// container doesn't intersect. trigger "out" event if necessary
4370
				if(this.containers[i].containerCache.over) {
4371
					this.containers[i]._trigger("out", event, this._uiHash(this));
4372
					this.containers[i].containerCache.over = 0;
4373
				}
4374
			}
4375
 
4376
		}
4377
 
4378
		// if no intersecting containers found, return
4379
		if(!innermostContainer) return;
4380
 
4381
		// move the item into the container if it's not there already
4382
		if(this.containers.length === 1) {
4383
			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4384
			this.containers[innermostIndex].containerCache.over = 1;
4385
		} else {
4386
 
4387
			//When entering a new container, we will find the item with the least distance and append our item near it
4388
			var dist = 10000; var itemWithLeastDistance = null;
4389
			var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
4390
			var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
4391
			var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4392
			for (var j = this.items.length - 1; j >= 0; j--) {
4393
				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
4394
				if(this.items[j].item[0] == this.currentItem[0]) continue;
4395
				var cur = this.items[j].item.offset()[posProperty];
4396
				var nearBottom = false;
4397
				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4398
					nearBottom = true;
4399
					cur += this.items[j][sizeProperty];
4400
				}
4401
 
4402
				if(Math.abs(cur - base) < dist) {
4403
					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4404
					this.direction = nearBottom ? "up": "down";
4405
				}
4406
			}
4407
 
4408
			if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
4409
				return;
4410
 
4411
			this.currentContainer = this.containers[innermostIndex];
4412
			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4413
			this._trigger("change", event, this._uiHash());
4414
			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4415
 
4416
			//Update the placeholder
4417
			this.options.placeholder.update(this.currentContainer, this.placeholder);
4418
 
4419
			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4420
			this.containers[innermostIndex].containerCache.over = 1;
4421
		}
4422
 
4423
 
4424
	},
4425
 
4426
	_createHelper: function(event) {
4427
 
4428
		var o = this.options;
4429
		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
4430
 
4431
		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
4432
			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4433
 
4434
		if(helper[0] == this.currentItem[0])
4435
			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
4436
 
4437
		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
4438
		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
4439
 
4440
		return helper;
4441
 
4442
	},
4443
 
4444
	_adjustOffsetFromHelper: function(obj) {
4445
		if (typeof obj == 'string') {
4446
			obj = obj.split(' ');
4447
		}
4448
		if ($.isArray(obj)) {
4449
			obj = {left: +obj[0], top: +obj[1] || 0};
4450
		}
4451
		if ('left' in obj) {
4452
			this.offset.click.left = obj.left + this.margins.left;
4453
		}
4454
		if ('right' in obj) {
4455
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4456
		}
4457
		if ('top' in obj) {
4458
			this.offset.click.top = obj.top + this.margins.top;
4459
		}
4460
		if ('bottom' in obj) {
4461
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4462
		}
4463
	},
4464
 
4465
	_getParentOffset: function() {
4466
 
4467
 
4468
		//Get the offsetParent and cache its position
4469
		this.offsetParent = this.helper.offsetParent();
4470
		var po = this.offsetParent.offset();
4471
 
4472
		// This is a special case where we need to modify a offset calculated on start, since the following happened:
4473
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4474
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4475
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4476
		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4477
			po.left += this.scrollParent.scrollLeft();
4478
			po.top += this.scrollParent.scrollTop();
4479
		}
4480
 
4481
		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4482
		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
4483
			po = { top: 0, left: 0 };
4484
 
4485
		return {
4486
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4487
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4488
		};
4489
 
4490
	},
4491
 
4492
	_getRelativeOffset: function() {
4493
 
4494
		if(this.cssPosition == "relative") {
4495
			var p = this.currentItem.position();
4496
			return {
4497
				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4498
				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4499
			};
4500
		} else {
4501
			return { top: 0, left: 0 };
4502
		}
4503
 
4504
	},
4505
 
4506
	_cacheMargins: function() {
4507
		this.margins = {
4508
			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4509
			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4510
		};
4511
	},
4512
 
4513
	_cacheHelperProportions: function() {
4514
		this.helperProportions = {
4515
			width: this.helper.outerWidth(),
4516
			height: this.helper.outerHeight()
4517
		};
4518
	},
4519
 
4520
	_setContainment: function() {
4521
 
4522
		var o = this.options;
4523
		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4524
		if(o.containment == 'document' || o.containment == 'window') this.containment = [
4525
 
4526
 
4527
			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4528
			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4529
		];
4530
 
4531
		if(!(/^(document|window|parent)$/).test(o.containment)) {
4532
			var ce = $(o.containment)[0];
4533
			var co = $(o.containment).offset();
4534
			var over = ($(ce).css("overflow") != 'hidden');
4535
 
4536
			this.containment = [
4537
				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4538
				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4539
				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
4540
				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4541
			];
4542
		}
4543
 
4544
	},
4545
 
4546
	_convertPositionTo: function(d, pos) {
4547
 
4548
		if(!pos) pos = this.position;
4549
		var mod = d == "absolute" ? 1 : -1;
4550
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4551
 
4552
		return {
4553
			top: (
4554
				pos.top																	// The absolute mouse position
4555
				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4556
				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
4557
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4558
			),
4559
			left: (
4560
				pos.left																// The absolute mouse position
4561
				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4562
				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
4563
				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4564
			)
4565
		};
4566
 
4567
	},
4568
 
4569
	_generatePosition: function(event) {
4570
 
4571
		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4572
 
4573
		// This is another very weird special case that only happens for relative elements:
4574
		// 1. If the css position is relative
4575
		// 2. and the scroll parent is the document or similar to the offset parent
4576
		// we have to refresh the relative offset during the scroll so there are no jumps
4577
		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4578
			this.offset.relative = this._getRelativeOffset();
4579
		}
4580
 
4581
		var pageX = event.pageX;
4582
		var pageY = event.pageY;
4583
 
4584
		/*
4585
		 * - Position constraining -
4586
		 * Constrain the position to a mix of grid, containment.
4587
		 */
4588
 
4589
		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4590
 
4591
			if(this.containment) {
4592
				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4593
				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4594
				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4595
				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4596
			}
4597
 
4598
			if(o.grid) {
4599
				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4600
				pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
4601
 
4602
				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4603
				pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
4604
			}
4605
 
4606
		}
4607
 
4608
		return {
4609
			top: (
4610
				pageY																// The absolute mouse position
4611
				- this.offset.click.top													// Click offset (relative to the element)
4612
				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
4613
				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
4614
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4615
			),
4616
			left: (
4617
				pageX																// The absolute mouse position
4618
				- this.offset.click.left												// Click offset (relative to the element)
4619
				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
4620
				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
4621
				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4622
			)
4623
		};
4624
 
4625
	},
4626
 
4627
	_rearrange: function(event, i, a, hardRefresh) {
4628
 
4629
		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
4630
 
4631
		//Various things done here to improve the performance:
4632
		// 1. we create a setTimeout, that calls refreshPositions
4633
		// 2. on the instance, we have a counter variable, that get's higher after every append
4634
		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4635
		// 4. this lets only the last addition to the timeout stack through
4636
		this.counter = this.counter ? ++this.counter : 1;
4637
		var counter = this.counter;
4638
 
4639
		this._delay(function() {
4640
			if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4641
		});
4642
 
4643
	},
4644
 
4645
	_clear: function(event, noPropagation) {
4646
 
4647
		this.reverting = false;
4648
		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
4649
		// everything else normalized again
4650
		var delayedTriggers = [];
4651
 
4652
		// We first have to update the dom position of the actual currentItem
4653
		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4654
		if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4655
		this._noFinalSort = null;
4656
 
4657
		if(this.helper[0] == this.currentItem[0]) {
4658
			for(var i in this._storedCSS) {
4659
				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4660
			}
4661
			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4662
		} else {
4663
			this.currentItem.show();
4664
		}
4665
 
4666
		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4667
		if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4668
 
4669
		// Check if the items Container has Changed and trigger appropriate
4670
		// events.
4671
		if (this !== this.currentContainer) {
4672
			if(!noPropagation) {
4673
				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4674
				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
4675
				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
4676
			}
4677
		}
4678
 
4679
 
4680
		//Post events to containers
4681
		for (var i = this.containers.length - 1; i >= 0; i--){
4682
			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4683
			if(this.containers[i].containerCache.over) {
4684
				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4685
				this.containers[i].containerCache.over = 0;
4686
			}
4687
		}
4688
 
4689
		//Do what was originally in plugins
4690
		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4691
		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4692
		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4693
 
4694
		this.dragging = false;
4695
		if(this.cancelHelperRemoval) {
4696
			if(!noPropagation) {
4697
				this._trigger("beforeStop", event, this._uiHash());
4698
				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4699
				this._trigger("stop", event, this._uiHash());
4700
			}
4701
 
4702
			this.fromOutside = false;
4703
			return false;
4704
		}
4705
 
4706
		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4707
 
4708
		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4709
		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4710
 
4711
		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4712
 
4713
		if(!noPropagation) {
4714
			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4715
			this._trigger("stop", event, this._uiHash());
4716
		}
4717
 
4718
		this.fromOutside = false;
4719
		return true;
4720
 
4721
	},
4722
 
4723
	_trigger: function() {
4724
		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4725
			this.cancel();
4726
		}
4727
	},
4728
 
4729
	_uiHash: function(_inst) {
4730
		var inst = _inst || this;
4731
		return {
4732
			helper: inst.helper,
4733
			placeholder: inst.placeholder || $([]),
4734
			position: inst.position,
4735
			originalPosition: inst.originalPosition,
4736
			offset: inst.positionAbs,
4737
			item: inst.currentItem,
4738
			sender: _inst ? _inst.element : null
4739
		};
4740
	}
4741
 
4742
});
4743
 
4744
})(jQuery);
4745
(function( $, undefined ) {
4746
 
4747
var uid = 0,
4748
	hideProps = {},
4749
	showProps = {};
4750
 
4751
hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
4752
	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
4753
showProps.height = showProps.paddingTop = showProps.paddingBottom =
4754
	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
4755
 
4756
$.widget( "ui.accordion", {
4757
	version: "1.9.2",
4758
	options: {
4759
		active: 0,
4760
		animate: {},
4761
		collapsible: false,
4762
		event: "click",
4763
		header: "> li > :first-child,> :not(li):even",
4764
		heightStyle: "auto",
4765
		icons: {
4766
			activeHeader: "ui-icon-triangle-1-s",
4767
			header: "ui-icon-triangle-1-e"
4768
		},
4769
 
4770
		// callbacks
4771
		activate: null,
4772
		beforeActivate: null
4773
	},
4774
 
4775
	_create: function() {
4776
		var accordionId = this.accordionId = "ui-accordion-" +
4777
				(this.element.attr( "id" ) || ++uid),
4778
			options = this.options;
4779
 
4780
		this.prevShow = this.prevHide = $();
4781
		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
4782
 
4783
		this.headers = this.element.find( options.header )
4784
			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
4785
		this._hoverable( this.headers );
4786
		this._focusable( this.headers );
4787
 
4788
		this.headers.next()
4789
			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
4790
			.hide();
4791
 
4792
		// don't allow collapsible: false and active: false / null
4793
		if ( !options.collapsible && (options.active === false || options.active == null) ) {
4794
			options.active = 0;
4795
		}
4796
		// handle negative values
4797
		if ( options.active < 0 ) {
4798
			options.active += this.headers.length;
4799
		}
4800
		this.active = this._findActive( options.active )
4801
			.addClass( "ui-accordion-header-active ui-state-active" )
4802
			.toggleClass( "ui-corner-all ui-corner-top" );
4803
		this.active.next()
4804
			.addClass( "ui-accordion-content-active" )
4805
			.show();
4806
 
4807
		this._createIcons();
4808
		this.refresh();
4809
 
4810
		// ARIA
4811
		this.element.attr( "role", "tablist" );
4812
 
4813
		this.headers
4814
			.attr( "role", "tab" )
4815
			.each(function( i ) {
4816
				var header = $( this ),
4817
					headerId = header.attr( "id" ),
4818
					panel = header.next(),
4819
					panelId = panel.attr( "id" );
4820
				if ( !headerId ) {
4821
					headerId = accordionId + "-header-" + i;
4822
					header.attr( "id", headerId );
4823
				}
4824
				if ( !panelId ) {
4825
					panelId = accordionId + "-panel-" + i;
4826
					panel.attr( "id", panelId );
4827
				}
4828
				header.attr( "aria-controls", panelId );
4829
				panel.attr( "aria-labelledby", headerId );
4830
			})
4831
			.next()
4832
				.attr( "role", "tabpanel" );
4833
 
4834
		this.headers
4835
			.not( this.active )
4836
			.attr({
4837
				"aria-selected": "false",
4838
				tabIndex: -1
4839
			})
4840
			.next()
4841
				.attr({
4842
					"aria-expanded": "false",
4843
					"aria-hidden": "true"
4844
				})
4845
				.hide();
4846
 
4847
		// make sure at least one header is in the tab order
4848
		if ( !this.active.length ) {
4849
			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4850
		} else {
4851
			this.active.attr({
4852
				"aria-selected": "true",
4853
				tabIndex: 0
4854
			})
4855
			.next()
4856
				.attr({
4857
					"aria-expanded": "true",
4858
					"aria-hidden": "false"
4859
				});
4860
		}
4861
 
4862
		this._on( this.headers, { keydown: "_keydown" });
4863
		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
4864
		this._setupEvents( options.event );
4865
	},
4866
 
4867
	_getCreateEventData: function() {
4868
		return {
4869
			header: this.active,
4870
			content: !this.active.length ? $() : this.active.next()
4871
		};
4872
	},
4873
 
4874
	_createIcons: function() {
4875
		var icons = this.options.icons;
4876
		if ( icons ) {
4877
			$( "<span>" )
4878
				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
4879
				.prependTo( this.headers );
4880
			this.active.children( ".ui-accordion-header-icon" )
4881
				.removeClass( icons.header )
4882
				.addClass( icons.activeHeader );
4883
			this.headers.addClass( "ui-accordion-icons" );
4884
		}
4885
	},
4886
 
4887
	_destroyIcons: function() {
4888
		this.headers
4889
			.removeClass( "ui-accordion-icons" )
4890
			.children( ".ui-accordion-header-icon" )
4891
				.remove();
4892
	},
4893
 
4894
	_destroy: function() {
4895
		var contents;
4896
 
4897
		// clean up main element
4898
		this.element
4899
			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
4900
			.removeAttr( "role" );
4901
 
4902
		// clean up headers
4903
		this.headers
4904
			.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" )
4905
			.removeAttr( "role" )
4906
			.removeAttr( "aria-selected" )
4907
			.removeAttr( "aria-controls" )
4908
			.removeAttr( "tabIndex" )
4909
			.each(function() {
4910
				if ( /^ui-accordion/.test( this.id ) ) {
4911
					this.removeAttribute( "id" );
4912
				}
4913
			});
4914
		this._destroyIcons();
4915
 
4916
		// clean up content panels
4917
		contents = this.headers.next()
4918
			.css( "display", "" )
4919
			.removeAttr( "role" )
4920
			.removeAttr( "aria-expanded" )
4921
			.removeAttr( "aria-hidden" )
4922
			.removeAttr( "aria-labelledby" )
4923
			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
4924
			.each(function() {
4925
				if ( /^ui-accordion/.test( this.id ) ) {
4926
					this.removeAttribute( "id" );
4927
				}
4928
			});
4929
		if ( this.options.heightStyle !== "content" ) {
4930
			contents.css( "height", "" );
4931
		}
4932
	},
4933
 
4934
	_setOption: function( key, value ) {
4935
		if ( key === "active" ) {
4936
			// _activate() will handle invalid values and update this.options
4937
			this._activate( value );
4938
			return;
4939
		}
4940
 
4941
		if ( key === "event" ) {
4942
			if ( this.options.event ) {
4943
				this._off( this.headers, this.options.event );
4944
			}
4945
			this._setupEvents( value );
4946
		}
4947
 
4948
		this._super( key, value );
4949
 
4950
		// setting collapsible: false while collapsed; open first panel
4951
		if ( key === "collapsible" && !value && this.options.active === false ) {
4952
			this._activate( 0 );
4953
		}
4954
 
4955
		if ( key === "icons" ) {
4956
			this._destroyIcons();
4957
			if ( value ) {
4958
				this._createIcons();
4959
			}
4960
		}
4961
 
4962
		// #5332 - opacity doesn't cascade to positioned elements in IE
4963
		// so we need to add the disabled class to the headers and panels
4964
		if ( key === "disabled" ) {
4965
			this.headers.add( this.headers.next() )
4966
				.toggleClass( "ui-state-disabled", !!value );
4967
		}
4968
	},
4969
 
4970
	_keydown: function( event ) {
4971
		if ( event.altKey || event.ctrlKey ) {
4972
			return;
4973
		}
4974
 
4975
		var keyCode = $.ui.keyCode,
4976
			length = this.headers.length,
4977
			currentIndex = this.headers.index( event.target ),
4978
			toFocus = false;
4979
 
4980
		switch ( event.keyCode ) {
4981
			case keyCode.RIGHT:
4982
			case keyCode.DOWN:
4983
				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4984
				break;
4985
			case keyCode.LEFT:
4986
			case keyCode.UP:
4987
				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4988
				break;
4989
			case keyCode.SPACE:
4990
			case keyCode.ENTER:
4991
				this._eventHandler( event );
4992
				break;
4993
			case keyCode.HOME:
4994
				toFocus = this.headers[ 0 ];
4995
				break;
4996
			case keyCode.END:
4997
				toFocus = this.headers[ length - 1 ];
4998
				break;
4999
		}
5000
 
5001
		if ( toFocus ) {
5002
			$( event.target ).attr( "tabIndex", -1 );
5003
			$( toFocus ).attr( "tabIndex", 0 );
5004
			toFocus.focus();
5005
			event.preventDefault();
5006
		}
5007
	},
5008
 
5009
	_panelKeyDown : function( event ) {
5010
		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5011
			$( event.currentTarget ).prev().focus();
5012
		}
5013
	},
5014
 
5015
	refresh: function() {
5016
		var maxHeight, overflow,
5017
			heightStyle = this.options.heightStyle,
5018
			parent = this.element.parent();
5019
 
5020
 
5021
		if ( heightStyle === "fill" ) {
5022
			// IE 6 treats height like minHeight, so we need to turn off overflow
5023
			// in order to get a reliable height
5024
			// we use the minHeight support test because we assume that only
5025
			// browsers that don't support minHeight will treat height as minHeight
5026
			if ( !$.support.minHeight ) {
5027
				overflow = parent.css( "overflow" );
5028
				parent.css( "overflow", "hidden");
5029
			}
5030
			maxHeight = parent.height();
5031
			this.element.siblings( ":visible" ).each(function() {
5032
				var elem = $( this ),
5033
					position = elem.css( "position" );
5034
 
5035
				if ( position === "absolute" || position === "fixed" ) {
5036
					return;
5037
				}
5038
				maxHeight -= elem.outerHeight( true );
5039
			});
5040
			if ( overflow ) {
5041
				parent.css( "overflow", overflow );
5042
			}
5043
 
5044
			this.headers.each(function() {
5045
				maxHeight -= $( this ).outerHeight( true );
5046
			});
5047
 
5048
			this.headers.next()
5049
				.each(function() {
5050
					$( this ).height( Math.max( 0, maxHeight -
5051
						$( this ).innerHeight() + $( this ).height() ) );
5052
				})
5053
				.css( "overflow", "auto" );
5054
		} else if ( heightStyle === "auto" ) {
5055
			maxHeight = 0;
5056
			this.headers.next()
5057
				.each(function() {
5058
					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5059
				})
5060
				.height( maxHeight );
5061
		}
5062
	},
5063
 
5064
	_activate: function( index ) {
5065
		var active = this._findActive( index )[ 0 ];
5066
 
5067
		// trying to activate the already active panel
5068
		if ( active === this.active[ 0 ] ) {
5069
			return;
5070
		}
5071
 
5072
		// trying to collapse, simulate a click on the currently active header
5073
		active = active || this.active[ 0 ];
5074
 
5075
		this._eventHandler({
5076
			target: active,
5077
			currentTarget: active,
5078
			preventDefault: $.noop
5079
		});
5080
	},
5081
 
5082
	_findActive: function( selector ) {
5083
		return typeof selector === "number" ? this.headers.eq( selector ) : $();
5084
	},
5085
 
5086
	_setupEvents: function( event ) {
5087
		var events = {};
5088
		if ( !event ) {
5089
			return;
5090
		}
5091
		$.each( event.split(" "), function( index, eventName ) {
5092
			events[ eventName ] = "_eventHandler";
5093
		});
5094
		this._on( this.headers, events );
5095
	},
5096
 
5097
	_eventHandler: function( event ) {
5098
		var options = this.options,
5099
			active = this.active,
5100
			clicked = $( event.currentTarget ),
5101
			clickedIsActive = clicked[ 0 ] === active[ 0 ],
5102
			collapsing = clickedIsActive && options.collapsible,
5103
			toShow = collapsing ? $() : clicked.next(),
5104
			toHide = active.next(),
5105
			eventData = {
5106
				oldHeader: active,
5107
				oldPanel: toHide,
5108
				newHeader: collapsing ? $() : clicked,
5109
				newPanel: toShow
5110
			};
5111
 
5112
		event.preventDefault();
5113
 
5114
		if (
5115
				// click on active header, but not collapsible
5116
				( clickedIsActive && !options.collapsible ) ||
5117
				// allow canceling activation
5118
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5119
			return;
5120
		}
5121
 
5122
		options.active = collapsing ? false : this.headers.index( clicked );
5123
 
5124
		// when the call to ._toggle() comes after the class changes
5125
		// it causes a very odd bug in IE 8 (see #6720)
5126
		this.active = clickedIsActive ? $() : clicked;
5127
		this._toggle( eventData );
5128
 
5129
		// switch classes
5130
		// corner classes on the previously active header stay after the animation
5131
		active.removeClass( "ui-accordion-header-active ui-state-active" );
5132
		if ( options.icons ) {
5133
			active.children( ".ui-accordion-header-icon" )
5134
				.removeClass( options.icons.activeHeader )
5135
				.addClass( options.icons.header );
5136
		}
5137
 
5138
		if ( !clickedIsActive ) {
5139
			clicked
5140
				.removeClass( "ui-corner-all" )
5141
				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5142
			if ( options.icons ) {
5143
				clicked.children( ".ui-accordion-header-icon" )
5144
					.removeClass( options.icons.header )
5145
					.addClass( options.icons.activeHeader );
5146
			}
5147
 
5148
			clicked
5149
				.next()
5150
				.addClass( "ui-accordion-content-active" );
5151
		}
5152
	},
5153
 
5154
	_toggle: function( data ) {
5155
		var toShow = data.newPanel,
5156
			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5157
 
5158
		// handle activating a panel during the animation for another activation
5159
		this.prevShow.add( this.prevHide ).stop( true, true );
5160
		this.prevShow = toShow;
5161
		this.prevHide = toHide;
5162
 
5163
		if ( this.options.animate ) {
5164
			this._animate( toShow, toHide, data );
5165
		} else {
5166
			toHide.hide();
5167
			toShow.show();
5168
			this._toggleComplete( data );
5169
		}
5170
 
5171
		toHide.attr({
5172
			"aria-expanded": "false",
5173
			"aria-hidden": "true"
5174
		});
5175
		toHide.prev().attr( "aria-selected", "false" );
5176
		// if we're switching panels, remove the old header from the tab order
5177
		// if we're opening from collapsed state, remove the previous header from the tab order
5178
		// if we're collapsing, then keep the collapsing header in the tab order
5179
		if ( toShow.length && toHide.length ) {
5180
			toHide.prev().attr( "tabIndex", -1 );
5181
		} else if ( toShow.length ) {
5182
			this.headers.filter(function() {
5183
				return $( this ).attr( "tabIndex" ) === 0;
5184
			})
5185
			.attr( "tabIndex", -1 );
5186
		}
5187
 
5188
		toShow
5189
			.attr({
5190
				"aria-expanded": "true",
5191
				"aria-hidden": "false"
5192
			})
5193
			.prev()
5194
				.attr({
5195
					"aria-selected": "true",
5196
					tabIndex: 0
5197
				});
5198
	},
5199
 
5200
	_animate: function( toShow, toHide, data ) {
5201
		var total, easing, duration,
5202
			that = this,
5203
			adjust = 0,
5204
			down = toShow.length &&
5205
				( !toHide.length || ( toShow.index() < toHide.index() ) ),
5206
			animate = this.options.animate || {},
5207
			options = down && animate.down || animate,
5208
			complete = function() {
5209
				that._toggleComplete( data );
5210
			};
5211
 
5212
		if ( typeof options === "number" ) {
5213
			duration = options;
5214
		}
5215
		if ( typeof options === "string" ) {
5216
			easing = options;
5217
		}
5218
		// fall back from options to animation in case of partial down settings
5219
		easing = easing || options.easing || animate.easing;
5220
		duration = duration || options.duration || animate.duration;
5221
 
5222
		if ( !toHide.length ) {
5223
			return toShow.animate( showProps, duration, easing, complete );
5224
		}
5225
		if ( !toShow.length ) {
5226
			return toHide.animate( hideProps, duration, easing, complete );
5227
		}
5228
 
5229
		total = toShow.show().outerHeight();
5230
		toHide.animate( hideProps, {
5231
			duration: duration,
5232
			easing: easing,
5233
			step: function( now, fx ) {
5234
				fx.now = Math.round( now );
5235
			}
5236
		});
5237
		toShow
5238
			.hide()
5239
			.animate( showProps, {
5240
				duration: duration,
5241
				easing: easing,
5242
				complete: complete,
5243
				step: function( now, fx ) {
5244
					fx.now = Math.round( now );
5245
					if ( fx.prop !== "height" ) {
5246
						adjust += fx.now;
5247
					} else if ( that.options.heightStyle !== "content" ) {
5248
						fx.now = Math.round( total - toHide.outerHeight() - adjust );
5249
						adjust = 0;
5250
					}
5251
				}
5252
			});
5253
	},
5254
 
5255
	_toggleComplete: function( data ) {
5256
		var toHide = data.oldPanel;
5257
 
5258
		toHide
5259
			.removeClass( "ui-accordion-content-active" )
5260
			.prev()
5261
				.removeClass( "ui-corner-top" )
5262
				.addClass( "ui-corner-all" );
5263
 
5264
		// Work around for rendering bug in IE (#5421)
5265
		if ( toHide.length ) {
5266
			toHide.parent()[0].className = toHide.parent()[0].className;
5267
		}
5268
 
5269
		this._trigger( "activate", null, data );
5270
	}
5271
});
5272
 
5273
 
5274
 
5275
// DEPRECATED
5276
if ( $.uiBackCompat !== false ) {
5277
	// navigation options
5278
	(function( $, prototype ) {
5279
		$.extend( prototype.options, {
5280
			navigation: false,
5281
			navigationFilter: function() {
5282
				return this.href.toLowerCase() === location.href.toLowerCase();
5283
			}
5284
		});
5285
 
5286
		var _create = prototype._create;
5287
		prototype._create = function() {
5288
			if ( this.options.navigation ) {
5289
				var that = this,
5290
					headers = this.element.find( this.options.header ),
5291
					content = headers.next(),
5292
					current = headers.add( content )
5293
						.find( "a" )
5294
						.filter( this.options.navigationFilter )
5295
						[ 0 ];
5296
				if ( current ) {
5297
					headers.add( content ).each( function( index ) {
5298
						if ( $.contains( this, current ) ) {
5299
							that.options.active = Math.floor( index / 2 );
5300
							return false;
5301
						}
5302
					});
5303
				}
5304
			}
5305
			_create.call( this );
5306
		};
5307
	}( jQuery, jQuery.ui.accordion.prototype ) );
5308
 
5309
	// height options
5310
	(function( $, prototype ) {
5311
		$.extend( prototype.options, {
5312
			heightStyle: null, // remove default so we fall back to old values
5313
			autoHeight: true, // use heightStyle: "auto"
5314
			clearStyle: false, // use heightStyle: "content"
5315
			fillSpace: false // use heightStyle: "fill"
5316
		});
5317
 
5318
		var _create = prototype._create,
5319
			_setOption = prototype._setOption;
5320
 
5321
		$.extend( prototype, {
5322
			_create: function() {
5323
				this.options.heightStyle = this.options.heightStyle ||
5324
					this._mergeHeightStyle();
5325
 
5326
				_create.call( this );
5327
			},
5328
 
5329
			_setOption: function( key ) {
5330
				if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
5331
					this.options.heightStyle = this._mergeHeightStyle();
5332
				}
5333
				_setOption.apply( this, arguments );
5334
			},
5335
 
5336
			_mergeHeightStyle: function() {
5337
				var options = this.options;
5338
 
5339
				if ( options.fillSpace ) {
5340
					return "fill";
5341
				}
5342
 
5343
				if ( options.clearStyle ) {
5344
					return "content";
5345
				}
5346
 
5347
				if ( options.autoHeight ) {
5348
					return "auto";
5349
				}
5350
			}
5351
		});
5352
	}( jQuery, jQuery.ui.accordion.prototype ) );
5353
 
5354
	// icon options
5355
	(function( $, prototype ) {
5356
		$.extend( prototype.options.icons, {
5357
			activeHeader: null, // remove default so we fall back to old values
5358
			headerSelected: "ui-icon-triangle-1-s"
5359
		});
5360
 
5361
		var _createIcons = prototype._createIcons;
5362
		prototype._createIcons = function() {
5363
			if ( this.options.icons ) {
5364
				this.options.icons.activeHeader = this.options.icons.activeHeader ||
5365
					this.options.icons.headerSelected;
5366
			}
5367
			_createIcons.call( this );
5368
		};
5369
	}( jQuery, jQuery.ui.accordion.prototype ) );
5370
 
5371
	// expanded active option, activate method
5372
	(function( $, prototype ) {
5373
		prototype.activate = prototype._activate;
5374
 
5375
		var _findActive = prototype._findActive;
5376
		prototype._findActive = function( index ) {
5377
			if ( index === -1 ) {
5378
				index = false;
5379
			}
5380
			if ( index && typeof index !== "number" ) {
5381
				index = this.headers.index( this.headers.filter( index ) );
5382
				if ( index === -1 ) {
5383
					index = false;
5384
				}
5385
			}
5386
			return _findActive.call( this, index );
5387
		};
5388
	}( jQuery, jQuery.ui.accordion.prototype ) );
5389
 
5390
	// resize method
5391
	jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
5392
 
5393
	// change events
5394
	(function( $, prototype ) {
5395
		$.extend( prototype.options, {
5396
			change: null,
5397
			changestart: null
5398
		});
5399
 
5400
		var _trigger = prototype._trigger;
5401
		prototype._trigger = function( type, event, data ) {
5402
			var ret = _trigger.apply( this, arguments );
5403
			if ( !ret ) {
5404
				return false;
5405
			}
5406
 
5407
			if ( type === "beforeActivate" ) {
5408
				ret = _trigger.call( this, "changestart", event, {
5409
					oldHeader: data.oldHeader,
5410
					oldContent: data.oldPanel,
5411
					newHeader: data.newHeader,
5412
					newContent: data.newPanel
5413
				});
5414
			} else if ( type === "activate" ) {
5415
				ret = _trigger.call( this, "change", event, {
5416
					oldHeader: data.oldHeader,
5417
					oldContent: data.oldPanel,
5418
					newHeader: data.newHeader,
5419
					newContent: data.newPanel
5420
				});
5421
			}
5422
			return ret;
5423
		};
5424
	}( jQuery, jQuery.ui.accordion.prototype ) );
5425
 
5426
	// animated option
5427
	// NOTE: this only provides support for "slide", "bounceslide", and easings
5428
	// not the full $.ui.accordion.animations API
5429
	(function( $, prototype ) {
5430
		$.extend( prototype.options, {
5431
			animate: null,
5432
			animated: "slide"
5433
		});
5434
 
5435
		var _create = prototype._create;
5436
		prototype._create = function() {
5437
			var options = this.options;
5438
			if ( options.animate === null ) {
5439
				if ( !options.animated ) {
5440
					options.animate = false;
5441
				} else if ( options.animated === "slide" ) {
5442
					options.animate = 300;
5443
				} else if ( options.animated === "bounceslide" ) {
5444
					options.animate = {
5445
						duration: 200,
5446
						down: {
5447
							easing: "easeOutBounce",
5448
							duration: 1000
5449
						}
5450
					};
5451
				} else {
5452
					options.animate = options.animated;
5453
				}
5454
			}
5455
 
5456
			_create.call( this );
5457
		};
5458
	}( jQuery, jQuery.ui.accordion.prototype ) );
5459
}
5460
 
5461
})( jQuery );
5462
(function( $, undefined ) {
5463
 
5464
// used to prevent race conditions with remote data sources
5465
var requestIndex = 0;
5466
 
5467
$.widget( "ui.autocomplete", {
5468
	version: "1.9.2",
5469
	defaultElement: "<input>",
5470
	options: {
5471
		appendTo: "body",
5472
		autoFocus: false,
5473
		delay: 300,
5474
		minLength: 1,
5475
		position: {
5476
			my: "left top",
5477
			at: "left bottom",
5478
			collision: "none"
5479
		},
5480
		source: null,
5481
 
5482
		// callbacks
5483
		change: null,
5484
		close: null,
5485
		focus: null,
5486
		open: null,
5487
		response: null,
5488
		search: null,
5489
		select: null
5490
	},
5491
 
5492
	pending: 0,
5493
 
5494
	_create: function() {
5495
		// Some browsers only repeat keydown events, not keypress events,
5496
		// so we use the suppressKeyPress flag to determine if we've already
5497
		// handled the keydown event. #7269
5498
		// Unfortunately the code for & in keypress is the same as the up arrow,
5499
		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5500
		// events when we know the keydown event was used to modify the
5501
		// search term. #7799
5502
		var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
5503
 
5504
		this.isMultiLine = this._isMultiLine();
5505
		this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
5506
		this.isNewMenu = true;
5507
 
5508
		this.element
5509
			.addClass( "ui-autocomplete-input" )
5510
			.attr( "autocomplete", "off" );
5511
 
5512
		this._on( this.element, {
5513
			keydown: function( event ) {
5514
				if ( this.element.prop( "readOnly" ) ) {
5515
					suppressKeyPress = true;
5516
					suppressInput = true;
5517
					suppressKeyPressRepeat = true;
5518
					return;
5519
				}
5520
 
5521
				suppressKeyPress = false;
5522
				suppressInput = false;
5523
				suppressKeyPressRepeat = false;
5524
				var keyCode = $.ui.keyCode;
5525
				switch( event.keyCode ) {
5526
				case keyCode.PAGE_UP:
5527
					suppressKeyPress = true;
5528
					this._move( "previousPage", event );
5529
					break;
5530
				case keyCode.PAGE_DOWN:
5531
					suppressKeyPress = true;
5532
					this._move( "nextPage", event );
5533
					break;
5534
				case keyCode.UP:
5535
					suppressKeyPress = true;
5536
					this._keyEvent( "previous", event );
5537
					break;
5538
				case keyCode.DOWN:
5539
					suppressKeyPress = true;
5540
					this._keyEvent( "next", event );
5541
					break;
5542
				case keyCode.ENTER:
5543
				case keyCode.NUMPAD_ENTER:
5544
					// when menu is open and has focus
5545
					if ( this.menu.active ) {
5546
						// #6055 - Opera still allows the keypress to occur
5547
						// which causes forms to submit
5548
						suppressKeyPress = true;
5549
						event.preventDefault();
5550
						this.menu.select( event );
5551
					}
5552
					break;
5553
				case keyCode.TAB:
5554
					if ( this.menu.active ) {
5555
						this.menu.select( event );
5556
					}
5557
					break;
5558
				case keyCode.ESCAPE:
5559
					if ( this.menu.element.is( ":visible" ) ) {
5560
						this._value( this.term );
5561
						this.close( event );
5562
						// Different browsers have different default behavior for escape
5563
						// Single press can mean undo or clear
5564
						// Double press in IE means clear the whole form
5565
						event.preventDefault();
5566
					}
5567
					break;
5568
				default:
5569
					suppressKeyPressRepeat = true;
5570
					// search timeout should be triggered before the input value is changed
5571
					this._searchTimeout( event );
5572
					break;
5573
				}
5574
			},
5575
			keypress: function( event ) {
5576
				if ( suppressKeyPress ) {
5577
					suppressKeyPress = false;
5578
					event.preventDefault();
5579
					return;
5580
				}
5581
				if ( suppressKeyPressRepeat ) {
5582
					return;
5583
				}
5584
 
5585
				// replicate some key handlers to allow them to repeat in Firefox and Opera
5586
				var keyCode = $.ui.keyCode;
5587
				switch( event.keyCode ) {
5588
				case keyCode.PAGE_UP:
5589
					this._move( "previousPage", event );
5590
					break;
5591
				case keyCode.PAGE_DOWN:
5592
					this._move( "nextPage", event );
5593
					break;
5594
				case keyCode.UP:
5595
					this._keyEvent( "previous", event );
5596
					break;
5597
				case keyCode.DOWN:
5598
					this._keyEvent( "next", event );
5599
					break;
5600
				}
5601
			},
5602
			input: function( event ) {
5603
				if ( suppressInput ) {
5604
					suppressInput = false;
5605
					event.preventDefault();
5606
					return;
5607
				}
5608
				this._searchTimeout( event );
5609
			},
5610
			focus: function() {
5611
				this.selectedItem = null;
5612
				this.previous = this._value();
5613
			},
5614
			blur: function( event ) {
5615
				if ( this.cancelBlur ) {
5616
					delete this.cancelBlur;
5617
					return;
5618
				}
5619
 
5620
				clearTimeout( this.searching );
5621
				this.close( event );
5622
				this._change( event );
5623
			}
5624
		});
5625
 
5626
		this._initSource();
5627
		this.menu = $( "<ul>" )
5628
			.addClass( "ui-autocomplete" )
5629
			.appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
5630
			.menu({
5631
				// custom key handling for now
5632
				input: $(),
5633
				// disable ARIA support, the live region takes care of that
5634
				role: null
5635
			})
5636
			.zIndex( this.element.zIndex() + 1 )
5637
			.hide()
5638
			.data( "menu" );
5639
 
5640
		this._on( this.menu.element, {
5641
			mousedown: function( event ) {
5642
				// prevent moving focus out of the text field
5643
				event.preventDefault();
5644
 
5645
				// IE doesn't prevent moving focus even with event.preventDefault()
5646
				// so we set a flag to know when we should ignore the blur event
5647
				this.cancelBlur = true;
5648
				this._delay(function() {
5649
					delete this.cancelBlur;
5650
				});
5651
 
5652
				// clicking on the scrollbar causes focus to shift to the body
5653
				// but we can't detect a mouseup or a click immediately afterward
5654
				// so we have to track the next mousedown and close the menu if
5655
				// the user clicks somewhere outside of the autocomplete
5656
				var menuElement = this.menu.element[ 0 ];
5657
				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5658
					this._delay(function() {
5659
						var that = this;
5660
						this.document.one( "mousedown", function( event ) {
5661
							if ( event.target !== that.element[ 0 ] &&
5662
									event.target !== menuElement &&
5663
									!$.contains( menuElement, event.target ) ) {
5664
								that.close();
5665
							}
5666
						});
5667
					});
5668
				}
5669
			},
5670
			menufocus: function( event, ui ) {
5671
				// #7024 - Prevent accidental activation of menu items in Firefox
5672
				if ( this.isNewMenu ) {
5673
					this.isNewMenu = false;
5674
					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5675
						this.menu.blur();
5676
 
5677
						this.document.one( "mousemove", function() {
5678
							$( event.target ).trigger( event.originalEvent );
5679
						});
5680
 
5681
						return;
5682
					}
5683
				}
5684
 
5685
				// back compat for _renderItem using item.autocomplete, via #7810
5686
				// TODO remove the fallback, see #8156
5687
				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
5688
				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5689
					// use value to match what will end up in the input, if it was a key event
5690
					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5691
						this._value( item.value );
5692
					}
5693
				} else {
5694
					// Normally the input is populated with the item's value as the
5695
					// menu is navigated, causing screen readers to notice a change and
5696
					// announce the item. Since the focus event was canceled, this doesn't
5697
					// happen, so we update the live region so that screen readers can
5698
					// still notice the change and announce it.
5699
					this.liveRegion.text( item.value );
5700
				}
5701
			},
5702
			menuselect: function( event, ui ) {
5703
				// back compat for _renderItem using item.autocomplete, via #7810
5704
				// TODO remove the fallback, see #8156
5705
				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
5706
					previous = this.previous;
5707
 
5708
				// only trigger when focus was lost (click on menu)
5709
				if ( this.element[0] !== this.document[0].activeElement ) {
5710
					this.element.focus();
5711
					this.previous = previous;
5712
					// #6109 - IE triggers two focus events and the second
5713
					// is asynchronous, so we need to reset the previous
5714
					// term synchronously and asynchronously :-(
5715
					this._delay(function() {
5716
						this.previous = previous;
5717
						this.selectedItem = item;
5718
					});
5719
				}
5720
 
5721
				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5722
					this._value( item.value );
5723
				}
5724
				// reset the term after the select event
5725
				// this allows custom select handling to work properly
5726
				this.term = this._value();
5727
 
5728
				this.close( event );
5729
				this.selectedItem = item;
5730
			}
5731
		});
5732
 
5733
		this.liveRegion = $( "<span>", {
5734
				role: "status",
5735
				"aria-live": "polite"
5736
			})
5737
			.addClass( "ui-helper-hidden-accessible" )
5738
			.insertAfter( this.element );
5739
 
5740
		if ( $.fn.bgiframe ) {
5741
			this.menu.element.bgiframe();
5742
		}
5743
 
5744
		// turning off autocomplete prevents the browser from remembering the
5745
		// value when navigating through history, so we re-enable autocomplete
5746
		// if the page is unloaded before the widget is destroyed. #7790
5747
		this._on( this.window, {
5748
			beforeunload: function() {
5749
				this.element.removeAttr( "autocomplete" );
5750
			}
5751
		});
5752
	},
5753
 
5754
	_destroy: function() {
5755
		clearTimeout( this.searching );
5756
		this.element
5757
			.removeClass( "ui-autocomplete-input" )
5758
			.removeAttr( "autocomplete" );
5759
		this.menu.element.remove();
5760
		this.liveRegion.remove();
5761
	},
5762
 
5763
	_setOption: function( key, value ) {
5764
		this._super( key, value );
5765
		if ( key === "source" ) {
5766
			this._initSource();
5767
		}
5768
		if ( key === "appendTo" ) {
5769
			this.menu.element.appendTo( this.document.find( value || "body" )[0] );
5770
		}
5771
		if ( key === "disabled" && value && this.xhr ) {
5772
			this.xhr.abort();
5773
		}
5774
	},
5775
 
5776
	_isMultiLine: function() {
5777
		// Textareas are always multi-line
5778
		if ( this.element.is( "textarea" ) ) {
5779
			return true;
5780
		}
5781
		// Inputs are always single-line, even if inside a contentEditable element
5782
		// IE also treats inputs as contentEditable
5783
		if ( this.element.is( "input" ) ) {
5784
			return false;
5785
		}
5786
		// All other element types are determined by whether or not they're contentEditable
5787
		return this.element.prop( "isContentEditable" );
5788
	},
5789
 
5790
	_initSource: function() {
5791
		var array, url,
5792
			that = this;
5793
		if ( $.isArray(this.options.source) ) {
5794
			array = this.options.source;
5795
			this.source = function( request, response ) {
5796
				response( $.ui.autocomplete.filter( array, request.term ) );
5797
			};
5798
		} else if ( typeof this.options.source === "string" ) {
5799
			url = this.options.source;
5800
			this.source = function( request, response ) {
5801
				if ( that.xhr ) {
5802
					that.xhr.abort();
5803
				}
5804
				that.xhr = $.ajax({
5805
					url: url,
5806
					data: request,
5807
					dataType: "json",
5808
					success: function( data ) {
5809
						response( data );
5810
					},
5811
					error: function() {
5812
						response( [] );
5813
					}
5814
				});
5815
			};
5816
		} else {
5817
			this.source = this.options.source;
5818
		}
5819
	},
5820
 
5821
	_searchTimeout: function( event ) {
5822
		clearTimeout( this.searching );
5823
		this.searching = this._delay(function() {
5824
			// only search if the value has changed
5825
			if ( this.term !== this._value() ) {
5826
				this.selectedItem = null;
5827
				this.search( null, event );
5828
			}
5829
		}, this.options.delay );
5830
	},
5831
 
5832
	search: function( value, event ) {
5833
		value = value != null ? value : this._value();
5834
 
5835
		// always save the actual value, not the one passed as an argument
5836
		this.term = this._value();
5837
 
5838
		if ( value.length < this.options.minLength ) {
5839
			return this.close( event );
5840
		}
5841
 
5842
		if ( this._trigger( "search", event ) === false ) {
5843
			return;
5844
		}
5845
 
5846
		return this._search( value );
5847
	},
5848
 
5849
	_search: function( value ) {
5850
		this.pending++;
5851
		this.element.addClass( "ui-autocomplete-loading" );
5852
		this.cancelSearch = false;
5853
 
5854
		this.source( { term: value }, this._response() );
5855
	},
5856
 
5857
	_response: function() {
5858
		var that = this,
5859
			index = ++requestIndex;
5860
 
5861
		return function( content ) {
5862
			if ( index === requestIndex ) {
5863
				that.__response( content );
5864
			}
5865
 
5866
			that.pending--;
5867
			if ( !that.pending ) {
5868
				that.element.removeClass( "ui-autocomplete-loading" );
5869
			}
5870
		};
5871
	},
5872
 
5873
	__response: function( content ) {
5874
		if ( content ) {
5875
			content = this._normalize( content );
5876
		}
5877
		this._trigger( "response", null, { content: content } );
5878
		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
5879
			this._suggest( content );
5880
			this._trigger( "open" );
5881
		} else {
5882
			// use ._close() instead of .close() so we don't cancel future searches
5883
			this._close();
5884
		}
5885
	},
5886
 
5887
	close: function( event ) {
5888
		this.cancelSearch = true;
5889
		this._close( event );
5890
	},
5891
 
5892
	_close: function( event ) {
5893
		if ( this.menu.element.is( ":visible" ) ) {
5894
			this.menu.element.hide();
5895
			this.menu.blur();
5896
			this.isNewMenu = true;
5897
			this._trigger( "close", event );
5898
		}
5899
	},
5900
 
5901
	_change: function( event ) {
5902
		if ( this.previous !== this._value() ) {
5903
			this._trigger( "change", event, { item: this.selectedItem } );
5904
		}
5905
	},
5906
 
5907
	_normalize: function( items ) {
5908
		// assume all items have the right format when the first item is complete
5909
		if ( items.length && items[0].label && items[0].value ) {
5910
			return items;
5911
		}
5912
		return $.map( items, function( item ) {
5913
			if ( typeof item === "string" ) {
5914
				return {
5915
					label: item,
5916
					value: item
5917
				};
5918
			}
5919
			return $.extend({
5920
				label: item.label || item.value,
5921
				value: item.value || item.label
5922
			}, item );
5923
		});
5924
	},
5925
 
5926
	_suggest: function( items ) {
5927
		var ul = this.menu.element
5928
			.empty()
5929
			.zIndex( this.element.zIndex() + 1 );
5930
		this._renderMenu( ul, items );
5931
		this.menu.refresh();
5932
 
5933
		// size and position menu
5934
		ul.show();
5935
		this._resizeMenu();
5936
		ul.position( $.extend({
5937
			of: this.element
5938
		}, this.options.position ));
5939
 
5940
		if ( this.options.autoFocus ) {
5941
			this.menu.next();
5942
		}
5943
	},
5944
 
5945
	_resizeMenu: function() {
5946
		var ul = this.menu.element;
5947
		ul.outerWidth( Math.max(
5948
			// Firefox wraps long text (possibly a rounding bug)
5949
			// so we add 1px to avoid the wrapping (#7513)
5950
			ul.width( "" ).outerWidth() + 1,
5951
			this.element.outerWidth()
5952
		) );
5953
	},
5954
 
5955
	_renderMenu: function( ul, items ) {
5956
		var that = this;
5957
		$.each( items, function( index, item ) {
5958
			that._renderItemData( ul, item );
5959
		});
5960
	},
5961
 
5962
	_renderItemData: function( ul, item ) {
5963
		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
5964
	},
5965
 
5966
	_renderItem: function( ul, item ) {
5967
		return $( "<li>" )
5968
			.append( $( "<a>" ).text( item.label ) )
5969
			.appendTo( ul );
5970
	},
5971
 
5972
	_move: function( direction, event ) {
5973
		if ( !this.menu.element.is( ":visible" ) ) {
5974
			this.search( null, event );
5975
			return;
5976
		}
5977
		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
5978
				this.menu.isLastItem() && /^next/.test( direction ) ) {
5979
			this._value( this.term );
5980
			this.menu.blur();
5981
			return;
5982
		}
5983
		this.menu[ direction ]( event );
5984
	},
5985
 
5986
	widget: function() {
5987
		return this.menu.element;
5988
	},
5989
 
5990
	_value: function() {
5991
		return this.valueMethod.apply( this.element, arguments );
5992
	},
5993
 
5994
	_keyEvent: function( keyEvent, event ) {
5995
		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5996
			this._move( keyEvent, event );
5997
 
5998
			// prevents moving cursor to beginning/end of the text field in some browsers
5999
			event.preventDefault();
6000
		}
6001
	}
6002
});
6003
 
6004
$.extend( $.ui.autocomplete, {
6005
	escapeRegex: function( value ) {
6006
		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
6007
	},
6008
	filter: function(array, term) {
6009
		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6010
		return $.grep( array, function(value) {
6011
			return matcher.test( value.label || value.value || value );
6012
		});
6013
	}
6014
});
6015
 
6016
 
6017
// live region extension, adding a `messages` option
6018
// NOTE: This is an experimental API. We are still investigating
6019
// a full solution for string manipulation and internationalization.
6020
$.widget( "ui.autocomplete", $.ui.autocomplete, {
6021
	options: {
6022
		messages: {
6023
			noResults: "No search results.",
6024
			results: function( amount ) {
6025
				return amount + ( amount > 1 ? " results are" : " result is" ) +
6026
					" available, use up and down arrow keys to navigate.";
6027
			}
6028
		}
6029
	},
6030
 
6031
	__response: function( content ) {
6032
		var message;
6033
		this._superApply( arguments );
6034
		if ( this.options.disabled || this.cancelSearch ) {
6035
			return;
6036
		}
6037
		if ( content && content.length ) {
6038
			message = this.options.messages.results( content.length );
6039
		} else {
6040
			message = this.options.messages.noResults;
6041
		}
6042
		this.liveRegion.text( message );
6043
	}
6044
});
6045
 
6046
 
6047
}( jQuery ));
6048
(function( $, undefined ) {
6049
 
6050
var lastActive, startXPos, startYPos, clickDragged,
6051
	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6052
	stateClasses = "ui-state-hover ui-state-active ",
6053
	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",
6054
	formResetHandler = function() {
6055
		var buttons = $( this ).find( ":ui-button" );
6056
		setTimeout(function() {
6057
			buttons.button( "refresh" );
6058
		}, 1 );
6059
	},
6060
	radioGroup = function( radio ) {
6061
		var name = radio.name,
6062
			form = radio.form,
6063
			radios = $( [] );
6064
		if ( name ) {
6065
			if ( form ) {
6066
				radios = $( form ).find( "[name='" + name + "']" );
6067
			} else {
6068
				radios = $( "[name='" + name + "']", radio.ownerDocument )
6069
					.filter(function() {
6070
						return !this.form;
6071
					});
6072
			}
6073
		}
6074
		return radios;
6075
	};
6076
 
6077
$.widget( "ui.button", {
6078
	version: "1.9.2",
6079
	defaultElement: "<button>",
6080
	options: {
6081
		disabled: null,
6082
		text: true,
6083
		label: null,
6084
		icons: {
6085
			primary: null,
6086
			secondary: null
6087
		}
6088
	},
6089
	_create: function() {
6090
		this.element.closest( "form" )
6091
			.unbind( "reset" + this.eventNamespace )
6092
			.bind( "reset" + this.eventNamespace, formResetHandler );
6093
 
6094
		if ( typeof this.options.disabled !== "boolean" ) {
6095
			this.options.disabled = !!this.element.prop( "disabled" );
6096
		} else {
6097
			this.element.prop( "disabled", this.options.disabled );
6098
		}
6099
 
6100
		this._determineButtonType();
6101
		this.hasTitle = !!this.buttonElement.attr( "title" );
6102
 
6103
		var that = this,
6104
			options = this.options,
6105
			toggleButton = this.type === "checkbox" || this.type === "radio",
6106
			activeClass = !toggleButton ? "ui-state-active" : "",
6107
			focusClass = "ui-state-focus";
6108
 
6109
		if ( options.label === null ) {
6110
			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6111
		}
6112
 
6113
		this._hoverable( this.buttonElement );
6114
 
6115
		this.buttonElement
6116
			.addClass( baseClasses )
6117
			.attr( "role", "button" )
6118
			.bind( "mouseenter" + this.eventNamespace, function() {
6119
				if ( options.disabled ) {
6120
					return;
6121
				}
6122
				if ( this === lastActive ) {
6123
					$( this ).addClass( "ui-state-active" );
6124
				}
6125
			})
6126
			.bind( "mouseleave" + this.eventNamespace, function() {
6127
				if ( options.disabled ) {
6128
					return;
6129
				}
6130
				$( this ).removeClass( activeClass );
6131
			})
6132
			.bind( "click" + this.eventNamespace, function( event ) {
6133
				if ( options.disabled ) {
6134
					event.preventDefault();
6135
					event.stopImmediatePropagation();
6136
				}
6137
			});
6138
 
6139
		this.element
6140
			.bind( "focus" + this.eventNamespace, function() {
6141
				// no need to check disabled, focus won't be triggered anyway
6142
				that.buttonElement.addClass( focusClass );
6143
			})
6144
			.bind( "blur" + this.eventNamespace, function() {
6145
				that.buttonElement.removeClass( focusClass );
6146
			});
6147
 
6148
		if ( toggleButton ) {
6149
			this.element.bind( "change" + this.eventNamespace, function() {
6150
				if ( clickDragged ) {
6151
					return;
6152
				}
6153
				that.refresh();
6154
			});
6155
			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6156
			// prevents issue where button state changes but checkbox/radio checked state
6157
			// does not in Firefox (see ticket #6970)
6158
			this.buttonElement
6159
				.bind( "mousedown" + this.eventNamespace, function( event ) {
6160
					if ( options.disabled ) {
6161
						return;
6162
					}
6163
					clickDragged = false;
6164
					startXPos = event.pageX;
6165
					startYPos = event.pageY;
6166
				})
6167
				.bind( "mouseup" + this.eventNamespace, function( event ) {
6168
					if ( options.disabled ) {
6169
						return;
6170
					}
6171
					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6172
						clickDragged = true;
6173
					}
6174
			});
6175
		}
6176
 
6177
		if ( this.type === "checkbox" ) {
6178
			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6179
				if ( options.disabled || clickDragged ) {
6180
					return false;
6181
				}
6182
				$( this ).toggleClass( "ui-state-active" );
6183
				that.buttonElement.attr( "aria-pressed", that.element[0].checked );
6184
			});
6185
		} else if ( this.type === "radio" ) {
6186
			this.buttonElement.bind( "click" + this.eventNamespace, function() {
6187
				if ( options.disabled || clickDragged ) {
6188
					return false;
6189
				}
6190
				$( this ).addClass( "ui-state-active" );
6191
				that.buttonElement.attr( "aria-pressed", "true" );
6192
 
6193
				var radio = that.element[ 0 ];
6194
				radioGroup( radio )
6195
					.not( radio )
6196
					.map(function() {
6197
						return $( this ).button( "widget" )[ 0 ];
6198
					})
6199
					.removeClass( "ui-state-active" )
6200
					.attr( "aria-pressed", "false" );
6201
			});
6202
		} else {
6203
			this.buttonElement
6204
				.bind( "mousedown" + this.eventNamespace, function() {
6205
					if ( options.disabled ) {
6206
						return false;
6207
					}
6208
					$( this ).addClass( "ui-state-active" );
6209
					lastActive = this;
6210
					that.document.one( "mouseup", function() {
6211
						lastActive = null;
6212
					});
6213
				})
6214
				.bind( "mouseup" + this.eventNamespace, function() {
6215
					if ( options.disabled ) {
6216
						return false;
6217
					}
6218
					$( this ).removeClass( "ui-state-active" );
6219
				})
6220
				.bind( "keydown" + this.eventNamespace, function(event) {
6221
					if ( options.disabled ) {
6222
						return false;
6223
					}
6224
					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6225
						$( this ).addClass( "ui-state-active" );
6226
					}
6227
				})
6228
				.bind( "keyup" + this.eventNamespace, function() {
6229
					$( this ).removeClass( "ui-state-active" );
6230
				});
6231
 
6232
			if ( this.buttonElement.is("a") ) {
6233
				this.buttonElement.keyup(function(event) {
6234
					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6235
						// TODO pass through original event correctly (just as 2nd argument doesn't work)
6236
						$( this ).click();
6237
					}
6238
				});
6239
			}
6240
		}
6241
 
6242
		// TODO: pull out $.Widget's handling for the disabled option into
6243
		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
6244
		// be overridden by individual plugins
6245
		this._setOption( "disabled", options.disabled );
6246
		this._resetButton();
6247
	},
6248
 
6249
	_determineButtonType: function() {
6250
		var ancestor, labelSelector, checked;
6251
 
6252
		if ( this.element.is("[type=checkbox]") ) {
6253
			this.type = "checkbox";
6254
		} else if ( this.element.is("[type=radio]") ) {
6255
			this.type = "radio";
6256
		} else if ( this.element.is("input") ) {
6257
			this.type = "input";
6258
		} else {
6259
			this.type = "button";
6260
		}
6261
 
6262
		if ( this.type === "checkbox" || this.type === "radio" ) {
6263
			// we don't search against the document in case the element
6264
			// is disconnected from the DOM
6265
			ancestor = this.element.parents().last();
6266
			labelSelector = "label[for='" + this.element.attr("id") + "']";
6267
			this.buttonElement = ancestor.find( labelSelector );
6268
			if ( !this.buttonElement.length ) {
6269
				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
6270
				this.buttonElement = ancestor.filter( labelSelector );
6271
				if ( !this.buttonElement.length ) {
6272
					this.buttonElement = ancestor.find( labelSelector );
6273
				}
6274
			}
6275
			this.element.addClass( "ui-helper-hidden-accessible" );
6276
 
6277
			checked = this.element.is( ":checked" );
6278
			if ( checked ) {
6279
				this.buttonElement.addClass( "ui-state-active" );
6280
			}
6281
			this.buttonElement.prop( "aria-pressed", checked );
6282
		} else {
6283
			this.buttonElement = this.element;
6284
		}
6285
	},
6286
 
6287
	widget: function() {
6288
		return this.buttonElement;
6289
	},
6290
 
6291
	_destroy: function() {
6292
		this.element
6293
			.removeClass( "ui-helper-hidden-accessible" );
6294
		this.buttonElement
6295
			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
6296
			.removeAttr( "role" )
6297
			.removeAttr( "aria-pressed" )
6298
			.html( this.buttonElement.find(".ui-button-text").html() );
6299
 
6300
		if ( !this.hasTitle ) {
6301
			this.buttonElement.removeAttr( "title" );
6302
		}
6303
	},
6304
 
6305
	_setOption: function( key, value ) {
6306
		this._super( key, value );
6307
		if ( key === "disabled" ) {
6308
			if ( value ) {
6309
				this.element.prop( "disabled", true );
6310
			} else {
6311
				this.element.prop( "disabled", false );
6312
			}
6313
			return;
6314
		}
6315
		this._resetButton();
6316
	},
6317
 
6318
	refresh: function() {
6319
		//See #8237 & #8828
6320
		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
6321
 
6322
		if ( isDisabled !== this.options.disabled ) {
6323
			this._setOption( "disabled", isDisabled );
6324
		}
6325
		if ( this.type === "radio" ) {
6326
			radioGroup( this.element[0] ).each(function() {
6327
				if ( $( this ).is( ":checked" ) ) {
6328
					$( this ).button( "widget" )
6329
						.addClass( "ui-state-active" )
6330
						.attr( "aria-pressed", "true" );
6331
				} else {
6332
					$( this ).button( "widget" )
6333
						.removeClass( "ui-state-active" )
6334
						.attr( "aria-pressed", "false" );
6335
				}
6336
			});
6337
		} else if ( this.type === "checkbox" ) {
6338
			if ( this.element.is( ":checked" ) ) {
6339
				this.buttonElement
6340
					.addClass( "ui-state-active" )
6341
					.attr( "aria-pressed", "true" );
6342
			} else {
6343
				this.buttonElement
6344
					.removeClass( "ui-state-active" )
6345
					.attr( "aria-pressed", "false" );
6346
			}
6347
		}
6348
	},
6349
 
6350
	_resetButton: function() {
6351
		if ( this.type === "input" ) {
6352
			if ( this.options.label ) {
6353
				this.element.val( this.options.label );
6354
			}
6355
			return;
6356
		}
6357
		var buttonElement = this.buttonElement.removeClass( typeClasses ),
6358
			buttonText = $( "<span></span>", this.document[0] )
6359
				.addClass( "ui-button-text" )
6360
				.html( this.options.label )
6361
				.appendTo( buttonElement.empty() )
6362
				.text(),
6363
			icons = this.options.icons,
6364
			multipleIcons = icons.primary && icons.secondary,
6365
			buttonClasses = [];
6366
 
6367
		if ( icons.primary || icons.secondary ) {
6368
			if ( this.options.text ) {
6369
				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
6370
			}
6371
 
6372
			if ( icons.primary ) {
6373
				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
6374
			}
6375
 
6376
			if ( icons.secondary ) {
6377
				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
6378
			}
6379
 
6380
			if ( !this.options.text ) {
6381
				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
6382
 
6383
				if ( !this.hasTitle ) {
6384
					buttonElement.attr( "title", $.trim( buttonText ) );
6385
				}
6386
			}
6387
		} else {
6388
			buttonClasses.push( "ui-button-text-only" );
6389
		}
6390
		buttonElement.addClass( buttonClasses.join( " " ) );
6391
	}
6392
});
6393
 
6394
$.widget( "ui.buttonset", {
6395
	version: "1.9.2",
6396
	options: {
6397
		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
6398
	},
6399
 
6400
	_create: function() {
6401
		this.element.addClass( "ui-buttonset" );
6402
	},
6403
 
6404
	_init: function() {
6405
		this.refresh();
6406
	},
6407
 
6408
	_setOption: function( key, value ) {
6409
		if ( key === "disabled" ) {
6410
			this.buttons.button( "option", key, value );
6411
		}
6412
 
6413
		this._super( key, value );
6414
	},
6415
 
6416
	refresh: function() {
6417
		var rtl = this.element.css( "direction" ) === "rtl";
6418
 
6419
		this.buttons = this.element.find( this.options.items )
6420
			.filter( ":ui-button" )
6421
				.button( "refresh" )
6422
			.end()
6423
			.not( ":ui-button" )
6424
				.button()
6425
			.end()
6426
			.map(function() {
6427
				return $( this ).button( "widget" )[ 0 ];
6428
			})
6429
				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
6430
				.filter( ":first" )
6431
					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
6432
				.end()
6433
				.filter( ":last" )
6434
					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
6435
				.end()
6436
			.end();
6437
	},
6438
 
6439
	_destroy: function() {
6440
		this.element.removeClass( "ui-buttonset" );
6441
		this.buttons
6442
			.map(function() {
6443
				return $( this ).button( "widget" )[ 0 ];
6444
			})
6445
				.removeClass( "ui-corner-left ui-corner-right" )
6446
			.end()
6447
			.button( "destroy" );
6448
	}
6449
});
6450
 
6451
}( jQuery ) );
6452
(function( $, undefined ) {
6453
 
6454
$.extend($.ui, { datepicker: { version: "1.9.2" } });
6455
 
6456
var PROP_NAME = 'datepicker';
6457
var dpuuid = new Date().getTime();
6458
var instActive;
6459
 
6460
/* Date picker manager.
6461
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
6462
   Settings for (groups of) date pickers are maintained in an instance object,
6463
   allowing multiple different settings on the same page. */
6464
 
6465
function Datepicker() {
6466
	this.debug = false; // Change this to true to start debugging
6467
	this._curInst = null; // The current instance in use
6468
	this._keyEvent = false; // If the last event was a key event
6469
	this._disabledInputs = []; // List of date picker inputs that have been disabled
6470
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
6471
	this._inDialog = false; // True if showing within a "dialog", false if not
6472
	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
6473
	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
6474
	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
6475
	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
6476
	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
6477
	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
6478
	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
6479
	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
6480
	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
6481
	this.regional = []; // Available regional settings, indexed by language code
6482
	this.regional[''] = { // Default regional settings
6483
		closeText: 'Done', // Display text for close link
6484
		prevText: 'Prev', // Display text for previous month link
6485
		nextText: 'Next', // Display text for next month link
6486
		currentText: 'Today', // Display text for current month link
6487
		monthNames: ['January','February','March','April','May','June',
6488
			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
6489
		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
6490
		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
6491
		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
6492
		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
6493
		weekHeader: 'Wk', // Column header for week of the year
6494
		dateFormat: 'mm/dd/yy', // See format options on parseDate
6495
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
6496
		isRTL: false, // True if right-to-left language, false if left-to-right
6497
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
6498
		yearSuffix: '' // Additional text to append to the year in the month headers
6499
	};
6500
	this._defaults = { // Global defaults for all the date picker instances
6501
		showOn: 'focus', // 'focus' for popup on focus,
6502
			// 'button' for trigger button, or 'both' for either
6503
		showAnim: 'fadeIn', // Name of jQuery animation for popup
6504
		showOptions: {}, // Options for enhanced animations
6505
		defaultDate: null, // Used when field is blank: actual date,
6506
			// +/-number for offset from today, null for today
6507
		appendText: '', // Display text following the input box, e.g. showing the format
6508
		buttonText: '...', // Text for trigger button
6509
		buttonImage: '', // URL for trigger button image
6510
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
6511
		hideIfNoPrevNext: false, // True to hide next/previous month links
6512
			// if not applicable, false to just disable them
6513
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
6514
		gotoCurrent: false, // True if today link goes back to current selection instead
6515
		changeMonth: false, // True if month can be selected directly, false if only prev/next
6516
		changeYear: false, // True if year can be selected directly, false if only prev/next
6517
		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
6518
			// either relative to today's year (-nn:+nn), relative to currently displayed year
6519
			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
6520
		showOtherMonths: false, // True to show dates in other months, false to leave blank
6521
		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
6522
		showWeek: false, // True to show week of the year, false to not show it
6523
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
6524
			// takes a Date and returns the number of the week for it
6525
		shortYearCutoff: '+10', // Short year values < this are in the current century,
6526
			// > this are in the previous century,
6527
			// string value starting with '+' for current year + value
6528
		minDate: null, // The earliest selectable date, or null for no limit
6529
		maxDate: null, // The latest selectable date, or null for no limit
6530
		duration: 'fast', // Duration of display/closure
6531
		beforeShowDay: null, // Function that takes a date and returns an array with
6532
			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
6533
			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
6534
		beforeShow: null, // Function that takes an input field and
6535
			// returns a set of custom settings for the date picker
6536
		onSelect: null, // Define a callback function when a date is selected
6537
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
6538
		onClose: null, // Define a callback function when the datepicker is closed
6539
		numberOfMonths: 1, // Number of months to show at a time
6540
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
6541
		stepMonths: 1, // Number of months to step back/forward
6542
		stepBigMonths: 12, // Number of months to step back/forward for the big links
6543
		altField: '', // Selector for an alternate field to store selected dates into
6544
		altFormat: '', // The date format to use for the alternate field
6545
		constrainInput: true, // The input is constrained by the current date format
6546
		showButtonPanel: false, // True to show button panel, false to not show it
6547
		autoSize: false, // True to size the input for the date format, false to leave as is
6548
		disabled: false // The initial disabled state
6549
	};
6550
	$.extend(this._defaults, this.regional['']);
6551
	this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
6552
}
6553
 
6554
$.extend(Datepicker.prototype, {
6555
	/* Class name added to elements to indicate already configured with a date picker. */
6556
	markerClassName: 'hasDatepicker',
6557
 
6558
	//Keep track of the maximum number of rows displayed (see #7043)
6559
	maxRows: 4,
6560
 
6561
	/* Debug logging (if enabled). */
6562
	log: function () {
6563
		if (this.debug)
6564
			console.log.apply('', arguments);
6565
	},
6566
 
6567
	// TODO rename to "widget" when switching to widget factory
6568
	_widgetDatepicker: function() {
6569
		return this.dpDiv;
6570
	},
6571
 
6572
	/* Override the default settings for all instances of the date picker.
6573
	   @param  settings  object - the new settings to use as defaults (anonymous object)
6574
	   @return the manager object */
6575
	setDefaults: function(settings) {
6576
		extendRemove(this._defaults, settings || {});
6577
		return this;
6578
	},
6579
 
6580
	/* Attach the date picker to a jQuery selection.
6581
	   @param  target    element - the target input field or division or span
6582
	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
6583
	_attachDatepicker: function(target, settings) {
6584
		// check for settings on the control itself - in namespace 'date:'
6585
		var inlineSettings = null;
6586
		for (var attrName in this._defaults) {
6587
			var attrValue = target.getAttribute('date:' + attrName);
6588
			if (attrValue) {
6589
				inlineSettings = inlineSettings || {};
6590
				try {
6591
					inlineSettings[attrName] = eval(attrValue);
6592
				} catch (err) {
6593
					inlineSettings[attrName] = attrValue;
6594
				}
6595
			}
6596
		}
6597
		var nodeName = target.nodeName.toLowerCase();
6598
		var inline = (nodeName == 'div' || nodeName == 'span');
6599
		if (!target.id) {
6600
			this.uuid += 1;
6601
			target.id = 'dp' + this.uuid;
6602
		}
6603
		var inst = this._newInst($(target), inline);
6604
		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
6605
		if (nodeName == 'input') {
6606
			this._connectDatepicker(target, inst);
6607
		} else if (inline) {
6608
			this._inlineDatepicker(target, inst);
6609
		}
6610
	},
6611
 
6612
	/* Create a new instance object. */
6613
	_newInst: function(target, inline) {
6614
		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
6615
		return {id: id, input: target, // associated target
6616
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
6617
			drawMonth: 0, drawYear: 0, // month being drawn
6618
			inline: inline, // is datepicker inline or not
6619
			dpDiv: (!inline ? this.dpDiv : // presentation div
6620
			bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
6621
	},
6622
 
6623
	/* Attach the date picker to an input field. */
6624
	_connectDatepicker: function(target, inst) {
6625
		var input = $(target);
6626
		inst.append = $([]);
6627
		inst.trigger = $([]);
6628
		if (input.hasClass(this.markerClassName))
6629
			return;
6630
		this._attachments(input, inst);
6631
		input.addClass(this.markerClassName).keydown(this._doKeyDown).
6632
			keypress(this._doKeyPress).keyup(this._doKeyUp).
6633
			bind("setData.datepicker", function(event, key, value) {
6634
				inst.settings[key] = value;
6635
			}).bind("getData.datepicker", function(event, key) {
6636
				return this._get(inst, key);
6637
			});
6638
		this._autoSize(inst);
6639
		$.data(target, PROP_NAME, inst);
6640
		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
6641
		if( inst.settings.disabled ) {
6642
			this._disableDatepicker( target );
6643
		}
6644
	},
6645
 
6646
	/* Make attachments based on settings. */
6647
	_attachments: function(input, inst) {
6648
		var appendText = this._get(inst, 'appendText');
6649
		var isRTL = this._get(inst, 'isRTL');
6650
		if (inst.append)
6651
			inst.append.remove();
6652
		if (appendText) {
6653
			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
6654
			input[isRTL ? 'before' : 'after'](inst.append);
6655
		}
6656
		input.unbind('focus', this._showDatepicker);
6657
		if (inst.trigger)
6658
			inst.trigger.remove();
6659
		var showOn = this._get(inst, 'showOn');
6660
		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
6661
			input.focus(this._showDatepicker);
6662
		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
6663
			var buttonText = this._get(inst, 'buttonText');
6664
			var buttonImage = this._get(inst, 'buttonImage');
6665
			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
6666
				$('<img/>').addClass(this._triggerClass).
6667
					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
6668
				$('<button type="button"></button>').addClass(this._triggerClass).
6669
					html(buttonImage == '' ? buttonText : $('<img/>').attr(
6670
					{ src:buttonImage, alt:buttonText, title:buttonText })));
6671
			input[isRTL ? 'before' : 'after'](inst.trigger);
6672
			inst.trigger.click(function() {
6673
				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
6674
					$.datepicker._hideDatepicker();
6675
				else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
6676
					$.datepicker._hideDatepicker();
6677
					$.datepicker._showDatepicker(input[0]);
6678
				} else
6679
					$.datepicker._showDatepicker(input[0]);
6680
				return false;
6681
			});
6682
		}
6683
	},
6684
 
6685
	/* Apply the maximum length for the date format. */
6686
	_autoSize: function(inst) {
6687
		if (this._get(inst, 'autoSize') && !inst.inline) {
6688
			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
6689
			var dateFormat = this._get(inst, 'dateFormat');
6690
			if (dateFormat.match(/[DM]/)) {
6691
				var findMax = function(names) {
6692
					var max = 0;
6693
					var maxI = 0;
6694
					for (var i = 0; i < names.length; i++) {
6695
						if (names[i].length > max) {
6696
							max = names[i].length;
6697
							maxI = i;
6698
						}
6699
					}
6700
					return maxI;
6701
				};
6702
				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
6703
					'monthNames' : 'monthNamesShort'))));
6704
				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
6705
					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
6706
			}
6707
			inst.input.attr('size', this._formatDate(inst, date).length);
6708
		}
6709
	},
6710
 
6711
	/* Attach an inline date picker to a div. */
6712
	_inlineDatepicker: function(target, inst) {
6713
		var divSpan = $(target);
6714
		if (divSpan.hasClass(this.markerClassName))
6715
			return;
6716
		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
6717
			bind("setData.datepicker", function(event, key, value){
6718
				inst.settings[key] = value;
6719
			}).bind("getData.datepicker", function(event, key){
6720
				return this._get(inst, key);
6721
			});
6722
		$.data(target, PROP_NAME, inst);
6723
		this._setDate(inst, this._getDefaultDate(inst), true);
6724
		this._updateDatepicker(inst);
6725
		this._updateAlternate(inst);
6726
		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
6727
		if( inst.settings.disabled ) {
6728
			this._disableDatepicker( target );
6729
		}
6730
		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
6731
		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
6732
		inst.dpDiv.css( "display", "block" );
6733
	},
6734
 
6735
	/* Pop-up the date picker in a "dialog" box.
6736
	   @param  input     element - ignored
6737
	   @param  date      string or Date - the initial date to display
6738
	   @param  onSelect  function - the function to call when a date is selected
6739
	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
6740
	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
6741
	                     event - with x/y coordinates or
6742
	                     leave empty for default (screen centre)
6743
	   @return the manager object */
6744
	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
6745
		var inst = this._dialogInst; // internal instance
6746
		if (!inst) {
6747
			this.uuid += 1;
6748
			var id = 'dp' + this.uuid;
6749
			this._dialogInput = $('<input type="text" id="' + id +
6750
				'" style="position: absolute; top: -100px; width: 0px;"/>');
6751
			this._dialogInput.keydown(this._doKeyDown);
6752
			$('body').append(this._dialogInput);
6753
			inst = this._dialogInst = this._newInst(this._dialogInput, false);
6754
			inst.settings = {};
6755
			$.data(this._dialogInput[0], PROP_NAME, inst);
6756
		}
6757
		extendRemove(inst.settings, settings || {});
6758
		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
6759
		this._dialogInput.val(date);
6760
 
6761
		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
6762
		if (!this._pos) {
6763
			var browserWidth = document.documentElement.clientWidth;
6764
			var browserHeight = document.documentElement.clientHeight;
6765
			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
6766
			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
6767
			this._pos = // should use actual width/height below
6768
				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
6769
		}
6770
 
6771
		// move input on screen for focus, but hidden behind dialog
6772
		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
6773
		inst.settings.onSelect = onSelect;
6774
		this._inDialog = true;
6775
		this.dpDiv.addClass(this._dialogClass);
6776
		this._showDatepicker(this._dialogInput[0]);
6777
		if ($.blockUI)
6778
			$.blockUI(this.dpDiv);
6779
		$.data(this._dialogInput[0], PROP_NAME, inst);
6780
		return this;
6781
	},
6782
 
6783
	/* Detach a datepicker from its control.
6784
	   @param  target    element - the target input field or division or span */
6785
	_destroyDatepicker: function(target) {
6786
		var $target = $(target);
6787
		var inst = $.data(target, PROP_NAME);
6788
		if (!$target.hasClass(this.markerClassName)) {
6789
			return;
6790
		}
6791
		var nodeName = target.nodeName.toLowerCase();
6792
		$.removeData(target, PROP_NAME);
6793
		if (nodeName == 'input') {
6794
			inst.append.remove();
6795
			inst.trigger.remove();
6796
			$target.removeClass(this.markerClassName).
6797
				unbind('focus', this._showDatepicker).
6798
				unbind('keydown', this._doKeyDown).
6799
				unbind('keypress', this._doKeyPress).
6800
				unbind('keyup', this._doKeyUp);
6801
		} else if (nodeName == 'div' || nodeName == 'span')
6802
			$target.removeClass(this.markerClassName).empty();
6803
	},
6804
 
6805
	/* Enable the date picker to a jQuery selection.
6806
	   @param  target    element - the target input field or division or span */
6807
	_enableDatepicker: function(target) {
6808
		var $target = $(target);
6809
		var inst = $.data(target, PROP_NAME);
6810
		if (!$target.hasClass(this.markerClassName)) {
6811
			return;
6812
		}
6813
		var nodeName = target.nodeName.toLowerCase();
6814
		if (nodeName == 'input') {
6815
			target.disabled = false;
6816
			inst.trigger.filter('button').
6817
				each(function() { this.disabled = false; }).end().
6818
				filter('img').css({opacity: '1.0', cursor: ''});
6819
		}
6820
		else if (nodeName == 'div' || nodeName == 'span') {
6821
			var inline = $target.children('.' + this._inlineClass);
6822
			inline.children().removeClass('ui-state-disabled');
6823
			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6824
				prop("disabled", false);
6825
		}
6826
		this._disabledInputs = $.map(this._disabledInputs,
6827
			function(value) { return (value == target ? null : value); }); // delete entry
6828
	},
6829
 
6830
	/* Disable the date picker to a jQuery selection.
6831
	   @param  target    element - the target input field or division or span */
6832
	_disableDatepicker: function(target) {
6833
		var $target = $(target);
6834
		var inst = $.data(target, PROP_NAME);
6835
		if (!$target.hasClass(this.markerClassName)) {
6836
			return;
6837
		}
6838
		var nodeName = target.nodeName.toLowerCase();
6839
		if (nodeName == 'input') {
6840
			target.disabled = true;
6841
			inst.trigger.filter('button').
6842
				each(function() { this.disabled = true; }).end().
6843
				filter('img').css({opacity: '0.5', cursor: 'default'});
6844
		}
6845
		else if (nodeName == 'div' || nodeName == 'span') {
6846
			var inline = $target.children('.' + this._inlineClass);
6847
			inline.children().addClass('ui-state-disabled');
6848
			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
6849
				prop("disabled", true);
6850
		}
6851
		this._disabledInputs = $.map(this._disabledInputs,
6852
			function(value) { return (value == target ? null : value); }); // delete entry
6853
		this._disabledInputs[this._disabledInputs.length] = target;
6854
	},
6855
 
6856
	/* Is the first field in a jQuery collection disabled as a datepicker?
6857
	   @param  target    element - the target input field or division or span
6858
	   @return boolean - true if disabled, false if enabled */
6859
	_isDisabledDatepicker: function(target) {
6860
		if (!target) {
6861
			return false;
6862
		}
6863
		for (var i = 0; i < this._disabledInputs.length; i++) {
6864
			if (this._disabledInputs[i] == target)
6865
				return true;
6866
		}
6867
		return false;
6868
	},
6869
 
6870
	/* Retrieve the instance data for the target control.
6871
	   @param  target  element - the target input field or division or span
6872
	   @return  object - the associated instance data
6873
	   @throws  error if a jQuery problem getting data */
6874
	_getInst: function(target) {
6875
		try {
6876
			return $.data(target, PROP_NAME);
6877
		}
6878
		catch (err) {
6879
			throw 'Missing instance data for this datepicker';
6880
		}
6881
	},
6882
 
6883
	/* Update or retrieve the settings for a date picker attached to an input field or division.
6884
	   @param  target  element - the target input field or division or span
6885
	   @param  name    object - the new settings to update or
6886
	                   string - the name of the setting to change or retrieve,
6887
	                   when retrieving also 'all' for all instance settings or
6888
	                   'defaults' for all global defaults
6889
	   @param  value   any - the new value for the setting
6890
	                   (omit if above is an object or to retrieve a value) */
6891
	_optionDatepicker: function(target, name, value) {
6892
		var inst = this._getInst(target);
6893
		if (arguments.length == 2 && typeof name == 'string') {
6894
			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
6895
				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
6896
				this._get(inst, name)) : null));
6897
		}
6898
		var settings = name || {};
6899
		if (typeof name == 'string') {
6900
			settings = {};
6901
			settings[name] = value;
6902
		}
6903
		if (inst) {
6904
			if (this._curInst == inst) {
6905
				this._hideDatepicker();
6906
			}
6907
			var date = this._getDateDatepicker(target, true);
6908
			var minDate = this._getMinMaxDate(inst, 'min');
6909
			var maxDate = this._getMinMaxDate(inst, 'max');
6910
			extendRemove(inst.settings, settings);
6911
			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
6912
			if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
6913
				inst.settings.minDate = this._formatDate(inst, minDate);
6914
			if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
6915
				inst.settings.maxDate = this._formatDate(inst, maxDate);
6916
			this._attachments($(target), inst);
6917
			this._autoSize(inst);
6918
			this._setDate(inst, date);
6919
			this._updateAlternate(inst);
6920
			this._updateDatepicker(inst);
6921
		}
6922
	},
6923
 
6924
	// change method deprecated
6925
	_changeDatepicker: function(target, name, value) {
6926
		this._optionDatepicker(target, name, value);
6927
	},
6928
 
6929
	/* Redraw the date picker attached to an input field or division.
6930
	   @param  target  element - the target input field or division or span */
6931
	_refreshDatepicker: function(target) {
6932
		var inst = this._getInst(target);
6933
		if (inst) {
6934
			this._updateDatepicker(inst);
6935
		}
6936
	},
6937
 
6938
	/* Set the dates for a jQuery selection.
6939
	   @param  target   element - the target input field or division or span
6940
	   @param  date     Date - the new date */
6941
	_setDateDatepicker: function(target, date) {
6942
		var inst = this._getInst(target);
6943
		if (inst) {
6944
			this._setDate(inst, date);
6945
			this._updateDatepicker(inst);
6946
			this._updateAlternate(inst);
6947
		}
6948
	},
6949
 
6950
	/* Get the date(s) for the first entry in a jQuery selection.
6951
	   @param  target     element - the target input field or division or span
6952
	   @param  noDefault  boolean - true if no default date is to be used
6953
	   @return Date - the current date */
6954
	_getDateDatepicker: function(target, noDefault) {
6955
		var inst = this._getInst(target);
6956
		if (inst && !inst.inline)
6957
			this._setDateFromField(inst, noDefault);
6958
		return (inst ? this._getDate(inst) : null);
6959
	},
6960
 
6961
	/* Handle keystrokes. */
6962
	_doKeyDown: function(event) {
6963
		var inst = $.datepicker._getInst(event.target);
6964
		var handled = true;
6965
		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
6966
		inst._keyEvent = true;
6967
		if ($.datepicker._datepickerShowing)
6968
			switch (event.keyCode) {
6969
				case 9: $.datepicker._hideDatepicker();
6970
						handled = false;
6971
						break; // hide on tab out
6972
				case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
6973
									$.datepicker._currentClass + ')', inst.dpDiv);
6974
						if (sel[0])
6975
							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
6976
							var onSelect = $.datepicker._get(inst, 'onSelect');
6977
							if (onSelect) {
6978
								var dateStr = $.datepicker._formatDate(inst);
6979
 
6980
								// trigger custom callback
6981
								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
6982
							}
6983
						else
6984
							$.datepicker._hideDatepicker();
6985
						return false; // don't submit the form
6986
						break; // select the value on enter
6987
				case 27: $.datepicker._hideDatepicker();
6988
						break; // hide on escape
6989
				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6990
							-$.datepicker._get(inst, 'stepBigMonths') :
6991
							-$.datepicker._get(inst, 'stepMonths')), 'M');
6992
						break; // previous month/year on page up/+ ctrl
6993
				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
6994
							+$.datepicker._get(inst, 'stepBigMonths') :
6995
							+$.datepicker._get(inst, 'stepMonths')), 'M');
6996
						break; // next month/year on page down/+ ctrl
6997
				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
6998
						handled = event.ctrlKey || event.metaKey;
6999
						break; // clear on ctrl or command +end
7000
				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7001
						handled = event.ctrlKey || event.metaKey;
7002
						break; // current on ctrl or command +home
7003
				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7004
						handled = event.ctrlKey || event.metaKey;
7005
						// -1 day on ctrl or command +left
7006
						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7007
									-$.datepicker._get(inst, 'stepBigMonths') :
7008
									-$.datepicker._get(inst, 'stepMonths')), 'M');
7009
						// next month/year on alt +left on Mac
7010
						break;
7011
				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7012
						handled = event.ctrlKey || event.metaKey;
7013
						break; // -1 week on ctrl or command +up
7014
				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7015
						handled = event.ctrlKey || event.metaKey;
7016
						// +1 day on ctrl or command +right
7017
						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7018
									+$.datepicker._get(inst, 'stepBigMonths') :
7019
									+$.datepicker._get(inst, 'stepMonths')), 'M');
7020
						// next month/year on alt +right
7021
						break;
7022
				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7023
						handled = event.ctrlKey || event.metaKey;
7024
						break; // +1 week on ctrl or command +down
7025
				default: handled = false;
7026
			}
7027
		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7028
			$.datepicker._showDatepicker(this);
7029
		else {
7030
			handled = false;
7031
		}
7032
		if (handled) {
7033
			event.preventDefault();
7034
			event.stopPropagation();
7035
		}
7036
	},
7037
 
7038
	/* Filter entered characters - based on date format. */
7039
	_doKeyPress: function(event) {
7040
		var inst = $.datepicker._getInst(event.target);
7041
		if ($.datepicker._get(inst, 'constrainInput')) {
7042
			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7043
			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7044
			return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7045
		}
7046
	},
7047
 
7048
	/* Synchronise manual entry and field/alternate field. */
7049
	_doKeyUp: function(event) {
7050
		var inst = $.datepicker._getInst(event.target);
7051
		if (inst.input.val() != inst.lastVal) {
7052
			try {
7053
				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7054
					(inst.input ? inst.input.val() : null),
7055
					$.datepicker._getFormatConfig(inst));
7056
				if (date) { // only if valid
7057
					$.datepicker._setDateFromField(inst);
7058
					$.datepicker._updateAlternate(inst);
7059
					$.datepicker._updateDatepicker(inst);
7060
				}
7061
			}
7062
			catch (err) {
7063
				$.datepicker.log(err);
7064
			}
7065
		}
7066
		return true;
7067
	},
7068
 
7069
	/* Pop-up the date picker for a given input field.
7070
	   If false returned from beforeShow event handler do not show.
7071
	   @param  input  element - the input field attached to the date picker or
7072
	                  event - if triggered by focus */
7073
	_showDatepicker: function(input) {
7074
		input = input.target || input;
7075
		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7076
			input = $('input', input.parentNode)[0];
7077
		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7078
			return;
7079
		var inst = $.datepicker._getInst(input);
7080
		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7081
			$.datepicker._curInst.dpDiv.stop(true, true);
7082
			if ( inst && $.datepicker._datepickerShowing ) {
7083
				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7084
			}
7085
		}
7086
		var beforeShow = $.datepicker._get(inst, 'beforeShow');
7087
		var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7088
		if(beforeShowSettings === false){
7089
			//false
7090
			return;
7091
		}
7092
		extendRemove(inst.settings, beforeShowSettings);
7093
		inst.lastVal = null;
7094
		$.datepicker._lastInput = input;
7095
		$.datepicker._setDateFromField(inst);
7096
		if ($.datepicker._inDialog) // hide cursor
7097
			input.value = '';
7098
		if (!$.datepicker._pos) { // position below input
7099
			$.datepicker._pos = $.datepicker._findPos(input);
7100
			$.datepicker._pos[1] += input.offsetHeight; // add the height
7101
		}
7102
		var isFixed = false;
7103
		$(input).parents().each(function() {
7104
			isFixed |= $(this).css('position') == 'fixed';
7105
			return !isFixed;
7106
		});
7107
		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7108
		$.datepicker._pos = null;
7109
		//to avoid flashes on Firefox
7110
		inst.dpDiv.empty();
7111
		// determine sizing offscreen
7112
		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7113
		$.datepicker._updateDatepicker(inst);
7114
		// fix width for dynamic number of date pickers
7115
		// and adjust position before showing
7116
		offset = $.datepicker._checkOffset(inst, offset, isFixed);
7117
		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7118
			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7119
			left: offset.left + 'px', top: offset.top + 'px'});
7120
		if (!inst.inline) {
7121
			var showAnim = $.datepicker._get(inst, 'showAnim');
7122
			var duration = $.datepicker._get(inst, 'duration');
7123
			var postProcess = function() {
7124
				var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7125
				if( !! cover.length ){
7126
					var borders = $.datepicker._getBorders(inst.dpDiv);
7127
					cover.css({left: -borders[0], top: -borders[1],
7128
						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7129
				}
7130
			};
7131
			inst.dpDiv.zIndex($(input).zIndex()+1);
7132
			$.datepicker._datepickerShowing = true;
7133
 
7134
			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7135
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
7136
				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7137
			else
7138
				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7139
			if (!showAnim || !duration)
7140
				postProcess();
7141
			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7142
				inst.input.focus();
7143
			$.datepicker._curInst = inst;
7144
		}
7145
	},
7146
 
7147
	/* Generate the date picker content. */
7148
	_updateDatepicker: function(inst) {
7149
		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7150
		var borders = $.datepicker._getBorders(inst.dpDiv);
7151
		instActive = inst; // for delegate hover events
7152
		inst.dpDiv.empty().append(this._generateHTML(inst));
7153
		this._attachHandlers(inst);
7154
		var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7155
		if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7156
			cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7157
		}
7158
		inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
7159
		var numMonths = this._getNumberOfMonths(inst);
7160
		var cols = numMonths[1];
7161
		var width = 17;
7162
		inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
7163
		if (cols > 1)
7164
			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
7165
		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
7166
			'Class']('ui-datepicker-multi');
7167
		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
7168
			'Class']('ui-datepicker-rtl');
7169
		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
7170
				// #6694 - don't focus the input if it's already focused
7171
				// this breaks the change event in IE
7172
				inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
7173
			inst.input.focus();
7174
		// deffered render of the years select (to avoid flashes on Firefox)
7175
		if( inst.yearshtml ){
7176
			var origyearshtml = inst.yearshtml;
7177
			setTimeout(function(){
7178
				//assure that inst.yearshtml didn't change.
7179
				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7180
					inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
7181
				}
7182
				origyearshtml = inst.yearshtml = null;
7183
			}, 0);
7184
		}
7185
	},
7186
 
7187
	/* Retrieve the size of left and top borders for an element.
7188
	   @param  elem  (jQuery object) the element of interest
7189
	   @return  (number[2]) the left and top borders */
7190
	_getBorders: function(elem) {
7191
		var convert = function(value) {
7192
			return {thin: 1, medium: 2, thick: 3}[value] || value;
7193
		};
7194
		return [parseFloat(convert(elem.css('border-left-width'))),
7195
			parseFloat(convert(elem.css('border-top-width')))];
7196
	},
7197
 
7198
	/* Check positioning to remain on screen. */
7199
	_checkOffset: function(inst, offset, isFixed) {
7200
		var dpWidth = inst.dpDiv.outerWidth();
7201
		var dpHeight = inst.dpDiv.outerHeight();
7202
		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
7203
		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
7204
		var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
7205
		var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7206
 
7207
		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
7208
		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
7209
		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7210
 
7211
		// now check if datepicker is showing outside window viewport - move to a better place if so.
7212
		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7213
			Math.abs(offset.left + dpWidth - viewWidth) : 0);
7214
		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7215
			Math.abs(dpHeight + inputHeight) : 0);
7216
 
7217
		return offset;
7218
	},
7219
 
7220
	/* Find an object's position on the screen. */
7221
	_findPos: function(obj) {
7222
		var inst = this._getInst(obj);
7223
		var isRTL = this._get(inst, 'isRTL');
7224
		while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
7225
			obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
7226
		}
7227
		var position = $(obj).offset();
7228
		return [position.left, position.top];
7229
	},
7230
 
7231
	/* Hide the date picker from view.
7232
	   @param  input  element - the input field attached to the date picker */
7233
	_hideDatepicker: function(input) {
7234
		var inst = this._curInst;
7235
		if (!inst || (input && inst != $.data(input, PROP_NAME)))
7236
			return;
7237
		if (this._datepickerShowing) {
7238
			var showAnim = this._get(inst, 'showAnim');
7239
			var duration = this._get(inst, 'duration');
7240
			var postProcess = function() {
7241
				$.datepicker._tidyDialog(inst);
7242
			};
7243
 
7244
			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7245
			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
7246
				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7247
			else
7248
				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
7249
					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
7250
			if (!showAnim)
7251
				postProcess();
7252
			this._datepickerShowing = false;
7253
			var onClose = this._get(inst, 'onClose');
7254
			if (onClose)
7255
				onClose.apply((inst.input ? inst.input[0] : null),
7256
					[(inst.input ? inst.input.val() : ''), inst]);
7257
			this._lastInput = null;
7258
			if (this._inDialog) {
7259
				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
7260
				if ($.blockUI) {
7261
					$.unblockUI();
7262
					$('body').append(this.dpDiv);
7263
				}
7264
			}
7265
			this._inDialog = false;
7266
		}
7267
	},
7268
 
7269
	/* Tidy up after a dialog display. */
7270
	_tidyDialog: function(inst) {
7271
		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
7272
	},
7273
 
7274
	/* Close date picker if clicked elsewhere. */
7275
	_checkExternalClick: function(event) {
7276
		if (!$.datepicker._curInst)
7277
			return;
7278
 
7279
		var $target = $(event.target),
7280
			inst = $.datepicker._getInst($target[0]);
7281
 
7282
		if ( ( ( $target[0].id != $.datepicker._mainDivId &&
7283
				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
7284
				!$target.hasClass($.datepicker.markerClassName) &&
7285
				!$target.closest("." + $.datepicker._triggerClass).length &&
7286
				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
7287
			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
7288
			$.datepicker._hideDatepicker();
7289
	},
7290
 
7291
	/* Adjust one of the date sub-fields. */
7292
	_adjustDate: function(id, offset, period) {
7293
		var target = $(id);
7294
		var inst = this._getInst(target[0]);
7295
		if (this._isDisabledDatepicker(target[0])) {
7296
			return;
7297
		}
7298
		this._adjustInstDate(inst, offset +
7299
			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
7300
			period);
7301
		this._updateDatepicker(inst);
7302
	},
7303
 
7304
	/* Action for current link. */
7305
	_gotoToday: function(id) {
7306
		var target = $(id);
7307
		var inst = this._getInst(target[0]);
7308
		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
7309
			inst.selectedDay = inst.currentDay;
7310
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
7311
			inst.drawYear = inst.selectedYear = inst.currentYear;
7312
		}
7313
		else {
7314
			var date = new Date();
7315
			inst.selectedDay = date.getDate();
7316
			inst.drawMonth = inst.selectedMonth = date.getMonth();
7317
			inst.drawYear = inst.selectedYear = date.getFullYear();
7318
		}
7319
		this._notifyChange(inst);
7320
		this._adjustDate(target);
7321
	},
7322
 
7323
	/* Action for selecting a new month/year. */
7324
	_selectMonthYear: function(id, select, period) {
7325
		var target = $(id);
7326
		var inst = this._getInst(target[0]);
7327
		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
7328
		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
7329
			parseInt(select.options[select.selectedIndex].value,10);
7330
		this._notifyChange(inst);
7331
		this._adjustDate(target);
7332
	},
7333
 
7334
	/* Action for selecting a day. */
7335
	_selectDay: function(id, month, year, td) {
7336
		var target = $(id);
7337
		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7338
			return;
7339
		}
7340
		var inst = this._getInst(target[0]);
7341
		inst.selectedDay = inst.currentDay = $('a', td).html();
7342
		inst.selectedMonth = inst.currentMonth = month;
7343
		inst.selectedYear = inst.currentYear = year;
7344
		this._selectDate(id, this._formatDate(inst,
7345
			inst.currentDay, inst.currentMonth, inst.currentYear));
7346
	},
7347
 
7348
	/* Erase the input field and hide the date picker. */
7349
	_clearDate: function(id) {
7350
		var target = $(id);
7351
		var inst = this._getInst(target[0]);
7352
		this._selectDate(target, '');
7353
	},
7354
 
7355
	/* Update the input field with the selected date. */
7356
	_selectDate: function(id, dateStr) {
7357
		var target = $(id);
7358
		var inst = this._getInst(target[0]);
7359
		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7360
		if (inst.input)
7361
			inst.input.val(dateStr);
7362
		this._updateAlternate(inst);
7363
		var onSelect = this._get(inst, 'onSelect');
7364
		if (onSelect)
7365
			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
7366
		else if (inst.input)
7367
			inst.input.trigger('change'); // fire the change event
7368
		if (inst.inline)
7369
			this._updateDatepicker(inst);
7370
		else {
7371
			this._hideDatepicker();
7372
			this._lastInput = inst.input[0];
7373
			if (typeof(inst.input[0]) != 'object')
7374
				inst.input.focus(); // restore focus
7375
			this._lastInput = null;
7376
		}
7377
	},
7378
 
7379
	/* Update any alternate field to synchronise with the main field. */
7380
	_updateAlternate: function(inst) {
7381
		var altField = this._get(inst, 'altField');
7382
		if (altField) { // update alternate field too
7383
			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
7384
			var date = this._getDate(inst);
7385
			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7386
			$(altField).each(function() { $(this).val(dateStr); });
7387
		}
7388
	},
7389
 
7390
	/* Set as beforeShowDay function to prevent selection of weekends.
7391
	   @param  date  Date - the date to customise
7392
	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
7393
	noWeekends: function(date) {
7394
		var day = date.getDay();
7395
		return [(day > 0 && day < 6), ''];
7396
	},
7397
 
7398
	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7399
	   @param  date  Date - the date to get the week for
7400
	   @return  number - the number of the week within the year that contains this date */
7401
	iso8601Week: function(date) {
7402
		var checkDate = new Date(date.getTime());
7403
		// Find Thursday of this week starting on Monday
7404
		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7405
		var time = checkDate.getTime();
7406
		checkDate.setMonth(0); // Compare with Jan 1
7407
		checkDate.setDate(1);
7408
		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7409
	},
7410
 
7411
	/* Parse a string value into a date object.
7412
	   See formatDate below for the possible formats.
7413
 
7414
	   @param  format    string - the expected format of the date
7415
	   @param  value     string - the date in the above format
7416
	   @param  settings  Object - attributes include:
7417
	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
7418
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
7419
	                     dayNames         string[7] - names of the days from Sunday (optional)
7420
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
7421
	                     monthNames       string[12] - names of the months (optional)
7422
	   @return  Date - the extracted date value or null if value is blank */
7423
	parseDate: function (format, value, settings) {
7424
		if (format == null || value == null)
7425
			throw 'Invalid arguments';
7426
		value = (typeof value == 'object' ? value.toString() : value + '');
7427
		if (value == '')
7428
			return null;
7429
		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
7430
		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
7431
				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
7432
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
7433
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
7434
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
7435
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
7436
		var year = -1;
7437
		var month = -1;
7438
		var day = -1;
7439
		var doy = -1;
7440
		var literal = false;
7441
		// Check whether a format character is doubled
7442
		var lookAhead = function(match) {
7443
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7444
			if (matches)
7445
				iFormat++;
7446
			return matches;
7447
		};
7448
		// Extract a number from the string value
7449
		var getNumber = function(match) {
7450
			var isDoubled = lookAhead(match);
7451
			var size = (match == '@' ? 14 : (match == '!' ? 20 :
7452
				(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
7453
			var digits = new RegExp('^\\d{1,' + size + '}');
7454
			var num = value.substring(iValue).match(digits);
7455
			if (!num)
7456
				throw 'Missing number at position ' + iValue;
7457
			iValue += num[0].length;
7458
			return parseInt(num[0], 10);
7459
		};
7460
		// Extract a name from the string value and convert to an index
7461
		var getName = function(match, shortNames, longNames) {
7462
			var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
7463
				return [ [k, v] ];
7464
			}).sort(function (a, b) {
7465
				return -(a[1].length - b[1].length);
7466
			});
7467
			var index = -1;
7468
			$.each(names, function (i, pair) {
7469
				var name = pair[1];
7470
				if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
7471
					index = pair[0];
7472
					iValue += name.length;
7473
					return false;
7474
				}
7475
			});
7476
			if (index != -1)
7477
				return index + 1;
7478
			else
7479
				throw 'Unknown name at position ' + iValue;
7480
		};
7481
		// Confirm that a literal character matches the string value
7482
		var checkLiteral = function() {
7483
			if (value.charAt(iValue) != format.charAt(iFormat))
7484
				throw 'Unexpected literal at position ' + iValue;
7485
			iValue++;
7486
		};
7487
		var iValue = 0;
7488
		for (var iFormat = 0; iFormat < format.length; iFormat++) {
7489
			if (literal)
7490
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7491
					literal = false;
7492
				else
7493
					checkLiteral();
7494
			else
7495
				switch (format.charAt(iFormat)) {
7496
					case 'd':
7497
						day = getNumber('d');
7498
						break;
7499
					case 'D':
7500
						getName('D', dayNamesShort, dayNames);
7501
						break;
7502
					case 'o':
7503
						doy = getNumber('o');
7504
						break;
7505
					case 'm':
7506
						month = getNumber('m');
7507
						break;
7508
					case 'M':
7509
						month = getName('M', monthNamesShort, monthNames);
7510
						break;
7511
					case 'y':
7512
						year = getNumber('y');
7513
						break;
7514
					case '@':
7515
						var date = new Date(getNumber('@'));
7516
						year = date.getFullYear();
7517
						month = date.getMonth() + 1;
7518
						day = date.getDate();
7519
						break;
7520
					case '!':
7521
						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
7522
						year = date.getFullYear();
7523
						month = date.getMonth() + 1;
7524
						day = date.getDate();
7525
						break;
7526
					case "'":
7527
						if (lookAhead("'"))
7528
							checkLiteral();
7529
						else
7530
							literal = true;
7531
						break;
7532
					default:
7533
						checkLiteral();
7534
				}
7535
		}
7536
		if (iValue < value.length){
7537
			var extra = value.substr(iValue);
7538
			if (!/^\s+/.test(extra)) {
7539
				throw "Extra/unparsed characters found in date: " + extra;
7540
			}
7541
		}
7542
		if (year == -1)
7543
			year = new Date().getFullYear();
7544
		else if (year < 100)
7545
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
7546
				(year <= shortYearCutoff ? 0 : -100);
7547
		if (doy > -1) {
7548
			month = 1;
7549
			day = doy;
7550
			do {
7551
				var dim = this._getDaysInMonth(year, month - 1);
7552
				if (day <= dim)
7553
					break;
7554
				month++;
7555
				day -= dim;
7556
			} while (true);
7557
		}
7558
		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
7559
		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
7560
			throw 'Invalid date'; // E.g. 31/02/00
7561
		return date;
7562
	},
7563
 
7564
	/* Standard date formats. */
7565
	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
7566
	COOKIE: 'D, dd M yy',
7567
	ISO_8601: 'yy-mm-dd',
7568
	RFC_822: 'D, d M y',
7569
	RFC_850: 'DD, dd-M-y',
7570
	RFC_1036: 'D, d M y',
7571
	RFC_1123: 'D, d M yy',
7572
	RFC_2822: 'D, d M yy',
7573
	RSS: 'D, d M y', // RFC 822
7574
	TICKS: '!',
7575
	TIMESTAMP: '@',
7576
	W3C: 'yy-mm-dd', // ISO 8601
7577
 
7578
	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
7579
		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
7580
 
7581
	/* Format a date object into a string value.
7582
	   The format can be combinations of the following:
7583
	   d  - day of month (no leading zero)
7584
	   dd - day of month (two digit)
7585
	   o  - day of year (no leading zeros)
7586
	   oo - day of year (three digit)
7587
	   D  - day name short
7588
	   DD - day name long
7589
	   m  - month of year (no leading zero)
7590
	   mm - month of year (two digit)
7591
	   M  - month name short
7592
	   MM - month name long
7593
	   y  - year (two digit)
7594
	   yy - year (four digit)
7595
	   @ - Unix timestamp (ms since 01/01/1970)
7596
	   ! - Windows ticks (100ns since 01/01/0001)
7597
	   '...' - literal text
7598
	   '' - single quote
7599
 
7600
	   @param  format    string - the desired format of the date
7601
	   @param  date      Date - the date value to format
7602
	   @param  settings  Object - attributes include:
7603
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
7604
	                     dayNames         string[7] - names of the days from Sunday (optional)
7605
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
7606
	                     monthNames       string[12] - names of the months (optional)
7607
	   @return  string - the date in the above format */
7608
	formatDate: function (format, date, settings) {
7609
		if (!date)
7610
			return '';
7611
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
7612
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
7613
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
7614
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
7615
		// Check whether a format character is doubled
7616
		var lookAhead = function(match) {
7617
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7618
			if (matches)
7619
				iFormat++;
7620
			return matches;
7621
		};
7622
		// Format a number, with leading zero if necessary
7623
		var formatNumber = function(match, value, len) {
7624
			var num = '' + value;
7625
			if (lookAhead(match))
7626
				while (num.length < len)
7627
					num = '0' + num;
7628
			return num;
7629
		};
7630
		// Format a name, short or long as requested
7631
		var formatName = function(match, value, shortNames, longNames) {
7632
			return (lookAhead(match) ? longNames[value] : shortNames[value]);
7633
		};
7634
		var output = '';
7635
		var literal = false;
7636
		if (date)
7637
			for (var iFormat = 0; iFormat < format.length; iFormat++) {
7638
				if (literal)
7639
					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7640
						literal = false;
7641
					else
7642
						output += format.charAt(iFormat);
7643
				else
7644
					switch (format.charAt(iFormat)) {
7645
						case 'd':
7646
							output += formatNumber('d', date.getDate(), 2);
7647
							break;
7648
						case 'D':
7649
							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
7650
							break;
7651
						case 'o':
7652
							output += formatNumber('o',
7653
								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
7654
							break;
7655
						case 'm':
7656
							output += formatNumber('m', date.getMonth() + 1, 2);
7657
							break;
7658
						case 'M':
7659
							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
7660
							break;
7661
						case 'y':
7662
							output += (lookAhead('y') ? date.getFullYear() :
7663
								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
7664
							break;
7665
						case '@':
7666
							output += date.getTime();
7667
							break;
7668
						case '!':
7669
							output += date.getTime() * 10000 + this._ticksTo1970;
7670
							break;
7671
						case "'":
7672
							if (lookAhead("'"))
7673
								output += "'";
7674
							else
7675
								literal = true;
7676
							break;
7677
						default:
7678
							output += format.charAt(iFormat);
7679
					}
7680
			}
7681
		return output;
7682
	},
7683
 
7684
	/* Extract all possible characters from the date format. */
7685
	_possibleChars: function (format) {
7686
		var chars = '';
7687
		var literal = false;
7688
		// Check whether a format character is doubled
7689
		var lookAhead = function(match) {
7690
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
7691
			if (matches)
7692
				iFormat++;
7693
			return matches;
7694
		};
7695
		for (var iFormat = 0; iFormat < format.length; iFormat++)
7696
			if (literal)
7697
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
7698
					literal = false;
7699
				else
7700
					chars += format.charAt(iFormat);
7701
			else
7702
				switch (format.charAt(iFormat)) {
7703
					case 'd': case 'm': case 'y': case '@':
7704
						chars += '0123456789';
7705
						break;
7706
					case 'D': case 'M':
7707
						return null; // Accept anything
7708
					case "'":
7709
						if (lookAhead("'"))
7710
							chars += "'";
7711
						else
7712
							literal = true;
7713
						break;
7714
					default:
7715
						chars += format.charAt(iFormat);
7716
				}
7717
		return chars;
7718
	},
7719
 
7720
	/* Get a setting value, defaulting if necessary. */
7721
	_get: function(inst, name) {
7722
		return inst.settings[name] !== undefined ?
7723
			inst.settings[name] : this._defaults[name];
7724
	},
7725
 
7726
	/* Parse existing date and initialise date picker. */
7727
	_setDateFromField: function(inst, noDefault) {
7728
		if (inst.input.val() == inst.lastVal) {
7729
			return;
7730
		}
7731
		var dateFormat = this._get(inst, 'dateFormat');
7732
		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
7733
		var date, defaultDate;
7734
		date = defaultDate = this._getDefaultDate(inst);
7735
		var settings = this._getFormatConfig(inst);
7736
		try {
7737
			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
7738
		} catch (event) {
7739
			this.log(event);
7740
			dates = (noDefault ? '' : dates);
7741
		}
7742
		inst.selectedDay = date.getDate();
7743
		inst.drawMonth = inst.selectedMonth = date.getMonth();
7744
		inst.drawYear = inst.selectedYear = date.getFullYear();
7745
		inst.currentDay = (dates ? date.getDate() : 0);
7746
		inst.currentMonth = (dates ? date.getMonth() : 0);
7747
		inst.currentYear = (dates ? date.getFullYear() : 0);
7748
		this._adjustInstDate(inst);
7749
	},
7750
 
7751
	/* Retrieve the default date shown on opening. */
7752
	_getDefaultDate: function(inst) {
7753
		return this._restrictMinMax(inst,
7754
			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
7755
	},
7756
 
7757
	/* A date may be specified as an exact value or a relative one. */
7758
	_determineDate: function(inst, date, defaultDate) {
7759
		var offsetNumeric = function(offset) {
7760
			var date = new Date();
7761
			date.setDate(date.getDate() + offset);
7762
			return date;
7763
		};
7764
		var offsetString = function(offset) {
7765
			try {
7766
				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7767
					offset, $.datepicker._getFormatConfig(inst));
7768
			}
7769
			catch (e) {
7770
				// Ignore
7771
			}
7772
			var date = (offset.toLowerCase().match(/^c/) ?
7773
				$.datepicker._getDate(inst) : null) || new Date();
7774
			var year = date.getFullYear();
7775
			var month = date.getMonth();
7776
			var day = date.getDate();
7777
			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
7778
			var matches = pattern.exec(offset);
7779
			while (matches) {
7780
				switch (matches[2] || 'd') {
7781
					case 'd' : case 'D' :
7782
						day += parseInt(matches[1],10); break;
7783
					case 'w' : case 'W' :
7784
						day += parseInt(matches[1],10) * 7; break;
7785
					case 'm' : case 'M' :
7786
						month += parseInt(matches[1],10);
7787
						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
7788
						break;
7789
					case 'y': case 'Y' :
7790
						year += parseInt(matches[1],10);
7791
						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
7792
						break;
7793
				}
7794
				matches = pattern.exec(offset);
7795
			}
7796
			return new Date(year, month, day);
7797
		};
7798
		var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
7799
			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
7800
		newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
7801
		if (newDate) {
7802
			newDate.setHours(0);
7803
			newDate.setMinutes(0);
7804
			newDate.setSeconds(0);
7805
			newDate.setMilliseconds(0);
7806
		}
7807
		return this._daylightSavingAdjust(newDate);
7808
	},
7809
 
7810
	/* Handle switch to/from daylight saving.
7811
	   Hours may be non-zero on daylight saving cut-over:
7812
	   > 12 when midnight changeover, but then cannot generate
7813
	   midnight datetime, so jump to 1AM, otherwise reset.
7814
	   @param  date  (Date) the date to check
7815
	   @return  (Date) the corrected date */
7816
	_daylightSavingAdjust: function(date) {
7817
		if (!date) return null;
7818
		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
7819
		return date;
7820
	},
7821
 
7822
	/* Set the date(s) directly. */
7823
	_setDate: function(inst, date, noChange) {
7824
		var clear = !date;
7825
		var origMonth = inst.selectedMonth;
7826
		var origYear = inst.selectedYear;
7827
		var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
7828
		inst.selectedDay = inst.currentDay = newDate.getDate();
7829
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
7830
		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
7831
		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
7832
			this._notifyChange(inst);
7833
		this._adjustInstDate(inst);
7834
		if (inst.input) {
7835
			inst.input.val(clear ? '' : this._formatDate(inst));
7836
		}
7837
	},
7838
 
7839
	/* Retrieve the date(s) directly. */
7840
	_getDate: function(inst) {
7841
		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
7842
			this._daylightSavingAdjust(new Date(
7843
			inst.currentYear, inst.currentMonth, inst.currentDay)));
7844
			return startDate;
7845
	},
7846
 
7847
	/* Attach the onxxx handlers.  These are declared statically so
7848
	 * they work with static code transformers like Caja.
7849
	 */
7850
	_attachHandlers: function(inst) {
7851
		var stepMonths = this._get(inst, 'stepMonths');
7852
		var id = '#' + inst.id.replace( /\\\\/g, "\\" );
7853
		inst.dpDiv.find('[data-handler]').map(function () {
7854
			var handler = {
7855
				prev: function () {
7856
					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
7857
				},
7858
				next: function () {
7859
					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
7860
				},
7861
				hide: function () {
7862
					window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
7863
				},
7864
				today: function () {
7865
					window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
7866
				},
7867
				selectDay: function () {
7868
					window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
7869
					return false;
7870
				},
7871
				selectMonth: function () {
7872
					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
7873
					return false;
7874
				},
7875
				selectYear: function () {
7876
					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
7877
					return false;
7878
				}
7879
			};
7880
			$(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
7881
		});
7882
	},
7883
 
7884
	/* Generate the HTML for the current state of the date picker. */
7885
	_generateHTML: function(inst) {
7886
		var today = new Date();
7887
		today = this._daylightSavingAdjust(
7888
			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
7889
		var isRTL = this._get(inst, 'isRTL');
7890
		var showButtonPanel = this._get(inst, 'showButtonPanel');
7891
		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
7892
		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
7893
		var numMonths = this._getNumberOfMonths(inst);
7894
		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
7895
		var stepMonths = this._get(inst, 'stepMonths');
7896
		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
7897
		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
7898
			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
7899
		var minDate = this._getMinMaxDate(inst, 'min');
7900
		var maxDate = this._getMinMaxDate(inst, 'max');
7901
		var drawMonth = inst.drawMonth - showCurrentAtPos;
7902
		var drawYear = inst.drawYear;
7903
		if (drawMonth < 0) {
7904
			drawMonth += 12;
7905
			drawYear--;
7906
		}
7907
		if (maxDate) {
7908
			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
7909
				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
7910
			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
7911
			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
7912
				drawMonth--;
7913
				if (drawMonth < 0) {
7914
					drawMonth = 11;
7915
					drawYear--;
7916
				}
7917
			}
7918
		}
7919
		inst.drawMonth = drawMonth;
7920
		inst.drawYear = drawYear;
7921
		var prevText = this._get(inst, 'prevText');
7922
		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
7923
			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
7924
			this._getFormatConfig(inst)));
7925
		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
7926
			'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
7927
			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
7928
			(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>'));
7929
		var nextText = this._get(inst, 'nextText');
7930
		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
7931
			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
7932
			this._getFormatConfig(inst)));
7933
		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
7934
			'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
7935
			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
7936
			(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>'));
7937
		var currentText = this._get(inst, 'currentText');
7938
		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
7939
		currentText = (!navigationAsDateFormat ? currentText :
7940
			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
7941
		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">' +
7942
			this._get(inst, 'closeText') + '</button>' : '');
7943
		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
7944
			(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"' +
7945
			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
7946
		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
7947
		firstDay = (isNaN(firstDay) ? 0 : firstDay);
7948
		var showWeek = this._get(inst, 'showWeek');
7949
		var dayNames = this._get(inst, 'dayNames');
7950
		var dayNamesShort = this._get(inst, 'dayNamesShort');
7951
		var dayNamesMin = this._get(inst, 'dayNamesMin');
7952
		var monthNames = this._get(inst, 'monthNames');
7953
		var monthNamesShort = this._get(inst, 'monthNamesShort');
7954
		var beforeShowDay = this._get(inst, 'beforeShowDay');
7955
		var showOtherMonths = this._get(inst, 'showOtherMonths');
7956
		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
7957
		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
7958
		var defaultDate = this._getDefaultDate(inst);
7959
		var html = '';
7960
		for (var row = 0; row < numMonths[0]; row++) {
7961
			var group = '';
7962
			this.maxRows = 4;
7963
			for (var col = 0; col < numMonths[1]; col++) {
7964
				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
7965
				var cornerClass = ' ui-corner-all';
7966
				var calender = '';
7967
				if (isMultiMonth) {
7968
					calender += '<div class="ui-datepicker-group';
7969
					if (numMonths[1] > 1)
7970
						switch (col) {
7971
							case 0: calender += ' ui-datepicker-group-first';
7972
								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
7973
							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
7974
								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
7975
							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
7976
						}
7977
					calender += '">';
7978
				}
7979
				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
7980
					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
7981
					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
7982
					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
7983
					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
7984
					'</div><table class="ui-datepicker-calendar"><thead>' +
7985
					'<tr>';
7986
				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
7987
				for (var dow = 0; dow < 7; dow++) { // days of the week
7988
					var day = (dow + firstDay) % 7;
7989
					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
7990
						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
7991
				}
7992
				calender += thead + '</tr></thead><tbody>';
7993
				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
7994
				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
7995
					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
7996
				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
7997
				var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
7998
				var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
7999
				this.maxRows = numRows;
8000
				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8001
				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8002
					calender += '<tr>';
8003
					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8004
						this._get(inst, 'calculateWeek')(printDate) + '</td>');
8005
					for (var dow = 0; dow < 7; dow++) { // create date picker days
8006
						var daySettings = (beforeShowDay ?
8007
							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8008
						var otherMonth = (printDate.getMonth() != drawMonth);
8009
						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8010
							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8011
						tbody += '<td class="' +
8012
							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8013
							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8014
							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8015
							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8016
							// or defaultDate is current printedDate and defaultDate is selectedDate
8017
							' ' + this._dayOverClass : '') + // highlight selected day
8018
							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
8019
							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8020
							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8021
							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8022
							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8023
							(unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
8024
							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
8025
							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8026
							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8027
							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8028
							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8029
							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8030
						printDate.setDate(printDate.getDate() + 1);
8031
						printDate = this._daylightSavingAdjust(printDate);
8032
					}
8033
					calender += tbody + '</tr>';
8034
				}
8035
				drawMonth++;
8036
				if (drawMonth > 11) {
8037
					drawMonth = 0;
8038
					drawYear++;
8039
				}
8040
				calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
8041
							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8042
				group += calender;
8043
			}
8044
			html += group;
8045
		}
8046
		html += buttonPanel + ($.ui.ie6 && !inst.inline ?
8047
			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8048
		inst._keyEvent = false;
8049
		return html;
8050
	},
8051
 
8052
	/* Generate the month and year header. */
8053
	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8054
			secondary, monthNames, monthNamesShort) {
8055
		var changeMonth = this._get(inst, 'changeMonth');
8056
		var changeYear = this._get(inst, 'changeYear');
8057
		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8058
		var html = '<div class="ui-datepicker-title">';
8059
		var monthHtml = '';
8060
		// month selection
8061
		if (secondary || !changeMonth)
8062
			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8063
		else {
8064
			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8065
			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8066
			monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
8067
			for (var month = 0; month < 12; month++) {
8068
				if ((!inMinYear || month >= minDate.getMonth()) &&
8069
						(!inMaxYear || month <= maxDate.getMonth()))
8070
					monthHtml += '<option value="' + month + '"' +
8071
						(month == drawMonth ? ' selected="selected"' : '') +
8072
						'>' + monthNamesShort[month] + '</option>';
8073
			}
8074
			monthHtml += '</select>';
8075
		}
8076
		if (!showMonthAfterYear)
8077
			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
8078
		// year selection
8079
		if ( !inst.yearshtml ) {
8080
			inst.yearshtml = '';
8081
			if (secondary || !changeYear)
8082
				html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
8083
			else {
8084
				// determine range of years to display
8085
				var years = this._get(inst, 'yearRange').split(':');
8086
				var thisYear = new Date().getFullYear();
8087
				var determineYear = function(value) {
8088
					var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8089
						(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8090
						parseInt(value, 10)));
8091
					return (isNaN(year) ? thisYear : year);
8092
				};
8093
				var year = determineYear(years[0]);
8094
				var endYear = Math.max(year, determineYear(years[1] || ''));
8095
				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8096
				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8097
				inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
8098
				for (; year <= endYear; year++) {
8099
					inst.yearshtml += '<option value="' + year + '"' +
8100
						(year == drawYear ? ' selected="selected"' : '') +
8101
						'>' + year + '</option>';
8102
				}
8103
				inst.yearshtml += '</select>';
8104
 
8105
				html += inst.yearshtml;
8106
				inst.yearshtml = null;
8107
			}
8108
		}
8109
		html += this._get(inst, 'yearSuffix');
8110
		if (showMonthAfterYear)
8111
			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
8112
		html += '</div>'; // Close datepicker_header
8113
		return html;
8114
	},
8115
 
8116
	/* Adjust one of the date sub-fields. */
8117
	_adjustInstDate: function(inst, offset, period) {
8118
		var year = inst.drawYear + (period == 'Y' ? offset : 0);
8119
		var month = inst.drawMonth + (period == 'M' ? offset : 0);
8120
		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8121
			(period == 'D' ? offset : 0);
8122
		var date = this._restrictMinMax(inst,
8123
			this._daylightSavingAdjust(new Date(year, month, day)));
8124
		inst.selectedDay = date.getDate();
8125
		inst.drawMonth = inst.selectedMonth = date.getMonth();
8126
		inst.drawYear = inst.selectedYear = date.getFullYear();
8127
		if (period == 'M' || period == 'Y')
8128
			this._notifyChange(inst);
8129
	},
8130
 
8131
	/* Ensure a date is within any min/max bounds. */
8132
	_restrictMinMax: function(inst, date) {
8133
		var minDate = this._getMinMaxDate(inst, 'min');
8134
		var maxDate = this._getMinMaxDate(inst, 'max');
8135
		var newDate = (minDate && date < minDate ? minDate : date);
8136
		newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8137
		return newDate;
8138
	},
8139
 
8140
	/* Notify change of month/year. */
8141
	_notifyChange: function(inst) {
8142
		var onChange = this._get(inst, 'onChangeMonthYear');
8143
		if (onChange)
8144
			onChange.apply((inst.input ? inst.input[0] : null),
8145
				[inst.selectedYear, inst.selectedMonth + 1, inst]);
8146
	},
8147
 
8148
	/* Determine the number of months to show. */
8149
	_getNumberOfMonths: function(inst) {
8150
		var numMonths = this._get(inst, 'numberOfMonths');
8151
		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8152
	},
8153
 
8154
	/* Determine the current maximum date - ensure no time components are set. */
8155
	_getMinMaxDate: function(inst, minMax) {
8156
		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8157
	},
8158
 
8159
	/* Find the number of days in a given month. */
8160
	_getDaysInMonth: function(year, month) {
8161
		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8162
	},
8163
 
8164
	/* Find the day of the week of the first of a month. */
8165
	_getFirstDayOfMonth: function(year, month) {
8166
		return new Date(year, month, 1).getDay();
8167
	},
8168
 
8169
	/* Determines if we should allow a "next/prev" month display change. */
8170
	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
8171
		var numMonths = this._getNumberOfMonths(inst);
8172
		var date = this._daylightSavingAdjust(new Date(curYear,
8173
			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8174
		if (offset < 0)
8175
			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8176
		return this._isInRange(inst, date);
8177
	},
8178
 
8179
	/* Is the given date in the accepted range? */
8180
	_isInRange: function(inst, date) {
8181
		var minDate = this._getMinMaxDate(inst, 'min');
8182
		var maxDate = this._getMinMaxDate(inst, 'max');
8183
		return ((!minDate || date.getTime() >= minDate.getTime()) &&
8184
			(!maxDate || date.getTime() <= maxDate.getTime()));
8185
	},
8186
 
8187
	/* Provide the configuration settings for formatting/parsing. */
8188
	_getFormatConfig: function(inst) {
8189
		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8190
		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8191
			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8192
		return {shortYearCutoff: shortYearCutoff,
8193
			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
8194
			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
8195
	},
8196
 
8197
	/* Format the given date for display. */
8198
	_formatDate: function(inst, day, month, year) {
8199
		if (!day) {
8200
			inst.currentDay = inst.selectedDay;
8201
			inst.currentMonth = inst.selectedMonth;
8202
			inst.currentYear = inst.selectedYear;
8203
		}
8204
		var date = (day ? (typeof day == 'object' ? day :
8205
			this._daylightSavingAdjust(new Date(year, month, day))) :
8206
			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8207
		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
8208
	}
8209
});
8210
 
8211
/*
8212
 * Bind hover events for datepicker elements.
8213
 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8214
 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8215
 */
8216
function bindHover(dpDiv) {
8217
	var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
8218
	return dpDiv.delegate(selector, 'mouseout', function() {
8219
			$(this).removeClass('ui-state-hover');
8220
			if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
8221
			if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
8222
		})
8223
		.delegate(selector, 'mouseover', function(){
8224
			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
8225
				$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
8226
				$(this).addClass('ui-state-hover');
8227
				if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
8228
				if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
8229
			}
8230
		});
8231
}
8232
 
8233
/* jQuery extend now ignores nulls! */
8234
function extendRemove(target, props) {
8235
	$.extend(target, props);
8236
	for (var name in props)
8237
		if (props[name] == null || props[name] == undefined)
8238
			target[name] = props[name];
8239
	return target;
8240
};
8241
 
8242
/* Invoke the datepicker functionality.
8243
   @param  options  string - a command, optionally followed by additional parameters or
8244
	                Object - settings for attaching new datepicker functionality
8245
   @return  jQuery object */
8246
$.fn.datepicker = function(options){
8247
 
8248
	/* Verify an empty collection wasn't passed - Fixes #6976 */
8249
	if ( !this.length ) {
8250
		return this;
8251
	}
8252
 
8253
	/* Initialise the date picker. */
8254
	if (!$.datepicker.initialized) {
8255
		$(document).mousedown($.datepicker._checkExternalClick).
8256
			find(document.body).append($.datepicker.dpDiv);
8257
		$.datepicker.initialized = true;
8258
	}
8259
 
8260
	var otherArgs = Array.prototype.slice.call(arguments, 1);
8261
	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
8262
		return $.datepicker['_' + options + 'Datepicker'].
8263
			apply($.datepicker, [this[0]].concat(otherArgs));
8264
	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
8265
		return $.datepicker['_' + options + 'Datepicker'].
8266
			apply($.datepicker, [this[0]].concat(otherArgs));
8267
	return this.each(function() {
8268
		typeof options == 'string' ?
8269
			$.datepicker['_' + options + 'Datepicker'].
8270
				apply($.datepicker, [this].concat(otherArgs)) :
8271
			$.datepicker._attachDatepicker(this, options);
8272
	});
8273
};
8274
 
8275
$.datepicker = new Datepicker(); // singleton instance
8276
$.datepicker.initialized = false;
8277
$.datepicker.uuid = new Date().getTime();
8278
$.datepicker.version = "1.9.2";
8279
 
8280
// Workaround for #4055
8281
// Add another global to avoid noConflict issues with inline event handlers
8282
window['DP_jQuery_' + dpuuid] = $;
8283
 
8284
})(jQuery);
8285
(function( $, undefined ) {
8286
 
8287
var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
8288
	sizeRelatedOptions = {
8289
		buttons: true,
8290
		height: true,
8291
		maxHeight: true,
8292
		maxWidth: true,
8293
		minHeight: true,
8294
		minWidth: true,
8295
		width: true
8296
	},
8297
	resizableRelatedOptions = {
8298
		maxHeight: true,
8299
		maxWidth: true,
8300
		minHeight: true,
8301
		minWidth: true
8302
	};
8303
 
8304
$.widget("ui.dialog", {
8305
	version: "1.9.2",
8306
	options: {
8307
		autoOpen: true,
8308
		buttons: {},
8309
		closeOnEscape: true,
8310
		closeText: "close",
8311
		dialogClass: "",
8312
		draggable: true,
8313
		hide: null,
8314
		height: "auto",
8315
		maxHeight: false,
8316
		maxWidth: false,
8317
		minHeight: 150,
8318
		minWidth: 150,
8319
		modal: false,
8320
		position: {
8321
			my: "center",
8322
			at: "center",
8323
			of: window,
8324
			collision: "fit",
8325
			// ensure that the titlebar is never outside the document
8326
			using: function( pos ) {
8327
				var topOffset = $( this ).css( pos ).offset().top;
8328
				if ( topOffset < 0 ) {
8329
					$( this ).css( "top", pos.top - topOffset );
8330
				}
8331
			}
8332
		},
8333
		resizable: true,
8334
		show: null,
8335
		stack: true,
8336
		title: "",
8337
		width: 300,
8338
		zIndex: 1000
8339
	},
8340
 
8341
	_create: function() {
8342
		this.originalTitle = this.element.attr( "title" );
8343
		// #5742 - .attr() might return a DOMElement
8344
		if ( typeof this.originalTitle !== "string" ) {
8345
			this.originalTitle = "";
8346
		}
8347
		this.oldPosition = {
8348
			parent: this.element.parent(),
8349
			index: this.element.parent().children().index( this.element )
8350
		};
8351
		this.options.title = this.options.title || this.originalTitle;
8352
		var that = this,
8353
			options = this.options,
8354
 
8355
			title = options.title || "&#160;",
8356
			uiDialog,
8357
			uiDialogTitlebar,
8358
			uiDialogTitlebarClose,
8359
			uiDialogTitle,
8360
			uiDialogButtonPane;
8361
 
8362
			uiDialog = ( this.uiDialog = $( "<div>" ) )
8363
				.addClass( uiDialogClasses + options.dialogClass )
8364
				.css({
8365
					display: "none",
8366
					outline: 0, // TODO: move to stylesheet
8367
					zIndex: options.zIndex
8368
				})
8369
				// setting tabIndex makes the div focusable
8370
				.attr( "tabIndex", -1)
8371
				.keydown(function( event ) {
8372
					if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8373
							event.keyCode === $.ui.keyCode.ESCAPE ) {
8374
						that.close( event );
8375
						event.preventDefault();
8376
					}
8377
				})
8378
				.mousedown(function( event ) {
8379
					that.moveToTop( false, event );
8380
				})
8381
				.appendTo( "body" );
8382
 
8383
			this.element
8384
				.show()
8385
				.removeAttr( "title" )
8386
				.addClass( "ui-dialog-content ui-widget-content" )
8387
				.appendTo( uiDialog );
8388
 
8389
			uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
8390
				.addClass( "ui-dialog-titlebar  ui-widget-header  " +
8391
					"ui-corner-all  ui-helper-clearfix" )
8392
				.bind( "mousedown", function() {
8393
					// Dialog isn't getting focus when dragging (#8063)
8394
					uiDialog.focus();
8395
				})
8396
				.prependTo( uiDialog );
8397
 
8398
			uiDialogTitlebarClose = $( "<a href='#'></a>" )
8399
				.addClass( "ui-dialog-titlebar-close  ui-corner-all" )
8400
				.attr( "role", "button" )
8401
				.click(function( event ) {
8402
					event.preventDefault();
8403
					that.close( event );
8404
				})
8405
				.appendTo( uiDialogTitlebar );
8406
 
8407
			( this.uiDialogTitlebarCloseText = $( "<span>" ) )
8408
				.addClass( "ui-icon ui-icon-closethick" )
8409
				.text( options.closeText )
8410
				.appendTo( uiDialogTitlebarClose );
8411
 
8412
			uiDialogTitle = $( "<span>" )
8413
				.uniqueId()
8414
				.addClass( "ui-dialog-title" )
8415
				.html( title )
8416
				.prependTo( uiDialogTitlebar );
8417
 
8418
			uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
8419
				.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8420
 
8421
			( this.uiButtonSet = $( "<div>" ) )
8422
				.addClass( "ui-dialog-buttonset" )
8423
				.appendTo( uiDialogButtonPane );
8424
 
8425
		uiDialog.attr({
8426
			role: "dialog",
8427
			"aria-labelledby": uiDialogTitle.attr( "id" )
8428
		});
8429
 
8430
		uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
8431
		this._hoverable( uiDialogTitlebarClose );
8432
		this._focusable( uiDialogTitlebarClose );
8433
 
8434
		if ( options.draggable && $.fn.draggable ) {
8435
			this._makeDraggable();
8436
		}
8437
		if ( options.resizable && $.fn.resizable ) {
8438
			this._makeResizable();
8439
		}
8440
 
8441
		this._createButtons( options.buttons );
8442
		this._isOpen = false;
8443
 
8444
		if ( $.fn.bgiframe ) {
8445
			uiDialog.bgiframe();
8446
		}
8447
 
8448
		// prevent tabbing out of modal dialogs
8449
		this._on( uiDialog, { keydown: function( event ) {
8450
			if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
8451
				return;
8452
			}
8453
 
8454
			var tabbables = $( ":tabbable", uiDialog ),
8455
				first = tabbables.filter( ":first" ),
8456
				last  = tabbables.filter( ":last" );
8457
 
8458
			if ( event.target === last[0] && !event.shiftKey ) {
8459
				first.focus( 1 );
8460
				return false;
8461
			} else if ( event.target === first[0] && event.shiftKey ) {
8462
				last.focus( 1 );
8463
				return false;
8464
			}
8465
		}});
8466
	},
8467
 
8468
	_init: function() {
8469
		if ( this.options.autoOpen ) {
8470
			this.open();
8471
		}
8472
	},
8473
 
8474
	_destroy: function() {
8475
		var next,
8476
			oldPosition = this.oldPosition;
8477
 
8478
		if ( this.overlay ) {
8479
			this.overlay.destroy();
8480
		}
8481
		this.uiDialog.hide();
8482
		this.element
8483
			.removeClass( "ui-dialog-content ui-widget-content" )
8484
			.hide()
8485
			.appendTo( "body" );
8486
		this.uiDialog.remove();
8487
 
8488
		if ( this.originalTitle ) {
8489
			this.element.attr( "title", this.originalTitle );
8490
		}
8491
 
8492
		next = oldPosition.parent.children().eq( oldPosition.index );
8493
		// Don't try to place the dialog next to itself (#8613)
8494
		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8495
			next.before( this.element );
8496
		} else {
8497
			oldPosition.parent.append( this.element );
8498
		}
8499
	},
8500
 
8501
	widget: function() {
8502
		return this.uiDialog;
8503
	},
8504
 
8505
	close: function( event ) {
8506
		var that = this,
8507
			maxZ, thisZ;
8508
 
8509
		if ( !this._isOpen ) {
8510
			return;
8511
		}
8512
 
8513
		if ( false === this._trigger( "beforeClose", event ) ) {
8514
			return;
8515
		}
8516
 
8517
		this._isOpen = false;
8518
 
8519
		if ( this.overlay ) {
8520
			this.overlay.destroy();
8521
		}
8522
 
8523
		if ( this.options.hide ) {
8524
			this._hide( this.uiDialog, this.options.hide, function() {
8525
				that._trigger( "close", event );
8526
			});
8527
		} else {
8528
			this.uiDialog.hide();
8529
			this._trigger( "close", event );
8530
		}
8531
 
8532
		$.ui.dialog.overlay.resize();
8533
 
8534
		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
8535
		if ( this.options.modal ) {
8536
			maxZ = 0;
8537
			$( ".ui-dialog" ).each(function() {
8538
				if ( this !== that.uiDialog[0] ) {
8539
					thisZ = $( this ).css( "z-index" );
8540
					if ( !isNaN( thisZ ) ) {
8541
						maxZ = Math.max( maxZ, thisZ );
8542
					}
8543
				}
8544
			});
8545
			$.ui.dialog.maxZ = maxZ;
8546
		}
8547
 
8548
		return this;
8549
	},
8550
 
8551
	isOpen: function() {
8552
		return this._isOpen;
8553
	},
8554
 
8555
	// the force parameter allows us to move modal dialogs to their correct
8556
	// position on open
8557
	moveToTop: function( force, event ) {
8558
		var options = this.options,
8559
			saveScroll;
8560
 
8561
		if ( ( options.modal && !force ) ||
8562
				( !options.stack && !options.modal ) ) {
8563
			return this._trigger( "focus", event );
8564
		}
8565
 
8566
		if ( options.zIndex > $.ui.dialog.maxZ ) {
8567
			$.ui.dialog.maxZ = options.zIndex;
8568
		}
8569
		if ( this.overlay ) {
8570
			$.ui.dialog.maxZ += 1;
8571
			$.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
8572
			this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
8573
		}
8574
 
8575
		// Save and then restore scroll
8576
		// Opera 9.5+ resets when parent z-index is changed.
8577
		// http://bugs.jqueryui.com/ticket/3193
8578
		saveScroll = {
8579
			scrollTop: this.element.scrollTop(),
8580
			scrollLeft: this.element.scrollLeft()
8581
		};
8582
		$.ui.dialog.maxZ += 1;
8583
		this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
8584
		this.element.attr( saveScroll );
8585
		this._trigger( "focus", event );
8586
 
8587
		return this;
8588
	},
8589
 
8590
	open: function() {
8591
		if ( this._isOpen ) {
8592
			return;
8593
		}
8594
 
8595
		var hasFocus,
8596
			options = this.options,
8597
			uiDialog = this.uiDialog;
8598
 
8599
		this._size();
8600
		this._position( options.position );
8601
		uiDialog.show( options.show );
8602
		this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
8603
		this.moveToTop( true );
8604
 
8605
		// set focus to the first tabbable element in the content area or the first button
8606
		// if there are no tabbable elements, set focus on the dialog itself
8607
		hasFocus = this.element.find( ":tabbable" );
8608
		if ( !hasFocus.length ) {
8609
			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8610
			if ( !hasFocus.length ) {
8611
				hasFocus = uiDialog;
8612
			}
8613
		}
8614
		hasFocus.eq( 0 ).focus();
8615
 
8616
		this._isOpen = true;
8617
		this._trigger( "open" );
8618
 
8619
		return this;
8620
	},
8621
 
8622
	_createButtons: function( buttons ) {
8623
		var that = this,
8624
			hasButtons = false;
8625
 
8626
		// if we already have a button pane, remove it
8627
		this.uiDialogButtonPane.remove();
8628
		this.uiButtonSet.empty();
8629
 
8630
		if ( typeof buttons === "object" && buttons !== null ) {
8631
			$.each( buttons, function() {
8632
				return !(hasButtons = true);
8633
			});
8634
		}
8635
		if ( hasButtons ) {
8636
			$.each( buttons, function( name, props ) {
8637
				var button, click;
8638
				props = $.isFunction( props ) ?
8639
					{ click: props, text: name } :
8640
					props;
8641
				// Default to a non-submitting button
8642
				props = $.extend( { type: "button" }, props );
8643
				// Change the context for the click callback to be the main element
8644
				click = props.click;
8645
				props.click = function() {
8646
					click.apply( that.element[0], arguments );
8647
				};
8648
				button = $( "<button></button>", props )
8649
					.appendTo( that.uiButtonSet );
8650
				if ( $.fn.button ) {
8651
					button.button();
8652
				}
8653
			});
8654
			this.uiDialog.addClass( "ui-dialog-buttons" );
8655
			this.uiDialogButtonPane.appendTo( this.uiDialog );
8656
		} else {
8657
			this.uiDialog.removeClass( "ui-dialog-buttons" );
8658
		}
8659
	},
8660
 
8661
	_makeDraggable: function() {
8662
		var that = this,
8663
			options = this.options;
8664
 
8665
		function filteredUi( ui ) {
8666
			return {
8667
				position: ui.position,
8668
				offset: ui.offset
8669
			};
8670
		}
8671
 
8672
		this.uiDialog.draggable({
8673
			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8674
			handle: ".ui-dialog-titlebar",
8675
			containment: "document",
8676
			start: function( event, ui ) {
8677
				$( this )
8678
					.addClass( "ui-dialog-dragging" );
8679
				that._trigger( "dragStart", event, filteredUi( ui ) );
8680
			},
8681
			drag: function( event, ui ) {
8682
				that._trigger( "drag", event, filteredUi( ui ) );
8683
			},
8684
			stop: function( event, ui ) {
8685
				options.position = [
8686
					ui.position.left - that.document.scrollLeft(),
8687
					ui.position.top - that.document.scrollTop()
8688
				];
8689
				$( this )
8690
					.removeClass( "ui-dialog-dragging" );
8691
				that._trigger( "dragStop", event, filteredUi( ui ) );
8692
				$.ui.dialog.overlay.resize();
8693
			}
8694
		});
8695
	},
8696
 
8697
	_makeResizable: function( handles ) {
8698
		handles = (handles === undefined ? this.options.resizable : handles);
8699
		var that = this,
8700
			options = this.options,
8701
			// .ui-resizable has position: relative defined in the stylesheet
8702
			// but dialogs have to use absolute or fixed positioning
8703
			position = this.uiDialog.css( "position" ),
8704
			resizeHandles = typeof handles === 'string' ?
8705
				handles	:
8706
				"n,e,s,w,se,sw,ne,nw";
8707
 
8708
		function filteredUi( ui ) {
8709
			return {
8710
				originalPosition: ui.originalPosition,
8711
				originalSize: ui.originalSize,
8712
				position: ui.position,
8713
				size: ui.size
8714
			};
8715
		}
8716
 
8717
		this.uiDialog.resizable({
8718
			cancel: ".ui-dialog-content",
8719
			containment: "document",
8720
			alsoResize: this.element,
8721
			maxWidth: options.maxWidth,
8722
			maxHeight: options.maxHeight,
8723
			minWidth: options.minWidth,
8724
			minHeight: this._minHeight(),
8725
			handles: resizeHandles,
8726
			start: function( event, ui ) {
8727
				$( this ).addClass( "ui-dialog-resizing" );
8728
				that._trigger( "resizeStart", event, filteredUi( ui ) );
8729
			},
8730
			resize: function( event, ui ) {
8731
				that._trigger( "resize", event, filteredUi( ui ) );
8732
			},
8733
			stop: function( event, ui ) {
8734
				$( this ).removeClass( "ui-dialog-resizing" );
8735
				options.height = $( this ).height();
8736
				options.width = $( this ).width();
8737
				that._trigger( "resizeStop", event, filteredUi( ui ) );
8738
				$.ui.dialog.overlay.resize();
8739
			}
8740
		})
8741
		.css( "position", position )
8742
		.find( ".ui-resizable-se" )
8743
			.addClass( "ui-icon ui-icon-grip-diagonal-se" );
8744
	},
8745
 
8746
	_minHeight: function() {
8747
		var options = this.options;
8748
 
8749
		if ( options.height === "auto" ) {
8750
			return options.minHeight;
8751
		} else {
8752
			return Math.min( options.minHeight, options.height );
8753
		}
8754
	},
8755
 
8756
	_position: function( position ) {
8757
		var myAt = [],
8758
			offset = [ 0, 0 ],
8759
			isVisible;
8760
 
8761
		if ( position ) {
8762
			// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
8763
	//		if (typeof position == 'string' || $.isArray(position)) {
8764
	//			myAt = $.isArray(position) ? position : position.split(' ');
8765
 
8766
			if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
8767
				myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
8768
				if ( myAt.length === 1 ) {
8769
					myAt[ 1 ] = myAt[ 0 ];
8770
				}
8771
 
8772
				$.each( [ "left", "top" ], function( i, offsetPosition ) {
8773
					if ( +myAt[ i ] === myAt[ i ] ) {
8774
						offset[ i ] = myAt[ i ];
8775
						myAt[ i ] = offsetPosition;
8776
					}
8777
				});
8778
 
8779
				position = {
8780
					my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
8781
						myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
8782
					at: myAt.join( " " )
8783
				};
8784
			}
8785
 
8786
			position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
8787
		} else {
8788
			position = $.ui.dialog.prototype.options.position;
8789
		}
8790
 
8791
		// need to show the dialog to get the actual offset in the position plugin
8792
		isVisible = this.uiDialog.is( ":visible" );
8793
		if ( !isVisible ) {
8794
			this.uiDialog.show();
8795
		}
8796
		this.uiDialog.position( position );
8797
		if ( !isVisible ) {
8798
			this.uiDialog.hide();
8799
		}
8800
	},
8801
 
8802
	_setOptions: function( options ) {
8803
		var that = this,
8804
			resizableOptions = {},
8805
			resize = false;
8806
 
8807
		$.each( options, function( key, value ) {
8808
			that._setOption( key, value );
8809
 
8810
			if ( key in sizeRelatedOptions ) {
8811
				resize = true;
8812
			}
8813
			if ( key in resizableRelatedOptions ) {
8814
				resizableOptions[ key ] = value;
8815
			}
8816
		});
8817
 
8818
		if ( resize ) {
8819
			this._size();
8820
		}
8821
		if ( this.uiDialog.is( ":data(resizable)" ) ) {
8822
			this.uiDialog.resizable( "option", resizableOptions );
8823
		}
8824
	},
8825
 
8826
	_setOption: function( key, value ) {
8827
		var isDraggable, isResizable,
8828
			uiDialog = this.uiDialog;
8829
 
8830
		switch ( key ) {
8831
			case "buttons":
8832
				this._createButtons( value );
8833
				break;
8834
			case "closeText":
8835
				// ensure that we always pass a string
8836
				this.uiDialogTitlebarCloseText.text( "" + value );
8837
				break;
8838
			case "dialogClass":
8839
				uiDialog
8840
					.removeClass( this.options.dialogClass )
8841
					.addClass( uiDialogClasses + value );
8842
				break;
8843
			case "disabled":
8844
				if ( value ) {
8845
					uiDialog.addClass( "ui-dialog-disabled" );
8846
				} else {
8847
					uiDialog.removeClass( "ui-dialog-disabled" );
8848
				}
8849
				break;
8850
			case "draggable":
8851
				isDraggable = uiDialog.is( ":data(draggable)" );
8852
				if ( isDraggable && !value ) {
8853
					uiDialog.draggable( "destroy" );
8854
				}
8855
 
8856
				if ( !isDraggable && value ) {
8857
					this._makeDraggable();
8858
				}
8859
				break;
8860
			case "position":
8861
				this._position( value );
8862
				break;
8863
			case "resizable":
8864
				// currently resizable, becoming non-resizable
8865
				isResizable = uiDialog.is( ":data(resizable)" );
8866
				if ( isResizable && !value ) {
8867
					uiDialog.resizable( "destroy" );
8868
				}
8869
 
8870
				// currently resizable, changing handles
8871
				if ( isResizable && typeof value === "string" ) {
8872
					uiDialog.resizable( "option", "handles", value );
8873
				}
8874
 
8875
				// currently non-resizable, becoming resizable
8876
				if ( !isResizable && value !== false ) {
8877
					this._makeResizable( value );
8878
				}
8879
				break;
8880
			case "title":
8881
				// convert whatever was passed in o a string, for html() to not throw up
8882
				$( ".ui-dialog-title", this.uiDialogTitlebar )
8883
					.html( "" + ( value || "&#160;" ) );
8884
				break;
8885
		}
8886
 
8887
		this._super( key, value );
8888
	},
8889
 
8890
	_size: function() {
8891
		/* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8892
		 * divs will both have width and height set, so we need to reset them
8893
		 */
8894
		var nonContentHeight, minContentHeight, autoHeight,
8895
			options = this.options,
8896
			isVisible = this.uiDialog.is( ":visible" );
8897
 
8898
		// reset content sizing
8899
		this.element.show().css({
8900
			width: "auto",
8901
			minHeight: 0,
8902
			height: 0
8903
		});
8904
 
8905
		if ( options.minWidth > options.width ) {
8906
			options.width = options.minWidth;
8907
		}
8908
 
8909
		// reset wrapper sizing
8910
		// determine the height of all the non-content elements
8911
		nonContentHeight = this.uiDialog.css({
8912
				height: "auto",
8913
				width: options.width
8914
			})
8915
			.outerHeight();
8916
		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8917
 
8918
		if ( options.height === "auto" ) {
8919
			// only needed for IE6 support
8920
			if ( $.support.minHeight ) {
8921
				this.element.css({
8922
					minHeight: minContentHeight,
8923
					height: "auto"
8924
				});
8925
			} else {
8926
				this.uiDialog.show();
8927
				autoHeight = this.element.css( "height", "auto" ).height();
8928
				if ( !isVisible ) {
8929
					this.uiDialog.hide();
8930
				}
8931
				this.element.height( Math.max( autoHeight, minContentHeight ) );
8932
			}
8933
		} else {
8934
			this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
8935
		}
8936
 
8937
		if (this.uiDialog.is( ":data(resizable)" ) ) {
8938
			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8939
		}
8940
	}
8941
});
8942
 
8943
$.extend($.ui.dialog, {
8944
	uuid: 0,
8945
	maxZ: 0,
8946
 
8947
	getTitleId: function($el) {
8948
		var id = $el.attr( "id" );
8949
		if ( !id ) {
8950
			this.uuid += 1;
8951
			id = this.uuid;
8952
		}
8953
		return "ui-dialog-title-" + id;
8954
	},
8955
 
8956
	overlay: function( dialog ) {
8957
		this.$el = $.ui.dialog.overlay.create( dialog );
8958
	}
8959
});
8960
 
8961
$.extend( $.ui.dialog.overlay, {
8962
	instances: [],
8963
	// reuse old instances due to IE memory leak with alpha transparency (see #5185)
8964
	oldInstances: [],
8965
	maxZ: 0,
8966
	events: $.map(
8967
		"focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
8968
		function( event ) {
8969
			return event + ".dialog-overlay";
8970
		}
8971
	).join( " " ),
8972
	create: function( dialog ) {
8973
		if ( this.instances.length === 0 ) {
8974
			// prevent use of anchors and inputs
8975
			// we use a setTimeout in case the overlay is created from an
8976
			// event that we're going to be cancelling (see #2804)
8977
			setTimeout(function() {
8978
				// handle $(el).dialog().dialog('close') (see #4065)
8979
				if ( $.ui.dialog.overlay.instances.length ) {
8980
					$( document ).bind( $.ui.dialog.overlay.events, function( event ) {
8981
						// stop events if the z-index of the target is < the z-index of the overlay
8982
						// we cannot return true when we don't want to cancel the event (#3523)
8983
						if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
8984
							return false;
8985
						}
8986
					});
8987
				}
8988
			}, 1 );
8989
 
8990
			// handle window resize
8991
			$( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
8992
		}
8993
 
8994
		var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
8995
 
8996
		// allow closing by pressing the escape key
8997
		$( document ).bind( "keydown.dialog-overlay", function( event ) {
8998
			var instances = $.ui.dialog.overlay.instances;
8999
			// only react to the event if we're the top overlay
9000
			if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
9001
				dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9002
				event.keyCode === $.ui.keyCode.ESCAPE ) {
9003
 
9004
				dialog.close( event );
9005
				event.preventDefault();
9006
			}
9007
		});
9008
 
9009
		$el.appendTo( document.body ).css({
9010
			width: this.width(),
9011
			height: this.height()
9012
		});
9013
 
9014
		if ( $.fn.bgiframe ) {
9015
			$el.bgiframe();
9016
		}
9017
 
9018
		this.instances.push( $el );
9019
		return $el;
9020
	},
9021
 
9022
	destroy: function( $el ) {
9023
		var indexOf = $.inArray( $el, this.instances ),
9024
			maxZ = 0;
9025
 
9026
		if ( indexOf !== -1 ) {
9027
			this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
9028
		}
9029
 
9030
		if ( this.instances.length === 0 ) {
9031
			$( [ document, window ] ).unbind( ".dialog-overlay" );
9032
		}
9033
 
9034
		$el.height( 0 ).width( 0 ).remove();
9035
 
9036
		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9037
		$.each( this.instances, function() {
9038
			maxZ = Math.max( maxZ, this.css( "z-index" ) );
9039
		});
9040
		this.maxZ = maxZ;
9041
	},
9042
 
9043
	height: function() {
9044
		var scrollHeight,
9045
			offsetHeight;
9046
		// handle IE
9047
		if ( $.ui.ie ) {
9048
			scrollHeight = Math.max(
9049
				document.documentElement.scrollHeight,
9050
				document.body.scrollHeight
9051
			);
9052
			offsetHeight = Math.max(
9053
				document.documentElement.offsetHeight,
9054
				document.body.offsetHeight
9055
			);
9056
 
9057
			if ( scrollHeight < offsetHeight ) {
9058
				return $( window ).height() + "px";
9059
			} else {
9060
				return scrollHeight + "px";
9061
			}
9062
		// handle "good" browsers
9063
		} else {
9064
			return $( document ).height() + "px";
9065
		}
9066
	},
9067
 
9068
	width: function() {
9069
		var scrollWidth,
9070
			offsetWidth;
9071
		// handle IE
9072
		if ( $.ui.ie ) {
9073
			scrollWidth = Math.max(
9074
				document.documentElement.scrollWidth,
9075
				document.body.scrollWidth
9076
			);
9077
			offsetWidth = Math.max(
9078
				document.documentElement.offsetWidth,
9079
				document.body.offsetWidth
9080
			);
9081
 
9082
			if ( scrollWidth < offsetWidth ) {
9083
				return $( window ).width() + "px";
9084
			} else {
9085
				return scrollWidth + "px";
9086
			}
9087
		// handle "good" browsers
9088
		} else {
9089
			return $( document ).width() + "px";
9090
		}
9091
	},
9092
 
9093
	resize: function() {
9094
		/* If the dialog is draggable and the user drags it past the
9095
		 * right edge of the window, the document becomes wider so we
9096
		 * need to stretch the overlay. If the user then drags the
9097
		 * dialog back to the left, the document will become narrower,
9098
		 * so we need to shrink the overlay to the appropriate size.
9099
		 * This is handled by shrinking the overlay before setting it
9100
		 * to the full document size.
9101
		 */
9102
		var $overlays = $( [] );
9103
		$.each( $.ui.dialog.overlay.instances, function() {
9104
			$overlays = $overlays.add( this );
9105
		});
9106
 
9107
		$overlays.css({
9108
			width: 0,
9109
			height: 0
9110
		}).css({
9111
			width: $.ui.dialog.overlay.width(),
9112
			height: $.ui.dialog.overlay.height()
9113
		});
9114
	}
9115
});
9116
 
9117
$.extend( $.ui.dialog.overlay.prototype, {
9118
	destroy: function() {
9119
		$.ui.dialog.overlay.destroy( this.$el );
9120
	}
9121
});
9122
 
9123
}( jQuery ) );
9124
(function( $, undefined ) {
9125
 
9126
var mouseHandled = false;
9127
 
9128
$.widget( "ui.menu", {
9129
	version: "1.9.2",
9130
	defaultElement: "<ul>",
9131
	delay: 300,
9132
	options: {
9133
		icons: {
9134
			submenu: "ui-icon-carat-1-e"
9135
		},
9136
		menus: "ul",
9137
		position: {
9138
			my: "left top",
9139
			at: "right top"
9140
		},
9141
		role: "menu",
9142
 
9143
		// callbacks
9144
		blur: null,
9145
		focus: null,
9146
		select: null
9147
	},
9148
 
9149
	_create: function() {
9150
		this.activeMenu = this.element;
9151
		this.element
9152
			.uniqueId()
9153
			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9154
			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
9155
			.attr({
9156
				role: this.options.role,
9157
				tabIndex: 0
9158
			})
9159
			// need to catch all clicks on disabled menu
9160
			// not possible through _on
9161
			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
9162
				if ( this.options.disabled ) {
9163
					event.preventDefault();
9164
				}
9165
			}, this ));
9166
 
9167
		if ( this.options.disabled ) {
9168
			this.element
9169
				.addClass( "ui-state-disabled" )
9170
				.attr( "aria-disabled", "true" );
9171
		}
9172
 
9173
		this._on({
9174
			// Prevent focus from sticking to links inside menu after clicking
9175
			// them (focus should always stay on UL during navigation).
9176
			"mousedown .ui-menu-item > a": function( event ) {
9177
				event.preventDefault();
9178
			},
9179
			"click .ui-state-disabled > a": function( event ) {
9180
				event.preventDefault();
9181
			},
9182
			"click .ui-menu-item:has(a)": function( event ) {
9183
				var target = $( event.target ).closest( ".ui-menu-item" );
9184
				if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
9185
					mouseHandled = true;
9186
 
9187
					this.select( event );
9188
					// Open submenu on click
9189
					if ( target.has( ".ui-menu" ).length ) {
9190
						this.expand( event );
9191
					} else if ( !this.element.is( ":focus" ) ) {
9192
						// Redirect focus to the menu
9193
						this.element.trigger( "focus", [ true ] );
9194
 
9195
						// If the active item is on the top level, let it stay active.
9196
						// Otherwise, blur the active item since it is no longer visible.
9197
						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
9198
							clearTimeout( this.timer );
9199
						}
9200
					}
9201
				}
9202
			},
9203
			"mouseenter .ui-menu-item": function( event ) {
9204
				var target = $( event.currentTarget );
9205
				// Remove ui-state-active class from siblings of the newly focused menu item
9206
				// to avoid a jump caused by adjacent elements both having a class with a border
9207
				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
9208
				this.focus( event, target );
9209
			},
9210
			mouseleave: "collapseAll",
9211
			"mouseleave .ui-menu": "collapseAll",
9212
			focus: function( event, keepActiveItem ) {
9213
				// If there's already an active item, keep it active
9214
				// If not, activate the first item
9215
				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
9216
 
9217
				if ( !keepActiveItem ) {
9218
					this.focus( event, item );
9219
				}
9220
			},
9221
			blur: function( event ) {
9222
				this._delay(function() {
9223
					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
9224
						this.collapseAll( event );
9225
					}
9226
				});
9227
			},
9228
			keydown: "_keydown"
9229
		});
9230
 
9231
		this.refresh();
9232
 
9233
		// Clicks outside of a menu collapse any open menus
9234
		this._on( this.document, {
9235
			click: function( event ) {
9236
				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
9237
					this.collapseAll( event );
9238
				}
9239
 
9240
				// Reset the mouseHandled flag
9241
				mouseHandled = false;
9242
			}
9243
		});
9244
	},
9245
 
9246
	_destroy: function() {
9247
		// Destroy (sub)menus
9248
		this.element
9249
			.removeAttr( "aria-activedescendant" )
9250
			.find( ".ui-menu" ).andSelf()
9251
				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
9252
				.removeAttr( "role" )
9253
				.removeAttr( "tabIndex" )
9254
				.removeAttr( "aria-labelledby" )
9255
				.removeAttr( "aria-expanded" )
9256
				.removeAttr( "aria-hidden" )
9257
				.removeAttr( "aria-disabled" )
9258
				.removeUniqueId()
9259
				.show();
9260
 
9261
		// Destroy menu items
9262
		this.element.find( ".ui-menu-item" )
9263
			.removeClass( "ui-menu-item" )
9264
			.removeAttr( "role" )
9265
			.removeAttr( "aria-disabled" )
9266
			.children( "a" )
9267
				.removeUniqueId()
9268
				.removeClass( "ui-corner-all ui-state-hover" )
9269
				.removeAttr( "tabIndex" )
9270
				.removeAttr( "role" )
9271
				.removeAttr( "aria-haspopup" )
9272
				.children().each( function() {
9273
					var elem = $( this );
9274
					if ( elem.data( "ui-menu-submenu-carat" ) ) {
9275
						elem.remove();
9276
					}
9277
				});
9278
 
9279
		// Destroy menu dividers
9280
		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
9281
	},
9282
 
9283
	_keydown: function( event ) {
9284
		var match, prev, character, skip, regex,
9285
			preventDefault = true;
9286
 
9287
		function escape( value ) {
9288
			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
9289
		}
9290
 
9291
		switch ( event.keyCode ) {
9292
		case $.ui.keyCode.PAGE_UP:
9293
			this.previousPage( event );
9294
			break;
9295
		case $.ui.keyCode.PAGE_DOWN:
9296
			this.nextPage( event );
9297
			break;
9298
		case $.ui.keyCode.HOME:
9299
			this._move( "first", "first", event );
9300
			break;
9301
		case $.ui.keyCode.END:
9302
			this._move( "last", "last", event );
9303
			break;
9304
		case $.ui.keyCode.UP:
9305
			this.previous( event );
9306
			break;
9307
		case $.ui.keyCode.DOWN:
9308
			this.next( event );
9309
			break;
9310
		case $.ui.keyCode.LEFT:
9311
			this.collapse( event );
9312
			break;
9313
		case $.ui.keyCode.RIGHT:
9314
			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
9315
				this.expand( event );
9316
			}
9317
			break;
9318
		case $.ui.keyCode.ENTER:
9319
		case $.ui.keyCode.SPACE:
9320
			this._activate( event );
9321
			break;
9322
		case $.ui.keyCode.ESCAPE:
9323
			this.collapse( event );
9324
			break;
9325
		default:
9326
			preventDefault = false;
9327
			prev = this.previousFilter || "";
9328
			character = String.fromCharCode( event.keyCode );
9329
			skip = false;
9330
 
9331
			clearTimeout( this.filterTimer );
9332
 
9333
			if ( character === prev ) {
9334
				skip = true;
9335
			} else {
9336
				character = prev + character;
9337
			}
9338
 
9339
			regex = new RegExp( "^" + escape( character ), "i" );
9340
			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9341
				return regex.test( $( this ).children( "a" ).text() );
9342
			});
9343
			match = skip && match.index( this.active.next() ) !== -1 ?
9344
				this.active.nextAll( ".ui-menu-item" ) :
9345
				match;
9346
 
9347
			// If no matches on the current filter, reset to the last character pressed
9348
			// to move down the menu to the first item that starts with that character
9349
			if ( !match.length ) {
9350
				character = String.fromCharCode( event.keyCode );
9351
				regex = new RegExp( "^" + escape( character ), "i" );
9352
				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9353
					return regex.test( $( this ).children( "a" ).text() );
9354
				});
9355
			}
9356
 
9357
			if ( match.length ) {
9358
				this.focus( event, match );
9359
				if ( match.length > 1 ) {
9360
					this.previousFilter = character;
9361
					this.filterTimer = this._delay(function() {
9362
						delete this.previousFilter;
9363
					}, 1000 );
9364
				} else {
9365
					delete this.previousFilter;
9366
				}
9367
			} else {
9368
				delete this.previousFilter;
9369
			}
9370
		}
9371
 
9372
		if ( preventDefault ) {
9373
			event.preventDefault();
9374
		}
9375
	},
9376
 
9377
	_activate: function( event ) {
9378
		if ( !this.active.is( ".ui-state-disabled" ) ) {
9379
			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
9380
				this.expand( event );
9381
			} else {
9382
				this.select( event );
9383
			}
9384
		}
9385
	},
9386
 
9387
	refresh: function() {
9388
		var menus,
9389
			icon = this.options.icons.submenu,
9390
			submenus = this.element.find( this.options.menus );
9391
 
9392
		// Initialize nested menus
9393
		submenus.filter( ":not(.ui-menu)" )
9394
			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9395
			.hide()
9396
			.attr({
9397
				role: this.options.role,
9398
				"aria-hidden": "true",
9399
				"aria-expanded": "false"
9400
			})
9401
			.each(function() {
9402
				var menu = $( this ),
9403
					item = menu.prev( "a" ),
9404
					submenuCarat = $( "<span>" )
9405
						.addClass( "ui-menu-icon ui-icon " + icon )
9406
						.data( "ui-menu-submenu-carat", true );
9407
 
9408
				item
9409
					.attr( "aria-haspopup", "true" )
9410
					.prepend( submenuCarat );
9411
				menu.attr( "aria-labelledby", item.attr( "id" ) );
9412
			});
9413
 
9414
		menus = submenus.add( this.element );
9415
 
9416
		// Don't refresh list items that are already adapted
9417
		menus.children( ":not(.ui-menu-item):has(a)" )
9418
			.addClass( "ui-menu-item" )
9419
			.attr( "role", "presentation" )
9420
			.children( "a" )
9421
				.uniqueId()
9422
				.addClass( "ui-corner-all" )
9423
				.attr({
9424
					tabIndex: -1,
9425
					role: this._itemRole()
9426
				});
9427
 
9428
		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
9429
		menus.children( ":not(.ui-menu-item)" ).each(function() {
9430
			var item = $( this );
9431
			// hyphen, em dash, en dash
9432
			if ( !/[^\-—–\s]/.test( item.text() ) ) {
9433
				item.addClass( "ui-widget-content ui-menu-divider" );
9434
			}
9435
		});
9436
 
9437
		// Add aria-disabled attribute to any disabled menu item
9438
		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
9439
 
9440
		// If the active item has been removed, blur the menu
9441
		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
9442
			this.blur();
9443
		}
9444
	},
9445
 
9446
	_itemRole: function() {
9447
		return {
9448
			menu: "menuitem",
9449
			listbox: "option"
9450
		}[ this.options.role ];
9451
	},
9452
 
9453
	focus: function( event, item ) {
9454
		var nested, focused;
9455
		this.blur( event, event && event.type === "focus" );
9456
 
9457
		this._scrollIntoView( item );
9458
 
9459
		this.active = item.first();
9460
		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
9461
		// Only update aria-activedescendant if there's a role
9462
		// otherwise we assume focus is managed elsewhere
9463
		if ( this.options.role ) {
9464
			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
9465
		}
9466
 
9467
		// Highlight active parent menu item, if any
9468
		this.active
9469
			.parent()
9470
			.closest( ".ui-menu-item" )
9471
			.children( "a:first" )
9472
			.addClass( "ui-state-active" );
9473
 
9474
		if ( event && event.type === "keydown" ) {
9475
			this._close();
9476
		} else {
9477
			this.timer = this._delay(function() {
9478
				this._close();
9479
			}, this.delay );
9480
		}
9481
 
9482
		nested = item.children( ".ui-menu" );
9483
		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
9484
			this._startOpening(nested);
9485
		}
9486
		this.activeMenu = item.parent();
9487
 
9488
		this._trigger( "focus", event, { item: item } );
9489
	},
9490
 
9491
	_scrollIntoView: function( item ) {
9492
		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
9493
		if ( this._hasScroll() ) {
9494
			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
9495
			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
9496
			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
9497
			scroll = this.activeMenu.scrollTop();
9498
			elementHeight = this.activeMenu.height();
9499
			itemHeight = item.height();
9500
 
9501
			if ( offset < 0 ) {
9502
				this.activeMenu.scrollTop( scroll + offset );
9503
			} else if ( offset + itemHeight > elementHeight ) {
9504
				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
9505
			}
9506
		}
9507
	},
9508
 
9509
	blur: function( event, fromFocus ) {
9510
		if ( !fromFocus ) {
9511
			clearTimeout( this.timer );
9512
		}
9513
 
9514
		if ( !this.active ) {
9515
			return;
9516
		}
9517
 
9518
		this.active.children( "a" ).removeClass( "ui-state-focus" );
9519
		this.active = null;
9520
 
9521
		this._trigger( "blur", event, { item: this.active } );
9522
	},
9523
 
9524
	_startOpening: function( submenu ) {
9525
		clearTimeout( this.timer );
9526
 
9527
		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
9528
		// shift in the submenu position when mousing over the carat icon
9529
		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
9530
			return;
9531
		}
9532
 
9533
		this.timer = this._delay(function() {
9534
			this._close();
9535
			this._open( submenu );
9536
		}, this.delay );
9537
	},
9538
 
9539
	_open: function( submenu ) {
9540
		var position = $.extend({
9541
			of: this.active
9542
		}, this.options.position );
9543
 
9544
		clearTimeout( this.timer );
9545
		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
9546
			.hide()
9547
			.attr( "aria-hidden", "true" );
9548
 
9549
		submenu
9550
			.show()
9551
			.removeAttr( "aria-hidden" )
9552
			.attr( "aria-expanded", "true" )
9553
			.position( position );
9554
	},
9555
 
9556
	collapseAll: function( event, all ) {
9557
		clearTimeout( this.timer );
9558
		this.timer = this._delay(function() {
9559
			// If we were passed an event, look for the submenu that contains the event
9560
			var currentMenu = all ? this.element :
9561
				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
9562
 
9563
			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
9564
			if ( !currentMenu.length ) {
9565
				currentMenu = this.element;
9566
			}
9567
 
9568
			this._close( currentMenu );
9569
 
9570
			this.blur( event );
9571
			this.activeMenu = currentMenu;
9572
		}, this.delay );
9573
	},
9574
 
9575
	// With no arguments, closes the currently active menu - if nothing is active
9576
	// it closes all menus.  If passed an argument, it will search for menus BELOW
9577
	_close: function( startMenu ) {
9578
		if ( !startMenu ) {
9579
			startMenu = this.active ? this.active.parent() : this.element;
9580
		}
9581
 
9582
		startMenu
9583
			.find( ".ui-menu" )
9584
				.hide()
9585
				.attr( "aria-hidden", "true" )
9586
				.attr( "aria-expanded", "false" )
9587
			.end()
9588
			.find( "a.ui-state-active" )
9589
				.removeClass( "ui-state-active" );
9590
	},
9591
 
9592
	collapse: function( event ) {
9593
		var newItem = this.active &&
9594
			this.active.parent().closest( ".ui-menu-item", this.element );
9595
		if ( newItem && newItem.length ) {
9596
			this._close();
9597
			this.focus( event, newItem );
9598
		}
9599
	},
9600
 
9601
	expand: function( event ) {
9602
		var newItem = this.active &&
9603
			this.active
9604
				.children( ".ui-menu " )
9605
				.children( ".ui-menu-item" )
9606
				.first();
9607
 
9608
		if ( newItem && newItem.length ) {
9609
			this._open( newItem.parent() );
9610
 
9611
			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
9612
			this._delay(function() {
9613
				this.focus( event, newItem );
9614
			});
9615
		}
9616
	},
9617
 
9618
	next: function( event ) {
9619
		this._move( "next", "first", event );
9620
	},
9621
 
9622
	previous: function( event ) {
9623
		this._move( "prev", "last", event );
9624
	},
9625
 
9626
	isFirstItem: function() {
9627
		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
9628
	},
9629
 
9630
	isLastItem: function() {
9631
		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
9632
	},
9633
 
9634
	_move: function( direction, filter, event ) {
9635
		var next;
9636
		if ( this.active ) {
9637
			if ( direction === "first" || direction === "last" ) {
9638
				next = this.active
9639
					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
9640
					.eq( -1 );
9641
			} else {
9642
				next = this.active
9643
					[ direction + "All" ]( ".ui-menu-item" )
9644
					.eq( 0 );
9645
			}
9646
		}
9647
		if ( !next || !next.length || !this.active ) {
9648
			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
9649
		}
9650
 
9651
		this.focus( event, next );
9652
	},
9653
 
9654
	nextPage: function( event ) {
9655
		var item, base, height;
9656
 
9657
		if ( !this.active ) {
9658
			this.next( event );
9659
			return;
9660
		}
9661
		if ( this.isLastItem() ) {
9662
			return;
9663
		}
9664
		if ( this._hasScroll() ) {
9665
			base = this.active.offset().top;
9666
			height = this.element.height();
9667
			this.active.nextAll( ".ui-menu-item" ).each(function() {
9668
				item = $( this );
9669
				return item.offset().top - base - height < 0;
9670
			});
9671
 
9672
			this.focus( event, item );
9673
		} else {
9674
			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
9675
				[ !this.active ? "first" : "last" ]() );
9676
		}
9677
	},
9678
 
9679
	previousPage: function( event ) {
9680
		var item, base, height;
9681
		if ( !this.active ) {
9682
			this.next( event );
9683
			return;
9684
		}
9685
		if ( this.isFirstItem() ) {
9686
			return;
9687
		}
9688
		if ( this._hasScroll() ) {
9689
			base = this.active.offset().top;
9690
			height = this.element.height();
9691
			this.active.prevAll( ".ui-menu-item" ).each(function() {
9692
				item = $( this );
9693
				return item.offset().top - base + height > 0;
9694
			});
9695
 
9696
			this.focus( event, item );
9697
		} else {
9698
			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
9699
		}
9700
	},
9701
 
9702
	_hasScroll: function() {
9703
		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
9704
	},
9705
 
9706
	select: function( event ) {
9707
		// TODO: It should never be possible to not have an active item at this
9708
		// point, but the tests don't trigger mouseenter before click.
9709
		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
9710
		var ui = { item: this.active };
9711
		if ( !this.active.has( ".ui-menu" ).length ) {
9712
			this.collapseAll( event, true );
9713
		}
9714
		this._trigger( "select", event, ui );
9715
	}
9716
});
9717
 
9718
}( jQuery ));
9719
(function( $, undefined ) {
9720
 
9721
$.widget( "ui.progressbar", {
9722
	version: "1.9.2",
9723
	options: {
9724
		value: 0,
9725
		max: 100
9726
	},
9727
 
9728
	min: 0,
9729
 
9730
	_create: function() {
9731
		this.element
9732
			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9733
			.attr({
9734
				role: "progressbar",
9735
				"aria-valuemin": this.min,
9736
				"aria-valuemax": this.options.max,
9737
				"aria-valuenow": this._value()
9738
			});
9739
 
9740
		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
9741
			.appendTo( this.element );
9742
 
9743
		this.oldValue = this._value();
9744
		this._refreshValue();
9745
	},
9746
 
9747
	_destroy: function() {
9748
		this.element
9749
			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
9750
			.removeAttr( "role" )
9751
			.removeAttr( "aria-valuemin" )
9752
			.removeAttr( "aria-valuemax" )
9753
			.removeAttr( "aria-valuenow" );
9754
 
9755
		this.valueDiv.remove();
9756
	},
9757
 
9758
	value: function( newValue ) {
9759
		if ( newValue === undefined ) {
9760
			return this._value();
9761
		}
9762
 
9763
		this._setOption( "value", newValue );
9764
		return this;
9765
	},
9766
 
9767
	_setOption: function( key, value ) {
9768
		if ( key === "value" ) {
9769
			this.options.value = value;
9770
			this._refreshValue();
9771
			if ( this._value() === this.options.max ) {
9772
				this._trigger( "complete" );
9773
			}
9774
		}
9775
 
9776
		this._super( key, value );
9777
	},
9778
 
9779
	_value: function() {
9780
		var val = this.options.value;
9781
		// normalize invalid value
9782
		if ( typeof val !== "number" ) {
9783
			val = 0;
9784
		}
9785
		return Math.min( this.options.max, Math.max( this.min, val ) );
9786
	},
9787
 
9788
	_percentage: function() {
9789
		return 100 * this._value() / this.options.max;
9790
	},
9791
 
9792
	_refreshValue: function() {
9793
		var value = this.value(),
9794
			percentage = this._percentage();
9795
 
9796
		if ( this.oldValue !== value ) {
9797
			this.oldValue = value;
9798
			this._trigger( "change" );
9799
		}
9800
 
9801
		this.valueDiv
9802
			.toggle( value > this.min )
9803
			.toggleClass( "ui-corner-right", value === this.options.max )
9804
			.width( percentage.toFixed(0) + "%" );
9805
		this.element.attr( "aria-valuenow", value );
9806
	}
9807
});
9808
 
9809
})( jQuery );
9810
(function( $, undefined ) {
9811
 
9812
// number of pages in a slider
9813
// (how many times can you page up/down to go through the whole range)
9814
var numPages = 5;
9815
 
9816
$.widget( "ui.slider", $.ui.mouse, {
9817
	version: "1.9.2",
9818
	widgetEventPrefix: "slide",
9819
 
9820
	options: {
9821
		animate: false,
9822
		distance: 0,
9823
		max: 100,
9824
		min: 0,
9825
		orientation: "horizontal",
9826
		range: false,
9827
		step: 1,
9828
		value: 0,
9829
		values: null
9830
	},
9831
 
9832
	_create: function() {
9833
		var i, handleCount,
9834
			o = this.options,
9835
			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
9836
			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
9837
			handles = [];
9838
 
9839
		this._keySliding = false;
9840
		this._mouseSliding = false;
9841
		this._animateOff = true;
9842
		this._handleIndex = null;
9843
		this._detectOrientation();
9844
		this._mouseInit();
9845
 
9846
		this.element
9847
			.addClass( "ui-slider" +
9848
				" ui-slider-" + this.orientation +
9849
				" ui-widget" +
9850
				" ui-widget-content" +
9851
				" ui-corner-all" +
9852
				( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
9853
 
9854
		this.range = $([]);
9855
 
9856
		if ( o.range ) {
9857
			if ( o.range === true ) {
9858
				if ( !o.values ) {
9859
					o.values = [ this._valueMin(), this._valueMin() ];
9860
				}
9861
				if ( o.values.length && o.values.length !== 2 ) {
9862
					o.values = [ o.values[0], o.values[0] ];
9863
				}
9864
			}
9865
 
9866
			this.range = $( "<div></div>" )
9867
				.appendTo( this.element )
9868
				.addClass( "ui-slider-range" +
9869
				// note: this isn't the most fittingly semantic framework class for this element,
9870
				// but worked best visually with a variety of themes
9871
				" ui-widget-header" +
9872
				( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
9873
		}
9874
 
9875
		handleCount = ( o.values && o.values.length ) || 1;
9876
 
9877
		for ( i = existingHandles.length; i < handleCount; i++ ) {
9878
			handles.push( handle );
9879
		}
9880
 
9881
		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
9882
 
9883
		this.handle = this.handles.eq( 0 );
9884
 
9885
		this.handles.add( this.range ).filter( "a" )
9886
			.click(function( event ) {
9887
				event.preventDefault();
9888
			})
9889
			.mouseenter(function() {
9890
				if ( !o.disabled ) {
9891
					$( this ).addClass( "ui-state-hover" );
9892
				}
9893
			})
9894
			.mouseleave(function() {
9895
				$( this ).removeClass( "ui-state-hover" );
9896
			})
9897
			.focus(function() {
9898
				if ( !o.disabled ) {
9899
					$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
9900
					$( this ).addClass( "ui-state-focus" );
9901
				} else {
9902
					$( this ).blur();
9903
				}
9904
			})
9905
			.blur(function() {
9906
				$( this ).removeClass( "ui-state-focus" );
9907
			});
9908
 
9909
		this.handles.each(function( i ) {
9910
			$( this ).data( "ui-slider-handle-index", i );
9911
		});
9912
 
9913
		this._on( this.handles, {
9914
			keydown: function( event ) {
9915
				var allowed, curVal, newVal, step,
9916
					index = $( event.target ).data( "ui-slider-handle-index" );
9917
 
9918
				switch ( event.keyCode ) {
9919
					case $.ui.keyCode.HOME:
9920
					case $.ui.keyCode.END:
9921
					case $.ui.keyCode.PAGE_UP:
9922
					case $.ui.keyCode.PAGE_DOWN:
9923
					case $.ui.keyCode.UP:
9924
					case $.ui.keyCode.RIGHT:
9925
					case $.ui.keyCode.DOWN:
9926
					case $.ui.keyCode.LEFT:
9927
						event.preventDefault();
9928
						if ( !this._keySliding ) {
9929
							this._keySliding = true;
9930
							$( event.target ).addClass( "ui-state-active" );
9931
							allowed = this._start( event, index );
9932
							if ( allowed === false ) {
9933
								return;
9934
							}
9935
						}
9936
						break;
9937
				}
9938
 
9939
				step = this.options.step;
9940
				if ( this.options.values && this.options.values.length ) {
9941
					curVal = newVal = this.values( index );
9942
				} else {
9943
					curVal = newVal = this.value();
9944
				}
9945
 
9946
				switch ( event.keyCode ) {
9947
					case $.ui.keyCode.HOME:
9948
						newVal = this._valueMin();
9949
						break;
9950
					case $.ui.keyCode.END:
9951
						newVal = this._valueMax();
9952
						break;
9953
					case $.ui.keyCode.PAGE_UP:
9954
						newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
9955
						break;
9956
					case $.ui.keyCode.PAGE_DOWN:
9957
						newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
9958
						break;
9959
					case $.ui.keyCode.UP:
9960
					case $.ui.keyCode.RIGHT:
9961
						if ( curVal === this._valueMax() ) {
9962
							return;
9963
						}
9964
						newVal = this._trimAlignValue( curVal + step );
9965
						break;
9966
					case $.ui.keyCode.DOWN:
9967
					case $.ui.keyCode.LEFT:
9968
						if ( curVal === this._valueMin() ) {
9969
							return;
9970
						}
9971
						newVal = this._trimAlignValue( curVal - step );
9972
						break;
9973
				}
9974
 
9975
				this._slide( event, index, newVal );
9976
			},
9977
			keyup: function( event ) {
9978
				var index = $( event.target ).data( "ui-slider-handle-index" );
9979
 
9980
				if ( this._keySliding ) {
9981
					this._keySliding = false;
9982
					this._stop( event, index );
9983
					this._change( event, index );
9984
					$( event.target ).removeClass( "ui-state-active" );
9985
				}
9986
			}
9987
		});
9988
 
9989
		this._refreshValue();
9990
 
9991
		this._animateOff = false;
9992
	},
9993
 
9994
	_destroy: function() {
9995
		this.handles.remove();
9996
		this.range.remove();
9997
 
9998
		this.element
9999
			.removeClass( "ui-slider" +
10000
				" ui-slider-horizontal" +
10001
				" ui-slider-vertical" +
10002
				" ui-slider-disabled" +
10003
				" ui-widget" +
10004
				" ui-widget-content" +
10005
				" ui-corner-all" );
10006
 
10007
		this._mouseDestroy();
10008
	},
10009
 
10010
	_mouseCapture: function( event ) {
10011
		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
10012
			that = this,
10013
			o = this.options;
10014
 
10015
		if ( o.disabled ) {
10016
			return false;
10017
		}
10018
 
10019
		this.elementSize = {
10020
			width: this.element.outerWidth(),
10021
			height: this.element.outerHeight()
10022
		};
10023
		this.elementOffset = this.element.offset();
10024
 
10025
		position = { x: event.pageX, y: event.pageY };
10026
		normValue = this._normValueFromMouse( position );
10027
		distance = this._valueMax() - this._valueMin() + 1;
10028
		this.handles.each(function( i ) {
10029
			var thisDistance = Math.abs( normValue - that.values(i) );
10030
			if ( distance > thisDistance ) {
10031
				distance = thisDistance;
10032
				closestHandle = $( this );
10033
				index = i;
10034
			}
10035
		});
10036
 
10037
		// workaround for bug #3736 (if both handles of a range are at 0,
10038
		// the first is always used as the one with least distance,
10039
		// and moving it is obviously prevented by preventing negative ranges)
10040
		if( o.range === true && this.values(1) === o.min ) {
10041
			index += 1;
10042
			closestHandle = $( this.handles[index] );
10043
		}
10044
 
10045
		allowed = this._start( event, index );
10046
		if ( allowed === false ) {
10047
			return false;
10048
		}
10049
		this._mouseSliding = true;
10050
 
10051
		this._handleIndex = index;
10052
 
10053
		closestHandle
10054
			.addClass( "ui-state-active" )
10055
			.focus();
10056
 
10057
		offset = closestHandle.offset();
10058
		mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
10059
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10060
			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10061
			top: event.pageY - offset.top -
10062
				( closestHandle.height() / 2 ) -
10063
				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10064
				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10065
				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10066
		};
10067
 
10068
		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10069
			this._slide( event, index, normValue );
10070
		}
10071
		this._animateOff = true;
10072
		return true;
10073
	},
10074
 
10075
	_mouseStart: function() {
10076
		return true;
10077
	},
10078
 
10079
	_mouseDrag: function( event ) {
10080
		var position = { x: event.pageX, y: event.pageY },
10081
			normValue = this._normValueFromMouse( position );
10082
 
10083
		this._slide( event, this._handleIndex, normValue );
10084
 
10085
		return false;
10086
	},
10087
 
10088
	_mouseStop: function( event ) {
10089
		this.handles.removeClass( "ui-state-active" );
10090
		this._mouseSliding = false;
10091
 
10092
		this._stop( event, this._handleIndex );
10093
		this._change( event, this._handleIndex );
10094
 
10095
		this._handleIndex = null;
10096
		this._clickOffset = null;
10097
		this._animateOff = false;
10098
 
10099
		return false;
10100
	},
10101
 
10102
	_detectOrientation: function() {
10103
		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10104
	},
10105
 
10106
	_normValueFromMouse: function( position ) {
10107
		var pixelTotal,
10108
			pixelMouse,
10109
			percentMouse,
10110
			valueTotal,
10111
			valueMouse;
10112
 
10113
		if ( this.orientation === "horizontal" ) {
10114
			pixelTotal = this.elementSize.width;
10115
			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10116
		} else {
10117
			pixelTotal = this.elementSize.height;
10118
			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10119
		}
10120
 
10121
		percentMouse = ( pixelMouse / pixelTotal );
10122
		if ( percentMouse > 1 ) {
10123
			percentMouse = 1;
10124
		}
10125
		if ( percentMouse < 0 ) {
10126
			percentMouse = 0;
10127
		}
10128
		if ( this.orientation === "vertical" ) {
10129
			percentMouse = 1 - percentMouse;
10130
		}
10131
 
10132
		valueTotal = this._valueMax() - this._valueMin();
10133
		valueMouse = this._valueMin() + percentMouse * valueTotal;
10134
 
10135
		return this._trimAlignValue( valueMouse );
10136
	},
10137
 
10138
	_start: function( event, index ) {
10139
		var uiHash = {
10140
			handle: this.handles[ index ],
10141
			value: this.value()
10142
		};
10143
		if ( this.options.values && this.options.values.length ) {
10144
			uiHash.value = this.values( index );
10145
			uiHash.values = this.values();
10146
		}
10147
		return this._trigger( "start", event, uiHash );
10148
	},
10149
 
10150
	_slide: function( event, index, newVal ) {
10151
		var otherVal,
10152
			newValues,
10153
			allowed;
10154
 
10155
		if ( this.options.values && this.options.values.length ) {
10156
			otherVal = this.values( index ? 0 : 1 );
10157
 
10158
			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
10159
					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10160
				) {
10161
				newVal = otherVal;
10162
			}
10163
 
10164
			if ( newVal !== this.values( index ) ) {
10165
				newValues = this.values();
10166
				newValues[ index ] = newVal;
10167
				// A slide can be canceled by returning false from the slide callback
10168
				allowed = this._trigger( "slide", event, {
10169
					handle: this.handles[ index ],
10170
					value: newVal,
10171
					values: newValues
10172
				} );
10173
				otherVal = this.values( index ? 0 : 1 );
10174
				if ( allowed !== false ) {
10175
					this.values( index, newVal, true );
10176
				}
10177
			}
10178
		} else {
10179
			if ( newVal !== this.value() ) {
10180
				// A slide can be canceled by returning false from the slide callback
10181
				allowed = this._trigger( "slide", event, {
10182
					handle: this.handles[ index ],
10183
					value: newVal
10184
				} );
10185
				if ( allowed !== false ) {
10186
					this.value( newVal );
10187
				}
10188
			}
10189
		}
10190
	},
10191
 
10192
	_stop: function( event, index ) {
10193
		var uiHash = {
10194
			handle: this.handles[ index ],
10195
			value: this.value()
10196
		};
10197
		if ( this.options.values && this.options.values.length ) {
10198
			uiHash.value = this.values( index );
10199
			uiHash.values = this.values();
10200
		}
10201
 
10202
		this._trigger( "stop", event, uiHash );
10203
	},
10204
 
10205
	_change: function( event, index ) {
10206
		if ( !this._keySliding && !this._mouseSliding ) {
10207
			var uiHash = {
10208
				handle: this.handles[ index ],
10209
				value: this.value()
10210
			};
10211
			if ( this.options.values && this.options.values.length ) {
10212
				uiHash.value = this.values( index );
10213
				uiHash.values = this.values();
10214
			}
10215
 
10216
			this._trigger( "change", event, uiHash );
10217
		}
10218
	},
10219
 
10220
	value: function( newValue ) {
10221
		if ( arguments.length ) {
10222
			this.options.value = this._trimAlignValue( newValue );
10223
			this._refreshValue();
10224
			this._change( null, 0 );
10225
			return;
10226
		}
10227
 
10228
		return this._value();
10229
	},
10230
 
10231
	values: function( index, newValue ) {
10232
		var vals,
10233
			newValues,
10234
			i;
10235
 
10236
		if ( arguments.length > 1 ) {
10237
			this.options.values[ index ] = this._trimAlignValue( newValue );
10238
			this._refreshValue();
10239
			this._change( null, index );
10240
			return;
10241
		}
10242
 
10243
		if ( arguments.length ) {
10244
			if ( $.isArray( arguments[ 0 ] ) ) {
10245
				vals = this.options.values;
10246
				newValues = arguments[ 0 ];
10247
				for ( i = 0; i < vals.length; i += 1 ) {
10248
					vals[ i ] = this._trimAlignValue( newValues[ i ] );
10249
					this._change( null, i );
10250
				}
10251
				this._refreshValue();
10252
			} else {
10253
				if ( this.options.values && this.options.values.length ) {
10254
					return this._values( index );
10255
				} else {
10256
					return this.value();
10257
				}
10258
			}
10259
		} else {
10260
			return this._values();
10261
		}
10262
	},
10263
 
10264
	_setOption: function( key, value ) {
10265
		var i,
10266
			valsLength = 0;
10267
 
10268
		if ( $.isArray( this.options.values ) ) {
10269
			valsLength = this.options.values.length;
10270
		}
10271
 
10272
		$.Widget.prototype._setOption.apply( this, arguments );
10273
 
10274
		switch ( key ) {
10275
			case "disabled":
10276
				if ( value ) {
10277
					this.handles.filter( ".ui-state-focus" ).blur();
10278
					this.handles.removeClass( "ui-state-hover" );
10279
					this.handles.prop( "disabled", true );
10280
					this.element.addClass( "ui-disabled" );
10281
				} else {
10282
					this.handles.prop( "disabled", false );
10283
					this.element.removeClass( "ui-disabled" );
10284
				}
10285
				break;
10286
			case "orientation":
10287
				this._detectOrientation();
10288
				this.element
10289
					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
10290
					.addClass( "ui-slider-" + this.orientation );
10291
				this._refreshValue();
10292
				break;
10293
			case "value":
10294
				this._animateOff = true;
10295
				this._refreshValue();
10296
				this._change( null, 0 );
10297
				this._animateOff = false;
10298
				break;
10299
			case "values":
10300
				this._animateOff = true;
10301
				this._refreshValue();
10302
				for ( i = 0; i < valsLength; i += 1 ) {
10303
					this._change( null, i );
10304
				}
10305
				this._animateOff = false;
10306
				break;
10307
			case "min":
10308
			case "max":
10309
				this._animateOff = true;
10310
				this._refreshValue();
10311
				this._animateOff = false;
10312
				break;
10313
		}
10314
	},
10315
 
10316
	//internal value getter
10317
	// _value() returns value trimmed by min and max, aligned by step
10318
	_value: function() {
10319
		var val = this.options.value;
10320
		val = this._trimAlignValue( val );
10321
 
10322
		return val;
10323
	},
10324
 
10325
	//internal values getter
10326
	// _values() returns array of values trimmed by min and max, aligned by step
10327
	// _values( index ) returns single value trimmed by min and max, aligned by step
10328
	_values: function( index ) {
10329
		var val,
10330
			vals,
10331
			i;
10332
 
10333
		if ( arguments.length ) {
10334
			val = this.options.values[ index ];
10335
			val = this._trimAlignValue( val );
10336
 
10337
			return val;
10338
		} else {
10339
			// .slice() creates a copy of the array
10340
			// this copy gets trimmed by min and max and then returned
10341
			vals = this.options.values.slice();
10342
			for ( i = 0; i < vals.length; i+= 1) {
10343
				vals[ i ] = this._trimAlignValue( vals[ i ] );
10344
			}
10345
 
10346
			return vals;
10347
		}
10348
	},
10349
 
10350
	// returns the step-aligned value that val is closest to, between (inclusive) min and max
10351
	_trimAlignValue: function( val ) {
10352
		if ( val <= this._valueMin() ) {
10353
			return this._valueMin();
10354
		}
10355
		if ( val >= this._valueMax() ) {
10356
			return this._valueMax();
10357
		}
10358
		var step = ( this.options.step > 0 ) ? this.options.step : 1,
10359
			valModStep = (val - this._valueMin()) % step,
10360
			alignValue = val - valModStep;
10361
 
10362
		if ( Math.abs(valModStep) * 2 >= step ) {
10363
			alignValue += ( valModStep > 0 ) ? step : ( -step );
10364
		}
10365
 
10366
		// Since JavaScript has problems with large floats, round
10367
		// the final value to 5 digits after the decimal point (see #4124)
10368
		return parseFloat( alignValue.toFixed(5) );
10369
	},
10370
 
10371
	_valueMin: function() {
10372
		return this.options.min;
10373
	},
10374
 
10375
	_valueMax: function() {
10376
		return this.options.max;
10377
	},
10378
 
10379
	_refreshValue: function() {
10380
		var lastValPercent, valPercent, value, valueMin, valueMax,
10381
			oRange = this.options.range,
10382
			o = this.options,
10383
			that = this,
10384
			animate = ( !this._animateOff ) ? o.animate : false,
10385
			_set = {};
10386
 
10387
		if ( this.options.values && this.options.values.length ) {
10388
			this.handles.each(function( i ) {
10389
				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
10390
				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10391
				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10392
				if ( that.options.range === true ) {
10393
					if ( that.orientation === "horizontal" ) {
10394
						if ( i === 0 ) {
10395
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10396
						}
10397
						if ( i === 1 ) {
10398
							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10399
						}
10400
					} else {
10401
						if ( i === 0 ) {
10402
							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10403
						}
10404
						if ( i === 1 ) {
10405
							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10406
						}
10407
					}
10408
				}
10409
				lastValPercent = valPercent;
10410
			});
10411
		} else {
10412
			value = this.value();
10413
			valueMin = this._valueMin();
10414
			valueMax = this._valueMax();
10415
			valPercent = ( valueMax !== valueMin ) ?
10416
					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10417
					0;
10418
			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10419
			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10420
 
10421
			if ( oRange === "min" && this.orientation === "horizontal" ) {
10422
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10423
			}
10424
			if ( oRange === "max" && this.orientation === "horizontal" ) {
10425
				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10426
			}
10427
			if ( oRange === "min" && this.orientation === "vertical" ) {
10428
				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10429
			}
10430
			if ( oRange === "max" && this.orientation === "vertical" ) {
10431
				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10432
			}
10433
		}
10434
	}
10435
 
10436
});
10437
 
10438
}(jQuery));
10439
(function( $ ) {
10440
 
10441
function modifier( fn ) {
10442
	return function() {
10443
		var previous = this.element.val();
10444
		fn.apply( this, arguments );
10445
		this._refresh();
10446
		if ( previous !== this.element.val() ) {
10447
			this._trigger( "change" );
10448
		}
10449
	};
10450
}
10451
 
10452
$.widget( "ui.spinner", {
10453
	version: "1.9.2",
10454
	defaultElement: "<input>",
10455
	widgetEventPrefix: "spin",
10456
	options: {
10457
		culture: null,
10458
		icons: {
10459
			down: "ui-icon-triangle-1-s",
10460
			up: "ui-icon-triangle-1-n"
10461
		},
10462
		incremental: true,
10463
		max: null,
10464
		min: null,
10465
		numberFormat: null,
10466
		page: 10,
10467
		step: 1,
10468
 
10469
		change: null,
10470
		spin: null,
10471
		start: null,
10472
		stop: null
10473
	},
10474
 
10475
	_create: function() {
10476
		// handle string values that need to be parsed
10477
		this._setOption( "max", this.options.max );
10478
		this._setOption( "min", this.options.min );
10479
		this._setOption( "step", this.options.step );
10480
 
10481
		// format the value, but don't constrain
10482
		this._value( this.element.val(), true );
10483
 
10484
		this._draw();
10485
		this._on( this._events );
10486
		this._refresh();
10487
 
10488
		// turning off autocomplete prevents the browser from remembering the
10489
		// value when navigating through history, so we re-enable autocomplete
10490
		// if the page is unloaded before the widget is destroyed. #7790
10491
		this._on( this.window, {
10492
			beforeunload: function() {
10493
				this.element.removeAttr( "autocomplete" );
10494
			}
10495
		});
10496
	},
10497
 
10498
	_getCreateOptions: function() {
10499
		var options = {},
10500
			element = this.element;
10501
 
10502
		$.each( [ "min", "max", "step" ], function( i, option ) {
10503
			var value = element.attr( option );
10504
			if ( value !== undefined && value.length ) {
10505
				options[ option ] = value;
10506
			}
10507
		});
10508
 
10509
		return options;
10510
	},
10511
 
10512
	_events: {
10513
		keydown: function( event ) {
10514
			if ( this._start( event ) && this._keydown( event ) ) {
10515
				event.preventDefault();
10516
			}
10517
		},
10518
		keyup: "_stop",
10519
		focus: function() {
10520
			this.previous = this.element.val();
10521
		},
10522
		blur: function( event ) {
10523
			if ( this.cancelBlur ) {
10524
				delete this.cancelBlur;
10525
				return;
10526
			}
10527
 
10528
			this._refresh();
10529
			if ( this.previous !== this.element.val() ) {
10530
				this._trigger( "change", event );
10531
			}
10532
		},
10533
		mousewheel: function( event, delta ) {
10534
			if ( !delta ) {
10535
				return;
10536
			}
10537
			if ( !this.spinning && !this._start( event ) ) {
10538
				return false;
10539
			}
10540
 
10541
			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
10542
			clearTimeout( this.mousewheelTimer );
10543
			this.mousewheelTimer = this._delay(function() {
10544
				if ( this.spinning ) {
10545
					this._stop( event );
10546
				}
10547
			}, 100 );
10548
			event.preventDefault();
10549
		},
10550
		"mousedown .ui-spinner-button": function( event ) {
10551
			var previous;
10552
 
10553
			// We never want the buttons to have focus; whenever the user is
10554
			// interacting with the spinner, the focus should be on the input.
10555
			// If the input is focused then this.previous is properly set from
10556
			// when the input first received focus. If the input is not focused
10557
			// then we need to set this.previous based on the value before spinning.
10558
			previous = this.element[0] === this.document[0].activeElement ?
10559
				this.previous : this.element.val();
10560
			function checkFocus() {
10561
				var isActive = this.element[0] === this.document[0].activeElement;
10562
				if ( !isActive ) {
10563
					this.element.focus();
10564
					this.previous = previous;
10565
					// support: IE
10566
					// IE sets focus asynchronously, so we need to check if focus
10567
					// moved off of the input because the user clicked on the button.
10568
					this._delay(function() {
10569
						this.previous = previous;
10570
					});
10571
				}
10572
			}
10573
 
10574
			// ensure focus is on (or stays on) the text field
10575
			event.preventDefault();
10576
			checkFocus.call( this );
10577
 
10578
			// support: IE
10579
			// IE doesn't prevent moving focus even with event.preventDefault()
10580
			// so we set a flag to know when we should ignore the blur event
10581
			// and check (again) if focus moved off of the input.
10582
			this.cancelBlur = true;
10583
			this._delay(function() {
10584
				delete this.cancelBlur;
10585
				checkFocus.call( this );
10586
			});
10587
 
10588
			if ( this._start( event ) === false ) {
10589
				return;
10590
			}
10591
 
10592
			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
10593
		},
10594
		"mouseup .ui-spinner-button": "_stop",
10595
		"mouseenter .ui-spinner-button": function( event ) {
10596
			// button will add ui-state-active if mouse was down while mouseleave and kept down
10597
			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
10598
				return;
10599
			}
10600
 
10601
			if ( this._start( event ) === false ) {
10602
				return false;
10603
			}
10604
			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
10605
		},
10606
		// TODO: do we really want to consider this a stop?
10607
		// shouldn't we just stop the repeater and wait until mouseup before
10608
		// we trigger the stop event?
10609
		"mouseleave .ui-spinner-button": "_stop"
10610
	},
10611
 
10612
	_draw: function() {
10613
		var uiSpinner = this.uiSpinner = this.element
10614
			.addClass( "ui-spinner-input" )
10615
			.attr( "autocomplete", "off" )
10616
			.wrap( this._uiSpinnerHtml() )
10617
			.parent()
10618
				// add buttons
10619
				.append( this._buttonHtml() );
10620
 
10621
		this.element.attr( "role", "spinbutton" );
10622
 
10623
		// button bindings
10624
		this.buttons = uiSpinner.find( ".ui-spinner-button" )
10625
			.attr( "tabIndex", -1 )
10626
			.button()
10627
			.removeClass( "ui-corner-all" );
10628
 
10629
		// IE 6 doesn't understand height: 50% for the buttons
10630
		// unless the wrapper has an explicit height
10631
		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
10632
				uiSpinner.height() > 0 ) {
10633
			uiSpinner.height( uiSpinner.height() );
10634
		}
10635
 
10636
		// disable spinner if element was already disabled
10637
		if ( this.options.disabled ) {
10638
			this.disable();
10639
		}
10640
	},
10641
 
10642
	_keydown: function( event ) {
10643
		var options = this.options,
10644
			keyCode = $.ui.keyCode;
10645
 
10646
		switch ( event.keyCode ) {
10647
		case keyCode.UP:
10648
			this._repeat( null, 1, event );
10649
			return true;
10650
		case keyCode.DOWN:
10651
			this._repeat( null, -1, event );
10652
			return true;
10653
		case keyCode.PAGE_UP:
10654
			this._repeat( null, options.page, event );
10655
			return true;
10656
		case keyCode.PAGE_DOWN:
10657
			this._repeat( null, -options.page, event );
10658
			return true;
10659
		}
10660
 
10661
		return false;
10662
	},
10663
 
10664
	_uiSpinnerHtml: function() {
10665
		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
10666
	},
10667
 
10668
	_buttonHtml: function() {
10669
		return "" +
10670
			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
10671
				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
10672
			"</a>" +
10673
			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
10674
				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
10675
			"</a>";
10676
	},
10677
 
10678
	_start: function( event ) {
10679
		if ( !this.spinning && this._trigger( "start", event ) === false ) {
10680
			return false;
10681
		}
10682
 
10683
		if ( !this.counter ) {
10684
			this.counter = 1;
10685
		}
10686
		this.spinning = true;
10687
		return true;
10688
	},
10689
 
10690
	_repeat: function( i, steps, event ) {
10691
		i = i || 500;
10692
 
10693
		clearTimeout( this.timer );
10694
		this.timer = this._delay(function() {
10695
			this._repeat( 40, steps, event );
10696
		}, i );
10697
 
10698
		this._spin( steps * this.options.step, event );
10699
	},
10700
 
10701
	_spin: function( step, event ) {
10702
		var value = this.value() || 0;
10703
 
10704
		if ( !this.counter ) {
10705
			this.counter = 1;
10706
		}
10707
 
10708
		value = this._adjustValue( value + step * this._increment( this.counter ) );
10709
 
10710
		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
10711
			this._value( value );
10712
			this.counter++;
10713
		}
10714
	},
10715
 
10716
	_increment: function( i ) {
10717
		var incremental = this.options.incremental;
10718
 
10719
		if ( incremental ) {
10720
			return $.isFunction( incremental ) ?
10721
				incremental( i ) :
10722
				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
10723
		}
10724
 
10725
		return 1;
10726
	},
10727
 
10728
	_precision: function() {
10729
		var precision = this._precisionOf( this.options.step );
10730
		if ( this.options.min !== null ) {
10731
			precision = Math.max( precision, this._precisionOf( this.options.min ) );
10732
		}
10733
		return precision;
10734
	},
10735
 
10736
	_precisionOf: function( num ) {
10737
		var str = num.toString(),
10738
			decimal = str.indexOf( "." );
10739
		return decimal === -1 ? 0 : str.length - decimal - 1;
10740
	},
10741
 
10742
	_adjustValue: function( value ) {
10743
		var base, aboveMin,
10744
			options = this.options;
10745
 
10746
		// make sure we're at a valid step
10747
		// - find out where we are relative to the base (min or 0)
10748
		base = options.min !== null ? options.min : 0;
10749
		aboveMin = value - base;
10750
		// - round to the nearest step
10751
		aboveMin = Math.round(aboveMin / options.step) * options.step;
10752
		// - rounding is based on 0, so adjust back to our base
10753
		value = base + aboveMin;
10754
 
10755
		// fix precision from bad JS floating point math
10756
		value = parseFloat( value.toFixed( this._precision() ) );
10757
 
10758
		// clamp the value
10759
		if ( options.max !== null && value > options.max) {
10760
			return options.max;
10761
		}
10762
		if ( options.min !== null && value < options.min ) {
10763
			return options.min;
10764
		}
10765
 
10766
		return value;
10767
	},
10768
 
10769
	_stop: function( event ) {
10770
		if ( !this.spinning ) {
10771
			return;
10772
		}
10773
 
10774
		clearTimeout( this.timer );
10775
		clearTimeout( this.mousewheelTimer );
10776
		this.counter = 0;
10777
		this.spinning = false;
10778
		this._trigger( "stop", event );
10779
	},
10780
 
10781
	_setOption: function( key, value ) {
10782
		if ( key === "culture" || key === "numberFormat" ) {
10783
			var prevValue = this._parse( this.element.val() );
10784
			this.options[ key ] = value;
10785
			this.element.val( this._format( prevValue ) );
10786
			return;
10787
		}
10788
 
10789
		if ( key === "max" || key === "min" || key === "step" ) {
10790
			if ( typeof value === "string" ) {
10791
				value = this._parse( value );
10792
			}
10793
		}
10794
 
10795
		this._super( key, value );
10796
 
10797
		if ( key === "disabled" ) {
10798
			if ( value ) {
10799
				this.element.prop( "disabled", true );
10800
				this.buttons.button( "disable" );
10801
			} else {
10802
				this.element.prop( "disabled", false );
10803
				this.buttons.button( "enable" );
10804
			}
10805
		}
10806
	},
10807
 
10808
	_setOptions: modifier(function( options ) {
10809
		this._super( options );
10810
		this._value( this.element.val() );
10811
	}),
10812
 
10813
	_parse: function( val ) {
10814
		if ( typeof val === "string" && val !== "" ) {
10815
			val = window.Globalize && this.options.numberFormat ?
10816
				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
10817
		}
10818
		return val === "" || isNaN( val ) ? null : val;
10819
	},
10820
 
10821
	_format: function( value ) {
10822
		if ( value === "" ) {
10823
			return "";
10824
		}
10825
		return window.Globalize && this.options.numberFormat ?
10826
			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
10827
			value;
10828
	},
10829
 
10830
	_refresh: function() {
10831
		this.element.attr({
10832
			"aria-valuemin": this.options.min,
10833
			"aria-valuemax": this.options.max,
10834
			// TODO: what should we do with values that can't be parsed?
10835
			"aria-valuenow": this._parse( this.element.val() )
10836
		});
10837
	},
10838
 
10839
	// update the value without triggering change
10840
	_value: function( value, allowAny ) {
10841
		var parsed;
10842
		if ( value !== "" ) {
10843
			parsed = this._parse( value );
10844
			if ( parsed !== null ) {
10845
				if ( !allowAny ) {
10846
					parsed = this._adjustValue( parsed );
10847
				}
10848
				value = this._format( parsed );
10849
			}
10850
		}
10851
		this.element.val( value );
10852
		this._refresh();
10853
	},
10854
 
10855
	_destroy: function() {
10856
		this.element
10857
			.removeClass( "ui-spinner-input" )
10858
			.prop( "disabled", false )
10859
			.removeAttr( "autocomplete" )
10860
			.removeAttr( "role" )
10861
			.removeAttr( "aria-valuemin" )
10862
			.removeAttr( "aria-valuemax" )
10863
			.removeAttr( "aria-valuenow" );
10864
		this.uiSpinner.replaceWith( this.element );
10865
	},
10866
 
10867
	stepUp: modifier(function( steps ) {
10868
		this._stepUp( steps );
10869
	}),
10870
	_stepUp: function( steps ) {
10871
		this._spin( (steps || 1) * this.options.step );
10872
	},
10873
 
10874
	stepDown: modifier(function( steps ) {
10875
		this._stepDown( steps );
10876
	}),
10877
	_stepDown: function( steps ) {
10878
		this._spin( (steps || 1) * -this.options.step );
10879
	},
10880
 
10881
	pageUp: modifier(function( pages ) {
10882
		this._stepUp( (pages || 1) * this.options.page );
10883
	}),
10884
 
10885
	pageDown: modifier(function( pages ) {
10886
		this._stepDown( (pages || 1) * this.options.page );
10887
	}),
10888
 
10889
	value: function( newVal ) {
10890
		if ( !arguments.length ) {
10891
			return this._parse( this.element.val() );
10892
		}
10893
		modifier( this._value ).call( this, newVal );
10894
	},
10895
 
10896
	widget: function() {
10897
		return this.uiSpinner;
10898
	}
10899
});
10900
 
10901
}( jQuery ) );
10902
(function( $, undefined ) {
10903
 
10904
var tabId = 0,
10905
	rhash = /#.*$/;
10906
 
10907
function getNextTabId() {
10908
	return ++tabId;
10909
}
10910
 
10911
function isLocal( anchor ) {
10912
	return anchor.hash.length > 1 &&
10913
		anchor.href.replace( rhash, "" ) ===
10914
			location.href.replace( rhash, "" )
10915
				// support: Safari 5.1
10916
				// Safari 5.1 doesn't encode spaces in window.location
10917
				// but it does encode spaces from anchors (#8777)
10918
				.replace( /\s/g, "%20" );
10919
}
10920
 
10921
$.widget( "ui.tabs", {
10922
	version: "1.9.2",
10923
	delay: 300,
10924
	options: {
10925
		active: null,
10926
		collapsible: false,
10927
		event: "click",
10928
		heightStyle: "content",
10929
		hide: null,
10930
		show: null,
10931
 
10932
		// callbacks
10933
		activate: null,
10934
		beforeActivate: null,
10935
		beforeLoad: null,
10936
		load: null
10937
	},
10938
 
10939
	_create: function() {
10940
		var that = this,
10941
			options = this.options,
10942
			active = options.active,
10943
			locationHash = location.hash.substring( 1 );
10944
 
10945
		this.running = false;
10946
 
10947
		this.element
10948
			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
10949
			.toggleClass( "ui-tabs-collapsible", options.collapsible )
10950
			// Prevent users from focusing disabled tabs via click
10951
			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
10952
				if ( $( this ).is( ".ui-state-disabled" ) ) {
10953
					event.preventDefault();
10954
				}
10955
			})
10956
			// support: IE <9
10957
			// Preventing the default action in mousedown doesn't prevent IE
10958
			// from focusing the element, so if the anchor gets focused, blur.
10959
			// We don't have to worry about focusing the previously focused
10960
			// element since clicking on a non-focusable element should focus
10961
			// the body anyway.
10962
			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
10963
				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
10964
					this.blur();
10965
				}
10966
			});
10967
 
10968
		this._processTabs();
10969
 
10970
		if ( active === null ) {
10971
			// check the fragment identifier in the URL
10972
			if ( locationHash ) {
10973
				this.tabs.each(function( i, tab ) {
10974
					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
10975
						active = i;
10976
						return false;
10977
					}
10978
				});
10979
			}
10980
 
10981
			// check for a tab marked active via a class
10982
			if ( active === null ) {
10983
				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
10984
			}
10985
 
10986
			// no active tab, set to false
10987
			if ( active === null || active === -1 ) {
10988
				active = this.tabs.length ? 0 : false;
10989
			}
10990
		}
10991
 
10992
		// handle numbers: negative, out of range
10993
		if ( active !== false ) {
10994
			active = this.tabs.index( this.tabs.eq( active ) );
10995
			if ( active === -1 ) {
10996
				active = options.collapsible ? false : 0;
10997
			}
10998
		}
10999
		options.active = active;
11000
 
11001
		// don't allow collapsible: false and active: false
11002
		if ( !options.collapsible && options.active === false && this.anchors.length ) {
11003
			options.active = 0;
11004
		}
11005
 
11006
		// Take disabling tabs via class attribute from HTML
11007
		// into account and update option properly.
11008
		if ( $.isArray( options.disabled ) ) {
11009
			options.disabled = $.unique( options.disabled.concat(
11010
				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
11011
					return that.tabs.index( li );
11012
				})
11013
			) ).sort();
11014
		}
11015
 
11016
		// check for length avoids error when initializing empty list
11017
		if ( this.options.active !== false && this.anchors.length ) {
11018
			this.active = this._findActive( this.options.active );
11019
		} else {
11020
			this.active = $();
11021
		}
11022
 
11023
		this._refresh();
11024
 
11025
		if ( this.active.length ) {
11026
			this.load( options.active );
11027
		}
11028
	},
11029
 
11030
	_getCreateEventData: function() {
11031
		return {
11032
			tab: this.active,
11033
			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
11034
		};
11035
	},
11036
 
11037
	_tabKeydown: function( event ) {
11038
		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
11039
			selectedIndex = this.tabs.index( focusedTab ),
11040
			goingForward = true;
11041
 
11042
		if ( this._handlePageNav( event ) ) {
11043
			return;
11044
		}
11045
 
11046
		switch ( event.keyCode ) {
11047
			case $.ui.keyCode.RIGHT:
11048
			case $.ui.keyCode.DOWN:
11049
				selectedIndex++;
11050
				break;
11051
			case $.ui.keyCode.UP:
11052
			case $.ui.keyCode.LEFT:
11053
				goingForward = false;
11054
				selectedIndex--;
11055
				break;
11056
			case $.ui.keyCode.END:
11057
				selectedIndex = this.anchors.length - 1;
11058
				break;
11059
			case $.ui.keyCode.HOME:
11060
				selectedIndex = 0;
11061
				break;
11062
			case $.ui.keyCode.SPACE:
11063
				// Activate only, no collapsing
11064
				event.preventDefault();
11065
				clearTimeout( this.activating );
11066
				this._activate( selectedIndex );
11067
				return;
11068
			case $.ui.keyCode.ENTER:
11069
				// Toggle (cancel delayed activation, allow collapsing)
11070
				event.preventDefault();
11071
				clearTimeout( this.activating );
11072
				// Determine if we should collapse or activate
11073
				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
11074
				return;
11075
			default:
11076
				return;
11077
		}
11078
 
11079
		// Focus the appropriate tab, based on which key was pressed
11080
		event.preventDefault();
11081
		clearTimeout( this.activating );
11082
		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
11083
 
11084
		// Navigating with control key will prevent automatic activation
11085
		if ( !event.ctrlKey ) {
11086
			// Update aria-selected immediately so that AT think the tab is already selected.
11087
			// Otherwise AT may confuse the user by stating that they need to activate the tab,
11088
			// but the tab will already be activated by the time the announcement finishes.
11089
			focusedTab.attr( "aria-selected", "false" );
11090
			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
11091
 
11092
			this.activating = this._delay(function() {
11093
				this.option( "active", selectedIndex );
11094
			}, this.delay );
11095
		}
11096
	},
11097
 
11098
	_panelKeydown: function( event ) {
11099
		if ( this._handlePageNav( event ) ) {
11100
			return;
11101
		}
11102
 
11103
		// Ctrl+up moves focus to the current tab
11104
		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
11105
			event.preventDefault();
11106
			this.active.focus();
11107
		}
11108
	},
11109
 
11110
	// Alt+page up/down moves focus to the previous/next tab (and activates)
11111
	_handlePageNav: function( event ) {
11112
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
11113
			this._activate( this._focusNextTab( this.options.active - 1, false ) );
11114
			return true;
11115
		}
11116
		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
11117
			this._activate( this._focusNextTab( this.options.active + 1, true ) );
11118
			return true;
11119
		}
11120
	},
11121
 
11122
	_findNextTab: function( index, goingForward ) {
11123
		var lastTabIndex = this.tabs.length - 1;
11124
 
11125
		function constrain() {
11126
			if ( index > lastTabIndex ) {
11127
				index = 0;
11128
			}
11129
			if ( index < 0 ) {
11130
				index = lastTabIndex;
11131
			}
11132
			return index;
11133
		}
11134
 
11135
		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
11136
			index = goingForward ? index + 1 : index - 1;
11137
		}
11138
 
11139
		return index;
11140
	},
11141
 
11142
	_focusNextTab: function( index, goingForward ) {
11143
		index = this._findNextTab( index, goingForward );
11144
		this.tabs.eq( index ).focus();
11145
		return index;
11146
	},
11147
 
11148
	_setOption: function( key, value ) {
11149
		if ( key === "active" ) {
11150
			// _activate() will handle invalid values and update this.options
11151
			this._activate( value );
11152
			return;
11153
		}
11154
 
11155
		if ( key === "disabled" ) {
11156
			// don't use the widget factory's disabled handling
11157
			this._setupDisabled( value );
11158
			return;
11159
		}
11160
 
11161
		this._super( key, value);
11162
 
11163
		if ( key === "collapsible" ) {
11164
			this.element.toggleClass( "ui-tabs-collapsible", value );
11165
			// Setting collapsible: false while collapsed; open first panel
11166
			if ( !value && this.options.active === false ) {
11167
				this._activate( 0 );
11168
			}
11169
		}
11170
 
11171
		if ( key === "event" ) {
11172
			this._setupEvents( value );
11173
		}
11174
 
11175
		if ( key === "heightStyle" ) {
11176
			this._setupHeightStyle( value );
11177
		}
11178
	},
11179
 
11180
	_tabId: function( tab ) {
11181
		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
11182
	},
11183
 
11184
	_sanitizeSelector: function( hash ) {
11185
		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
11186
	},
11187
 
11188
	refresh: function() {
11189
		var options = this.options,
11190
			lis = this.tablist.children( ":has(a[href])" );
11191
 
11192
		// get disabled tabs from class attribute from HTML
11193
		// this will get converted to a boolean if needed in _refresh()
11194
		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
11195
			return lis.index( tab );
11196
		});
11197
 
11198
		this._processTabs();
11199
 
11200
		// was collapsed or no tabs
11201
		if ( options.active === false || !this.anchors.length ) {
11202
			options.active = false;
11203
			this.active = $();
11204
		// was active, but active tab is gone
11205
		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
11206
			// all remaining tabs are disabled
11207
			if ( this.tabs.length === options.disabled.length ) {
11208
				options.active = false;
11209
				this.active = $();
11210
			// activate previous tab
11211
			} else {
11212
				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
11213
			}
11214
		// was active, active tab still exists
11215
		} else {
11216
			// make sure active index is correct
11217
			options.active = this.tabs.index( this.active );
11218
		}
11219
 
11220
		this._refresh();
11221
	},
11222
 
11223
	_refresh: function() {
11224
		this._setupDisabled( this.options.disabled );
11225
		this._setupEvents( this.options.event );
11226
		this._setupHeightStyle( this.options.heightStyle );
11227
 
11228
		this.tabs.not( this.active ).attr({
11229
			"aria-selected": "false",
11230
			tabIndex: -1
11231
		});
11232
		this.panels.not( this._getPanelForTab( this.active ) )
11233
			.hide()
11234
			.attr({
11235
				"aria-expanded": "false",
11236
				"aria-hidden": "true"
11237
			});
11238
 
11239
		// Make sure one tab is in the tab order
11240
		if ( !this.active.length ) {
11241
			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
11242
		} else {
11243
			this.active
11244
				.addClass( "ui-tabs-active ui-state-active" )
11245
				.attr({
11246
					"aria-selected": "true",
11247
					tabIndex: 0
11248
				});
11249
			this._getPanelForTab( this.active )
11250
				.show()
11251
				.attr({
11252
					"aria-expanded": "true",
11253
					"aria-hidden": "false"
11254
				});
11255
		}
11256
	},
11257
 
11258
	_processTabs: function() {
11259
		var that = this;
11260
 
11261
		this.tablist = this._getList()
11262
			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11263
			.attr( "role", "tablist" );
11264
 
11265
		this.tabs = this.tablist.find( "> li:has(a[href])" )
11266
			.addClass( "ui-state-default ui-corner-top" )
11267
			.attr({
11268
				role: "tab",
11269
				tabIndex: -1
11270
			});
11271
 
11272
		this.anchors = this.tabs.map(function() {
11273
				return $( "a", this )[ 0 ];
11274
			})
11275
			.addClass( "ui-tabs-anchor" )
11276
			.attr({
11277
				role: "presentation",
11278
				tabIndex: -1
11279
			});
11280
 
11281
		this.panels = $();
11282
 
11283
		this.anchors.each(function( i, anchor ) {
11284
			var selector, panel, panelId,
11285
				anchorId = $( anchor ).uniqueId().attr( "id" ),
11286
				tab = $( anchor ).closest( "li" ),
11287
				originalAriaControls = tab.attr( "aria-controls" );
11288
 
11289
			// inline tab
11290
			if ( isLocal( anchor ) ) {
11291
				selector = anchor.hash;
11292
				panel = that.element.find( that._sanitizeSelector( selector ) );
11293
			// remote tab
11294
			} else {
11295
				panelId = that._tabId( tab );
11296
				selector = "#" + panelId;
11297
				panel = that.element.find( selector );
11298
				if ( !panel.length ) {
11299
					panel = that._createPanel( panelId );
11300
					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
11301
				}
11302
				panel.attr( "aria-live", "polite" );
11303
			}
11304
 
11305
			if ( panel.length) {
11306
				that.panels = that.panels.add( panel );
11307
			}
11308
			if ( originalAriaControls ) {
11309
				tab.data( "ui-tabs-aria-controls", originalAriaControls );
11310
			}
11311
			tab.attr({
11312
				"aria-controls": selector.substring( 1 ),
11313
				"aria-labelledby": anchorId
11314
			});
11315
			panel.attr( "aria-labelledby", anchorId );
11316
		});
11317
 
11318
		this.panels
11319
			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11320
			.attr( "role", "tabpanel" );
11321
	},
11322
 
11323
	// allow overriding how to find the list for rare usage scenarios (#7715)
11324
	_getList: function() {
11325
		return this.element.find( "ol,ul" ).eq( 0 );
11326
	},
11327
 
11328
	_createPanel: function( id ) {
11329
		return $( "<div>" )
11330
			.attr( "id", id )
11331
			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11332
			.data( "ui-tabs-destroy", true );
11333
	},
11334
 
11335
	_setupDisabled: function( disabled ) {
11336
		if ( $.isArray( disabled ) ) {
11337
			if ( !disabled.length ) {
11338
				disabled = false;
11339
			} else if ( disabled.length === this.anchors.length ) {
11340
				disabled = true;
11341
			}
11342
		}
11343
 
11344
		// disable tabs
11345
		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
11346
			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
11347
				$( li )
11348
					.addClass( "ui-state-disabled" )
11349
					.attr( "aria-disabled", "true" );
11350
			} else {
11351
				$( li )
11352
					.removeClass( "ui-state-disabled" )
11353
					.removeAttr( "aria-disabled" );
11354
			}
11355
		}
11356
 
11357
		this.options.disabled = disabled;
11358
	},
11359
 
11360
	_setupEvents: function( event ) {
11361
		var events = {
11362
			click: function( event ) {
11363
				event.preventDefault();
11364
			}
11365
		};
11366
		if ( event ) {
11367
			$.each( event.split(" "), function( index, eventName ) {
11368
				events[ eventName ] = "_eventHandler";
11369
			});
11370
		}
11371
 
11372
		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
11373
		this._on( this.anchors, events );
11374
		this._on( this.tabs, { keydown: "_tabKeydown" } );
11375
		this._on( this.panels, { keydown: "_panelKeydown" } );
11376
 
11377
		this._focusable( this.tabs );
11378
		this._hoverable( this.tabs );
11379
	},
11380
 
11381
	_setupHeightStyle: function( heightStyle ) {
11382
		var maxHeight, overflow,
11383
			parent = this.element.parent();
11384
 
11385
		if ( heightStyle === "fill" ) {
11386
			// IE 6 treats height like minHeight, so we need to turn off overflow
11387
			// in order to get a reliable height
11388
			// we use the minHeight support test because we assume that only
11389
			// browsers that don't support minHeight will treat height as minHeight
11390
			if ( !$.support.minHeight ) {
11391
				overflow = parent.css( "overflow" );
11392
				parent.css( "overflow", "hidden");
11393
			}
11394
			maxHeight = parent.height();
11395
			this.element.siblings( ":visible" ).each(function() {
11396
				var elem = $( this ),
11397
					position = elem.css( "position" );
11398
 
11399
				if ( position === "absolute" || position === "fixed" ) {
11400
					return;
11401
				}
11402
				maxHeight -= elem.outerHeight( true );
11403
			});
11404
			if ( overflow ) {
11405
				parent.css( "overflow", overflow );
11406
			}
11407
 
11408
			this.element.children().not( this.panels ).each(function() {
11409
				maxHeight -= $( this ).outerHeight( true );
11410
			});
11411
 
11412
			this.panels.each(function() {
11413
				$( this ).height( Math.max( 0, maxHeight -
11414
					$( this ).innerHeight() + $( this ).height() ) );
11415
			})
11416
			.css( "overflow", "auto" );
11417
		} else if ( heightStyle === "auto" ) {
11418
			maxHeight = 0;
11419
			this.panels.each(function() {
11420
				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
11421
			}).height( maxHeight );
11422
		}
11423
	},
11424
 
11425
	_eventHandler: function( event ) {
11426
		var options = this.options,
11427
			active = this.active,
11428
			anchor = $( event.currentTarget ),
11429
			tab = anchor.closest( "li" ),
11430
			clickedIsActive = tab[ 0 ] === active[ 0 ],
11431
			collapsing = clickedIsActive && options.collapsible,
11432
			toShow = collapsing ? $() : this._getPanelForTab( tab ),
11433
			toHide = !active.length ? $() : this._getPanelForTab( active ),
11434
			eventData = {
11435
				oldTab: active,
11436
				oldPanel: toHide,
11437
				newTab: collapsing ? $() : tab,
11438
				newPanel: toShow
11439
			};
11440
 
11441
		event.preventDefault();
11442
 
11443
		if ( tab.hasClass( "ui-state-disabled" ) ||
11444
				// tab is already loading
11445
				tab.hasClass( "ui-tabs-loading" ) ||
11446
				// can't switch durning an animation
11447
				this.running ||
11448
				// click on active header, but not collapsible
11449
				( clickedIsActive && !options.collapsible ) ||
11450
				// allow canceling activation
11451
				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
11452
			return;
11453
		}
11454
 
11455
		options.active = collapsing ? false : this.tabs.index( tab );
11456
 
11457
		this.active = clickedIsActive ? $() : tab;
11458
		if ( this.xhr ) {
11459
			this.xhr.abort();
11460
		}
11461
 
11462
		if ( !toHide.length && !toShow.length ) {
11463
			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
11464
		}
11465
 
11466
		if ( toShow.length ) {
11467
			this.load( this.tabs.index( tab ), event );
11468
		}
11469
		this._toggle( event, eventData );
11470
	},
11471
 
11472
	// handles show/hide for selecting tabs
11473
	_toggle: function( event, eventData ) {
11474
		var that = this,
11475
			toShow = eventData.newPanel,
11476
			toHide = eventData.oldPanel;
11477
 
11478
		this.running = true;
11479
 
11480
		function complete() {
11481
			that.running = false;
11482
			that._trigger( "activate", event, eventData );
11483
		}
11484
 
11485
		function show() {
11486
			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
11487
 
11488
			if ( toShow.length && that.options.show ) {
11489
				that._show( toShow, that.options.show, complete );
11490
			} else {
11491
				toShow.show();
11492
				complete();
11493
			}
11494
		}
11495
 
11496
		// start out by hiding, then showing, then completing
11497
		if ( toHide.length && this.options.hide ) {
11498
			this._hide( toHide, this.options.hide, function() {
11499
				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
11500
				show();
11501
			});
11502
		} else {
11503
			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
11504
			toHide.hide();
11505
			show();
11506
		}
11507
 
11508
		toHide.attr({
11509
			"aria-expanded": "false",
11510
			"aria-hidden": "true"
11511
		});
11512
		eventData.oldTab.attr( "aria-selected", "false" );
11513
		// If we're switching tabs, remove the old tab from the tab order.
11514
		// If we're opening from collapsed state, remove the previous tab from the tab order.
11515
		// If we're collapsing, then keep the collapsing tab in the tab order.
11516
		if ( toShow.length && toHide.length ) {
11517
			eventData.oldTab.attr( "tabIndex", -1 );
11518
		} else if ( toShow.length ) {
11519
			this.tabs.filter(function() {
11520
				return $( this ).attr( "tabIndex" ) === 0;
11521
			})
11522
			.attr( "tabIndex", -1 );
11523
		}
11524
 
11525
		toShow.attr({
11526
			"aria-expanded": "true",
11527
			"aria-hidden": "false"
11528
		});
11529
		eventData.newTab.attr({
11530
			"aria-selected": "true",
11531
			tabIndex: 0
11532
		});
11533
	},
11534
 
11535
	_activate: function( index ) {
11536
		var anchor,
11537
			active = this._findActive( index );
11538
 
11539
		// trying to activate the already active panel
11540
		if ( active[ 0 ] === this.active[ 0 ] ) {
11541
			return;
11542
		}
11543
 
11544
		// trying to collapse, simulate a click on the current active header
11545
		if ( !active.length ) {
11546
			active = this.active;
11547
		}
11548
 
11549
		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
11550
		this._eventHandler({
11551
			target: anchor,
11552
			currentTarget: anchor,
11553
			preventDefault: $.noop
11554
		});
11555
	},
11556
 
11557
	_findActive: function( index ) {
11558
		return index === false ? $() : this.tabs.eq( index );
11559
	},
11560
 
11561
	_getIndex: function( index ) {
11562
		// meta-function to give users option to provide a href string instead of a numerical index.
11563
		if ( typeof index === "string" ) {
11564
			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
11565
		}
11566
 
11567
		return index;
11568
	},
11569
 
11570
	_destroy: function() {
11571
		if ( this.xhr ) {
11572
			this.xhr.abort();
11573
		}
11574
 
11575
		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
11576
 
11577
		this.tablist
11578
			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11579
			.removeAttr( "role" );
11580
 
11581
		this.anchors
11582
			.removeClass( "ui-tabs-anchor" )
11583
			.removeAttr( "role" )
11584
			.removeAttr( "tabIndex" )
11585
			.removeData( "href.tabs" )
11586
			.removeData( "load.tabs" )
11587
			.removeUniqueId();
11588
 
11589
		this.tabs.add( this.panels ).each(function() {
11590
			if ( $.data( this, "ui-tabs-destroy" ) ) {
11591
				$( this ).remove();
11592
			} else {
11593
				$( this )
11594
					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
11595
						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
11596
					.removeAttr( "tabIndex" )
11597
					.removeAttr( "aria-live" )
11598
					.removeAttr( "aria-busy" )
11599
					.removeAttr( "aria-selected" )
11600
					.removeAttr( "aria-labelledby" )
11601
					.removeAttr( "aria-hidden" )
11602
					.removeAttr( "aria-expanded" )
11603
					.removeAttr( "role" );
11604
			}
11605
		});
11606
 
11607
		this.tabs.each(function() {
11608
			var li = $( this ),
11609
				prev = li.data( "ui-tabs-aria-controls" );
11610
			if ( prev ) {
11611
				li.attr( "aria-controls", prev );
11612
			} else {
11613
				li.removeAttr( "aria-controls" );
11614
			}
11615
		});
11616
 
11617
		this.panels.show();
11618
 
11619
		if ( this.options.heightStyle !== "content" ) {
11620
			this.panels.css( "height", "" );
11621
		}
11622
	},
11623
 
11624
	enable: function( index ) {
11625
		var disabled = this.options.disabled;
11626
		if ( disabled === false ) {
11627
			return;
11628
		}
11629
 
11630
		if ( index === undefined ) {
11631
			disabled = false;
11632
		} else {
11633
			index = this._getIndex( index );
11634
			if ( $.isArray( disabled ) ) {
11635
				disabled = $.map( disabled, function( num ) {
11636
					return num !== index ? num : null;
11637
				});
11638
			} else {
11639
				disabled = $.map( this.tabs, function( li, num ) {
11640
					return num !== index ? num : null;
11641
				});
11642
			}
11643
		}
11644
		this._setupDisabled( disabled );
11645
	},
11646
 
11647
	disable: function( index ) {
11648
		var disabled = this.options.disabled;
11649
		if ( disabled === true ) {
11650
			return;
11651
		}
11652
 
11653
		if ( index === undefined ) {
11654
			disabled = true;
11655
		} else {
11656
			index = this._getIndex( index );
11657
			if ( $.inArray( index, disabled ) !== -1 ) {
11658
				return;
11659
			}
11660
			if ( $.isArray( disabled ) ) {
11661
				disabled = $.merge( [ index ], disabled ).sort();
11662
			} else {
11663
				disabled = [ index ];
11664
			}
11665
		}
11666
		this._setupDisabled( disabled );
11667
	},
11668
 
11669
	load: function( index, event ) {
11670
		index = this._getIndex( index );
11671
		var that = this,
11672
			tab = this.tabs.eq( index ),
11673
			anchor = tab.find( ".ui-tabs-anchor" ),
11674
			panel = this._getPanelForTab( tab ),
11675
			eventData = {
11676
				tab: tab,
11677
				panel: panel
11678
			};
11679
 
11680
		// not remote
11681
		if ( isLocal( anchor[ 0 ] ) ) {
11682
			return;
11683
		}
11684
 
11685
		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
11686
 
11687
		// support: jQuery <1.8
11688
		// jQuery <1.8 returns false if the request is canceled in beforeSend,
11689
		// but as of 1.8, $.ajax() always returns a jqXHR object.
11690
		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
11691
			tab.addClass( "ui-tabs-loading" );
11692
			panel.attr( "aria-busy", "true" );
11693
 
11694
			this.xhr
11695
				.success(function( response ) {
11696
					// support: jQuery <1.8
11697
					// http://bugs.jquery.com/ticket/11778
11698
					setTimeout(function() {
11699
						panel.html( response );
11700
						that._trigger( "load", event, eventData );
11701
					}, 1 );
11702
				})
11703
				.complete(function( jqXHR, status ) {
11704
					// support: jQuery <1.8
11705
					// http://bugs.jquery.com/ticket/11778
11706
					setTimeout(function() {
11707
						if ( status === "abort" ) {
11708
							that.panels.stop( false, true );
11709
						}
11710
 
11711
						tab.removeClass( "ui-tabs-loading" );
11712
						panel.removeAttr( "aria-busy" );
11713
 
11714
						if ( jqXHR === that.xhr ) {
11715
							delete that.xhr;
11716
						}
11717
					}, 1 );
11718
				});
11719
		}
11720
	},
11721
 
11722
	// TODO: Remove this function in 1.10 when ajaxOptions is removed
11723
	_ajaxSettings: function( anchor, event, eventData ) {
11724
		var that = this;
11725
		return {
11726
			url: anchor.attr( "href" ),
11727
			beforeSend: function( jqXHR, settings ) {
11728
				return that._trigger( "beforeLoad", event,
11729
					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
11730
			}
11731
		};
11732
	},
11733
 
11734
	_getPanelForTab: function( tab ) {
11735
		var id = $( tab ).attr( "aria-controls" );
11736
		return this.element.find( this._sanitizeSelector( "#" + id ) );
11737
	}
11738
});
11739
 
11740
// DEPRECATED
11741
if ( $.uiBackCompat !== false ) {
11742
 
11743
	// helper method for a lot of the back compat extensions
11744
	$.ui.tabs.prototype._ui = function( tab, panel ) {
11745
		return {
11746
			tab: tab,
11747
			panel: panel,
11748
			index: this.anchors.index( tab )
11749
		};
11750
	};
11751
 
11752
	// url method
11753
	$.widget( "ui.tabs", $.ui.tabs, {
11754
		url: function( index, url ) {
11755
			this.anchors.eq( index ).attr( "href", url );
11756
		}
11757
	});
11758
 
11759
	// TODO: Remove _ajaxSettings() method when removing this extension
11760
	// ajaxOptions and cache options
11761
	$.widget( "ui.tabs", $.ui.tabs, {
11762
		options: {
11763
			ajaxOptions: null,
11764
			cache: false
11765
		},
11766
 
11767
		_create: function() {
11768
			this._super();
11769
 
11770
			var that = this;
11771
 
11772
			this._on({ tabsbeforeload: function( event, ui ) {
11773
				// tab is already cached
11774
				if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
11775
					event.preventDefault();
11776
					return;
11777
				}
11778
 
11779
				ui.jqXHR.success(function() {
11780
					if ( that.options.cache ) {
11781
						$.data( ui.tab[ 0 ], "cache.tabs", true );
11782
					}
11783
				});
11784
			}});
11785
		},
11786
 
11787
		_ajaxSettings: function( anchor, event, ui ) {
11788
			var ajaxOptions = this.options.ajaxOptions;
11789
			return $.extend( {}, ajaxOptions, {
11790
				error: function( xhr, status ) {
11791
					try {
11792
						// Passing index avoid a race condition when this method is
11793
						// called after the user has selected another tab.
11794
						// Pass the anchor that initiated this request allows
11795
						// loadError to manipulate the tab content panel via $(a.hash)
11796
						ajaxOptions.error(
11797
							xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
11798
					}
11799
					catch ( error ) {}
11800
				}
11801
			}, this._superApply( arguments ) );
11802
		},
11803
 
11804
		_setOption: function( key, value ) {
11805
			// reset cache if switching from cached to not cached
11806
			if ( key === "cache" && value === false ) {
11807
				this.anchors.removeData( "cache.tabs" );
11808
			}
11809
			this._super( key, value );
11810
		},
11811
 
11812
		_destroy: function() {
11813
			this.anchors.removeData( "cache.tabs" );
11814
			this._super();
11815
		},
11816
 
11817
		url: function( index ){
11818
			this.anchors.eq( index ).removeData( "cache.tabs" );
11819
			this._superApply( arguments );
11820
		}
11821
	});
11822
 
11823
	// abort method
11824
	$.widget( "ui.tabs", $.ui.tabs, {
11825
		abort: function() {
11826
			if ( this.xhr ) {
11827
				this.xhr.abort();
11828
			}
11829
		}
11830
	});
11831
 
11832
	// spinner
11833
	$.widget( "ui.tabs", $.ui.tabs, {
11834
		options: {
11835
			spinner: "<em>Loading&#8230;</em>"
11836
		},
11837
		_create: function() {
11838
			this._super();
11839
			this._on({
11840
				tabsbeforeload: function( event, ui ) {
11841
					// Don't react to nested tabs or tabs that don't use a spinner
11842
					if ( event.target !== this.element[ 0 ] ||
11843
							!this.options.spinner ) {
11844
						return;
11845
					}
11846
 
11847
					var span = ui.tab.find( "span" ),
11848
						html = span.html();
11849
					span.html( this.options.spinner );
11850
					ui.jqXHR.complete(function() {
11851
						span.html( html );
11852
					});
11853
				}
11854
			});
11855
		}
11856
	});
11857
 
11858
	// enable/disable events
11859
	$.widget( "ui.tabs", $.ui.tabs, {
11860
		options: {
11861
			enable: null,
11862
			disable: null
11863
		},
11864
 
11865
		enable: function( index ) {
11866
			var options = this.options,
11867
				trigger;
11868
 
11869
			if ( index && options.disabled === true ||
11870
					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
11871
				trigger = true;
11872
			}
11873
 
11874
			this._superApply( arguments );
11875
 
11876
			if ( trigger ) {
11877
				this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11878
			}
11879
		},
11880
 
11881
		disable: function( index ) {
11882
			var options = this.options,
11883
				trigger;
11884
 
11885
			if ( index && options.disabled === false ||
11886
					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
11887
				trigger = true;
11888
			}
11889
 
11890
			this._superApply( arguments );
11891
 
11892
			if ( trigger ) {
11893
				this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11894
			}
11895
		}
11896
	});
11897
 
11898
	// add/remove methods and events
11899
	$.widget( "ui.tabs", $.ui.tabs, {
11900
		options: {
11901
			add: null,
11902
			remove: null,
11903
			tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
11904
		},
11905
 
11906
		add: function( url, label, index ) {
11907
			if ( index === undefined ) {
11908
				index = this.anchors.length;
11909
			}
11910
 
11911
			var doInsertAfter, panel,
11912
				options = this.options,
11913
				li = $( options.tabTemplate
11914
					.replace( /#\{href\}/g, url )
11915
					.replace( /#\{label\}/g, label ) ),
11916
				id = !url.indexOf( "#" ) ?
11917
					url.replace( "#", "" ) :
11918
					this._tabId( li );
11919
 
11920
			li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
11921
			li.attr( "aria-controls", id );
11922
 
11923
			doInsertAfter = index >= this.tabs.length;
11924
 
11925
			// try to find an existing element before creating a new one
11926
			panel = this.element.find( "#" + id );
11927
			if ( !panel.length ) {
11928
				panel = this._createPanel( id );
11929
				if ( doInsertAfter ) {
11930
					if ( index > 0 ) {
11931
						panel.insertAfter( this.panels.eq( -1 ) );
11932
					} else {
11933
						panel.appendTo( this.element );
11934
					}
11935
				} else {
11936
					panel.insertBefore( this.panels[ index ] );
11937
				}
11938
			}
11939
			panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
11940
 
11941
			if ( doInsertAfter ) {
11942
				li.appendTo( this.tablist );
11943
			} else {
11944
				li.insertBefore( this.tabs[ index ] );
11945
			}
11946
 
11947
			options.disabled = $.map( options.disabled, function( n ) {
11948
				return n >= index ? ++n : n;
11949
			});
11950
 
11951
			this.refresh();
11952
			if ( this.tabs.length === 1 && options.active === false ) {
11953
				this.option( "active", 0 );
11954
			}
11955
 
11956
			this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11957
			return this;
11958
		},
11959
 
11960
		remove: function( index ) {
11961
			index = this._getIndex( index );
11962
			var options = this.options,
11963
				tab = this.tabs.eq( index ).remove(),
11964
				panel = this._getPanelForTab( tab ).remove();
11965
 
11966
			// If selected tab was removed focus tab to the right or
11967
			// in case the last tab was removed the tab to the left.
11968
			// We check for more than 2 tabs, because if there are only 2,
11969
			// then when we remove this tab, there will only be one tab left
11970
			// so we don't need to detect which tab to activate.
11971
			if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
11972
				this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
11973
			}
11974
 
11975
			options.disabled = $.map(
11976
				$.grep( options.disabled, function( n ) {
11977
					return n !== index;
11978
				}),
11979
				function( n ) {
11980
					return n >= index ? --n : n;
11981
				});
11982
 
11983
			this.refresh();
11984
 
11985
			this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
11986
			return this;
11987
		}
11988
	});
11989
 
11990
	// length method
11991
	$.widget( "ui.tabs", $.ui.tabs, {
11992
		length: function() {
11993
			return this.anchors.length;
11994
		}
11995
	});
11996
 
11997
	// panel ids (idPrefix option + title attribute)
11998
	$.widget( "ui.tabs", $.ui.tabs, {
11999
		options: {
12000
			idPrefix: "ui-tabs-"
12001
		},
12002
 
12003
		_tabId: function( tab ) {
12004
			var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
12005
			a = a[0];
12006
			return $( a ).closest( "li" ).attr( "aria-controls" ) ||
12007
				a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
12008
				this.options.idPrefix + getNextTabId();
12009
		}
12010
	});
12011
 
12012
	// _createPanel method
12013
	$.widget( "ui.tabs", $.ui.tabs, {
12014
		options: {
12015
			panelTemplate: "<div></div>"
12016
		},
12017
 
12018
		_createPanel: function( id ) {
12019
			return $( this.options.panelTemplate )
12020
				.attr( "id", id )
12021
				.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
12022
				.data( "ui-tabs-destroy", true );
12023
		}
12024
	});
12025
 
12026
	// selected option
12027
	$.widget( "ui.tabs", $.ui.tabs, {
12028
		_create: function() {
12029
			var options = this.options;
12030
			if ( options.active === null && options.selected !== undefined ) {
12031
				options.active = options.selected === -1 ? false : options.selected;
12032
			}
12033
			this._super();
12034
			options.selected = options.active;
12035
			if ( options.selected === false ) {
12036
				options.selected = -1;
12037
			}
12038
		},
12039
 
12040
		_setOption: function( key, value ) {
12041
			if ( key !== "selected" ) {
12042
				return this._super( key, value );
12043
			}
12044
 
12045
			var options = this.options;
12046
			this._super( "active", value === -1 ? false : value );
12047
			options.selected = options.active;
12048
			if ( options.selected === false ) {
12049
				options.selected = -1;
12050
			}
12051
		},
12052
 
12053
		_eventHandler: function() {
12054
			this._superApply( arguments );
12055
			this.options.selected = this.options.active;
12056
			if ( this.options.selected === false ) {
12057
				this.options.selected = -1;
12058
			}
12059
		}
12060
	});
12061
 
12062
	// show and select event
12063
	$.widget( "ui.tabs", $.ui.tabs, {
12064
		options: {
12065
			show: null,
12066
			select: null
12067
		},
12068
		_create: function() {
12069
			this._super();
12070
			if ( this.options.active !== false ) {
12071
				this._trigger( "show", null, this._ui(
12072
					this.active.find( ".ui-tabs-anchor" )[ 0 ],
12073
					this._getPanelForTab( this.active )[ 0 ] ) );
12074
			}
12075
		},
12076
		_trigger: function( type, event, data ) {
12077
			var tab, panel,
12078
				ret = this._superApply( arguments );
12079
 
12080
			if ( !ret ) {
12081
				return false;
12082
			}
12083
 
12084
			if ( type === "beforeActivate" ) {
12085
				tab = data.newTab.length ? data.newTab : data.oldTab;
12086
				panel = data.newPanel.length ? data.newPanel : data.oldPanel;
12087
				ret = this._super( "select", event, {
12088
					tab: tab.find( ".ui-tabs-anchor" )[ 0],
12089
					panel: panel[ 0 ],
12090
					index: tab.closest( "li" ).index()
12091
				});
12092
			} else if ( type === "activate" && data.newTab.length ) {
12093
				ret = this._super( "show", event, {
12094
					tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
12095
					panel: data.newPanel[ 0 ],
12096
					index: data.newTab.closest( "li" ).index()
12097
				});
12098
			}
12099
			return ret;
12100
		}
12101
	});
12102
 
12103
	// select method
12104
	$.widget( "ui.tabs", $.ui.tabs, {
12105
		select: function( index ) {
12106
			index = this._getIndex( index );
12107
			if ( index === -1 ) {
12108
				if ( this.options.collapsible && this.options.selected !== -1 ) {
12109
					index = this.options.selected;
12110
				} else {
12111
					return;
12112
				}
12113
			}
12114
			this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
12115
		}
12116
	});
12117
 
12118
	// cookie option
12119
	(function() {
12120
 
12121
	var listId = 0;
12122
 
12123
	$.widget( "ui.tabs", $.ui.tabs, {
12124
		options: {
12125
			cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
12126
		},
12127
		_create: function() {
12128
			var options = this.options,
12129
				active;
12130
			if ( options.active == null && options.cookie ) {
12131
				active = parseInt( this._cookie(), 10 );
12132
				if ( active === -1 ) {
12133
					active = false;
12134
				}
12135
				options.active = active;
12136
			}
12137
			this._super();
12138
		},
12139
		_cookie: function( active ) {
12140
			var cookie = [ this.cookie ||
12141
				( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
12142
			if ( arguments.length ) {
12143
				cookie.push( active === false ? -1 : active );
12144
				cookie.push( this.options.cookie );
12145
			}
12146
			return $.cookie.apply( null, cookie );
12147
		},
12148
		_refresh: function() {
12149
			this._super();
12150
			if ( this.options.cookie ) {
12151
				this._cookie( this.options.active, this.options.cookie );
12152
			}
12153
		},
12154
		_eventHandler: function() {
12155
			this._superApply( arguments );
12156
			if ( this.options.cookie ) {
12157
				this._cookie( this.options.active, this.options.cookie );
12158
			}
12159
		},
12160
		_destroy: function() {
12161
			this._super();
12162
			if ( this.options.cookie ) {
12163
				this._cookie( null, this.options.cookie );
12164
			}
12165
		}
12166
	});
12167
 
12168
	})();
12169
 
12170
	// load event
12171
	$.widget( "ui.tabs", $.ui.tabs, {
12172
		_trigger: function( type, event, data ) {
12173
			var _data = $.extend( {}, data );
12174
			if ( type === "load" ) {
12175
				_data.panel = _data.panel[ 0 ];
12176
				_data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
12177
			}
12178
			return this._super( type, event, _data );
12179
		}
12180
	});
12181
 
12182
	// fx option
12183
	// The new animation options (show, hide) conflict with the old show callback.
12184
	// The old fx option wins over show/hide anyway (always favor back-compat).
12185
	// If a user wants to use the new animation API, they must give up the old API.
12186
	$.widget( "ui.tabs", $.ui.tabs, {
12187
		options: {
12188
			fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
12189
		},
12190
 
12191
		_getFx: function() {
12192
			var hide, show,
12193
				fx = this.options.fx;
12194
 
12195
			if ( fx ) {
12196
				if ( $.isArray( fx ) ) {
12197
					hide = fx[ 0 ];
12198
					show = fx[ 1 ];
12199
				} else {
12200
					hide = show = fx;
12201
				}
12202
			}
12203
 
12204
			return fx ? { show: show, hide: hide } : null;
12205
		},
12206
 
12207
		_toggle: function( event, eventData ) {
12208
			var that = this,
12209
				toShow = eventData.newPanel,
12210
				toHide = eventData.oldPanel,
12211
				fx = this._getFx();
12212
 
12213
			if ( !fx ) {
12214
				return this._super( event, eventData );
12215
			}
12216
 
12217
			that.running = true;
12218
 
12219
			function complete() {
12220
				that.running = false;
12221
				that._trigger( "activate", event, eventData );
12222
			}
12223
 
12224
			function show() {
12225
				eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
12226
 
12227
				if ( toShow.length && fx.show ) {
12228
					toShow
12229
						.animate( fx.show, fx.show.duration, function() {
12230
							complete();
12231
						});
12232
				} else {
12233
					toShow.show();
12234
					complete();
12235
				}
12236
			}
12237
 
12238
			// start out by hiding, then showing, then completing
12239
			if ( toHide.length && fx.hide ) {
12240
				toHide.animate( fx.hide, fx.hide.duration, function() {
12241
					eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12242
					show();
12243
				});
12244
			} else {
12245
				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12246
				toHide.hide();
12247
				show();
12248
			}
12249
		}
12250
	});
12251
}
12252
 
12253
})( jQuery );
12254
(function( $ ) {
12255
 
12256
var increments = 0;
12257
 
12258
function addDescribedBy( elem, id ) {
12259
	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
12260
	describedby.push( id );
12261
	elem
12262
		.data( "ui-tooltip-id", id )
12263
		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
12264
}
12265
 
12266
function removeDescribedBy( elem ) {
12267
	var id = elem.data( "ui-tooltip-id" ),
12268
		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
12269
		index = $.inArray( id, describedby );
12270
	if ( index !== -1 ) {
12271
		describedby.splice( index, 1 );
12272
	}
12273
 
12274
	elem.removeData( "ui-tooltip-id" );
12275
	describedby = $.trim( describedby.join( " " ) );
12276
	if ( describedby ) {
12277
		elem.attr( "aria-describedby", describedby );
12278
	} else {
12279
		elem.removeAttr( "aria-describedby" );
12280
	}
12281
}
12282
 
12283
$.widget( "ui.tooltip", {
12284
	version: "1.9.2",
12285
	options: {
12286
		content: function() {
12287
			return $( this ).attr( "title" );
12288
		},
12289
		hide: true,
12290
		// Disabled elements have inconsistent behavior across browsers (#8661)
12291
		items: "[title]:not([disabled])",
12292
		position: {
12293
			my: "left top+15",
12294
			at: "left bottom",
12295
			collision: "flipfit flip"
12296
		},
12297
		show: true,
12298
		tooltipClass: null,
12299
		track: false,
12300
 
12301
		// callbacks
12302
		close: null,
12303
		open: null
12304
	},
12305
 
12306
	_create: function() {
12307
		this._on({
12308
			mouseover: "open",
12309
			focusin: "open"
12310
		});
12311
 
12312
		// IDs of generated tooltips, needed for destroy
12313
		this.tooltips = {};
12314
		// IDs of parent tooltips where we removed the title attribute
12315
		this.parents = {};
12316
 
12317
		if ( this.options.disabled ) {
12318
			this._disable();
12319
		}
12320
	},
12321
 
12322
	_setOption: function( key, value ) {
12323
		var that = this;
12324
 
12325
		if ( key === "disabled" ) {
12326
			this[ value ? "_disable" : "_enable" ]();
12327
			this.options[ key ] = value;
12328
			// disable element style changes
12329
			return;
12330
		}
12331
 
12332
		this._super( key, value );
12333
 
12334
		if ( key === "content" ) {
12335
			$.each( this.tooltips, function( id, element ) {
12336
				that._updateContent( element );
12337
			});
12338
		}
12339
	},
12340
 
12341
	_disable: function() {
12342
		var that = this;
12343
 
12344
		// close open tooltips
12345
		$.each( this.tooltips, function( id, element ) {
12346
			var event = $.Event( "blur" );
12347
			event.target = event.currentTarget = element[0];
12348
			that.close( event, true );
12349
		});
12350
 
12351
		// remove title attributes to prevent native tooltips
12352
		this.element.find( this.options.items ).andSelf().each(function() {
12353
			var element = $( this );
12354
			if ( element.is( "[title]" ) ) {
12355
				element
12356
					.data( "ui-tooltip-title", element.attr( "title" ) )
12357
					.attr( "title", "" );
12358
			}
12359
		});
12360
	},
12361
 
12362
	_enable: function() {
12363
		// restore title attributes
12364
		this.element.find( this.options.items ).andSelf().each(function() {
12365
			var element = $( this );
12366
			if ( element.data( "ui-tooltip-title" ) ) {
12367
				element.attr( "title", element.data( "ui-tooltip-title" ) );
12368
			}
12369
		});
12370
	},
12371
 
12372
	open: function( event ) {
12373
		var that = this,
12374
			target = $( event ? event.target : this.element )
12375
				// we need closest here due to mouseover bubbling,
12376
				// but always pointing at the same event target
12377
				.closest( this.options.items );
12378
 
12379
		// No element to show a tooltip for or the tooltip is already open
12380
		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
12381
			return;
12382
		}
12383
 
12384
		if ( target.attr( "title" ) ) {
12385
			target.data( "ui-tooltip-title", target.attr( "title" ) );
12386
		}
12387
 
12388
		target.data( "ui-tooltip-open", true );
12389
 
12390
		// kill parent tooltips, custom or native, for hover
12391
		if ( event && event.type === "mouseover" ) {
12392
			target.parents().each(function() {
12393
				var parent = $( this ),
12394
					blurEvent;
12395
				if ( parent.data( "ui-tooltip-open" ) ) {
12396
					blurEvent = $.Event( "blur" );
12397
					blurEvent.target = blurEvent.currentTarget = this;
12398
					that.close( blurEvent, true );
12399
				}
12400
				if ( parent.attr( "title" ) ) {
12401
					parent.uniqueId();
12402
					that.parents[ this.id ] = {
12403
						element: this,
12404
						title: parent.attr( "title" )
12405
					};
12406
					parent.attr( "title", "" );
12407
				}
12408
			});
12409
		}
12410
 
12411
		this._updateContent( target, event );
12412
	},
12413
 
12414
	_updateContent: function( target, event ) {
12415
		var content,
12416
			contentOption = this.options.content,
12417
			that = this,
12418
			eventType = event ? event.type : null;
12419
 
12420
		if ( typeof contentOption === "string" ) {
12421
			return this._open( event, target, contentOption );
12422
		}
12423
 
12424
		content = contentOption.call( target[0], function( response ) {
12425
			// ignore async response if tooltip was closed already
12426
			if ( !target.data( "ui-tooltip-open" ) ) {
12427
				return;
12428
			}
12429
			// IE may instantly serve a cached response for ajax requests
12430
			// delay this call to _open so the other call to _open runs first
12431
			that._delay(function() {
12432
				// jQuery creates a special event for focusin when it doesn't
12433
				// exist natively. To improve performance, the native event
12434
				// object is reused and the type is changed. Therefore, we can't
12435
				// rely on the type being correct after the event finished
12436
				// bubbling, so we set it back to the previous value. (#8740)
12437
				if ( event ) {
12438
					event.type = eventType;
12439
				}
12440
				this._open( event, target, response );
12441
			});
12442
		});
12443
		if ( content ) {
12444
			this._open( event, target, content );
12445
		}
12446
	},
12447
 
12448
	_open: function( event, target, content ) {
12449
		var tooltip, events, delayedShow,
12450
			positionOption = $.extend( {}, this.options.position );
12451
 
12452
		if ( !content ) {
12453
			return;
12454
		}
12455
 
12456
		// Content can be updated multiple times. If the tooltip already
12457
		// exists, then just update the content and bail.
12458
		tooltip = this._find( target );
12459
		if ( tooltip.length ) {
12460
			tooltip.find( ".ui-tooltip-content" ).html( content );
12461
			return;
12462
		}
12463
 
12464
		// if we have a title, clear it to prevent the native tooltip
12465
		// we have to check first to avoid defining a title if none exists
12466
		// (we don't want to cause an element to start matching [title])
12467
		//
12468
		// We use removeAttr only for key events, to allow IE to export the correct
12469
		// accessible attributes. For mouse events, set to empty string to avoid
12470
		// native tooltip showing up (happens only when removing inside mouseover).
12471
		if ( target.is( "[title]" ) ) {
12472
			if ( event && event.type === "mouseover" ) {
12473
				target.attr( "title", "" );
12474
			} else {
12475
				target.removeAttr( "title" );
12476
			}
12477
		}
12478
 
12479
		tooltip = this._tooltip( target );
12480
		addDescribedBy( target, tooltip.attr( "id" ) );
12481
		tooltip.find( ".ui-tooltip-content" ).html( content );
12482
 
12483
		function position( event ) {
12484
			positionOption.of = event;
12485
			if ( tooltip.is( ":hidden" ) ) {
12486
				return;
12487
			}
12488
			tooltip.position( positionOption );
12489
		}
12490
		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
12491
			this._on( this.document, {
12492
				mousemove: position
12493
			});
12494
			// trigger once to override element-relative positioning
12495
			position( event );
12496
		} else {
12497
			tooltip.position( $.extend({
12498
				of: target
12499
			}, this.options.position ) );
12500
		}
12501
 
12502
		tooltip.hide();
12503
 
12504
		this._show( tooltip, this.options.show );
12505
		// Handle tracking tooltips that are shown with a delay (#8644). As soon
12506
		// as the tooltip is visible, position the tooltip using the most recent
12507
		// event.
12508
		if ( this.options.show && this.options.show.delay ) {
12509
			delayedShow = setInterval(function() {
12510
				if ( tooltip.is( ":visible" ) ) {
12511
					position( positionOption.of );
12512
					clearInterval( delayedShow );
12513
				}
12514
			}, $.fx.interval );
12515
		}
12516
 
12517
		this._trigger( "open", event, { tooltip: tooltip } );
12518
 
12519
		events = {
12520
			keyup: function( event ) {
12521
				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
12522
					var fakeEvent = $.Event(event);
12523
					fakeEvent.currentTarget = target[0];
12524
					this.close( fakeEvent, true );
12525
				}
12526
			},
12527
			remove: function() {
12528
				this._removeTooltip( tooltip );
12529
			}
12530
		};
12531
		if ( !event || event.type === "mouseover" ) {
12532
			events.mouseleave = "close";
12533
		}
12534
		if ( !event || event.type === "focusin" ) {
12535
			events.focusout = "close";
12536
		}
12537
		this._on( true, target, events );
12538
	},
12539
 
12540
	close: function( event ) {
12541
		var that = this,
12542
			target = $( event ? event.currentTarget : this.element ),
12543
			tooltip = this._find( target );
12544
 
12545
		// disabling closes the tooltip, so we need to track when we're closing
12546
		// to avoid an infinite loop in case the tooltip becomes disabled on close
12547
		if ( this.closing ) {
12548
			return;
12549
		}
12550
 
12551
		// only set title if we had one before (see comment in _open())
12552
		if ( target.data( "ui-tooltip-title" ) ) {
12553
			target.attr( "title", target.data( "ui-tooltip-title" ) );
12554
		}
12555
 
12556
		removeDescribedBy( target );
12557
 
12558
		tooltip.stop( true );
12559
		this._hide( tooltip, this.options.hide, function() {
12560
			that._removeTooltip( $( this ) );
12561
		});
12562
 
12563
		target.removeData( "ui-tooltip-open" );
12564
		this._off( target, "mouseleave focusout keyup" );
12565
		// Remove 'remove' binding only on delegated targets
12566
		if ( target[0] !== this.element[0] ) {
12567
			this._off( target, "remove" );
12568
		}
12569
		this._off( this.document, "mousemove" );
12570
 
12571
		if ( event && event.type === "mouseleave" ) {
12572
			$.each( this.parents, function( id, parent ) {
12573
				$( parent.element ).attr( "title", parent.title );
12574
				delete that.parents[ id ];
12575
			});
12576
		}
12577
 
12578
		this.closing = true;
12579
		this._trigger( "close", event, { tooltip: tooltip } );
12580
		this.closing = false;
12581
	},
12582
 
12583
	_tooltip: function( element ) {
12584
		var id = "ui-tooltip-" + increments++,
12585
			tooltip = $( "<div>" )
12586
				.attr({
12587
					id: id,
12588
					role: "tooltip"
12589
				})
12590
				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
12591
					( this.options.tooltipClass || "" ) );
12592
		$( "<div>" )
12593
			.addClass( "ui-tooltip-content" )
12594
			.appendTo( tooltip );
12595
		tooltip.appendTo( this.document[0].body );
12596
		if ( $.fn.bgiframe ) {
12597
			tooltip.bgiframe();
12598
		}
12599
		this.tooltips[ id ] = element;
12600
		return tooltip;
12601
	},
12602
 
12603
	_find: function( target ) {
12604
		var id = target.data( "ui-tooltip-id" );
12605
		return id ? $( "#" + id ) : $();
12606
	},
12607
 
12608
	_removeTooltip: function( tooltip ) {
12609
		tooltip.remove();
12610
		delete this.tooltips[ tooltip.attr( "id" ) ];
12611
	},
12612
 
12613
	_destroy: function() {
12614
		var that = this;
12615
 
12616
		// close open tooltips
12617
		$.each( this.tooltips, function( id, element ) {
12618
			// Delegate to close method to handle common cleanup
12619
			var event = $.Event( "blur" );
12620
			event.target = event.currentTarget = element[0];
12621
			that.close( event, true );
12622
 
12623
			// Remove immediately; destroying an open tooltip doesn't use the
12624
			// hide animation
12625
			$( "#" + id ).remove();
12626
 
12627
			// Restore the title
12628
			if ( element.data( "ui-tooltip-title" ) ) {
12629
				element.attr( "title", element.data( "ui-tooltip-title" ) );
12630
				element.removeData( "ui-tooltip-title" );
12631
			}
12632
		});
12633
	}
12634
});
12635
 
12636
}( jQuery ) );
12637
;(jQuery.effects || (function($, undefined) {
12638
 
12639
var backCompat = $.uiBackCompat !== false,
12640
	// prefix used for storing data on .data()
12641
	dataSpace = "ui-effects-";
12642
 
12643
$.effects = {
12644
	effect: {}
12645
};
12646
 
12647
/*!
12648
 * jQuery Color Animations v2.0.0
12649
 * http://jquery.com/
12650
 *
12651
 * Copyright 2012 jQuery Foundation and other contributors
12652
 * Released under the MIT license.
12653
 * http://jquery.org/license
12654
 *
12655
 * Date: Mon Aug 13 13:41:02 2012 -0500
12656
 */
12657
(function( jQuery, undefined ) {
12658
 
12659
	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
12660
 
12661
	// plusequals test for += 100 -= 100
12662
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
12663
	// a set of RE's that can match strings and generate color tuples.
12664
	stringParsers = [{
12665
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12666
			parse: function( execResult ) {
12667
				return [
12668
					execResult[ 1 ],
12669
					execResult[ 2 ],
12670
					execResult[ 3 ],
12671
					execResult[ 4 ]
12672
				];
12673
			}
12674
		}, {
12675
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12676
			parse: function( execResult ) {
12677
				return [
12678
					execResult[ 1 ] * 2.55,
12679
					execResult[ 2 ] * 2.55,
12680
					execResult[ 3 ] * 2.55,
12681
					execResult[ 4 ]
12682
				];
12683
			}
12684
		}, {
12685
			// this regex ignores A-F because it's compared against an already lowercased string
12686
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
12687
			parse: function( execResult ) {
12688
				return [
12689
					parseInt( execResult[ 1 ], 16 ),
12690
					parseInt( execResult[ 2 ], 16 ),
12691
					parseInt( execResult[ 3 ], 16 )
12692
				];
12693
			}
12694
		}, {
12695
			// this regex ignores A-F because it's compared against an already lowercased string
12696
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
12697
			parse: function( execResult ) {
12698
				return [
12699
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
12700
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
12701
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
12702
				];
12703
			}
12704
		}, {
12705
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
12706
			space: "hsla",
12707
			parse: function( execResult ) {
12708
				return [
12709
					execResult[ 1 ],
12710
					execResult[ 2 ] / 100,
12711
					execResult[ 3 ] / 100,
12712
					execResult[ 4 ]
12713
				];
12714
			}
12715
		}],
12716
 
12717
	// jQuery.Color( )
12718
	color = jQuery.Color = function( color, green, blue, alpha ) {
12719
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
12720
	},
12721
	spaces = {
12722
		rgba: {
12723
			props: {
12724
				red: {
12725
					idx: 0,
12726
					type: "byte"
12727
				},
12728
				green: {
12729
					idx: 1,
12730
					type: "byte"
12731
				},
12732
				blue: {
12733
					idx: 2,
12734
					type: "byte"
12735
				}
12736
			}
12737
		},
12738
 
12739
		hsla: {
12740
			props: {
12741
				hue: {
12742
					idx: 0,
12743
					type: "degrees"
12744
				},
12745
				saturation: {
12746
					idx: 1,
12747
					type: "percent"
12748
				},
12749
				lightness: {
12750
					idx: 2,
12751
					type: "percent"
12752
				}
12753
			}
12754
		}
12755
	},
12756
	propTypes = {
12757
		"byte": {
12758
			floor: true,
12759
			max: 255
12760
		},
12761
		"percent": {
12762
			max: 1
12763
		},
12764
		"degrees": {
12765
			mod: 360,
12766
			floor: true
12767
		}
12768
	},
12769
	support = color.support = {},
12770
 
12771
	// element for support tests
12772
	supportElem = jQuery( "<p>" )[ 0 ],
12773
 
12774
	// colors = jQuery.Color.names
12775
	colors,
12776
 
12777
	// local aliases of functions called often
12778
	each = jQuery.each;
12779
 
12780
// determine rgba support immediately
12781
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
12782
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
12783
 
12784
// define cache name and alpha properties
12785
// for rgba and hsla spaces
12786
each( spaces, function( spaceName, space ) {
12787
	space.cache = "_" + spaceName;
12788
	space.props.alpha = {
12789
		idx: 3,
12790
		type: "percent",
12791
		def: 1
12792
	};
12793
});
12794
 
12795
function clamp( value, prop, allowEmpty ) {
12796
	var type = propTypes[ prop.type ] || {};
12797
 
12798
	if ( value == null ) {
12799
		return (allowEmpty || !prop.def) ? null : prop.def;
12800
	}
12801
 
12802
	// ~~ is an short way of doing floor for positive numbers
12803
	value = type.floor ? ~~value : parseFloat( value );
12804
 
12805
	// IE will pass in empty strings as value for alpha,
12806
	// which will hit this case
12807
	if ( isNaN( value ) ) {
12808
		return prop.def;
12809
	}
12810
 
12811
	if ( type.mod ) {
12812
		// we add mod before modding to make sure that negatives values
12813
		// get converted properly: -10 -> 350
12814
		return (value + type.mod) % type.mod;
12815
	}
12816
 
12817
	// for now all property types without mod have min and max
12818
	return 0 > value ? 0 : type.max < value ? type.max : value;
12819
}
12820
 
12821
function stringParse( string ) {
12822
	var inst = color(),
12823
		rgba = inst._rgba = [];
12824
 
12825
	string = string.toLowerCase();
12826
 
12827
	each( stringParsers, function( i, parser ) {
12828
		var parsed,
12829
			match = parser.re.exec( string ),
12830
			values = match && parser.parse( match ),
12831
			spaceName = parser.space || "rgba";
12832
 
12833
		if ( values ) {
12834
			parsed = inst[ spaceName ]( values );
12835
 
12836
			// if this was an rgba parse the assignment might happen twice
12837
			// oh well....
12838
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
12839
			rgba = inst._rgba = parsed._rgba;
12840
 
12841
			// exit each( stringParsers ) here because we matched
12842
			return false;
12843
		}
12844
	});
12845
 
12846
	// Found a stringParser that handled it
12847
	if ( rgba.length ) {
12848
 
12849
		// if this came from a parsed string, force "transparent" when alpha is 0
12850
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
12851
		if ( rgba.join() === "0,0,0,0" ) {
12852
			jQuery.extend( rgba, colors.transparent );
12853
		}
12854
		return inst;
12855
	}
12856
 
12857
	// named colors
12858
	return colors[ string ];
12859
}
12860
 
12861
color.fn = jQuery.extend( color.prototype, {
12862
	parse: function( red, green, blue, alpha ) {
12863
		if ( red === undefined ) {
12864
			this._rgba = [ null, null, null, null ];
12865
			return this;
12866
		}
12867
		if ( red.jquery || red.nodeType ) {
12868
			red = jQuery( red ).css( green );
12869
			green = undefined;
12870
		}
12871
 
12872
		var inst = this,
12873
			type = jQuery.type( red ),
12874
			rgba = this._rgba = [];
12875
 
12876
		// more than 1 argument specified - assume ( red, green, blue, alpha )
12877
		if ( green !== undefined ) {
12878
			red = [ red, green, blue, alpha ];
12879
			type = "array";
12880
		}
12881
 
12882
		if ( type === "string" ) {
12883
			return this.parse( stringParse( red ) || colors._default );
12884
		}
12885
 
12886
		if ( type === "array" ) {
12887
			each( spaces.rgba.props, function( key, prop ) {
12888
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
12889
			});
12890
			return this;
12891
		}
12892
 
12893
		if ( type === "object" ) {
12894
			if ( red instanceof color ) {
12895
				each( spaces, function( spaceName, space ) {
12896
					if ( red[ space.cache ] ) {
12897
						inst[ space.cache ] = red[ space.cache ].slice();
12898
					}
12899
				});
12900
			} else {
12901
				each( spaces, function( spaceName, space ) {
12902
					var cache = space.cache;
12903
					each( space.props, function( key, prop ) {
12904
 
12905
						// if the cache doesn't exist, and we know how to convert
12906
						if ( !inst[ cache ] && space.to ) {
12907
 
12908
							// if the value was null, we don't need to copy it
12909
							// if the key was alpha, we don't need to copy it either
12910
							if ( key === "alpha" || red[ key ] == null ) {
12911
								return;
12912
							}
12913
							inst[ cache ] = space.to( inst._rgba );
12914
						}
12915
 
12916
						// this is the only case where we allow nulls for ALL properties.
12917
						// call clamp with alwaysAllowEmpty
12918
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
12919
					});
12920
 
12921
					// everything defined but alpha?
12922
					if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
12923
						// use the default of 1
12924
						inst[ cache ][ 3 ] = 1;
12925
						if ( space.from ) {
12926
							inst._rgba = space.from( inst[ cache ] );
12927
						}
12928
					}
12929
				});
12930
			}
12931
			return this;
12932
		}
12933
	},
12934
	is: function( compare ) {
12935
		var is = color( compare ),
12936
			same = true,
12937
			inst = this;
12938
 
12939
		each( spaces, function( _, space ) {
12940
			var localCache,
12941
				isCache = is[ space.cache ];
12942
			if (isCache) {
12943
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
12944
				each( space.props, function( _, prop ) {
12945
					if ( isCache[ prop.idx ] != null ) {
12946
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
12947
						return same;
12948
					}
12949
				});
12950
			}
12951
			return same;
12952
		});
12953
		return same;
12954
	},
12955
	_space: function() {
12956
		var used = [],
12957
			inst = this;
12958
		each( spaces, function( spaceName, space ) {
12959
			if ( inst[ space.cache ] ) {
12960
				used.push( spaceName );
12961
			}
12962
		});
12963
		return used.pop();
12964
	},
12965
	transition: function( other, distance ) {
12966
		var end = color( other ),
12967
			spaceName = end._space(),
12968
			space = spaces[ spaceName ],
12969
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
12970
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
12971
			result = start.slice();
12972
 
12973
		end = end[ space.cache ];
12974
		each( space.props, function( key, prop ) {
12975
			var index = prop.idx,
12976
				startValue = start[ index ],
12977
				endValue = end[ index ],
12978
				type = propTypes[ prop.type ] || {};
12979
 
12980
			// if null, don't override start value
12981
			if ( endValue === null ) {
12982
				return;
12983
			}
12984
			// if null - use end
12985
			if ( startValue === null ) {
12986
				result[ index ] = endValue;
12987
			} else {
12988
				if ( type.mod ) {
12989
					if ( endValue - startValue > type.mod / 2 ) {
12990
						startValue += type.mod;
12991
					} else if ( startValue - endValue > type.mod / 2 ) {
12992
						startValue -= type.mod;
12993
					}
12994
				}
12995
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
12996
			}
12997
		});
12998
		return this[ spaceName ]( result );
12999
	},
13000
	blend: function( opaque ) {
13001
		// if we are already opaque - return ourself
13002
		if ( this._rgba[ 3 ] === 1 ) {
13003
			return this;
13004
		}
13005
 
13006
		var rgb = this._rgba.slice(),
13007
			a = rgb.pop(),
13008
			blend = color( opaque )._rgba;
13009
 
13010
		return color( jQuery.map( rgb, function( v, i ) {
13011
			return ( 1 - a ) * blend[ i ] + a * v;
13012
		}));
13013
	},
13014
	toRgbaString: function() {
13015
		var prefix = "rgba(",
13016
			rgba = jQuery.map( this._rgba, function( v, i ) {
13017
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
13018
			});
13019
 
13020
		if ( rgba[ 3 ] === 1 ) {
13021
			rgba.pop();
13022
			prefix = "rgb(";
13023
		}
13024
 
13025
		return prefix + rgba.join() + ")";
13026
	},
13027
	toHslaString: function() {
13028
		var prefix = "hsla(",
13029
			hsla = jQuery.map( this.hsla(), function( v, i ) {
13030
				if ( v == null ) {
13031
					v = i > 2 ? 1 : 0;
13032
				}
13033
 
13034
				// catch 1 and 2
13035
				if ( i && i < 3 ) {
13036
					v = Math.round( v * 100 ) + "%";
13037
				}
13038
				return v;
13039
			});
13040
 
13041
		if ( hsla[ 3 ] === 1 ) {
13042
			hsla.pop();
13043
			prefix = "hsl(";
13044
		}
13045
		return prefix + hsla.join() + ")";
13046
	},
13047
	toHexString: function( includeAlpha ) {
13048
		var rgba = this._rgba.slice(),
13049
			alpha = rgba.pop();
13050
 
13051
		if ( includeAlpha ) {
13052
			rgba.push( ~~( alpha * 255 ) );
13053
		}
13054
 
13055
		return "#" + jQuery.map( rgba, function( v ) {
13056
 
13057
			// default to 0 when nulls exist
13058
			v = ( v || 0 ).toString( 16 );
13059
			return v.length === 1 ? "0" + v : v;
13060
		}).join("");
13061
	},
13062
	toString: function() {
13063
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
13064
	}
13065
});
13066
color.fn.parse.prototype = color.fn;
13067
 
13068
// hsla conversions adapted from:
13069
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
13070
 
13071
function hue2rgb( p, q, h ) {
13072
	h = ( h + 1 ) % 1;
13073
	if ( h * 6 < 1 ) {
13074
		return p + (q - p) * h * 6;
13075
	}
13076
	if ( h * 2 < 1) {
13077
		return q;
13078
	}
13079
	if ( h * 3 < 2 ) {
13080
		return p + (q - p) * ((2/3) - h) * 6;
13081
	}
13082
	return p;
13083
}
13084
 
13085
spaces.hsla.to = function ( rgba ) {
13086
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
13087
		return [ null, null, null, rgba[ 3 ] ];
13088
	}
13089
	var r = rgba[ 0 ] / 255,
13090
		g = rgba[ 1 ] / 255,
13091
		b = rgba[ 2 ] / 255,
13092
		a = rgba[ 3 ],
13093
		max = Math.max( r, g, b ),
13094
		min = Math.min( r, g, b ),
13095
		diff = max - min,
13096
		add = max + min,
13097
		l = add * 0.5,
13098
		h, s;
13099
 
13100
	if ( min === max ) {
13101
		h = 0;
13102
	} else if ( r === max ) {
13103
		h = ( 60 * ( g - b ) / diff ) + 360;
13104
	} else if ( g === max ) {
13105
		h = ( 60 * ( b - r ) / diff ) + 120;
13106
	} else {
13107
		h = ( 60 * ( r - g ) / diff ) + 240;
13108
	}
13109
 
13110
	if ( l === 0 || l === 1 ) {
13111
		s = l;
13112
	} else if ( l <= 0.5 ) {
13113
		s = diff / add;
13114
	} else {
13115
		s = diff / ( 2 - add );
13116
	}
13117
	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
13118
};
13119
 
13120
spaces.hsla.from = function ( hsla ) {
13121
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
13122
		return [ null, null, null, hsla[ 3 ] ];
13123
	}
13124
	var h = hsla[ 0 ] / 360,
13125
		s = hsla[ 1 ],
13126
		l = hsla[ 2 ],
13127
		a = hsla[ 3 ],
13128
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
13129
		p = 2 * l - q;
13130
 
13131
	return [
13132
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
13133
		Math.round( hue2rgb( p, q, h ) * 255 ),
13134
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
13135
		a
13136
	];
13137
};
13138
 
13139
 
13140
each( spaces, function( spaceName, space ) {
13141
	var props = space.props,
13142
		cache = space.cache,
13143
		to = space.to,
13144
		from = space.from;
13145
 
13146
	// makes rgba() and hsla()
13147
	color.fn[ spaceName ] = function( value ) {
13148
 
13149
		// generate a cache for this space if it doesn't exist
13150
		if ( to && !this[ cache ] ) {
13151
			this[ cache ] = to( this._rgba );
13152
		}
13153
		if ( value === undefined ) {
13154
			return this[ cache ].slice();
13155
		}
13156
 
13157
		var ret,
13158
			type = jQuery.type( value ),
13159
			arr = ( type === "array" || type === "object" ) ? value : arguments,
13160
			local = this[ cache ].slice();
13161
 
13162
		each( props, function( key, prop ) {
13163
			var val = arr[ type === "object" ? key : prop.idx ];
13164
			if ( val == null ) {
13165
				val = local[ prop.idx ];
13166
			}
13167
			local[ prop.idx ] = clamp( val, prop );
13168
		});
13169
 
13170
		if ( from ) {
13171
			ret = color( from( local ) );
13172
			ret[ cache ] = local;
13173
			return ret;
13174
		} else {
13175
			return color( local );
13176
		}
13177
	};
13178
 
13179
	// makes red() green() blue() alpha() hue() saturation() lightness()
13180
	each( props, function( key, prop ) {
13181
		// alpha is included in more than one space
13182
		if ( color.fn[ key ] ) {
13183
			return;
13184
		}
13185
		color.fn[ key ] = function( value ) {
13186
			var vtype = jQuery.type( value ),
13187
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
13188
				local = this[ fn ](),
13189
				cur = local[ prop.idx ],
13190
				match;
13191
 
13192
			if ( vtype === "undefined" ) {
13193
				return cur;
13194
			}
13195
 
13196
			if ( vtype === "function" ) {
13197
				value = value.call( this, cur );
13198
				vtype = jQuery.type( value );
13199
			}
13200
			if ( value == null && prop.empty ) {
13201
				return this;
13202
			}
13203
			if ( vtype === "string" ) {
13204
				match = rplusequals.exec( value );
13205
				if ( match ) {
13206
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
13207
				}
13208
			}
13209
			local[ prop.idx ] = value;
13210
			return this[ fn ]( local );
13211
		};
13212
	});
13213
});
13214
 
13215
// add .fx.step functions
13216
each( stepHooks, function( i, hook ) {
13217
	jQuery.cssHooks[ hook ] = {
13218
		set: function( elem, value ) {
13219
			var parsed, curElem,
13220
				backgroundColor = "";
13221
 
13222
			if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
13223
				value = color( parsed || value );
13224
				if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
13225
					curElem = hook === "backgroundColor" ? elem.parentNode : elem;
13226
					while (
13227
						(backgroundColor === "" || backgroundColor === "transparent") &&
13228
						curElem && curElem.style
13229
					) {
13230
						try {
13231
							backgroundColor = jQuery.css( curElem, "backgroundColor" );
13232
							curElem = curElem.parentNode;
13233
						} catch ( e ) {
13234
						}
13235
					}
13236
 
13237
					value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
13238
						backgroundColor :
13239
						"_default" );
13240
				}
13241
 
13242
				value = value.toRgbaString();
13243
			}
13244
			try {
13245
				elem.style[ hook ] = value;
13246
			} catch( error ) {
13247
				// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
13248
			}
13249
		}
13250
	};
13251
	jQuery.fx.step[ hook ] = function( fx ) {
13252
		if ( !fx.colorInit ) {
13253
			fx.start = color( fx.elem, hook );
13254
			fx.end = color( fx.end );
13255
			fx.colorInit = true;
13256
		}
13257
		jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
13258
	};
13259
});
13260
 
13261
jQuery.cssHooks.borderColor = {
13262
	expand: function( value ) {
13263
		var expanded = {};
13264
 
13265
		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
13266
			expanded[ "border" + part + "Color" ] = value;
13267
		});
13268
		return expanded;
13269
	}
13270
};
13271
 
13272
// Basic color names only.
13273
// Usage of any of the other color names requires adding yourself or including
13274
// jquery.color.svg-names.js.
13275
colors = jQuery.Color.names = {
13276
	// 4.1. Basic color keywords
13277
	aqua: "#00ffff",
13278
	black: "#000000",
13279
	blue: "#0000ff",
13280
	fuchsia: "#ff00ff",
13281
	gray: "#808080",
13282
	green: "#008000",
13283
	lime: "#00ff00",
13284
	maroon: "#800000",
13285
	navy: "#000080",
13286
	olive: "#808000",
13287
	purple: "#800080",
13288
	red: "#ff0000",
13289
	silver: "#c0c0c0",
13290
	teal: "#008080",
13291
	white: "#ffffff",
13292
	yellow: "#ffff00",
13293
 
13294
	// 4.2.3. "transparent" color keyword
13295
	transparent: [ null, null, null, 0 ],
13296
 
13297
	_default: "#ffffff"
13298
};
13299
 
13300
})( jQuery );
13301
 
13302
 
13303
 
13304
/******************************************************************************/
13305
/****************************** CLASS ANIMATIONS ******************************/
13306
/******************************************************************************/
13307
(function() {
13308
 
13309
var classAnimationActions = [ "add", "remove", "toggle" ],
13310
	shorthandStyles = {
13311
		border: 1,
13312
		borderBottom: 1,
13313
		borderColor: 1,
13314
		borderLeft: 1,
13315
		borderRight: 1,
13316
		borderTop: 1,
13317
		borderWidth: 1,
13318
		margin: 1,
13319
		padding: 1
13320
	};
13321
 
13322
$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
13323
	$.fx.step[ prop ] = function( fx ) {
13324
		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
13325
			jQuery.style( fx.elem, prop, fx.end );
13326
			fx.setAttr = true;
13327
		}
13328
	};
13329
});
13330
 
13331
function getElementStyles() {
13332
	var style = this.ownerDocument.defaultView ?
13333
			this.ownerDocument.defaultView.getComputedStyle( this, null ) :
13334
			this.currentStyle,
13335
		newStyle = {},
13336
		key,
13337
		len;
13338
 
13339
	// webkit enumerates style porperties
13340
	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
13341
		len = style.length;
13342
		while ( len-- ) {
13343
			key = style[ len ];
13344
			if ( typeof style[ key ] === "string" ) {
13345
				newStyle[ $.camelCase( key ) ] = style[ key ];
13346
			}
13347
		}
13348
	} else {
13349
		for ( key in style ) {
13350
			if ( typeof style[ key ] === "string" ) {
13351
				newStyle[ key ] = style[ key ];
13352
			}
13353
		}
13354
	}
13355
 
13356
	return newStyle;
13357
}
13358
 
13359
 
13360
function styleDifference( oldStyle, newStyle ) {
13361
	var diff = {},
13362
		name, value;
13363
 
13364
	for ( name in newStyle ) {
13365
		value = newStyle[ name ];
13366
		if ( oldStyle[ name ] !== value ) {
13367
			if ( !shorthandStyles[ name ] ) {
13368
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
13369
					diff[ name ] = value;
13370
				}
13371
			}
13372
		}
13373
	}
13374
 
13375
	return diff;
13376
}
13377
 
13378
$.effects.animateClass = function( value, duration, easing, callback ) {
13379
	var o = $.speed( duration, easing, callback );
13380
 
13381
	return this.queue( function() {
13382
		var animated = $( this ),
13383
			baseClass = animated.attr( "class" ) || "",
13384
			applyClassChange,
13385
			allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
13386
 
13387
		// map the animated objects to store the original styles.
13388
		allAnimations = allAnimations.map(function() {
13389
			var el = $( this );
13390
			return {
13391
				el: el,
13392
				start: getElementStyles.call( this )
13393
			};
13394
		});
13395
 
13396
		// apply class change
13397
		applyClassChange = function() {
13398
			$.each( classAnimationActions, function(i, action) {
13399
				if ( value[ action ] ) {
13400
					animated[ action + "Class" ]( value[ action ] );
13401
				}
13402
			});
13403
		};
13404
		applyClassChange();
13405
 
13406
		// map all animated objects again - calculate new styles and diff
13407
		allAnimations = allAnimations.map(function() {
13408
			this.end = getElementStyles.call( this.el[ 0 ] );
13409
			this.diff = styleDifference( this.start, this.end );
13410
			return this;
13411
		});
13412
 
13413
		// apply original class
13414
		animated.attr( "class", baseClass );
13415
 
13416
		// map all animated objects again - this time collecting a promise
13417
		allAnimations = allAnimations.map(function() {
13418
			var styleInfo = this,
13419
				dfd = $.Deferred(),
13420
				opts = jQuery.extend({}, o, {
13421
					queue: false,
13422
					complete: function() {
13423
						dfd.resolve( styleInfo );
13424
					}
13425
				});
13426
 
13427
			this.el.animate( this.diff, opts );
13428
			return dfd.promise();
13429
		});
13430
 
13431
		// once all animations have completed:
13432
		$.when.apply( $, allAnimations.get() ).done(function() {
13433
 
13434
			// set the final class
13435
			applyClassChange();
13436
 
13437
			// for each animated element,
13438
			// clear all css properties that were animated
13439
			$.each( arguments, function() {
13440
				var el = this.el;
13441
				$.each( this.diff, function(key) {
13442
					el.css( key, '' );
13443
				});
13444
			});
13445
 
13446
			// this is guarnteed to be there if you use jQuery.speed()
13447
			// it also handles dequeuing the next anim...
13448
			o.complete.call( animated[ 0 ] );
13449
		});
13450
	});
13451
};
13452
 
13453
$.fn.extend({
13454
	_addClass: $.fn.addClass,
13455
	addClass: function( classNames, speed, easing, callback ) {
13456
		return speed ?
13457
			$.effects.animateClass.call( this,
13458
				{ add: classNames }, speed, easing, callback ) :
13459
			this._addClass( classNames );
13460
	},
13461
 
13462
	_removeClass: $.fn.removeClass,
13463
	removeClass: function( classNames, speed, easing, callback ) {
13464
		return speed ?
13465
			$.effects.animateClass.call( this,
13466
				{ remove: classNames }, speed, easing, callback ) :
13467
			this._removeClass( classNames );
13468
	},
13469
 
13470
	_toggleClass: $.fn.toggleClass,
13471
	toggleClass: function( classNames, force, speed, easing, callback ) {
13472
		if ( typeof force === "boolean" || force === undefined ) {
13473
			if ( !speed ) {
13474
				// without speed parameter
13475
				return this._toggleClass( classNames, force );
13476
			} else {
13477
				return $.effects.animateClass.call( this,
13478
					(force ? { add: classNames } : { remove: classNames }),
13479
					speed, easing, callback );
13480
			}
13481
		} else {
13482
			// without force parameter
13483
			return $.effects.animateClass.call( this,
13484
				{ toggle: classNames }, force, speed, easing );
13485
		}
13486
	},
13487
 
13488
	switchClass: function( remove, add, speed, easing, callback) {
13489
		return $.effects.animateClass.call( this, {
13490
			add: add,
13491
			remove: remove
13492
		}, speed, easing, callback );
13493
	}
13494
});
13495
 
13496
})();
13497
 
13498
/******************************************************************************/
13499
/*********************************** EFFECTS **********************************/
13500
/******************************************************************************/
13501
 
13502
(function() {
13503
 
13504
$.extend( $.effects, {
13505
	version: "1.9.2",
13506
 
13507
	// Saves a set of properties in a data storage
13508
	save: function( element, set ) {
13509
		for( var i=0; i < set.length; i++ ) {
13510
			if ( set[ i ] !== null ) {
13511
				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
13512
			}
13513
		}
13514
	},
13515
 
13516
	// Restores a set of previously saved properties from a data storage
13517
	restore: function( element, set ) {
13518
		var val, i;
13519
		for( i=0; i < set.length; i++ ) {
13520
			if ( set[ i ] !== null ) {
13521
				val = element.data( dataSpace + set[ i ] );
13522
				// support: jQuery 1.6.2
13523
				// http://bugs.jquery.com/ticket/9917
13524
				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
13525
				// We can't differentiate between "" and 0 here, so we just assume
13526
				// empty string since it's likely to be a more common value...
13527
				if ( val === undefined ) {
13528
					val = "";
13529
				}
13530
				element.css( set[ i ], val );
13531
			}
13532
		}
13533
	},
13534
 
13535
	setMode: function( el, mode ) {
13536
		if (mode === "toggle") {
13537
			mode = el.is( ":hidden" ) ? "show" : "hide";
13538
		}
13539
		return mode;
13540
	},
13541
 
13542
	// Translates a [top,left] array into a baseline value
13543
	// this should be a little more flexible in the future to handle a string & hash
13544
	getBaseline: function( origin, original ) {
13545
		var y, x;
13546
		switch ( origin[ 0 ] ) {
13547
			case "top": y = 0; break;
13548
			case "middle": y = 0.5; break;
13549
			case "bottom": y = 1; break;
13550
			default: y = origin[ 0 ] / original.height;
13551
		}
13552
		switch ( origin[ 1 ] ) {
13553
			case "left": x = 0; break;
13554
			case "center": x = 0.5; break;
13555
			case "right": x = 1; break;
13556
			default: x = origin[ 1 ] / original.width;
13557
		}
13558
		return {
13559
			x: x,
13560
			y: y
13561
		};
13562
	},
13563
 
13564
	// Wraps the element around a wrapper that copies position properties
13565
	createWrapper: function( element ) {
13566
 
13567
		// if the element is already wrapped, return it
13568
		if ( element.parent().is( ".ui-effects-wrapper" )) {
13569
			return element.parent();
13570
		}
13571
 
13572
		// wrap the element
13573
		var props = {
13574
				width: element.outerWidth(true),
13575
				height: element.outerHeight(true),
13576
				"float": element.css( "float" )
13577
			},
13578
			wrapper = $( "<div></div>" )
13579
				.addClass( "ui-effects-wrapper" )
13580
				.css({
13581
					fontSize: "100%",
13582
					background: "transparent",
13583
					border: "none",
13584
					margin: 0,
13585
					padding: 0
13586
				}),
13587
			// Store the size in case width/height are defined in % - Fixes #5245
13588
			size = {
13589
				width: element.width(),
13590
				height: element.height()
13591
			},
13592
			active = document.activeElement;
13593
 
13594
		// support: Firefox
13595
		// Firefox incorrectly exposes anonymous content
13596
		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
13597
		try {
13598
			active.id;
13599
		} catch( e ) {
13600
			active = document.body;
13601
		}
13602
 
13603
		element.wrap( wrapper );
13604
 
13605
		// Fixes #7595 - Elements lose focus when wrapped.
13606
		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13607
			$( active ).focus();
13608
		}
13609
 
13610
		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
13611
 
13612
		// transfer positioning properties to the wrapper
13613
		if ( element.css( "position" ) === "static" ) {
13614
			wrapper.css({ position: "relative" });
13615
			element.css({ position: "relative" });
13616
		} else {
13617
			$.extend( props, {
13618
				position: element.css( "position" ),
13619
				zIndex: element.css( "z-index" )
13620
			});
13621
			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
13622
				props[ pos ] = element.css( pos );
13623
				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
13624
					props[ pos ] = "auto";
13625
				}
13626
			});
13627
			element.css({
13628
				position: "relative",
13629
				top: 0,
13630
				left: 0,
13631
				right: "auto",
13632
				bottom: "auto"
13633
			});
13634
		}
13635
		element.css(size);
13636
 
13637
		return wrapper.css( props ).show();
13638
	},
13639
 
13640
	removeWrapper: function( element ) {
13641
		var active = document.activeElement;
13642
 
13643
		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
13644
			element.parent().replaceWith( element );
13645
 
13646
			// Fixes #7595 - Elements lose focus when wrapped.
13647
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13648
				$( active ).focus();
13649
			}
13650
		}
13651
 
13652
 
13653
		return element;
13654
	},
13655
 
13656
	setTransition: function( element, list, factor, value ) {
13657
		value = value || {};
13658
		$.each( list, function( i, x ) {
13659
			var unit = element.cssUnit( x );
13660
			if ( unit[ 0 ] > 0 ) {
13661
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
13662
			}
13663
		});
13664
		return value;
13665
	}
13666
});
13667
 
13668
// return an effect options object for the given parameters:
13669
function _normalizeArguments( effect, options, speed, callback ) {
13670
 
13671
	// allow passing all options as the first parameter
13672
	if ( $.isPlainObject( effect ) ) {
13673
		options = effect;
13674
		effect = effect.effect;
13675
	}
13676
 
13677
	// convert to an object
13678
	effect = { effect: effect };
13679
 
13680
	// catch (effect, null, ...)
13681
	if ( options == null ) {
13682
		options = {};
13683
	}
13684
 
13685
	// catch (effect, callback)
13686
	if ( $.isFunction( options ) ) {
13687
		callback = options;
13688
		speed = null;
13689
		options = {};
13690
	}
13691
 
13692
	// catch (effect, speed, ?)
13693
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13694
		callback = speed;
13695
		speed = options;
13696
		options = {};
13697
	}
13698
 
13699
	// catch (effect, options, callback)
13700
	if ( $.isFunction( speed ) ) {
13701
		callback = speed;
13702
		speed = null;
13703
	}
13704
 
13705
	// add options to effect
13706
	if ( options ) {
13707
		$.extend( effect, options );
13708
	}
13709
 
13710
	speed = speed || options.duration;
13711
	effect.duration = $.fx.off ? 0 :
13712
		typeof speed === "number" ? speed :
13713
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13714
		$.fx.speeds._default;
13715
 
13716
	effect.complete = callback || options.complete;
13717
 
13718
	return effect;
13719
}
13720
 
13721
function standardSpeed( speed ) {
13722
	// valid standard speeds
13723
	if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
13724
		return true;
13725
	}
13726
 
13727
	// invalid strings - treat as "normal" speed
13728
	if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
13729
		// TODO: remove in 2.0 (#7115)
13730
		if ( backCompat && $.effects[ speed ] ) {
13731
			return false;
13732
		}
13733
		return true;
13734
	}
13735
 
13736
	return false;
13737
}
13738
 
13739
$.fn.extend({
13740
	effect: function( /* effect, options, speed, callback */ ) {
13741
		var args = _normalizeArguments.apply( this, arguments ),
13742
			mode = args.mode,
13743
			queue = args.queue,
13744
			effectMethod = $.effects.effect[ args.effect ],
13745
 
13746
			// DEPRECATED: remove in 2.0 (#7115)
13747
			oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
13748
 
13749
		if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
13750
			// delegate to the original method (e.g., .show()) if possible
13751
			if ( mode ) {
13752
				return this[ mode ]( args.duration, args.complete );
13753
			} else {
13754
				return this.each( function() {
13755
					if ( args.complete ) {
13756
						args.complete.call( this );
13757
					}
13758
				});
13759
			}
13760
		}
13761
 
13762
		function run( next ) {
13763
			var elem = $( this ),
13764
				complete = args.complete,
13765
				mode = args.mode;
13766
 
13767
			function done() {
13768
				if ( $.isFunction( complete ) ) {
13769
					complete.call( elem[0] );
13770
				}
13771
				if ( $.isFunction( next ) ) {
13772
					next();
13773
				}
13774
			}
13775
 
13776
			// if the element is hiddden and mode is hide,
13777
			// or element is visible and mode is show
13778
			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13779
				done();
13780
			} else {
13781
				effectMethod.call( elem[0], args, done );
13782
			}
13783
		}
13784
 
13785
		// TODO: remove this check in 2.0, effectMethod will always be true
13786
		if ( effectMethod ) {
13787
			return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
13788
		} else {
13789
			// DEPRECATED: remove in 2.0 (#7115)
13790
			return oldEffectMethod.call(this, {
13791
				options: args,
13792
				duration: args.duration,
13793
				callback: args.complete,
13794
				mode: args.mode
13795
			});
13796
		}
13797
	},
13798
 
13799
	_show: $.fn.show,
13800
	show: function( speed ) {
13801
		if ( standardSpeed( speed ) ) {
13802
			return this._show.apply( this, arguments );
13803
		} else {
13804
			var args = _normalizeArguments.apply( this, arguments );
13805
			args.mode = "show";
13806
			return this.effect.call( this, args );
13807
		}
13808
	},
13809
 
13810
	_hide: $.fn.hide,
13811
	hide: function( speed ) {
13812
		if ( standardSpeed( speed ) ) {
13813
			return this._hide.apply( this, arguments );
13814
		} else {
13815
			var args = _normalizeArguments.apply( this, arguments );
13816
			args.mode = "hide";
13817
			return this.effect.call( this, args );
13818
		}
13819
	},
13820
 
13821
	// jQuery core overloads toggle and creates _toggle
13822
	__toggle: $.fn.toggle,
13823
	toggle: function( speed ) {
13824
		if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
13825
			return this.__toggle.apply( this, arguments );
13826
		} else {
13827
			var args = _normalizeArguments.apply( this, arguments );
13828
			args.mode = "toggle";
13829
			return this.effect.call( this, args );
13830
		}
13831
	},
13832
 
13833
	// helper functions
13834
	cssUnit: function(key) {
13835
		var style = this.css( key ),
13836
			val = [];
13837
 
13838
		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13839
			if ( style.indexOf( unit ) > 0 ) {
13840
				val = [ parseFloat( style ), unit ];
13841
			}
13842
		});
13843
		return val;
13844
	}
13845
});
13846
 
13847
})();
13848
 
13849
/******************************************************************************/
13850
/*********************************** EASING ***********************************/
13851
/******************************************************************************/
13852
 
13853
(function() {
13854
 
13855
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
13856
 
13857
var baseEasings = {};
13858
 
13859
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13860
	baseEasings[ name ] = function( p ) {
13861
		return Math.pow( p, i + 2 );
13862
	};
13863
});
13864
 
13865
$.extend( baseEasings, {
13866
	Sine: function ( p ) {
13867
		return 1 - Math.cos( p * Math.PI / 2 );
13868
	},
13869
	Circ: function ( p ) {
13870
		return 1 - Math.sqrt( 1 - p * p );
13871
	},
13872
	Elastic: function( p ) {
13873
		return p === 0 || p === 1 ? p :
13874
			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
13875
	},
13876
	Back: function( p ) {
13877
		return p * p * ( 3 * p - 2 );
13878
	},
13879
	Bounce: function ( p ) {
13880
		var pow2,
13881
			bounce = 4;
13882
 
13883
		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
13884
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
13885
	}
13886
});
13887
 
13888
$.each( baseEasings, function( name, easeIn ) {
13889
	$.easing[ "easeIn" + name ] = easeIn;
13890
	$.easing[ "easeOut" + name ] = function( p ) {
13891
		return 1 - easeIn( 1 - p );
13892
	};
13893
	$.easing[ "easeInOut" + name ] = function( p ) {
13894
		return p < 0.5 ?
13895
			easeIn( p * 2 ) / 2 :
13896
			1 - easeIn( p * -2 + 2 ) / 2;
13897
	};
13898
});
13899
 
13900
})();
13901
 
13902
})(jQuery));
13903
(function( $, undefined ) {
13904
 
13905
var rvertical = /up|down|vertical/,
13906
	rpositivemotion = /up|left|vertical|horizontal/;
13907
 
13908
$.effects.effect.blind = function( o, done ) {
13909
	// Create element
13910
	var el = $( this ),
13911
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13912
		mode = $.effects.setMode( el, o.mode || "hide" ),
13913
		direction = o.direction || "up",
13914
		vertical = rvertical.test( direction ),
13915
		ref = vertical ? "height" : "width",
13916
		ref2 = vertical ? "top" : "left",
13917
		motion = rpositivemotion.test( direction ),
13918
		animation = {},
13919
		show = mode === "show",
13920
		wrapper, distance, margin;
13921
 
13922
	// if already wrapped, the wrapper's properties are my property. #6245
13923
	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
13924
		$.effects.save( el.parent(), props );
13925
	} else {
13926
		$.effects.save( el, props );
13927
	}
13928
	el.show();
13929
	wrapper = $.effects.createWrapper( el ).css({
13930
		overflow: "hidden"
13931
	});
13932
 
13933
	distance = wrapper[ ref ]();
13934
	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
13935
 
13936
	animation[ ref ] = show ? distance : 0;
13937
	if ( !motion ) {
13938
		el
13939
			.css( vertical ? "bottom" : "right", 0 )
13940
			.css( vertical ? "top" : "left", "auto" )
13941
			.css({ position: "absolute" });
13942
 
13943
		animation[ ref2 ] = show ? margin : distance + margin;
13944
	}
13945
 
13946
	// start at 0 if we are showing
13947
	if ( show ) {
13948
		wrapper.css( ref, 0 );
13949
		if ( ! motion ) {
13950
			wrapper.css( ref2, margin + distance );
13951
		}
13952
	}
13953
 
13954
	// Animate
13955
	wrapper.animate( animation, {
13956
		duration: o.duration,
13957
		easing: o.easing,
13958
		queue: false,
13959
		complete: function() {
13960
			if ( mode === "hide" ) {
13961
				el.hide();
13962
			}
13963
			$.effects.restore( el, props );
13964
			$.effects.removeWrapper( el );
13965
			done();
13966
		}
13967
	});
13968
 
13969
};
13970
 
13971
})(jQuery);
13972
(function( $, undefined ) {
13973
 
13974
$.effects.effect.bounce = function( o, done ) {
13975
	var el = $( this ),
13976
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13977
 
13978
		// defaults:
13979
		mode = $.effects.setMode( el, o.mode || "effect" ),
13980
		hide = mode === "hide",
13981
		show = mode === "show",
13982
		direction = o.direction || "up",
13983
		distance = o.distance,
13984
		times = o.times || 5,
13985
 
13986
		// number of internal animations
13987
		anims = times * 2 + ( show || hide ? 1 : 0 ),
13988
		speed = o.duration / anims,
13989
		easing = o.easing,
13990
 
13991
		// utility:
13992
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
13993
		motion = ( direction === "up" || direction === "left" ),
13994
		i,
13995
		upAnim,
13996
		downAnim,
13997
 
13998
		// we will need to re-assemble the queue to stack our animations in place
13999
		queue = el.queue(),
14000
		queuelen = queue.length;
14001
 
14002
	// Avoid touching opacity to prevent clearType and PNG issues in IE
14003
	if ( show || hide ) {
14004
		props.push( "opacity" );
14005
	}
14006
 
14007
	$.effects.save( el, props );
14008
	el.show();
14009
	$.effects.createWrapper( el ); // Create Wrapper
14010
 
14011
	// default distance for the BIGGEST bounce is the outer Distance / 3
14012
	if ( !distance ) {
14013
		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
14014
	}
14015
 
14016
	if ( show ) {
14017
		downAnim = { opacity: 1 };
14018
		downAnim[ ref ] = 0;
14019
 
14020
		// if we are showing, force opacity 0 and set the initial position
14021
		// then do the "first" animation
14022
		el.css( "opacity", 0 )
14023
			.css( ref, motion ? -distance * 2 : distance * 2 )
14024
			.animate( downAnim, speed, easing );
14025
	}
14026
 
14027
	// start at the smallest distance if we are hiding
14028
	if ( hide ) {
14029
		distance = distance / Math.pow( 2, times - 1 );
14030
	}
14031
 
14032
	downAnim = {};
14033
	downAnim[ ref ] = 0;
14034
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
14035
	for ( i = 0; i < times; i++ ) {
14036
		upAnim = {};
14037
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14038
 
14039
		el.animate( upAnim, speed, easing )
14040
			.animate( downAnim, speed, easing );
14041
 
14042
		distance = hide ? distance * 2 : distance / 2;
14043
	}
14044
 
14045
	// Last Bounce when Hiding
14046
	if ( hide ) {
14047
		upAnim = { opacity: 0 };
14048
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14049
 
14050
		el.animate( upAnim, speed, easing );
14051
	}
14052
 
14053
	el.queue(function() {
14054
		if ( hide ) {
14055
			el.hide();
14056
		}
14057
		$.effects.restore( el, props );
14058
		$.effects.removeWrapper( el );
14059
		done();
14060
	});
14061
 
14062
	// inject all the animations we just queued to be first in line (after "inprogress")
14063
	if ( queuelen > 1) {
14064
		queue.splice.apply( queue,
14065
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14066
	}
14067
	el.dequeue();
14068
 
14069
};
14070
 
14071
})(jQuery);
14072
(function( $, undefined ) {
14073
 
14074
$.effects.effect.clip = function( o, done ) {
14075
	// Create element
14076
	var el = $( this ),
14077
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14078
		mode = $.effects.setMode( el, o.mode || "hide" ),
14079
		show = mode === "show",
14080
		direction = o.direction || "vertical",
14081
		vert = direction === "vertical",
14082
		size = vert ? "height" : "width",
14083
		position = vert ? "top" : "left",
14084
		animation = {},
14085
		wrapper, animate, distance;
14086
 
14087
	// Save & Show
14088
	$.effects.save( el, props );
14089
	el.show();
14090
 
14091
	// Create Wrapper
14092
	wrapper = $.effects.createWrapper( el ).css({
14093
		overflow: "hidden"
14094
	});
14095
	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
14096
	distance = animate[ size ]();
14097
 
14098
	// Shift
14099
	if ( show ) {
14100
		animate.css( size, 0 );
14101
		animate.css( position, distance / 2 );
14102
	}
14103
 
14104
	// Create Animation Object:
14105
	animation[ size ] = show ? distance : 0;
14106
	animation[ position ] = show ? 0 : distance / 2;
14107
 
14108
	// Animate
14109
	animate.animate( animation, {
14110
		queue: false,
14111
		duration: o.duration,
14112
		easing: o.easing,
14113
		complete: function() {
14114
			if ( !show ) {
14115
				el.hide();
14116
			}
14117
			$.effects.restore( el, props );
14118
			$.effects.removeWrapper( el );
14119
			done();
14120
		}
14121
	});
14122
 
14123
};
14124
 
14125
})(jQuery);
14126
(function( $, undefined ) {
14127
 
14128
$.effects.effect.drop = function( o, done ) {
14129
 
14130
	var el = $( this ),
14131
		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
14132
		mode = $.effects.setMode( el, o.mode || "hide" ),
14133
		show = mode === "show",
14134
		direction = o.direction || "left",
14135
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14136
		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
14137
		animation = {
14138
			opacity: show ? 1 : 0
14139
		},
14140
		distance;
14141
 
14142
	// Adjust
14143
	$.effects.save( el, props );
14144
	el.show();
14145
	$.effects.createWrapper( el );
14146
 
14147
	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
14148
 
14149
	if ( show ) {
14150
		el
14151
			.css( "opacity", 0 )
14152
			.css( ref, motion === "pos" ? -distance : distance );
14153
	}
14154
 
14155
	// Animation
14156
	animation[ ref ] = ( show ?
14157
		( motion === "pos" ? "+=" : "-=" ) :
14158
		( motion === "pos" ? "-=" : "+=" ) ) +
14159
		distance;
14160
 
14161
	// Animate
14162
	el.animate( animation, {
14163
		queue: false,
14164
		duration: o.duration,
14165
		easing: o.easing,
14166
		complete: function() {
14167
			if ( mode === "hide" ) {
14168
				el.hide();
14169
			}
14170
			$.effects.restore( el, props );
14171
			$.effects.removeWrapper( el );
14172
			done();
14173
		}
14174
	});
14175
};
14176
 
14177
})(jQuery);
14178
(function( $, undefined ) {
14179
 
14180
$.effects.effect.explode = function( o, done ) {
14181
 
14182
	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
14183
		cells = rows,
14184
		el = $( this ),
14185
		mode = $.effects.setMode( el, o.mode || "hide" ),
14186
		show = mode === "show",
14187
 
14188
		// show and then visibility:hidden the element before calculating offset
14189
		offset = el.show().css( "visibility", "hidden" ).offset(),
14190
 
14191
		// width and height of a piece
14192
		width = Math.ceil( el.outerWidth() / cells ),
14193
		height = Math.ceil( el.outerHeight() / rows ),
14194
		pieces = [],
14195
 
14196
		// loop
14197
		i, j, left, top, mx, my;
14198
 
14199
	// children animate complete:
14200
	function childComplete() {
14201
		pieces.push( this );
14202
		if ( pieces.length === rows * cells ) {
14203
			animComplete();
14204
		}
14205
	}
14206
 
14207
	// clone the element for each row and cell.
14208
	for( i = 0; i < rows ; i++ ) { // ===>
14209
		top = offset.top + i * height;
14210
		my = i - ( rows - 1 ) / 2 ;
14211
 
14212
		for( j = 0; j < cells ; j++ ) { // |||
14213
			left = offset.left + j * width;
14214
			mx = j - ( cells - 1 ) / 2 ;
14215
 
14216
			// Create a clone of the now hidden main element that will be absolute positioned
14217
			// within a wrapper div off the -left and -top equal to size of our pieces
14218
			el
14219
				.clone()
14220
				.appendTo( "body" )
14221
				.wrap( "<div></div>" )
14222
				.css({
14223
					position: "absolute",
14224
					visibility: "visible",
14225
					left: -j * width,
14226
					top: -i * height
14227
				})
14228
 
14229
			// select the wrapper - make it overflow: hidden and absolute positioned based on
14230
			// where the original was located +left and +top equal to the size of pieces
14231
				.parent()
14232
				.addClass( "ui-effects-explode" )
14233
				.css({
14234
					position: "absolute",
14235
					overflow: "hidden",
14236
					width: width,
14237
					height: height,
14238
					left: left + ( show ? mx * width : 0 ),
14239
					top: top + ( show ? my * height : 0 ),
14240
					opacity: show ? 0 : 1
14241
				}).animate({
14242
					left: left + ( show ? 0 : mx * width ),
14243
					top: top + ( show ? 0 : my * height ),
14244
					opacity: show ? 1 : 0
14245
				}, o.duration || 500, o.easing, childComplete );
14246
		}
14247
	}
14248
 
14249
	function animComplete() {
14250
		el.css({
14251
			visibility: "visible"
14252
		});
14253
		$( pieces ).remove();
14254
		if ( !show ) {
14255
			el.hide();
14256
		}
14257
		done();
14258
	}
14259
};
14260
 
14261
})(jQuery);
14262
(function( $, undefined ) {
14263
 
14264
$.effects.effect.fade = function( o, done ) {
14265
	var el = $( this ),
14266
		mode = $.effects.setMode( el, o.mode || "toggle" );
14267
 
14268
	el.animate({
14269
		opacity: mode
14270
	}, {
14271
		queue: false,
14272
		duration: o.duration,
14273
		easing: o.easing,
14274
		complete: done
14275
	});
14276
};
14277
 
14278
})( jQuery );
14279
(function( $, undefined ) {
14280
 
14281
$.effects.effect.fold = function( o, done ) {
14282
 
14283
	// Create element
14284
	var el = $( this ),
14285
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14286
		mode = $.effects.setMode( el, o.mode || "hide" ),
14287
		show = mode === "show",
14288
		hide = mode === "hide",
14289
		size = o.size || 15,
14290
		percent = /([0-9]+)%/.exec( size ),
14291
		horizFirst = !!o.horizFirst,
14292
		widthFirst = show !== horizFirst,
14293
		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
14294
		duration = o.duration / 2,
14295
		wrapper, distance,
14296
		animation1 = {},
14297
		animation2 = {};
14298
 
14299
	$.effects.save( el, props );
14300
	el.show();
14301
 
14302
	// Create Wrapper
14303
	wrapper = $.effects.createWrapper( el ).css({
14304
		overflow: "hidden"
14305
	});
14306
	distance = widthFirst ?
14307
		[ wrapper.width(), wrapper.height() ] :
14308
		[ wrapper.height(), wrapper.width() ];
14309
 
14310
	if ( percent ) {
14311
		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
14312
	}
14313
	if ( show ) {
14314
		wrapper.css( horizFirst ? {
14315
			height: 0,
14316
			width: size
14317
		} : {
14318
			height: size,
14319
			width: 0
14320
		});
14321
	}
14322
 
14323
	// Animation
14324
	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
14325
	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
14326
 
14327
	// Animate
14328
	wrapper
14329
		.animate( animation1, duration, o.easing )
14330
		.animate( animation2, duration, o.easing, function() {
14331
			if ( hide ) {
14332
				el.hide();
14333
			}
14334
			$.effects.restore( el, props );
14335
			$.effects.removeWrapper( el );
14336
			done();
14337
		});
14338
 
14339
};
14340
 
14341
})(jQuery);
14342
(function( $, undefined ) {
14343
 
14344
$.effects.effect.highlight = function( o, done ) {
14345
	var elem = $( this ),
14346
		props = [ "backgroundImage", "backgroundColor", "opacity" ],
14347
		mode = $.effects.setMode( elem, o.mode || "show" ),
14348
		animation = {
14349
			backgroundColor: elem.css( "backgroundColor" )
14350
		};
14351
 
14352
	if (mode === "hide") {
14353
		animation.opacity = 0;
14354
	}
14355
 
14356
	$.effects.save( elem, props );
14357
 
14358
	elem
14359
		.show()
14360
		.css({
14361
			backgroundImage: "none",
14362
			backgroundColor: o.color || "#ffff99"
14363
		})
14364
		.animate( animation, {
14365
			queue: false,
14366
			duration: o.duration,
14367
			easing: o.easing,
14368
			complete: function() {
14369
				if ( mode === "hide" ) {
14370
					elem.hide();
14371
				}
14372
				$.effects.restore( elem, props );
14373
				done();
14374
			}
14375
		});
14376
};
14377
 
14378
})(jQuery);
14379
(function( $, undefined ) {
14380
 
14381
$.effects.effect.pulsate = function( o, done ) {
14382
	var elem = $( this ),
14383
		mode = $.effects.setMode( elem, o.mode || "show" ),
14384
		show = mode === "show",
14385
		hide = mode === "hide",
14386
		showhide = ( show || mode === "hide" ),
14387
 
14388
		// showing or hiding leaves of the "last" animation
14389
		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
14390
		duration = o.duration / anims,
14391
		animateTo = 0,
14392
		queue = elem.queue(),
14393
		queuelen = queue.length,
14394
		i;
14395
 
14396
	if ( show || !elem.is(":visible")) {
14397
		elem.css( "opacity", 0 ).show();
14398
		animateTo = 1;
14399
	}
14400
 
14401
	// anims - 1 opacity "toggles"
14402
	for ( i = 1; i < anims; i++ ) {
14403
		elem.animate({
14404
			opacity: animateTo
14405
		}, duration, o.easing );
14406
		animateTo = 1 - animateTo;
14407
	}
14408
 
14409
	elem.animate({
14410
		opacity: animateTo
14411
	}, duration, o.easing);
14412
 
14413
	elem.queue(function() {
14414
		if ( hide ) {
14415
			elem.hide();
14416
		}
14417
		done();
14418
	});
14419
 
14420
	// We just queued up "anims" animations, we need to put them next in the queue
14421
	if ( queuelen > 1 ) {
14422
		queue.splice.apply( queue,
14423
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14424
	}
14425
	elem.dequeue();
14426
};
14427
 
14428
})(jQuery);
14429
(function( $, undefined ) {
14430
 
14431
$.effects.effect.puff = function( o, done ) {
14432
	var elem = $( this ),
14433
		mode = $.effects.setMode( elem, o.mode || "hide" ),
14434
		hide = mode === "hide",
14435
		percent = parseInt( o.percent, 10 ) || 150,
14436
		factor = percent / 100,
14437
		original = {
14438
			height: elem.height(),
14439
			width: elem.width(),
14440
			outerHeight: elem.outerHeight(),
14441
			outerWidth: elem.outerWidth()
14442
		};
14443
 
14444
	$.extend( o, {
14445
		effect: "scale",
14446
		queue: false,
14447
		fade: true,
14448
		mode: mode,
14449
		complete: done,
14450
		percent: hide ? percent : 100,
14451
		from: hide ?
14452
			original :
14453
			{
14454
				height: original.height * factor,
14455
				width: original.width * factor,
14456
				outerHeight: original.outerHeight * factor,
14457
				outerWidth: original.outerWidth * factor
14458
			}
14459
	});
14460
 
14461
	elem.effect( o );
14462
};
14463
 
14464
$.effects.effect.scale = function( o, done ) {
14465
 
14466
	// Create element
14467
	var el = $( this ),
14468
		options = $.extend( true, {}, o ),
14469
		mode = $.effects.setMode( el, o.mode || "effect" ),
14470
		percent = parseInt( o.percent, 10 ) ||
14471
			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
14472
		direction = o.direction || "both",
14473
		origin = o.origin,
14474
		original = {
14475
			height: el.height(),
14476
			width: el.width(),
14477
			outerHeight: el.outerHeight(),
14478
			outerWidth: el.outerWidth()
14479
		},
14480
		factor = {
14481
			y: direction !== "horizontal" ? (percent / 100) : 1,
14482
			x: direction !== "vertical" ? (percent / 100) : 1
14483
		};
14484
 
14485
	// We are going to pass this effect to the size effect:
14486
	options.effect = "size";
14487
	options.queue = false;
14488
	options.complete = done;
14489
 
14490
	// Set default origin and restore for show/hide
14491
	if ( mode !== "effect" ) {
14492
		options.origin = origin || ["middle","center"];
14493
		options.restore = true;
14494
	}
14495
 
14496
	options.from = o.from || ( mode === "show" ? {
14497
		height: 0,
14498
		width: 0,
14499
		outerHeight: 0,
14500
		outerWidth: 0
14501
	} : original );
14502
	options.to = {
14503
		height: original.height * factor.y,
14504
		width: original.width * factor.x,
14505
		outerHeight: original.outerHeight * factor.y,
14506
		outerWidth: original.outerWidth * factor.x
14507
	};
14508
 
14509
	// Fade option to support puff
14510
	if ( options.fade ) {
14511
		if ( mode === "show" ) {
14512
			options.from.opacity = 0;
14513
			options.to.opacity = 1;
14514
		}
14515
		if ( mode === "hide" ) {
14516
			options.from.opacity = 1;
14517
			options.to.opacity = 0;
14518
		}
14519
	}
14520
 
14521
	// Animate
14522
	el.effect( options );
14523
 
14524
};
14525
 
14526
$.effects.effect.size = function( o, done ) {
14527
 
14528
	// Create element
14529
	var original, baseline, factor,
14530
		el = $( this ),
14531
		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
14532
 
14533
		// Always restore
14534
		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
14535
 
14536
		// Copy for children
14537
		props2 = [ "width", "height", "overflow" ],
14538
		cProps = [ "fontSize" ],
14539
		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
14540
		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
14541
 
14542
		// Set options
14543
		mode = $.effects.setMode( el, o.mode || "effect" ),
14544
		restore = o.restore || mode !== "effect",
14545
		scale = o.scale || "both",
14546
		origin = o.origin || [ "middle", "center" ],
14547
		position = el.css( "position" ),
14548
		props = restore ? props0 : props1,
14549
		zero = {
14550
			height: 0,
14551
			width: 0,
14552
			outerHeight: 0,
14553
			outerWidth: 0
14554
		};
14555
 
14556
	if ( mode === "show" ) {
14557
		el.show();
14558
	}
14559
	original = {
14560
		height: el.height(),
14561
		width: el.width(),
14562
		outerHeight: el.outerHeight(),
14563
		outerWidth: el.outerWidth()
14564
	};
14565
 
14566
	if ( o.mode === "toggle" && mode === "show" ) {
14567
		el.from = o.to || zero;
14568
		el.to = o.from || original;
14569
	} else {
14570
		el.from = o.from || ( mode === "show" ? zero : original );
14571
		el.to = o.to || ( mode === "hide" ? zero : original );
14572
	}
14573
 
14574
	// Set scaling factor
14575
	factor = {
14576
		from: {
14577
			y: el.from.height / original.height,
14578
			x: el.from.width / original.width
14579
		},
14580
		to: {
14581
			y: el.to.height / original.height,
14582
			x: el.to.width / original.width
14583
		}
14584
	};
14585
 
14586
	// Scale the css box
14587
	if ( scale === "box" || scale === "both" ) {
14588
 
14589
		// Vertical props scaling
14590
		if ( factor.from.y !== factor.to.y ) {
14591
			props = props.concat( vProps );
14592
			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
14593
			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
14594
		}
14595
 
14596
		// Horizontal props scaling
14597
		if ( factor.from.x !== factor.to.x ) {
14598
			props = props.concat( hProps );
14599
			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
14600
			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
14601
		}
14602
	}
14603
 
14604
	// Scale the content
14605
	if ( scale === "content" || scale === "both" ) {
14606
 
14607
		// Vertical props scaling
14608
		if ( factor.from.y !== factor.to.y ) {
14609
			props = props.concat( cProps ).concat( props2 );
14610
			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
14611
			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
14612
		}
14613
	}
14614
 
14615
	$.effects.save( el, props );
14616
	el.show();
14617
	$.effects.createWrapper( el );
14618
	el.css( "overflow", "hidden" ).css( el.from );
14619
 
14620
	// Adjust
14621
	if (origin) { // Calculate baseline shifts
14622
		baseline = $.effects.getBaseline( origin, original );
14623
		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
14624
		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
14625
		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
14626
		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
14627
	}
14628
	el.css( el.from ); // set top & left
14629
 
14630
	// Animate
14631
	if ( scale === "content" || scale === "both" ) { // Scale the children
14632
 
14633
		// Add margins/font-size
14634
		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
14635
		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
14636
		props2 = props0.concat(vProps).concat(hProps);
14637
 
14638
		el.find( "*[width]" ).each( function(){
14639
			var child = $( this ),
14640
				c_original = {
14641
					height: child.height(),
14642
					width: child.width(),
14643
					outerHeight: child.outerHeight(),
14644
					outerWidth: child.outerWidth()
14645
				};
14646
			if (restore) {
14647
				$.effects.save(child, props2);
14648
			}
14649
 
14650
			child.from = {
14651
				height: c_original.height * factor.from.y,
14652
				width: c_original.width * factor.from.x,
14653
				outerHeight: c_original.outerHeight * factor.from.y,
14654
				outerWidth: c_original.outerWidth * factor.from.x
14655
			};
14656
			child.to = {
14657
				height: c_original.height * factor.to.y,
14658
				width: c_original.width * factor.to.x,
14659
				outerHeight: c_original.height * factor.to.y,
14660
				outerWidth: c_original.width * factor.to.x
14661
			};
14662
 
14663
			// Vertical props scaling
14664
			if ( factor.from.y !== factor.to.y ) {
14665
				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
14666
				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
14667
			}
14668
 
14669
			// Horizontal props scaling
14670
			if ( factor.from.x !== factor.to.x ) {
14671
				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
14672
				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
14673
			}
14674
 
14675
			// Animate children
14676
			child.css( child.from );
14677
			child.animate( child.to, o.duration, o.easing, function() {
14678
 
14679
				// Restore children
14680
				if ( restore ) {
14681
					$.effects.restore( child, props2 );
14682
				}
14683
			});
14684
		});
14685
	}
14686
 
14687
	// Animate
14688
	el.animate( el.to, {
14689
		queue: false,
14690
		duration: o.duration,
14691
		easing: o.easing,
14692
		complete: function() {
14693
			if ( el.to.opacity === 0 ) {
14694
				el.css( "opacity", el.from.opacity );
14695
			}
14696
			if( mode === "hide" ) {
14697
				el.hide();
14698
			}
14699
			$.effects.restore( el, props );
14700
			if ( !restore ) {
14701
 
14702
				// we need to calculate our new positioning based on the scaling
14703
				if ( position === "static" ) {
14704
					el.css({
14705
						position: "relative",
14706
						top: el.to.top,
14707
						left: el.to.left
14708
					});
14709
				} else {
14710
					$.each([ "top", "left" ], function( idx, pos ) {
14711
						el.css( pos, function( _, str ) {
14712
							var val = parseInt( str, 10 ),
14713
								toRef = idx ? el.to.left : el.to.top;
14714
 
14715
							// if original was "auto", recalculate the new value from wrapper
14716
							if ( str === "auto" ) {
14717
								return toRef + "px";
14718
							}
14719
 
14720
							return val + toRef + "px";
14721
						});
14722
					});
14723
				}
14724
			}
14725
 
14726
			$.effects.removeWrapper( el );
14727
			done();
14728
		}
14729
	});
14730
 
14731
};
14732
 
14733
})(jQuery);
14734
(function( $, undefined ) {
14735
 
14736
$.effects.effect.shake = function( o, done ) {
14737
 
14738
	var el = $( this ),
14739
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14740
		mode = $.effects.setMode( el, o.mode || "effect" ),
14741
		direction = o.direction || "left",
14742
		distance = o.distance || 20,
14743
		times = o.times || 3,
14744
		anims = times * 2 + 1,
14745
		speed = Math.round(o.duration/anims),
14746
		ref = (direction === "up" || direction === "down") ? "top" : "left",
14747
		positiveMotion = (direction === "up" || direction === "left"),
14748
		animation = {},
14749
		animation1 = {},
14750
		animation2 = {},
14751
		i,
14752
 
14753
		// we will need to re-assemble the queue to stack our animations in place
14754
		queue = el.queue(),
14755
		queuelen = queue.length;
14756
 
14757
	$.effects.save( el, props );
14758
	el.show();
14759
	$.effects.createWrapper( el );
14760
 
14761
	// Animation
14762
	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
14763
	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
14764
	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
14765
 
14766
	// Animate
14767
	el.animate( animation, speed, o.easing );
14768
 
14769
	// Shakes
14770
	for ( i = 1; i < times; i++ ) {
14771
		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
14772
	}
14773
	el
14774
		.animate( animation1, speed, o.easing )
14775
		.animate( animation, speed / 2, o.easing )
14776
		.queue(function() {
14777
			if ( mode === "hide" ) {
14778
				el.hide();
14779
			}
14780
			$.effects.restore( el, props );
14781
			$.effects.removeWrapper( el );
14782
			done();
14783
		});
14784
 
14785
	// inject all the animations we just queued to be first in line (after "inprogress")
14786
	if ( queuelen > 1) {
14787
		queue.splice.apply( queue,
14788
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14789
	}
14790
	el.dequeue();
14791
 
14792
};
14793
 
14794
})(jQuery);
14795
(function( $, undefined ) {
14796
 
14797
$.effects.effect.slide = function( o, done ) {
14798
 
14799
	// Create element
14800
	var el = $( this ),
14801
		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
14802
		mode = $.effects.setMode( el, o.mode || "show" ),
14803
		show = mode === "show",
14804
		direction = o.direction || "left",
14805
		ref = (direction === "up" || direction === "down") ? "top" : "left",
14806
		positiveMotion = (direction === "up" || direction === "left"),
14807
		distance,
14808
		animation = {};
14809
 
14810
	// Adjust
14811
	$.effects.save( el, props );
14812
	el.show();
14813
	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
14814
 
14815
	$.effects.createWrapper( el ).css({
14816
		overflow: "hidden"
14817
	});
14818
 
14819
	if ( show ) {
14820
		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
14821
	}
14822
 
14823
	// Animation
14824
	animation[ ref ] = ( show ?
14825
		( positiveMotion ? "+=" : "-=") :
14826
		( positiveMotion ? "-=" : "+=")) +
14827
		distance;
14828
 
14829
	// Animate
14830
	el.animate( animation, {
14831
		queue: false,
14832
		duration: o.duration,
14833
		easing: o.easing,
14834
		complete: function() {
14835
			if ( mode === "hide" ) {
14836
				el.hide();
14837
			}
14838
			$.effects.restore( el, props );
14839
			$.effects.removeWrapper( el );
14840
			done();
14841
		}
14842
	});
14843
};
14844
 
14845
})(jQuery);
14846
(function( $, undefined ) {
14847
 
14848
$.effects.effect.transfer = function( o, done ) {
14849
	var elem = $( this ),
14850
		target = $( o.to ),
14851
		targetFixed = target.css( "position" ) === "fixed",
14852
		body = $("body"),
14853
		fixTop = targetFixed ? body.scrollTop() : 0,
14854
		fixLeft = targetFixed ? body.scrollLeft() : 0,
14855
		endPosition = target.offset(),
14856
		animation = {
14857
			top: endPosition.top - fixTop ,
14858
			left: endPosition.left - fixLeft ,
14859
			height: target.innerHeight(),
14860
			width: target.innerWidth()
14861
		},
14862
		startPosition = elem.offset(),
14863
		transfer = $( '<div class="ui-effects-transfer"></div>' )
14864
			.appendTo( document.body )
14865
			.addClass( o.className )
14866
			.css({
14867
				top: startPosition.top - fixTop ,
14868
				left: startPosition.left - fixLeft ,
14869
				height: elem.innerHeight(),
14870
				width: elem.innerWidth(),
14871
				position: targetFixed ? "fixed" : "absolute"
14872
			})
14873
			.animate( animation, o.duration, o.easing, function() {
14874
				transfer.remove();
14875
				done();
14876
			});
14877
};
14878
 
14879
})(jQuery);