PageSourceSearch

https://dgmmalaysia.com/wp-content/plugins/booking/js/datepick/jquery.datepick.wpbc.9.0.js?ver=11.7

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