PageSourceSearch

http://www.kanoclublier.be/wp-content/plugins/booking/js/datepick/jquery.datepick.wpbc.9.0.js?ver=11.8.4

js kanoclublier.be collected 2026-10-03 02:27:59 UTC 104,458 bytes, 2,267 lines download raw bytes

1/* http://keith-wood.name/datepick.html
2   Datepicker for jQuery 3.7.1.
3   Written by Marc Grabanski ([email protected]) and
4              Keith Wood (kbwood{at}iinet.com.au).
5   Dual licensed under the GPL (http://dev.jQuery.com/browser/trunk/jQuery/GPL-LICENSE.txt) and
6   MIT (http://dev.jQuery.com/browser/trunk/jQuery/MIT-LICENSE.txt) licenses.
7   Please attribute the authors if you use it. */
8
9/**
10 * TODO: for fixing conflicts with  any other datepickers, we will be need to make fix like this here,  and then  in all  other places in plugin.
11 * Replaced items (2023-07-01 )
12 *
13 * 	.datepick > .wpbc_calendar
14		$.datepick 			> 	$.wpbc_calendar
15		jQuery.datepick		>	jQuery.wpbc_calendar
16	Datepick			>	WPBC_Calendar
17
18	browser_is_supported_datepick 	> 	browser_is_supported_wpbc_calendar
19	isArray							>	wpbc_is_array
20	extendRemove					>	wpbc_extend_remove
21
22	var PROP_NAME = 'datepick';		>	var PROP_NAME = 'wpbc_calendar';
23	_tableClass: ['datepick', 		>	_tableClass: ['datepick wpbc_calendar',
24 */
25
26(function($) { // Hide the namespace
27
28var PROP_NAME = 'datepick';
29
30
31    // https://github.com/jquery/jquery-migrate/blob/master/src/core.js#L50
32	// FixIn: 8.7.10.1.
33    if (!$.browser_is_supported_datepick) {
34        var uaMatch = function(ua) {
35            ua = ua.toLowerCase();
36
37            var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
38
39            return match[2] || '0';
40        };
41
42        $.browser_is_supported_datepick = {
43            mozilla: /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit/.test(navigator.userAgent.toLowerCase()),
44            webkit: /webkit/.test(navigator.userAgent.toLowerCase()),
45            opera: /opera/.test(navigator.userAgent.toLowerCase()),
46            msie: /msie/.test(navigator.userAgent.toLowerCase()),
47            android: (navigator.userAgent.toLowerCase().indexOf('mozilla/5.0') > -1 && navigator.userAgent.toLowerCase().indexOf('android ') > -1 && navigator.userAgent.toLowerCase().indexOf('applewebkit') > -1),
48            version: uaMatch(navigator.userAgent)
49        };
50    }
51
52/* Date picker manager.
53   Use the singleton instance of this class, $.datepick, 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 Datepick() {
58	this._uuid = new Date().getTime(); // Unique identifier seed
59	this._curInst = null; // The current instance in use
60	this._keyEvent = false; // If the last event was a key event
61	this._disabledInputs = []; // List of date picker inputs that have been disabled
62	this._datepickerShowing = false; // True if the popup picker is showing , false if not
63	this._inDialog = false; // True if showing within a "dialog", false if not
64	this.regional = []; // Available regional settings, indexed by language code
65	this.regional[''] = { // Default regional settings
66		clearText: 'Clear', // Display text for clear link
67		clearStatus: 'Erase the current date', // Status text for clear link
68		closeText: 'Close', // Display text for close link
69		closeStatus: 'Close without change', // Status text for close link
70		prevText: '&#x3c;Prev', // Display text for previous month link
71		prevStatus: 'Show the previous month', // Status text for previous month link
72		prevBigText: '&#x3c;&#x3c;', // Display text for previous year link
73		prevBigStatus: 'Show the previous year', // Status text for previous year link
74		nextText: 'Next&#x3e;', // Display text for next month link
75		nextStatus: 'Show the next month', // Status text for next month link
76		nextBigText: '&#x3e;&#x3e;', // Display text for next year link
77		nextBigStatus: 'Show the next year', // Status text for next year link
78		currentText: 'Today', // Display text for current month link
79		currentStatus: 'Show the current month', // Status text for current month link
80		monthNames: ['January','February','March','April','May','June',
81			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
82		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
83		monthStatus: 'Show a different month', // Status text for selecting a month
84		yearStatus: 'Show a different year', // Status text for selecting a year
85		weekHeader: 'Wk', // Header for the week of the year column
86		weekStatus: 'Week of the year', // Status text for the week of the year column
87		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
88		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
89		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
90		dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
91		dateStatus: 'Select DD, M d', // Status text for the date selection
92		dateFormat: 'mm/dd/yy', // See format options on parseDate
93		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
94		initStatus: 'Select a date', // Initial Status text on opening
95		isRTL: false, // True if right-to-left language, false if left-to-right
96		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
97		yearSuffix: '' // Additional text to append to the year in the month headers
98	};
99	this._defaults = { // Global defaults for all the date picker instances
100		wpbc_resource_id: 0, // ID of booking resource - customization	// FixIn: 9.4.4.13.
101		useThemeRoller: false, // True to apply ThemeRoller styling, false for default styling
102		showOn: 'focus', // 'focus' for popup on focus,
103			// 'button' for trigger button, or 'both' for either
104		showAnim: 'show', // Name of jQuery animation for popup
105		showOptions: {}, // Options for enhanced animations
106		duration: 'normal', // Duration of display/closure
107		buttonText: '...', // Text for trigger button
108		buttonImage: '', // URL for trigger button image
109		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
110		alignment: 'bottom', // Alignment of popup - with nominated corner of input:
111			// 'top' or 'bottom' aligns depending on language direction,
112			// 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'
113		autoSize: false, // True to size the input for the date format, false to leave as is
114		defaultDate: null, // Used when field is blank: actual date,
115			// +/-number for offset from today, null for today
116		showDefault: false, // True to populate field with the default date
117		appendText: '', // Display text following the input box, e.g. showing the format
118		closeAtTop: true, // True to have the clear/close at the top,
119			// false to have them at the bottom
120		mandatory: false, // True to hide the Clear link, false to include it
121		hideIfNoPrevNext: false, // True to hide next/previous month links
122			// if not applicable, false to just disable them
123		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
124		showBigPrevNext: false, // True to show big prev/next links
125		stepMonths: 1, // Number of months to step back/forward
126		stepBigMonths: 12, // Number of months to step back/forward for the big links
127		gotoCurrent: false, // True if today link goes back to current selection instead
128		changeMonth: true, // True if month can be selected directly, false if only prev/next
129		changeYear: true, // True if year can be selected directly, false if only prev/next
130		yearRange: '-10:+10', // Range of years to display in drop-down,
131			// either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
132		changeFirstDay: false, // True to click on day name to change, false to remain as set
133		showOtherMonths: false, // True to show dates in other months, false to leave blank
134		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
135		highlightWeek: false, // True to highlight the selected week
136		showWeeks: false, // True to show week of the year, false to omit
137		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
138			// takes a Date and returns the number of the week for it
139		shortYearCutoff: '+10', // Short year values < this are in the current century,
140			// > this are in the previous century, string value starting with '+'
141			// for current year + value, -1 for no change
142		showStatus: false, // True to show status bar at bottom, false to not show it
143		statusForDate: this.dateStatus, // Function to provide status text for a date -
144			// takes date and instance as parameters, returns display text
145		minDate: null, // The earliest selectable date, or null for no limit
146		maxDate: null, // The latest selectable date, or null for no limit
147		numberOfMonths: 1, // Number of months to show at a time
148		showCurrentAtPos: 0, // The position in multiple months at which to show the current month (starting at 0)
149		rangeSelect: false, // Allows for selecting a date range on one date picker
150		rangeSeparator: ' - ', // Text between two dates in a range
151		multiSelect: 0, // Maximum number of selectable dates
152		multiSeparator: ',', // Text between multiple dates
153		beforeShow: null, // Function that takes an input field and
154			// returns a set of custom settings for the date picker
155		beforeShowDay: null, // Function that takes a date and returns an array with
156			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
157			// [2] = cell title (optional), e.g. $.datepick.noWeekends
158		onChangeMonthYear: null, // Define a callback function when the month or year is changed
159		onHover: null, // Define a callback function when hovering over a day
160		onSelect: null, // Define a callback function when a date is selected
161		onClose: null, // Define a callback function when the datepicker is closed
162		altField: '', // Selector for an alternate field to store selected dates into
163		altFormat: '', // The date format to use for the alternate field
164		constrainInput: true // The input is constrained by the current date format
165	};
166	$.extend(this._defaults, this.regional['']);
167	this.dpDiv = $('<div style="display: none;"></div>');
168}
169
170$.extend(Datepick.prototype, {
171	version: '3.7.0', // Current version
172
173	/* Class name added to elements to indicate already configured with a date picker. */
174	markerClassName: 'hasDatepick', // Responsive Skin
175
176	// Class/id names for default and ThemeRoller stylings
177	_mainDivId: ['datepick-div', 'ui-datepicker-div'], // The main datepicker division
178	_mainDivClass: ['', 'ui-datepicker ' +
179		'ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'], // Popup class
180	_inlineClass: ['datepick-inline', 'ui-datepicker-inline ui-datepicker ' +
181		'ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'], // Inline class
182	_multiClass: ['datepick-multi', 'ui-datepicker-multi'], // Multi-month class
183	_rtlClass: ['datepick-rtl', 'ui-datepicker-rtl'], // Right-to-left class
184	_appendClass: ['datepick-append', 'ui-datepicker-append'], // Append text class
185	_triggerClass: ['datepick-trigger', 'ui-datepicker-trigger'], // Trigger class
186	_dialogClass: ['datepick-dialog', 'ui-datepicker-dialog'], // Dialog class
187	_promptClass: ['datepick-prompt', 'ui-datepicker-prompt'], // Dialog prompt class
188	_disableClass: ['datepick-disabled', 'ui-datepicker-disabled'], // Disabled covering class
189	_controlClass: ['datepick-control', 'ui-datepicker-header ' +
190		'ui-widget-header ui-helper-clearfix ui-corner-all'], // Control bar class
191	_clearClass: ['datepick-clear', 'ui-datepicker-clear'], // Clear class
192	_closeClass: ['datepick-close', 'ui-datepicker-close'], // Close class
193	_linksClass: ['datepick-links', 'ui-datepicker-header ' +
194		'ui-widget-header ui-helper-clearfix ui-corner-all'], // Links bar class
195	_prevClass: ['datepick-prev', 'ui-datepicker-prev'], // Previous class
196	_nextClass: ['datepick-next', 'ui-datepicker-next'], // Next class
197	_currentClass: ['datepick-current', 'ui-datepicker-current'], // Current class
198	_oneMonthClass: ['datepick-one-month', 'ui-datepicker-group'], // Single month class
199	_newRowClass: ['datepick-new-row', 'ui-datepicker-row-break'], // New month row class
200	_monthYearClass: ['datepick-header', 'ui-datepicker-header ' +
201		'ui-widget-header ui-helper-clearfix ui-corner-all'], // Month/year header class
202	_monthSelectClass: ['datepick-new-month', 'ui-datepicker-month'], // Month select class
203	_monthClass: ['', 'ui-datepicker-month'], // Month text class
204	_yearSelectClass: ['datepick-new-year', 'ui-datepicker-year'], // Year select class
205	_yearClass: ['', 'ui-datepicker-year'], // Year text class
206	_tableClass: ['datepick wpbc_calendar', 'ui-datepicker-calendar'], // Month table class		// FixIn: 9.7.3.7
207	_tableHeaderClass: ['datepick-title-row', ''], // Week header class
208	_weekColClass: ['datepick-week-col', 'ui-datepicker-week-col'], // Week number column class
209	_weekRowClass: ['datepick-days-row', ''], // Week row class
210	_weekendClass: ['datepick-week-end-cell', 'ui-datepicker-week-end'], // Weekend class
211	_dayClass: ['datepick-days-cell', ''], // Single day class
212	_otherMonthClass: ['datepick-other-month', 'ui-datepicker-other-month'], // Other month class
213	_todayClass: ['datepick-today', 'ui-state-highlight'], // Today class
214	_selectableClass: ['', 'ui-state-default'], // Selectable cell class
215	_unselectableClass: ['datepick-unselectable',
216		'ui-datepicker-unselectable ui-state-disabled'], // Unselectable cell class
217	_selectedClass: ['datepick-current-day', 'ui-state-active'], // Selected day class
218	_dayOverClass: ['datepick-days-cell-over', 'ui-state-hover'], // Day hover class
219	_weekOverClass: ['datepick-week-over', 'ui-state-hover'], // Week hover class
220	_statusClass: ['datepick-status', 'ui-datepicker-status'], // Status bar class
221	_statusId: ['datepick-status-', 'ui-datepicker-status-'], // Status bar ID prefix
222	_coverClass: ['datepick-cover', 'ui-datepicker-cover'], // IE6- iframe class
223
224	/* Override the default settings for all instances of the date picker.
225	   @param  settings  (object) the new settings to use as defaults (anonymous object)
226	   @return  (Datepick) the manager object */
227	setDefaults: function(settings) {
228		extendRemove(this._defaults, settings || {});
229		return this;
230	},
231
232	/* Attach the date picker to a jQuery selection.
233	   @param  target    (element) the target input field or division or span
234	   @param  settings  (object) the new settings to use for this date picker instance */
235	_attachDatepick: function(target, settings) {
236		if (!target.id)
237			target.id = 'dp' + (++this._uuid);
238		var nodeName = target.nodeName.toLowerCase();
239		var inst = this._newInst($(target), (nodeName == 'div' || nodeName == 'span'));
240		// Check for settings on the control itself
241		var inlineSettings = ($.fn.metadata ? $(target).metadata() : {});
242		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
243		this._adjustInstDate(inst);	// FixIn: Adjust cursor date (currently  rendering Month,  if we define the minDate in the future !!!  // FixIn: 10.13.1.4.
244		if (inst.inline) {
245			inst.dpDiv.addClass(this._inlineClass[
246				this._get(inst, 'useThemeRoller') ? 1 : 0]);
247			this._inlineDatepick(target, inst);
248		}
249		else
250			this._connectDatepick(target, inst);
251	},
252
253	/* Create a new instance object.
254	   @param  target  (jQuery) the target input field or division or span
255	   @param  inline  (boolean) true if this datepicker appears inline */
256	_newInst: function(target, inline) {
257		var id = target[0].id.replace(/([:\[\]\.\$])/g, '\\\\$1'); // Escape jQuery meta chars
258		return {id: id, input: target, // Associated target
259			cursorDate: this._daylightSavingAdjust(new Date()), // Current position
260			drawMonth: 0, drawYear: 0, // Month being drawn
261			dates: [], // Selected dates
262			inline: inline, // Is datepicker inline or not
263			dpDiv: (!inline ? this.dpDiv : $('<div></div>')), // presentation div
264			siblings: $([])}; // Created siblings (trigger/append)
265	},
266
267	/* Attach the date picker to an input field.
268	   @param  target  (element) the target input field or division or span
269	   @param  inst    (object) the instance settings for this datepicker */
270	_connectDatepick: function(target, inst) {
271		var input = $(target);
272		if (input.hasClass(this.markerClassName))
273			return;
274		var appendText = this._get(inst, 'appendText');
275		var isRTL = this._get(inst, 'isRTL');
276		var useTR = this._get(inst, 'useThemeRoller') ? 1 : 0;
277		if (appendText) {
278			var append = $('<span class="' + this._appendClass[useTR] + '">' + appendText + '</span>');
279			input[isRTL ? 'before' : 'after'](append);
280			inst.siblings = inst.siblings.add(append);
281		}
282		var showOn = this._get(inst, 'showOn');
283		if (showOn == 'focus' || showOn == 'both') // Pop-up date picker when in the marked field
284			input.on('focus.wpbc_datepick', this._showDatepick);			// FixIn: 10.0.0.45.
285		if (showOn == 'button' || showOn == 'both') { // Pop-up date picker when button clicked
286			var buttonText = this._get(inst, 'buttonText');
287			var buttonImage = this._get(inst, 'buttonImage');
288			var trigger = $(this._get(inst, 'buttonImageOnly') ?
289				$('<img/>').addClass(this._triggerClass[useTR]).
290					attr({src: buttonImage, alt: buttonText, title: buttonText}) :
291				$('<button type="button"></button>').addClass(this._triggerClass[useTR]).
292					html(buttonImage == '' ? buttonText : $('<img/>').attr(
293					{src: buttonImage, alt: buttonText, title: buttonText})));
294			input[isRTL ? 'before' : 'after'](trigger);
295			inst.siblings = inst.siblings.add(trigger);
296			// FixIn: 8.7.11.12.
297			trigger.on( 'click', function (){
298				if ($.datepick._datepickerShowing && $.datepick._lastInput == target)
299					$.datepick._hideDatepick();
300				else
301					$.datepick._showDatepick(target);
302				return false;
303			});
304		}
305		input.addClass( this.markerClassName ).on( 'keydown.wpbc_datepick', this._doKeyDown ).on( 'keypress.wpbc_datepick', this._doKeyPress ).on( 'keyup.wpbc_datepick', this._doKeyUp );	//FixIn: 10.0.0.45	// FixIn: 8.7.11.12.
306		if (this._get(inst, 'showDefault') && !inst.input.val()) {
307			inst.dates = [this._getDefaultDate(inst)];
308			this._showDate(inst);
309		}
310		this._autoSize(inst);
311		$.data(target, PROP_NAME, inst);
312	},
313
314	/* Apply the maximum length for the date format.
315	   @param  inst  (object) the instance settings for this datepicker */
316	_autoSize: function(inst) {
317		if (this._get(inst, 'autoSize') && !inst.inline) {
318			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
319			var dateFormat = this._get(inst, 'dateFormat');
320			if (dateFormat.match(/[DM]/)) {
321				var findMax = function(names) {
322					var max = 0;
323					var maxI = 0;
324					for (var i = 0; i < names.length; i++) {
325						if (names[i].length > max) {
326							max = names[i].length;
327							maxI = i;
328						}
329					}
330					return maxI;
331				};
332				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
333					'monthNames' : 'monthNamesShort'))));
334				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
335					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
336			}
337			inst.input.attr('size', this._formatDate(inst, date).length);
338		}
339	},
340
341	/* Attach an inline date picker to a div.
342	   @param  target  (element) the target input field or division or span
343	   @param  inst    (object) the instance settings for this datepicker */
344	_inlineDatepick: function(target, inst) {
345		var divSpan = $(target);
346		if (divSpan.hasClass(this.markerClassName))
347			return;
348		divSpan.addClass(this.markerClassName);
349		$.data(target, PROP_NAME, inst);
350		inst.drawMonth = inst.cursorDate.getMonth();
351		inst.drawYear = inst.cursorDate.getFullYear();
352		$('body').append(inst.dpDiv);
353		this._updateDatepick(inst);
354		// Fix width for dynamic number of date pickers
355		/* // FixIn: 9.7.3.4
356		   // Commented below 3 lines to  not include width into <div class="datepick-inline datepick-multi" style="width: 4428px;">
357		 inst.dpDiv.width(this._getNumberOfMonths(inst)[1] *
358		 		$('.' + this._oneMonthClass[this._get(inst, 'useThemeRoller') ? 1 : 0],
359		 		inst.dpDiv)[0].offsetWidth);
360		 */
361		divSpan.append(inst.dpDiv);
362		this._updateAlternate(inst);
363
364		// FixIn: 9.4.4.13.
365		var resource_id = parseInt( divSpan.get( 0 ).getAttribute( 'id' ).replace( 'calendar_booking', '' ) );
366		inst.settings.wpbc_resource_id = resource_id;  		// To get this property use: 	this._get(inst, 'wpbc_resource_id')
367
368		// FixIn: 9.4.4.12.
369		$( 'body' ).trigger(
370							  'wpbc_datepick_inline_calendar_loaded'													// event name
371							, [
372								  divSpan.get( 0 ).getAttribute( 'id' ).replace( 'calendar_booking', '' )				// Resource ID	-	'1'
373								, divSpan																				// jQuery( '#calendar_booking1' )
374								, inst 																					// datepick Obj
375							  ]
376							);
377		// To catch this event: jQuery( 'body' ).on('wpbc_datepick_inline_calendar_loaded', function( event, resource_id, jCalContainer, inst ) { ... } );
378		//FixIn End: 9.4.4.12
379	},
380
381	/* Pop-up the date picker in a "dialog" box.
382	   @param  input     (element) ignored
383	   @param  date      (string or Date) the initial date to display
384	   @param  onSelect  (function) the function to call when a date is selected
385	   @param  settings  (object) update the dialog date picker instance's settings
386	   @param  pos       (int[2]) coordinates for the dialog's position within the screen or
387	                     (event) with x/y coordinates or
388	                     leave empty for default (screen centre) */
389	_dialogDatepick: function(input, date, onSelect, settings, pos) {
390		var inst = this._dialogInst; // Internal instance
391		if (!inst) {
392			var id = 'dp' + (++this._uuid);
393			this._dialogInput = $('<input type="text" id="' + id +
394				'" style="position: absolute; width: 1px; z-index: -1"/>');
395			this._dialogInput.on( 'keydown.wpbc_datepick', this._doKeyDown);		// FixIn: 10.0.0.45.
396			$('body').append(this._dialogInput);
397			inst = this._dialogInst = this._newInst(this._dialogInput, false);
398			inst.settings = {};
399			$.data(this._dialogInput[0], PROP_NAME, inst);
400		}
401		extendRemove(inst.settings, settings || {});
402		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
403		this._dialogInput.val(date);
404		this._pos = (pos ? (isArray(pos) ? pos : [pos.pageX, pos.pageY]) : null);
405		if (!this._pos) {
406			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
407			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
408			this._pos = // Should use actual width/height below
409				[(document.documentElement.clientWidth / 2) - 100 + scrollX,
410				(document.documentElement.clientHeight / 2) - 150 + scrollY];
411		}
412
413		// Move input on screen for focus, but hidden behind dialog
414		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
415		inst.settings.onSelect = onSelect;
416		this._inDialog = true;
417		this.dpDiv.addClass(this._dialogClass[this._get(inst, 'useThemeRoller') ? 1 : 0]);
418		this._showDatepick(this._dialogInput[0]);
419		if ($.blockUI)
420			$.blockUI(this.dpDiv);
421		$.data(this._dialogInput[0], PROP_NAME, inst);
422	},
423
424	/* Detach a datepicker from its control.
425	   @param  target  (element) the target input field or division or span */
426	_destroyDatepick: function(target) {
427		var $target = $(target);
428		if (!$target.hasClass(this.markerClassName)) {
429			return;
430		}
431		var inst = $.data(target, PROP_NAME);
432		$.removeData(target, PROP_NAME);
433		if (inst.inline)
434			$target.removeClass(this.markerClassName).empty();
435		else {
436			$(inst.siblings).remove();
437			//$target.removeClass(this.markerClassName).unbind('focus', this._showDatepick).unbind('keydown', this._doKeyDown).unbind('keypress', this._doKeyPress).unbind('keyup', this._doKeyUp);	// FixIn: 10.0.0.45.
438			//$target.removeClass(this.markerClassName).off('focus', this._showDatepick).off('keydown', this._doKeyDown).off('keypress', this._doKeyPress).off('keyup', this._doKeyUp);				// FixIn: 10.0.0.45.
439			$target.removeClass( this.markerClassName ).off( 'focus.wpbc_datepick' ).off( 'keydown.wpbc_datepick' ).off( 'keypress.wpbc_datepick' ).off( 'keyup.wpbc_datepick' );					// FixIn: 10.0.0.45.
440		}
441	},
442
443	/* Enable the date picker to a jQuery selection.
444	   @param  target  (element) the target input field or division or span */
445	_enableDatepick: function(target) {
446		var $target = $(target);
447		if (!$target.hasClass(this.markerClassName))
448			return;
449		var inst = $.data(target, PROP_NAME);
450		var useTR = this._get(inst, 'useThemeRoller') ? 1 : 0;
451		if (inst.inline)
452			$target.children('.' + this._disableClass[useTR]).remove().end().
453				find('select').attr('disabled', '');
454		else {
455			target.disabled = false;
456			inst.siblings.filter('button.' + this._triggerClass[useTR]).
457				each(function() { this.disabled = false; }).end().
458				filter('img.' + this._triggerClass[useTR]).
459				css({opacity: '1.0', cursor: ''});
460		}
461		this._disabledInputs = $.map(this._disabledInputs,
462			function(value) { return (value == target ? null : value); }); // Delete entry
463	},
464
465	/* Disable the date picker to a jQuery selection.
466	   @param  target  (element) the target input field or division or span */
467	_disableDatepick: function(target) {
468		var $target = $(target);
469		if (!$target.hasClass(this.markerClassName))
470			return;
471		var inst = $.data(target, PROP_NAME);
472		var useTR = this._get(inst, 'useThemeRoller') ? 1 : 0;
473		if (inst.inline) {
474			var inline = $target.children('.' + this._inlineClass[useTR]);
475			var offset = inline.offset();
476			var relOffset = {left: 0, top: 0};
477			inline.parents().each(function() {
478				if ($(this).css('position') == 'relative') {
479					relOffset = $(this).offset();
480					return false;
481				}
482			});
483			$target.prepend('<div class="' + this._disableClass[useTR] + '" style="' +
484				'width: ' + inline.width() + 'px; height: ' + inline.height() +
485				'px; left: ' + (offset.left - relOffset.left) +
486				'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>').
487				find('select').attr('disabled', 'disabled');
488		}
489		else {
490			target.disabled = true;
491			inst.siblings.filter('button.' + this._triggerClass[useTR]).
492				each(function() { this.disabled = true; }).end().
493				filter('img.' + this._triggerClass[useTR]).
494				css({opacity: '0.5', cursor: 'default'});
495		}
496		this._disabledInputs = $.map(this._disabledInputs,
497			function(value) { return (value == target ? null : value); }); // Delete entry
498		this._disabledInputs.push(target);
499	},
500
501	/* Is the first field in a jQuery collection disabled as a datepicker?
502	   @param  target  (element) the target input field or division or span
503	   @return  (boolean) true if disabled, false if enabled */
504	_isDisabledDatepick: function(target) {
505		return (!target ? false : $.inArray(target, this._disabledInputs) > -1);
506	},
507
508	/* Retrieve the instance data for the target control.
509	   @param  target  (element) the target input field or division or span
510	   @return  (object) the associated instance data
511	   @throws  error if a jQuery problem getting data */
512	_getInst: function(target) {//alert(target.id);
513		try {
514			return $.data(target, PROP_NAME);
515		}
516		catch (err) {
517			throw 'Missing instance data for this datepicker';
518		}
519	},
520
521	/* Update or retrieve the settings for a date picker attached to an input field or division.
522	   @param  target  (element) the target input field or division or span
523	   @param  name    (object) the new settings to update or
524	                   (string) the name of the setting to change or retrieve,
525	                   when retrieving also 'all' for all instance settings or
526	                   'defaults' for all global defaults
527	   @param  value   (any) the new value for the setting
528	                   (omit if above is an object or to retrieve value) */
529	_optionDatepick: function(target, name, value) {
530		var inst = this._getInst(target);
531		if (arguments.length == 2 && typeof name == 'string') {
532			return (name == 'defaults' ? $.extend({}, $.datepick._defaults) :
533				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
534				this._get(inst, name)) : null));
535		}
536		var settings = name || {};
537		if (typeof name == 'string') {
538			settings = {};
539			settings[name] = value;
540		}
541		if (inst) {
542			if (this._curInst == inst) {
543				this._hideDatepick(null);
544			}
545			var dates = this._getDateDatepick(target);
546			extendRemove(inst.settings, settings);
547			this._autoSize(inst);
548			extendRemove(inst, {dates: []});
549			var blank = (!dates || isArray(dates));
550			if (isArray(dates))
551				for (var i = 0; i < dates.length; i++)
552					if (dates[i]) {
553						blank = false;
554						break;
555					}
556			if (!blank)
557				this._setDateDatepick(target, dates);
558			if (inst.inline)
559				$(target).children('div').removeClass(this._inlineClass.join(' ')).
560					addClass(this._inlineClass[this._get(inst, 'useThemeRoller') ? 1 : 0]);
561			this._updateDatepick(inst);
562		}
563	},
564
565	// Change method deprecated
566	_changeDatepick: function(target, name, value) {
567		this._optionDatepick(target, name, value);
568	},
569
570	/* Redraw the date picker attached to an input field or division.
571	   @param  target  (element) the target input field or division or span */
572	_refreshDatepick: function(target) {
573		var inst = this._getInst(target);
574		if (inst) {
575			this._updateDatepick(inst);
576		}
577	},
578
579	/* Set the dates for a jQuery selection.
580	   @param  target   (element) the target input field or division or span
581	   @param  date     (Date) the new date
582	   @param  endDate  (Date) the new end date for a range (optional) */
583	_setDateDatepick: function(target, date, endDate) {
584		var inst = this._getInst(target);
585		if (inst) {
586			this._setDate(inst, date, endDate);
587			this._updateDatepick(inst);
588			this._updateAlternate(inst);
589		}
590	},
591
592	/* Get the date(s) for the first entry in a jQuery selection.
593	   @param  target  (element) the target input field or division or span
594	   @return (Date) the current date or
595	           (Date[2]) the current dates for a range */
596	_getDateDatepick: function(target) {
597		var inst = this._getInst(target);
598		if (inst && !inst.inline)
599			this._setDateFromField(inst);
600		return (inst ? this._getDate(inst) : null);
601	},
602
603	/* Handle keystrokes.
604	   @param  event  (KeyEvent) the keystroke details
605	   @return  (boolean) true to continue, false to discard */
606	_doKeyDown: function(event) {
607		var inst = $.datepick._getInst(event.target);
608		inst.keyEvent = true;
609		var handled = true;
610		var isRTL = $.datepick._get(inst, 'isRTL');
611		var useTR = $.datepick._get(inst, 'useThemeRoller') ? 1 : 0;
612		if ($.datepick._datepickerShowing)
613			switch (event.keyCode) {
614				case 9:  $.datepick._hideDatepick(null, '');
615						break; // Hide on tab out
616				case 13: var sel = $('td.' + $.datepick._dayOverClass[useTR], inst.dpDiv);
617						if (sel.length == 0)
618							sel = $('td.' + $.datepick._selectedClass[useTR] + ':first', inst.dpDiv);
619						if (sel[0])
620							$.datepick._selectDay(sel[0], event.target, inst.cursorDate.getTime());
621						else
622							$.datepick._hideDatepick(null, $.datepick._get(inst, 'duration'));
623						break; // Select the value on enter
624				case 27: $.datepick._hideDatepick(null, $.datepick._get(inst, 'duration'));
625						break; // Hide on escape
626				case 33: $.datepick._adjustDate(event.target, (event.ctrlKey ?
627							-$.datepick._get(inst, 'stepBigMonths') :
628							-$.datepick._get(inst, 'stepMonths')), 'M');
629						break; // Previous month/year on page up/+ ctrl
630				case 34: $.datepick._adjustDate(event.target, (event.ctrlKey ?
631							+$.datepick._get(inst, 'stepBigMonths') :
632							+$.datepick._get(inst, 'stepMonths')), 'M');
633						break; // Next month/year on page down/+ ctrl
634				case 35: if (event.ctrlKey || event.metaKey)
635							$.datepick._clearDate(event.target);
636						handled = event.ctrlKey || event.metaKey;
637						break; // Clear on ctrl or command + end
638				case 36: if (event.ctrlKey || event.metaKey)
639							$.datepick._gotoToday(event.target);
640						handled = event.ctrlKey || event.metaKey;
641						break; // Current on ctrl or command + home
642				case 37: if (event.ctrlKey || event.metaKey)
643							$.datepick._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
644						handled = event.ctrlKey || event.metaKey;
645						// -1 day on ctrl or command + left
646						if (event.originalEvent.altKey)
647							$.datepick._adjustDate(event.target,
648								(event.ctrlKey ? -$.datepick._get(inst, 'stepBigMonths') :
649								-$.datepick._get(inst, 'stepMonths')), 'M');
650						// Next month/year on alt + left/+ ctrl
651						break;
652				case 38: if (event.ctrlKey || event.metaKey)
653							$.datepick._adjustDate(event.target, -7, 'D');
654						handled = event.ctrlKey || event.metaKey;
655						break; // -1 week on ctrl or command + up
656				case 39: if (event.ctrlKey || event.metaKey)
657							$.datepick._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
658						handled = event.ctrlKey || event.metaKey;
659						// +1 day on ctrl or command + right
660						if (event.originalEvent.altKey)
661							$.datepick._adjustDate(event.target,
662								(event.ctrlKey ? +$.datepick._get(inst, 'stepBigMonths') :
663								+$.datepick._get(inst, 'stepMonths')), 'M');
664						// Next month/year on alt + right/+ ctrl
665						break;
666				case 40: if (event.ctrlKey || event.metaKey)
667							$.datepick._adjustDate(event.target, +7, 'D');
668						handled = event.ctrlKey || event.metaKey;
669						break; // +1 week on ctrl or command + down
670				default: handled = false;
671			}
672		else if (event.keyCode == 36 && event.ctrlKey) // Display the date picker on ctrl+home
673			$.datepick._showDatepick(this);
674		else
675			handled = false;
676		if (handled) {
677			event.preventDefault();
678			event.stopPropagation();
679		}
680		inst.ctrlKey = (event.keyCode < 48);
681		return !handled;
682	},
683
684	/* Filter entered characters - based on date format.
685	   @param  event  (KeyEvent) the keystroke details
686	   @return  (boolean) true to continue, false to discard */
687	_doKeyPress: function(event) {
688		var inst = $.datepick._getInst(event.target);
689		if ($.datepick._get(inst, 'constrainInput')) {
690			var chars = $.datepick._possibleChars(inst);
691			var chr = String.fromCharCode(event.keyCode || event.charCode);
692			return inst.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
693		}
694	},
695
696	/* Synchronise manual entry and field/alternate field.
697	   @param  event  (KeyEvent) the keystroke details
698	   @return  (boolean) true to continue */
699	_doKeyUp: function(event) {
700		var inst = $.datepick._getInst(event.target);
701		if (inst.input.val() != inst.lastVal) {
702			try {
703				var separator = ($.datepick._get(inst, 'rangeSelect') ?
704					$.datepick._get(inst, 'rangeSeparator') :
705					($.datepick._get(inst, 'multiSelect') ?
706					$.datepick._get(inst, 'multiSeparator') : ''));
707				var dates = (inst.input ? inst.input.val() : '');
708				dates = (separator ? dates.split(separator) : [dates]);
709				var ok = true;
710				for (var i = 0; i < dates.length; i++) {
711					if (!$.datepick.parseDate($.datepick._get(inst, 'dateFormat'),
712							dates[i], $.datepick._getFormatConfig(inst))) {
713						ok = false;
714						break;
715					}
716				}
717				if (ok) { // Only if valid
718					$.datepick._setDateFromField(inst);
719					$.datepick._updateAlternate(inst);
720					$.datepick._updateDatepick(inst);
721				}
722			}
723			catch (event) {
724				// Ignore
725			}
726		}
727		return true;
728	},
729
730	/* Extract all possible characters from the date format.
731	   @param  inst  (object) the instance settings for this datepicker
732	   @return  (string) the set of characters allowed by this format */
733	_possibleChars: function (inst) {
734		var dateFormat = $.datepick._get(inst, 'dateFormat');
735		var chars = ($.datepick._get(inst, 'rangeSelect') ?
736			$.datepick._get(inst, 'rangeSeparator') :
737			($.datepick._get(inst, 'multiSelect') ?
738			$.datepick._get(inst, 'multiSeparator') : ''));
739		var literal = false;
740		for (var iFormat = 0; iFormat < dateFormat.length; iFormat++)
741			if (literal)
742				if (dateFormat.charAt(iFormat) == "'" && !lookAhead("'"))
743					literal = false;
744				else
745					chars += dateFormat.charAt(iFormat);
746			else
747				switch (dateFormat.charAt(iFormat)) {
748					case 'd': case 'm': case 'y': case '@':
749						chars += '0123456789';
750						break;
751					case 'D': case 'M':
752						return null; // Accept anything
753					case "'":
754						if (lookAhead("'"))
755							chars += "'";
756						else
757							literal = true;
758						break;
759					default:
760						chars += dateFormat.charAt(iFormat);
761				}
762		return chars;
763	},
764
765	/* Update the datepicker when hovering over a date.
766	   @param  td         (element) the current cell
767	   @param  id         (string) the ID of the datepicker instance
768	   @param  timestamp  (number) the timestamp for this date */
769	_doMouseOver: function(td, id, timestamp) {
770		var inst = $.datepick._getInst($('#' + id)[0]);
771		var useTR = $.datepick._get(inst, 'useThemeRoller') ? 1 : 0;
772		if ( $( td ).find( 'a' ).length )																				//FixIn: 2023-08-06
773			$(td).parents('tbody').find('td').
774				removeClass($.datepick._dayOverClass[useTR]).end().end().
775				addClass($.datepick._dayOverClass[useTR]);
776		if ($.datepick._get(inst, 'highlightWeek'))
777			$(td).parent().parent().find('tr').
778				removeClass($.datepick._weekOverClass[useTR]).end().end().
779				addClass($.datepick._weekOverClass[useTR]);
780		if ($(td).text()) {
781			var date = new Date(timestamp);
782			if ($.datepick._get(inst, 'showStatus')) {
783				var status = ($.datepick._get(inst, 'statusForDate').apply(
784					(inst.input ? inst.input[0] : null), [date, inst]) ||
785					$.datepick._get(inst, 'initStatus'));
786				$('#' + $.datepick._statusId[useTR] + id).html(status);
787			}
788			if ($.datepick._get(inst, 'onHover'))
789				$.datepick._doHover(td, '#' + id, date.getFullYear(), date.getMonth());
790		}
791	},
792
793	/* Update the datepicker when no longer hovering over a date.
794	   @param  td  (element) the current cell
795	   @param  id  (string) the ID of the datepicker instance */
796	_doMouseOut: function(td, id) {
797		var inst = $.datepick._getInst($('#' + id)[0]);
798		var useTR = $.datepick._get(inst, 'useThemeRoller') ? 1 : 0;
799		$(td).removeClass($.datepick._dayOverClass[useTR]).
800			removeClass($.datepick._weekOverClass[useTR]);
801		if ($.datepick._get(inst, 'showStatus'))
802			$('#' + $.datepick._statusId[useTR] + id).html($.datepick._get(inst, 'initStatus'));
803		if ($.datepick._get(inst, 'onHover'))
804			$.datepick._doHover(td, '#' + id);
805	},
806
807	/* Hover over a particular day.
808	   @param  td     (element) the table cell containing the selection
809	   @param  id     (string) the ID of the target field
810	   @param  year   (number) the year for this day
811	   @param  month  (number) the month for this day */
812	_doHover: function(td, id, year, month) {
813		var inst = this._getInst($(id)[0]);
814		var useTR = $.datepick._get(inst, 'useThemeRoller') ? 1 : 0;
815		//if ($(td).hasClass(this._unselectableClass[useTR]))
816		//	return;
817		var onHover = this._get(inst, 'onHover');
818		//FixIn: 2023-08-06
819		var temp_daylight_day = ( $( td ).find( 'a' ).length) ? new Date( year, month, $( td ).find( 'a' ).text() ) : null;
820		temp_daylight_day = ( ( null === temp_daylight_day ) && ( $( td ).find( 'span' ).length ) ) ? new Date( year, month, $( td ).find( 'span' ).text() ) : temp_daylight_day;
821
822		var date = (year ?
823//			this._daylightSavingAdjust(new Date(year, month, $(td).find('a').text())) : null);							//FixIn: 2023-08-06
824			this._daylightSavingAdjust( temp_daylight_day ) : null);													//FixIn: 2023-08-06
825		onHover.apply((inst.input ? inst.input[0] : null),
826			[(date ? this._formatDate(inst, date) : ''), date, inst]);
827	},
828
829	/* Pop-up the date picker for a given input field.
830	   @param  input  (element) the input field attached to the date picker or
831	                  (event) if triggered by focus */
832	_showDatepick: function(input) {
833		input = input.target || input;
834		if ($.datepick._isDisabledDatepick(input) || $.datepick._lastInput == input) // Already here
835			return;
836		var inst = $.datepick._getInst(input);
837		var beforeShow = $.datepick._get(inst, 'beforeShow');
838		var useTR = $.datepick._get(inst, 'useThemeRoller') ? 1 : 0;
839		extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
840		$.datepick._hideDatepick(null, '');
841		$.datepick._lastInput = input;
842		$.datepick._setDateFromField(inst);
843		if ($.datepick._inDialog) // Hide cursor
844			input.value = '';
845		if (!$.datepick._pos) { // Position below input
846			$.datepick._pos = $.datepick._findPos(input);
847			$.datepick._pos[1] += input.offsetHeight; // Add the height
848		}
849		var isFixed = false;
850		$(input).parents().each(function() {
851			isFixed |= $(this).css('position') == 'fixed';
852			return !isFixed;
853		});
854		if (isFixed && $.browser_is_supported_datepick.opera) { // Correction for Opera when fixed and scrolled
855			$.datepick._pos[0] -= document.documentElement.scrollLeft;
856			$.datepick._pos[1] -= document.documentElement.scrollTop;
857		}
858		var offset = {left: $.datepick._pos[0], top: $.datepick._pos[1]};
859		$.datepick._pos = null;
860		// Determine sizing offscreen
861		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
862		$.datepick._updateDatepick(inst);
863		// Fix width for dynamic number of date pickers
864		inst.dpDiv.width($.datepick._getNumberOfMonths(inst)[1] *
865			$('.' + $.datepick._oneMonthClass[useTR], inst.dpDiv).width());
866		// And adjust position before showing
867		offset = $.datepick._checkOffset(inst, offset, isFixed);
868		inst.dpDiv.css({position: ($.datepick._inDialog && $.blockUI ?
869			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
870			left: offset.left + 'px', top: offset.top + 'px'});
871		if (!inst.inline) {
872			var showAnim = $.datepick._get(inst, 'showAnim') || 'show';
873			var duration = $.datepick._get(inst, 'duration');
874			var postProcess = function() {
875				$.datepick._datepickerShowing = true;
876				var borders = $.datepick._getBorders(inst.dpDiv);
877				inst.dpDiv.find('iframe.' + $.datepick._coverClass[useTR]). // IE6- only
878					css({left: -borders[0], top: -borders[1],
879						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
880			};
881			if ($.effects && $.effects[showAnim])
882				inst.dpDiv.show(showAnim, $.datepick._get(inst, 'showOptions'), duration, postProcess);
883			else
884				inst.dpDiv[showAnim](duration, postProcess);
885			if (duration == '')
886				postProcess();
887			if (inst.input[0].type != 'hidden')
888			    $( inst.input ).trigger( 'focus' );		// FixIn: 8.7.11.12.
889			$.datepick._curInst = inst;
890		}
891	},
892
893	/* Generate the date picker content.
894	   @param  inst  (object) the instance settings for this datepicker */
895	_updateDatepick: function(inst) {
896		if ( null === inst ) {
897			return;
898		}
899		var borders = this._getBorders(inst.dpDiv);
900		var useTR = this._get(inst, 'useThemeRoller') ? 1 : 0;
901		inst.dpDiv.empty().append(this._generateHTML(inst)).
902			find('iframe.' + this._coverClass[useTR]). // IE6- only
903			css({left: -borders[0], top: -borders[1],
904				width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
905		var numMonths = this._getNumberOfMonths(inst);
906		if (!inst.inline)
907			inst.dpDiv.attr('id', this._mainDivId[useTR]);
908		if (!inst.inline) inst.dpDiv.attr('class', 'datepick-inline');  // Added by wpdevelop for the correct  showing of calendar in the search form.
909		inst.dpDiv.removeClass(this._mainDivClass[1 - useTR]).
910			addClass(this._mainDivClass[useTR]).
911			removeClass(this._multiClass.join(' ')).
912			addClass(numMonths[0] != 1 || numMonths[1] != 1 ? this._multiClass[useTR] : '').
913			removeClass(this._rtlClass.join(' ')).
914			addClass(this._get(inst, 'isRTL') ? this._rtlClass[useTR] : '');
915		if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepick._curInst)
916			$( inst.input ).trigger( 'focus' );		// FixIn: 8.7.11.12.
917
918		// FixIn: 9.4.4.13.
919		var resource_id = this._get(inst, 'wpbc_resource_id');
920		if ( resource_id > 0 ){
921			$( 'body' ).trigger(
922								  'wpbc_datepick_inline_calendar_refresh'													// event name
923								, [
924									  resource_id																			// Resource ID	-	1
925									, inst 																					// datepick Obj
926								  ]
927								);
928		}
929		// To catch this event: jQuery( 'body' ).on('wpbc_datepick_inline_calendar_refresh', function( event, resource_id, inst ) { ... } );
930		//FixIn End: 9.4.4.13
931	},
932
933	/* Retrieve the size of left and top borders for an element.
934	   @param  elem  (jQuery object) the element of interest
935	   @return  (number[2]) the left and top borders */
936	_getBorders: function(elem) {
937		var convert = function(value) {
938			var extra = ($.browser_is_supported_datepick.msie ? 1 : 0);
939			return {thin: 1 + extra, medium: 3 + extra, thick: 5 + extra}[value] || value;
940		};
941		return [parseFloat(convert(elem.css('border-left-width'))),
942			parseFloat(convert(elem.css('border-top-width')))];
943	},
944
945	/* Check positioning to remain on the screen.
946	   @param  inst     (object) the instance settings for this datepicker
947	   @param  offset   (object) the offset of the attached field
948	   @param  isFixed  (boolean) true if control or a parent is 'fixed' in position
949	   @return  (object) the updated offset for the datepicker */
950	_checkOffset: function(inst, offset, isFixed) {
951		var alignment = this._get(inst, 'alignment');
952		var isRTL = this._get(inst, 'isRTL');
953		var pos = inst.input ? this._findPos(inst.input[0]) : null;
954		var browserWidth = document.documentElement.clientWidth;
955		var browserHeight = document.documentElement.clientHeight;
956		if (browserWidth == 0)
957			return offset;
958		var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
959		var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
960		var above = pos[1] - (this._inDialog ? 0 : inst.dpDiv.outerHeight()) -
961			(isFixed && $.browser_is_supported_datepick.opera ? document.documentElement.scrollTop : 0);
962		var below = offset.top;
963		var alignL = offset.left;
964		var alignR = pos[0] + (inst.input ? inst.input.outerWidth() : 0) - inst.dpDiv.outerWidth() -
965			(isFixed && $.browser_is_supported_datepick.opera ? document.documentElement.scrollLeft : 0);
966		var tooWide = (offset.left + inst.dpDiv.outerWidth() - scrollX) > browserWidth;
967		var tooHigh = (offset.top + inst.dpDiv.outerHeight() - scrollY) > browserHeight;
968		if (alignment == 'topLeft') {
969			offset = {left: alignL, top: above};
970		}
971		else if (alignment == 'topRight') {
972			offset = {left: alignR, top: above};
973		}
974		else if (alignment == 'bottomLeft') {
975			offset = {left: alignL, top: below};
976		}
977		else if (alignment == 'bottomRight') {
978			offset = {left: alignR, top: below};
979		}
980		else if (alignment == 'top') {
981			offset = {left: (isRTL || tooWide ? alignR : alignL), top: above};
982		}
983		else { // bottom
984			offset = {left: (isRTL || tooWide ? alignR : alignL),
985				top: (tooHigh ? above : below)};
986		}
987		offset.left = Math.max((isFixed ? 0 : scrollX), offset.left - (isFixed ? scrollX : 0));
988		offset.top = Math.max((isFixed ? 0 : scrollY), offset.top - (isFixed ? scrollY : 0));
989		return offset;
990	},
991
992	/* Find an element's position on the screen.
993	   @param  elem  (element) the element to check
994	   @return  (number[2]) the x- and y-coordinates for the object */
995	_findPos: function(elem) {
996        while (elem && (elem.type == 'hidden' || elem.nodeType != 1)) {
997            elem = elem.nextSibling;
998        }
999        var position = $(elem).offset();
1000	    return [position.left, position.top];
1001	},
1002
1003	/* Hide the date picker from view.
1004	   @param  input     (element) the input field attached to the date picker
1005	   @param  duration  (string) the duration over which to close the date picker */
1006	_hideDatepick: function(input, duration) {
1007		var inst = this._curInst;
1008		if (!inst || (input && inst != $.data(input, PROP_NAME)))
1009			return false;
1010		var rangeSelect = this._get(inst, 'rangeSelect');
1011		if (rangeSelect && inst.stayOpen)
1012			this._updateInput('#' + inst.id);
1013		inst.stayOpen = false;
1014		if (this._datepickerShowing) {
1015			duration = (duration != null ? duration : this._get(inst, 'duration'));
1016			var showAnim = this._get(inst, 'showAnim');
1017			var postProcess = function() {
1018				$.datepick._tidyDialog(inst);
1019			};
1020			if (duration != '' && $.effects && $.effects[showAnim])
1021				inst.dpDiv.hide(showAnim, $.datepick._get(inst, 'showOptions'),
1022					duration, postProcess);
1023			else
1024				inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
1025					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
1026			if (duration == '')
1027				this._tidyDialog(inst);
1028			var onClose = this._get(inst, 'onClose');
1029			if (onClose)  // Trigger custom callback
1030				onClose.apply((inst.input ? inst.input[0] : null),
1031					[(inst.input ? inst.input.val() : ''), this._getDate(inst), inst]);
1032			this._datepickerShowing = false;
1033			this._lastInput = null;
1034			inst.settings.prompt = null;
1035			if (this._inDialog) {
1036				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
1037				this.dpDiv.removeClass(this._dialogClass[this._get(inst, 'useThemeRoller') ? 1 : 0]);
1038				if ($.blockUI) {
1039					$.unblockUI();
1040					$('body').append(this.dpDiv);
1041				}
1042			}
1043			this._inDialog = false;
1044		}
1045		this._curInst = null;
1046		return false;
1047	},
1048
1049	/* Tidy up after a dialog display.
1050	   @param  inst  (object) the instance settings for this datepicker */
1051	_tidyDialog: function(inst) {
1052		var useTR = this._get(inst, 'useThemeRoller') ? 1 : 0;
1053		//inst.dpDiv.removeClass(this._dialogClass[useTR]).unbind('.datepick');		// FixIn: 10.0.0.45.
1054		inst.dpDiv.removeClass(this._dialogClass[useTR]).off('.datepick');			// FixIn: 10.0.0.45.
1055		$('.' + this._promptClass[useTR], inst.dpDiv).remove();
1056	},
1057
1058	/* Close date picker if clicked elsewhere.
1059	   @param  event  (MouseEvent) the mouse click to check */
1060	_checkExternalClick: function(event) {
1061		if (!$.datepick._curInst)
1062			return;
1063		var $target = $(event.target);
1064		var useTR = $.datepick._get($.datepick._curInst, 'useThemeRoller') ? 1 : 0;
1065		// replaced .andSelf to .addBack		// FixIn: 10.0.0.45.
1066		if (!$target.parents().addBack().is('#' + $.datepick._mainDivId[useTR]) &&
1067				!$target.hasClass($.datepick.markerClassName) &&
1068				!$target.parents().addBack().hasClass($.datepick._triggerClass[useTR]) &&
1069				$.datepick._datepickerShowing && !($.datepick._inDialog && $.blockUI))
1070			$.datepick._hideDatepick(null, '');
1071	},
1072
1073	/* Adjust one of the date sub-fields.
1074	   @param  id      (string) the ID of the target field
1075	   @param  offset  (number) the amount to change by
1076	   @param  period  (string) 'D' for days, 'M' for months, 'Y' for years */
1077	_adjustDate: function(id, offset, period) {
1078		var inst = this._getInst($(id)[0]);
1079		this._adjustInstDate(inst, offset +
1080			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // Undo positioning
1081			period);
1082		this._updateDatepick(inst);
1083		return false;
1084	},
1085
1086	/* Show the month for today or the current selection.
1087	   @param  id  (string) the ID of the target field */
1088	_gotoToday: function(id) {
1089		var target = $(id);
1090		var inst = this._getInst(target[0]);
1091		if (this._get(inst, 'gotoCurrent') && inst.dates[0])
1092			inst.cursorDate = new Date(inst.dates[0].getTime());
1093		else
1094			inst.cursorDate = this._daylightSavingAdjust(new Date());
1095		inst.drawMonth = inst.cursorDate.getMonth();
1096		inst.drawYear = inst.cursorDate.getFullYear();
1097		this._notifyChange(inst);
1098		this._adjustDate(target);
1099		return false;
1100	},
1101
1102	/* Selecting a new month/year.
1103	   @param  id      (string) the ID of the target field
1104	   @param  select  (element) the select being chosen from
1105	   @param  period  (string) 'M' for month, 'Y' for year */
1106	_selectMonthYear: function(id, select, period) {
1107		var target = $(id);
1108		var inst = this._getInst(target[0]);
1109		inst.selectingMonthYear = false;
1110		var value = parseInt(select.options[select.selectedIndex].value, 10);
1111		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
1112		inst['draw' + (period == 'M' ? 'Month' : 'Year')] = value;
1113		inst.cursorDate.setDate(Math.min(inst.cursorDate.getDate(),
1114			$.datepick._getDaysInMonth(inst.drawYear, inst.drawMonth)));
1115		inst.cursorDate['set' + (period == 'M' ? 'Month' : 'FullYear')](value);
1116		this._notifyChange(inst);
1117		this._adjustDate(target);
1118	},
1119
1120	/* Restore input focus after not changing month/year.
1121	   @param  id  (string) the ID of the target field */
1122	_clickMonthYear: function(id) {
1123		var inst = this._getInst($(id)[0]);
1124		if (inst.input && inst.selectingMonthYear && !$.browser_is_supported_datepick.msie)
1125			$( inst.input ).trigger( 'focus' );		// FixIn: 8.7.11.12.
1126		inst.selectingMonthYear = !inst.selectingMonthYear;
1127	},
1128
1129	/* Action for changing the first week day.
1130	   @param  id   (string) the ID of the target field
1131	   @param  day  (number) the number of the first day, 0 = Sun, 1 = Mon, ... */
1132	_changeFirstDay: function(id, day) {
1133		var inst = this._getInst($(id)[0]);
1134		inst.settings.firstDay = day;
1135		this._updateDatepick(inst);
1136		return false;
1137	},
1138
1139	/* Select a particular day.
1140	   @param  td         (element) the table cell containing the selection
1141	   @param  id         (string) the ID of the target field
1142	   @param  timestamp  (number) the timestamp for this day */
1143	_selectDay: function(td, id, timestamp) {
1144		var inst = this._getInst($(id)[0]);
1145		var useTR = this._get(inst, 'useThemeRoller') ? 1 : 0;
1146		if ($(td).hasClass(this._unselectableClass[useTR]))
1147			return false;
1148		var rangeSelect = this._get(inst, 'rangeSelect');
1149		var multiSelect = this._get(inst, 'multiSelect');
1150		if (rangeSelect)
1151			inst.stayOpen = !inst.stayOpen;
1152		else if (multiSelect)
1153			inst.stayOpen = true;
1154		if (inst.stayOpen) {
1155			$('.datepick td', inst.dpDiv).removeClass(this._selectedClass[useTR]);
1156			$(td).addClass(this._selectedClass[useTR]);
1157		}
1158		inst.cursorDate = this._daylightSavingAdjust(new Date(timestamp));
1159		var date = new Date(inst.cursorDate.getTime());
1160		if (rangeSelect && !inst.stayOpen)
1161			inst.dates[1] = date;
1162		else if (multiSelect) {
1163			var pos = -1;
1164			for (var i = 0; i < inst.dates.length; i++)
1165				if (inst.dates[i] && date.getTime() == inst.dates[i].getTime()) {
1166					pos = i;
1167					break;
1168				}
1169			if (pos > -1)
1170				inst.dates.splice(pos, 1);
1171			else if (inst.dates.length < multiSelect) {
1172				if (inst.dates[0])
1173					inst.dates.push(date);
1174				else
1175					inst.dates = [date];
1176				inst.stayOpen = (inst.dates.length != multiSelect);
1177			}
1178		}
1179		else
1180			inst.dates = [date];
1181		this._updateInput(id);
1182		if (inst.stayOpen)
1183			this._updateDatepick(inst);
1184		else if ((rangeSelect || multiSelect) && inst.inline)
1185			this._updateDatepick(inst);
1186		return false;
1187	},
1188
1189	/* Erase the input field and hide the date picker.
1190	   @param  id  (string) the ID of the target field */
1191	_clearDate: function(id) {
1192		var target = $(id);
1193		var inst = this._getInst(target[0]);
1194		if (this._get(inst, 'mandatory'))
1195			return false;
1196		inst.stayOpen = false;
1197		inst.dates = (this._get(inst, 'showDefault') ?
1198			[this._getDefaultDate(inst)] : []);
1199		this._updateInput(target);
1200		return false;
1201	},
1202
1203	/* Update the input field with the selected date.
1204	   @param  id       (string) the ID of the target field or
1205	                    (element) the target object */
1206	_updateInput: function(id) {
1207		var inst = this._getInst($(id)[0]);
1208		var dateStr = this._showDate(inst);
1209		this._updateAlternate(inst);
1210		var onSelect = this._get(inst, 'onSelect');
1211		if (onSelect)
1212			onSelect.apply((inst.input ? inst.input[0] : null),
1213				[dateStr, this._getDate(inst), inst]);  // Trigger custom callback
1214		else if (inst.input)
1215			inst.input.trigger('change'); // Fire the change event
1216		if (inst.inline)
1217			this._updateDatepick(inst);
1218		else if (!inst.stayOpen) {
1219			this._hideDatepick(null, this._get(inst, 'duration'));
1220			this._lastInput = inst.input[0];
1221			if (typeof(inst.input[0]) != 'object')
1222				$( inst.input ).trigger( 'focus' );		//FixIn: 8.7.11.12	// Restore focus
1223			this._lastInput = null;
1224		}
1225		return false;
1226	},
1227
1228	/* Update the input field with the current date(s).
1229	   @param  inst  (object) the instance settings for this datepicker
1230	   @return  (string) the formatted date(s) */
1231	_showDate: function(inst) {
1232		var dateStr = '';
1233		if (inst.input) {
1234			dateStr = (inst.dates.length == 0 ? '' : this._formatDate(inst, inst.dates[0]));
1235			if (dateStr) {
1236				if (this._get(inst, 'rangeSelect'))
1237					dateStr += this._get(inst, 'rangeSeparator') +
1238						this._formatDate(inst, inst.dates[1] || inst.dates[0]);
1239				else if (this._get(inst, 'multiSelect'))
1240					for (var i = 1; i < inst.dates.length; i++)
1241						dateStr += this._get(inst, 'multiSeparator') +
1242							this._formatDate(inst, inst.dates[i]);
1243			}
1244			inst.input.val(dateStr);
1245		}
1246		return dateStr;
1247	},
1248
1249	/* Update any alternate field to synchronise with the main field.
1250	   @param  inst  (object) the instance settings for this datepicker */
1251	_updateAlternate: function(inst) {
1252		var altField = this._get(inst, 'altField');
1253		if (altField) { // Update alternate field too
1254			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
1255			var settings = this._getFormatConfig(inst);
1256			var dateStr = this.formatDate(altFormat, inst.dates[0], settings);
1257			if (dateStr && this._get(inst, 'rangeSelect'))
1258				dateStr += this._get(inst, 'rangeSeparator') + this.formatDate(
1259					altFormat, inst.dates[1] || inst.dates[0], settings);
1260			else if (this._get(inst, 'multiSelect'))
1261				for (var i = 1; i < inst.dates.length; i++)
1262					dateStr += this._get(inst, 'multiSeparator') +
1263						this.formatDate(altFormat, inst.dates[i], settings);
1264			$(altField).val(dateStr);
1265		}
1266	},
1267
1268	/* Set as beforeShowDay function to prevent selection of weekends.
1269	   @param  date  (Date) the date to customise
1270	   @return  ([boolean, string]) is this date selectable?, what is its CSS class? */
1271	noWeekends: function(date) {
1272		return [(date.getDay() || 7) < 6, ''];
1273	},
1274
1275	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
1276	   @param  date  (Date) the date to get the week for
1277	   @return  (number) the number of the week within the year that contains this date */
1278	iso8601Week: function(date) {
1279		var checkDate = new Date(date.getTime());
1280		// Find Thursday of this week starting on Monday
1281		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
1282		var time = checkDate.getTime();
1283		checkDate.setMonth(0); // Compare with Jan 1
1284		checkDate.setDate(1);
1285		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
1286	},
1287
1288	/* Provide status text for a particular date.
1289	   @param  date  (Date) the date to get the status for
1290	   @param  inst  (object) the current datepicker instance
1291	   @return  (string) the status display text for this date */
1292	dateStatus: function(date, inst) {
1293		return $.datepick.formatDate($.datepick._get(inst, 'dateStatus'),
1294			date, $.datepick._getFormatConfig(inst));
1295	},
1296
1297	/* Parse a string value into a date object.
1298	   See formatDate below for the possible formats.
1299	   @param  format    (string) the expected format of the date
1300	   @param  value     (string) the date in the above format
1301	   @param  settings  (object) attributes include:
1302	                     shortYearCutoff  (number) the cutoff year for determining the century (optional)
1303	                     dayNamesShort    (string[7]) abbreviated names of the days from Sunday (optional)
1304	                     dayNames         (string[7]) names of the days from Sunday (optional)
1305	                     monthNamesShort  (string[12]) abbreviated names of the months (optional)
1306	                     monthNames       (string[12]) names of the months (optional)
1307	   @return  (Date) the extracted date value or null if value is blank */
1308	parseDate: function (format, value, settings) {
1309		if (format == null || value == null)
1310			throw 'Invalid arguments';
1311		value = (typeof value == 'object' ? value.toString() : value + '');
1312		if (value == '')
1313			return null;
1314		settings = settings || {};
1315		var shortYearCutoff = settings.shortYearCutoff || this._defaults.shortYearCutoff;
1316		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
1317			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1318		var dayNamesShort = settings.dayNamesShort || this._defaults.dayNamesShort;
1319		var dayNames = settings.dayNames || this._defaults.dayNames;
1320		var monthNamesShort = settings.monthNamesShort || this._defaults.monthNamesShort;
1321		var monthNames = settings.monthNames || this._defaults.monthNames;
1322		var year = -1;
1323		var month = -1;
1324		var day = -1;
1325		var doy = -1;
1326		var literal = false;
1327		// Check whether a format character is doubled
1328		var lookAhead = function(match) {
1329			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
1330			if (matches)
1331				iFormat++;
1332			return matches;
1333		};
1334		// Extract a number from the string value
1335		var getNumber = function(match) {
1336			lookAhead(match);
1337			var size = (match == '@' ? 14 : (match == '!' ? 20 :
1338				(match == 'y' ? 4 : (match == 'o' ? 3 : 2))));
1339			var digits = new RegExp('^\\d{1,' + size + '}');
1340			var num = value.substring(iValue).match(digits);
1341			if (!num)
1342				throw 'Missing number at position ' + iValue;
1343			iValue += num[0].length;
1344			return parseInt(num[0], 10);
1345		};
1346		// Extract a name from the string value and convert to an index
1347		var getName = function(match, shortNames, longNames) {
1348			var names = (lookAhead(match) ? longNames : shortNames);
1349			for (var i = 0; i < names.length; i++) {
1350				if (value.substr(iValue, names[i].length) == names[i]) {
1351					iValue += names[i].length;
1352					return i + 1;
1353				}
1354			}
1355			throw 'Unknown name at position ' + iValue;
1356		};
1357		// Confirm that a literal character matches the string value
1358		var checkLiteral = function() {
1359			if (value.charAt(iValue) != format.charAt(iFormat))
1360				throw 'Unexpected literal at position ' + iValue;
1361			iValue++;
1362		};
1363		var iValue = 0;
1364		for (var iFormat = 0; iFormat < format.length; iFormat++) {
1365			if (literal)
1366				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1367					literal = false;
1368				else
1369					checkLiteral();
1370			else
1371				switch (format.charAt(iFormat)) {
1372					case 'd':
1373						day = getNumber('d');
1374						break;
1375					case 'D':
1376						getName('D', dayNamesShort, dayNames);
1377						break;
1378					case 'o':
1379						doy = getNumber('o');
1380						break;
1381					case 'w':
1382						getNumber('w');
1383						break;
1384					case 'm':
1385						month = getNumber('m');
1386						break;
1387					case 'M':
1388						month = getName('M', monthNamesShort, monthNames);
1389						break;
1390					case 'y':
1391						year = getNumber('y');
1392						break;
1393					case '@':
1394						var date = new Date(getNumber('@'));
1395						year = date.getFullYear();
1396						month = date.getMonth() + 1;
1397						day = date.getDate();
1398						break;
1399					case '!':
1400						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
1401						year = date.getFullYear();
1402						month = date.getMonth() + 1;
1403						day = date.getDate();
1404						break;
1405					case "'":
1406						if (lookAhead("'"))
1407							checkLiteral();
1408						else
1409							literal = true;
1410						break;
1411					default:
1412						checkLiteral();
1413				}
1414		}
1415		if (iValue < value.length)
1416			throw 'Additional text found at end';
1417		if (year == -1)
1418			year = new Date().getFullYear();
1419		else if (year < 100)
1420			year += (shortYearCutoff == -1 ? 1900 : new Date().getFullYear() -
1421				new Date().getFullYear() % 100 - (year <= shortYearCutoff ? 0 : 100));
1422		if (doy > -1) {
1423			month = 1;
1424			day = doy;
1425			do {
1426				var dim = this._getDaysInMonth(year, month - 1);
1427				if (day <= dim)
1428					break;
1429				month++;
1430				day -= dim;
1431			} while (true);
1432		}
1433		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
1434		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
1435			throw 'Invalid date'; // E.g. 31/02/*
1436		return date;
1437	},
1438
1439	/* Standard date formats. */
1440	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
1441	COOKIE: 'D, dd M yy',
1442	ISO_8601: 'yy-mm-dd',
1443	RFC_822: 'D, d M y',
1444	RFC_850: 'DD, dd-M-y',
1445	RFC_1036: 'D, d M y',
1446	RFC_1123: 'D, d M yy',
1447	RFC_2822: 'D, d M yy',
1448	RSS: 'D, d M y', // RFC 822
1449	TICKS: '!',
1450	TIMESTAMP: '@',
1451	W3C: 'yy-mm-dd', // ISO 8601
1452
1453	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
1454		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
1455
1456	/* Format a date object into a string value.
1457	   The format can be combinations of the following:
1458	   d  - day of month (no leading zero)
1459	   dd - day of month (two digit)
1460	   o  - day of year (no leading zeros)
1461	   oo - day of year (three digit)
1462	   D  - day name short
1463	   DD - day name long
1464	   w  - week of year (no leading zero)
1465	   ww - week of year (two digit)
1466	   m  - month of year (no leading zero)
1467	   mm - month of year (two digit)
1468	   M  - month name short
1469	   MM - month name long
1470	   y  - year (two digit)
1471	   yy - year (four digit)
1472	   @ - Unix timestamp (ms since 01/01/1970)
1473	   ! - Windows ticks (100ns since 01/01/0001)
1474	   '...' - literal text
1475	   '' - single quote
1476	   @param  format    (string) the desired format of the date
1477	   @param  date      (Date) the date value to format
1478	   @param  settings  (object) attributes include:
1479	                     dayNamesShort    (string[7]) abbreviated names of the days from Sunday (optional)
1480	                     dayNames         (string[7]) names of the days from Sunday (optional)
1481	                     monthNamesShort  (string[12]) abbreviated names of the months (optional)
1482	                     monthNames       (string[12]) names of the months (optional)
1483						 calculateWeek    (function) function that determines week of the year (optional)
1484	   @return  (string) the date in the above format */
1485	formatDate: function (format, date, settings) {
1486		if (!date)
1487			return '';
1488		settings = settings || {};
1489		var dayNamesShort = settings.dayNamesShort || this._defaults.dayNamesShort;
1490		var dayNames = settings.dayNames || this._defaults.dayNames;
1491		var monthNamesShort = settings.monthNamesShort || this._defaults.monthNamesShort;
1492		var monthNames = settings.monthNames || this._defaults.monthNames;
1493		var calculateWeek = settings.calculateWeek || this._defaults.calculateWeek;
1494		// Check whether a format character is doubled
1495		var lookAhead = function(match) {
1496			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
1497			if (matches)
1498				iFormat++;
1499			return matches;
1500		};
1501		// Format a number, with leading zero if necessary
1502		var formatNumber = function(match, value, len) {
1503			var num = '' + value;
1504			if (lookAhead(match))
1505				while (num.length < len)
1506					num = '0' + num;
1507			return num;
1508		};
1509		// Format a name, short or long as requested
1510		var formatName = function(match, value, shortNames, longNames) {
1511			return (lookAhead(match) ? longNames[value] : shortNames[value]);
1512		};
1513		var output = '';
1514		var literal = false;
1515		if (date)
1516			for (var iFormat = 0; iFormat < format.length; iFormat++) {
1517				if (literal)
1518					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1519						literal = false;
1520					else
1521						output += format.charAt(iFormat);
1522				else
1523					switch (format.charAt(iFormat)) {
1524						case 'd':
1525							output += formatNumber('d', date.getDate(), 2);
1526							break;
1527						case 'D':
1528							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
1529							break;
1530						case 'o':
1531							output += formatNumber('o',
1532								(date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);
1533							break;
1534						case 'w':
1535							output += formatNumber('w', calculateWeek(date), 2);
1536							break;
1537						case 'm':
1538							output += formatNumber('m', date.getMonth() + 1, 2);
1539							break;
1540						case 'M':
1541							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
1542							break;
1543						case 'y':
1544							output += (lookAhead('y') ? date.getFullYear() :
1545								(date.getFullYear() % 100 < 10 ? '0' : '') + date.getFullYear() % 100);
1546							break;
1547						case '@':
1548							output += date.getTime();
1549							break;
1550						case '!':
1551							output += date.getTime() * 10000 + this._ticksTo1970;
1552							break;
1553						case "'":
1554							if (lookAhead("'"))
1555								output += "'";
1556							else
1557								literal = true;
1558							break;
1559						default:
1560							output += format.charAt(iFormat);
1561					}
1562			}
1563		return output;
1564	},
1565
1566	/* Get a setting value, defaulting if necessary.
1567	   @param  inst  (object) the instance settings for this datepicker
1568	   @param  name  (string) the name of the property
1569	   @return  (any) the property's value */
1570	_get: function(inst, name) {
1571		return inst.settings[name] !== undefined ?
1572			inst.settings[name] : this._defaults[name];
1573	},
1574
1575	/* Parse existing date and initialise date picker.
1576	   @param  inst  (object) the instance settings for this datepicker */
1577	_setDateFromField: function(inst) {
1578		var dateFormat = this._get(inst, 'dateFormat');
1579		var rangeSelect = this._get(inst, 'rangeSelect');
1580		var multiSelect = this._get(inst, 'multiSelect');
1581		inst.lastVal = (inst.input ? inst.input.val() : '');
1582		var dates = inst.lastVal;
1583		dates = (rangeSelect ? dates.split(this._get(inst, 'rangeSeparator')) :
1584			(multiSelect ? dates.split(this._get(inst, 'multiSeparator')) : [dates]));
1585		inst.dates = [];
1586		var settings = this._getFormatConfig(inst);
1587		for (var i = 0; i < dates.length; i++)
1588			try {
1589				inst.dates[i] = this.parseDate(dateFormat, dates[i], settings);
1590			}
1591			catch (event) {
1592				inst.dates[i] = null;
1593			}
1594		for (var i = inst.dates.length - 1; i >= 0; i--)
1595			if (!inst.dates[i])
1596				inst.dates.splice(i, 1);
1597		if (rangeSelect && inst.dates.length < 2)
1598			inst.dates[1] = inst.dates[0];
1599		if (multiSelect && inst.dates.length > multiSelect)
1600			inst.dates.splice(multiSelect, inst.dates.length);
1601		inst.cursorDate = new Date((inst.dates[0] || this._getDefaultDate(inst)).getTime());
1602		inst.drawMonth = inst.cursorDate.getMonth();
1603		inst.drawYear = inst.cursorDate.getFullYear();
1604		this._adjustInstDate(inst);
1605	},
1606
1607	/* Retrieve the default date shown on opening.
1608	   @param  inst  (object) the instance settings for this datepicker
1609	   @return  (Date) the default date */
1610	_getDefaultDate: function(inst) {
1611		return this._restrictMinMax(inst,
1612			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
1613	},
1614
1615	/* A date may be specified as an exact value or a relative one.
1616	   @param  inst         (object) the instance settings for this datepicker
1617	   @param  date         (Date or number or string) the date or offset
1618	   @param  defaultDate  (Date) the date to use if no other supplied
1619	   @return  (Date) the decoded date */
1620	_determineDate: function(inst, date, defaultDate) {
1621		var offsetNumeric = function(offset) {
1622			var date = new Date();
1623			date.setDate(date.getDate() + offset);
1624			return date;
1625		};
1626		var offsetString = function(offset) {
1627			try {
1628				return $.datepick.parseDate($.datepick._get(inst, 'dateFormat'),
1629					offset, $.datepick._getFormatConfig(inst));
1630			}
1631			catch (e) {
1632				// Ignore
1633			}
1634			var date = (offset.toLowerCase().match(/^c/) ?
1635				$.datepick._getDate(inst) : null) || new Date();
1636			var year = date.getFullYear();
1637			var month = date.getMonth();
1638			var day = date.getDate();
1639			var pattern = /([+-]?[0-9]+)\s*(d|w|m|y)?/g;
1640			var matches = pattern.exec(offset.toLowerCase());
1641			while (matches) {
1642				switch (matches[2] || 'd') {
1643					case 'd':
1644						day += parseInt(matches[1], 10); break;
1645					case 'w':
1646						day += parseInt(matches[1], 10) * 7; break;
1647					case 'm':
1648						month += parseInt(matches[1], 10);
1649						day = Math.min(day, $.datepick._getDaysInMonth(year, month));
1650						break;
1651					case 'y':
1652						year += parseInt(matches[1], 10);
1653						day = Math.min(day, $.datepick._getDaysInMonth(year, month));
1654						break;
1655				}
1656				matches = pattern.exec(offset.toLowerCase());
1657			}
1658			return new Date(year, month, day);
1659		};
1660		date = (date == null ? defaultDate : (typeof date == 'string' ? offsetString(date) :
1661			(typeof date == 'number' ? (isNaN(date) || date == Infinity || date == -Infinity ?
1662			defaultDate : offsetNumeric(date)) : date)));
1663		date = (date && (date.toString() == 'Invalid Date' ||
1664			date.toString() == 'NaN') ? defaultDate : date);
1665		if (date) {
1666			date.setHours(0);
1667			date.setMinutes(0);
1668			date.setSeconds(0);
1669			date.setMilliseconds(0);
1670		}
1671		return this._daylightSavingAdjust(date);
1672	},
1673
1674	/* Handle switch to/from daylight saving.
1675	   Hours may be non-zero on daylight saving cut-over:
1676	   > 12 when midnight changeover, but then cannot generate
1677	   midnight datetime, so jump to 1AM, otherwise reset.
1678	   @param  date  (Date) the date to check
1679	   @return  (Date) the corrected date */
1680	_daylightSavingAdjust: function(date) {
1681		if (!date) return null;
1682		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
1683		return date;
1684	},
1685
1686	/* Set the date(s) directly.
1687	   @param  inst     (object) the instance settings for this datepicker
1688	   @param  date     (Date or Date[] or number or string) the new date or start of a range
1689	   @param  endDate  (Date or number or string) the end of a range */
1690	_setDate: function(inst, date, endDate) {
1691		date = (!date ? [] : (isArray(date) ? date : [date]));
1692		if (endDate)
1693			date.push(endDate);
1694		var clear = (date.length == 0);
1695		var origMonth = inst.cursorDate.getMonth();
1696		var origYear = inst.cursorDate.getFullYear();
1697		inst.dates = [this._restrictMinMax(inst, this._determineDate(inst, date[0], new Date()))];
1698		inst.cursorDate = new Date(inst.dates[0].getTime());
1699		inst.drawMonth = inst.cursorDate.getMonth();
1700		inst.drawYear = inst.cursorDate.getFullYear();
1701		if (this._get(inst, 'rangeSelect'))
1702			inst.dates[1] = (date.length < 1 ? inst.dates[0] :
1703				this._restrictMinMax(inst, this._determineDate(inst, date[1], null)));
1704		else if (this._get(inst, 'multiSelect'))
1705			for (var i = 1; i < date.length; i++)
1706				inst.dates[i] = this._restrictMinMax(inst, this._determineDate(inst, date[i], null));
1707		if (origMonth != inst.cursorDate.getMonth() || origYear != inst.cursorDate.getFullYear())
1708			this._notifyChange(inst);
1709		this._adjustInstDate(inst);
1710		this._showDate(inst);
1711	},
1712
1713	/* Retrieve the date(s) directly.
1714	   @param  inst  (object) the instance settings for this datepicker
1715	   @return  (Date or Date[2] or Date[]) the current date or dates
1716	            (for a range or multiples) */
1717	_getDate: function(inst) {
1718		var startDate = (inst.input && inst.input.val() == '' ? null : inst.dates[0]);
1719		if (this._get(inst, 'rangeSelect'))
1720			return (startDate ? [inst.dates[0], inst.dates[1] || inst.dates[0]] : [null, null]);
1721		else if (this._get(inst, 'multiSelect'))
1722			return inst.dates.slice(0, inst.dates.length);
1723		else
1724			return startDate;
1725	},
1726
1727
1728	/* Generate the HTML for the current state of the date picker.
1729	   @param  inst  (object) the instance settings for this datepicker
1730	   @return  (string) the new HTML for the datepicker */
1731	_generateHTML: function(inst) {
1732		var today = new Date();
1733		today = this._daylightSavingAdjust(
1734			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // Clear time
1735
1736
1737		var showStatus = this._get(inst, 'showStatus');
1738		var initStatus = this._get(inst, 'initStatus') || '&#xa0;';
1739		var isRTL = this._get(inst, 'isRTL');
1740		var useTR = this._get(inst, 'useThemeRoller') ? 1 : 0;
1741		// Build the date picker HTML
1742		var clear = (this._get(inst, 'mandatory') ? '' :
1743			'<div class="' + this._clearClass[useTR] + '"><a href="javascript:void(0)" ' +
1744			'onclick="jQuery.datepick._clearDate(\'#' + inst.id + '\');"' +
1745			this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'clearStatus'), initStatus) +
1746			'>' + this._get(inst, 'clearText') + '</a></div>');
1747		var controls = '<div class="' + this._controlClass[useTR] + '">' + (isRTL ? '' : clear) +
1748			'<div class="' + this._closeClass[useTR] + '"><a href="javascript:void(0)" ' +
1749			'onclick="jQuery.datepick._hideDatepick();"' +
1750			this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'closeStatus'), initStatus) +
1751			'>' + this._get(inst, 'closeText') + '</a></div>' + (isRTL ? clear : '')  + '</div>';
1752		var prompt = this._get(inst, 'prompt');
1753		var closeAtTop = this._get(inst, 'closeAtTop');
1754		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
1755		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
1756		var showBigPrevNext = this._get(inst, 'showBigPrevNext');
1757		var numMonths = this._getNumberOfMonths(inst);
1758		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
1759		var stepMonths = this._get(inst, 'stepMonths');
1760		var stepBigMonths = this._get(inst, 'stepBigMonths');
1761		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
1762		var minDate = this._getMinMaxDate(inst, 'min', true);
1763		var maxDate = this._getMinMaxDate(inst, 'max');
1764		var drawMonth = inst.drawMonth - showCurrentAtPos;
1765		var drawYear = inst.drawYear;
1766		if (drawMonth < 0) {
1767			drawMonth += 12;
1768			drawYear--;
1769		}
1770		if (maxDate) { // Don't show past maximum unless also restricted by minimum
1771			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
1772				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
1773			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1774			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
1775				drawMonth--;
1776				if (drawMonth < 0) {
1777					drawMonth = 11;
1778					drawYear--;
1779				}
1780			}
1781		}
1782		inst.drawMonth = drawMonth;
1783		inst.drawYear = drawYear;
1784		// Controls and links
1785		var prevText = this._get(inst, 'prevText');
1786		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
1787			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
1788			this._getFormatConfig(inst)));
1789		var prevBigText = (showBigPrevNext ? this._get(inst, 'prevBigText') : '');
1790		prevBigText = (!navigationAsDateFormat ? prevBigText : this.formatDate(prevBigText,
1791			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepBigMonths, 1)),
1792			this._getFormatConfig(inst)));
1793		var prev = '<div class="' + this._prevClass[useTR] + '">' +
1794			(this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
1795			(showBigPrevNext ? '<a href="javascript:void(0)" onclick="jQuery.datepick._adju
1795stDate(\'#' +
1796			inst.id + '\', -' + stepBigMonths + ', \'M\');"' +
1797			this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'prevBigStatus'), initStatus) +
1798			'>' + prevBigText + '</a>' : '') +
1799			'<a href="javascript:void(0)" onclick="jQuery.datepick._adjustDate(\'#' +
1800			inst.id + '\', -' + stepMonths + ', \'M\');"' +
1801			this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'prevStatus'), initStatus) +
1802			'>' + prevText + '</a>' :
1803			(hideIfNoPrevNext ? '&#xa0;' : (showBigPrevNext ? '<label>' + prevBigText + '</label>' : '') +
1804			'<label>' + prevText + '</label>')) + '</div>';
1805		var nextText = this._get(inst, 'nextText');
1806		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
1807			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
1808			this._getFormatConfig(inst)));
1809		var nextBigText = (showBigPrevNext ? this._get(inst, 'nextBigText') : '');
1810		nextBigText = (!navigationAsDateFormat ? nextBigText : this.formatDate(nextBigText,
1811			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepBigMonths, 1)),
1812			this._getFormatConfig(inst)));
1813		var next = '<div class="' + this._nextClass[useTR] + '">' +
1814			(this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
1815			'<a href="javascript:void(0)" onclick="jQuery.datepick._adjustDate(\'#' +
1816			inst.id + '\', +' + stepMonths + ', \'M\');"' +
1817			this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'nextStatus'), initStatus) +
1818			'>' + nextText + '</a>' +
1819			(showBigPrevNext ? '<a href="javascript:void(0)" onclick="jQuery.datepick._adjustDate(\'#' +
1820			inst.id + '\', +' + stepBigMonths + ', \'M\');"' +
1821			this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'nextBigStatus'), initStatus) +
1822			'>' + nextBigText + '</a>' : '') :
1823			(hideIfNoPrevNext ? '&#xa0;' : '<label>' + nextText + '</label>' +
1824			(showBigPrevNext ? '<label>' + nextBigText + '</label>' : ''))) + '</div>';
1825		var currentText = this._get(inst, 'currentText');
1826		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.dates[0] ? inst.dates[0] : today);
1827		currentText = (!navigationAsDateFormat ? currentText :
1828			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
1829		var html = (closeAtTop && !inst.inline ? controls : '');/* +
1830			'<div class="' + this._linksClass[useTR] + '">' + (isRTL ? next : prev) +
1831			'<div class="' + this._currentClass[useTR] + '">' + (this._isInRange(inst, gotoDate) ?
1832			'<a href="javascript:void(0)" onclick="jQuery.datepick._gotoToday(\'#' + inst.id + '\');"' +
1833			this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'currentStatus'), initStatus) + '>' +
1834			currentText + '</a>' : (hideIfNoPrevNext ? '&#xa0;' : '<label>' + currentText + '</label>')) +
1835			'</div>' + (isRTL ? prev : next) + '</div>' +
1836			(prompt ? '<div class="' + this._promptClass[useTR] + '"><span>' +
1837			prompt + '</span></div>' : '');/**/
1838                    html +=  '<div class="calendar-links">' + (isRTL ? next : prev)   ;
1839                    html +=    (isRTL ? prev : next) + '</div>' ;
1840		var firstDay = parseInt(this._get(inst, 'firstDay'), 10);
1841		firstDay = (isNaN(firstDay) ? 0 : firstDay);
1842		var changeFirstDay = this._get(inst, 'changeFirstDay');
1843		var dayNames = this._get(inst, 'dayNames');
1844		var dayNamesShort = this._get(inst, 'dayNamesShort');
1845		var dayNamesMin = this._get(inst, 'dayNamesMin');
1846		var monthNames = this._get(inst, 'monthNames');
1847		var beforeShowDay = this._get(inst, 'beforeShowDay');
1848		var showOtherMonths = this._get(inst, 'showOtherMonths');
1849		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
1850		var showWeeks = this._get(inst, 'showWeeks');
1851		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
1852		var weekStatus = this._get(inst, 'weekStatus');
1853		var status = (showStatus ? this._get(inst, 'dayStatus') || initStatus : '');
1854		var dateStatus = this._get(inst, 'statusForDate') || this.dateStatus;
1855		var defaultDate = this._getDefaultDate(inst);
1856		for (var row = 0; row < numMonths[0]; row++) {
1857			for (var col = 0; col < numMonths[1]; col++) {
1858				var cursorDate = this._daylightSavingAdjust(
1859					new Date(drawYear, drawMonth, inst.cursorDate.getDate()));
1860				html += '<div class="' + this._oneMonthClass[useTR] +            // Responsive skin
1861					(col == 0 && !useTR ? ' ' + this._newRowClass[useTR] : '') + '">' +
1862					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
1863					cursorDate, row > 0 || col > 0, useTR, showStatus, initStatus, monthNames) + // Draw month headers
1864					'<table class="' + this._tableClass[useTR] + '" cellpadding="0" cellspacing="0"><thead>' +
1865					'<tr class="' + this._tableHeaderClass[useTR] + '">' + (showWeeks ? '<th' +
1866					this._addStatus(useTR, showStatus, inst.id, weekStatus, initStatus) + '>' +
1867					this._get(inst, 'weekHeader') + '</th>' : '');
1868				for (var dow = 0; dow < 7; dow++) { // Days of the week
1869					var day = (dow + firstDay) % 7;
1870					var dayStatus = (!showStatus || !changeFirstDay ? '' :
1871						status.replace(/DD/, dayNames[day]).replace(/D/, dayNamesShort[day]));
1872					html += '<th' + ((dow + firstDay + 6) % 7 < 5 ? '' :
1873						' class="' + this._weekendClass[useTR] + '"') + '>
1873' +
1874						(!changeFirstDay ? '<span' +
1875						this._addStatus(useTR, showStatus, inst.id, dayNames[day], initStatus) :
1876						'<a href="javascript:void(0)" onclick="jQuery.datepick._changeFirstDay(\'#' +
1877						inst.id + '\', ' + day + ');"' +
1878						this._addStatus(useTR, showStatus, inst.id, dayStatus, initStatus)) +
1879						' title="' + dayNames[day] + '">' +
1880						dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</th>';
1881				}
1882				html += '</tr></thead><tbody>';
1883				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1884				if (drawYear == inst.cursorDate.getFullYear() && drawMonth == inst.cursorDate.getMonth())
1885					inst.cursorDate.setDate(Math.min(inst.cursorDate.getDate(), daysInMonth));
1886				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1887				var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7));
1888				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
1889				for (var dRow = 0; dRow < numRows; dRow++) { // Create datepicker rows
1890					html += '<tr class="' + this._weekRowClass[useTR] + '">' +
1891						(showWeeks ? '<td class="' + this._weekColClass[useTR] + '"' +
1892						this._addStatus(useTR, showStatus, inst.id, weekStatus, initStatus) + '>' +
1893						calculateWeek(printDate) + '</td>' : '');
1894					for (var dow = 0; dow < 7; dow++) { // Create datepicker days
1895						var daySettings = (beforeShowDay ?
1896							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
1897						var otherMonth = (printDate.getMonth() != drawMonth);
1898						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
1899							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1900						var selected = (this._get(inst, 'rangeSelect') && inst.dates[0] &&
1901							printDate.getTime() >= inst.dates[0].getTime() &&
1902							printDate.getTime() <= (inst.dates[1] || inst.dates[0]).getTime());
1903						for (var i = 0; i < inst.dates.length; i++)
1904							selected = selected || (inst.dates[i] &&
1905								printDate.getTime() == inst.dates[i].getTime());
1906						var empty = otherMonth && !showOtherMonths;
1907						html += '<td data-content="" class="' + this._dayClass[useTR] +
1908							((dow + firstDay + 6) % 7 >= 5 ? ' ' + this._weekendClass[useTR] : '') + // Highlight weekends
1909							(otherMonth ? ' ' + this._otherMonthClass[useTR] : '') + // Highlight days from other months
1910							((printDate.getTime() == cursorDate.getTime() &&
1911							drawMonth == inst.cursorDate.getMonth() && inst.keyEvent) || // User pressed key
1912							(defaultDate.getTime() == printDate.getTime() &&
1913							defaultDate.getTime() == cursorDate.getTime()) ?
1914							// Or defaultDate is selected printedDate and defaultDate is cursorDate
1915							' ' /*+ $.datepick._dayOverClass[useTR]*/ : '') + // Highlight selected day		// FixIn: 9.2.1.7.
1916							(unselectable ? ' ' + this._unselectableClass[useTR] :
1917							' ' + this._selectableClass[useTR]) +  // Highlight unselectable days
1918							(empty ? '' : ' ' + daySettings[1] + // Highlight custom dates
1919							(selected ? ' ' + this._selectedClass[useTR] : '') + // Currently selected
1920							// Highlight today (if different)
1921							(printDate.getTime() == today.getTime() ? ' ' + this._todayClass[useTR] : '')) + '"' +
1922							(!empty && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // Cell title
1923//							(unselectable ? '' : ' onmouseover="' + 'jQuery.datepick._doMouseOver(this,\'' +
1924							(false ? '' : ' onmouseover="' + 'jQuery.datepick._doMouseOver(this,\'' +					//FixIn: 2023-08-06
1925							inst.id + '\',' + printDate.getTime() + ')"' +
1926							' onmouseout="jQuery.datepick._doMouseOut(this,\'' + inst.id + '\')"' +
1927							' onclick="jQuery.datepick._selectDay(this,\'#' + // Select
1928							inst.id + '\',' + printDate.getTime() + ')"') + '>';
1929
1930							/** Start content of Day cell *************************************************************/
1931							html += '<div class="wpbc-cell-box">' +														// FixIn: 8.9.4.13.
1932										'<div class="wpbc-diagonal-el">' +
1933											'<div class="wpbc-co-out">' +
1934												'<svg height="100%" width="100%" viewBox="0 0 100 100" preserveAspectRatio="none">' +
1935													'<polygon points="0,0 0,99 99,0"></polygon>' +
1936													'<polygon points="0,0 0,100 49,100 49,0"></polygon>' +
1937												'</svg>' +
1938											'</div>' +
1939											'<div class="wpbc-co-in">' +
1940												'<svg height="100%" width="100%" viewBox="0 0 98 98" preserveAspectRatio="none">' +
1941													'<polygon points="0,99 99,99 99,0"></polygon>' +
1942													'<polygon points="50,98 98,98 98,0 50,0"></polygon>' +
1943												'</svg>' +
1944											'</div>' +
1945										'</div>' +
1946										    //'<div class="check-in-div"><div></div></div>' +		// Deprecated! remove this line
1947										    //'<div class="check-out-div"><div></div></div>' +		// Deprecated! remove this line
1948										'<div class="date-cell-content">' +												// FixIn: 8.9.4.13.
1949											'<div class="date-content-top">' +
1950												(unselectable ? '' : ((typeof (wpbc_show_date_info_top) == 'function') ? wpbc_show_date_info_top( inst.id, printDate.getTime() ) : '')) +
1951											'</div>' +
1952											(empty ? '&#xa0;' : // Not showing other months // FixIn: 6.0.1.2.
1953											(unselectable ? '<span>' + printDate.getDate()+ '</span>' : '<a href="javascript:void(0)" >' + printDate.getDate() + '</a>')) +		// FixIn: 10.0.0.19.
1954											'<div class="date-content-bottom">'+
1955												(unselectable ? '' : ((typeof (wpbc_show_date_info_bottom) == 'function') ? wpbc_show_date_info_bottom( inst.id, printDate.getTime() ) : '')) +
1956											'</div>' +
1957										'</div>' +
1958									'</div>';
1959						/** End content of Day cell *******************************************************************/
1960                        html += '</td>';
1961						printDate.setDate(printDate.getDate() + 1);
1962						printDate = this._daylightSavingAdjust(printDate);
1963					}
1964					html += '</tr>';
1965				}
1966				drawMonth++;
1967				if (drawMonth > 11) {
1968					drawMonth = 0;
1969					drawYear++;
1970				}
1971				html += '</tbody></table></div>';
1972			}
1973			if (useTR)
1974				html += '<div class="' + this._newRowClass[useTR] + '"></div>';
1975		}
1976		html += (showStatus ? '<div style="clear: both;"></div><div id="' + this._statusId[useTR] +
1977			inst.id +'" class="' + this._statusClass[useTR] + '">' + initStatus + '</div>' : '') +
1978			(!closeAtTop && !inst.inline ? controls : '') +
1979			'<div style="clear: both;"></div>' +
1980			($.browser_is_supported_datepick.msie && parseInt($.browser_is_supported_datepick.version, 10) < 7 && !inst.inline ?
1981			'<iframe src="javascript:false;" class="' + this._coverClass[useTR] + '"></iframe>' : '');
1982		inst.keyEvent = false;
1983		return html;
1984	},
1985
1986	/* Generate the month and year header.
1987	   @param  inst        (object) the instance settings for this datepicker
1988	   @param  drawMonth   (number) the current month
1989	   @param  drawYear    (number) the current year
1990	   @param  minDate     (Date) the minimum allowed date or null if none
1991	   @param  maxDate     (Date) the maximum allowed date or null if none
1992	   @param  cursorDate  (Date) the current date position
1993	   @param  secondary   (boolean) true if not the first month/year header
1994	   @param  useTR       (number) 1 if applying ThemeRoller styling, 0 if not
1995	   @param  showStatus  (boolean) true if status bar is visible
1996	   @param  initStatus  (string) the default status message
1997	   @param  monthNames  (string[12]) the names of the months
1998	   @return  (string) the HTML for the month and year */
1999	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
2000			cursorDate, secondary, useTR, showStatus, initStatus, monthNames) {
2001		var minDraw = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1));
2002		minDate = (minDate && minDraw < minDate ? minDraw : minDate);
2003		var changeMonth = this._get(inst, 'changeMonth');
2004		var changeYear = this._get(inst, 'changeYear');
2005		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
2006		var html = '<div class="' + this._monthYearClass[useTR] + '">';
2007		var monthHtml = '';
2008		// Month selection
2009		if (secondary || !changeMonth)
2010			monthHtml += '<span class="' + this._monthClass[useTR] + '">' +
2011				monthNames[drawMonth] + '</span>';
2012		else {
2013			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
2014			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
2015			monthHtml += '<select class="' + this._monthSelectClass[useTR] + '" ' +
2016				'onchange="jQuery.datepick._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
2017				'onclick="jQuery.datepick._clickMonthYear(\'#' + inst.id + '\');"' +
2018				this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'monthStatus'),
2019				initStatus) + '>';
2020			for (var month = 0; month < 12; month++) {
2021				if ((!inMinYear || month >= minDate.getMonth()) &&
2022						(!inMaxYear || month <= maxDate.getMonth()))
2023					monthHtml += '<option value="' + month + '"' +
2024						(month == drawMonth ? ' selected="selected"' : '') +
2025						'>' + monthNames[month] + '</option>';
2026			}
2027			monthHtml += '</select>';
2028		}
2029		if (!showMonthAfterYear)
2030			html += monthHtml + (secondary || !changeMonth || !changeYear ? '&#xa0;' : '');
2031		// Year selection
2032		if (secondary || !changeYear)
2033			html += '<span class="' + this._yearClass[useTR] + '">' + drawYear + '</span>';
2034		else {
2035			// Determine range of years to display
2036			var years = this._get(inst, 'yearRange').split(':');
2037			var year = 0;
2038			var endYear = 0;
2039			if (years.length != 2) {
2040				year = drawYear - 10;
2041				endYear = drawYear + 10;
2042			} else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
2043				year = drawYear + parseInt(years[0], 10);
2044				endYear = drawYear + parseInt(years[1], 10);
2045			} else {
2046				year = parseInt(years[0], 10);
2047				endYear = parseInt(years[1], 10);
2048			}
2049			year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
2050			endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
2051			html += '<select class="' + this._yearSelectClass[useTR] + '" ' +
2052				'onchange="jQuery.datepick._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
2053				'onclick="jQuery.datepick._clickMonthYear(\'#' + inst.id + '\');"' +
2054				this._addStatus(useTR, showStatus, inst.id, this._get(inst, 'yearStatus'),
2055				initStatus) + '>';
2056			for (; year <= endYear; year++) {
2057				html += '<option value="' + year + '"' +
2058					(year == drawYear ? ' selected="selected"' : '') +
2059					'>' + year + '</option>';
2060			}
2061			html += '</select>';
2062		}
2063		html += this._get(inst, 'yearSuffix');
2064		if (showMonthAfterYear)
2065			html += (secondary || !changeMonth || !changeYear ? '&#xa0;' : '') + monthHtml;
2066		html += '</div>'; // Close datepicker_header
2067		return html;
2068	},
2069
2070	/* Provide code to set and clear the status panel.
2071	   @param  useTR       (number) 1 if applying ThemeRoller styling, 0 if not
2072	   @param  showStatus  (boolean) true if the status bar is shown
2073	   @param  id          (string) the ID of the datepicker instance
2074	   @param  text        (string) the status text to display
2075	   @param  initStatus  (string) the default status message
2076	   @return  (string) hover actions for the status messages */
2077	_addStatus: function(useTR, showStatus, id, text, initStatus) {
2078		return (showStatus ? ' onmouseover="jQuery(\'#' + this._statusId[useTR] + id +
2079			'\').html(\'' + (text || initStatus) + '\');" ' +
2080			'onmouseout="jQuery(\'#' + this._statusId[useTR] + id +
2081			'\').html(\'' + initStatus + '\');"' : '');
2082	},
2083
2084	/* Adjust one of the date sub-fields.
2085	   @param  inst    (object) the instance settings for this datepicker
2086	   @param  offset  (number) the change to apply
2087	   @param  period  (string) 'D' for days, 'M' for months, 'Y' for years */
2088	_adjustInstDate: function(inst, offset, period) {
2089		var yearMonth = inst.drawYear + '/' + inst.drawMonth;
2090		var year = inst.drawYear + (period == 'Y' ? offset : 0);
2091		var month = inst.drawMonth + (period == 'M' ? offset : 0);
2092		var day = Math.min(inst.cursorDate.getDate(), this._getDaysInMonth(year, month)) +
2093			(period == 'D' ? offset : 0);
2094		inst.cursorDate = this._restrictMinMax(inst,
2095			this._daylightSavingAdjust(new Date(year, month, day)));
2096		inst.drawMonth = inst.cursorDate.getMonth();
2097		inst.drawYear = inst.cursorDate.getFullYear();
2098		if (yearMonth != inst.drawYear + '/' + inst.drawMonth)
2099			this._notifyChange(inst);
2100	},
2101
2102	/* Ensure a date is within any min/max bounds.
2103	   @param  inst  (object) the instance settings for this datepicker
2104	   @param  date  (Date) the date to check
2105	   @return  (Date) the restricted date */
2106	_restrictMinMax: function(inst, date) {
2107		var minDate = this._getMinMaxDate(inst, 'min', true);
2108		var maxDate = this._getMinMaxDate(inst, 'max');
2109		date = (minDate && date < minDate ? new Date(minDate.getTime()) : date);
2110		date = (maxDate && date > maxDate ? new Date(maxDate.getTime()) : date);
2111		return date;
2112	},
2113
2114	/* Notify change of month/year.
2115	   @param  inst  (object) the instance settings for this datepicker */
2116	_notifyChange: function(inst) {
2117		var onChange = this._get(inst, 'onChangeMonthYear');
2118		if (onChange)
2119			onChange.apply((inst.input ? inst.input[0] : null),
2120				[inst.cursorDate.getFullYear(), inst.cursorDate.getMonth() + 1,
2121				this._daylightSavingAdjust(new Date(
2122				inst.cursorDate.getFullYear(), inst.cursorDate.getMonth(), 1)), inst]);
2123	},
2124
2125	/* Determine the number of months to show.
2126	   @param  inst  (object) the instance settings for this datepicker
2127	   @return  (number[2]) the number of rows and columns to display */
2128	_getNumberOfMonths: function(inst) {
2129		var numMonths = this._get(inst, 'numberOfMonths');
2130		return (numMonths == null ? [1, 1] :
2131			(typeof numMonths == 'number' ? [1, numMonths] : numMonths));
2132	},
2133
2134	/* Determine the current minimum/maximum date.
2135	   Ensure no time components are set. May be overridden for a range.
2136	   @param  inst        (object) the instance settings for this datepicker
2137	   @param  minMax      (string) 'min' or 'max' for required date
2138	   @param  checkRange  (boolean) true to allow override for a range minimum
2139	   @return  (Date) the minimum/maximum date or null if none */
2140	_getMinMaxDate: function(inst, minMax, checkRange) {
2141		var date = this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
2142		var rangeMin = this._getRangeMin(inst);
2143		return (checkRange && rangeMin && (!date || rangeMin > date) ? rangeMin : date);
2144	},
2145
2146	/* Retrieve the temporary range minimum when in the process of selecting.
2147	   @param  inst  (object) the instance settings for this datepicker
2148	   @return  (Date) the temporary minimum or null */
2149	_getRangeMin: function(inst) {
2150		return (this._get(inst, 'rangeSelect') && inst.dates[0] &&
2151			!inst.dates[1] ? inst.dates[0] : null);
2152	},
2153
2154	/* Find the number of days in a given month.
2155	   @param  year   (number) the full year
2156	   @param  month  (number) the month (0 to 11)
2157	   @return  (number) the number of days in this month */
2158	_getDaysInMonth: function(year, month) {
2159		return 32 - new Date(year, month, 32).getDate();
2160	},
2161
2162	/* Find the day of the week of the first of a month.
2163	   @param  year   (number) the full year
2164	   @param  month  (number) the month (0 to 11)
2165	   @return  (number) 0 = Sunday, 1 = Monday, ... */
2166	_getFirstDayOfMonth: function(year, month) {
2167		return new Date(year, month, 1).getDay();
2168	},
2169
2170	/* Determines if we should allow a "prev/next" month display change.
2171	   @param  inst      (object) the instance settings for this datepicker
2172	   @param  offset    (number) the number of months to change by
2173	   @param  curYear   (number) the full current year
2174	   @param  curMonth  (number) the current month (0 to 11)
2175	   @return  (boolean) true if prev/next allowed, false if not */
2176	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
2177		var numMonths = this._getNumberOfMonths(inst);
2178		var date = this._daylightSavingAdjust(new Date(curYear,
2179			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
2180		if (offset < 0)
2181			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
2182		return this._isInRange(inst, date);
2183	},
2184
2185	/* Is the given date in the accepted range?
2186	   @param  inst  (object) the instance settings for this datepicker
2187	   @param  date  (Date) the date to check
2188	   @return  (boolean) true if the date is in the allowed minimum/maximum, false if not */
2189	_isInRange: function(inst, date) {
2190		// During range selection, use minimum of selected date and range start
2191		var minDate = this._getRangeMin(inst) || this._getMinMaxDate(inst, 'min');
2192		var maxDate = this._getMinMaxDate(inst, 'max');
2193		return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
2194	},
2195
2196	/* Provide the configuration settings for formatting/parsing.
2197	   @param  inst  (object) the instance settings for this datepicker
2198	   @return  (object) the settings subset */
2199	_getFormatConfig: function(inst) {
2200		return {shortYearCutoff: this._get(inst, 'shortYearCutoff'),
2201			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
2202			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
2203	},
2204
2205	/* Format the given date for display.
2206	   @param  inst   (object) the instance settings for this datepicker
2207	   @param  year   (number, optional) the full year
2208	   @param  month  (number, optional) the month of the year (0 to 11)
2209	   @param  day    (number, optional) the day of the month
2210	   @return  (string) formatted date */
2211	_formatDate: function(inst, year, month, day) {
2212		if (!year)
2213			inst.dates[0] = new Date(inst.cursorDate.getTime());
2214		var date = (year ? (typeof year == 'object' ? year :
2215			this._daylightSavingAdjust(new Date(year, month, day))) : inst.dates[0]);
2216		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
2217	}
2218});
2219
2220/* jQuery extend now ignores nulls!
2221   @param  target  (object) the object to extend
2222   @param  props   (object) the new settings
2223   @return  (object) the updated object */
2224function extendRemove(target, props) {
2225	$.extend(target, props);
2226	for (var name in props)
2227		if (props[name] == null || props[name] == undefined)
2228			target[name] = props[name];
2229	return target;
2230};
2231
2232/* Determine whether an object is an array.
2233   @param  a  (object) the object to test
2234   @return  (boolean) true if an array, false if not */
2235function isArray(a) {
2236	return (a && a.constructor == Array);
2237};
2238
2239/* Invoke the datepicker functionality.
2240   @param  options  (string) a command, optionally followed by additional parameters or
2241                    (object) settings for attaching new datepicker functionality
2242   @return  (jQuery) jQuery object */
2243$.fn.datepick = function(options){
2244	var otherArgs = Array.prototype.slice.call(arguments, 1);
2245	if (typeof options == 'string' && (options == 'isDisabled' ||
2246			options == 'getDate' || options == 'settings'))
2247		return $.datepick['_' + options + 'Datepick'].
2248			apply($.datepick, [this[0]].concat(otherArgs));
2249	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
2250		return $.datepick['_' + options + 'Datepick'].
2251			apply($.datepick, [this[0]].concat(otherArgs));
2252	return this.each(function() {
2253		typeof options == 'string' ?
2254			$.datepick['_' + options + 'Datepick'].
2255				apply($.datepick, [this].concat(otherArgs)) :
2256			$.datepick._attachDatepick(this, options);
2257	});
2258};
2259
2260$.datepick = new Datepick(); // Singleton instance
2261
2262$(function() {
2263
2264	$( document ).on( 'mousedown', $.datepick._checkExternalClick ).find( 'body' ).append( $.datepick.dpDiv );			// FixIn: 8.7.11.12.
2265});
2266
2267})(jQuery);

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.