PageSourceSearch

https://reminder.top/common/js/jquery-ui-1.11.4/ui/datepicker.js?u=079

js reminder.top collected 2026-10-02 06:14:34 UTC 77,973 bytes, 2,084 lines download raw bytes

1/*!
2 * jQuery UI Datepicker 1.11.4
3 * http://jqueryui.com
4 *
5 * Copyright jQuery Foundation and other contributors
6 * Released under the MIT license.
7 * http://jquery.org/license
8 *
9 * http://api.jqueryui.com/datepicker/
10 */
11(function( factory ) {
12	if ( typeof define === "function" && define.amd ) {
13
14		// AMD. Register as an anonymous module.
15		define([
16			"jquery",
17			"./core"
18		], factory );
19	} else {
20
21		// Browser globals
22		factory( jQuery );
23	}
24}(function( $ ) {
vendor: 23,233 bytes, lines 24-593
24
25
26$.extend($.ui, { datepicker: { version: "1.11.4" } });
27
28var datepicker_instActive;
29
30function datepicker_getZindex( elem ) {
31	var position, value;
32	while ( elem.length && elem[ 0 ] !== document ) {
33		// Ignore z-index if position is set to a value where z-index is ignored by the browser
34		// This makes behavior of this function consistent across browsers
35		// WebKit always returns auto if the element is positioned
36		position = elem.css( "position" );
37		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
38			// IE returns 0 when zIndex is not specified
39			// other browsers return a string
40			// we ignore the case of nested elements with an explicit value of 0
41			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
42			value = parseInt( elem.css( "zIndex" ), 10 );
43			if ( !isNaN( value ) && value !== 0 ) {
44				return value;
45			}
46		}
47		elem = elem.parent();
48	}
49
50	return 0;
51}
52/* Date picker manager.
53   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
54   Settings for (groups of) date pickers are maintained in an instance object,
55   allowing multiple different settings on the same page. */
56
57function Datepicker() {
58	this._curInst = null; // The current instance in use
59	this._keyEvent = false; // If the last event was a key event
60	this._disabledInputs = []; // List of date picker inputs that have been disabled
61	this._datepickerShowing = false; // True if the popup picker is showing , false if not
62	this._inDialog = false; // True if showing within a "dialog", false if not
63	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
64	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
65	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
66	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
67	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
68	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
69	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
70	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
71	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
72	this.regional = []; // Available regional settings, indexed by language code
73	this.regional[""] = { // Default regional settings
74		closeText: "Done", // Display text for close link
75		prevText: "Prev", // Display text for previous month link
76		nextText: "Next", // Display text for next month link
77		currentText: "Today", // Display text for current month link
78		monthNames: ["January","February","March","April","May","June",
79			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
80		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
81		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
82		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
83		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
84		weekHeader: "Wk", // Column header for week of the year
85		dateFormat: "mm/dd/yy", // See format options on parseDate
86		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
87		isRTL: false, // True if right-to-left language, false if left-to-right
88		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
89		yearSuffix: "" // Additional text to append to the year in the month headers
90	};
91	this._defaults = { // Global defaults for all the date picker instances
92		showOn: "focus", // "focus" for popup on focus,
93			// "button" for trigger button, or "both" for either
94		showAnim: "fadeIn", // Name of jQuery animation for popup
95		showOptions: {}, // Options for enhanced animations
96		defaultDate: null, // Used when field is blank: actual date,
97			// +/-number for offset from today, null for today
98		appendText: "", // Display text following the input box, e.g. showing the format
99		buttonText: "...", // Text for trigger button
100		buttonImage: "", // URL for trigger button image
101		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
102		hideIfNoPrevNext: false, // True to hide next/previous month links
103			// if not applicable, false to just disable them
104		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
105		gotoCurrent: false, // True if today link goes back to current selection instead
106		changeMonth: false, // True if month can be selected directly, false if only prev/next
107		changeYear: false, // True if year can be selected directly, false if only prev/next
108		yearRange: "c-10:c+10", // Range of years to display in drop-down,
109			// either relative to today's year (-nn:+nn), relative to currently displayed year
110			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
111		showOtherMonths: false, // True to show dates in other months, false to leave blank
112		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
113		showWeek: false, // True to show week of the year, false to not show it
114		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
115			// takes a Date and returns the number of the week for it
116		shortYearCutoff: "+10", // Short year values < this are in the current century,
117			// > this are in the previous century,
118			// string value starting with "+" for current year + value
119		minDate: null, // The earliest selectable date, or null for no limit
120		maxDate: null, // The latest selectable date, or null for no limit
121		duration: "fast", // Duration of display/closure
122		beforeShowDay: null, // Function that takes a date and returns an array with
123			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
124			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
125		beforeShow: null, // Function that takes an input field and
126			// returns a set of custom settings for the date picker
127		onSelect: null, // Define a callback function when a date is selected
128		onChangeMonthYear: null, // Define a callback function when the month or year is changed
129		onClose: null, // Define a callback function when the datepicker is closed
130		numberOfMonths: 1, // Number of months to show at a time
131		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
132		stepMonths: 1, // Number of months to step back/forward
133		stepBigMonths: 12, // Number of months to step back/forward for the big links
134		altField: "", // Selector for an alternate field to store selected dates into
135		altFormat: "", // The date format to use for the alternate field
136		constrainInput: true, // The input is constrained by the current date format
137		showButtonPanel: false, // True to show button panel, false to not show it
138		autoSize: false, // True to size the input for the date format, false to leave as is
139		disabled: false // The initial disabled state
140	};
141	$.extend(this._defaults, this.regional[""]);
142	this.regional.en = $.extend( true, {}, this.regional[ "" ]);
143	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
144	this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
145}
146
147$.extend(Datepicker.prototype, {
148	/* Class name added to elements to indicate already configured with a date picker. */
149	markerClassName: "hasDatepicker",
150
151	//Keep track of the maximum number of rows displayed (see #7043)
152	maxRows: 4,
153
154	// TODO rename to "widget" when switching to widget factory
155	_widgetDatepicker: function() {
156		return this.dpDiv;
157	},
158
159	/* Override the default settings for all instances of the date picker.
160	 * @param  settings  object - the new settings to use as defaults (anonymous object)
161	 * @return the manager object
162	 */
163	setDefaults: function(settings) {
164		datepicker_extendRemove(this._defaults, settings || {});
165		return this;
166	},
167
168	/* Attach the date picker to a jQuery selection.
169	 * @param  target	element - the target input field or division or span
170	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
171	 */
172	_attachDatepicker: function(target, settings) {
173		var nodeName, inline, inst;
174		nodeName = target.nodeName.toLowerCase();
175		inline = (nodeName === "div" || nodeName === "span");
176		if (!target.id) {
177			this.uuid += 1;
178			target.id = "dp" + this.uuid;
179		}
180		inst = this._newInst($(target), inline);
181		inst.settings = $.extend({}, settings || {});
182		if (nodeName === "input") {
183			this._connectDatepicker(target, inst);
184		} else if (inline) {
185			this._inlineDatepicker(target, inst);
186		}
187	},
188
189	/* Create a new instance object. */
190	_newInst: function(target, inline) {
191		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
192		return {id: id, input: target, // associated target
193			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
194			drawMonth: 0, drawYear: 0, // month being drawn
195			inline: inline, // is datepicker inline or not
196			dpDiv: (!inline ? this.dpDiv : // presentation div
197			datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
198	},
199
200	/* Attach the date picker to an input field. */
201	_connectDatepicker: function(target, inst) {
202		var input = $(target);
203		inst.append = $([]);
204		inst.trigger = $([]);
205		if (input.hasClass(this.markerClassName)) {
206			return;
207		}
208		this._attachments(input, inst);
209		input.addClass(this.markerClassName).keydown(this._doKeyDown).
210			keypress(this._doKeyPress).keyup(this._doKeyUp);
211		this._autoSize(inst);
212		$.data(target, "datepicker", inst);
213		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
214		if( inst.settings.disabled ) {
215			this._disableDatepicker( target );
216		}
217	},
218
219	/* Make attachments based on settings. */
220	_attachments: function(input, inst) {
221		var showOn, buttonText, buttonImage,
222			appendText = this._get(inst, "appendText"),
223			isRTL = this._get(inst, "isRTL");
224
225		if (inst.append) {
226			inst.append.remove();
227		}
228		if (appendText) {
229			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
230			input[isRTL ? "before" : "after"](inst.append);
231		}
232
233		input.unbind("focus", this._showDatepicker);
234
235		if (inst.trigger) {
236			inst.trigger.remove();
237		}
238
239		showOn = this._get(inst, "showOn");
240		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
241			input.focus(this._showDatepicker);
242		}
243		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
244			buttonText = this._get(inst, "buttonText");
245			buttonImage = this._get(inst, "buttonImage");
246			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
247				$("<img/>").addClass(this._triggerClass).
248					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
249				$("<button type='button'></button>").addClass(this._triggerClass).
250					html(!buttonImage ? buttonText : $("<img/>").attr(
251					{ src:buttonImage, alt:buttonText, title:buttonText })));
252			input[isRTL ? "before" : "after"](inst.trigger);
253			inst.trigger.click(function() {
254				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
255					$.datepicker._hideDatepicker();
256				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
257					$.datepicker._hideDatepicker();
258					$.datepicker._showDatepicker(input[0]);
259				} else {
260					$.datepicker._showDatepicker(input[0]);
261				}
262				return false;
263			});
264		}
265	},
266
267	/* Apply the maximum length for the date format. */
268	_autoSize: function(inst) {
269		if (this._get(inst, "autoSize") && !inst.inline) {
270			var findMax, max, maxI, i,
271				date = new Date(2009, 12 - 1, 20), // Ensure double digits
272				dateFormat = this._get(inst, "dateFormat");
273
274			if (dateFormat.match(/[DM]/)) {
275				findMax = function(names) {
276					max = 0;
277					maxI = 0;
278					for (i = 0; i < names.length; i++) {
279						if (names[i].length > max) {
280							max = names[i].length;
281							maxI = i;
282						}
283					}
284					return maxI;
285				};
286				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
287					"monthNames" : "monthNamesShort"))));
288				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
289					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
290			}
291			inst.input.attr("size", this._formatDate(inst, date).length);
292		}
293	},
294
295	/* Attach an inline date picker to a div. */
296	_inlineDatepicker: function(target, inst) {
297		var divSpan = $(target);
298		if (divSpan.hasClass(this.markerClassName)) {
299			return;
300		}
301		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
302		$.data(target, "datepicker", inst);
303		this._setDate(inst, this._getDefaultDate(inst), true);
304		this._updateDatepicker(inst);
305		this._updateAlternate(inst);
306		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
307		if( inst.settings.disabled ) {
308			this._disableDatepicker( target );
309		}
310		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
311		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
312		inst.dpDiv.css( "display", "block" );
313	},
314
315	/* Pop-up the date picker in a "dialog" box.
316	 * @param  input element - ignored
317	 * @param  date	string or Date - the initial date to display
318	 * @param  onSelect  function - the function to call when a date is selected
319	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
320	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
321	 *					event - with x/y coordinates or
322	 *					leave empty for default (screen centre)
323	 * @return the manager object
324	 */
325	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
326		var id, browserWidth, browserHeight, scrollX, scrollY,
327			inst = this._dialogInst; // internal instance
328
329		if (!inst) {
330			this.uuid += 1;
331			id = "dp" + this.uuid;
332			this._dialogInput = $("<input type='text' id='" + id +
333				"' style='position: absolute; top: -100px; width: 0px;'/>");
334			this._dialogInput.keydown(this._doKeyDown);
335			$("body").append(this._dialogInput);
336			inst = this._dialogInst = this._newInst(this._dialogInput, false);
337			inst.settings = {};
338			$.data(this._dialogInput[0], "datepicker", inst);
339		}
340		datepicker_extendRemove(inst.settings, settings || {});
341		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
342		this._dialogInput.val(date);
343
344		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
345		if (!this._pos) {
346			browserWidth = document.documentElement.clientWidth;
347			browserHeight = document.documentElement.clientHeight;
348			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
349			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
350			this._pos = // should use actual width/height below
351				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
352		}
353
354		// move input on screen for focus, but hidden behind dialog
355		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
356		inst.settings.onSelect = onSelect;
357		this._inDialog = true;
358		this.dpDiv.addClass(this._dialogClass);
359		this._showDatepicker(this._dialogInput[0]);
360		if ($.blockUI) {
361			$.blockUI(this.dpDiv);
362		}
363		$.data(this._dialogInput[0], "datepicker", inst);
364		return this;
365	},
366
367	/* Detach a datepicker from its control.
368	 * @param  target	element - the target input field or division or span
369	 */
370	_destroyDatepicker: function(target) {
371		var nodeName,
372			$target = $(target),
373			inst = $.data(target, "datepicker");
374
375		if (!$target.hasClass(this.markerClassName)) {
376			return;
377		}
378
379		nodeName = target.nodeName.toLowerCase();
380		$.removeData(target, "datepicker");
381		if (nodeName === "input") {
382			inst.append.remove();
383			inst.trigger.remove();
384			$target.removeClass(this.markerClassName).
385				unbind("focus", this._showDatepicker).
386				unbind("keydown", this._doKeyDown).
387				unbind("keypress", this._doKeyPress).
388				unbind("keyup", this._doKeyUp);
389		} else if (nodeName === "div" || nodeName === "span") {
390			$target.removeClass(this.markerClassName).empty();
391		}
392
393		if ( datepicker_instActive === inst ) {
394			datepicker_instActive = null;
395		}
396	},
397
398	/* Enable the date picker to a jQuery selection.
399	 * @param  target	element - the target input field or division or span
400	 */
401	_enableDatepicker: function(target) {
402		var nodeName, inline,
403			$target = $(target),
404			inst = $.data(target, "datepicker");
405
406		if (!$target.hasClass(this.markerClassName)) {
407			return;
408		}
409
410		nodeName = target.nodeName.toLowerCase();
411		if (nodeName === "input") {
412			target.disabled = false;
413			inst.trigger.filter("button").
414				each(function() { this.disabled = false; }).end().
415				filter("img").css({opacity: "1.0", cursor: ""});
416		} else if (nodeName === "div" || nodeName === "span") {
417			inline = $target.children("." + this._inlineClass);
418			inline.children().removeClass("ui-state-disabled");
419			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
420				prop("disabled", false);
421		}
422		this._disabledInputs = $.map(this._disabledInputs,
423			function(value) { return (value === target ? null : value); }); // delete entry
424	},
425
426	/* Disable the date picker to a jQuery selection.
427	 * @param  target	element - the target input field or division or span
428	 */
429	_disableDatepicker: function(target) {
430		var nodeName, inline,
431			$target = $(target),
432			inst = $.data(target, "datepicker");
433
434		if (!$target.hasClass(this.markerClassName)) {
435			return;
436		}
437
438		nodeName = target.nodeName.toLowerCase();
439		if (nodeName === "input") {
440			target.disabled = true;
441			inst.trigger.filter("button").
442				each(function() { this.disabled = true; }).end().
443				filter("img").css({opacity: "0.5", cursor: "default"});
444		} else if (nodeName === "div" || nodeName === "span") {
445			inline = $target.children("." + this._inlineClass);
446			inline.children().addClass("ui-state-disabled");
447			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
448				prop("disabled", true);
449		}
450		this._disabledInputs = $.map(this._disabledInputs,
451			function(value) { return (value === target ? null : value); }); // delete entry
452		this._disabledInputs[this._disabledInputs.length] = target;
453	},
454
455	/* Is the first field in a jQuery collection disabled as a datepicker?
456	 * @param  target	element - the target input field or division or span
457	 * @return boolean - true if disabled, false if enabled
458	 */
459	_isDisabledDatepicker: function(target) {
460		if (!target) {
461			return false;
462		}
463		for (var i = 0; i < this._disabledInputs.length; i++) {
464			if (this._disabledInputs[i] === target) {
465				return true;
466			}
467		}
468		return false;
469	},
470
471	/* Retrieve the instance data for the target control.
472	 * @param  target  element - the target input field or division or span
473	 * @return  object - the associated instance data
474	 * @throws  error if a jQuery problem getting data
475	 */
476	_getInst: function(target) {
477		try {
478			return $.data(target, "datepicker");
479		}
480		catch (err) {
481			throw "Missing instance data for this datepicker";
482		}
483	},
484
485	/* Update or retrieve the settings for a date picker attached to an input field or division.
486	 * @param  target  element - the target input field or division or span
487	 * @param  name	object - the new settings to update or
488	 *				string - the name of the setting to change or retrieve,
489	 *				when retrieving also "all" for all instance settings or
490	 *				"defaults" for all global defaults
491	 * @param  value   any - the new value for the setting
492	 *				(omit if above is an object or to retrieve a value)
493	 */
494	_optionDatepicker: function(target, name, value) {
495		var settings, date, minDate, maxDate,
496			inst = this._getInst(target);
497
498		if (arguments.length === 2 && typeof name === "string") {
499			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
500				(inst ? (name === "all" ? $.extend({}, inst.settings) :
501				this._get(inst, name)) : null));
502		}
503
504		settings = name || {};
505		if (typeof name === "string") {
506			settings = {};
507			settings[name] = value;
508		}
509
510		if (inst) {
511			if (this._curInst === inst) {
512				this._hideDatepicker();
513			}
514
515			date = this._getDateDatepicker(target, true);
516			minDate = this._getMinMaxDate(inst, "min");
517			maxDate = this._getMinMaxDate(inst, "max");
518			datepicker_extendRemove(inst.settings, settings);
519			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
520			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
521				inst.settings.minDate = this._formatDate(inst, minDate);
522			}
523			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
524				inst.settings.maxDate = this._formatDate(inst, maxDate);
525			}
526			if ( "disabled" in settings ) {
527				if ( settings.disabled ) {
528					this._disableDatepicker(target);
529				} else {
530					this._enableDatepicker(target);
531				}
532			}
533			this._attachments($(target), inst);
534			this._autoSize(inst);
535			this._setDate(inst, date);
536			this._updateAlternate(inst);
537			this._updateDatepicker(inst);
538		}
539	},
540
541	// change method deprecated
542	_changeDatepicker: function(target, name, value) {
543		this._optionDatepicker(target, name, value);
544	},
545
546	/* Redraw the date picker attached to an input field or division.
547	 * @param  target  element - the target input field or division or span
548	 */
549	_refreshDatepicker: function(target) {
550		var inst = this._getInst(target);
551		if (inst) {
552			this._updateDatepicker(inst);
553		}
554	},
555
556	/* Set the dates for a jQuery selection.
557	 * @param  target element - the target input field or division or span
558	 * @param  date	Date - the new date
559	 */
560	_setDateDatepicker: function(target, date) {
561		var inst = this._getInst(target);
562		if (inst) {
563			this._setDate(inst, date);
564			this._updateDatepicker(inst);
565			this._updateAlternate(inst);
566		}
567	},
568
569	/* Get the date(s) for the first entry in a jQuery selection.
570	 * @param  target element - the target input field or division or span
571	 * @param  noDefault boolean - true if no default date is to be used
572	 * @return Date - the current date
573	 */
574	_getDateDatepicker: function(target, noDefault) {
575		var inst = this._getInst(target);
576		if (inst && !inst.inline) {
577			this._setDateFromField(inst, noDefault);
578		}
579		return (inst ? this._getDate(inst) : null);
580	},
581
582	/* Handle keystrokes. */
583	_doKeyDown: function(event) {
584		var onSelect, dateStr, sel,
585			inst = $.datepicker._getInst(event.target),
586			handled = true,
587			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
588
589		inst._keyEvent = true;
590		if ($.datepicker._datepickerShowing) {
591			switch (event.keyCode) {
592				case 9: $.datepicker._hideDatepicker();
593						handled = false;
vendor: 4,495 bytes, lines 594-717
594						break; // hide on tab out
595				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
596									$.datepicker._currentClass + ")", inst.dpDiv);
597						if (sel[0]) {
598							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
599						}
600
601						onSelect = $.datepicker._get(inst, "onSelect");
602						if (onSelect) {
603							dateStr = $.datepicker._formatDate(inst);
604
605							// trigger custom callback
606							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
607						} else {
608							$.datepicker._hideDatepicker();
609						}
610
611						return false; // don't submit the form
612				case 27: $.datepicker._hideDatepicker();
613						break; // hide on escape
614				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
615							-$.datepicker._get(inst, "stepBigMonths") :
616							-$.datepicker._get(inst, "stepMonths")), "M");
617						break; // previous month/year on page up/+ ctrl
618				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
619							+$.datepicker._get(inst, "stepBigMonths") :
620							+$.datepicker._get(inst, "stepMonths")), "M");
621						break; // next month/year on page down/+ ctrl
622				case 35: if (event.ctrlKey || event.metaKey) {
623							$.datepicker._clearDate(event.target);
624						}
625						handled = event.ctrlKey || event.metaKey;
626						break; // clear on ctrl or command +end
627				case 36: if (event.ctrlKey || event.metaKey) {
628							$.datepicker._gotoToday(event.target);
629						}
630						handled = event.ctrlKey || event.metaKey;
631						break; // current on ctrl or command +home
632				case 37: if (event.ctrlKey || event.metaKey) {
633							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
634						}
635						handled = event.ctrlKey || event.metaKey;
636						// -1 day on ctrl or command +left
637						if (event.originalEvent.altKey) {
638							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
639								-$.datepicker._get(inst, "stepBigMonths") :
640								-$.datepicker._get(inst, "stepMonths")), "M");
641						}
642						// next month/year on alt +left on Mac
643						break;
644				case 38: if (event.ctrlKey || event.metaKey) {
645							$.datepicker._adjustDate(event.target, -7, "D");
646						}
647						handled = event.ctrlKey || event.metaKey;
648						break; // -1 week on ctrl or command +up
649				case 39: if (event.ctrlKey || event.metaKey) {
650							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
651						}
652						handled = event.ctrlKey || event.metaKey;
653						// +1 day on ctrl or command +right
654						if (event.originalEvent.altKey) {
655							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
656								+$.datepicker._get(inst, "stepBigMonths") :
657								+$.datepicker._get(inst, "stepMonths")), "M");
658						}
659						// next month/year on alt +right
660						break;
661				case 40: if (event.ctrlKey || event.metaKey) {
662							$.datepicker._adjustDate(event.target, +7, "D");
663						}
664						handled = event.ctrlKey || event.metaKey;
665						break; // +1 week on ctrl or command +down
666				default: handled = false;
667			}
668		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
669			$.datepicker._showDatepicker(this);
670		} else {
671			handled = false;
672		}
673
674		if (handled) {
675			event.preventDefault();
676			event.stopPropagation();
677		}
678	},
679
680	/* Filter entered characters - based on date format. */
681	_doKeyPress: function(event) {
682		var chars, chr,
683			inst = $.datepicker._getInst(event.target);
684
685		if ($.datepicker._get(inst, "constrainInput")) {
686			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
687			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
688			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
689		}
690	},
691
692	/* Synchronise manual entry and field/alternate field. */
693	_doKeyUp: function(event) {
694		var date,
695			inst = $.datepicker._getInst(event.target);
696
697		if (inst.input.val() !== inst.lastVal) {
698			try {
699				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
700					(inst.input ? inst.input.val() : null),
701					$.datepicker._getFormatConfig(inst));
702
703				if (date) { // only if valid
704					$.datepicker._setDateFromField(inst);
705					$.datepicker._updateAlternate(inst);
706					$.datepicker._updateDatepicker(inst);
707				}
708			}
709			catch (err) {
710			}
711		}
712		return true;
713	},
714
715	/* Pop-up the date picker for a given input field.
716	 * If false returned from beforeShow event handler do not show.
717	 * @param  input  element - the input field attached to the date picker or
vendor: 9,398 bytes, lines 718-992
718	 *					event - if triggered by focus
719	 */
720	_showDatepicker: function(input) {
721		input = input.target || input;
722		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
723			input = $("input", input.parentNode)[0];
724		}
725
726		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
727			return;
728		}
729
730		var inst, beforeShow, beforeShowSettings, isFixed,
731			offset, showAnim, duration;
732
733		inst = $.datepicker._getInst(input);
734		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
735			$.datepicker._curInst.dpDiv.stop(true, true);
736			if ( inst && $.datepicker._datepickerShowing ) {
737				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
738			}
739		}
740
741		beforeShow = $.datepicker._get(inst, "beforeShow");
742		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
743		if(beforeShowSettings === false){
744			return;
745		}
746		datepicker_extendRemove(inst.settings, beforeShowSettings);
747
748		inst.lastVal = null;
749		$.datepicker._lastInput = input;
750		$.datepicker._setDateFromField(inst);
751
752		if ($.datepicker._inDialog) { // hide cursor
753			input.value = "";
754		}
755		if (!$.datepicker._pos) { // position below input
756			$.datepicker._pos = $.datepicker._findPos(input);
757			$.datepicker._pos[1] += input.offsetHeight; // add the height
758		}
759
760		isFixed = false;
761		$(input).parents().each(function() {
762			isFixed |= $(this).css("position") === "fixed";
763			return !isFixed;
764		});
765
766		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
767		$.datepicker._pos = null;
768		//to avoid flashes on Firefox
769		inst.dpDiv.empty();
770		// determine sizing offscreen
771		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
772		$.datepicker._updateDatepicker(inst);
773		// fix width for dynamic number of date pickers
774		// and adjust position before showing
775		offset = $.datepicker._checkOffset(inst, offset, isFixed);
776		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
777			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
778			left: offset.left + "px", top: offset.top + "px"});
779
780		if (!inst.inline) {
781			showAnim = $.datepicker._get(inst, "showAnim");
782			duration = $.datepicker._get(inst, "duration");
783			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
784			$.datepicker._datepickerShowing = true;
785
786			if ( $.effects && $.effects.effect[ showAnim ] ) {
787				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
788			} else {
789				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
790			}
791
792			if ( $.datepicker._shouldFocusInput( inst ) ) {
793				inst.input.focus();
794			}
795
796			$.datepicker._curInst = inst;
797		}
798	},
799
800	/* Generate the date picker content. */
801	_updateDatepicker: function(inst) {
802		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
803		datepicker_instActive = inst; // for delegate hover events
804		inst.dpDiv.empty().append(this._generateHTML(inst));
805		this._attachHandlers(inst);
806
807		var origyearshtml,
808			numMonths = this._getNumberOfMonths(inst),
809			cols = numMonths[1],
810			width = 17,
811			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
812
813		if ( activeCell.length > 0 ) {
814			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
815		}
816
817		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
818		if (cols > 1) {
819			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
820		}
821		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
822			"Class"]("ui-datepicker-multi");
823		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
824			"Class"]("ui-datepicker-rtl");
825
826		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
827			inst.input.focus();
828		}
829
830		// deffered render of the years select (to avoid flashes on Firefox)
831		if( inst.yearshtml ){
832			origyearshtml = inst.yearshtml;
833			setTimeout(function(){
834				//assure that inst.yearshtml didn't change.
835				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
836					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
837				}
838				origyearshtml = inst.yearshtml = null;
839			}, 0);
840		}
841	},
842
843	// #6694 - don't focus the input if it's already focused
844	// this breaks the change event in IE
845	// Support: IE and jQuery <1.9
846	_shouldFocusInput: function( inst ) {
847		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
848	},
849
850	/* Check positioning to remain on screen. */
851	_checkOffset: function(inst, offset, isFixed) {
852		var dpWidth = inst.dpDiv.outerWidth(),
853			dpHeight = inst.dpDiv.outerHeight(),
854			inputWidth = inst.input ? inst.input.outerWidth() : 0,
855			inputHeight = inst.input ? inst.input.outerHeight() : 0,
856			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
857			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
858
859		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
860		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
861		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
862
863		// now check if datepicker is showing outside window viewport - move to a better place if so.
864		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
865			Math.abs(offset.left + dpWidth - viewWidth) : 0);
866		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
867			Math.abs(dpHeight + inputHeight) : 0);
868
869		return offset;
870	},
871
872	/* Find an object's position on the screen. */
873	_findPos: function(obj) {
874		var position,
875			inst = this._getInst(obj),
876			isRTL = this._get(inst, "isRTL");
877
878		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
879			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
880		}
881
882		position = $(obj).offset();
883		return [position.left, position.top];
884	},
885
886	/* Hide the date picker from view.
887	 * @param  input  element - the input field attached to the date picker
888	 */
889	_hideDatepicker: function(input) {
890		var showAnim, duration, postProcess, onClose,
891			inst = this._curInst;
892
893		if (!inst || (input && inst !== $.data(input, "datepicker"))) {
894			return;
895		}
896
897		if (this._datepickerShowing) {
898			showAnim = this._get(inst, "showAnim");
899			duration = this._get(inst, "duration");
900			postProcess = function() {
901				$.datepicker._tidyDialog(inst);
902			};
903
904			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
905			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
906				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
907			} else {
908				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
909					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
910			}
911
912			if (!showAnim) {
913				postProcess();
914			}
915			this._datepickerShowing = false;
916
917			onClose = this._get(inst, "onClose");
918			if (onClose) {
919				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
920			}
921
922			this._lastInput = null;
923			if (this._inDialog) {
924				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
925				if ($.blockUI) {
926					$.unblockUI();
927					$("body").append(this.dpDiv);
928				}
929			}
930			this._inDialog = false;
931		}
932	},
933
934	/* Tidy up after a dialog display. */
935	_tidyDialog: function(inst) {
936		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
937	},
938
939	/* Close date picker if clicked elsewhere. */
940	_checkExternalClick: function(event) {
941		if (!$.datepicker._curInst) {
942			return;
943		}
944
945		var $target = $(event.target),
946			inst = $.datepicker._getInst($target[0]);
947
948		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
949				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
950				!$target.hasClass($.datepicker.markerClassName) &&
951				!$target.closest("." + $.datepicker._triggerClass).length &&
952				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
953			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
954				$.datepicker._hideDatepicker();
955		}
956	},
957
958	/* Adjust one of the date sub-fields. */
959	_adjustDate: function(id, offset, period) {
960		var target = $(id),
961			inst = this._getInst(target[0]);
962
963		if (this._isDisabledDatepicker(target[0])) {
964			return;
965		}
966		this._adjustInstDate(inst, offset +
967			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
968			period);
969		this._updateDatepicker(inst);
970	},
971
972	/* Action for current link. */
973	_gotoToday: function(id) {
974		var date,
975			target = $(id),
976			inst = this._getInst(target[0]);
977
978		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
979			inst.selectedDay = inst.currentDay;
980			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
981			inst.drawYear = inst.selectedYear = inst.currentYear;
982		} else {
983			date = new Date();
984			inst.selectedDay = date.getDate();
985			inst.drawMonth = inst.selectedMonth = date.getMonth();
986			inst.drawYear = inst.selectedYear = date.getFullYear();
987		}
988		this._notifyChange(inst);
989		this._adjustDate(target);
990	},
991
992	/* Action for selecting a new month/year. */
vendor: 4,436 bytes, lines 993-1124
993	_selectMonthYear: function(id, select, period) {
994		var target = $(id),
995			inst = this._getInst(target[0]);
996
997		inst["selected" + (period === "M" ? "Month" : "Year")] =
998		inst["draw" + (period === "M" ? "Month" : "Year")] =
999			parseInt(select.options[select.selectedIndex].value,10);
1000
1001		this._notifyChange(inst);
1002		this._adjustDate(target);
1003	},
1004
1005	/* Action for selecting a day. */
1006	_selectDay: function(id, month, year, td) {
1007		var inst,
1008			target = $(id);
1009
1010		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
1011			return;
1012		}
1013
1014		inst = this._getInst(target[0]);
1015		inst.selectedDay = inst.currentDay = $("a", td).html();
1016		inst.selectedMonth = inst.currentMonth = month;
1017		inst.selectedYear = inst.currentYear = year;
1018		this._selectDate(id, this._formatDate(inst,
1019			inst.currentDay, inst.currentMonth, inst.currentYear));
1020	},
1021
1022	/* Erase the input field and hide the date picker. */
1023	_clearDate: function(id) {
1024		var target = $(id);
1025		this._selectDate(target, "");
1026	},
1027
1028	/* Update the input field with the selected date. */
1029	_selectDate: function(id, dateStr) {
1030		var onSelect,
1031			target = $(id),
1032			inst = this._getInst(target[0]);
1033
1034		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
1035		if (inst.input) {
1036			inst.input.val(dateStr);
1037		}
1038		this._updateAlternate(inst);
1039
1040		onSelect = this._get(inst, "onSelect");
1041		if (onSelect) {
1042			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
1043		} else if (inst.input) {
1044			inst.input.trigger("change"); // fire the change event
1045		}
1046
1047		if (inst.inline){
1048			this._updateDatepicker(inst);
1049		} else {
1050			this._hideDatepicker();
1051			this._lastInput = inst.input[0];
1052			if (typeof(inst.input[0]) !== "object") {
1053				inst.input.focus(); // restore focus
1054			}
1055			this._lastInput = null;
1056		}
1057	},
1058
1059	/* Update any alternate field to synchronise with the main field. */
1060	_updateAlternate: function(inst) {
1061		var altFormat, date, dateStr,
1062			altField = this._get(inst, "altField");
1063
1064		if (altField) { // update alternate field too
1065			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
1066			date = this._getDate(inst);
1067			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
1068			$(altField).each(function() { $(this).val(dateStr); });
1069		}
1070	},
1071
1072	/* Set as beforeShowDay function to prevent selection of weekends.
1073	 * @param  date  Date - the date to customise
1074	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
1075	 */
1076	noWeekends: function(date) {
1077		var day = date.getDay();
1078		return [(day > 0 && day < 6), ""];
1079	},
1080
1081	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
1082	 * @param  date  Date - the date to get the week for
1083	 * @return  number - the number of the week within the year that contains this date
1084	 */
1085	iso8601Week: function(date) {
1086		var time,
1087			checkDate = new Date(date.getTime());
1088
1089		// Find Thursday of this week starting on Monday
1090		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
1091
1092		time = checkDate.getTime();
1093		checkDate.setMonth(0); // Compare with Jan 1
1094		checkDate.setDate(1);
1095		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
1096	},
1097
1098	/* Parse a string value into a date object.
1099	 * See formatDate below for the possible formats.
1100	 *
1101	 * @param  format string - the expected format of the date
1102	 * @param  value string - the date in the above format
1103	 * @param  settings Object - attributes include:
1104	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
1105	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
1106	 *					dayNames		string[7] - names of the days from Sunday (optional)
1107	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
1108	 *					monthNames		string[12] - names of the months (optional)
1109	 * @return  Date - the extracted date value or null if value is blank
1110	 */
1111	parseDate: function (format, value, settings) {
1112		if (format == null || value == null) {
1113			throw "Invalid arguments";
1114		}
1115
1116		value = (typeof value === "object" ? value.toString() : value + "");
1117		if (value === "") {
1118			return null;
1119		}
1120
1121		var iFormat, dim, extra,
1122			iValue = 0,
1123			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
1124			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 5,261 bytes, lines 1124-1310
1124:
1125				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
1126			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
1127			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
1128			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
1129			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
1130			year = -1,
1131			month = -1,
1132			day = -1,
1133			doy = -1,
1134			literal = false,
1135			date,
1136			// Check whether a format character is doubled
1137			lookAhead = function(match) {
1138				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
1139				if (matches) {
1140					iFormat++;
1141				}
1142				return matches;
1143			},
1144			// Extract a number from the string value
1145			getNumber = function(match) {
1146				var isDoubled = lookAhead(match),
1147					size = (match === "@" ? 14 : (match === "!" ? 20 :
1148					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
1149					minSize = (match === "y" ? size : 1),
1150					digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
1151					num = value.substring(iValue).match(digits);
1152				if (!num) {
1153					throw "Missing number at position " + iValue;
1154				}
1155				iValue += num[0].length;
1156				return parseInt(num[0], 10);
1157			},
1158			// Extract a name from the string value and convert to an index
1159			getName = function(match, shortNames, longNames) {
1160				var index = -1,
1161					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
1162						return [ [k, v] ];
1163					}).sort(function (a, b) {
1164						return -(a[1].length - b[1].length);
1165					});
1166
1167				$.each(names, function (i, pair) {
1168					var name = pair[1];
1169					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
1170						index = pair[0];
1171						iValue += name.length;
1172						return false;
1173					}
1174				});
1175				if (index !== -1) {
1176					return index + 1;
1177				} else {
1178					throw "Unknown name at position " + iValue;
1179				}
1180			},
1181			// Confirm that a literal character matches the string value
1182			checkLiteral = function() {
1183				if (value.charAt(iValue) !== format.charAt(iFormat)) {
1184					throw "Unexpected literal at position " + iValue;
1185				}
1186				iValue++;
1187			};
1188
1189		for (iFormat = 0; iFormat < format.length; iFormat++) {
1190			if (literal) {
1191				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
1192					literal = false;
1193				} else {
1194					checkLiteral();
1195				}
1196			} else {
1197				switch (format.charAt(iFormat)) {
1198					case "d":
1199						day = getNumber("d");
1200						break;
1201					case "D":
1202						getName("D", dayNamesShort, dayNames);
1203						break;
1204					case "o":
1205						doy = getNumber("o");
1206						break;
1207					case "m":
1208						month = getNumber("m");
1209						break;
1210					case "M":
1211						month = getName("M", monthNamesShort, monthNames);
1212						break;
1213					case "y":
1214						year = getNumber("y");
1215						break;
1216					case "@":
1217						date = new Date(getNumber("@"));
1218						year = date.getFullYear();
1219						month = date.getMonth() + 1;
1220						day = date.getDate();
1221						break;
1222					case "!":
1223						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
1224						year = date.getFullYear();
1225						month = date.getMonth() + 1;
1226						day = date.getDate();
1227						break;
1228					case "'":
1229						if (lookAhead("'")){
1230							checkLiteral();
1231						} else {
1232							literal = true;
1233						}
1234						break;
1235					default:
1236						checkLiteral();
1237				}
1238			}
1239		}
1240
1241		if (iValue < value.length){
1242			extra = value.substr(iValue);
1243			if (!/^\s+/.test(extra)) {
1244				throw "Extra/unparsed characters found in date: " + extra;
1245			}
1246		}
1247
1248		if (year === -1) {
1249			year = new Date().getFullYear();
1250		} else if (year < 100) {
1251			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
1252				(year <= shortYearCutoff ? 0 : -100);
1253		}
1254
1255		if (doy > -1) {
1256			month = 1;
1257			day = doy;
1258			do {
1259				dim = this._getDaysInMonth(year, month - 1);
1260				if (day <= dim) {
1261					break;
1262				}
1263				month++;
1264				day -= dim;
1265			} while (true);
1266		}
1267
1268		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
1269		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
1270			throw "Invalid date"; // E.g. 31/02/00
1271		}
1272		return date;
1273	},
1274
1275	/* Standard date formats. */
1276	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
1277	COOKIE: "D, dd M yy",
1278	ISO_8601: "yy-mm-dd",
1279	RFC_822: "D, d M y",
1280	RFC_850: "DD, dd-M-y",
1281	RFC_1036: "D, d M y",
1282	RFC_1123: "D, d M yy",
1283	RFC_2822: "D, d M yy",
1284	RSS: "D, d M y", // RFC 822
1285	TICKS: "!",
1286	TIMESTAMP: "@",
1287	W3C: "yy-mm-dd", // ISO 8601
1288
1289	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
1290		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
1291
1292	/* Format a date object into a string value.
1293	 * The format can be combinations of the following:
1294	 * d  - day of month (no leading zero)
1295	 * dd - day of month (two digit)
1296	 * o  - day of year (no leading zeros)
1297	 * oo - day of year (three digit)
1298	 * D  - day name short
1299	 * DD - day name long
1300	 * m  - month of year (no leading zero)
1301	 * mm - month of year (two digit)
1302	 * M  - month name short
1303	 * MM - month name long
1304	 * y  - year (two digit)
1305	 * yy - year (four digit)
1306	 * @ - Unix timestamp (ms since 01/01/1970)
1307	 * ! - Windows ticks (100ns since 01/01/0001)
1308	 * "..." - literal text
1309	 * '' - single quote
1310	 *
vendor: 11,157 bytes, lines 1311-1644
1311	 * @param  format string - the desired format of the date
1312	 * @param  date Date - the date value to format
1313	 * @param  settings Object - attributes include:
1314	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
1315	 *					dayNames		string[7] - names of the days from Sunday (optional)
1316	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
1317	 *					monthNames		string[12] - names of the months (optional)
1318	 * @return  string - the date in the above format
1319	 */
1320	formatDate: function (format, date, settings) {
1321		if (!date) {
1322			return "";
1323		}
1324
1325		var iFormat,
1326			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
1327			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
1328			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
1329			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
1330			// Check whether a format character is doubled
1331			lookAhead = function(match) {
1332				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
1333				if (matches) {
1334					iFormat++;
1335				}
1336				return matches;
1337			},
1338			// Format a number, with leading zero if necessary
1339			formatNumber = function(match, value, len) {
1340				var num = "" + value;
1341				if (lookAhead(match)) {
1342					while (num.length < len) {
1343						num = "0" + num;
1344					}
1345				}
1346				return num;
1347			},
1348			// Format a name, short or long as requested
1349			formatName = function(match, value, shortNames, longNames) {
1350				return (lookAhead(match) ? longNames[value] : shortNames[value]);
1351			},
1352			output = "",
1353			literal = false;
1354
1355		if (date) {
1356			for (iFormat = 0; iFormat < format.length; iFormat++) {
1357				if (literal) {
1358					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
1359						literal = false;
1360					} else {
1361						output += format.charAt(iFormat);
1362					}
1363				} else {
1364					switch (format.charAt(iFormat)) {
1365						case "d":
1366							output += formatNumber("d", date.getDate(), 2);
1367							break;
1368						case "D":
1369							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
1370							break;
1371						case "o":
1372							output += formatNumber("o",
1373								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
1374							break;
1375						case "m":
1376							output += formatNumber("m", date.getMonth() + 1, 2);
1377							break;
1378						case "M":
1379							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
1380							break;
1381						case "y":
1382							output += (lookAhead("y") ? date.getFullYear() :
1383								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
1384							break;
1385						case "@":
1386							output += date.getTime();
1387							break;
1388						case "!":
1389							output += date.getTime() * 10000 + this._ticksTo1970;
1390							break;
1391						case "'":
1392							if (lookAhead("'")) {
1393								output += "'";
1394							} else {
1395								literal = true;
1396							}
1397							break;
1398						default:
1399							output += format.charAt(iFormat);
1400					}
1401				}
1402			}
1403		}
1404		return output;
1405	},
1406
1407	/* Extract all possible characters from the date format. */
1408	_possibleChars: function (format) {
1409		var iFormat,
1410			chars = "",
1411			literal = false,
1412			// Check whether a format character is doubled
1413			lookAhead = function(match) {
1414				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
1415				if (matches) {
1416					iFormat++;
1417				}
1418				return matches;
1419			};
1420
1421		for (iFormat = 0; iFormat < format.length; iFormat++) {
1422			if (literal) {
1423				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
1424					literal = false;
1425				} else {
1426					chars += format.charAt(iFormat);
1427				}
1428			} else {
1429				switch (format.charAt(iFormat)) {
1430					case "d": case "m": case "y": case "@":
1431						chars += "0123456789";
1432						break;
1433					case "D": case "M":
1434						return null; // Accept anything
1435					case "'":
1436						if (lookAhead("'")) {
1437							chars += "'";
1438						} else {
1439							literal = true;
1440						}
1441						break;
1442					default:
1443						chars += format.charAt(iFormat);
1444				}
1445			}
1446		}
1447		return chars;
1448	},
1449
1450	/* Get a setting value, defaulting if necessary. */
1451	_get: function(inst, name) {
1452		return inst.settings[name] !== undefined ?
1453			inst.settings[name] : this._defaults[name];
1454	},
1455
1456	/* Parse existing date and initialise date picker. */
1457	_setDateFromField: function(inst, noDefault) {
1458		if (inst.input.val() === inst.lastVal) {
1459			return;
1460		}
1461
1462		var dateFormat = this._get(inst, "dateFormat"),
1463			dates = inst.lastVal = inst.input ? inst.input.val() : null,
1464			defaultDate = this._getDefaultDate(inst),
1465			date = defaultDate,
1466			settings = this._getFormatConfig(inst);
1467
1468		try {
1469			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
1470		} catch (event) {
1471			dates = (noDefault ? "" : dates);
1472		}
1473		inst.selectedDay = date.getDate();
1474		inst.drawMonth = inst.selectedMonth = date.getMonth();
1475		inst.drawYear = inst.selectedYear = date.getFullYear();
1476		inst.currentDay = (dates ? date.getDate() : 0);
1477		inst.currentMonth = (dates ? date.getMonth() : 0);
1478		inst.currentYear = (dates ? date.getFullYear() : 0);
1479		this._adjustInstDate(inst);
1480	},
1481
1482	/* Retrieve the default date shown on opening. */
1483	_getDefaultDate: function(inst) {
1484		return this._restrictMinMax(inst,
1485			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
1486	},
1487
1488	/* A date may be specified as an exact value or a relative one. */
1489	_determineDate: function(inst, date, defaultDate) {
1490		var offsetNumeric = function(offset) {
1491				var date = new Date();
1492				date.setDate(date.getDate() + offset);
1493				return date;
1494			},
1495			offsetString = function(offset) {
1496				try {
1497					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
1498						offset, $.datepicker._getFormatConfig(inst));
1499				}
1500				catch (e) {
1501					// Ignore
1502				}
1503
1504				var date = (offset.toLowerCase().match(/^c/) ?
1505					$.datepicker._getDate(inst) : null) || new Date(),
1506					year = date.getFullYear(),
1507					month = date.getMonth(),
1508					day = date.getDate(),
1509					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
1510					matches = pattern.exec(offset);
1511
1512				while (matches) {
1513					switch (matches[2] || "d") {
1514						case "d" : case "D" :
1515							day += parseInt(matches[1],10); break;
1516						case "w" : case "W" :
1517							day += parseInt(matches[1],10) * 7; break;
1518						case "m" : case "M" :
1519							month += parseInt(matches[1],10);
1520							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
1521							break;
1522						case "y": case "Y" :
1523							year += parseInt(matches[1],10);
1524							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
1525							break;
1526					}
1527					matches = pattern.exec(offset);
1528				}
1529				return new Date(year, month, day);
1530			},
1531			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
1532				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
1533
1534		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
1535		if (newDate) {
1536			newDate.setHours(0);
1537			newDate.setMinutes(0);
1538			newDate.setSeconds(0);
1539			newDate.setMilliseconds(0);
1540		}
1541		return this._daylightSavingAdjust(newDate);
1542	},
1543
1544	/* Handle switch to/from daylight saving.
1545	 * Hours may be non-zero on daylight saving cut-over:
1546	 * > 12 when midnight changeover, but then cannot generate
1547	 * midnight datetime, so jump to 1AM, otherwise reset.
1548	 * @param  date  (Date) the date to check
1549	 * @return  (Date) the corrected date
1550	 */
1551	_daylightSavingAdjust: function(date) {
1552		if (!date) {
1553			return null;
1554		}
1555		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
1556		return date;
1557	},
1558
1559	/* Set the date(s) directly. */
1560	_setDate: function(inst, date, noChange) {
1561		var clear = !date,
1562			origMonth = inst.selectedMonth,
1563			origYear = inst.selectedYear,
1564			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
1565
1566		inst.selectedDay = inst.currentDay = newDate.getDate();
1567		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
1568		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
1569		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
1570			this._notifyChange(inst);
1571		}
1572		this._adjustInstDate(inst);
1573		if (inst.input) {
1574			inst.input.val(clear ? "" : this._formatDate(inst));
1575		}
1576	},
1577
1578	/* Retrieve the date(s) directly. */
1579	_getDate: function(inst) {
1580		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
1581			this._daylightSavingAdjust(new Date(
1582			inst.currentYear, inst.currentMonth, inst.currentDay)));
1583			return startDate;
1584	},
1585
1586	/* Attach the onxxx handlers.  These are declared statically so
1587	 * they work with static code transformers like Caja.
1588	 */
1589	_attachHandlers: function(inst) {
1590		var stepMonths = this._get(inst, "stepMonths"),
1591			id = "#" + inst.id.replace( /\\\\/g, "\\" );
1592		inst.dpDiv.find("[data-handler]").map(function () {
1593			var handler = {
1594				prev: function () {
1595					$.datepicker._adjustDate(id, -stepMonths, "M");
1596				},
1597				next: function () {
1598					$.datepicker._adjustDate(id, +stepMonths, "M");
1599				},
1600				hide: function () {
1601					$.datepicker._hideDatepicker();
1602				},
1603				today: function () {
1604					$.datepicker._gotoToday(id);
1605				},
1606				selectDay: function () {
1607					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
1608					return false;
1609				},
1610				selectMonth: function () {
1611					$.datepicker._selectMonthYear(id, this, "M");
1612					return false;
1613				},
1614				selectYear: function () {
1615					$.datepicker._selectMonthYear(id, this, "Y");
1616					return false;
1617				}
1618			};
1619			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
1620		});
1621	},
1622
1623	/* Generate the HTML for the current state of the date picker. */
1624	_generateHTML: function(inst) {
1625		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
1626			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
1627			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
1628			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
1629			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
1630			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
1631			tempDate = new Date(),
1632			today = this._daylightSavingAdjust(
1633				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
1634			isRTL = this._get(inst, "isRTL"),
1635			showButtonPanel = this._get(inst, "showButtonPanel"),
1636			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
1637			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
1638			numMonths = this._getNumberOfMonths(inst),
1639			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
1640			stepMonths = this._get(inst, "stepMonths"),
1641			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
1642			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
1643				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
1644			minDate = this._getMinMaxDate(inst, "min"),
vendor: 9,139 bytes, lines 1645-1803
1645			maxDate = this._getMinMaxDate(inst, "max"),
1646			drawMonth = inst.drawMonth - showCurrentAtPos,
1647			drawYear = inst.drawYear;
1648
1649		if (drawMonth < 0) {
1650			drawMonth += 12;
1651			drawYear--;
1652		}
1653		if (maxDate) {
1654			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
1655				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
1656			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1657			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
1658				drawMonth--;
1659				if (drawMonth < 0) {
1660					drawMonth = 11;
1661					drawYear--;
1662				}
1663			}
1664		}
1665		inst.drawMonth = drawMonth;
1666		inst.drawYear = drawYear;
1667
1668		prevText = this._get(inst, "prevText");
1669		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
1670			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
1671			this._getFormatConfig(inst)));
1672
1673		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
1674			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
1675			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
1676			(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>"));
1677
1678		nextText = this._get(inst, "nextText");
1679		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
1680			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
1681			this._getFormatConfig(inst)));
1682
1683		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
1684			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
1685			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
1686			(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>"));
1687
1688		currentText = this._get(inst, "currentText");
1689		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
1690		currentText = (!navigationAsDateFormat ? currentText :
1691			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
1692
1693		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'>" +
1694			this._get(inst, "closeText") + "</button>" : "");
1695
1696		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
1697			(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'" +
1698			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
1699
1700		firstDay = parseInt(this._get(inst, "firstDay"),10);
1701		firstDay = (isNaN(firstDay) ? 0 : firstDay);
1702
1703		showWeek = this._get(inst, "showWeek");
1704		dayNames = this._get(inst, "dayNames");
1705		dayNamesMin = this._get(inst, "dayNamesMin");
1706		monthNames = this._get(inst, "monthNames");
1707		monthNamesShort = this._get(inst, "monthNamesShort");
1708		beforeShowDay = this._get(inst, "beforeShowDay");
1709		showOtherMonths = this._get(inst, "showOtherMonths");
1710		selectOtherMonths = this._get(inst, "selectOtherMonths");
1711		defaultDate = this._getDefaultDate(inst);
1712		html = "";
1713		dow;
1714		for (row = 0; row < numMonths[0]; row++) {
1715			group = "";
1716			this.maxRows = 4;
1717			for (col = 0; col < numMonths[1]; col++) {
1718				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
1719				cornerClass = " ui-corner-all";
1720				calender = "";
1721				if (isMultiMonth) {
1722					calender += "<div class='ui-datepicker-group";
1723					if (numMonths[1] > 1) {
1724						switch (col) {
1725							case 0: calender += " ui-datepicker-group-first";
1726								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
1727							case numMonths[1]-1: calender += " ui-datepicker-group-last";
1728								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
1729							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
1730						}
1731					}
1732					calender += "'>";
1733				}
1734				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
1735					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
1736					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
1737					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
1738					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
1739					"</div><table class='ui-datepicker-calendar'><thead>" +
1740					"<tr>";
1741				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
1742				for (dow = 0; dow < 7; dow++) { // days of the week
1743					day = (dow + firstDay) % 7;
1744					thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
1745						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
1746				}
1747				calender += thead + "</tr></thead><tbody>";
1748				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1749				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
1750					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
1751				}
1752				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1753				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
1754				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
1755				this.maxRows = numRows;
1756				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
1757				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
1758					calender += "<tr>";
1759					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
1760						this._get(inst, "calculateWeek")(printDate) + "</td>");
1761					for (dow = 0; dow < 7; dow++) { // create date picker days
1762						daySettings = (beforeShowDay ?
1763							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
1764						otherMonth = (printDate.getMonth() !== drawMonth);
1765						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
1766							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1767						tbody += "<td class='" +
1768							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
1769							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
1770							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
1771							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
1772							// or defaultDate is current printedDate and defaultDate is selectedDate
1773							" " + this._dayOverClass : "") + // highlight selected day
1774							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
1775							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
1776							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
1777							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
1778							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
1779							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
1780							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
1781							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
1782							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
1783							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
1784							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
1785							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
1786						printDate.setDate(printDate.getDate() + 1);
1787						printDate = this._daylightSavingAdjust(printDate);
1788					}
1789					calender += tbody + "</tr>";
1790				}
1791				drawMonth++;
1792				if (drawMonth > 11) {
1793					drawMonth = 0;
1794					drawYear++;
1795				}
1796				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
1797							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
1798				group += calender;
1799			}
1800			html += group;
1801		}
1802		html += buttonPanel;
1803		inst._keyEvent = false;
vendor: 5,431 bytes, lines 1804-1947
1804		return html;
1805	},
1806
1807	/* Generate the month and year header. */
1808	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
1809			secondary, monthNames, monthNamesShort) {
1810
1811		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
1812			changeMonth = this._get(inst, "changeMonth"),
1813			changeYear = this._get(inst, "changeYear"),
1814			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
1815			html = "<div class='ui-datepicker-title'>",
1816			monthHtml = "";
1817
1818		// month selection
1819		if (secondary || !changeMonth) {
1820			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
1821		} else {
1822			inMinYear = (minDate && minDate.getFullYear() === drawYear);
1823			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
1824			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
1825			for ( month = 0; month < 12; month++) {
1826				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
1827					monthHtml += "<option value='" + month + "'" +
1828						(month === drawMonth ? " selected='selected'" : "") +
1829						">" + monthNamesShort[month] + "</option>";
1830				}
1831			}
1832			monthHtml += "</select>";
1833		}
1834
1835		if (!showMonthAfterYear) {
1836			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
1837		}
1838
1839		// year selection
1840		if ( !inst.yearshtml ) {
1841			inst.yearshtml = "";
1842			if (secondary || !changeYear) {
1843				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
1844			} else {
1845				// determine range of years to display
1846				years = this._get(inst, "yearRange").split(":");
1847				thisYear = new Date().getFullYear();
1848				determineYear = function(value) {
1849					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
1850						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
1851						parseInt(value, 10)));
1852					return (isNaN(year) ? thisYear : year);
1853				};
1854				year = determineYear(years[0]);
1855				endYear = Math.max(year, determineYear(years[1] || ""));
1856				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
1857				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1858				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
1859				for (; year <= endYear; year++) {
1860					inst.yearshtml += "<option value='" + year + "'" +
1861						(year === drawYear ? " selected='selected'" : "") +
1862						">" + year + "</option>";
1863				}
1864				inst.yearshtml += "</select>";
1865
1866				html += inst.yearshtml;
1867				inst.yearshtml = null;
1868			}
1869		}
1870
1871		html += this._get(inst, "yearSuffix");
1872		if (showMonthAfterYear) {
1873			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
1874		}
1875		html += "</div>"; // Close datepicker_header
1876		return html;
1877	},
1878
1879	/* Adjust one of the date sub-fields. */
1880	_adjustInstDate: function(inst, offset, period) {
1881		var year = inst.drawYear + (period === "Y" ? offset : 0),
1882			month = inst.drawMonth + (period === "M" ? offset : 0),
1883			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
1884			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
1885
1886		inst.selectedDay = date.getDate();
1887		inst.drawMonth = inst.selectedMonth = date.getMonth();
1888		inst.drawYear = inst.selectedYear = date.getFullYear();
1889		if (period === "M" || period === "Y") {
1890			this._notifyChange(inst);
1891		}
1892	},
1893
1894	/* Ensure a date is within any min/max bounds. */
1895	_restrictMinMax: function(inst, date) {
1896		var minDate = this._getMinMaxDate(inst, "min"),
1897			maxDate = this._getMinMaxDate(inst, "max"),
1898			newDate = (minDate && date < minDate ? minDate : date);
1899		return (maxDate && newDate > maxDate ? maxDate : newDate);
1900	},
1901
1902	/* Notify change of month/year. */
1903	_notifyChange: function(inst) {
1904		var onChange = this._get(inst, "onChangeMonthYear");
1905		if (onChange) {
1906			onChange.apply((inst.input ? inst.input[0] : null),
1907				[inst.selectedYear, inst.selectedMonth + 1, inst]);
1908		}
1909	},
1910
1911	/* Determine the number of months to show. */
1912	_getNumberOfMonths: function(inst) {
1913		var numMonths = this._get(inst, "numberOfMonths");
1914		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
1915	},
1916
1917	/* Determine the current maximum date - ensure no time components are set. */
1918	_getMinMaxDate: function(inst, minMax) {
1919		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
1920	},
1921
1922	/* Find the number of days in a given month. */
1923	_getDaysInMonth: function(year, month) {
1924		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
1925	},
1926
1927	/* Find the day of the week of the first of a month. */
1928	_getFirstDayOfMonth: function(year, month) {
1929		return new Date(year, month, 1).getDay();
1930	},
1931
1932	/* Determines if we should allow a "next/prev" month display change. */
1933	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
1934		var numMonths = this._getNumberOfMonths(inst),
1935			date = this._daylightSavingAdjust(new Date(curYear,
1936			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
1937
1938		if (offset < 0) {
1939			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
1940		}
1941		return this._isInRange(inst, date);
1942	},
1943
1944	/* Is the given date in the accepted range? */
1945	_isInRange: function(inst, date) {
1946		var yearSplit, currentYear,
1947			minDate = this._getMinMaxDate(inst, "min"),
vendor: 4,926 bytes, lines 1948-2081
1948			maxDate = this._getMinMaxDate(inst, "max"),
1949			minYear = null,
1950			maxYear = null,
1951			years = this._get(inst, "yearRange");
1952			if (years){
1953				yearSplit = years.split(":");
1954				currentYear = new Date().getFullYear();
1955				minYear = parseInt(yearSplit[0], 10);
1956				maxYear = parseInt(yearSplit[1], 10);
1957				if ( yearSplit[0].match(/[+\-].*/) ) {
1958					minYear += currentYear;
1959				}
1960				if ( yearSplit[1].match(/[+\-].*/) ) {
1961					maxYear += currentYear;
1962				}
1963			}
1964
1965		return ((!minDate || date.getTime() >= minDate.getTime()) &&
1966			(!maxDate || date.getTime() <= maxDate.getTime()) &&
1967			(!minYear || date.getFullYear() >= minYear) &&
1968			(!maxYear || date.getFullYear() <= maxYear));
1969	},
1970
1971	/* Provide the configuration settings for formatting/parsing. */
1972	_getFormatConfig: function(inst) {
1973		var shortYearCutoff = this._get(inst, "shortYearCutoff");
1974		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
1975			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1976		return {shortYearCutoff: shortYearCutoff,
1977			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
1978			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
1979	},
1980
1981	/* Format the given date for display. */
1982	_formatDate: function(inst, day, month, year) {
1983		if (!day) {
1984			inst.currentDay = inst.selectedDay;
1985			inst.currentMonth = inst.selectedMonth;
1986			inst.currentYear = inst.selectedYear;
1987		}
1988		var date = (day ? (typeof day === "object" ? day :
1989			this._daylightSavingAdjust(new Date(year, month, day))) :
1990			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
1991		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
1992	}
1993});
1994
1995/*
1996 * Bind hover events for datepicker elements.
1997 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
1998 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
1999 */
2000function datepicker_bindHover(dpDiv) {
2001	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
2002	return dpDiv.delegate(selector, "mouseout", function() {
2003			$(this).removeClass("ui-state-hover");
2004			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
2005				$(this).removeClass("ui-datepicker-prev-hover");
2006			}
2007			if (this.className.indexOf("ui-datepicker-next") !== -1) {
2008				$(this).removeClass("ui-datepicker-next-hover");
2009			}
2010		})
2011		.delegate( selector, "mouseover", datepicker_handleMouseover );
2012}
2013
2014function datepicker_handleMouseover() {
2015	if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
2016		$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
2017		$(this).addClass("ui-state-hover");
2018		if (this.className.indexOf("ui-datepicker-prev") !== -1) {
2019			$(this).addClass("ui-datepicker-prev-hover");
2020		}
2021		if (this.className.indexOf("ui-datepicker-next") !== -1) {
2022			$(this).addClass("ui-datepicker-next-hover");
2023		}
2024	}
2025}
2026
2027/* jQuery extend now ignores nulls! */
2028function datepicker_extendRemove(target, props) {
2029	$.extend(target, props);
2030	for (var name in props) {
2031		if (props[name] == null) {
2032			target[name] = props[name];
2033		}
2034	}
2035	return target;
2036}
2037
2038/* Invoke the datepicker functionality.
2039   @param  options  string - a command, optionally followed by additional parameters or
2040					Object - settings for attaching new datepicker functionality
2041   @return  jQuery object */
2042$.fn.datepicker = function(options){
2043
2044	/* Verify an empty collection wasn't passed - Fixes #6976 */
2045	if ( !this.length ) {
2046		return this;
2047	}
2048
2049	/* Initialise the date picker. */
2050	if (!$.datepicker.initialized) {
2051		$(document).mousedown($.datepicker._checkExternalClick);
2052		$.datepicker.initialized = true;
2053	}
2054
2055	/* Append datepicker main container to body if not exist. */
2056	if ($("#"+$.datepicker._mainDivId).length === 0) {
2057		$("body").append($.datepicker.dpDiv);
2058	}
2059
2060	var otherArgs = Array.prototype.slice.call(arguments, 1);
2061	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
2062		return $.datepicker["_" + options + "Datepicker"].
2063			apply($.datepicker, [this[0]].concat(otherArgs));
2064	}
2065	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
2066		return $.datepicker["_" + options + "Datepicker"].
2067			apply($.datepicker, [this[0]].concat(otherArgs));
2068	}
2069	return this.each(function() {
2070		typeof options === "string" ?
2071			$.datepicker["_" + options + "Datepicker"].
2072				apply($.datepicker, [this].concat(otherArgs)) :
2073			$.datepicker._attachDatepicker(this, options);
2074	});
2075};
2076
2077$.datepicker = new Datepicker(); // singleton instance
2078$.datepicker.initialized = false;
2079$.datepicker.uuid = new Date().getTime();
2080$.datepicker.version = "1.11.4";
2081
2082return $.datepicker;
2083
2084}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.