PageSourceSearch

https://www.corporatekeysaustralia.com.au/__assets/js/search-listing/vendor/calendar/calendar.js

js corporatekeysaustralia.com.au collected 2026-09-26 16:36:21 UTC 47,758 bytes, 1,780 lines download raw bytes

1/** The Calendar object constructor. */
2Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
3	// member variables
4	this.activeDiv = null;
5	this.currentDateEl = null;
6	this.getDateStatus = null;
7	this.getDateToolTip = null;
8	this.getDateText = null;
9	this.timeout = null;
10	this.onSelected = onSelected || null;
11	this.onClose = onClose || null;
12	this.dragging = false;
13	this.hidden = false;
14	this.minYear = 1970;
15	this.maxYear = 2050;
16	this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
17	this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
18	this.isPopup = true;
19	this.weekNumbers = true;
20	this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc.
21	this.showsOtherMonths = false;
22	this.dateStr = dateStr;
23	this.ar_days = null;
24	this.showsTime = false;
25	this.time24 = true;
26	this.yearStep = 2;
27	this.hiliteToday = true;
28	this.multiple = null;
29	// HTML elements
30	this.table = null;
31	this.element = null;
32	this.tbody = null;
33	this.firstdayname = null;
34	// Combo boxes
35	this.monthsCombo = null;
36	this.yearsCombo = null;
37	this.hilitedMonth = null;
38	this.activeMonth = null;
39	this.hilitedYear = null;
40	this.activeYear = null;
41	// Information
42	this.dateClicked = false;
43
44	// one-time initializations
45	if (typeof Calendar._SDN == "undefined") {
46		// table of short day names
47		if (typeof Calendar._SDN_len == "undefined")
48			Calendar._SDN_len = 3;
49		var ar = new Array();
50		for (var i = 8; i > 0;) {
51			ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
52		}
53		Calendar._SDN = ar;
54		// table of short month names
55		if (typeof Calendar._SMN_len == "undefined")
56			Calendar._SMN_len = 3;
57		ar = new Array();
58		for (var i = 12; i > 0;) {
59			ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
60		}
61		Calendar._SMN = ar;
62	}
63};
64
65// ** constants
66
67/// "static", needed for event handlers.
68Calendar._C = null;
69
70/// detect a special case of "web browser"
71Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
72		   !/opera/i.test(navigator.userAgent) );
73
74Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
75
76/// detect Opera browser
77Calendar.is_opera = /opera/i.test(navigator.userAgent);
78
79/// detect KHTML-based browsers
80Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
81
82// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
83//        library, at some point.
84
85Calendar.getAbsolutePos = function(el) {
86	var SL = 0, ST = 0;
87	var is_div = /^div$/i.test(el.tagName);
88	if (is_div && el.scrollLeft)
89		SL = el.scrollLeft;
90	if (is_div && el.scrollTop)
91		ST = el.scrollTop;
92	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
93	if (el.offsetParent) {
94		var tmp = this.getAbsolutePos(el.offsetParent);
95		r.x += tmp.x;
96		r.y += tmp.y;
97	}
98	return r;
99};
100
101Calendar.isRelated = function (el, evt) {
102	var related = evt.relatedTarget;
103	if (!related) {
104		var type = evt.type;
105		if (type == "mouseover") {
106			related = evt.fromElement;
107		} else if (type == "mouseout") {
108			related = evt.toElement;
109		}
110	}
111	while (related) {
112		if (related == el) {
113			return true;
114		}
115		related = related.parentNode;
116	}
117	return false;
118};
119
120Calendar.removeClass = function(el, className) {
121	if (!(el && el.className)) {
122		return;
123	}
124	var cls = el.className.split(" ");
125	var ar = new Array();
126	for (var i = cls.length; i > 0;) {
127		if (cls[--i] != className) {
128			ar[ar.length] = cls[i];
129		}
130	}
131	el.className = ar.join(" ");
132};
133
134Calendar.addClass = function(el, className) {
135	Calendar.removeClass(el, className);
136	el.className += " " + className;
137};
138
139// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
140Calendar.getElement = function(ev) {
141	var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
142	while (f.nodeType != 1 || /^div$/i.test(f.tagName))
143		f = f.parentNode;
144	return f;
145};
146
147Calendar.getTargetElement = function(ev) {
148	var f = Calendar.is_ie ? window.event.srcElement : ev.target;
149	while (f.nodeType != 1)
150		f = f.parentNode;
151	return f;
152};
153
154Calendar.stopEvent = function(ev) {
155	ev || (ev = window.event);
156	if (Calendar.is_ie) {
157		ev.cancelBubble = true;
158		ev.returnValue = false;
159	} else {
160		ev.preventDefault();
161		ev.stopPropagation();
162	}
163	return false;
164};
165
166Calendar.addEvent = function(el, evname, func) {
167	if (el.attachEvent) { // IE
168		el.attachEvent("on" + evname, func);
169	} else if (el.addEventListener) { // Gecko / W3C
170		el.addEventListener(evname, func, true);
171	} else {
172		el["on" + evname] = func;
173	}
174};
175
176Calendar.removeEvent = function(el, evname, func) {
177	if (el.detachEvent) { // IE
178		el.detachEvent("on" + evname, func);
179	} else if (el.removeEventListener) { // Gecko / W3C
180		el.removeEventListener(evname, func, true);
181	} else {
182		el["on" + evname] = null;
183	}
184};
185
186Calendar.createElement = function(type, parent) {
187	var el = null;
188	if (document.createElementNS) {
189		// use the XHTML namespace; IE won't normally get here unless
190		// _they_ "fix" the DOM2 implementation.
191		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
192	} else {
193		el = document.createElement(type);
194	}
195	if (typeof parent != "undefined") {
196		parent.appendChild(el);
197	}
198	return el;
199};
200
201// END: UTILITY FUNCTIONS
202
203// BEGIN: CALENDAR STATIC FUNCTIONS
204
205/** Internal -- adds a set of events to make some element behave like a button. */
206Calendar._add_evs = function(el) {
207	with (Calendar) {
208		addEvent(el, "mouseover", dayMouseOver);
209		addEvent(el, "mousedown", dayMouseDown);
210		addEvent(el, "mouseout", dayMouseOut);
211		if (is_ie) {
212			addEvent(el, "dblclick", dayMouseDblClick);
213			el.setAttribute("unselectable", true);
214		}
215	}
216};
217
218Calendar.findMonth = function(el) {
219	if (typeof el.month != "undefined") {
220		return el;
221	} else if (typeof el.parentNode.month != "undefined") {
222		return el.parentNode;
223	}
224	return null;
225};
226
227Calendar.findYear = function(el) {
228	if (typeof el.year != "undefined") {
229		return el;
230	} else if (typeof el.parentNode.year != "undefined") {
231		return el.parentNode;
232	}
233	return null;
234};
235
236Calendar.showMonthsCombo = function () {
237	var cal = Calendar._C;
238	if (!cal) {
239		return false;
240	}
241	var cal = cal;
242	var cd = cal.activeDiv;
243	var mc = cal.monthsCombo;
244	if (cal.hilitedMonth) {
245		Calendar.removeClass(cal.hilitedMonth, "hilite");
246	}
247	if (cal.activeMonth) {
248		Calendar.removeClass(cal.activeMonth, "active");
249	}
250	var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
251	Calendar.addClass(mon, "active");
252	cal.activeMonth = mon;
253	var s = mc.style;
254	s.display = "block";
255	if (cd.navtype < 0)
256		s.left = cd.offsetLeft + "px";
257	else {
258		var mcw = mc.offsetWidth;
259		if (typeof mcw == "undefined")
260			// Konqueror brain-dead techniques
261			mcw = 50;
262		s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
263	}
264	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
265};
266
267Calendar.showYearsCombo = function (fwd) {
268	var cal = Calendar._C;
269	if (!cal) {
270		return false;
271	}
272	var cal = cal;
273	var cd = cal.activeDiv;
274	var yc = cal.yearsCombo;
275	if (cal.hilitedYear) {
276		Calendar.removeClass(cal.hilitedYear, "hilite");
277	}
278	if (cal.activeYear) {
279		Calendar.removeClass(cal.activeYear, "active");
280	}
281	cal.activeYear = null;
282	var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
283	var yr = yc.firstChild;
284	var show = false;
285	for (var i = 12; i > 0; --i) {
286		if (Y >= cal.minYear && Y <= cal.maxYear) {
287			yr.innerHTML = Y;
288			yr.year = Y;
289			yr.style.display = "block";
290			show = true;
291		} else {
292			yr.style.display = "none";
293		}
294		yr = yr.nextSibling;
295		Y += fwd ? cal.yearStep : -cal.yearStep;
296	}
297	if (show) {
298		var s = yc.style;
299		s.display = "block";
300		if (cd.navtype < 0)
301			s.left = cd.offsetLeft + "px";
302		else {
303			var ycw = yc.offsetWidth;
304			if (typeof ycw == "undefined")
305				// Konqueror brain-dead techniques
306				ycw = 50;
307			s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
308		}
309		s.top = (cd.offsetTop + cd.offsetHeight) + "px";
310	}
311};
312
313// event handlers
314
315Calendar.tableMouseUp = function(ev) {
316	var cal = Calendar._C;
317	if (!cal) {
318		return false;
319	}
320	if (cal.timeout) {
321		clearTimeout(cal.timeout);
322	}
323	var el = cal.activeDiv;
324	if (!el) {
325		return false;
326	}
327	var target = Calendar.getTargetElement(ev);
328	ev || (ev = window.event);
329	Calendar.removeClass(el, "active");
330	if (target == el || target.parentNode == el) {
331		Calendar.cellClick(el, ev);
332	}
333	var mon = Calendar.findMonth(target);
334	var date = null;
335	if (mon) {
336		date = new Date(cal.date);
337		if (mon.month != date.getMonth()) {
338			date.setMonth(mon.month);
339			cal.setDate(date);
340			cal.dateClicked = false;
341			cal.callHandler();
342		}
343	} else {
344		var year = Calendar.findYear(target);
345		if (year) {
346			date = new Date(cal.date);
347			if (year.year != date.getFullYear()) {
348				date.setFullYear(year.year);
349				cal.setDate(date);
350				cal.dateClicked = false;
351				cal.callHandler();
352			}
353		}
354	}
355
356	// HOOK! ROMAR!
357	jQuery("#clear-date-filter").prop("disabled", false);
358
359	with (Calendar) {
360		removeEvent(document, "mouseup", tableMouseUp);
361		removeEvent(document, "mouseover", tableMouseOver);
362		removeEvent(document, "mousemove", tableMouseOver);
363		cal._hideCombos();
364		_C = null;
365		return stopEvent(ev);
366	}
367};
368
369Calendar.tableMouseOver = function (ev) {
370	var cal = Calendar._C;
371	if (!cal) {
372		return;
373	}
374	var el = cal.activeDiv;
375	var target = Calendar.getTargetElement(ev);
376	if (target == el || target.parentNode == el) {
377		Calendar.addClass(el, "hilite active");
378		Calendar.addClass(el.parentNode, "rowhilite");
379	} else {
380		if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
381			Calendar.removeClass(el, "active");
382		Calendar.removeClass(el, "hilite");
383		Calendar.removeClass(el.parentNode, "rowhilite");
384	}
385	ev || (ev = window.event);
386	if (el.navtype == 50 && target != el) {
387		var pos = Calendar.getAbsolutePos(el);
388		var w = el.offsetWidth;
389		var x = ev.clientX;
390		var dx;
391		var decrease = true;
392		if (x > pos.x + w) {
393			dx = x - pos.x - w;
394			decrease = false;
395		} else
396			dx = pos.x - x;
397
398		if (dx < 0) dx = 0;
399		var range = el._range;
400		var current = el._current;
401		var count = Math.floor(dx / 10) % range.length;
402		for (var i = range.length; --i >= 0;)
403			if (range[i] == current)
404				break;
405		while (count-- > 0)
406			if (decrease) {
407				if (--i < 0)
408					i = range.length - 1;
409			} else if ( ++i >= range.length )
410				i = 0;
411		var newval = range[i];
412		el.innerHTML = newval;
413
414		cal.onUpdateTime();
415	}
416	var mon = Calendar.findMonth(target);
417	if (mon) {
418		if (mon.month != cal.date.getMonth()) {
419			if (cal.hilitedMonth) {
420				Calendar.removeClass(cal.hilitedMonth, "hilite");
421			}
422			Calendar.addClass(mon, "hilite");
423			cal.hilitedMonth = mon;
424		} else if (cal.hilitedMonth) {
425			Calendar.removeClass(cal.hilitedMonth, "hilite");
426		}
427	} else {
428		if (cal.hilitedMonth) {
429			Calendar.removeClass(cal.hilitedMonth, "hilite");
430		}
431		var year = Calendar.findYear(target);
432		if (year) {
433			if (year.year != cal.date.getFullYear()) {
434				if (cal.hilitedYear) {
435					Calendar.removeClass(cal.hilitedYear, "hilite");
436				}
437				Calendar.addClass(year, "hilite");
438				cal.hilitedYear = year;
439			} else if (cal.hilitedYear) {
440				Calendar.removeClass(cal.hilitedYear, "hilite");
441			}
442		} else if (cal.hilitedYear) {
443			Calendar.removeClass(cal.hilitedYear, "hilite");
444		}
445	}
446	return Calendar.stopEvent(ev);
447};
448
449Calendar.tableMouseDown = function (ev) {
450	if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
451		return Calendar.stopEvent(ev);
452	}
453};
454
455Calendar.calDragIt = function (ev) {
456	var cal = Calendar._C;
457	if (!(cal && cal.dragging)) {
458		return false;
459	}
460	var posX;
461	var posY;
462	if (Calendar.is_ie) {
463		posY = window.event.clientY + document.body.scrollTop;
464		posX = window.event.clientX + document.body.scrollLeft;
465	} else {
466		posX = ev.pageX;
467		posY = ev.pageY;
468	}
469	cal.hideShowCovered();
470	var st = cal.element.style;
471	st.left = (posX - cal.xOffs) + "px";
472	st.top = (posY - cal.yOffs) + "px";
473	return Calendar.stopEvent(ev);
474};
475
476Calendar.calDragEnd = function (ev) {
477	var cal = Calendar._C;
478	if (!cal) {
479		return false;
480	}
481	cal.dragging = false;
482	with (Calendar) {
483		removeEvent(document, "mousemove", calDragIt);
484		removeEvent(document, "mouseup", calDragEnd);
485		tableMouseUp(ev);
486	}
487	cal.hideShowCovered();
488};
489
490Calendar.dayMouseDown = function(ev) {
491	var el = Calendar.getElement(ev);
492	if (el.disabled) {
493		return false;
494	}
495	var cal = el.calendar;
496	cal.activeDiv = el;
497	Calendar._C = cal;
498	if (el.navtype != 300) with (Calendar) {
499		if (el.navtype == 50) {
500			el._current = el.innerHTML;
501			addEvent(document, "mousemove", tableMouseOver);
502		} else
503			addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
504		addClass(el, "hilite active");
505		addEvent(document, "mouseup", tableMouseUp);
506	} else if (cal.isPopup) {
507		cal._dragStart(ev);
508	}
509	if (el.navtype == -1 || el.navtype == 1) {
510		if (cal.timeout) clearTimeout(cal.timeout);
511		cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
512	} else if (el.navtype == -2 || el.navtype == 2) {
513		if (cal.timeout) clearTimeout(cal.timeout);
514		cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
515	} else {
516		cal.timeout = null;
517	}
518	return Calendar.stopEvent(ev);
519};
520
521Calendar.dayMouseDblClick = function(ev) {
522	Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
523	if (Calendar.is_ie) {
524		document.selection.empty();
525	}
526};
527
528Calendar.dayMouseOver = function(ev) {
529	var el = Calendar.getElement(ev);
530	if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
531		return false;
532	}
533	if (el.ttip) {
534		if (el.ttip.substr(0, 1) == "_") {
535			el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
536		}
537		el.calendar.tooltips.innerHTML = el.ttip;
538	}
539	if (el.navtype != 300) {
540		Calendar.addClass(el, "hilite");
541		if (el.caldate) {
542			Calendar.addClass(el.parentNode, "rowhilite");
543		}
544	}
545	return Calendar.stopEvent(ev);
546};
547
548Calendar.dayMouseOut = function(ev) {
549	with (Calendar) {
550		var el = getElement(ev);
551		if (isRelated(el, ev) || _C || el.disabled)
552			return false;
553		removeClass(el, "hilite");
554		if (el.caldate)
555			removeClass(el.parentNode, "rowhilite");
556		if (el.calendar)
557			el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
558		return stopEvent(ev);
559	}
560};
561
562/**
563 *  A generic "click" handler :) handles all types of buttons defined in this
564 *  calendar.
565 */
566Calendar.cellClick = function(el, ev) {
567	var cal = el.calendar;
568	var closing = false;
569	var newdate = false;
570	var date = null;
571	if (typeof el.navtype == "undefined") {
572		if (cal.currentDateEl) {
573			Calendar.removeClass(cal.currentDateEl, "selected");
574			Calendar.addClass(el, "selected");
575			closing = (cal.currentDateEl == el);
576			if (!closing) {
577				cal.currentDateEl = el;
578			}
579		}
580		cal.date.setDateOnly(el.caldate);
581		date = cal.date;
582		var other_month = !(cal.dateClicked = !el.otherMonth);
583		if (!other_month && !cal.currentDateEl)
584			cal._toggleMultipleDate(new Date(date));
585		else
586			newdate = !el.disabled;
587		// a date was clicked
588		if (other_month)
589			cal._init(cal.firstDayOfWeek, date);
590	} else {
591		if (el.navtype == 200) {
592			Calendar.removeClass(el, "hilite");
593			cal.callCloseHandler();
594			return;
595		}
596		date = new Date(cal.date);
597		if (el.navtype == 0)
598			date.setDateOnly(new Date()); // TODAY
599		// unless "today" was clicked, we assume no date was clicked so
600		// the selected handler will know not to close the calenar when
601		// in single-click mode.
602		// cal.dateClicked = (el.navtype == 0);
603		cal.dateClicked = false;
604		var year = date.getFullYear();
605		var mon = date.getMonth();
606		function setMonth(m) {
607			var day = date.getDate();
608			var max = date.getMonthDays(m);
609			if (day > max) {
610				date.setDate(max);
611			}
612			date.setMonth(m);
613		};
614		switch (el.navtype) {
615		    case 400:
616			Calendar.removeClass(el, "hilite");
617			var text = Calendar._TT["ABOUT"];
618			if (typeof text != "undefined") {
619				text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
620			} else {
621				// FIXME: this should be removed as soon as lang files get updated!
622				text = "Help text here";
623			}
624			alert(text);
625			return;
626		    case -2:
627			if (year > cal.minYear) {
628				date.setFullYear(year - 1);
629			}
630			break;
631		    case -1:
632			if (mon > 0) {
633				setMonth(mon - 1);
634			} else if (year-- > cal.minYear) {
635				date.setFullYear(year);
636				setMonth(11);
637			}
638			break;
639		    case 1:
640			if (mon < 11) {
641				setMonth(mon + 1);
642			} else if (year < cal.maxYear) {
643				date.setFullYear(year + 1);
644				setMonth(0);
645			}
646			break;
647		    case 2:
648			if (year < cal.maxYear) {
649				date.setFullYear(year + 1);
650			}
651			break;
652		    case 100:
653			cal.setFirstDayOfWeek(el.fdow);
654			return;
655		    case 50:
656			var range = el._range;
657			var current = el.innerHTML;
658			for (var i = range.length; --i >= 0;)
659				if (range[i] == current)
660					break;
661			if (ev && ev.shiftKey) {
662				if (--i < 0)
663					i = range.length - 1;
664			} else if ( ++i >= range.length )
665				i = 0;
666			var newval = range[i];
667			el.innerHTML = newval;
668			cal.onUpdateTime();
669			return;
670		    case 0:
671			// TODAY will bring us here
672			if ((typeof cal.getDateStatus == "function") &&
673			    cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
674				return false;
675			}
676			break;
677		}
678		if (!date.equalsTo(cal.date)) {
679			cal.setDate(date);
680			newdate = true;
681		} else if (el.navtype == 0)
682			newdate = closing = true;
683	}
684	if (newdate) {
685		ev && cal.callHandler();
686	}
687	if (closing) {
688		Calendar.removeClass(el, "hilite");
689		ev && cal.callCloseHandler();
690	}
691};
692
693
694Calendar.prototype.create = function (_par) {
695	var parent = null;
696	if (! _par) {
697		// default parent is the document body, in which case we create
698		// a popup calendar.
699		parent = document.getElementsByTagName("body")[0];
700		this.isPopup = true;
701	} else {
702		parent = _par;
703		this.isPopup = false;
704	}
705	this.date = this.dateStr ? new Date(this.dateStr) : new Date();
706
707	var table = Calendar.createElement("table");
708	this.table = table;
709	table.cellSpacing = 0;
710	table.cellPadding = 0;
711	table.calendar = this;
712	Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);
713
714	var div = Calendar.createElement("div");
715	this.element = div;
716	div.className = "calendar";
717	if (this.isPopup) {
718		div.style.position = "absolute";
719		div.style.display = "none";
720	}
721	div.appendChild(table);
722
723	var thead = Calendar.createElement("thead", table);
724	var cell = null;
725	var row = null;
726
727	var cal = this;
728	var hh = function (text, cs, navtype) {
729		cell = Calendar.createElement("td", row);
730		cell.colSpan = cs;
731		cell.className = "button";
732		if (navtype != 0 && Math.abs(navtype) <= 2)
733			cell.className += " nav";
734		Calendar._add_evs(cell);
735		cell.calendar = cal;
736		cell.navtype = navtype;
737		cell.innerHTML = "<div unselectable='on'>
737" + text + "</div>";
738		return cell;
739	};
740
741	row = Calendar.createElement("tr", thead);
742	var title_length = 6;
743	(this.isPopup) && --title_length;
744	(this.weekNumbers) && ++title_length;
745
746	hh("?", 1, 400).ttip = Calendar._TT["INFO"];
747	this.title = hh("", title_length, 300);
748	this.title.className = "title";
749	if (this.isPopup) {
750		this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
751		this.title.style.cursor = "move";
752		hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
753	}
754
755	row = Calendar.createElement("tr", thead);
756	row.className = "headrow";
757
758	this._nav_py = hh("&#x00ab;", 1, -2);
759	this._nav_py.ttip = Calendar._TT["PREV_YEAR"];
760
761	this._nav_pm = hh("&#x2039;", 1, -1);
762	this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];
763
764	this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
765	this._nav_now.ttip = Calendar._TT["GO_TODAY"];
766
767	this._nav_nm = hh("&#x203a;", 1, 1);
768	this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];
769
770	this._nav_ny = hh("&#x00bb;", 1, 2);
771	this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];
772
773	// day names
774	row = Calendar.createElement("tr", thead);
775	row.className = "daynames";
776	if (this.weekNumbers) {
777		cell = Calendar.createElement("td", row);
778		cell.className = "name wn";
779		cell.innerHTML = Calendar._TT["WK"];
780	}
781	for (var i = 7; i > 0; --i) {
782		cell = Calendar.createElement("td", row);
783		if (!i) {
784			cell.navtype = 100;
785			cell.calendar = this;
786			Calendar._add_evs(cell);
787		}
788	}
789	this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
790	this._displayWeekdays();
791
792	var tbody = Calendar.createElement("tbody", table);
793	this.tbody = tbody;
794
795	for (i = 6; i > 0; --i) {
796		row = Calendar.createElement("tr", tbody);
797		if (this.weekNumbers) {
798			cell = Calendar.createElement("td", row);
799		}
800		for (var j = 7; j > 0; --j) {
801			cell = Calendar.createElement("td", row);
802			cell.calendar = this;
803			Calendar._add_evs(cell);
804		}
805	}
806
807	if (this.showsTime) {
808		row = Calendar.createElement("tr", tbody);
809		row.className = "time";
810
811		cell = Calendar.createElement("td", row);
812		cell.className = "time";
813		cell.colSpan = 2;
814		cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";
815
816		cell = Calendar.createElement("td", row);
817		cell.className = "time";
818		cell.colSpan = this.weekNumbers ? 4 : 3;
819
820		(function(){
821			function makeTimePart(className, init, range_start, range_end) {
822				var part = Calendar.createElement("span", cell);
823				part.className = className;
824				part.innerHTML = init;
825				part.calendar = cal;
826				part.ttip = Calendar._TT["TIME_PART"];
827				part.navtype = 50;
828				part._range = [];
829				if (typeof range_start != "number")
830					part._range = range_start;
831				else {
832					for (var i = range_start; i <= range_end; ++i) {
833						var txt;
834						if (i < 10 && range_end >= 10) txt = '0' + i;
835						else txt = '' + i;
836						part._range[part._range.length] = txt;
837					}
838				}
839				Calendar._add_evs(part);
840				return part;
841			};
842			var hrs = cal.date.getHours();
843			var mins = cal.date.getMinutes();
844			var t12 = !cal.time24;
845			var pm = (hrs > 12);
846			if (t12 && pm) hrs -= 12;
847			var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
848			var span = Calendar.createElement("span", cell);
849			span.innerHTML = ":";
850			span.className = "colon";
851			var M = makeTimePart("minute", mins, 0, 59);
852			var AP = null;
853			cell = Calendar.createElement("td", row);
854			cell.className = "time";
855			cell.colSpan = 2;
856			if (t12)
857				AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
858			else
859				cell.innerHTML = "&nbsp;";
860
861			cal.onSetTime = function() {
862				var pm, hrs = this.date.getHours(),
863					mins = this.date.getMinutes();
864				if (t12) {
865					pm = (hrs >= 12);
866					if (pm) hrs -= 12;
867					if (hrs == 0) hrs = 12;
868					AP.innerHTML = pm ? "pm" : "am";
869				}
870				H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
871				M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
872			};
873
874			cal.onUpdateTime = function() {
875				var date = this.date;
876				var h = parseInt(H.innerHTML, 10);
877				if (t12) {
878					if (/pm/i.test(AP.innerHTML) && h < 12)
879						h += 12;
880					else if (/am/i.test(AP.innerHTML) && h == 12)
881						h = 0;
882				}
883				var d = date.getDate();
884				var m = date.getMonth();
885				var y = date.getFullYear();
886				date.setHours(h);
887				date.setMinutes(parseInt(M.innerHTML, 10));
888				date.setFullYear(y);
889				date.setMonth(m);
890				date.setDate(d);
891				this.dateClicked = false;
892				this.callHandler();
893			};
894		})();
895	} else {
896		this.onSetTime = this.onUpdateTime = function() {};
897	}
898
899	var tfoot = Calendar.createElement("tfoot", table);
900
901	row = Calendar.createElement("tr", tfoot);
902	row.className = "footrow";
903
904	cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
905	cell.className = "ttip";
906	if (this.isPopup) {
907		cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
908		cell.style.cursor = "move";
909	}
910	this.tooltips = cell;
911
912	div = Calendar.createElement("div", this.element);
913	this.monthsCombo = div;
914	div.className = "combo";
915	for (i = 0; i < Calendar._MN.length; ++i) {
916		var mn = Calendar.createElement("div");
917		mn.className = Calendar.is_ie ? "label-IEfix" : "label";
918		mn.month = i;
919		mn.innerHTML = Calendar._SMN[i];
920		div.appendChild(mn);
921	}
922
923	div = Calendar.createElement("div", this.element);
924	this.yearsCombo = div;
925	div.className = "combo";
926	for (i = 12; i > 0; --i) {
927		var yr = Calendar.createElement("div");
928		yr.className = Calendar.is_ie ? "label-IEfix" : "label";
929		div.appendChild(yr);
930	}
931
932	this._init(this.firstDayOfWeek, this.date);
933	parent.appendChild(this.element);
934};
935
936/** keyboard navigation, only for popup calendars */
937Calendar._keyEvent = function(ev) {
938	var cal = window._dynarch_popupCalendar;
939	if (!cal || cal.multiple)
940		return false;
941	(Calendar.is_ie) && (ev = window.event);
942	var act = (Calendar.is_ie || ev.type == "keypress"),
943		K = ev.keyCode;
944	if (ev.ctrlKey) {
945		switch (K) {
946		    case 37: // KEY left
947			act && Calendar.cellClick(cal._nav_pm);
948			break;
949		    case 38: // KEY up
950			act && Calendar.cellClick(cal._nav_py);
951			break;
952		    case 39: // KEY right
953			act && Calendar.cellClick(cal._nav_nm);
954			break;
955		    case 40: // KEY down
956			act && Calendar.cellClick(cal._nav_ny);
957			break;
958		    default:
959			return false;
960		}
961	} else switch (K) {
962	    case 32: // KEY space (now)
963		Calendar.cellClick(cal._nav_now);
964		break;
965	    case 27: // KEY esc
966		act && cal.callCloseHandler();
967		break;
968	    case 37: // KEY left
969	    case 38: // KEY up
970	    case 39: // KEY right
971	    case 40: // KEY down
972		if (act) {
973			var prev, x, y, ne, el, step;
974			prev = K == 37 || K == 38;
975			step = (K == 37 || K == 39) ? 1 : 7;
976			function setVars() {
977				el = cal.currentDateEl;
978				var p = el.pos;
979				x = p & 15;
980				y = p >> 4;
981				ne = cal.ar_days[y][x];
982			};setVars();
983			function prevMonth() {
984				var date = new Date(cal.date);
985				date.setDate(date.getDate() - step);
986				cal.setDate(date);
987			};
988			function nextMonth() {
989				var date = new Date(cal.date);
990				date.setDate(date.getDate() + step);
991				cal.setDate(date);
992			};
993			while (1) {
994				switch (K) {
995				    case 37: // KEY left
996					if (--x >= 0)
997						ne = cal.ar_days[y][x];
998					else {
999						x = 6;
1000						K = 38;
1001						continue;
1002					}
1003					break;
1004				    case 38: // KEY up
1005					if (--y >= 0)
1006						ne = cal.ar_days[y][x];
1007					else {
1008						prevMonth();
1009						setVars();
1010					}
1011					break;
1012				    case 39: // KEY right
1013					if (++x < 7)
1014						ne = cal.ar_days[y][x];
1015					else {
1016						x = 0;
1017						K = 40;
1018						continue;
1019					}
1020					break;
1021				    case 40: // KEY down
1022					if (++y < cal.ar_days.length)
1023						ne = cal.ar_days[y][x];
1024					else {
1025						nextMonth();
1026						setVars();
1027					}
1028					break;
1029				}
1030				break;
1031			}
1032			if (ne) {
1033				if (!ne.disabled)
1034					Calendar.cellClick(ne);
1035				else if (prev)
1036					prevMonth();
1037				else
1038					nextMonth();
1039			}
1040		}
1041		break;
1042	    case 13: // KEY enter
1043		if (act)
1044			Calendar.cellClick(cal.currentDateEl, ev);
1045		break;
1046	    default:
1047		return false;
1048	}
1049	return Calendar.stopEvent(ev);
1050};
1051
1052/**
1053 *  (RE)Initializes the calendar to the given date and firstDayOfWeek
1054 */
1055Calendar.prototype._init = function (firstDayOfWeek, date) {
1056	var today = new Date(),
1057		TY = today.getFullYear(),
1058		TM = today.getMonth(),
1059		TD = today.getDate();
1060	this.table.style.visibility = "hidden";
1061	var year = date.getFullYear();
1062	if (year < this.minYear) {
1063		year = this.minYear;
1064		date.setFullYear(year);
1065	} else if (year > this.maxYear) {
1066		year = this.maxYear;
1067		date.setFullYear(year);
1068	}
1069	this.firstDayOfWeek = firstDayOfWeek;
1070	this.date = new Date(date);
1071	var month = date.getMonth();
1072	var mday = date.getDate();
1073	var no_days = date.getMonthDays();
1074
1075	// WARNING: this is magic. ;-)
1076	date.setDate(1);
1077	var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
1078	if (day1 < 0)
1079		day1 += 7;
1080	date.setDate(-day1);
1081	date.setDate(date.getDate() + 1);
1082
1083	var row = this.tbody.firstChild;
1084	var MN = Calendar._SMN[month];
1085	var ar_days = this.ar_days = new Array();
1086	var weekend = Calendar._TT["WEEKEND"];
1087	var dates = this.multiple ? (this.datesCells = {}) : null;
1088	for (var i = 0; i < 6; ++i, row = row.nextSibling) {
1089		var cell = row.firstChild;
1090		if (this.weekNumbers) {
1091			cell.className = "day wn";
1092			cell.innerHTML = date.getWeekNumber();
1093			cell = cell.nextSibling;
1094		}
1095		row.className = "daysrow";
1096		var hasdays = false, iday, dpos = ar_days[i] = [];
1097		for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
1098			iday = date.getDate();
1099			var wday = date.getDay();
1100			cell.className = "day";
1101			cell.pos = i << 4 | j;
1102			dpos[j] = cell;
1103			var current_month = (date.getMonth() == month);
1104			if (!current_month) {
1105				if (this.showsOtherMonths) {
1106					cell.className += " othermonth";
1107					cell.otherMonth = true;
1108				} else {
1109					cell.className = "emptycell";
1110					cell.innerHTML = "&nbsp;";
1111					cell.disabled = true;
1112					continue;
1113				}
1114			} else {
1115				cell.otherMonth = false;
1116				hasdays = true;
1117			}
1118			cell.disabled = false;
1119			cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
1120			if (dates)
1121				dates[date.print("%Y%m%d")] = cell;
1122			if (this.getDateStatus) {
1123				var status = this.getDateStatus(date, year, month, iday);
1124				if (this.getDateToolTip) {
1125					var toolTip = this.getDateToolTip(date, year, month, iday);
1126					if (toolTip)
1127						cell.title = toolTip;
1128				}
1129				if (status === true) {
1130					cell.className += " disabled";
1131					cell.disabled = true;
1132				} else {
1133					if (/disabled/i.test(status))
1134						cell.disabled = true;
1135					cell.className += " " + status;
1136				}
1137			}
1138			if (!cell.disabled) {
1139				cell.caldate = new Date(date);
1140				cell.ttip = "_";
1141				if (!this.multiple && current_month
1142				    && iday == mday && this.hiliteToday) {
1143					cell.className += " selected";
1144					this.currentDateEl = cell;
1145				}
1146				if (date.getFullYear() == TY &&
1147				    date.getMonth() == TM &&
1148				    iday == TD) {
1149					cell.className += " today";
1150					cell.ttip += Calendar._TT["PART_TODAY"];
1151				}
1152				if (weekend.indexOf(wday.toString()) != -1)
1153					cell.className += cell.otherMonth ? " oweekend" : " weekend";
1154			}
1155		}
1156		if (!(hasdays || this.showsOtherMonths))
1157			row.className = "emptyrow";
1158	}
1159	this.title.innerHTML = Calendar._MN[month] + ", " + year;
1160	this.onSetTime();
1161	this.table.style.visibility = "visible";
1162	this._initMultipleDates();
1163	// PROFILE
1164	// this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
1165};
1166
1167Calendar.prototype._initMultipleDates = function() {
1168	if (this.multiple) {
1169		for (var i in this.multiple) {
1170			var cell = this.datesCells[i];
1171			var d = this.multiple[i];
1172			if (!d)
1173				continue;
1174			if (cell)
1175				cell.className += " selected";
1176		}
1177	}
1178};
1179
1180Calendar.prototype._toggleMultipleDate = function(date) {
1181	if (this.multiple) {
1182		var ds = date.print("%Y%m%d");
1183		var cell = this.datesCells[ds];
1184		if (cell) {
1185			var d = this.multiple[ds];
1186			if (!d) {
1187				Calendar.addClass(cell, "selected");
1188				this.multiple[ds] = date;
1189			} else {
1190				Calendar.removeClass(cell, "selected");
1191				delete this.multiple[ds];
1192			}
1193		}
1194	}
1195};
1196
1197Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
1198	this.getDateToolTip = unaryFunction;
1199};
1200
1201
1202Calendar.prototype.setDate = function (date) {
1203	if (!date.equalsTo(this.date)) {
1204		this._init(this.firstDayOfWeek, date);
1205	}
1206};
1207
1208
1209Calendar.prototype.refresh = function () {
1210	this._init(this.firstDayOfWeek, this.date);
1211};
1212
1213/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
1214Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
1215	this._init(firstDayOfWeek, this.date);
1216	this._displayWeekdays();
1217};
1218
1219/**
1220 *  Allows customization of what dates are enabled.  The "unaryFunction"
1221 *  parameter must be a function object that receives the date (as a JS Date
1222 *  object) and returns a boolean value.  If the returned value is true then
1223 *  the passed date will be marked as disabled.
1224 */
1225Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
1226	this.getDateStatus = unaryFunction;
1227};
1228
1229/** Customization of allowed year range for the calendar. */
1230Calendar.prototype.setRange = function (a, z) {
1231	this.minYear = a;
1232	this.maxYear = z;
1233};
1234
1235/** Calls the first user handler (selectedHandler). */
1236Calendar.prototype.callHandler = function () {
1237	if (this.onSelected) {
1238		this.onSelected(this, this.date.print(this.dateFormat));
1239	}
1240};
1241
1242/** Calls the second user handler (closeHandler). */
1243Calendar.prototype.callCloseHandler = function () {
1244	if (this.onClose) {
1245		this.onClose(this);
1246	}
1247	this.hideShowCovered();
1248};
1249
1250/** Removes the calendar object from the DOM tree and destroys it. */
1251Calendar.prototype.destroy = function () {
1252	var el = this.element.parentNode;
1253	el.removeChild(this.element);
1254	Calendar._C = null;
1255	window._dynarch_popupCalendar = null;
1256};
1257
1258/**
1259 *  Moves the calendar element to a different section in the DOM tree (changes
1260 *  its parent).
1261 */
1262Calendar.prototype.reparent = function (new_parent) {
1263	var el = this.element;
1264	el.parentNode.removeChild(el);
1265	new_parent.appendChild(el);
1266};
1267
1268// This gets called when the user presses a mouse button anywhere in the
1269// document, if the calendar is shown.  If the click was outside the open
1270// calendar this function closes it.
1271Calendar._checkCalendar = function(ev) {
1272	var calendar = window._dynarch_popupCalendar;
1273	if (!calendar) {
1274		return false;
1275	}
1276	var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
1277	for (; el != null && el != calendar.element; el = el.parentNode);
1278	if (el == null) {
1279		// calls closeHandler which should hide the calendar.
1280		window._dynarch_popupCalendar.callCloseHandler();
1281		return Calendar.stopEvent(ev);
1282	}
1283};
1284
1285/** Shows the calendar. */
1286Calendar.prototype.show = function () {
1287	var rows = this.table.getElementsByTagName("tr");
1288	for (var i = rows.length; i > 0;) {
1289		var row = rows[--i];
1290		Calendar.removeClass(row, "rowhilite");
1291		var cells = row.getElementsByTagName("td");
1292		for (var j = cells.length; j > 0;) {
1293			var cell = cells[--j];
1294			Calendar.removeClass(cell, "hilite");
1295			Calendar.removeClass(cell, "active");
1296		}
1297	}
1298	this.element.style.display = "block";
1299	this.hidden = false;
1300	if (this.isPopup) {
1301		window._dynarch_popupCalendar = this;
1302		Calendar.addEvent(document, "keydown", Calendar._keyEvent);
1303		Calendar.addEvent(document, "keypress", Calendar._keyEvent);
1304		Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
1305	}
1306	this.hideShowCovered();
1307};
1308
1309/**
1310 *  Hides the calendar.  Also removes any "hilite" from the class of any TD
1311 *  element.
1312 */
1313Calendar.prototype.hide = function () {
1314	if (this.isPopup) {
1315		Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
1316		Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
1317		Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
1318	}
1319	this.element.style.display = "none";
1320	this.hidden = true;
1321	this.hideShowCovered();
1322};
1323
1324/**
1325 *  Shows the calendar at a given absolute position (beware that, depending on
1326 *  the calendar element style -- position property -- this might be relative
1327 *  to the parent's containing rectangle).
1328 */
1329Calendar.prototype.showAt = function (x, y) {
1330	var s = this.element.style;
1331	s.left = x + "px";
1332	s.top = y + "px";
1333	this.show();
1334};
1335
1336/** Shows the calendar near a given element. */
1337Calendar.prototype.showAtElement = function (el, opts) {
1338	var self = this;
1339	var p = Calendar.getAbsolutePos(el);
1340	if (!opts || typeof opts != "string") {
1341		this.showAt(p.x, p.y + el.offsetHeight);
1342		return true;
1343	}
1344	function fixPosition(box) {
1345		if (box.x < 0)
1346			box.x = 0;
1347		if (box.y < 0)
1348			box.y = 0;
1349		var cp = document.createElement("div");
1350		var s = cp.style;
1351		s.position = "absolute";
1352		s.right = s.bottom = s.width = s.height = "0px";
1353		document.body.appendChild(cp);
1354		var br = Calendar.getAbsolutePos(cp);
1355		document.body.removeChild(cp);
1356		/*
1357		if (Calendar.is_ie) {
1358			br.y += document.body.scrollTop;
1359			br.x += document.body.scrollLeft;
1360		} else {
1361			br.y += window.scrollY;
1362			br.x += window.scrollX;
1363		}
1364		*/ //Commented by Mark
1365		
1366		if (document.body.scrollLeft){br.x += document.body.scrollLeft;}
1367 	        br.x += window.scrollX;
1368 	        if (document.body.scrollTop){br.y += document.body.scrollTop;}
1369 	        br.y += window.scrollY;
1370		// above block is added by mark
1371		
1372		
1373		var tmp = box.x + box.width - br.x;
1374		if (tmp > 0) box.x -= tmp;
1375		tmp = box.y + box.height - br.y;
1376		if (tmp > 0) box.y -= tmp;
1377	};
1378	this.element.style.display = "block";
1379	Calendar.continuation_for_the_fucking_khtml_browser = function() {
1380		var w = self.element.offsetWidth;
1381		var h = self.element.offsetHeight;
1382		self.element.style.display = "none";
1383		var valign = opts.substr(0, 1);
1384		var halign = "l";
1385		if (opts.length > 1) {
1386			halign = opts.substr(1, 1);
1387		}
1388		// vertical alignment
1389		switch (valign) {
1390		    case "T": p.y -= h; break;
1391		    case "B": p.y += el.offsetHeight; break;
1392		    case "C": p.y += (el.offsetHeight - h) / 2; break;
1393		    case "t": p.y += el.offsetHeight - h; break;
1394		    case "b": break; // already there
1395		}
1396		// horizontal alignment
1397		switch (halign) {
1398		    case "L": p.x -= w; break;
1399		    case "R": p.x += el.offsetWidth; break;
1400		    case "C": p.x += (el.offsetWidth - w) / 2; break;
1401		    case "l": p.x += el.offsetWidth - w; break;
1402		    case "r": break; // already there
1403		}
1404		p.width = w;
1405		p.height = h + 40;
1406		self.monthsCombo.style.display = "none";
1407		fixPosition(p);
1408		self.showAt(p.x, p.y);
1409	};
1410	if (Calendar.is_khtml)
1411		setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
1412	else
1413		Calendar.continuation_for_the_fucking_khtml_browser();
1414};
1415
1416/** Customizes the date format. */
1417Calendar.prototype.setDateFormat = function (str) {
1418	this.dateFormat = str;
1419};
1420
1421/** Customizes the tooltip date format. */
1422Calendar.prototype.setTtDateFormat = function (str) {
1423	this.ttDateFormat = str;
1424};
1425
1426/**
1427 *  Tries to identify the date represented in a string.  If successful it also
1428 *  calls this.setDate which moves the calendar to the given date.
1429 */
1430Calendar.prototype.parseDate = function(str, fmt) {
1431	if (!fmt)
1432		fmt = this.dateFormat;
1433	this.setDate(Date.parseDate(str, fmt));
1434};
1435
1436Calendar.prototype.hideShowCovered = function () {
1437	if (!Calendar.is_ie && !Calendar.is_opera)
1438		return;
1439	function getVisib(obj){
1440		var value = obj.style.visibility;
1441		if (!value) {
1442			if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
1443				if (!Calendar.is_khtml)
1444					value = document.defaultView.
1445						getComputedStyle(obj, "").getPropertyValue("visibility");
1446				else
1447					value = '';
1448			} else if (obj.currentStyle) { // IE
1449				value = obj.currentStyle.visibility;
1450			} else
1451				value = '';
1452		}
1453		return value;
1454	};
1455
1456	var tags = new Array("applet", "iframe", "select");
1457	var el = this.element;
1458
1459	var p = Calendar.getAbsolutePos(el);
1460	var EX1 = p.x;
1461	var EX2 = el.offsetWidth + EX1;
1462	var EY1 = p.y;
1463	var EY2 = el.offsetHeight + EY1;
1464
1465	for (var k = tags.length; k > 0; ) {
1466		var ar = document.getElementsByTagName(tags[--k]);
1467		var cc = null;
1468
1469		for (var i = ar.length; i > 0;) {
1470			cc = ar[--i];
1471
1472			p = Calendar.getAbsolutePos(cc);
1473			var CX1 = p.x;
1474			var CX2 = cc.offsetWidth + CX1;
1475			var CY1 = p.y;
1476			var CY2 = cc.offsetHeight + CY1;
1477
1478			if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
1479				if (!cc.__msh_save_visibility) {
1480					cc.__msh_save_visibility = getVisib(cc);
1481				}
1482				cc.style.visibility = cc.__msh_save_visibility;
1483			} else {
1484				if (!cc.__msh_save_visibility) {
1485					cc.__msh_save_visibility = getVisib(cc);
1486				}
1487				cc.style.visibility = "hidden";
1488			}
1489		}
1490	}
1491};
1492
1493/** Internal function; it displays the bar with the names of the weekday. */
1494Calendar.prototype._displayWeekdays = function () {
1495	var fdow = this.firstDayOfWeek;
1496	var cell = this.firstdayname;
1497	var weekend = Calendar._TT["WEEKEND"];
1498	for (var i = 0; i < 7; ++i) {
1499		cell.className = "day name";
1500		var realday = (i + fdow) % 7;
1501		if (i) {
1502			cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
1503			cell.navtype = 100;
1504			cell.calendar = this;
1505			cell.fdow = realday;
1506			Calendar._add_evs(cell);
1507		}
1508		if (weekend.indexOf(realday.toString()) != -1) {
1509			Calendar.addClass(cell, "weekend");
1510		}
1511		cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
1512		cell = cell.nextSibling;
1513	}
1514};
1515
1516/** Internal function.  Hides all combo boxes that might be displayed. */
1517Calendar.prototype._hideCombos = function () {
1518	this.monthsCombo.style.display = "none";
1519	this.yearsCombo.style.display = "none";
1520};
1521
1522/** Internal function.  Starts dragging the element. */
1523Calendar.prototype._dragStart = function (ev) {
1524	if (this.dragging) {
1525		return;
1526	}
1527	this.dragging = true;
1528	var posX;
1529	var posY;
1530	if (Calendar.is_ie) {
1531		posY = window.event.clientY + document.body.scrollTop;
1532		posX = window.event.clientX + document.body.scrollLeft;
1533	} else {
1534		posY = ev.clientY + window.scrollY;
1535		posX = ev.clientX + window.scrollX;
1536	}
1537	var st = this.element.style;
1538	this.xOffs = posX - parseInt(st.left);
1539	this.yOffs = posY - parseInt(st.top);
1540	with (Calendar) {
1541		addEvent(document, "mousemove", calDragIt);
1542		addEvent(document, "mouseup", calDragEnd);
1543	}
1544};
1545
1546// BEGIN: DATE OBJECT PATCHES
1547
1548/** Adds the number of days array to the Date object. */
1549Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
1550
1551/** Constants used for time computations */
1552Date.SECOND = 1000 /* milliseconds */;
1553Date.MINUTE = 60 * Date.SECOND;
1554Date.HOUR   = 60 * Date.MINUTE;
1555Date.DAY    = 24 * Date.HOUR;
1556Date.WEEK   =  7 * Date.DAY;
1557
1558Date.parseDate = function(str, fmt) {
1559	var today = new Date();
1560	var y = 0;
1561	var m = -1;
1562	var d = 0;
1563	var a = str.split(/\W+/);
1564	var b = fmt.match(/%./g);
1565	var i = 0, j = 0;
1566	var hr = 0;
1567	var min = 0;
1568	for (i = 0; i < a.length; ++i) {
1569		if (!a[i])
1570			continue;
1571		switch (b[i]) {
1572		    case "%d":
1573		    case "%e":
1574			d = parseInt(a[i], 10);
1575			break;
1576
1577		    case "%m":
1578			m = parseInt(a[i], 10) - 1;
1579			break;
1580
1581		    case "%Y":
1582		    case "%y":
1583			y = parseInt(a[i], 10);
1584			(y < 100) && (y += (y > 29) ? 1900 : 2000);
1585			break;
1586
1587		    case "%b":
1588		    case "%B":
1589			for (j = 0; j < 12; ++j) {
1590				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
1591			}
1592			break;
1593
1594		    case "%H":
1595		    case "%I":
1596		    case "%k":
1597		    case "%l":
1598			hr = parseInt(a[i], 10);
1599			break;
1600
1601		    case "%P":
1602		    case "%p":
1603			if (/pm/i.test(a[i]) && hr < 12)
1604				hr += 12;
1605			else if (/am/i.test(a[i]) && hr >= 12)
1606				hr -= 12;
1607			break;
1608
1609		    case "%M":
1610			min = parseInt(a[i], 10);
1611			break;
1612		}
1613	}
1614	if (isNaN(y)) y = today.getFullYear();
1615	if (isNaN(m)) m = today.getMonth();
1616	if (isNaN(d)) d = today.getDate();
1617	if (isNaN(hr)) hr = today.getHours();
1618	if (isNaN(min)) min = today.getMinutes();
1619	if (y != 0 && m != -1 && d != 0)
1620		return new Date(y, m, d, hr, min, 0);
1621	y = 0; m = -1; d = 0;
1622	for (i = 0; i < a.length; ++i) {
1623		if (a[i].search(/[a-zA-Z]+/) != -1) {
1624			var t = -1;
1625			for (j = 0; j < 12; ++j) {
1626				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
1627			}
1628			if (t != -1) {
1629				if (m != -1) {
1630					d = m+1;
1631				}
1632				m = t;
1633			}
1634		} else if (parseInt(a[i], 10) <= 12 && m == -1) {
1635			m = a[i]-1;
1636		} else if (parseInt(a[i], 10) > 31 && y == 0) {
1637			y = parseInt(a[i], 10);
1638			(y < 100) && (y += (y > 29) ? 1900 : 2000);
1639		} else if (d == 0) {
1640			d = a[i];
1641		}
1642	}
1643	if (y == 0)
1644		y = today.getFullYear();
1645	if (m != -1 && d != 0)
1646		return new Date(y, m, d, hr, min, 0);
1647	return today;
1648};
1649
1650/** Returns the number of days in the current month */
1651Date.prototype.getMonthDays = function(month) {
1652	var year = this.getFullYear();
1653	if (typeof month == "undefined") {
1654		month = this.getMonth();
1655	}
1656	if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
1657		return 29;
1658	} else {
1659		return Date._MD[month];
1660	}
1661};
1662
1663/** Returns the number of day in the year. */
1664Date.prototype.getDayOfYear = function() {
1665	var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
1666	var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
1667	var time = now - then;
1668	return Math.floor(time / Date.DAY);
1669};
1670
1671/** Returns the number of the week in year, as defined in ISO 8601. */
1672Date.prototype.getWeekNumber = function() {
1673	var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
1674	var DoW = d.getDay();
1675	d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
1676	var ms = d.valueOf(); // GMT
1677	d.setMonth(0);
1678	d.setDate(4); // Thu in Week 1
1679	return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
1680};
1681
1682/** Checks date and time equality */
1683Date.prototype.equalsTo = function(date) {
1684	return ((this.getFullYear() == date.getFullYear()) &&
1685		(this.getMonth() == date.getMonth()) &&
1686		(this.getDate() == date.getDate()) &&
1687		(this.getHours() == date.getHours()) &&
1688		(this.getMinutes() == date.getMinutes()));
1689};
1690
1691/** Set only the year, month, date parts (keep existing time) */
1692Date.prototype.setDateOnly = function(date) {
1693	var tmp = new Date(date);
1694	this.setDate(1);
1695	this.setFullYear(tmp.getFullYear());
1696	this.setMonth(tmp.getMonth());
1697	this.setDate(tmp.getDate());
1698};
1699
1700/** Prints the date in a string according to the given format. */
1701Date.prototype.print = function (str) {
1702	var m = this.getMonth();
1703	var d = this.getDate();
1704	var y = this.getFullYear();
1705	var wn = this.getWeekNumber();
1706	var w = this.getDay();
1707	var s = {};
1708	var hr = this.getHours();
1709	var pm = (hr >= 12);
1710	var ir = (pm) ? (hr - 12) : hr;
1711	var dy = this.getDayOfYear();
1712	if (ir == 0)
1713		ir = 12;
1714	var min = this.getMinutes();
1715	var sec = this.getSeconds();
1716	s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
1717	s["%A"] = Calendar._DN[w]; // full weekday name
1718	s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
1719	s["%B"] = Calendar._MN[m]; // full month name
1720	// FIXME: %c : preferred date and time representation for the current locale
1721	s["%C"] = 1 + Math.floor(y / 100); // the century number
1722	s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
1723	s["%e"] = d; // the day of the month (range 1 to 31)
1724	// FIXME: %D : american date style: %m/%d/%y
1725	// FIXME: %E, %F, %G, %g, %h (man strftime)
1726	s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
1727	s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
1728	s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
1729	s["%k"] = hr;		// hour, range 0 to 23 (24h format)
1730	s["%l"] = ir;		// hour, range 1 to 12 (12h format)
1731	s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
1732	s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
1733	s["%n"] = "\n";		// a newline character
1734	s["%p"] = pm ? "PM" : "AM";
1735	s["%P"] = pm ? "pm" : "am";
1736	// FIXME: %r : the time in am/pm notation %I:%M:%S %p
1737	// FIXME: %R : the time in 24-hour notation %H:%M
1738	s["%s"] = Math.floor(this.getTime() / 1000);
1739	s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
1740	s["%t"] = "\t";		// a tab character
1741	// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
1742	s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
1743	s["%u"] = w + 1;	// the day of the week (range 1 to 7, 1 = MON)
1744	s["%w"] = w;		// the day of the week (range 0 to 6, 0 = SUN)
1745	// FIXME: %x : preferred date representation for the current locale without the time
1746	// FIXME: %X : preferred time representation for the current locale without the date
1747	s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
1748	s["%Y"] = y;		// year with the century
1749	s["%%"] = "%";		// a literal '%' character
1750
1751	var re = /%./g;
1752	if (!Calendar.is_ie5 && !Calendar.is_khtml)
1753		return str.replace(re, function (par) { return s[par] || par; });
1754
1755	var a = str.match(re);
1756	for (var i = 0; i < a.length; i++) {
1757		var tmp = s[a[i]];
1758		if (tmp) {
1759			re = new RegExp(a[i], 'g');
1760			str = str.replace(re, tmp);
1761		}
1762	}
1763
1764	return str;
1765};
1766
1767Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
1768Date.prototype.setFullYear = function(y) {
1769	var d = new Date(this);
1770	d.__msh_oldSetFullYear(y);
1771	if (d.getMonth() != this.getMonth())
1772		this.setDate(28);
1773	this.__msh_oldSetFullYear(y);
1774};
1775
1776// END: DATE OBJECT PATCHES
1777
1778
1779// global object that remembers the calendar
1780window._dynarch_popupCalendar = null;

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.