/* Abrahamic Calendar - a JavaScript Secular, Western Christian, Orthodox Christian, Hebrew, Islamic, Coptic and Bahai (Western) greeting calendar.
(C)OPYRIGHT Virtual Church of the Blind Chihuahua(TM), 2003,2007,2008. USE UNDER GPL. CONTACT: http://www.dogchurch.org/narthex/contact.html
PUT <script type="text/javascript" src="http://j.maxmind.com/app/geoip.js"></script> IN YOUR HTML BEFORE THIS SCRIPT TO use GeoIP in SUNRISE/SUNSET CALCULATION
PUT <script type="text/javascript" src="http://topocoding.com/api/getapi_v1.php?key=YOURKEY"></script> TO ADD Elevation Correction
ACKNOWLEDGMENTS: Acknowledge dogchurch.org for this script, and Maxmind.com for geoip location services, topocoding.com for altitude services
Date Conversions adapted from "Calendrical Calculations" (henceforth CC) by Reingold and Dershowitz, Cambridge U Press, 2001,2002.
DISCLAIMER: We do not certify the accuracy or reliability of this script for any purpose whatsoever. Use at your own risk.
2.17: Dec 2008 ABCalWidget function, DateFmFix function
2.16: Jun 2008 Mayan Long Count and Hindu Kali Yuga day count added, elevation corrections to sunrise/set using topocoding.com
2.15: Jun 2008 sgn & clockMod functions added, ccMod eliminated. Bahai calendar uses Bahai dates. Liturgical time intervals can straddle midnight.
	  Consolidated Salutation functions. Seasons can overlap. CC-like Easter & qibla functions. Corrected shela & birkath ha-hama dates. dateLocale global object
2.13: Aug 2007 try/catch blocks added for GeoIP functions, making MaxMind script optional.
2.12: May 2007 Clock object for Liturgical Times, Solar Time calculations from NOAA, GeoIP from MaxMind.
2.02: Apr 2007 Bahai and Coptic calendars, fractional fixed (R.D.) dates, use of Date.getTime().
1.73: Jan 2006 Calendar object. Julian Calendar for Orthodox Holidays, CC-like version of from() & Hebrew Holiday adjustments.
1.00  ??? 2003 Initial version: Hebrew, Islamic and combined Western Secular-Liturgical calendars
Example Usage: document.write(Salutation("Gregorian")); Example Test: document.write(Salutation("Gregorian",Date,geoLocale)); for other times and places
Cross-Validation: http://emr.cs.iit.edu/home/reingold/calendar-book/Calendrica.html */
// ***************************************************************************************** New Date property & methods Test
Date.prototype.kind = "Gregorian"; // default type
Date.prototype.getTimeOfDay = function(){return this.getHours()*60+this.getMinutes()} // minutes from midnight
Date.prototype.get = function(what,kind,where){ // what="year"|"month"|"date"|"day"|"major"|"cycle"
	var kk=kind||this.kind; var ffdate=fixFmDate(this); var w=where||dateLocale; var a=(this.getTimeOfDay()>getSolarTimes(this,w)[2])?1:0;
	switch (kk){
		case "Julian": case "Orthodox":	return JulianFmFix(ffdate,what);
		case "Coptic":		return CopticFmFix(ffdate,what);
		case "Hebrew":		return HebrewFmFix(ffdate+a,what);
		case "Islamic":		return IslamicFmFix(ffdate+a,what);
		case "Bahai":		return BahaiFmFix(ffdate+a,what);
		case "Long Count": 	return LongCountFmFix(ffdate,what);
		default:			return GregorianFmFix(ffdate,what);
}}
Date.prototype.set = function(yyyy,mm,df,kind,major,cycle){ // df=date.fraction (of day)
	var ffdate; if(kind) this.kind=kind;
	switch(this.kind){
		case "Julian": case "Orthodox":	ffdate = fixFmJulian(yyyy,mm,df); break;
		case "Coptic":		ffdate = fixFmCoptic(yyyy,mm,df); break;
		case "Hebrew":		ffdate = fixFmHebrew(yyyy,mm,df); break;
		case "Islamic":		ffdate = fixFmIslamic(yyyy,mm,df); break;
		case "Bahai":		ffdate = fixFmBahai(major,cycle,yyyy,mm,df); break;
		case "Long Count": 	ffdate = fixFmLongCount(major,cycle,yyyy,mm,df);break;
		default:			ffdate = fixFmGregorian(yyyy,mm,df);
	} this.setTime((ffdate-epoch["javascript"])*msd);
}
Date.prototype.from = function(n,kday,mcycle,offset){ // nth day, or kday of the mcycle, from Date. n<0 on or before, n=0 in same week, n>0 on or after
	var result, jetzt=fixFmDate(this);
	if(typeof(kday) == "number"){ var m=mcycle||7, Delta=offset||0, d=this.getDay(), s=sgn(n);
		result=DateFmFix(jetzt+(n-s)*m-(d+Delta-kday-(s*m))%m);
	} else result=DateFmFix(jetzt+n);
	result.kind=this.kind; return result;
}
function altDate(mjr,cyc,yyyy,mm,dd,ff,kind){this.major=mjr;this.cycle=cyc;this.year=yyyy;this.month=mm;this.date=dd;this.frac=ff;this.kind=kind;} //return type only
//******************************************* Date Conversions adapted from "Calendrical Calculations," Reingold & Dershowitz, Cambridge U Press, 2001,2002.
var msd=86400000, tzo=(new Date()).getTimezoneOffset(); var epoch=[]; epoch["Hebrew"]=-1373427; epoch["Mayan"]=-1137142; epoch["Hindu"]=-1132959; 
epoch["Julian"]=-1; epoch["Gregorian"]=1; epoch["Coptic"]=103605; epoch["Islamic"]=227015; epoch["Bahai"]=673222; epoch["javascript"]=719163-tzo/1440; 
function clockMod(n,m) {if(m==0) return null; var rslt=n%m; return (rslt<0)?(m-rslt):rslt;}
function IntDiv(num,dvsr) {if(dvsr==0) return null; var rslt=num/dvsr; return (rslt<0)?Math.ceil(rslt):Math.floor(rslt);}
function sgn(x) {if(x>0) return 1; else if(x<0) return -1; else return 0;}
function fixFmDate(aDate) {return (epoch["javascript"]*msd+aDate.getTime())/msd;}
function DateFmFix(ffdate) {var result=new Date(); result.setTime((ffdate-epoch["javascript"])*msd); return result;}
// Gregorian
function GregorianLeapYear(ayear){return ((ayear%4==0)&&(ayear%100!=0))||(ayear%400==0);}
function fixFmGregorian(yyyy,mm,df){ if(yyyy instanceof Date) return fixFmDate(yyyy);
	var y1=yyyy-1; var fdate=epoch["Gregorian"]-1+365*y1+Math.floor(y1/4)-Math.floor(y1/100)+Math.floor(y1/400)+Math.floor((367*(mm+1)-362)/12)+df;
	if(mm>1) fdate-=GregorianLeapYear(yyyy)?1:2; return fdate;
}
function GregorianFmFix(ffdate,what){ var aDate=DateFmFix(ffdate);
	switch(what){case "day":return aDate.getDay();case "year":return aDate.getFullYear();case "month":return aDate.getMonth();case "date":return aDate.getDate();}
	if(what)return false; return aDate;
}
//Julian
function JulianLeapYear(jYear) {return (jYear > 0)?(jYear%4 == 0):(jYear%4 == 3);}
function fixFmJulian(yyyy,mm,df){ if(yyyy instanceof Date) return fixFmDate(yyyy);
	var y1 = (yyyy<0)?yyyy:yyyy-1;
	var fdate=epoch["Julian"]-1+365*y1+Math.floor(y1/4)+Math.floor((367*(mm+1)-362)/12)+df;
	if(mm>1) fdate-=JulianLeapYear(yyyy)?1:2; return fdate;
}
function JulianFmFix(ffdate,what){
	var fdate=Math.floor(ffdate), frac=ffdate-fdate;				if(what=="day") return fdate%7;
	var approx = Math.floor((4*(fdate-epoch["Julian"])+1464)/1461); 
	var yyyy = (approx > 0)?approx:approx-1;						if(what=="year") return yyyy;
	var pdays = fdate-fixFmJulian(yyyy,0,1); 
	var corr=0; if(fdate >= fixFmJulian(yyyy,2,1)) corr+=(JulianLeapYear(yyyy))?1:2;
	var mm = Math.floor((12*(pdays+corr)+373)/367)-1;				if(what=="month") return mm;
	var dd = fdate-fixFmJulian(yyyy,mm,1)+1;						if(what=="date") return dd; if(what) return false;
	return new altDate(0,0,yyyy,mm,dd,frac,"Julian");
}
//Coptic		function CopticLeapYear(cYear) {return cYear%4==3;}
function fixFmCoptic(yyyy,mm,df){ if(yyyy instanceof Date) return fixFmDate(yyyy); return epoch["Coptic"]-1+365*(yyyy-1)+Math.floor(yyyy/4)+30*mm+df; }
function CopticFmFix(ffdate,what){
	var fdate=Math.floor(ffdate), frac=ffdate-fdate;				if(what=="day") return fdate%7;
	var yyyy = Math.floor((4*(fdate-epoch["Coptic"])+1463)/1461);	if(what=="year") return yyyy;
	var mm = Math.floor((fdate-fixFmCoptic(yyyy,0,1))/30);			if(what=="month") return mm;
	var dd = fdate + 1 - fixFmCoptic(yyyy,mm,1);					if(what=="date") return dd; if(what) return false;
	return new altDate(0,0,yyyy,mm,dd,frac,"Coptic");
}
// Islamic
function fixFmIslamic(yyyy,mm,df) { if(yyyy instanceof Date) return fixFmDate(yyyy);
	return epoch["Islamic"]-1 + (yyyy-1)*354+Math.floor((3+11*yyyy)/30) + 29*mm + Math.floor((mm+1)/2.0) + df;
}
function IslamicFmFix(ffdate,what){
	var fdate=Math.floor(ffdate), frac=ffdate-fdate;				if(what=="day") return fdate%7;
	var yyyy=Math.floor((30*(fdate-epoch["Islamic"])+10646)/10631); if(what=="year") return yyyy;
	var pdays=fdate-fixFmIslamic(yyyy,0,1);
	var mm=Math.floor((11*pdays+330)/325)-1;						if(what=="month") return mm;
	var dd=fdate-fixFmIslamic(yyyy,mm,1)+1;							if(what=="date") return dd; if(what) return false;
	return new altDate(0,0,yyyy,mm,dd,frac,"Islamic");
}
// Hebrew
function HebrewLeapYear(hyear) { return (7*hyear+1)%19<7; }
function HebCalElapsDays(hyear){
	var months_elapsed = Math.floor((235*hyear-234)/19);
	var parts_elapsed = 12084+13753*months_elapsed;
	var day1 = 29*months_elapsed+Math.floor(parts_elapsed/25920)+1;
	return (3*day1)%7<3 ? day1 : --day1 ;
}
function HebNYDelay(hyear){
	var days; var ny0 = HebCalElapsDays(hyear-1); var ny1 = HebCalElapsDays(hyear); var ny2 = HebCalElapsDays(hyear+1);
	if((ny2-ny1)==356) days=2; else if((ny1-ny0)==382) days=1; else days=0; return days;
}
function HebNewYear(hyear){ return epoch["Hebrew"]+HebCalElapsDays(hyear)+HebNYDelay(hyear); }
function daysInHebYear(yyyy){ return HebNewYear(yyyy+1)-HebNewYear(yyyy); }
function lastDayHebMonth(hyear,hmonth){
	if(hmonth==1 || hmonth==3 || hmonth==5 || hmonth==9 || hmonth==12) return 29;
	if(hmonth==11) return (HebrewLeapYear(hyear))?30:29; var y=daysInHebYear(hyear);
	if(hmonth==7)  return (y==355||y==385)?30:29; // long marheshvan
	if(hmonth==8)  return (y==353||y==383)?29:30; // short kislev
	return 30;	
}
function fixFmHebrew(yyyy,mm,df){ if(yyyy instanceof Date) return fixFmDate(yyyy);
	var dd=HebNewYear(yyyy)+df-1; 
	if(mm<6){var mlast=(HebrewLeapYear(yyyy))?13:12; for(var m=6;m<mlast;m++) dd+=lastDayHebMonth(yyyy,m); for(var m=0;m<mm;m++) dd+=lastDayHebMonth(yyyy,m);}
	else {for(var m=6;m<mm;m++) dd+=lastDayHebMonth(yyyy,m);} 
	return dd;
}
function HebrewFmFix(ffdate,what){
	var fdate=Math.floor(ffdate), frac=ffdate-fdate;				if(what=="day") return fdate%7;
	var yyyy, mm, dd=1, start, mlast, approx=Math.floor((fdate-epoch["Hebrew"])/(35975351/98496)); 
	for(var y=approx; HebNewYear(y)<=fdate; y++){ yyyy=y; }			if(what=="year") return yyyy;
	start=(fdate<fixFmHebrew(yyyy,0,1))?6:0; mlast=(HebrewLeapYear(yyyy))?13:12; mm=start-1; 
	for(var m=start;m<mlast;m++){if(fdate<=fixFmHebrew(yyyy,m,lastDayHebMonth(yyyy,m))){mm=m; break;}}	if(what=="month") return mm;
	dd=fdate-fixFmHebrew(yyyy,mm,1)+1;								if(what=="date") return dd;	if(what) return false;
	return new altDate(0,0,yyyy,mm,dd,frac,"Hebrew");
}
//Bahai
function fixFmBahai(major,cycle,yyyy,mm,df){ if(major instanceof Date) return fixFmDate(major);
	var gyear = 361*(major-1) + 19*(cycle-1) + yyyy-1+1844; var ffdate = fixFmGregorian(gyear,2,20)+df;
	if(mm==0) ffdate+=342; else if(mm==19) ffdate+=GregorianLeapYear(gyear+1)?347:346; else ffdate+=19*(mm-1);
	return ffdate;	
}
function BahaiFmFix(ffdate,what){ 
	var fdate=Math.floor(ffdate), frac=ffdate-fdate;				if(what=="day") return fdate%7;
	var gyear=GregorianFmFix(fdate,"year");
	var years=gyear-1844-(fdate<=fixFmGregorian(gyear,2,20)?1:0);
	var major=Math.floor(years/361)+1;								if(what=="major") return major;
	var cycle=Math.floor((years%361)/19)+1;							if(what=="cycle") return cycle;
	var yyyy=years%19 + 1;											if(what=="year") return yyyy;
	var days=fdate-fixFmBahai(major,cycle,yyyy,1,1); var mm;
	if(fdate>=fixFmBahai(major,cycle,yyyy,19,1)) mm=19; else if(fdate>=fixFmBahai(major,cycle,yyyy,0,1)) mm=0;
	else mm=Math.floor(days/19)+1;									if(what=="month") return mm;
	var dd=fdate+1-fixFmBahai(major,cycle,yyyy,mm,1);				if(what=="date") return dd; if(what) return false;
	return new altDate(major,cycle,yyyy,mm,dd,frac,"Bahai");	
}
//Mayan Long Count
function fixFmLongCount(baktun,katun,tun,uinal,kin){if(baktun instanceof Date) return fixFmDate(baktun);
	return epoch["Mayan"]+baktun*144000+katun*7200+tun*360+uinal*20+kin; }
function longCountFmFix(ffdate,what){ var fdate=Math.floor(ffdate), frac=ffdate-fdate;
	var long_count = fdate-epoch["Mayan"], cycle_end=2880000;		if(what == "countdown") return cycle_end - long_count;
	var baktun = Math.floor(long_count/144000);						if(what=="baktun") return baktun;
	var day_of_baktun = long_count%144000
	var katun = Math.floor(day_of_baktun/7200);						if(what=="katun") return katun;
	var day_of_katun = day_of_baktun%7200;
	var tun = Math.floor(day_of_katun/360);							if(what=="tun") return tun;
	var day_of_tun = day_of_katun%360;
	var uinal = Math.floor(day_of_tun/20);							if(what=="uinal") return uinal;
	var kin = day_of_tun%20;										if(what=="kin") return kin;
	return new altDate(baktun,katun,tun,uinal,kin,frac,"Long Count");
}
//Hindu Kali Yuga
function hindu_day_count(ffdate) { return ffdate-epoch["Hindu"];}
function hindu_countdown(ffdate) { return 432000*356.25 - hindu_day_count(ffdate); }
// ********************************************************************************************** GeoLocale & Astronomical Time Calculations
var Rearth=6372.7976; // mean earth radius in km
function geoLocale(name,lati,longi,country_code,alti){ this.name=name||"My Location"; // geoip_functions in decimal degrees from MaxMind.com
	if(typeof lati == "number") this.latitude=lati; else try{this.latitude=geoip_latitude();} catch(e){this.latitude=0.0;}
	if(typeof longi == "number") this.longitude=longi; else try{this.longitude=geoip_longitude();} catch(e){this.longitude = -(new Date()).getTimezoneOffset()*0.25;}
	if(country_code)this.cc=country_code; else try{this.cc=geoip_country_code();} catch(e){this.cc="W";} this.altitude=alti||0;
	if(typeof alti == "number")this.altitude=alti; //non-working elevation lookup from topocoding.com
	else try {topoGetAltitude(this.latitude,this.longitude,function(altitude,context){context.altitude=altitude;},this,1000);} catch(e) {this.altitude=0;} // meters 
	this.lat=degToRad(this.latitude); this.lon=degToRad(this.longitude);}
var myLocale=new geoLocale(), dateLocale=myLocale; var Jerusalem=new geoLocale("Jerusalem",31.8,35.2,"IL",800), Mecca=new geoLocale("Mecca",21.423,39.823,"SA",298);
function qibla(which,wLoc){ var focus,dist,angle,w=wLoc||dateLocale; // adapted from Calendrical Calculations
	if(which=="Islamic")focus=Mecca; else if(which=="Hebrew")focus=Jerusalem; else return "";
	var denom=Math.cos(w.lat)*Math.tan(focus.lat)-Math.sin(w.lat)*Math.cos(w.lon-focus.lon);
	if(denom==0)angle=0; else {var x=(denom<0)?2:1; angle=Math.round(radToDeg(Math.atan2(Math.sin(focus.lon-w.lon)/denom,x))%360);}
	dist=Math.round(Rearth*Math.SQRT2*Math.sqrt(1+Math.cos(w.lat)*Math.cos(focus.lat)*(1-Math.cos(focus.lon-w.lon))-Math.cos(focus.lat-w.lat)));
	return nl+focus.name+" ~ "+dist.toString()+" km, "+angle.toString()+"<sup>o</sup> E";
}
function elevCorr(w){var h=Math.max(0,w.altitude); if(h>0)return radToDeg(Math.acos(Rearth/(Rearth+0.001*h)))+Math.sqrt(h)*19/3600; else return 0;} // degrees
// *********** Astronomical calculations adapted from http://www.srrb.noaa.gov/highlights/sunrise/calcdetails.html
function getSolarTimes(theDate,theLocale){ var bDate=theDate||new Date(), w=theLocale||dateLocale, snoonUTC=720-4*w.longitude, mtc=1/(1440*36524.25);
	var aDate=new Date(bDate.getFullYear(),bDate.getMonth(),bDate.getDate(),0,0,0,0); aDate.setUTCHours(0); var t0=getJulianCentury(aDate); // midnight, UTC	  
	var corr=calcEquationOfTime(t0+snoonUTC*mtc); if(typeof corr == "number") snoonUTC-=corr; var snoon=clockMod(snoonUTC-aDate.getTimezoneOffset(),1440);
	var decl=calcSunDeclination(t0+snoonUTC*mtc); var ha4=calcHourAngle(0.833+elevCorr(w),decl,w); if(typeof ha4 != "number") ha4=360;
	return [snoon-ha4,snoon,snoon+ha4,decl]; } // sunrise,noon,sunset (minutes from local midnight), solar declination (radians, positive below horizon)
function getJulianCentury(aDate){ var jNoon=new Date(2000,0,1); jNoon.setUTCHours(12); return (aDate.getTime()-jNoon.getTime())/(msd*36524.25); }
function getSolarMidnight(theDate,theLocale){ var bDate=theDate||new Date(); var wLocale=theLocale||myLocale;
	var today=getSolarTimes(bDate,wLocale), tomorrow=getSolarTimes(bDate.from(1)); return clockMod((tomorrow[0]+today[2]-1440)/2,1440);}
function radToDeg(angleRad) {return angleRad*(180/Math.PI);}   function degToRad(angleDeg) {return angleDeg*(Math.PI/180);}	
function calcGeomMeanLongSun(t){ return clockMod(280.46646 + t*(36000.76983 + 0.0003032*t),360); } // degrees
function calcGeomMeanAnomalySun(t){ return 357.52911 + t*(35999.05029 - 0.0001537*t); } // degrees
function calcEccentricityEarthOrbit(t){ return 0.016708634 - t*(0.000042037 + 0.0000001267*t); } // unitless
function calcSunEqOfCenter(t){ var m=degToRad(calcGeomMeanAnomalySun(t));
	return Math.sin(m)*(1.914602-t*(0.004817+0.000014*t))+Math.sin(2*m)*(0.019993-0.000101*t)+Math.sin(3*m)*0.000289; } // degrees
function calcSunTrueLong(t){ return calcGeomMeanLongSun(t) + calcSunEqOfCenter(t); } // degrees
function calcSunApparentLong(t){ return calcSunTrueLong(t) - 0.00569 - 0.00478*Math.sin(degToRad(125.04 - 1934.136*t)); } // degrees
function calcMeanObliquityOfEcliptic(t){ var seconds = 21.448 - t*(46.8150 + t*(0.00059 - t*0.001813)); return 23 + (26 + (seconds/60))/60; }// degrees
function calcObliquityCorrection(t){ return calcMeanObliquityOfEcliptic(t) + 0.00256*Math.cos(degToRad(125.04 - 1934.136*t)); } // degrees
function calcSunDeclination(t) { return Math.asin(Math.sin(degToRad(calcObliquityCorrection(t))) * Math.sin(degToRad(calcSunApparentLong(t)))); }// radians
function calcHourAngle(dep,decl,wLoc){ var w=wLoc||dateLocale;
	return 4*radToDeg(Math.acos(-Math.sin(degToRad(dep))/(Math.cos(w.lat)*Math.cos(decl))-Math.tan(w.lat)*Math.tan(decl)));}  // minutes of time
function calcEquationOfTime(t){
	var l0 = degToRad(calcGeomMeanLongSun(t)); var e = calcEccentricityEarthOrbit(t);
	var m = degToRad(calcGeomMeanAnomalySun(t)); var y = Math.tan(degToRad(calcObliquityCorrection(t))/2); y*=y;
	var sinm=Math.sin(m), sin2m=Math.sin(2*m); var sin4l0=Math.sin(4*l0), sin2l0=Math.sin(2*l0), cos2l0=Math.cos(2*l0);
	return  4*radToDeg(y*sin2l0 - 2*e*sinm + 4*e*y*sinm*cos2l0 - 0.5*y*y*sin4l0 - 1.25*e*e*sin2m); // minutes of time
}
//**************************************************************** Calendar Object, Properties & Methods
var Sun=0,Mon=1,Tue=2,Wed=3,Thu=4,Fri=5,Sat=6; var nl="<br />", burl="http://www.dogchurch.org/"; // www.elca.org/dcm/worship/faq/worship_space/liturgical_colors.html
var B="#0000FF",P="#800080",W="#FFFFFF",G="green",BK="#000000",S="#FF0000",GO="#F7C700",R="#DC143C",DF="#990033"; 
function Ordinal(n){if(n<1)return "";var th="th",m=n%10;if(IntDiv(n,10)==1)th="th";else if(m==1)th="st";else if(m==2)th="nd";else if(m==3)th="rd";return (n+th);}
function CalendarEvent(msg,bgcolor,bdrcolor) {this.msg=msg; this.bgcolor=bgcolor||DF; this.bdrcolor=bdrcolor||this.bgcolor;}
function CalendarEventList(){} CalendarEventList.prototype = new Object(); // a hash table of arrays
CalendarEventList.prototype.get=function(aDate){return this[aDate.get("month")+"/"+aDate.get("date")];}
CalendarEventList.prototype.set=function(mm,dd,msg,bg,bdr){var p,key=mm+"/"+dd; if(!this[key])this[key]=[]; var p=this[key].push(new CalendarEvent(msg,bg,bdr));}
CalendarEventList.prototype.setByDate=function(aDate,msg,bg,bdr){this.set(aDate.get("month"),aDate.get("date"),msg,bg,bdr);}
function CalendarSeason(name,start,stop,bgcolor,bdrcolor,ord,prefix){
	this.name=name; this.start=fixFmDate(start); this.stop=fixFmDate(stop);  this.nth=""; this.msg="";
	this.bgcolor=bgcolor||DF; this.bdrcolor=bdrcolor||this.bgcolor; if(typeof(ord)=="number") this.ord = ord; else this.ord=7; this.nday=0; this.prefix=prefix||""; }
function CalendarSeasonList(){} CalendarSeasonList.prototype = new Array();
CalendarSeasonList.prototype.set = function(name,start,stop,bg,bdr,ord,pre){var p=this.push(new CalendarSeason(name,start,stop,bg,bdr,ord,pre));}
CalendarSeasonList.prototype.get = function(qDate,theLoc){ var qFix=fixFmDate(qDate), k=qDate.kind; var ord,p,n,a,b,result=false, w=theLoc||dateLocale;
	if(k=="Bahai"||k=="Hebrew"||k=="Islamic"){ if(qDate.getTimeOfDay()>getSolarTimes(qDate,w)[2]) qFix+=1;}
	for(var i=0;i<this.length;i++){ 
		if((this[i].start<=qFix) && (qFix<=this[i].stop)){ 
			ord=Math.abs(this[i].ord); this[i].nday=1+qFix-this[i].start; a=(this[i].prefix.indexOf("after")>-1)?2:1;
			if(ord==1)n=IntDiv(this[i].nday,1); else if(ord>1) n=IntDiv(this[i].nday-a,ord)+1; this[i].nth=Ordinal(n);
			if(!result) result=[]; var p=result.push(this[i]);
	}} return result;
}
function Calendar(inDate,inKind,inLoc){ // sets for a year
	this.myDate = inDate||new Date(); this.kind=inKind||this.myDate.kind; var theYear=this.myDate.get("year"); this.myLoc=inLoc||dateLocale;
	this.Season = new CalendarSeasonList(); this.Holiday = new CalendarEventList(); var aDate=new Date(); var bDate = new Date();
	this.Month  = ["January","February","March","April","May","June","July","August","September","October","November","December"];
	this.WeekDay= ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
	this.yearName = false; this.dateName = false; this.majorName = false; this.cycleName=false;
	this.yeartype=" <a href=\"javascript:alert('Anno Domini — The Year of our Lord. The Western Churches and the international community use the annual calendar comissioned by Pope Gregory XIII in A.D. 1542 as a reform of the Julian Calendar. Years are reckoned from the Birth of Christ, as determined by a monk in Rome named Dionysius Exiguus in A. D. 525.')\">A.D.</a> ";
	this.daytype="<a href=\"javascript:alert('English day names are of Teutonic pagan origin, while organizing days into 7-day weeks is Jewish. To fix the date, reset the clock on your computer.')\">*</a>";
	switch (this.kind) {
	case "Hebrew": // with help from www.ou.org/chagim/default.htm
		this.Month = ["Nisan","Iyyar","Sivan","Tammuz","Av","Elul","Tishri","Marheshvan","Kislev","Tevet","Shevat","Adar","Adar II"];
		this.WeekDay=["yom rishon", "yom sheni","yom shelishi","yom revi'i","yom hamishi","yom shishi","yom shabbat (sabbath)"];
		this.yeartype = " <a href=\"javascript:alert('Anno Mundi - Hebrew time is reckoned from the Creation of the World as calculated from the lifespans of Biblical patriarchs.')\">A.M.</a> ";
		this.daytype = "<a href=\"javascript:alert('Hebrew and Islamic days begin at sunset, and are numbered beginning with Sunday, not named, except as noted (in parenthesis).')\">*</a>";
		var mlast; if(HebrewLeapYear(theYear)){this.Month[11]="Adar I"; mlast=12;} else mlast=11;
		this.Holiday.set(0,15,"1st Seder");
		this.Holiday.set(0,16,"2nd Seder"); aDate.set(theYear,0,27,"Hebrew"); var dd=(aDate.getDay()==Sun)?28:27;
		this.Holiday.set(0,dd,"<a href='http://www.ushmm.org/' target='win2'>Yom Ha-Shoah</a>");
		aDate.set(theYear,1,4,"Hebrew"); if(aDate.getDay()<=Wed) aDate=aDate.from(0,Wed);
		this.Holiday.setByDate(aDate,"Yom Ha-Zikaron");
		this.Holiday.set(1,5,"Yom Ha-Atzmaut");
		this.Holiday.set(1,18,"Lag B'Omer");
		this.Holiday.set(1,28,"Yom Yerushalayim");
		this.Holiday.set(2,6,"Shavu'ot (Israel & Diaspora)");
		this.Holiday.set(2,7,"Shavu'ot (Diaspora)");
		this.Holiday.set(3,17,"Asar B'Tammuz"); aDate.set(theYear,4,9,"Hebrew"); dd=(aDate.getDay()==Sat)?10:9; 
		this.Holiday.set(4,dd,"Tisha B'Av (Destruction of the Temple)");
		this.Holiday.set(4,15,"Tu B'Av");
		this.Holiday.set(6,1,"Rosh Ha-Shanah");
		this.Holiday.set(6,2,"Rosh Ha-Shanah");
		this.Holiday.set(6,3,"Tzom Gedaliah");
		this.Holiday.set(6,10,"Yom Kippur");
		this.Holiday.set(6,21,"Hoshana Rabba");
		this.Holiday.set(6,22,"Shemini Azeret"+nl+"Simchat Torah (Israel)");
		this.Holiday.set(6,23,"Simchat Torah (Diaspora)");
		this.Holiday.set(9,8,"Septuagint Translation of the Torah");
		this.Holiday.set(9,10,"Asarah B'Tevet");
		this.Holiday.set(10,15,"Tu B'Shevat"); aDate.set(theYear,mlast,14,"Hebrew"); dd=(aDate.getDay()==Sun)?10:13;
		this.Holiday.set(mlast,dd,"Fast of Esther");
		this.Holiday.set(mlast,14,"Purim");
		this.Holiday.set(mlast,15,"Shushan Purim"); var cYear=this.myDate.get("year","Coptic"); aDate.set(cYear,2,26,"Coptic"); aDate.kind="Hebrew";
		this.Holiday.setByDate(aDate,"Sh'ela (request for rain - Diaspora)");
		if(cYear%28==17){aDate.set(cYear,6,30,"Coptic"); aDate.kind="Hebrew"; this.Holiday.setByDate(aDate,"Birkath-hahama");}
		for(var i=0; i<=mlast; i++){this.Holiday.set(i,1,"Rosh Hodesh"); this.Holiday.set(i,30,"Rosh Hodesh");}
	//	Liturgical Seasons
		aDate.set(theYear,0,15,"Hebrew"); bDate.set(theYear,0,21,"Hebrew");	this.Season.set("Pesah (Passover)",aDate,bDate);
		aDate.set(theYear,0,16,"Hebrew"); bDate=aDate.from(48);				this.Season.set("Sefirat Ha-Omer",aDate,bDate,DF,DF,1);
		aDate.set(theYear,6,1,"Hebrew");  bDate.set(theYear,6,10,"Hebrew");	this.Season.set("Days of Awe",aDate,bDate);
		aDate.set(theYear,6,16,"Hebrew"); bDate.set(theYear,6,21,"Hebrew");	this.Season.set("Sukkot",aDate,bDate);
		aDate.set(theYear,8,25,"Hebrew"); bDate=aDate.from(8);				this.Season.set("Hanukkah",aDate,bDate,DF,DF,1);
		break;
	case "Islamic":
		this.Month = ["Muharram","Safar","Rabi I","Rabi II","Jumada I","Jumada II","Rajab","Sha'ban","Ramadan","Shawwal","Dhu al-Qa'da","Dhu al-Hijja"];
		this.WeekDay=["yaum al-ahad","yaum al-ithnayna","yaum ath-thalatha","yaum al-arba'a","yaum al-hamis","yaum al-jum'a (assembly)","yaum as-sabt (sabbath)"];
		this.yeartype = " <a href=\"javascript:alert('Anno Higrae - Islamic time is reckoned from the Hijra, or Emigration from Mecca to Medina.')\">A.H.</a> ";
		this.daytype = "<a href=\"javascript:alert('Hebrew and Islamic days begin at sunset, and are numbered beginning with Sunday, not named, except as noted (in parenthesis).')\">*</a>";
		this.Holiday.set(0,1,"Islamic New Year");
		this.Holiday.set(0,10,"Ashura begins (Martyrdom of Husayn)");
		this.Holiday.set(2,12,"Mawlid al-Nabiy (Birth of the Prophet)");
		this.Holiday.set(6,27,"Lailat al-Miraj (Ascension of the Prophet)");
		this.Holiday.set(7,15,"Lailat al-Bara'a (Preparation for Ramadan)"); aDate.set(theYear,8,30,"Islamic"); aDate=aDate.from(-1,Fri);
		this.Holiday.setByDate(aDate,"Jum'at al-Wada"); // last Friday in Ramadan
		this.Holiday.set(8,27,"Lailat al-Qadr (Night of Power)");
		this.Holiday.set(9,1,"Eid al-Fitr (Ramadan ends)" + nl + "<i>Eid Mubarak</i>");	
		this.Holiday.set(11,9,"Day of Arafat");
		this.Holiday.set(11,10,"Eid al-Adha (Hajj ends)");
	//	Liturgical Seasons
		aDate.set(theYear,0,10,"Islamic"); bDate.set(theYear,0,20,"Islamic");  this.Season.set("Ashura (Shia)",aDate,bDate);
		aDate.set(theYear,8,1,"Islamic");  bDate.set(theYear,8,30,"Islamic");  this.Season.set("Ramadan Mubarak",aDate,bDate);
		aDate.set(theYear,11,1,"Islamic"); bDate.set(theYear,11,10,"Islamic"); this.Season.set("Hajj",aDate,bDate);
		break;
	case "Bahai": // Western Version
		this.yearName=["","Alif","Ba","Ab (Father)","Dal","Bab (Gate)","Vav","Abad (Eternity)","Jad (Generosity)","Baha (Splendor)","Hubb (Love)","Bahhaj (Delight)",
		"Javab (Answer)","Ahad (Single)","Vahhab (Bountiful)","Vidad (Affection)","Badi (Beginning)","Bahi (Luminous)","Abha (Most Luminous)","Vahid (Unity)"];
		this.Month=["Ayyam-i-Ha (Days of God)","Baha (Splendor)","Jalal (Glory)","Jamal (Beauty)","'Azmat (Grandeur)","Nur (Light)","Rahmat (Mercy)","Kalimat (Words)","Kamal (Perfection)",
		"Asma (Names)","'Izzat (Might)","Mashiyyat (Will)","'Ilm (Knowledge)","Qudrat (Power)","Qawl (Speech)","Masa'il (Questions)","Sharaf (Honor)","Sultan (Power)","Mulk (Dominion)","'Ala' (Loftiness)"];
		this.WeekDay=["Jamal (Beauty)","Kamal (Perfection)","Fidal (Grace)","'Idal (Justice)","Istijlal (Majesty)","Istiqlal (Independence)","Jalal (Glory)"];
		this.dateName = this.Month; this.cycleName = "Vahid"; this.majorName = "Kull-i-Shay";
		this.yeartype = " <a href=\"javascript:alert('Bahai Era - Bahai time is reckoned from the spring equinox of 1844 A.D, the year the Bab declared he was the herald of a new Messenger of God for this age.')\"> B.E.</a>";
		this.daytype = "<a href=\"javascript:alert('Bahai dates, 19-day months, 19-month years and days are named after attributes of God, and begin at sunset (as do Hebrew and Islamic days). Years are grouped into 19- and 361-year minor and major cycles. The Bahai 7-day week begins on Saturday (as does the Persian week).')\">*</a>";
		var gYear=this.myDate.getFullYear(); var major = this.myDate.get("major"); var cycle=this.myDate.get("cycle");
		this.Holiday.set(0,4,"Holiday");
		this.Holiday.set(1,1,"Naw-Ruz (New Year)");
		this.Holiday.set(2,13,"Feast of Ridvan");		// Ridvan 1
		this.Holiday.set(3,2,"Holiday");				// Ridvan 9
		this.Holiday.set(3,5,"Holiday");				// Ridvan 12
		this.Holiday.set(4,7,"Declaration of the Bab");
		this.Holiday.set(4,7,"Birth of 'Abdu'l-Baha");
		this.Holiday.set(4,13,"Ascension of the Baha'u'llah");
		this.Holiday.set(6,16,"Martyrdom of the Bab");
		this.Holiday.set(12,5,"Birth of the Bab");
		this.Holiday.set(13,9,"Birth of the Baha'u'llah");
		this.Holiday.set(14,4,"Day of the Covenant"); 
		this.Holiday.set(14,6,"Ascension of 'Abdu'l-Baha");
		aDate.set(gYear,0,1,"Gregorian"); aDate=aDate.from(3,Sun); aDate.kind="Bahai";				this.Holiday.setByDate(aDate,"World Religion Day");
		aDate.set(gYear,5,1,"Gregorian"); aDate=aDate.from(2,Sun); aDate.kind="Bahai";				this.Holiday.setByDate(aDate,"Race Unity Day");
		for(var i=1;i<19;i++){this.Holiday.set(i,1,"Feast");}
		aDate.set(theYear,2,13,"Bahai",major,cycle); bDate.set(theYear,3,5,"Bahai",major,cycle);	this.Season.set("Ridvan",aDate,bDate,DF,DF,1);
		aDate.set(theYear,19,1,"Bahai",major,cycle); bDate.set(theYear,19,19,"Bahai",major,cycle);	this.Season.set("Fast",aDate,bDate);
		break;
	case "Julian": case "Orthodox":
		this.yeartype = " <a href=\"javascript:alert('Anno Domini - The Year of Our Lord. The Orthodox Churches of Jerusalem, Russia and Serbia still use the Julian calendar, based on the Roman calendar established by Julius Caesar in 45 B.C. Years are reckoned from the Birth of Christ, as determined by a monk in Rome named Dionysius Exiguus in A.D. 525.')\">A.D.</a> ";
		this.Holiday.set(0,6,"The Theophany (Epiphany) of our Lord");
		this.Holiday.set(1,2,"The Presentation of our Lord");
		this.Holiday.set(2,25,"The Annunciation");
		this.Holiday.set(7,8,"The Transfiguration");
		this.Holiday.set(7,15,"The Repose of the Virgin Mary)");
		this.Holiday.set(8,8,"Nativity of the Virgin Mary");
		this.Holiday.set(8,14,"The Elevation of the Life-Giving Cross");
		this.Holiday.set(10,21,"The Presentation of the Virgin Mary in the Temple");
		this.Holiday.set(11,25,"Christmas");
	//	Moveable feasts of the Eastern Church		
		var joEaster = EasterOrthodox(this.myDate.getFullYear()); joEaster.kind = "Julian";
		this.Holiday.setByDate(joEaster,"<a href='http://www.dogchurch.org/scriptorium/res.html'>Pascha (Easter)</a>");
		this.Holiday.setByDate(joEaster.from(-42),"Feast of Orthodoxy");
		this.Holiday.setByDate(joEaster.from(-7),"Palm Sunday");
		this.Holiday.setByDate(joEaster.from(-2),"<a href='http://www.dogchurch.org/scriptorium/cross.html'>Good Friday</a>");
		this.Holiday.setByDate(joEaster.from(39),"Ascension of our Lord");
		this.Holiday.setByDate(joEaster.from(49),"Pentecost");
	//	Liturgical Seasons
		aDate.set(theYear,7,1,"Julian");  bDate.set(theYear,7,14,"Julian");		this.Season.set("Fast of the Repose of the Virgin Mary",aDate,bDate);
		aDate.set(theYear,11,5,"Julian"); bDate.set(theYear,11,24,"Julian");	this.Season.set("Fast of Christmas",aDate,bDate);
		aDate=joEaster.from(-48);		  bDate=joEaster.from(-8);				this.Season.set("Quadragesima (Lent)",aDate,bDate);
		aDate=joEaster.from(57);		  bDate.set(theYear,5,28,"Julian");		this.Season.set("Fast of the Apostles",aDate,bDate);
		break;
	case "Coptic":
		this.Month = ["Thoout","Paope","Athor","Koiak","Tobe","Meshir","Paremotep","Parmoute","Pashons","Paone","Epep","Mesore","Epagomene"];
		this.WeekDay=["Tkyriake","Pesnau","Pshoment","Peftoou","Ptiou","Psoou","Psabbaton"];
		this.yeartype=" <a href=\"javascript:alert('Anno Martyrum - Coptic time is reckoned from the Year of the Martyrs, when Diocletian became Emperor of Rome.')\">A.M.</a> ";
		this.daytype="<a href=\"javascript:alert('Coptic month and day names are derived from a Hellenized/Christianized form of Pharonic Egyptian.')\">*</a>";
		var CopticEaster = EasterOrthodox(this.myDate.getFullYear()); CopticEaster.kind = "Coptic";
		this.Holiday.setByDate(CopticEaster,"Easter");
		this.Holiday.set(0,17,"Building of the Cross");
		this.Holiday.set(3,29,"Christmas");
		this.Holiday.set(4,6,"Jesus's Circumcision");
		this.Holiday.set(4,11,"Epiphany");
		this.Holiday.set(6,29,"Mary's Announcement");
		this.Holiday.set(11,13,"Jesus's Transfiguration"); theYear=this.myDate.getFullYear();
		break;
	case "Lutheran": // Holidays from the Lutheran Book of Worship and http://www.smart.net/~mmontes/ec-cal.html
		this.Holiday.set(0,1,"The Holy Name (Christ's Briss)",W);
		this.Holiday.set(0,2,"Johann Konrad Wilhelm Loehe, pastor, 1872",W);
		this.Holiday.set(0,5,"Kaj Munk, martyr, 1944",R);
		this.Holiday.set(0,6,"The Epiphany of Christ",W);
		this.Holiday.set(0,13,"George Fox, Renewer of Society, 1691",W);
		this.Holiday.set(0,14,"Elvind, Josef Berggrav, Bishop of Oslo, 1959",W)
		this.Holiday.set(0,15,"<a href='http://www.dogchurch.org/scriptorium/king.html'>Martin Luther King, Jr.</a>, Renewer of Society, martyr, 1968",R);
		this.Holiday.set(0,18,"Confession of St. Peter"+nl+"<i>Week of Prayer for Christian Unity begins</i>",W);
		this.Holiday.set(0,19,"Henry, Bishop of Uppsala, missionary to Finland, martyr 1156",R);
		this.Holiday.set(0,25,"Conversion of St. Paul"+nl+"<i>Week of Prayer for Christian Unity Ends</i>",W);
		this.Holiday.set(0,26,"Timothy, Titus and Silas",W);
		this.Holiday.set(0,27,"Lydia, Dorcas and Phoebe",W);
		this.Holiday.setByDate((new Date(theYear,0,6)).from(1,Sun),"Christ's Baptism",W); // 1st Sunday after Epiphany
		this.Holiday.set(1,2,"Candlemas (Presentation of Christ in the Temple)",W);
		this.Holiday.set(1,3,"Angsar, Archbishop of Hamburg,"+nl+" missionary to Denmark & Sweden, 865",W);
		this.Holiday.set(1,5,"The Martyrs of Japan, 1597",R);
		this.Holiday.set(1,14,"Cyril, monk, 869"+nl+"Methodius, bishop, 885"+nl+"missionaries to the Slavs",W)
		this.Holiday.set(1,18,"Martin Luther, Renewer of the Church, 1546",W);
		this.Holiday.set(1,20,"Rasmus Jensen, first Lutheran pastor in North America, 1620",W);
		this.Holiday.set(1,23,"Bartolomaeus Ziegenbalg, missionary to India, 1719",W);
		this.Holiday.set(1,23,"Polycarp, Bishop of Smyrna, martyr, 156",R);
		this.Holiday.set(1,24,"St. Matthias, Apostle",R);
		this.Holiday.set(1,25,"Elizabeth Fedde, deaconess,1921",W);
		this.Holiday.set(2,1,"George Herbert, priest, 1633",W);	
		this.Holiday.set(2,2,"John Wesley, 1791"+nl+"Charles Wesley, 1788"+nl+"Renewers of the Church",W);
		this.Holiday.set(2,7,"Thomas Acquinas, teacher, 1274",W);
		this.Holiday.set(2,7,"Perpetua and her companions, martyrs at Carthage, 202",R);
		this.Holiday.set(2,12,"Gregory the Great, Bishop of Rome, 604",W);
		this.Holiday.set(2,17,"St. Patrick, Bishop and missionary to Ireland, 461",W);
		this.Holiday.set(2,19,"Joseph, husband of Mary",W);
		this.Holiday.set(2,22,"Jonathan Edwards, missionary to the Native Americans, 1758",W);
		this.Holiday.set(2,25,"Annunciation to Mary",W);
		this.Holiday.set(2,29,"Hans Nielsen Hauge, renewer of the Church, 1824",W);
		this.Holiday.set(2,31,"John Donne, poet and priest,1631",W);	
		this.Holiday.set(3,6,"Albrecht Dürer, painter 1528"+nl+"Michelangelo Buonarroti, artist, 1564",W);
		this.Holiday.set(3,9,"Dietrich Bonhoeffer, teacher, martyr, 1945",R);
		this.Holiday.set(3,10,"Mikael Agricola, Bishop of Turku, 1557",W);
		this.Holiday.set(3,19,"Olavus Petri, priest 1552"+nl+"Laurentius Petri, Archbishop of Uppsala, 1573"+nl+"renewers of the Church",W);
		this.Holiday.set(3,21,"Anselm, Archbishop of Canterbury, 1109",W);
		this.Holiday.set(3,23,"Toyohiko Kagawa, renewer of society, 1960",W);
		this.Holiday.set(3,25,"St. Mark, Evangelist",R);
		this.Holiday.set(3,29,"Catherine of Siena, teacher, 1380",W);		
		this.Holiday.set(4,1,"St. Philip and St. James, Apostles",R);
		this.Holiday.set(4,2,"Athanasius, Bishop of Alexandria, 373",W);
		this.Holiday.set(4,4,"Monica, mother of Augustine, 387",W);
		this.Holiday.set(4,18,"Erik, King of Sweden, martyr, 1160",R);
		this.Holiday.set(4,19,"Dunstan, Archbishop of Canturbury, 988",W);
		this.Holiday.set(4,21,"John Eliot, missionary to the Native Americans, 1690",W);
		this.Holiday.set(4,23,"Ludwig Nommensen, missionary to Sumatra, 1918",W);
		this.Holiday.set(4,24,"Nicolaus Copernicus, 1543"+nl+"Leonhard Euler, 1783"+nl+"teachers",W);
		this.Holiday.set(4,27,"John Calvin, Renewer of the Church 1564",W);
		this.Holiday.set(4,29,"Jiri Tranovsky, hymnwriter, 1637",W);
		this.Holiday.set(4,31,"The Visitation of Mary to Elizabeth",W);	
		this.Holiday.set(5,1,"Justin, martyr at Rome, c. 165",R);
		this.Holiday.set(5,3,"John XXIII, Bishop of Rome, 1963",W);
		this.Holiday.set(5,5,"Boniface, Archbishop of Mainz, missionary to Germany, martyr, 754",R);
		this.Holiday.set(5,7,"Seattle, Chief of the Duwamish Confederacy, 1866",W);
		this.Holiday.set(5,9,"Columba, 597; Aidan, 651; Bede, 735"+nl+"confessors",W);
		this.Holiday.set(5,11,"St. Barnabas, Apostle",W);
		this.Holiday.set(5,14,"Basil the Great, Bishop of Caesarea, 379",W);
		this.Holiday.set(5,14,"Gregory of Nazianzus, Bishop of Constantinople, c. 389",W);
		this.Holiday.set(5,14,"Gregory, Bishop of Nyssa, c. 385",W);
		this.Holiday.set(5,21,"Onesimos Nesib, translator, evangelist, 1931",W);
		this.Holiday.set(5,24,"Nativity of St. John the Baptist",W);
		this.Holiday.set(5,25,"Presentation of the Augsburg Confession, 1530",W);
		this.Holiday.set(5,25,"Philip Melancthon, Renewer of the Church, 1560",W);
		this.Holiday.set(5,28,"Irenaeus, Bishop of Lyons, c. 202",W);
		this.Holiday.set(5,29,"St. Peter and St. Paul, Apostles",R);
		this.Holiday.set(5,30,"Johan Olof Wallin, Archbishop of Uppsala, hymnwriter, 1839",W);		
		this.Holiday.set(6,1,"Catherine Winkworth, 1878; Mason Neale, 1866, hymnwriters",W);
		this.Holiday.set(6,6,"Jan Hus, martyr, 1415",R);
		this.Holiday.set(6,11,"Benedict of Nursia, Abbot of Monte Cassino, c. 540",W);
		this.Holiday.set(6,12,"Nathan Soederblom, Archbishop of Uppsala, 1931",W);
		this.Holiday.set(6,15,"Vladimir, first Christian ruler of Russia, 1015",W);
		this.Holiday.set(6,17,"Bartholome de Las Casas, missionary to the West Indies, 1566",W);
		this.Holiday.set(6,22,"St. Mary Magdalene",W);
		this.Holiday.set(6,23,"Birgitta of Sweden, 1373",W);
		this.Holiday.set(6,25,"St. James the Elder, Apostle",R);
		this.Holiday.set(6,28,"Johann Sebastian Bach, 1750"+nl+"Heinrich Schuetz, 1672"+nl+"Georg Friedrich Handel, 1759"+nl+"composers",W);
		this.Holiday.set(6,29,"Olaf, King of Norway, martyr, 1030",R);
		this.Holiday.set(6,29,"Mary, Martha and Lazarus of Bethany",W);		
		this.Holiday.set(7,10,"Lawrence, deacon, martyr, 258",R);
		this.Holiday.set(7,13,"Florence Nightingale, 1910; Clara Maass, 1901"+nl+"renewers of society",W);
		this.Holiday.set(7,15,"Assumption of Mary, Mother of Christ",W);
		this.Holiday.set(7,20,"Bernard, Abbot of Clairvaux, 1153",W);
		this.Holiday.set(7,24,"St. Bartholomew, Apostle",R);
		this.Holiday.set(7,28,"St. Augustine, Bishop of Hippo, 430",W);
		this.Holiday.set(7,31,"John Bunyan, teacher, 1688",W);
		this.Holiday.set(8,2,"Nikolai Frederik Severin Grundtvig, bishop, renewer of the Church, 1872",W);
		this.Holiday.set(8,4,"Albert Schweitzer, missionary to Africa, 1965",W);	
		this.Holiday.set(8,13,"John Chrysotom, Bishop of Constantinople, 407",W);
		this.Holiday.set(8,14,"The Holy Cross",R);
		this.Holiday.set(8,21,"St. Matthew, Apostle and Evangelist",R);
		this.Holiday.set(8,25,"Sergius of Radonezh, Abbot of the Holy Trinity, Moscow, 1392",W);
		this.Holiday.set(8,29,"Mass of St. Michael and all Angels",W);
		this.Holiday.set(8,30,"Jerome, translator, teacher, 420",W);	
		this.Holiday.set(9,4,"St. Francis of Assisi, renewer of the Church, 1226",W);
		this.Holiday.set(9,4,"Teodor Fliedner, renewer of society, 1864",W);
		this.Holiday.set(9,6,"William Tyndale, translator of the Bible into English, martyr, 1536",R);
		this.Holiday.set(9,7,"Henry Melchior Muhlenberg, missionary to America, 1787",W);
		this.Holiday.set(9,17,"Ignatius, Bishop of Antioch, martyr, c. 115",R);
		this.Holiday.set(9,18,"St. Luke, Evangelist",R);
		this.Holiday.set(9,23,"James of Jerusalem, martyr",R);
		this.Holiday.set(9,26,"Philipp Nicolai, 1608; Johann Heermanhn, 1647; Paul Gerhardt, 1676; hymnwriters",W);
		this.Holiday.set(9,28,"St. Simon and St. Jude, Apostles",R);
		this.Holiday.set(9,31,"Reformation Day",R);		
		this.Holiday.set(10,1,"All Saints' Day",W);
		this.Holiday.set(10,2,"All Souls' Day",W);
		this.Holiday.set(10,7,"John Christian Frederick Heyer, missionary to India, 1873",W);
		this.Holiday.set(10,11,"Martin, Bishop of Tours, 397",W);
		this.Holiday.set(10,11,"Soren Aabye Kierkegaard, teacher, 1855",W);
		this.Holiday.set(10,17,"Elizabeth of Thuringia, Princess of Hungary, 1231",W);
		this.Holiday.set(10,23,"Clement, Bishop of Rome, c. 100",W);
		this.Holiday.set(10,25,"Isaac Watts, hymnwriter, 1748",W);
		this.Holiday.set(10,30,"St. Andrew, Apostle",R);
		this.Holiday.setByDate((new Date(theYear,10,20)).from(1,Sun),"Christ the King Sunday",W); // 1st Sunday after Nov. 20 (last Sunday after Pentecost)		
		this.Holiday.set(11,3,"Francis Xavier, missionary to Asia, 1552",W);
		this.Holiday.set(11,6,"Nicholas, Bishop of Myra, c. 342",W);
		this.Holiday.set(11,7,"Ambrose, Bishop of Milan, 397",W);
		this.Holiday.set(11,8,"The Immaculate Conception",W);
		this.Holiday.set(11,11,"Lars Olsen Skefsrud, missionary to India, 1910",W);
		this.Holiday.set(11,12,"Our Lady of Guadalupe",W);
		this.Holiday.set(11,14,"John of the Cross, renewer of the Church, 1591",W)
		this.Holiday.set(11,14,"Teresa of Avila, renewer of the Church, 1582",W);
		this.Holiday.set(11,21,"St. Thomas, Apostle",R);
		this.Holiday.set(11,24,"Christmas Eve",W);
		this.Holiday.set(11,25,"Christmas (Birth of Christ)",W);
		this.Holiday.set(11,26,"St. Stephen, Deacon and martyr",R);
		this.Holiday.set(11,27,"St. John, Apostle and Evangelist",W);
		this.Holiday.set(11,28,"The Holy Innocents, martyrs (Childermas)",R,R);		
	//	Moveable feasts of the Western Church
		var Easter = EasterWestern(theYear);
		this.Holiday.setByDate(Easter,"<a href='http://www.dogchurch.org/scriptorium/res.html'>Easter (Christ's Resurrection)</a>",GO,W);
		this.Holiday.setByDate(Easter.from(-49),"Transfiguration of Christ",W);
		this.Holiday.setByDate(Easter.from(-47),"Shrove Tuesday (Mardi Gras, Fasching)");
		this.Holiday.setByDate(Easter.from(-46),"Ash Wednesday",BK,P);
		this.Holiday.setByDate(Easter.from(-14),"Passion Sunday",S,P);
		this.Holiday.setByDate(Easter.from(-7),"Palm Sunday",S,P);
		this.Holiday.setByDate(Easter.from(-3),"<a href='http://www.dogchurch.org/scriptorium/KillingChrist.htm#parting'>Maundy Thursday (The Last Supper)</a>",S,W);
		this.Holiday.setByDate(Easter.from(-2),"<a href='http://www.dogchurch.org/scriptorium/cross.html'>Good Friday (Christ's Crucifixion)</a>",BK);
		this.Holiday.setByDate(Easter.from(-1),"Vigil of Easter",W);
		this.Holiday.setByDate(Easter.from(35),"Rogation Sunday",W);
		this.Holiday.setByDate(Easter.from(39),"Ascension of Christ",W);
		this.Holiday.setByDate(Easter.from(48),"Vigil of Pentecost",R);
		this.Holiday.setByDate(Easter.from(49),"Pentecost (Whitsunday)",R);
		this.Holiday.setByDate(Easter.from(56),"Holy Trinity Sunday",W);
		this.Holiday.setByDate(Easter.from(60),"Corpus Christi",W);
	//	// Liturgical Seasons of the Western Church from http://www.elca.org/co/faq/chyear.html 
		this.Season.set("Christmas",new Date(theYear-1,11,25),new Date(theYear,0,5),W,W,1,"of ");
		this.Season.set("Epiphany",new Date(theYear,0,6),Easter.from(-47),G,G,7,"after the ");
		this.Season.set("Lent",Easter.from(-46),Easter.from(-7),P,P,7,"in ");
		this.Season.set("Holy Week",Easter.from(-7),Easter.from(-1),S,P,0,"of ");
		this.Season.set("Easter",Easter.from(-1),Easter.from(48),W,W,7,"in ");
		var adventDate=new Date(theYear,10,27); adventDate=adventDate.from(1,Sun); // 1st Sunday after Nov. 27
		this.Season.set("Pentecost",Easter.from(49),adventDate.from(-1),G,G,7,"after ");
		this.Season.set("Advent",adventDate,new Date(theYear,11,24),B,P,7,"in ");
		this.Season.set("Christmas",new Date(theYear,11,25),new Date(theYear+1,0,5),W,W,1,"of ");
		this.Season.set("Ordinary Time",new Date(theYear,0,1),new Date(theYear,11,31),G,G,0,"in ");
		break;		
	default: // Western Semi-Secular
		this.Holiday.set(0,1,"<a href='"+burl+"scriptorium/icecrystals.html'>New Year's Day</a>");
		this.Holiday.set(0,5,"Twelfth Night");
		if(theYear%4==1 && theYear>1936) this.Holiday.set(0,20,"Inauguration Day (US)");
		this.Holiday.set(0,27,"Liberation of Auschwitz, 1945");
		this.Holiday.setByDate((new Date(theYear,0,1)).from(3,Mon),"<a href='"+burl+"scriptorium/king.html'>Martin Luther King, Jr.'s</a> Birthday (observed)");  // 3rd Monday in January
		this.Holiday.set(1,2,"Ground Hog Day");
		this.Holiday.set(1,12,"Abraham Lincoln's Birthday");
		this.Holiday.set(1,14,"St. Valentine's Day");
		this.Holiday.set(1,19,"Internment of Japanese Americans, WWII");
		this.Holiday.set(1,22,"George Washington's Birthday");
		if(GregorianLeapYear(theYear)) this.Holiday.set(1,24,"Leap Day");
		this.Holiday.setByDate((new Date(theYear,1,1)).from(3,Mon),"President's Day"); // 3rd Monday in February
		this.Holiday.set(2,17,"St. Patrick, Bishop and missionary to Ireland, 461",W);
		this.Holiday.set(2,17,"<a href='http://www.lambda.net/~maximum/rustin.html' target='win2'>Bayard Rustin</a>, Renewer of Society, 1912",W);
		this.Holiday.set(2,20,"Vernal Equinox");
		this.Holiday.setByDate((new Date(theYear,2,1)).from(2,Sun),"Daylight Saving Time Begins"); // 2nd Sunday in March, 2005 Fed Eng Policy Act
		this.Holiday.set(3,1,"VCBC's Day of Amazement that Anything Exists");
		this.Holiday.set(3,1,"April Fool's Day");
		var aDate=new Date(theYear,3,15); var taxday=aDate.getDay(); if(taxday==Sat||taxday==Sun) aDate=aDate.from(1,Tue);
		this.Holiday.setByDate(aDate,"Tax Day (US)"); // Apr 15 on a weekday, 1st Tue after if not
		this.Holiday.set(3,22,"Earth Day"); aDate=new Date(theYear,3,30); bDate=aDate.from(-1,Sat); // last Saturday in April
		this.Holiday.setByDate(bDate.from(-3),"Administrative Professional's Day"); // Wednesday before the last Saturday in April
		this.Holiday.setByDate(aDate.from(-1,Fri),"Arbor Day"); // last Friday in April
		this.Holiday.set(4,5,"El Cinco de Mayo");
		this.Holiday.set(4,8,"German Surrender Ends WWII in Europe, 1945");
		this.Holiday.set(4,14,"Israel Independence Day (Gregorian Calendar)");
		this.Holiday.set(4,19,"Malcolm X, renewer of society, <i>shahid</i> (martyr)");
		this.Holiday.set(4,30,"Memorial Day (traditional)"); aDate = new Date(theYear,4,1); // May 1
		this.Holiday.setByDate(aDate.from(1,Thu),"<a href='http://www.nationaldayofprayer.org/' target='win2'>National Day of Prayer (US)</a>"); // 1st Thu in May (not May 5?)
		this.Holiday.setByDate(aDate.from(2,Sun),"Mother's Day"); // 2nd Sunday in May
		this.Holiday.setByDate(aDate.from(3,Sat),"Armed Forces Day"); // 3rd Saturday in May
		this.Holiday.setByDate((new Date(theYear,4,31)).from(-1,1),"Memorial Day (observed)"); // last Monday in May
		this.Holiday.set(5,6,"D-Day Invasion of Europe, 1944");		
		this.Holiday.set(5,14,"Flag Day (US)");		
		this.Holiday.set(5,19,"Juneteenth (Emancipation Day, Texas)");
		this.Holiday.set(5,21,"Summer Solstice");
		this.Holiday.set(5,27,"The Stonewall Rebellion, 1969"); aDate=new Date(theYear,5,1);
		this.Holiday.setByDate(aDate.from(3,Sun),"Father's Day"); // 3rd Sunday in June
		this.Holiday.set(6,4,"American Independence Day");
		this.Holiday.set(6,4,"<a href='"+burl+"chapel/pulpit/sermon.html'>VCBC debuts, 1996</a>");
		this.Holiday.set(6,14,"Bastille Day (FR)");
		this.Holiday.set(6,16,"Trinity Event, first human-initiated nuclear explosion, 1945");
		this.Holiday.set(6,24,"Pioneer Day(LDS)");
		this.Holiday.setByDate((new Date(theYear,6,1)).from(4,Sun),"Parent's Day"); // 4th Sunday in July
		this.Holiday.set(7,6,"US Atomic Bombing of <a href='http://dogchurch.blogspot.com/2005/08/hiroshima-remembered.html'>Hiroshima</a>, 1945");
		this.Holiday.set(7,9,"US Atomic Bombing of Nagasaki, 1945)");
		this.Holiday.set(7,10,"Destruction of the Second Temple (Gregorian Calendar) A.D. 70");
		this.Holiday.set(7,15,"Japanese Surrender Ends WWII, 1945");
		this.Holiday.set(7,20,"Muhammad's (pbuh) Birthday (Gregorian)"); aDate=(new Date(theYear,8,1)).from(1,Mon); // 1st Monday in September
		this.Holiday.setByDate(aDate,"Labor Day");
		this.Holiday.setByDate(aDate.from(6),"Grandparent's Day"); // 1st Sunday after Labor Day
		this.Holiday.set(8,11,"<a href='http://www.dogchurch.org/scriptorium/wtc1.html'>Al-Qaeda attacks the World Trade Center and the Pentagon, 2001</a>");
		this.Holiday.set(8,23,"Autumnal Equinox");
		this.Holiday.set(9,12,"Columbus Day (traditional)");
		this.Holiday.set(9,24,"United Nations Day");
		this.Holiday.set(9,31,"Halloween, Dia de los Muertes");
		this.Holiday.setByDate((new Date(theYear,9,1)).from(2,Mon),"Columbus Day (observed)"); // 2nd Monday in October
		this.Holiday.set(10,5,"Guy Fawkes Day (UK)");
		this.Holiday.setByDate((new Date(theYear,10,2)).from(1,Tue),"Election Day (US)"); // 1st Tuesday on or after Nov 2
		this.Holiday.set(10,11,"Veteran's Day"); aDate=new Date(theYear,10,1);
		this.Holiday.setByDate(aDate.from(1,Sun),"Daylight Savings Time Ends"); // First Sunday in November
		this.Holiday.setByDate(aDate.from(4,Thu),"<a href='http://www.dogchurch.org/narthex/aovertheriver.html'>Thanksgiving Day (US)</a>"); // 4th Thursday in November
		this.Holiday.set(11,7,"Japan bombs Pearl Harbor, 1941");
		this.Holiday.set(11,8,"Buddha's Enlightenment (Japan)");
		this.Holiday.set(11,22,"Winter Solstice");
		this.Holiday.set(11,24,"Christmas Eve",W);
		this.Holiday.set(11,25,"Christmas (Birth of Christ)",W);
		this.Holiday.set(11,26,"Kwanzaa Begins");
		this.Holiday.set(11,26,"Boxing Day (Canada)");
		this.Holiday.set(11,31,"<a href='http://www.dogchurch.org/narthex/auldlangsyne.html'>New Year's Eve</a>"); var gYear=this.myDate.getFullYear();
		var Easter = EasterWestern(gYear); var oEaster = EasterOrthodox(gYear); oEaster.kind="Gregorian";
		this.Holiday.setByDate(oEaster,"<a href='http://www.dogchurch.org/scriptorium/res.html'>Easter (Orthodox)</a>",W,GO);
		this.Holiday.setByDate(Easter,"<a href='http://www.dogchurch.org/scriptorium/res.html'>Easter (Christ's Resurrection)</a>",W,GO);
		this.Holiday.setByDate(Easter.from(-3),"<a href='http://www.dogchurch.org/scriptorium/KillingChrist.htm#parting'>Maundy Thursday (The Last Supper)</a>",S,W);
		this.Holiday.setByDate(Easter.from(-2),"<a href='http://www.dogchurch.org/scriptorium/cross.html'>Good Friday (Christ's Crucifixion)</a>",BK);
		this.Holiday.setByDate(Easter.from(1),"Easter Monday");
	//	Seasons
		var snames; if(this.myLoc.latitude>=0) snames=["Winter","Spring","Summer","Autumn","Winter"]; else snames=["Summer","Autumn","Winter","Spring","Summer"];
		this.Season.set(snames[0],new Date(theYear-1,11,22),new Date(theYear,2,19),W,W);
		this.Season.set(snames[1],new Date(theYear,2,20),new Date(theYear,5,20),W,W);
		this.Season.set(snames[2],new Date(theYear,5,21),new Date(theYear,8,22),W,W);
		this.Season.set(snames[3],new Date(theYear,8,23),new Date(theYear,11,21),W,W);
		this.Season.set(snames[4],new Date(theYear,11,22),new Date(theYear+1,2,20),W,W);
		this.Season.set("<a href='http://www.dogchurch.org/chapel/pulpit/easter.html'>Happy Easter!</a>",Easter,Easter.from(7));
		this.Season.set("Merry Christmas from <a href='http://www.dogchurch.org/chapel/pulpit/xmas.html'>us</a> and our <a href='"+burl+"restroom/lawyerxmas.html'>lawyers</a>!",new Date(theYear,11,1),new Date(theYear,11,31));
	}
}
Calendar.prototype.getSeason	=	function(qDate){ return this.Season.get(qDate,this.myLoc); }
Calendar.prototype.getDayName	=	function(aDate){ return this.WeekDay[aDate.get("day")]; }
Calendar.prototype.getDateName	=	function(aDate){ var b=aDate.get("date"),a=this.dateName[b]; return a?a:b.toString();}
Calendar.prototype.getMonthName	=	function(aDate){ return " "+this.Month[aDate.get("month")]; }
Calendar.prototype.getYearName	=	function(aDate){ var b=aDate.get("year"),a=this.yearName[b]; return a?a:b.toString();}
Calendar.prototype.getCycleName =	function(aDate){ return this.cycleName?" of "+this.cycleName+" "+aDate.get("cycle").toString():"";}
Calendar.prototype.getMajorName =	function(aDate){ return this.majorName?nl+this.majorName+" "+aDate.get("major").toString():"";}
Calendar.prototype.getEvents	=	function(aDate){ return this.Holiday.get(aDate); }
Calendar.prototype.getMessages	=	function(aDate,aType){ // gets text (default) or colored divs
	var mray = this.getEvents(aDate); var msg=""; var myType=aType||"text";
	if(mray){if(myType == "text"){for(var i=0,j=mray.length; i<j; i++){ msg+=mray[i].msg; if((j-i)>1) msg+=nl; }}
			else {for(var i=0;i<mray.length;i++){ var textcolor=(mray[i].bgcolor == W)?BK:W;
				msg+="<div style='border:2px "+mray[i].bdrcolor+";background-color:"+mray[i].bgcolor+";color:"+textcolor+";'>"+mray[i].msg+"</div>";}}
	}return msg;
}
function EasterWestern(gYear){ // CC version
	var century=Math.floor(gYear/100)+1; var paschalMoon=new Date(gYear,3,19); var year19=gYear%19; 
	var shiftedEpact=(14+11*year19-Math.floor(0.75*century)+Math.floor((5+8*century)/25))%30;
	if(shiftedEpact==0||(shiftedEpact==1 && 10<year19)) shiftedEpact++; paschalMoon=paschalMoon.from(-shiftedEpact);
	return paschalMoon.from(1,Sun);
}
function EasterOrthodox(gYear){ // CC version
	var jYear=(gYear>0)?gYear:gYear-1; var paschalMoon=new Date(); paschalMoon.set(jYear,3,19,"Julian");
	var shiftedEpact=(14+11*(gYear%19))%30; paschalMoon=paschalMoon.from(-shiftedEpact);
	return paschalMoon.from(1,Sun);
}
//********************************************************************Clock Object, properties and methods
function liturgicalTime(name,start,stop,comment){ // start, stop in minutes from midnight=0
	this.start=clockMod(start,1440); this.stop=clockMod(stop,1440); this.msg="<a href=\"javascript:alert('"+comment+"')\">"+name+"</a>"; }
function liturgicalTimeList(){} liturgicalTimeList.prototype = new Array();
liturgicalTimeList.prototype.set = function(name,start,stop,comment){var p=this.push(new liturgicalTime(name,start,stop,comment));}
liturgicalTimeList.prototype.get = function(qDate){ var tod=qDate.getTimeOfDay(); // gets interval in which a time lies
	for(var i=0;i<this.length;i++){  var start=this[i].start, stop=this[i].stop;
		if((start<=tod)&&(tod<stop)) return(this[i].msg);						// regular interval
		if((start>stop)&&((start<=tod)||(tod<stop))) return(this[i].msg); 		// interval straddles midnight
	} return false;
}
liturgicalTimeList.prototype.getAll=function(aDate,display){ var msg,hrs,mins,tt,zph,zpm; // displays starttimes of all intervals for a day
	msg=nl+"<div align='center'><table>"
	for(var i=0;i<this.length;i++){ mins=this[i].start; hrs=IntDiv(mins,60); mins=Math.floor(mins-hrs*60);
		if(display<24){ zph=""; tt=(hrs<12)?" a.m.":" p.m."; hrs=clockMod(hrs,12); if(hrs==0)hrs=12; zph=(hrs<10)?"&nbsp;":"";}
		else{ zph=(hrs<10)?"0":""; tt=""; }  zpm=(mins<10)?"0":"";
		if(this[i].start!=this[i].stop)msg+="<tr><td align='right'>"+zph+hrs.toString()+":"+zpm+mins.toString()+tt+" </td><td align='left'>"+this[i].msg+"</td></tr>";
	} return msg+"</table></div>";
}
function Clock(inDate,inKind,inLocale) { // sets for a day
	this.myDate=inDate||new Date(); this.kind=inKind||this.myDate.kind; this.myLocale=inLocale||dateLocale; this.Times=new liturgicalTimeList();
	var tray = getSolarTimes(this.myDate,this.myLocale); var sunrise=tray[0], noon=tray[1], sunset=tray[2], decl=tray[3];
	switch(this.kind){
	case "Hebrew": // Liturgical Times adapted from chabad.org
		var dawn = noon-calcHourAngle(16,decl,this.myLocale); var dusk = noon+calcHourAngle(4.66,decl,this.myLocale);
		var earliest_tefillah = noon-calcHourAngle(11,decl,this.myLocale); var nightfall = noon+calcHourAngle(7.083,decl,this.myLocale);
		var midnight = getSolarMidnight(this.myDate,this.myLocale); var shabbat_end=calcHourAngle(8,decl,this.myLocale); 
		var jhour = (sunset-sunrise)/12; var theDay=this.myDate.getDay(); var candle=(theDay==Fri)?0.3*jhour:0; var shabbat_plus=(theDay==Sat)?0.3*jhour:0;
		this.Times.set("Alot Hashachar",dawn,earliest_tefillah,"Dawn, time to recite the Shema");
		this.Times.set("Earliest Tefillah",earliest_tefillah,sunrise,"Morning Prayer");
		this.Times.set("Netz Hachamah",sunrise,sunrise+3*jhour,"Morning");
		this.Times.set("Latest Shema",sunrise+3*jhour,sunrise+4*jhour,"Latest time to recite the Shema");
		this.Times.set("Latest Tefillah",sunrise+4*jhour,noon,"Latest time for Morning Prayer");
		this.Times.set("Chatzot",noon,noon+0.5*jhour,"Mid-day");
		this.Times.set("Minchah Gedolah",noon+0.5*jhour,noon+3.5*jhour,"Earliest Afternoon Prayer");
		this.Times.set("Minchah Ketanah",noon+3.5*jhour,sunset-1.25*jhour,"Latest Afternoon Prayer");
		this.Times.set("Plag Haminchah",sunset-1.25*jhour,sunset-candle,"Maariv (evening) Service");
		this.Times.set("Candle Lighting",sunset-candle,sunset,"Traditionally done by the leading woman of the household");
		this.Times.set("Shkiah",sunset,dusk,"Sunset");	
		this.Times.set("Tzeit Hakochovim",nightfall,shabbat_end,"Nightfall");
		this.Times.set("Shabbat Ends",shabbat_end,(shabbat_end+shabbat_plus),"The Sabbath ends slightly after nightfall");
		this.Times.set("Chatzot",midnight,midnight+10,"Midnight");
		break;
	case "Islamic": // Liturgical Times from islamicfinder.org
		var fia=fajrisha(this.myLocale); var midnight = getSolarMidnight(this.myDate,this.myLocale);
		var dawn=noon-calcHourAngle(fia[0],decl,this.myLocale), dusk=noon+calcHourAngle(fia[1],decl,this.myLocale);
		var ta = Math.tan(Math.PI/2-(this.myLocale.lat-decl)); var ha1 = -radToDeg(Math.atan(ta/(ta+1))), ha2 = -radToDeg(Math.atan(ta/(2*ta+1))); //CC,202+errata+sign error
		var asr1 = noon+calcHourAngle(ha1,decl,this.myLocale), asr2 = noon+calcHourAngle(ha2,decl,this.myLocale); 
		this.Times.set("Fajr",dawn,sunrise,"Dawn Prayer");
		this.Times.set("Shurooq",sunrise,sunrise+10,"Sunrise, Fajr ends");
		this.Times.set("Dhur",noon,asr1,"Mid-Day Prayer");
		this.Times.set("Asr",asr1,asr2,"Afternoon Prayer, standard (Imamas Shafii, Hanbali & Maliki) method.");
		this.Times.set("Asr (Hanafi)",asr2,sunset,"Afternoon Prayer, Hanafi method.");
		this.Times.set("Maghrib",sunset,dusk,"Sunset Prayer");
		this.Times.set("Isha",dusk,midnight,"Nightfall Prayer");
		break;
	case "Bahai": // Liturgical times from bahai-library.com/encyclopedia/prayer.html
		var DawnDuskAngle = calcHourAngle(18,decl,this.myLocale); var dawn=noon-DawnDuskAngle, dusk=noon+DawnDuskAngle;
		this.Times.set("Morning",dawn,noon,"Medium-length individual prayer, anytime from dawn to noon.");
		this.Times.set("Afternoon",noon,sunset,"Brief individual prayer, anytime from noon to sunset.");
		this.Times.set("Evening",sunset,sunset+120,"Brief individual prayer, anytime from sunset to 2 hours after sunset.");
		break;
	case "Christian": case "Lutheran": case "Julian": case "Coptic": case "Orthodox": // Liturgical Times
		var DawnDuskAngle = calcHourAngle(6,decl,this.myLocale); var dawn=noon-DawnDuskAngle, dusk=noon+DawnDuskAngle;
		this.Times.set("Lauds",dawn,sunrise,"Dawn Prayer");
		this.Times.set("Prime",sunrise,sunrise+60,"Sunrise Prayer, now superceded by Readings, which may be performed anytime");
		this.Times.set("Terce",540,600,"Mid-Morning Prayer");
		this.Times.set("Sext",720,780,"Noon Prayer");
		this.Times.set("None",900,960,"Afternoon Prayer");
		this.Times.set("Vespers",sunset,dusk,"Sunset Prayer");
		this.Times.set("Compline",dusk,dusk+60,"Nightfall Prayer");
		this.Times.set("Matins",0,60,"Midnight Prayer, also called Vigils, now superceded by Readings, which may be performed anytime");
		this.Times.set("Readings",0,1439,"Replacing both Matins and Prime, the Office of the Readings may now be performed at anytime, day or night");
		break;
	default: // Secular Times
		var DawnDuskAngle = calcHourAngle(6,decl,this.myLocale); var dawn=noon-DawnDuskAngle, dusk=noon+DawnDuskAngle;
		var secmsg = "For Christian liturgical hours, please visit our Chapel"; 
		this.Times.set("Greetings in the<br />wee, small hours.",0,dawn,secmsg);
		this.Times.set("Good <i>early</i> Morning.",dawn,sunrise,secmsg);
		this.Times.set("Good Morning.",sunrise,720,secmsg);
		this.Times.set("Good Afternoon.",720,sunset,secmsg);
		this.Times.set("Good late Afternoon.",sunset,dusk,secmsg);
		this.Times.set("Good Evening.",dusk,1439,secmsg);
	}
}
Clock.prototype.getTimes = function(aDate){ return this.Times.get(aDate); }
Clock.prototype.getAll = function(aDate,display) { return this.Times.getAll(aDate,display); }
function fajrisha(aLocale){ var w=aLocale||dateLocale, c=w.cc, la=w.latitude, lo=w.longitude; //[fajr,isha] solar depression angles in degrees
	if(c=="US"||c=="CA"||c=="UK") return [15,15]; // Islamic Society of North America (N. America & UK)
	if(c=="SA"||c=="YE"||c=="OM"||c=="QA"||c=="BH"||c=="AE"||c=="KW") return [19,19]; // Umm al-Qura Committee (Arabian Peninsula)
	if(c=="IZ"||c=="SY"||c=="LB"||c=="MY"||c=="MA"||c=="DZ"||c=="TN"||c=="LY"||c=="EG") return [19.5,17.5]; //Egyptian General Authority of Survey
	if(30>la && la>-40 && 53>lo && lo>-20) return [19.5,17.5]; //EGAoS - Africa
	if(c=="PK"||c=="BD"||c=="IN"||c=="AF") return [18,18]; // University of Islamic Sciences, Karachi
	if(lo>-22) return [18,17]; //Muslim World League (Europe and Far East)
	return [18,18];
}
//*********************************************************************************** Salutations
function LiturgicalSalutation(inKind,doTime,inDate,inLocale){ // Liturgical colors, no season overlap
	var aDate=new Date(); if(inDate) aDate.setTime(inDate.getTime()); var doIt=doTime||0, mt=false; var sp=" "; var msg=new String("<div>");
	if(inKind=="Lutheran") aDate.kind="Gregorian"; else aDate.kind=inKind; var theCalendar = new Calendar(aDate,inKind); dateLocale=inLocale||myLocale; 
	if(doIt>0){var theClock=new Clock(aDate,inKind); if(doIt==1) mt=theClock.getTimes(aDate); else if(doIt>1) mt=theClock.getAll(aDate,12);} if(mt) msg+=mt+nl;
	var theSeasons=theCalendar.getSeason(aDate); var theDayName=theCalendar.getDayName(aDate)+theCalendar.daytype;
	var cmsg = theCalendar.getMessages(aDate,"colors"); var smsg="";
	if(theSeasons) for(var i=0;i<1;i++){ var theSname=nl+theSeasons[i].prefix+theSeasons[i].name; // only one liturgical season
		if(cmsg.indexOf(theSeasons[i].name)>-1) smsg+=theDayName;
		else if(theSeasons[i].ord==1) smsg+=theDayName+nl+theSeasons[i].nth+" day"+theSname;
		else if(theSeasons[i].ord==0) smsg+=theDayName+theSname;
		else smsg+=theSeasons[i].nth+sp+theDayName+theSname;
		var textcolor = (theSeasons[i].bgcolor==W)?BK:W; var linkcolor = "gray"; //a:link {color:"+linkcolor+";}
		smsg="<div style='text-align:center; border:5px "+theSeasons[i].bdrcolor+";background-color:"+theSeasons[i].bgcolor+";color:"+textcolor+";'>"+smsg+"</div>";
	} if(smsg != "") msg+=smsg; else msg+=theDayName+nl; if(cmsg != "") msg+=cmsg;
	msg+=theCalendar.getDateName(aDate)+theCalendar.getMonthName(aDate);
	if(aDate.kind != "Bahai") msg += theCalendar.yeartype+theCalendar.getYearName(aDate);
	else msg += nl+theCalendar.getYearName(aDate)+theCalendar.getCycleName(aDate)+theCalendar.getMajorName(aDate)+theCalendar.yeartype;
	return msg+qibla(aDate.kind)+"</div>";
}
function Salutation(kind,doTime,inDate,inLocale){ // Season overlap, no liturgical colors
	var aDate = inDate || new Date(); aDate.kind=kind||"Gregorian"; var msg=new String(); var doIt=doTime||1; dateLocale=inLocale||myLocale;
	var theCalendar = new Calendar(aDate); var theSeasons = theCalendar.getSeason(aDate); var theClock = new Clock(aDate); var mt=false;
	if(doIt>1) mt=theClock.getAll(aDate,12); else if(doIt==1) mt=theClock.getTimes(aDate); if(mt) msg+=mt+nl;
	msg += theCalendar.getDayName(aDate)+theCalendar.daytype+nl+theCalendar.getDateName(aDate)+theCalendar.getMonthName(aDate);
	if(aDate.kind != "Bahai") msg += theCalendar.yeartype+theCalendar.getYearName(aDate);
	else msg += nl+theCalendar.getYearName(aDate)+theCalendar.getCycleName(aDate)+theCalendar.getMajorName(aDate)+theCalendar.yeartype;
	var msgs = theCalendar.getMessages(aDate); if(msgs) msg += nl+msgs;
	if(theSeasons){for(var i=0;i<theSeasons.length;i++){msg+=nl+"<i>"+theSeasons[i].name+"</i>"; if(theSeasons[i].ord==1) msg+=": <i>"+theSeasons[i].nth+" day</i>";}}
	return msg+qibla(aDate.kind);
}
function CountDown(aDate){ var bDate=aDate||new Date(); var ffdate=fixFmDate(bDate);
	var mayan=Math.round(longCountFmFix(ffdate,"countdown")), hindu=Math.round(hindu_countdown(ffdate));
	return "Days to Apocalypse:"+nl+mayan.toString()+nl+"Mayan Long Count"+nl+hindu.toString()+nl+"Hindu Kali Yuga Era";
}
function ABCalWidget(aform){ // Dynamic selectable calendar
	var rd, inDate=new Date(), greeting, inKind="Gregorian", inLocale=myLocale;
	try{ 
		rd = aform.daDate.value.valueOf(); 
		if (rd){ var dd=new Date(); var r=rd.split("/"); // mm/dd/yyyy
			if(0<r[0] && r[0]<13) inDate=new Date(r[2],(r[0]-1),r[1],dd.getHours(),dd.getMinutes());
		}
	} catch(e) {}
	try {inKind=aform.daKind.value.valueOf();} catch(e){}
	switch(inKind){
		case "Gregorian": greeting=Salutation(inKind,0,inDate,inLocale); break;
		case "Countdown": greeting=CountDown(inDate); break;
		case "Lutheran": case "Coptic": case "Orthodox": greeting=LiturgicalSalutation(inKind,2,inDate,inLocale); break;
		default: greeting=Salutation(inKind,2,inDate,inLocale);
	}
	greeting="<div id='calendar' class='"+inKind.toLowerCase()+"'>"+greeting+"</div>";
	var obj = document.getElementById("ABCalendar");
	obj.innerHTML = greeting; // document.calTest.result.value=greeting;
}