// =====================================================================================
//	Author:	Henk-Reints.nl
//	Date:	Oct-1999
//
//	Description:
//		This is a JavaScript library containing different Easter date
//		algorithms and related functions.
//		It can also be used of an example of dynamic HTML programming.
//		Depending on the URL search string given when loading the page,
//		it builds a form in dutch or english to enter a year range and
//		specify an algirithm to use.
//		That form contains a START button (except in Netscape, I cannot yet
//		get that working in Netscape) and a SUBMIT button (in any browser).
//		With START an Easter date list is calculated and displayed on the
//		(local) client side only, with SUBMIT the form will be submitted
//		(and the page reloaded) with the form parameters included in the URL.
//		If those are all filled in the Easter date list is made at once.
//		Input is only validated when filling in the form.
//		It is also possible to directly link to the page with a 'search string',
//		but no input validation will then be done, thus possibly causing
//		unpredictable or incorrect results.
//
//	Usage:	<html><head><script language="JavaScript" src="easter.js"></script></head></html>
//
//	Note:	In boolean expressions (e.g. comparisons) numeric arguments are
//		multiplied by 1 to prevent number arguments to be evaluated as a
//		string ("123" is less than "2", but 123 is greater than 2).
// =====================================================================================

var copyrightstring = 'Copyright (c) 1999-2006, <a href="../index.htm">Henk-Reints.nl</a>';
var copyrightdutch  = copyrightstring;

var algname  = new Array;
var algdutch = new Array;
var algmin   = new Array;
var algmax   = new Array;

//	====================================================================================
//	The following lines are WIDE !!!  They define algname, algdutch, algmin, and algmax.
//	====================================================================================

algname[ 0]=12;	// not the total length but the highest index in algname

algname[ 1]="Universal Delambre+Lilius/Clavius";	algdutch[algname[ 1]]="Universeel Delambre+Lilius/Clavius";	algmin[algname[ 1]]=   1; algmax[algname[ 1]]=9999;
algname[ 2]="Universal Delambre";			algdutch[algname[ 2]]="Universeel Delambre";			algmin[algname[ 2]]=   1; algmax[algname[ 2]]=9999;
algname[ 3]="Universal Tondering";			algdutch[algname[ 3]]="Universeel Tondering";			algmin[algname[ 3]]=   1; algmax[algname[ 3]]=9999;
algname[ 4]="Universal Tables";				algdutch[algname[ 4]]="Universele Tabellen";			algmin[algname[ 4]]= 326; algmax[algname[ 4]]=4099;
algname[ 5]="Gregorian Lilius/Clavius";			algdutch[algname[ 5]]="Gregoriaans Lilius/Clavius";		algmin[algname[ 5]]=1583; algmax[algname[ 5]]=9999;
algname[ 6]="Gregorian Gauss";				algdutch[algname[ 6]]="Gregoriaans Gauss";			algmin[algname[ 6]]=1583; algmax[algname[ 6]]=9999;
algname[ 7]="Gregorian Delambre";			algdutch[algname[ 7]]="Gregoriaans Delambre";			algmin[algname[ 7]]=1583; algmax[algname[ 7]]=9999;
algname[ 8]="Gregorian Tondering";			algdutch[algname[ 8]]="Gregoriaans Tondering";			algmin[algname[ 8]]=1583; algmax[algname[ 8]]=9999;
algname[ 9]="Gregorian Tables";				algdutch[algname[ 9]]="Gregoriaanse Tabellen";			algmin[algname[ 9]]=1583; algmax[algname[ 9]]=4099;
algname[10]="Julian Delambre";				algdutch[algname[10]]="Juliaans Delambre";			algmin[algname[10]]=   1; algmax[algname[10]]=9999;
algname[11]="Julian Tondering";				algdutch[algname[11]]="Juliaans Tondering";			algmin[algname[11]]=   1; algmax[algname[11]]=9999;
algname[12]="Julian Tables";				algdutch[algname[12]]="Juliaanse Tabellen";			algmin[algname[12]]= 326; algmax[algname[12]]=4099;

// =====================================================================================

function EasterJulianTables (year) {
//	--------------------------------------------------------------------------------
//	This function determines the Easter date using the Julian algorithm described
//	in function GetEasterDate2 at http://www.chariot.net.au/~gmarts/eastalg.htm
//	That site owner (G.M.Arts) says that it can easily be proved to be 100% correct,
//	because it is directly derived from the official tables.
//	The result is a date on the Julian calendar as a day in March (even if > 31).
//	--------------------------------------------------------------------------------
	//
	var result,gold,cent,temp,tA,tB,tC,tD,tE;
	//
	if ((1*year < 326) || (1*year > 4099)) {
		result = NaN;
	} else {
		gold = year % 19;
		cent = Math.floor(year/100);
		temp = year % 100;
		tA = ((225 - 11*gold) % 30) + 21;
		tB = (tA - 19) % 7;
		tC = (40 - cent) % 7;
		tD = (temp + Math.floor(temp/4)) % 7;	
		tE = ((20 - tB - tC - tD) % 7) + 1;
		result = tA + tE;
	};
	return result;
};
// =====================================================================================

function EasterGregorianTables (year) {
//	--------------------------------------------------------------------------------
//	This function determines the Easter date using the Gregorian algorithm described
//	in function GetEasterDate2 at http://www.chariot.net.au/~gmarts/eastalg.htm
//	That site owner (G.M.Arts) says that it can easily be proved to be 100% correct,
//	because it is directly derived from the official tables.
//	The result is a date on the Gregorian calendar as a day in March (even if > 31).
//	--------------------------------------------------------------------------------
	//
	var result,gold,cent,temp,tA,tB,tC,tD,tE;
	//
	if ((1*year < 1583) || (1*year > 4099)) {
		result = NaN;
	} else {
		gold = year % 19;
		cent = Math.floor(year/100);
		temp = Math.floor((cent-15)/2) + 202 - 11*gold;
		if (cent >  26) { temp-- };
		if (cent >  38) { temp-- };
		if (cent == 21) { temp-- };
		if (cent == 24) { temp-- };
		if (cent == 25) { temp-- };
		if (cent == 33) { temp-- };
		if (cent == 36) { temp-- };
		if (cent == 37) { temp-- };
		temp = temp % 30;
		tA = temp + 21;
		if ( temp == 29                ) { tA-- };
		if ((temp == 28) && (gold > 10)) { tA-- };
		tB = (tA - 19) % 7;
		tC = (40 - cent) % 4;
		if (tC == 3) { tC++ };
		if (tC >  1) { tC++ };
		temp = year % 100;
		tD = (temp + Math.floor(temp/4)) % 7;	
		tE = ((20 - tB - tC - tD) % 7) + 1;
		result = tA + tE;
	};
	return result;
};
// =====================================================================================

function EasterGregorianLiliusClavius (year) {
//	--------------------------------------------------------------------------------
//	This function determines the Easter date using the algorithm developed by Lilius
//	and Clavius, which - to my knowledge - is the REAL thing since the introduction
//	of the Gregorian calendar in 1582.
//	The result is a date on the Gregorian calendar as a day in March (even if > 31).
//	--------------------------------------------------------------------------------
	//
	var result,a,b,c,d,e,f,g
	//
	if (1*year < 1583) {
		result = NaN;
	} else {
		a = (year % 19) + 1;
		b = Math.floor(year/100)    + 1;
		c = Math.floor((3*b)/4)     - 12;
		d = Math.floor((8*b + 5)/25)- 5;
		e = Math.floor((year*5)/4)  - 10 - c;
		f = (((11*a + 20 + d - c) % 30) + 30) % 30;
		if ((f == 24) || ((f == 25) && (a > 11))) { f++ };
		g = 44 - f;
		if (g < 21) { g = g + 30; };
		result = g + 7 - ((e + g) % 7);
	};
	return result;
};
// =====================================================================================

function EasterGregorianGauss (year) {
//	--------------------------------------------------------------------------------
//	This function determines the Easter date using the algorithm developed by Gauss,
//	which - at least in The Netherlands - is explained in various encyclopedias.
//	The result is a date on the Gregorian calendar as a day in March (even if > 31).
//	--------------------------------------------------------------------------------
	//
	var result,a,b,c,d,e,f,g,i,M,N;
	//
	if ((1*year < 1583) || (1*year > 9999)) {
		result = NaN;
	} else {
		M = new Array (22,22,23,23,24,
		24,24,25,26,25,26,27,27,27,28,
		28,29,29,29, 0, 1, 0, 1, 2, 2,
		 2, 3, 4, 4, 4, 5, 5, 6, 6, 6,
		 7, 8, 7, 8, 9, 9, 9,10,10,11,
		11,11,12,13,12,13,14,15,14,15,
		16,16,16,17,17,18,18,18,19,20,
		19,20,21,21,21,22,22,23,23,23,
		24,25,25,25,26,27,26,27,28,28);
		i = Math.floor(year/100)-15;	// index in array M for current century
		N = (4 + Math.floor(year/100) - Math.floor(year/400)) % 7;
		a = year % 19;
		b = year % 4;
		c = year % 7;
		d = (19*a + M[i]) % 30;
		e = (2*b + 4*c + 6*d + N) % 7;
		result = 22 + d + e;
		if (result==57 || (result==56 && e==6 && a>10)) { result = result-7; };
	};
	return result;
};
// =====================================================================================

function EasterJulianDelambre (year) {
//	--------------------------------------------------------------------------------
//	This function determines the Easter date using the Julian algorithm developed
//	by Jean Baptiste Joseph Delambre (1749-1822),
//	as found on http://www.geocities.com/CapeCanaveral/4274/easter.htm
//	It should be valid since A.D. 1,
//	although Jesus' resurrection could not yet be celebrated at that time...
//	In practice it is of coarse only valid since the Council of Nicea in A.D. 325.
//	The result is a date on the Julian calendar as a day in March (even if > 31).
//	--------------------------------------------------------------------------------
	//
	var result,a,b,c,d,e;
	//
	if (1*year < 1) {
		result = NaN;
	} else {
		a = year % 4;
		b = year % 7;
		c = year % 19;
		d = (19*c + 15) % 30;
		e = (2*a + 4*b - d + 34) % 7;
		result = 22 + d + e;
	};
	return result;
};
// =====================================================================================

function EasterGregorianDelambre (year) {
//	--------------------------------------------------------------------------------
//	This function determines the Easter date using the Gregorian algorithm developed
//	by Jean Baptiste Joseph Delambre (1749-1822),
//	as found on http://www.geocities.com/CapeCanaveral/4274/easter.htm
//	The result is a date on the Gregorian calendar as a day in March (even if > 31).
//	--------------------------------------------------------------------------------
	//
	var result,a,b,c,d,e,f,g,h,i,k,L,m;
	//
	if (1*year < 1583) {
		result = NaN;
	} else {
		a = year % 19;
		b = Math.floor(year/100);
		c = year % 100;
		d = Math.floor(b/4);
		e = b % 4;
		f = Math.floor((b + 8)/25);
		g = Math.floor((b - f + 1)/3);
		h = (19*a + b - d - g + 15) % 30;
		i = Math.floor(c/4);
		k = c % 4;
		L = (32 + 2*e + 2*i - h - k) % 7;
		m = Math.floor((a + 11*h + 22*L)/451);
		result = 22 + h + L - 7*m;
	};
	return result;
};
// =====================================================================================

function EasterJulianTondering (year) {
//	--------------------------------------------------------------------------------
//	This function determines the Easter date using the Julian algorithm explained
//	by Claus Tondering on http://www.tondering.dk/claus/calendar.html
//	(which is a VERY VERY VERY good site!)
//	The result is a date on the Julian calendar as a day in March (even if > 31).
//	--------------------------------------------------------------------------------
	//
	var result,g,i,j;
	//
	if (1*year < 1) {
		result = NaN;
	} else {
		g = year % 19;
		i = (19*g + 15) % 30;
		j = (year + Math.floor(year/4) + i) % 7;
		result = 28 + i - j;
	};
	return result;
};
// =====================================================================================

function EasterGregorianTondering (year) {
//	--------------------------------------------------------------------------------
//	This function determines the Easter date using the Gregorian algorithm explained
//	by Claus Tondering on http://www.tondering.dk/claus/calendar.html
//	(which is a VERY VERY VERY good site!)
//	The result is a date on the Gregorian calendar as a day in March (even if > 31).
//	--------------------------------------------------------------------------------
	//
	var result,g,c,d,h,k,i,j;
	//
	if (1*year < 1583) {
		result = NaN;
	} else {
		g = year % 19;
		c = Math.floor(year/100);
		d = c - Math.floor(c/4);
		h = (d - Math.floor((8*c+13)/25) + 19*g + 15) % 30;
		k = Math.floor(h/28);
		i = h - k*(1 - k*Math.floor(29/(h+1))*Math.floor((21-g)/11));
		j = (year + Math.floor(year/4) + i + 2 - d) % 7;
		result = 28 + i - j;
	};
	return result;
};
// =====================================================================================

function jul2greg (marchday, year, julian) {
//	--------------------------------------------------------------------------------
//	This function converts a Julian calendar March day to Gregorian if it
//	represents a date in the Gregorian era and if 'julian' is FALSE.
//	--------------------------------------------------------------------------------
	//
	var result,canbegregorian,x;
	//
	canbegregorian = (datestring(marchday,year,true) > "1582-10-04");
	if (canbegregorian && !julian && ""+marchday != "NaN") {
		result = 1*marchday + 10;
		x = Math.floor(year/100) - 16;
		if (x > 0) { result = result + x - Math.floor(x/4); };
	} else {
		result = marchday;
	};
	return result;
};
// =====================================================================================

function ThisYear (offset) {
//	--------------------------------------------------------------------------------
//	This function returns the current year plus a given offset,
//	according to the client computer's system date
//	(i.e. the computer on which the browser is executing).
//	Note:	the Date.getYear method should return the year minus 1900 according to
//		the Javascript documentation.
//		However, for the year 2000 it returns 2000 in MS IE 5 (dutch)
//		and 100 in NS 4.5 (dutch). I didn't check older versions and I won't.
//		*THIS* function (and this entire library) always returns a year as
//		the number that it actually is (as ALL software SHOULD do...).
//	--------------------------------------------------------------------------------
	//
	var year;
	//
	year  = (new Date()).getYear();
	if (1*year < 1900) { year += 1900; };
	return year + offset;
};
// =====================================================================================

function Leap (year, julian) {
//	--------------------------------------------------------------------------------
//	This function returns 1 if the given year is a leap year and 0 otherwise.
//	If the 'julian' argument evaluates as TRUE
//	then a check using the Julian calendar is forced, whatever the given year,
//	else a Gregorian check is made since 1583 and a Julian check before that year.
//	--------------------------------------------------------------------------------
	//
	var result,
	//
	result = CanDivide (year, 4);
	if ((1*year > 1582) && !julian) {
		result = result - CanDivide (year, 100) + CanDivide (year, 400);
	};
	return result;
};
// =====================================================================================

function days (month, year, julian) {
//	--------------------------------------------------------------------------------
//	This function returns the number of days in a month.
//	If julian evaluates as TRUE then the Julian leap year calculation is forced
//	else the Gregorian since 1583 and the Julian before that year.
//	--------------------------------------------------------------------------------
	//
	var result;
	//
	if      (month == 2) { result = 28 + Leap (year, julian); }
	else if (month <  8) { result = 30 + month % 2; }
	else                 { result = 31 - month % 2; };
	return result;
};
// =====================================================================================

function formatnumber (number, width, character) {
//	--------------------------------------------------------------------------------
//	This function returns a string with the decimal representation of the number
//	argument, left-padded to the given width with the specified character.
//	--------------------------------------------------------------------------------
	//
	var result;
	//
	result = "" + number;
	while (result.length < width) { result = character + result; };
	return result;
};
// =====================================================================================

function datestring (marchday, year, julian) {
//	--------------------------------------------------------------------------------
//	This function converts a year+marchday date to a yyyy-mm-dd date string.
//	Marchday can be any number on input.
//	--------------------------------------------------------------------------------
	//
	var result,y,m,d,loop;
	//
	if (""+marchday == "NaN") {
		result = "????-??-??";
	} else {
		y = 1*year;
		m = 3;
		d = 1*marchday;
		loop = 2;
		while (loop > 0) {
			loop = loop - 2;
			while (d>days(m,y,julian)) { d=d-days(m,y,julian); m=(m%12)+1; if (m==1) { y++ } };
			while (d < 1) { m=((m+10)%12)+1; if (m==12) { y-- }; d=d+days(m,y,julian) };
			if ((loop == 0) && !julian) {
				if (1*year<1583 && ((y*100+m)*100)+d>15821004) { d=d+10; loop++ };
				if (1*year>1582 && ((y*100+m)*100)+d<15821015) { d=d-10; loop++ };
			};
		};
		result=formatnumber(y,4,' ')+"-"+formatnumber(m,2,'0')+"-"+formatnumber(d,2,'0');
	};
	return result;
};
// =====================================================================================

function daymonth (marchday, year, julian, language) {
//	--------------------------------------------------------------------------------
//	This function returns the day and month of a date as 'dd Month' format in HTML.
//	--------------------------------------------------------------------------------
	//
	var x,day,mon,month;
	//
	var dutmon = new Array("*****","januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december");
	var engmon = new Array("*****","January","February","March","April","May","June","July","August"  ,"September","October","November","December");
	//
	if (""+marchday != "NaN") {
		x = datestring (marchday, year, julian);
		day = 1*x.substr(8,2);
		mon = 1*x.substr(5,2);
	} else {
		day = 0;
		mon = 0;
	};
	if (language=="dutch") { month = dutmon[mon]; }
	else                   { month = engmon[mon]; };
	return '<table><tr><td align="right" width=30><font face="Arial">' + day + '</font></td><td><font face="Arial">' + month + '&nbsp;&nbsp;</font></td></tr></table>';
};
// =====================================================================================

function CanDivide (m, n) {
//	--------------------------------------------------------------------------------
//	This function returns 1 if m can be divided by n, 0 otherwise.
//	--------------------------------------------------------------------------------
	//
	var result;
	//
	result = 0;
	if ((m % n) == 0) { result = 1; };
	return result;
};
// =====================================================================================

function IsInteger (number) {
//	--------------------------------------------------------------------------------
//	This function checks if input contains only decimal digits.
//	--------------------------------------------------------------------------------
	//
	var result = true;
	var d = "1234567890";
	var x = "" + number;
	var i,j;
	//
	for (i = 0; result && (i < x.length); i++) {
		for (j = 0; (j < d.length) && (x.substr(i,1) != d.substr(j,1)); j++) { };
		result = (j < d.length);
	};
	return result;
};
// =====================================================================================

function ValidateInteger (field1, low, high, replace, language) {
//	--------------------------------------------------------------------------------
//	This function checks if input is an integer number between given limits.
//	If 'replace' evaluates as TRUE then Out-of-range values are replaced by the
//	nearest value of low or high without indicating an error.
//	If invalid then an errormessage is displayed in dutch if language=="dutch"
//	(case-sensitive) or in english otherwise.
//	--------------------------------------------------------------------------------
	//
	var result,x;
	//
	result = IsInteger (field1.value) && IsInteger (low) && IsInteger (high);
	if (result) {
		if (replace && (1*field1.value < 1*low )) { field1.value = low ; };
		if (replace && (1*field1.value > 1*high)) { field1.value = high; };
		result = ((1*field1.value >= 1*low) && (1*field1.value <= 1*high));
	};
	if (!result) {
		if (language=="dutch") {
			x = "\"" + field1.value + "\" is een ongeldig getal.\n";
			x = x + "Geef een waarde tussen " + low + " en " + high + " (inclusief).";
		} else {
			x = "\"" + field1.value + "\" is an invalid number.\n";
			x = x + "Enter a value between " + low + " and " + high + " (inclusive).";
		};
		alert (x);
	};
	return result;
};
// =====================================================================================

function ValidateYear (field1, alg, replace, language) {
//	--------------------------------------------------------------------------------
//	This function checks if input is a valid year for the given Easter algorithm.
//	--------------------------------------------------------------------------------
	//
	return ValidateInteger(field1,algmin[alg],algmax[alg],replace,language);
};
// =====================================================================================

function ValidateYearField (field1, field2, mode, alg, replace, language) {
//	--------------------------------------------------------------------------------
//	This function checks if a field contains a valid year and updates another field
//	to contain at least or at most the same value.
//	--------------------------------------------------------------------------------
	//
	var result;
	//
	result = ValidateYear (field1, alg, replace, language);
	if (result) {
		if (mode=="atleast" && (1*field2.value < 1*field1.value)) { field2.value = field1.value };
		if (mode=="atmost"  && (1*field2.value > 1*field1.value)) { field2.value = field1.value };
	};
	return result;
};
// =====================================================================================

function least (number1, number2) {
//	--------------------------------------------------------------------------------
//	This function returns the least of two numbers.
//	--------------------------------------------------------------------------------
	//
	var result;
	//
	result = number1;
	if (1*number1 > 1*number2) { result = number2; };
	return result;
};
// =====================================================================================

function greatest (number1, number2) {
//	--------------------------------------------------------------------------------
//	This function returns the greatest of two numbers.
//	--------------------------------------------------------------------------------
	//
	var result;
	//
	result = number1;
	if (1*number1 < 1*number2) { result = number2; };
	return result;
};
// =====================================================================================

function setalgrange (algfield, lowfield, highfield) {
//	--------------------------------------------------------------------------------
//	This functions adjusts low and high fields according to the selected algorithm.
//	--------------------------------------------------------------------------------
	lowfield.value  = greatest (lowfield.value , algmin[algname[algfield.selectedIndex+1]]);
	highfield.value = least    (highfield.value, algmax[algname[algfield.selectedIndex+1]]);
	return true;
};
// =====================================================================================

function MakeEasterList (low, high, alg, gregalg, gregyear, language) {
//	--------------------------------------------------------------------------------
//	This function creates HTML output with a table containing Easter and related
//	dates within the given range from low to high.
//	Easter will be calculated using the algorithm specified in 'alg'.
//	If that is a Julian method, then 'gregyear' specifies from wich year the result
//	must be given according to the Gregorian calendar. Dates before that year will
//	be displayed according to the Julian calendar.
//	With the 'gregalg' argument the year is given since which the universal
//	algorithms start to use the Gregorian algorithms instead of the Julian.
//	--------------------------------------------------------------------------------
	//
	var f1,f2,title,years,algtx,algnm,jultx,grgtx,since,caltx,now,x1,x2,ed,year;
	var jinfo,ginfo,hinfo,jtext,gtext,htext,julcal,julalg;
	//
	f1 = "<font face=\"Arial\">";
	f2 = "</font>";
	if (language=="dutch") {
		title = "Pasen en gerelateerde data.";
		if (low==high)	{ years = "<tr><td>" + f1 + "Jaar:"  + f2 + "<td>" + f1 + low +                  "." + f2 + "</tr>"; }
		else		{ years = "<tr><td>" + f1 + "Jaren:" + f2 + "<td>" + f1 + low + " t/m " + high + "." + f2 + "</tr>"; };
		algtx = "<tr><td>"+f1+"Algoritme:"+f2+"<td>"+f1;
		algnm = algdutch[alg];
		jultx = "Juliaans";
		grgtx = "Gregoriaans";
		since = grgtx + " vanaf ";
		caltx = "<tr><td>"+f1+"Kalender:"+f2+"<td>"+f1;
		jtext = "<tr><td>"+f1+"Jaar+J"+f2+"</td><td>"+f1+"= Juliaanse algoritme en kalender."+f2+"</td></tr>";
		gtext = "<tr><td>"+f1+"Jaar+G"+f2+"</td><td>"+f1+"= Gregoriaanse algoritme en kalender."+f2+"</td></tr>";
		htext = "<tr><td>"+f1+"Jaar+H"+f2+"</td><td>"+f1+"= Hybride: Juliaanse algoritme en Gregoriaanse kalender (Orthodox)."+f2+"</td></tr>";
	} else {
		title = "Easter and related dates.";
		if (low==high)	{ years = "<tr><td>" + f1 + "Year:"  + f2 + "<td>" + f1 + low                      + "." + f2 + "</tr>"; }
		else		{ years = "<tr><td>" + f1 + "Years:" + f2 + "<td>" + f1 + low + " through " + high + "." + f2 + "</tr>"; };
		algtx = "<tr><td>"+f1+"Algorithm:"+f2+"<td>"+f1;
		algnm = alg;
		jultx = "Julian";
		grgtx = "Gregorian";
		since = grgtx + " since ";
		caltx = "<tr><td>"+f1+"Calendar:"+f2+"<td>"+f1;
		jtext = "<tr><td>"+f1+"Year+J"+f2+"</td><td>"+f1+"= Julian algorithm and calendar."+f2+"</td></tr>";
		gtext = "<tr><td>"+f1+"Year+G"+f2+"</td><td>"+f1+"= Gregorian algorithm and calendar."+f2+"</td></tr>";
		htext = "<tr><td>"+f1+"Year+H"+f2+"</td><td>"+f1+"= Hybrid: Julian algorithm and Gregorian calendar (Orthodox)."+f2+"</td></tr>";
	};
	jinfo = false;
	ginfo = false;
	hinfo = false;
	document.writeln ('<html><head><title>'+title+'</title></head><body bgcolor="bisque" link="blue" alink="blue" vlink="blue">'+f1);
	if (language=="dutch") {
		document.writeln('<center><a href="paasdatum.htm"><font face="Arial" size=+3>',title,'</font></a></center>');
		document.writeln ('<p align="center"><font face="Arial">Resultaat van de <a href="javascript:history.back();">Paasdatumrekenmachine.</a>');
	} else {
		document.writeln ('<center><u><font face="Arial" size=+3>',title,'</font></u></center>');
		document.writeln ('<p align="center"><font face="Arial">Result of the <a href="javascript:history.back();">Easter date calculator.</a>');
	};
	document.writeln ('<p><table align="center">');
	document.writeln (years);
	if (alg.substr(0,9)=="Universal") {
		if      (1*gregalg > 1*high) { algtx = algtx + " " + jultx + " ("; }
		else if (1*gregalg < 1*low ) { algtx = algtx + " " + grgtx + " ("; }
		else                         { algtx = algtx + " " + since + gregalg + " ("; };
		algnm = algnm + ")";
	};
	document.writeln (algtx + algnm + "." + f2 + "</tr>");
	if (alg.substr(0,6)=="Julian" || alg.substr(0,9)=="Universal") {
		if      (1*gregyear > 1*high) { caltx = caltx + " " + jultx + "."; }
		else if (1*gregyear < 1*low ) { caltx = caltx + " " + grgtx + "."; }
		else                          { caltx = caltx + " " + since + gregyear + "."; };
		document.writeln (caltx + f2 + "</tr>");
	};
	document.writeln ("</table>" + f2);
	document.writeln ('<p><table border align="center"><tr><td><table>');
	if (language=="dutch") {
		document.write   ("<tr>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Jaar"       + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Carnaval"   + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Pasen"      + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Hemelvaart" + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Pinksteren" + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.writeln ("</font></tr>");
	} else {
		document.write   ("<tr>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Year"      + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Carnival"  + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Easter"    + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Ascension" + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.write   ('<td align="center">&nbsp;&nbsp;<u><b>' + f1 + "Pentecost" + f2 + "</b></u>&nbsp;&nbsp;</td>");
		document.writeln ("</font></tr>");
	};
	now = ThisYear (0);
	for (year = 1*low; (year <= 1*high); year++) {
		window.status = "" + year;
		//
		julcal = (year < 1*gregyear);
		if      (alg==algname[ 1] && year <  gregalg) { julalg = true ; ed=jul2greg(EasterJulianDelambre        (year),year,julcal); }
		else if (alg==algname[ 1] && year >= gregalg) { julalg = false; ed=         EasterGregorianLiliusClavius(year); }
		else if (alg==algname[ 2] && year <  gregalg) { julalg = true ; ed=jul2greg(EasterJulianDelambre        (year),year,julcal); }
		else if (alg==algname[ 2] && year >= gregalg) { julalg = false; ed=         EasterGregorianDelambre     (year); }
		else if (alg==algname[ 3] && year <  gregalg) { julalg = true ; ed=jul2greg(EasterJulianTondering       (year),year,julcal); }
		else if (alg==algname[ 3] && year >= gregalg) { julalg = false; ed=         EasterGregorianTondering    (year); }
		else if (alg==algname[ 4] && year <  gregalg) { julalg = true ; ed=jul2greg(EasterJulianTables          (year),year,julcal); }
		else if (alg==algname[ 4] && year >= gregalg) { julalg = false; ed=         EasterGregorianTables       (year); }
		else if (alg==algname[ 5]                   ) { julalg = false; ed=         EasterGregorianLiliusClavius(year); }
		else if (alg==algname[ 6]                   ) { julalg = false; ed=         EasterGregorianGauss        (year); }
		else if (alg==algname[ 7]                   ) { julalg = false; ed=         EasterGregorianDelambre     (year); }
		else if (alg==algname[ 8]                   ) { julalg = false; ed=         EasterGregorianTondering    (year); }
		else if (alg==algname[ 9]                   ) { julalg = false; ed=         EasterGregorianTables       (year); }
		else if (alg==algname[10]                   ) { julalg = true ; ed=jul2greg(EasterJulianDelambre        (year),year,julcal); }
		else if (alg==algname[11]                   ) { julalg = true ; ed=jul2greg(EasterJulianTondering       (year),year,julcal); }
		else if (alg==algname[12]                   ) { julalg = true ; ed=jul2greg(EasterJulianTables          (year),year,julcal); }
		else { alert("Invalid Easter algorithm: " + alg); };
		yy = "" + year;
		if ((((1*low<1*gregalg)&&(1*gregalg<=1*high))||((1*low<1*gregyear)&&(1*gregyear<=1*high)))&&(alg.substr(0,9)!="Gregorian")) {
			if (julalg &&  julcal ) { yy = year + " J"; jinfo = true; };
			if (julalg && !julcal ) { yy = year + " H"; hinfo = true; };
			if (!julalg)            { yy = year + " G"; ginfo = true; };
		};
		x1 = f1
		x2 = f2
		if (year == now)
		{	document.write   ('<tr bgcolor=lightgreen><font face="Arial">');
		} else
		{	document.write   ('<tr><font face="Arial">');
		}
		document.write   ('<td>' + x1 + yy + x2 + '</td>');
		document.write   ('<td>' + x1 + daymonth (ed - 49, year, julcal, language) + x2 + '</td>');
		document.write   ('<td>' + x1 + daymonth (ed     , year, julcal, language) + x2 + '</td>');
		document.write   ('<td>' + x1 + daymonth (ed + 39, year, julcal, language) + x2 + '</td>');
		document.write   ('<td>' + x1 + daymonth (ed + 49, year, julcal, language) + x2 + '</td>');
		document.writeln ("</font></tr>");
	};
	document.writeln("</table></tr></table>");
	if (jinfo || hinfo || ginfo) {
		document.writeln('<br>');
		document.writeln('<table align="center">');
		if (jinfo) { document.writeln (jtext); };
		if (hinfo) { document.writeln (htext); };
		if (ginfo) { document.writeln (gtext); };
		document.writeln('</table>');
	};
	if (language=="dutch") {
		document.writeln (f1,'<p align="center">');

		document.writeln ('<table border=1 width=600 cellspacing=0 cellpadding=5>');
		document.writeln ('<tr><td valign=top>Pasen</td>'
				+'<td valign=top>= Zondag na Paschale Volle maan (PVM)'
				+' = <u>berekende schatting</u> van 1e volle maan in de lente</td></tr>');
		document.writeln ('<tr><td valign=top>Carnaval (zondag voor vastenavond, vastenavond = dag voor aswoensdag)</td>'
				+'<td valign=top>= 7 weken voor Pasen (aswoensdag = 40 dagen voor Pasen, zondagen niet meegeteld)</td></tr>');
		document.writeln ('<tr><td valign=top>Pinksteren</td>'
				+'<td valign=top>= 7 weken na Pasen '
				+'("Pinksteren" = verbastering van "Pentacosta" = Grieks voor "50", begin dagen te tellen '
				+'met "1" op Paaszondag, de 50e dag is dan Pinksteren)</td></tr>');
		document.writeln ('<tr><td valign=top>Hemelvaart</td><td valign=top>= 10 dagen voor Pinksteren</td></tr>');
		document.writeln ('</table>');

		document.writeln ('<p align="center"><font size=-1 color="blue">',copyrightdutch,'</font>' + f2);
		document.writeln ('<p>&nbsp;');
		document.writeln ('<table align="center" width=500><tr><td align="center"><font size=2 face="Arial" color="red">');
		document.writeln ('<b><u>DISCLAIMER</u></b>');
		document.writeln ('<p align="justify">');
		document.writeln ('Deze resultaten van de Paasdatumberekening dienen slechts voor demonstratieve doeleinden');
		document.writeln ('en voor het vermaak van personen die interesse of plezier hebben in de wiskundige aspecten');
		document.writeln ('van de Paasdatumberekening.');
		document.writeln ('De auteur of welke vermelde bron dan ook kan niet aansprakelijk worden gesteld voor de');
		document.writeln ('gevolgen van miscalculaties of misinterpretaties van het resultaat.');
		document.writeln ('Bij het plannen van activiteiten op basis van een Paas(gerelateerde )datum moeten altijd');
		document.writeln ('andere bronnen worden geraadpleegd om de juistheid van bovenvermelde data te verifi&euml;ren.');
		document.writeln ('</font></td></tr></table>');
	} else {
		document.writeln (f1,'<p align="center">');

		document.writeln ('<table border=1 width=600 cellspacing=0 cellpadding=5>');
		document.writeln ('<tr><td valign=top>Easter</td><td valign=top>= Sunday after Paschal Full Moon (PFM) = <u>computed estimate</u> of 1st full moon in spring</td></tr>');
		document.writeln ('<tr><td valign=top>Carnival<br>(Sunday before Mardi&nbsp;Gras / Pancake&nbsp;Tuesday)</td><td valign=top>= 7 weeks before Easter (Ash Wednesday = 40 days before Easter, not counting Sundays)</td></tr>');
		document.writeln ('<tr><td valign=top>Pentecost<br>(White Sunday)</td><td valign=top>= 7 weeks past Easter',
					' ("Pentacosta" = Greek for "50", start counting days with "1" on Easter Sunday, then 50th day = White Sunday)</td></tr>');
		document.writeln ('<tr><td valign=top>Ascension</td><td valign=top>= 10 days before Pentecost</td></tr>');
		document.writeln ('</table>');

		document.writeln ('<p align="center"><font size=-1 color="blue">',copyrightstring,'</font>' + f2);
		document.writeln ('<p>&nbsp;');
		document.writeln ('<table align="center" width=500><tr><td align="center"><font size=2 face="Arial" color="red">');
		document.writeln ('<b><u>DISCLAIMER</u></b>');
		document.writeln ('<p align="justify">');
		document.writeln ('These results of the Easter date calculator are provided for demonstrating purposes only');
		document.writeln ('and to enjoy people who have interest or fun in the mathematics of Easter date calculations.');
		document.writeln ('The author or any other source mentioned cannot be held responsible for any consequences');
		document.writeln ('of miscalculations or misinterpretations of the result.');
		document.writeln ('When planning activities based on an Easter (related) date,');
		document.writeln ('always consult other references to verify the correctness of the dates shown above.');
		document.writeln ('</font></td></tr></table>');
	};
	document.writeln ("<br>")
	sitemeter()
	document.writeln ("</body></html>");
	window.status = "";
	return true;
};
// =====================================================================================

function CompareAllMethods (low, high) {
//	--------------------------------------------------------------------------------
//	This function compares the results of all given algorithms for the entire
//	year range from low to high and lists any differences.
//	--------------------------------------------------------------------------------
	//
	var r,n,year,j1,j2,j3,g1,g2,g3,g4,g5,y,ok;
	//
	var listAll = false;	// set to true in order to list ALL Easter dates.
	//
	// in the next line the initial "C" is intentionally omitted:
	r = "omparing Easter date algorithms for year range " + low + ".." + high;
	n = 0;
	document.writeln ("C" + r);
	for (year = low; year <= high; year++) {
		window.status = "" + year + ": " + n;
		j1 = EasterJulianTables (year);
		j2 = EasterJulianDelambre (year);
		j3 = EasterJulianTondering (year);
		g1 = EasterGregorianTables (year);
		g2 = EasterGregorianLiliusClavius (year);
		g3 = EasterGregorianGauss (year);
		g4 = EasterGregorianDelambre (year);
		g5 = EasterGregorianTondering (year);
		y  = "<br>"   + formatnumber (year,4,"0");
		y  =  y + " " + formatnumber (j1,3,"0");
		y  =  y + " " + formatnumber (j2,3,"0");
		y  =  y + " " + formatnumber (j3,3,"0");
		y  =  y + " " + formatnumber (g1,3,"0");
		y  =  y + " " + formatnumber (g2,3,"0");
		y  =  y + " " + formatnumber (g3,3,"0");
		y  =  y + " " + formatnumber (g4,3,"0");
		y  =  y + " " + formatnumber (g5,3,"0");
		ok =      Compare (j1,j2,1 );
		ok = ok * Compare (j1,j3,ok);
		ok = ok * Compare (j2,j3,ok);
		ok = ok * Compare (g1,g2,ok);
		ok = ok * Compare (g1,g3,ok);
		ok = ok * Compare (g1,g4,ok);
		ok = ok * Compare (g1,g5,ok);
		ok = ok * Compare (g2,g3,ok);
		ok = ok * Compare (g2,g4,ok);
		ok = ok * Compare (g2,g5,ok);
		ok = ok * Compare (g3,g4,ok);
		ok = ok * Compare (g3,g5,ok);
		ok = ok * Compare (g4,g5,ok);
		if (ok==0) {
			n++;
			document.writeln (y + " ERROR");
		} else if (listAll) {
			document.writeln (y);
		};
	};
	document.writeln ("<br>Ready c" + r + ", found " + n + " errors");
	window.status = "";
	return true;
};
// =====================================================================================

function Compare (d1,d2,previousResult) {
//	--------------------------------------------------------------------------------
//	This function checks if d1 and d2 are valid and equal.
//	It is used by CompareAllMethods.
//	--------------------------------------------------------------------------------
	return (previousResult && (""+d1 == "NaN" || ""+d2 == "NaN" || d1 == d2));
};
// =====================================================================================

function buildform (language, defalg) {
//	--------------------------------------------------------------------------------
//	This functions builds the easterform document.
//	--------------------------------------------------------------------------------
	//
	var title,algtxt,grgtx1,grgtx2,lowtxt,higtxt,restxt,statxt;
	//
	if (language=="dutch") {
		title  = "Paasdatumrekenmachine";
		algtxt = "Algoritme";
		algtx2 = "<br>(afgezien van het verschil tussen Juliaanse<br>en Gregoriaanse berekening geven<br>alle algoritmes hetzelfde resultaat)"
		grgtx1 = "Gebruik Gregoriaanse algoritme vanaf:<br>(alleen voor Universele algoritmes)";
		grgtx2 = "Juliaans resultaat omzetten naar<br>Gregoriaanse kalender vanaf:";
		lowtxt = "Van jaar";
		higtxt = "T/m jaar";
		restxt = "Herstel";
		statxt = "Start";
	} else {
		title  = "Easter date calculator";
		algtxt = "Algorithm";
		algtx2 = "<br>(apart from the Julian/Gregorian difference<br>all algorithms give the same result)"
		grgtx1 = "Use Gregorian algorithm since:<br>(only for Universal algorithms)";
		grgtx2 = "Convert Julian result to<br>Gregorian calendar since:";
		lowtxt = "Low year";
		higtxt = "High year";
		restxt = "Reset";
		statxt = "Start";
	};
	document.writeln('<html>');
	document.writeln('<head>');
	document.writeln('<title>',title,'</title>');
	document.writeln('</head>');
	document.writeln('<body bgcolor="bisque" link="blue" alink="blue" vlink="blue">');
	document.writeln('<font face="Arial">');
	if (language=="dutch") {
	//	document.writeln('<center><a href="paasdatum.htm"><font size=+3>',title,'</font></a>');
		document.writeln('<center><u><font size=+3>',title,'</font></u>');
		document.writeln('<p><a href="eastercalc.htm?defalg=',defalg,'">Click here for English version.</a>');
	} else {
		document.writeln('<center><u><font size=+3>',title,'</font></u>');
		document.writeln('<p><a href="eastercalc.htm?defalg=',defalg,'&language=dutch">Klik hier voor Nederlandse versie.</a>');
	};
	document.writeln('</center>');
	document.writeln('<form name="easterform">');
	document.writeln('<input type="hidden" name="language" value="'+language+'">');
	document.writeln('<input type="hidden" name="defalg"   value="'+defalg+'">');
	document.writeln('<table border align="center" cellpadding=10>');
	document.writeln('<tr><td align="right"><a href="index.htm"><font face="Arial">'+algtxt+':</font></a>'+algtx2+'</td><td><font face="Arial">');
//
// Netscape does NOT return the value of a selectable item in a form,
// i.e. in this case the <select name="algorithm"> object.
// In Netscape the reference "document.form.algorithm.value" returns "null".
// In Internet Explorer it works fine.
// However, both NS and IE correctly return "document.form.algorithm.selectedIndex",
// which is an index in the option list, starting at zero.
// Therefore I use algname[document.form.algorithm.selectedIndex+1] for the value.
// (algname is an array in which the names start at index 1).
//
	document.writeln('<select name="algorithm" onchange="setalgrange(this,this.form.low,this.form.high);" style="font:10pt MS Sans Serif">');
	for (var i = 1; i <= algname[0]; i++) {
		document.write ('<option value="',algname[i],'">');
		if (language == "dutch") { document.writeln(algdutch[algname[i]]) }
		else                     { document.writeln(         algname[i] ) };
	};
	document.writeln('</select></font></td></tr>');
//
	document.writeln('<tr><td align="right"><font face="Arial">'+lowtxt+':</font></td><td><font face="Arial">');
	document.writeln('<input type="text"   name="low"                 size=4 maxlength=4 onchange="return      ValidateYearField(this              ,this.form.high    ,\'atleast\',algname[this.form.algorithm.selectedIndex+1],true,\'\');">');
	document.writeln('\&nbsp;\&nbsp;\&nbsp;\&nbsp;');
	document.writeln('<input type="button"                 value="+1"     onclick="this.form.low.value++;      ValidateYearField(this.form.low     ,this.form.high    ,\'atleast\',algname[this.form.algorithm.selectedIndex+1],true,\'\');">');
	document.writeln('<input type="button"                 value="-1"     onclick="this.form.low.value--;      ValidateYearField(this.form.low     ,this.form.high    ,\'atleast\',algname[this.form.algorithm.selectedIndex+1],true,\'\');">');
	document.writeln('</font></td></tr>');
//
	document.writeln('<tr><td align="right"><font face="Arial">'+higtxt+':</font></td><td><font face="Arial">');
	document.writeln('<input type="text"   name="high"                size=4 maxlength=4 onchange="return      ValidateYearField(this              ,this.form.low     ,\'atmost\' ,algname[this.form.algorithm.selectedIndex+1],true,\'\');">');
	document.writeln('\&nbsp;\&nbsp;\&nbsp;\&nbsp;');
	document.writeln('<input type="button"                 value="+1"     onclick="this.form.high.value++;     ValidateYearField(this.form.high    ,this.form.low     ,\'atmost\' ,algname[this.form.algorithm.selectedIndex+1],true,\'\');">');
	document.writeln('<input type="button"                 value="-1"     onclick="this.form.high.value--;     ValidateYearField(this.form.high    ,this.form.low     ,\'atmost\' ,algname[this.form.algorithm.selectedIndex+1],true,\'\');">');
	document.writeln('</font></td></tr>');
//
	document.writeln('<tr><td align="right"><font face="Arial">'+grgtx2+ '</font></td><td><font face="Arial">');
	document.writeln('<input type="text"   name="gregyear" value=1583 size=4 maxlength=4 onchange="return      ValidateYearField(this              ,this.form.gregalg ,\'atleast\',algname[5],true,\'\');">');
	document.writeln('\&nbsp;\&nbsp;\&nbsp;\&nbsp;');
	document.writeln('<input type="button"                 value="+1"     onclick="this.form.gregyear.value++; ValidateYearField(this.form.gregyear,this.form.gregalg ,\'atleast\',algname[5],true,\'\');">');
	document.writeln('<input type="button"                 value="-1"     onclick="this.form.gregyear.value--; ValidateYearField(this.form.gregyear,this.form.gregalg ,\'atleast\',algname[5],true,\'\');">');
	document.writeln('</font></td></tr>');
//
	document.writeln('<tr><td align="right"><font face="Arial">'+grgtx1+ '</font></td><td><font face="Arial">');
	document.writeln('<input type="text"   name="gregalg"  value=1583 size=4 maxlength=4 onchange="return      ValidateYearField(this              ,this.form.gregyear,\'atmost\' ,algname[5],true,\'\');">');
	document.writeln('\&nbsp;\&nbsp;\&nbsp;\&nbsp;');
	document.writeln('<input type="button"                 value="+1"     onclick="this.form.gregalg.value++;  ValidateYearField(this.form.gregalg ,this.form.gregyear,\'atmost\' ,algname[5],true,\'\');">');
	document.writeln('<input type="button"                 value="-1"     onclick="this.form.gregalg.value--;  ValidateYearField(this.form.gregalg ,this.form.gregyear,\'atmost\' ,algname[5],true,\'\');">');
	document.writeln('</font></td></tr>');
//
	document.writeln('<tr><td align="right"><font face="Arial"><input type="button" value="'+restxt+'" onclick="this.form.algorithm.selectedIndex=',defalg,'; this.form.gregalg.value=1583; this.form.gregyear.value=1583; this.form.low.value=ThisYear(-10); this.form.high.value=ThisYear(+10); return true;"></font></td>');
	document.writeln('    <td align="left" ><font face="Arial">');
	if (navigator.appName == "Netscape") {
		document.writeln('<input type="submit" value="Submit">');
	} else {
		document.writeln('<input type="button" value="'+statxt+'" onclick="return MakeEasterList(this.form.low.value,this.form.high.value,algname[this.form.algorithm.selectedIndex+1],this.form.gregalg.value,this.form.gregyear.value,\''+language+'\');">');
		document.writeln('<input type="submit" value="Submit">');
	};
	document.writeln('</font></td></tr>');
	document.writeln('</table>');
	document.writeln('</form>');

	if (navigator.appName == "Netscape") {
		document.writeln ('<table width=450 align="center"><tr><td><p align="center"><font face="Arial" color="red" size=-1>');
		if (language=="dutch") {
			document.writeln ('Op <u>mijn</u> computer is <b><u>Internet&nbsp;Explorer</u></b> veel sneller dan <b><u>Netscape</u></b>&nbsp;!');
//			document.writeln ('U gebruikt nu <b><u>Netscape</u></b>. Dat is prima, maar met');
//			document.writeln ('<b><u>Internet&nbsp;Explorer</u></b> werkt de Paasberekening VEEL sneller!');
		} else {
			document.writeln ('At <u>my</u> computer <b><u>Internet&nbsp;Explorer</u></b> is much faster than <b><u>Netscape</u></b>&nbsp;!');
//			document.writeln ('You are currently using <b><u>Netscape</u></b>. That\'s fine, but with');
//			document.writeln ('<b><u>Internet&nbsp;Explorer</u></b> the Easter calculation is MUCH faster!');
		};
		document.writeln ('</font></td></tr></table>');
	} else {
		document.writeln ('<table width=450 align="center"><tr><td><p align="justify"><font face="Arial" size=-1>');
		if (language=="dutch") {
			document.writeln ('Met de <b>Start</b> knop wordt alles lokaal afgehandeld op uw computer.');
			document.writeln ('Met de <b>Submit</b> knop wordt het formulier verstuurd en de pagina opnieuw geladen.');
			document.writeln ('Als u het resultaat wilt <u>afdrukken</u> moet u <b>Submit</b> gebruiken.');
		} else {
			document.writeln ('When pressing the <b>Start</b> button, everything is handled locally on your computer.');
			document.writeln ('When pressing the <b>Submit</b> button, the form is submitted and the page reloaded.');
			document.writeln ('If you want to <u>print</u> the result then you must use <b>Submit</b>.');
		};
		document.writeln ('</font></td></tr></table>');
	};
	if (language=="dutch") {
		document.writeln ('<p align="center"><font size=-1 color="blue">',copyrightdutch,'</font>');
	} else {
		document.writeln ('<p align="center"><font size=-1 color="blue">',copyrightstring,'</font>');
	};
// update 2000-04-01:
	document.writeln ('<p align="center"><font size=-1>')
	document.writeln ('<a href="http://www.dioceserimouski.com/ch/paquescalc2.html" target=_blank>Version française</a>')
	document.writeln ('implémenté par le')
	document.writeln ('<a href="http://www.dioceserimouski.com" target=_blank>Diocèse de Rimouski</a> (Québec).')
	document.writeln ('</font>')
// end update.
//
	document.writeln('<script language="JavaScript">');
	document.writeln('document.easterform.algorithm.selectedIndex=',defalg,';');
	document.writeln('if (document.easterform.low.value=="" ) { document.easterform.low.value  = ThisYear(-10); };');
	document.writeln('if (document.easterform.high.value=="") { document.easterform.high.value = ThisYear(+10); };');
	document.writeln('</script>');
	document.writeln('</font>');
	sitemeter()
	document.writeln('</body>');
	document.writeln('</html>');

	try
	{	top.easteralgindex.markCurrent (language == "dutch" ? "rekenmachine" : "eastercalc")
	} catch (e) {}

	window.focus()
	return true;
};
// =====================================================================================
function sitemeterHTML (siteRoot, smServer, smCode, center, debug)	// copied from sitemeter.js
{
	// next line get last 2 fields of domain	// DISABLED: + first directory,
							// DISABLED: e.g. it takes: "domain.com/me" from: "http://www.domain.com/me/subdir1/subdir2"
	var root	= location.hostname.split('.').slice(-2).join('.').toLowerCase()	// DISABLED: + "/" + location.href.split('/')[3]
	var now		= new Date()
	var smDomain	= 'http://' + smServer + '.sitemeter.com/'
	var smSite	= '?site=' + smServer + smCode
	var smStats	= smDomain + 'stats.asp' + smSite
	var smMeter	= smDomain + 'meter.asp' + smSite
	var smRefer	= (parent ? parent.document.referrer : document.referrer)
	var smRtype	= (smRefer ? (parent ? 1 : 4) : 0)
	var smHours	= now.getHours()
	var smMinutes	= now.getMinutes()
	var smParams	= '&refer=' + escape(smRefer) + '&rtype=' + smRtype + '&hours=' + smHours + '&minutes=' + smMinutes
	return	(center ? '<center>' : '')
	+ '<a target=_blank href="' + smStats + '">'
	+ '<img'
	+ ' title="Site Meter' + (debug ? '\n(' + smMeter + smParams + ')"' : '"')
	+ ' id=sitemeterlogo'
	+ ' border=0'
	+ ' src=sitemeterlogo.gif'
	+ (root != siteRoot ? ''
	  : ' onload=setTimeout("with(document.all.sitemeterlogo){onload=null;src=\''+smMeter+smParams+'\'}",10)'
	  )
	+ '>'
	+ '</a><br>'
	+ (center ? '</center>' : '')
}
// =====================================================================================
function sitemeter() {
	document.write ('<p align=center>')
	document.write (sitemeterHTML ("henk-reints.nl", "sm2", "HRchelloEaster") )
}
// =====================================================================================

function element (i, sep, text) {
//	--------------------------------------------------------------------------------
//	This function treats 'text' as a concatenation of substrings separated by 'sep'
//	and returns the i'th substring. counting starts with zero.
//	if there are less than i occurrances of sep then sep is returned.
//	(this is the same behaviour as the OpenVMS lexical function f$element).
//	--------------------------------------------------------------------------------
	//
	var j,k,m,n;
	//
	n = 0;
	j = 0;
	k = text.indexOf (sep, j); if (k == -1) { k = text.length; };
	m = k + sep.length;
	while (n < i && m < text.length) {
		n++;
		j = m;
		k = text.indexOf (sep, j); if (k == -1) { k = text.length; };
		m = k + sep.length;
	};
	return ( (n < i) ? sep : text.substr (j, k-j) );
};
// =====================================================================================

function startup () {
//	--------------------------------------------------------------------------------
//	This function is called whenever the page is loaded.
//	It parses 'location.search' and takes action accordingly.
//	--------------------------------------------------------------------------------
	//
	var i,j,x,y,z,f,v,w;
	var low      = null;
	var high     = null;
	var alg      = null;
	var gregalg  = null;
	var gregyear = null;
	var language = null;
	var defalg   = 0;
	//
	y = location.search; if (y != "") y = element (1, "?", y);
	i = 0;
	x = ((y=="") ? "&" : element (i, "&", y) );
	while (x != "&") {
		f = element (0, "=", x);
		v = element (1, "=", x);
		w = "";
		j = 0;
		while (j < v.length) {
			z = v.charAt(j);
			if (z=="+") { z = " "; };
			if (z=="%") { z = unescape(v.substr(j,3)); j += 2; };
			w += z;
			j++;
		};
		if (f=="low"      ) { low      = w; };
		if (f=="high"     ) { high     = w; };
		if (f=="algorithm") { alg      = w; };
		if (f=="gregalg"  ) { gregalg  = w; };
		if (f=="gregyear" ) { gregyear = w; };
		if (f=="language" ) { language = w; };
		if (f=="defalg"   ) { defalg   = w; };
		i++;
		x = element (i, "&", y);
	};
	if (navigator.appName != "Netscape") {top.window.moveTo(0,0);top.window.resizeTo(screen.availWidth,screen.availHeight);};
	if (low != null && high != null && alg != null && gregalg != null && gregyear != null) {
		MakeEasterList (low, high, alg, gregalg, gregyear, language);
	} else {
		buildform (language, defalg);
	};
};
// =====================================================================================

startup();

