var userAgent = window.navigator.userAgent;
var browserVers = parseInt(userAgent.charAt(userAgent.indexOf("/")+1),10);
var copyright_alert = 'Images on this website are Copyright protected.\nPlease don\'t make illegal copies.';
function getObjectId (objName) {
	var obj
	if (document.all) obj = document.all(objName)
	else if (document.getElementById) obj = document.getElementById(objName)
	else if (document.layers) obj = document.layers[objName]
	return (obj) ? obj : null
}
function setNodeStr (fld, str) {
	var elem
	if(elem=getObjectId(fld)) {
		(elem.childNodes.length) ?
			elem.childNodes[0].nodeValue = str :
			elem.appendChild(document.createTextNode(str))
	}
	return
}
function setNodeHTML (fld, html) {
	var elem
	if(elem=getObjectId(fld)) {
		elem.innerHTML = html
	}
	return
}
function lTrim (val) {
	var str = val.toString()
	for (var i=0; i<str.length && (str.charAt(i)==' '||str.charAt(i)=="\t"); i++) {}
	return (str.substring(i, str.length))
}
function reverseStr (val) {
	var str = val.toString()
	var result = ''
	for (var e=str.length-1; e>=0; e--) result += str.charAt(e)
	return result;
}
function rTrim (val) {
	return reverseStr(lTrim(reverseStr(val)))
}
function trimStr (val) {
	return lTrim(rTrim(val))
}
function urlEncode (url) {
	var ch, i, nurl = '', fndStr =" #{}|^~[]`\\"
	var rplArr = new Array("%20","%23","%7B","%7D", "%7C","%5E","%7E","%5B","%5D","%60","%5C")
	for (var x=0; x<url.length; x++) {
		ch = url.charAt(x)
		nurl += ((i=fndStr.indexOf(ch,0))==-1) ? ch : rplArr[i]
	}
	return nurl
}
function flash () {
	var obj
	if(flashArr && flashArr.length)
		for (var i=0; i<flashArr.length; i++)
			if(obj=getObjectId(flashArr[i])) {
				obj.style.visibility = (obj.style.visibility=='hidden')?'visible':'hidden'
			}
	return
}
function rotateStyle () {
	var obj
	if(idArr && idArr.length && styleArr && styleArr.length)
		for (var i=0; i<idArr.length; i++)
			if(obj=getObjectId(idArr[i]))
				for(var j=0; j<styleArr.length; j++)
					if(obj.className==styleArr[j])
					{	obj.className = styleArr[(((j+1)==styleArr.length)?0:j+1)]; break; }
	return
}
function format (expr, decplaces) {
	var str = "" + Math.round(eval(expr) * Math.pow(10,decplaces))
	while(str.length <= decplaces) str = "0" + str
	var decpoint = str.length - decplaces
	return str.substring(0,decpoint) + '.' + str.substring(decpoint,str.length)
}
function newImage(arg) {
	if (document.images) {
		rslt = new Image();
		rslt.src = arg;
		return rslt;
	}
}
mustInitImg = true;
function initImgID() {
	var di = document.images;
	if (mustInitImg && di) {
		for (var i=0; i<di.length; i++) { if (!di[i].id) di[i].id=di[i].name; }
		mustInitImg = false;
	}
}
function findElement(n,ly) {
	var d = document;
	if (browserVers < 4)	return d[n];
	if ((browserVers >= 6) && (d.getElementById)) {
		initImgID; return(d.getElementById(n))
	} 
	var cd = ly ? ly.document : d;
	var elem = cd[n];
	if (!elem) {
		for (var i=0;i<cd.layers.length;i++) {
			elem = findElement(n,cd.layers[i]);
			if (elem) return elem;
		}
	}
	return elem;
}
function changeImagesArray(array) {
	if (preloadFlag == true) {
		var d = document; var img;
		for (i=0;i<array.length;i+=2) {
			img = null; var n = array[i];
			if (d.images) {
				if (d.layers) {img = findElement(n,0);}
				else {img = d.images[n];}
			}
			if (!img && d.getElementById) {img = d.getElementById(n);}
			if (!img && d.getElementsByName) {
				var elms = d.getElementsByName(n);
				if (elms) {
					for (j=0;j<elms.length;j++) {
						if (elms[j].src) {img = elms[j]; break;}
					}
				}
			}
			if (img) {img.src = array[i+1];}
		}
	}
}
function changeImages() {
	changeImagesArray(changeImages.arguments);
}
function changeButton(button, btnName, imagePath) {
	button.src = (typeof gfxArr == 'undefined' || typeof gfxArr[btnName] == 'undefined') ? imagePath : gfxArr[btnName].src
	return
}
function makeArrayImplicit () {
	var Count
	this.length = makeArrayImplicit.arguments.length
	for (Count=1; Count<makeArrayImplicit.arguments.length+1; Count++)
		this[Count] = makeArrayImplicit.arguments[Count-1]
	return (this)
}
function addItem (form, itemType) {
	var hdnFld = (arguments.length==3) ? arguments[2] : 'new_item'
	var s = false, fld = form.elements[hdnFld]
	if(form && fld && (fld.type=='hidden' || fld.type=='text')) {
		var name = prompt('Enter name of new '+itemType+':',"")
		if(name!=null && name.length) {
			fld.value = name
			form.submit()
			s = true
		}
	} else {
		alert('Missing or invalid new item field')
	}
	return s
}

function monthAbbr2Int (Month) {
	var iMonth;
	Month = Month.toLowerCase().substr(0,3)
	if (Month == "jan") { iMonth = 1} else  
	if (Month == "feb") { iMonth = 2} else
	if (Month == "mar") { iMonth = 3} else 
	if (Month == "apr") { iMonth = 4} else 
	if (Month == "may") { iMonth = 5} else 
	if (Month == "jun") { iMonth = 6} else  
	if (Month == "jul") { iMonth = 7} else 
	if (Month == "aug") { iMonth = 8} else 
	if (Month == "sep") { iMonth = 9} else 
	if (Month == "oct") { iMonth = 10} else 
	if (Month == "nov") { iMonth = 11} else 
	if (Month == "dec") { iMonth = 12}
	return (iMonth);
}
function getDaysofYear (Year) {
	Leap = (leapYear(Year)==1) ? 29 : 28
	daysOfYear = new makeArrayImplicit(31, Leap, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
	return daysOfYear
}
function leapYear (Year) {
	return (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) ? 1 : 0
}
function setDayNumArray (Form, Prefix) {
	var field = Prefix + 'Yr';
	if(Form.elements[field].selectedIndex==0) {
		var now = new Date(); var year = now.getFullYear()
		for(var count=1; count<Form.elements[field].length; count++) {
			if(Form.elements[field].options[count].text==year) {
				Form.elements[field].selectedIndex = count; break
			}
		}
	} else
		var year = Form.elements[field].options[Form.elements[field].selectedIndex].text
	var dayCnt = getDaysofYear(year)
	field = Prefix + 'Mon'
	var month = (Form.elements[field].selectedIndex==0) ? 1 : Form.elements[field].selectedIndex
	field = Prefix + 'Day'
	var selectedDay = Form.elements[field].selectedIndex
	Form.elements[field].options.length = dayCnt[month]+1
	for(var count=1; count<=dayCnt[month]; count++)
		Form.elements[field].options[count].text = count
	if(selectedDay > dayCnt[month])
		Form.elements[field].selectedIndex = dayCnt[month]
	var obj = getObjectId(Prefix)
	if(obj) obj.style.display = (selectedDay>0 || year>0) ? '' : 'none'
	return
}
function setDayNumber (Form, Prefix) {
	var field = Prefix + 'Yr';
	var year = Form.elements[field].options[Form.elements[field].selectedIndex].text
	var dayCnt = getDaysofYear(year)
	field = Prefix + 'Mon'
	var month = Form.elements[field].selectedIndex+1
	field = Prefix + 'Day'
	var selectedDay = Form.elements[field].selectedIndex+1
	Form.elements[field].options.length = dayCnt[month]
	for(var count=1; count<=dayCnt[month]; count++) {
		Form.elements[field].options[count-1].text = count
		Form.elements[field].options[count-1].value = (count<10) ? '0'+count : count
	}
	if(selectedDay > dayCnt[month])
		Form.elements[field].selectedIndex = dayCnt[month]
	return
}
function enableDate (chkbx, prefix) {
	var obj
	if(obj=getObjectId(prefix+'_div'))
		obj.style.display = (chkbx.checked) ? '' : 'none'
	else {
		var flds = new Array(prefix+'Day',prefix+'Mon',prefix+'Yr')
		for(var cnt=0; cnt<flds.length; cnt++)
			if(obj=chkbx.form.elements[flds[cnt]]) obj.style.display = (chkbx.checked) ? '' : 'none'
	}
	if(!chkbx.checked && (fld=chkbx.form.elements[prefix])) fld.value = '0000-00-00'
	else setDatetime(chkbx.form, prefix, 0)
	return
}
function enableDatetime (chkbx, prefix) {
	var obj
	if(obj=getObjectId(prefix+'_div'))
		obj.style.display = (chkbx.checked) ? '' : 'none'
	else {
		var flds = new Array(prefix+'Day',prefix+'Mon',prefix+'Yr',prefix+'Hr',prefix+'Min',prefix+'Sec',prefix+'APm')
		for(var cnt=0; cnt<flds.length; cnt++)
			if(obj=chkbx.form.elements[flds[cnt]]) obj.style.display = (chkbx.checked) ? '' : 'none'
	}
	if(!chkbx.checked && (fld=chkbx.form.elements[prefix])) fld.value = '0000-00-00 00:00:00'
	else setDatetime(chkbx.form, prefix, 1)
	return
}
function setDatetime (form, prefix, time) {
	var fld, yr, mon, day, hrs, min, sec, apm
	if(fld=form.elements[prefix+'Yr']) {
		yr = (fld.value) ? fld.value : fld.options[fld.selectedIndex].text
		if(yr.length==2) yr = (yr>=70) ? '19'+yr : '20'+yr
	} else yr = '0000'
	if(fld=form.elements[prefix+'Mon']) {
		mon = (fld.value) ? fld.value : fld.options[fld.selectedIndex].text
		if(mon.length==3) {
			mon = monthAbbr2Int(mon)
			if(mon.length==1) mon = '0'+mon
		}
	} else mon = '00'
	if(fld=form.elements[prefix+'Day']) {
		day = (fld.value) ? fld.value : fld.options[fld.selectedIndex].text
		if(day.length==1) day = '0'+day
	} else day = '00'
	if(time) {
		if(fld=form.elements[prefix+'Hr']) {
			hrs = parseInt((fld.value) ? fld.value : fld.options[fld.selectedIndex].text,10)
			if(fld=form.elements[prefix+'APm']) {
				apm = (fld.value) ? fld.value : fld.options[fld.selectedIndex].text
				apm = (apm.toLowerCase()=='am') ?1:0
				hrs = (hrs==12) ? ((apm)?0:12) : ((apm)?hrs:hrs+12)
			}
			if(hrs<10) hrs = '0'+hrs
		} else hrs = '00'
		if(fld=form.elements[prefix+'Min']) {
			min = (fld.value) ? fld.value : fld.options[fld.selectedIndex].text
			if(min.length==1) min = '0'+min
		} else min = '00'
		if(fld=form.elements[prefix+'Sec']) {
			sec = (fld.value) ? fld.value : fld.options[fld.selectedIndex].text
			if(sec.length==1) sec = '0'+sec
		} else sec = '00'
	}
	if(fld=form.elements[prefix]) {
		fld.value = yr+'-'+mon+'-'+day
		if(time) fld.value += ' '+hrs+':'+min+':'+sec
	}
	return
}
function clrDate (button, prefix) {
	var field = new makeArrayImplicit(prefix + 'Day',prefix + 'Mon',prefix + 'Yr')
	for(var cnt=1; cnt<=field.length; cnt++)
		button.form.elements[field[cnt]].selectedIndex = 0
	button.style.display = 'none'
	return
}
function clrDateTime (button, prefix) {
	var field = new Array()
	field[0] = prefix + 'Day'
	field[1] = prefix + 'Mon'
	field[2] = prefix + 'Yr'
	field[3] = prefix + 'Min'
	field[4] = prefix + 'Hr'
	for(var cnt=0; cnt<5; cnt++)
		button.form.elements[field[cnt]].selectedIndex = 0
	button.style.display = 'none'
	return
}
function setTimezoneOffset (form, hdn) {
	var fld
	if(fld=form.elements[hdn]) {
		var d = new Date()
		fld.value = d.getTimezoneOffset()*-60
	}
	return
}
// =====================================================================================
// The following datetime* functions work together to support the html_datetime_input() PHP function
function datetimeGetYr (field) {
	var yr = '0000'
	if(field) {
		yr = (field.type=='hidden') ? field.value : field.options[field.selectedIndex].text
		if(yr.length==2) yr = (yr>=70) ? '19'+yr : '20'+yr
	}
	return yr
}
function datetimeGetMon (field) {
	var mon = '00'
	if(field) {
		mon = (field.type=='hidden') ? field.value : field.options[field.selectedIndex].text
		if(mon.length==3) mon = monthAbbr2Int(mon)
		if(mon.length==1) mon = '0'+mon
	}
	return mon
}
function datetimeSetDays (form, prefix, year, month) {
	var dayCnt = getDaysofYear(year)
	var mon = parseInt(month,10)
	var fld = form.elements[prefix+'Day']

	var selectedDay = parseInt((fld.value) ? fld.value : fld.options[fld.selectedIndex].text,10)
	fld.options.length = dayCnt[mon]
	for(var count=1; count<=dayCnt[mon]; count++) {
		fld.options[count-1].text = count
		fld.options[count-1].value = (count<10) ? '0'+count : count
	}
	if(selectedDay > dayCnt[mon])
		fld.selectedIndex = fld.options.length-1
	return
}
function datetimeInput (fld, prefix, time, secAdj) { // prefix is same as name of hidden field
	var f, v, mFld, yr, mon, day, hrs, min, sec, apm
	var form = fld.form
	var amhrs = new Array('01','02','03','04','05','06','07','08','09','10','11','00')
	var pmhrs = new Array('13','14','15','16','17','18','19','20','21','22','23','12')
	yr = datetimeGetYr((f=form.elements[prefix+'Yr']))
	mon = datetimeGetMon((mFld=form.elements[prefix+'Mon']))	
	if(fld==f||fld==mFld) {
		datetimeSetDays(form,prefix,yr,mon)
	}
	if(f=form.elements[prefix+'Day']) {
		day = (f.value) ? f.value : f.options[f.selectedIndex].text
		if(day.length==1) day = '0'+day
	} else day = '00'
	if(time) {
		if(f=form.elements[prefix+'Hr']) {
			if(apm=form.elements[prefix+'APm']) {
				var v = (apm.value) ? apm.value : apm.options[apm.selectedIndex].text
				v = (v.toLowerCase()=='am')?amhrs:pmhrs
				for(var x=0; x<12; x++) f.options[x].value=v[x]
			}	
			hrs = parseInt((f.value) ? f.value : f.options[f.selectedIndex].text,10)
			if(f.value=='' && apm) {
				var am = (f.value) ? f.value : f.options[f.selectedIndex].text
				am = (am.toLowerCase()=='am') ?1:0
				hrs = (hrs==12) ? ((am)?0:12) : ((am && hrs>12)?hrs-12: ((!am && hrs<12)?hrs+12:hrs))
			}
			if(hrs<10) hrs = '0'+hrs
		} else hrs = '00'
		if(f=form.elements[prefix+'Min']) {
			min = (f.value) ? f.value : f.options[f.selectedIndex].text
			if(min.length==1) min = '0'+min
		} else min = '00'
		if(f=form.elements[prefix+'Sec']) {
			sec = (f.value) ? f.value : f.options[fld.selectedIndex].text
			if(sec.length==1) sec = '0'+sec
		} else sec = '00'
	}
	if(f=form.elements[prefix]) {
		if(time) {
			var gmtDate = new Date(yr,parseInt(mon,10)-1,day,hrs,min,sec)
		// secAdj is not being set correctly when current datetime & pickup/flt time straddle the StandardTime/DaylightTime boundary
		// HARDCODED ADJUSTMENT FOR 2010 [DAYLIGHT SAVING HACK] months: 0-11, days: 1-31
			var dst_start = new Date(2010,2,14,2,0,0)
			var dst_end = new Date(2010,10,7,1,59,0)
			if(gmtDate.getTime()>=dst_start.getTime() && gmtDate.getTime()<dst_end.getTime())
				secAdj += 3600
		// -----------------------------------------------------------------------------------------------
			gmtDate.setTime(gmtDate.getTime()-(secAdj*1000))
			yr = gmtDate.getFullYear()
			mon = gmtDate.getMonth()+1; if(mon<10) mon = '0'+mon
			day = gmtDate.getDate(); if(day<10) day = '0'+day
			hrs = gmtDate.getHours(); if(hrs<10) hrs = '0'+hrs
			min = gmtDate.getMinutes(); if(min<10) min = '0'+min
			sec = gmtDate.getSeconds(); if(sec<10) sec = '0'+sec
			f.value = yr+'-'+mon+'-'+day+' '+hrs+':'+min+':'+sec
		} else f.value = yr+'-'+mon+'-'+day
	}
	resetBg(fld,'#fff');
	return ((v=form.elements['_'+prefix]) && f.value!=v.value)?1:0
}
function dateSetDays (form, prefix, year, month) {
	var dayCnt = getDaysofYear(year)
	var mon = (month) ? parseInt(month,10) : 1;
	var fld = form.elements[prefix+'Day']
	var selectedDay = parseInt((fld.value) ? fld.value : fld.options[fld.selectedIndex].text,10)
	fld.options.length = dayCnt[mon]+1 
	fld.options[0].text = ''
	fld.options[0].value = '00';
	for(var count=1; count<=dayCnt[mon]; count++) {
		fld.options[count].text = count
		fld.options[count].value = (count<10) ? '0'+count : count
	} 
	if(selectedDay > dayCnt[mon])
		fld.selectedIndex = fld.options.length-1
	return
}
function dateInput (fld, prefix) { // prefix is same as name of hidden field
	var f, mFld, yr, mon, day
	var form = fld.form, name = fld.name
	yr = datetimeGetYr((f=form.elements[prefix+'Yr']))
	mon = datetimeGetMon((mFld=form.elements[prefix+'Mon']))	
	if(fld==f||fld==mFld) {
		dateSetDays(form,prefix,yr,mon)
	}
	if(f=form.elements[prefix+'Day']) {
		day = (f.value) ? f.value : f.options[f.selectedIndex].text
		if(day.length==1) day = '0'+day
	} else day = '00'
	if(f=form.elements[prefix]) {
		f.value = yr+'-'+mon+'-'+day
	}
	resetBg(fld,'#fff');
	return
}
function datetimeCtl (form, prefix, enable, secAdj, time) {
	var fld, ctl = (enable) ? '' : 'none'
	if((fld=getObjectId(prefix+'Ctl')) && fld.style)
		fld.style.display = ctl
	else {
		var flds = new Array('Yr','Mon','Day','Hr','Min','Sec','APm','Tz')
		for(var cnt=0; cnt<flds.length; cnt++)
			if((fld=getObjectId(prefix+flds[cnt])) && fld.style)
				fld.style.display = ctl
	}
	if(fld=getObjectId(prefix)) {
		if(enable)
			datetimeInput(fld, prefix, time, secAdj)
		else
			fld.value = '0000-00-00'+((time)?' 00:00:00':'')
	}
	return
}
// =====================================================================================
function timeInput (fld, prefix) { // prefix is same as name of hidden field
	var f, v, hrs, min, sec, apm
	var form = fld.form
	var amhrs = new Array('01','02','03','04','05','06','07','08','09','10','11','00')
	var pmhrs = new Array('13','14','15','16','17','18','19','20','21','22','23','12')
	if(f=form.elements[prefix+'Hr']) {
		if(apm=form.elements[prefix+'APm']) {
			var v = (apm.value) ? apm.value : apm.options[apm.selectedIndex].text
			v = (v.toLowerCase()=='am')?amhrs:pmhrs
			for(var x=0; x<12; x++) f.options[x].value=v[x]
		}	
		hrs = parseInt((f.value) ? f.value : f.options[f.selectedIndex].text,10)
		if(f.value=='' && apm) {
			var am = (f.value) ? f.value : f.options[f.selectedIndex].text
			am = (am.toLowerCase()=='am') ?1:0
			hrs = (hrs==12) ? ((am)?0:12) : ((am && hrs>12)?hrs-12: ((!am && hrs<12)?hrs+12:hrs))
		}
		if(hrs<10) hrs = '0'+hrs
	} else hrs = '00'
	if(f=form.elements[prefix+'Min']) {
		min = (f.value) ? f.value : f.options[f.selectedIndex].text
		if(min.length==1) min = '0'+min
	} else min = '00'
	if(f=form.elements[prefix+'Sec']) {
		sec = (f.value) ? f.value : f.options[fld.selectedIndex].text
		if(sec.length==1) sec = '0'+sec
	} else sec = '00'
	if(f=form.elements[prefix]) f.value = hrs+':'+min+':'+sec
	resetBg(fld,'#fff');
	return
}
function recordPosition (form) {
	if(form.pg_x_offset)
		form.pg_x_offset.value =
			(document.documentElement && document.documentElement.scrollLeft) ?
				document.documentElement.scrollLeft :
				((document.body) ? document.body.scrollLeft : window.pageXOffset)
	if(form.pg_y_offset)
		form.pg_y_offset.value =
			(document.documentElement && document.documentElement.scrollTop) ?
				document.documentElement.scrollTop :
				((document.body) ? document.body.scrollTop : window.pageYOffset)
	return
}
function addYtoHref (anchor) {
	var y_offset =
		(document.documentElement && document.documentElement.scrollTop) ?
			document.documentElement.scrollTop :
			((document.body) ? document.body.scrollTop : window.pageYOffset)
	if(y_offset) {
		var c = (anchor.href.indexOf('?')==-1)?'?':'&'
		anchor.href += c+'oY='+y_offset
	}
	return
}
function setFocus (fldName) {
	var fld
	if(fld=getObjectId(fldName)) {
		fld.focus()
	} else if(document.forms[0]) {
		for(fld=0; fld<document.forms[0].length; fld++) {
			if(document.forms[0].elements[fldName]) {
				document.forms[0].elements[fldName].focus()
			}
		}
	}
	return
}
function sideMenu (elemName, labelStyle, gfxName, gfxSrc) {
	var objId
	elemName.className = labelStyle
	if(gfxSrc.length>0 && (objId=getObjectId(gfxName)))
		objId.src = (typeof gfxArr == 'undefined' || typeof gfxArr[gfxName] == 'undefined') ? gfxSrc : gfxArr[gfxName].src
	return
}
function doSelection (fld, clr) { 
	if(fld && fld.style && fld.style.display!='none') {
		fld.focus()
		if(fld.type=='text') {
			fld.select()
		}
		fld.style.background = clr
	}
	return
}
//function doSelectPlDn (fld, clr) { fld.focus(); fld.style.background = clr; }
function resetBg (fld /*clr*/) {
	var clr = (arguments.length>1) ? arguments[1] : '#fff'
	if(fld && fld.style && fld.style.background) {
		fld.style.background = clr
	}
	return
}
function getDigits (val) {
// Optional second parameter is a flag to keep decimal chars (def. false)
	var str = val.toString()
	var result = ''
	var dec = (arguments.length>1 && (arguments[1]==true || arguments[1]==1)) ? 1 : 0
	for (var i=0; i<str.length; i++) {
		var chr = str.charAt(i)
		if ((chr >= '0' && chr <= '9') || (dec == 1 && chr == '.')) {
			result += chr
		}
	}
	return result
}
function isPosInt (val) {
	var str = val.toString()
	for (var i = 0; i < str.length; i++) {
		var chr = str.charAt(i)
		if (chr < '0' || chr > '9') return false
	}
	return true
}
function ifExists (checkVar) {
// FAILS when called if checkVar isn't defined - DON'T USE!
	checkVar = "" + checkVar;
	return (checkVar == 'undefined') ? (false) : (true);
	//return (typeof(window[checkVar])=="undefined")?false:true
}
function isEmpty (val) {
	if (val == null || val == '') return true
	return false
}
// Return a boolean value telling whether // the first argument is a string. 
function isString () {
	if (typeof arguments[0] == 'string')
		return true
	if(typeof arguments[0] == 'object') {
		var criterion = arguments[0].constructor.toString().match(/string/i)
		return (criterion != null)
	}
	return false
}
// Return a boolean value telling whether // the first argument is an Array object. 
function isArray () {
	if (typeof arguments[0]=='object') {
		var criterion = arguments[0].constructor.toString().match(/array/i)
		return (criterion != null)
	}
	return false
}
function isAmount(val) {
// Optional second parameter can be used to specify an alternate value for zero(def. is '0.00')
	amt = format(getDigits(val,true),2)
	if(amt=='0.00' && arguments.length>1 && typeof(arguments[1])=='string' && arguments[1].length) {
		amt = arguments[1]
	}
	return amt
}
function checkAmount (fldObj, clr) {
// Optional third parameter can be a user-friendly name for the field
	var msg = ''
	if(fldObj && fldObj.type=='text') {
		var nm = (arguments.length>2 && typeof(arguments[2])=='string' && arguments[2].length) ?
			arguments[2] : fldObj.name
		if(fldObj.value.length==0) {
			msg = 'Missing value for '+nm+' field.'
			fldObj.style.background = clr
		} else {
			fldObj.value = isAmount(fldObj.value)
		}
	}
	return msg
}
function isCardNumber (val, type) {
	var str = getDigits(val)
	var ccn = ''
	var len = str.length
	var pan = str.substr(0,6)
	if((type=='amex' && len==15 && str.substr(0,2)=='37') ||
		(type=='dncl' && len==14 && ((pan>=300000 && pan<=305999)||(pan>=309500 && pan<=309599)||(pan>=360000 && pan<=369999)||(pan>=380000 && pan<=389999))) ||
		(type=='jcb' && len==16 && pan>=352800 && pan<=358999) ||
		(type=='mstr' && len==16 && pan>=510000 && pan<=559999) ||
		(type=='visa' && (len==13 || len==16) && pan>=400000 && pan<=499999) ||		
		(type=='dscr' && len==16 && ((pan>=601100 && pan<=601109)||(pan>=601120 && pan<=601149)||(pan>=601190 && pan<=601199)))) {
		for (var i=0; i<len; i++) {
			var chr = str.charAt(i)
			if(i==4 || (type!='amex' && i==8) || (type=='amex' && i==10) || (type!='amex' && i==12))
				ccn += '-'
			ccn += chr
	}	}
	return ccn
}
function isZipCode (val) {
	var str = getDigits(val)
	var zip = ''
	if (str.length==5 || str.length==9) {
		for (var i=0; i<str.length; i++) {
			if (i==5) zip += '-'
				var chr = str.charAt(i)
			zip += chr
	}	}
	return zip
}
function isPhone (val) {
	var chr, str = getDigits(val)
	var ph = ''
	if (str.length==10) {
		ph += '('
		for (var i=0; i<10; i++) {
			chr = str.charAt(i)
			ph += chr
			if (i==2) ph += ') '
			if (i==5) ph += '-'
	}	}
	return ph
}
function isSSN (val) {
	var str = getDigits(val)
	var ssn = ''
	if (str.length==9) {
		for (var i=0; i<9; i++) {
			ssn += str.charAt(i)
			if (i==2||i==4) {
				ssn += '-'
	}	}	}
	return ssn
}

function isValidChar (str, chars) {
	var l = str.length, s = str.toLowerCase(), msg = ''
	var valid = 'abcdefghijklmnopqrstuvwxyz'
	if(chars.length) valid += chars
	for (var i=0; i<l; i++)
		if (valid.indexOf(s.charAt(i),0)==-1) msg += str.charAt(i)
	return (msg);
}
// Mirrors the check_name() method of the client object
function checkName (nameObj, clr) {
	var vowels = 'aeiouy';
	var chr, msg = '', msgFlg = 1
	var newArr = new Array()
	var msgArr = new Array()
	var nm = (arguments.length>2 && typeof(arguments[2])=='string' && arguments[2].length) ?
		arguments[2] : fldObj.name
	if(nameObj) {
		var name = nameObj.value, l = name.length
		if(l) {
			var mu = (name==name.toLowerCase() || name==name.toUpperCase())?0:-1
			var vwl = cns = len = pos = wrd = 0
			var bad = word = null
			for(; pos<l; pos++) {
				chr = (name.charAt(pos)=='(' || name.charAt(pos)==')')?' ':name.charAt(pos).toLowerCase()
				if(chr.charCodeAt()>=97 && chr.charCodeAt()<=122 || chr=='&') {
					if(vowels.indexOf(chr)==-1)
						cns++
					else
					{	cns = 0; vwl++ }
					len++
					if(wrd) {
						if(mu==-1) word += name.charAt(pos)
						else { word += (mu) ? chr.toUpperCase() : chr; mu = 0 }
						if(wrd!=chr.charCodeAt()) wrd = 1
					}
					else {
						wrd = chr.charCodeAt()
						word = (mu==-1 && len!=1) ? name.charAt(pos) : chr.toUpperCase()
					}
				}
				else if(chr=='-' || chr=="'") {
					len++
					if(wrd) {
						word += chr
						if(mu!=-1 && !(pos+2==l && name.charAt(pos+1)=='s') && 
							!(pos+2<l && name.charAt(pos+1)=='s' &&
								(name.charAt(pos+2)==' '||name.charAt(pos+2)=="\t"||name.charAt(pos+2)=="\n")))
							mu = 1
					}
				}
				if(((pos+1)==l || chr==' ' || chr=="\t" || chr=="\n") && wrd) {
					if(word!='Mr' && word!='Mrs' && word!='Ms' && word!='Miss') {
						if((len==1 && word!='&') || word=='Jr' || word=='Sr' || word=='St' || word=='Dr')
							word += '.'
						else if(len==2 && cns==2 && word!='Ng')
							word = word.charAt(0)+'. '+word.charAt(1).toUpperCase()+'.';
						newArr.push(word)
						if(len>2 && !vwl) msgArr.push('No vowels.')
						if(cns>4) msgArr.push('More than 4 consants in a row.')
						if(len>1 && wrd>1) msgArr.push('All chars in word are the same.')
					}
					wrd = len = vwl = cns = 0
					word = null
				}
			}
		} else msgArr.push('Empty '+nm+' string.')
		nameObj.value = newArr.join(' ')
	} else msgArr.push('Bad input object.')
	if(msgArr.length) {
		msg = (msgFlg) ? msgArr.join("\n") : 'Invalid name.'
		nameObj.style.background = clr
	}
	return msg
}
function isValidFullName (fnObj, lnObj, clr) {
	var chars = ".'- ", bad = null, msg = '', arr
	var regexp = /\b\s+\b/
	if(fnObj) {
		if(isEmpty(fnObj.value))
		{	msg = 'Missing first name'; bad = fnObj }
		else {
			for (var i=0; i<fnObj.value.length; i++)
				msg += (fnObj.value.charAt(i)=='(' || fnObj.value.charAt(i)==')')?' ':fnObj.value.charAt(i)
			fnObj.value = msg
			msg = ''
			if((msg=isValidChar(fnObj.value,chars)) && msg.length)
			{	msg = 'Invalid character(s) in first name: '+msg; bad = fnObj }
			else {
				arr = fnObj.value.split(regexp)
				for(i=0; i<arr.length; i++) {
					if(arr[i].length>2 && !containsVowel(arr[i]))
					{	msg = 'Invalid '+((i>0)?'middle':'first')+' name'; bad = fnObj; break }
	}	}	}	}
	if(bad) { doSelection (bad, clr); bad = null }
	if(lnObj) {
		if(msg.length) msg += "\n"
		if(isEmpty(lnObj.value))
		{	msg += 'Missing last name'; bad = lnObj }
		else if((bad=isValidChar(lnObj.value,chars)) && msg.length)
		{	msg += 'Invalid character(s) in last name: '+bad; bad = lnObj }
		else if(fnObj.value.toLowerCase()==lnObj.value.toLowerCase())
		{	msg += 'First or last name is invalid (identical)'; doSelection(fnObj, clr); bad = lnObj }
		else if(lnObj.value.length==1 ||
			(lnObj.value.length==2 && 
				(lnObj.value.charAt(0).toLowerCase()==lnObj.value.charAt(1).toLowerCase() ||
				 lnObj.value.charAt(lnObj.value.length-1)=='.')))
		{	msg += 'Invalid last name (please enter complete name)'; bad = lnObj }
		else {
			arr = lnObj.value.split(regexp)
			for(i=0; i<arr.length; i++) {
				if(arr[i].length>2 && !containsVowel(arr[i]))
				{	msg += 'Invalid last name'; bad = lnObj; break }
	}	}	}
	if(bad) doSelection (bad, clr)
	return msg
}
function containsVowel (str) {
	var regexp = /[aAeEiIoOuUyY]+/
	return (str.match(regexp))?true:false
}
function emailCheck (emailStr) {
	if (emailStr.length==0)
	{	alert('Missing Email address'); return false }
	var checkTLD=1;
	var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
	var emailPat=/^(.+)@(.+)$/;
	var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var quotedUser="(\"[^\"]*\")";
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	var atom=validChars + '+';
	var word="(" + atom + "|" + quotedUser + ")";
	var userPat = new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat=new RegExp("^" + atom + "(\\." + atom + ")*$");
	var matchArray=emailStr.match(emailPat);

	if (matchArray==null)
	{	alert("Email address seems incorrect (check @ and .'s)"); return false }
	var user=matchArray[1];
	var domain=matchArray[2];
	for (i=0; i<user.length; i++) {
		if((user.charCodeAt(i) >= 0 && user.charCodeAt(i) <= 44) ||
			user.charCodeAt(i) == 47 || 
			(user.charCodeAt(i) >= 58 && user.charCodeAt(i) <=64) ||
		   (user.charCodeAt(i) >= 91 && user.charCodeAt(i) <= 94) ||
			user.charCodeAt(i) == 96 ||
		   (user.charCodeAt(i) >= 123 && user.charCodeAt(i) <= 255))
		{	alert("The username contains invalid character(s): "  + user.charAt(i)); return false }
	} 
	for (i=0; i<domain.length; i++) {
		if((domain.charCodeAt(i) >= 0 && domain.charCodeAt(i) <= 44) || domain.charCodeAt(i) == 47 || 
		   (domain.charCodeAt(i) >= 58 && domain.charCodeAt(i) <=64) ||
			(domain.charCodeAt(i) >= 91 && domain.charCodeAt(i) <= 96) || 
			(domain.charCodeAt(i) >= 123 && domain.charCodeAt(i) <= 255))
		{	alert("The domain name contains invalid character(s): "  + domain.charAt(i)); return false }
	}
	if (user.match(userPat)==null)
	{	alert("The username doesn't seem to be valid."); return false }
	var IPArray=domain.match(ipDomainPat);
	if (IPArray!=null) {
		for (var i=1;i<=4;i++)
			if (IPArray[i]>255) { alert("Destination IP address is invalid!"); return false }
		return true;
	}
	var atomPat=new RegExp("^" + atom + "$");
	var domArr=domain.split(".");
	var len=domArr.length;
	for (i=0;i<len;i++) {
		if (domArr[i].search(atomPat)==-1)
		{	alert("The domain name does not seem to be valid."); return false }
	}
	if (checkTLD && domArr[domArr.length-1].length!=2 && 
		domArr[domArr.length-1].search(knownDomsPat)==-1)
	{	alert("The address must end in a well-known domain or two letter " + "country."); return false }
	if (len<2)
	{	alert("This address is missing a hostname!"); return false }
	return true;
}
function checkEmail (fldObj, clr) {
	var i, m, emailStr, msg = ''
	var msgArr = new Array
	if (fldObj && fldObj.type=='text') {
		fldObj.value = emailStr = trimStr(fldObj.value.toLowerCase())
		if (emailStr.length==0) {
			fldObj.style.background = clr
			return 'Missing email address.'
		}

		var checkTLD = 1
		var knownDomsPat = /^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/
		var emailPat = /^(.+)@(.+)$/
		var specialChars = "\\(\\)><@,;:\\\\\\\"\\.\\[\\]"
		var validChars = "\[^\\s" + specialChars + "\]"
		var quotedUser = "(\"[^\"]*\")"
		var ipDomainPat = /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
		var atom = validChars + '+'
		var word = "(" + atom + "|" + quotedUser + ")"
		var userPat = new RegExp("^" + word + "(\\." + word + ")*$")
		var domainPat = new RegExp("^" + atom + "(\\." + atom +")*$")
		var matchArray = emailStr.match(emailPat)

		if (matchArray==null) {
			fldObj.style.background = clr
			return "Email address seems incorrect (check @ and .'s)."
		}
		var user = matchArray[1];
		var domain = matchArray[2];
		for (i=0,m=''; i<user.length; i++) {
			if ((user.charCodeAt(i) >= 0 && user.charCodeAt(i) <= 44)
				 || user.charCodeAt(i) == 47
				 || (user.charCodeAt(i) >= 58 && user.charCodeAt(i) <=64)
				 || (user.charCodeAt(i) >= 91 && user.charCodeAt(i) <= 94)
				 || user.charCodeAt(i) == 96
				 || (user.charCodeAt(i) >= 123 && user.charCodeAt(i) <= 255)) {
				m += user.charAt(i)
			}
		}
		if (m) {
			msgArr.push('The username contains invalid character(s): '+m)
		}
		for (i=0, m=''; i<domain.length; i++) {
			if ((domain.charCodeAt(i) >= 0 && domain.charCodeAt(i) <= 44)
				 || domain.charCodeAt(i) == 47
				 || (domain.charCodeAt(i) >= 58 && domain.charCodeAt(i) <=64)
				 || (domain.charCodeAt(i) >= 91 && domain.charCodeAt(i) <= 96)
				 || (domain.charCodeAt(i) >= 123 && domain.charCodeAt(i) <= 255)) {
				m += domain.charAt(i)
			}
			if (m) {
				msgArr.push('The domain name contains invalid character(s): '+m)
			}
		}
		if (user.match(userPat)==null) {
			msgArr.push("The username doesn't seem to be valid.")
		}
		var IPArray=domain.match(ipDomainPat)
		if (IPArray!=null) {
			for (i=1; i<=4; i++) {
				if (IPArray[i]>255) {
					msgArr.push('Destination IP address is invalid.')
					break
				}
			}
		}
		var atomPat = new RegExp("^" + atom + "$")
		var domArr = domain.split(".")
		var len = domArr.length
		for (i=0; i<len; i++) {
			if (domArr[i].search(atomPat)==-1) {
				msgArr.push('The domain name does not seem to be valid.')
				break
			}
		}
		if (checkTLD && domArr[domArr.length-1].length!=2
			 && domArr[domArr.length-1].search(knownDomsPat)==-1) {
			msgArr.push('The address must end in a well-known domain or two letter country.')
		} else if (len<2) {
			msgArr.push('This address is missing a hostname!')
		}
	}
	if (msgArr.length) {
		msg = msgArr.join("\n")
		fldObj.style.background = clr
	}
	return msg;
}

function _checkName (fldObj, clr, chars) {
	var msg = ''
	if(fldObj) {
		fldObj.value = trimStr(fldObj.value)
		if(fldObj.value==0)
			msg = 'Missing input'
		else if(msg=isValidChar(fldObj.value,chars))
			msg = "The name contains invalid character(s): "+msg
		if(msg.length) doSelection(fldObj,clr)
	}
	return msg;
}
function nameCheck (nameStr) {
	if (nameStr.length==0)
	{	alert('Missing name'); return false }
	for (i=0; i<nameStr.length; i++) {
		if((nameStr.charCodeAt(i) >= 0 && nameStr.charCodeAt(i) <= 31) || (nameStr.charCodeAt(i) >= 33 && nameStr.charCodeAt(i) <=37) || 
		   (nameStr.charCodeAt(i) >= 42 && nameStr.charCodeAt(i) <=44) || (nameStr.charCodeAt(i) >=47 && nameStr.charCodeAt(i) <= 64) ||
		   (nameStr.charCodeAt(i) >= 91 && nameStr.charCodeAt(i) <= 96) || (nameStr.charCodeAt(i) >= 123 && nameStr.charCodeAt(i) <= 255))
		{	alert("The name contains invalid character(s): "  + nameStr.charAt(i)); return false }
	} 
	return true;
}
function fldChkTxt (fldObj, clr) {
	var passed = true
	if(fldObj && isEmpty(fldObj.value))
	{	doSelection (fldObj, clr); passed = false }
	return passed
}
function checkText (fldObj, clr) {
	var msg = ''
	if(fldObj && (fldObj.type=='text'||fldObj.type=='password'||fldObj.type=='textarea'||fldObj.type=='file') && isEmpty(fldObj.value)) {
		var nm = (arguments.length>2 && typeof(arguments[2])=='string' && arguments[2].length) ?
			arguments[2] : fldObj.name
		msg = 'Missing value for '+nm+' field.'
		fldObj.style.background = clr
	}
	return msg
}
function fldChkInt (fldObj, clr) {
	var passed = true
	if(fldObj && (isEmpty(fldObj.value) || !isPosInt(fldObj.value)))
	{	doSelection (fldObj, clr); passed = false }
	return passed
}
function fldChkCCType (parObj, fldObj, clr) {
	var card = ''
	if(parObj && fldObj) {
		if(fldObj.length) {
			for(var i = 0; i<fldObj.length; i++)
				if(fldObj[i].checked)
				{	card = fldObj[i].value; break; }
			if(card=='') parObj.style.background = clr
		}
		else if(fldObj.type=='hidden')
			card = fldObj.value
	}
	return card
}
function fldChkCCNum (fldObj, clr, card) {
	var passed = true
	if(card.length || !fldObj.value.length) {
		tmp = isCardNumber(fldObj.value, card)
		if(tmp.length==0)
		{	doSelection (fldObj, clr); var passed = false }
		else
		{	fldObj.value = tmp; var passed = true }
	}
	return passed
}
function fldChkCCExp (fldMon, fldYr, clr) {
	var passed = true
	if(fldMon && fldYr) {
		if(!fldMon.selectedIndex)
		{	doSelection(fldMon, clr); passed = false }
		if(!fldYr.selectedIndex)
		{	doSelection(fldYr, clr); passed = false }
		if(passed) {
			var year = parseInt(fldYr.options[fldYr.selectedIndex].text,10)
			var month = parseInt(fldMon.options[fldMon.selectedIndex].text,10)-1
			var dayCnt = getDaysofYear(year)
			var exp = new Date(year,month,dayCnt[month+1],23,59,59)
			var today = new Date()
			if(exp.getTime()<today.getTime()) {
				doSelection(fldMon, clr)
				if(today.getFullYear()<year) doSelection(fldYr, clr)
				passed = false
			}
		}
	}
	return passed
}
function fldChkCCCode (fldObj, clr, card) {
	var passed = true
	if(fldObj && fldObj.value=='' ||
		(card=='amex' && (!isPosInt(fldObj.value) || fldObj.value.length!=4)) ||
		((card=='dscr'||card=='mstr'||card=='visa') && (!isPosInt(fldObj.value) || fldObj.value.length!=3)))
	{	doSelection (fldObj, clr); passed = false }
	return passed
}
function fldChkSel (fldObj, clr, index) {
	var passed = true
	if(fldObj && fldObj.selectedIndex==index)
	{	doSelection (fldObj, clr); passed = false }
	return passed
}
function checkSelect (fldObj, clr, index) {
	var msg = ''
	if(fldObj && (fldObj.type=='select-one'||fldObj.type=='select-multiple') && fldObj.selectedIndex==index) {
		var nm = (arguments.length>3 && typeof(arguments[3])=='string' && arguments[3].length) ?
			arguments[3] : fldObj.name
		msg = 'Missing value for '+nm+' field.'
		fldObj.style.background = clr
	}
	return msg
}
function checkRadio (parObj, radObj, clr) {
	var chk = false, msg = ''
	if(parObj && radObj && radObj[0].type=='radio') {
		var nm = (arguments.length>3 && typeof(arguments[3])=='string' && arguments[3].length) ?
			arguments[3] : radObj.name
		for(var i=0; i<radObj.length; i++) {
			if(radObj[i].checked) {
				chk = true
				break
			}
		}
		if(!chk) {
			msg = 'No selection for '+nm+' field.'
			parObj.style.background = clr
		}
	}
	return msg
}

function fldChkRad (parObj, fldObj, clr) {
	var passed = true
	if(parObj && fldObj && fldObj[0].type=='radio') {
		passed = false
		for(var i=0; i<fldObj.length; i++)
			if(fldObj[i].checked) {	passed = true; break }
		if(!passed) parObj.style.background = clr
	}
	return passed
}
function fldChkZip (fldObj, clr) {
	var passed = true
	if(fldObj) {
		var tmp = isZipCode(fldObj.value)
		if(tmp.length==0)
		{	doSelection (fldObj, clr); passed = false }
		else
			fldObj.value = tmp
	}
	return passed
}
function checkZipcode (fldObj, clr) {
	var msg = ''
	if(fldObj && fldObj.type=='text') {
		var tmp = isZipCode(fldObj.value)
		if(tmp.length==0) {
			msg = 'Invalid zipcode.'
			fldObj.style.background = clr
		} else {
			fldObj.value = tmp
		}
	}
	return msg
}
function fldChkUSPhone (fldObj, clr) {
	var passed = true
	if(fldObj) {
		var tmp = isPhone(fldObj.value)
		if(tmp.length==0 || tmp.charAt(1) < 2 || tmp.charAt(6) < 2 ||
			(tmp.charAt(1)==5 && tmp.charAt(2)==5 && tmp.charAt(3)==5)) {
			doSelection(fldObj, clr); 
			passed = false 
		} else
			fldObj.value = tmp
	}
	return passed
}
function checkPhone (fldObj, clr) {
	var msg = ''
	if(fldObj && fldObj.type=='text') {
		var tmp = isPhone(fldObj.value)
		if(tmp.length==0 || tmp.charAt(1) < 2 || tmp.charAt(6) < 2 ||
			(tmp.charAt(1)==5 && tmp.charAt(2)==5 && tmp.charAt(3)==5)) {
			var nm = (arguments.length>2 && typeof(arguments[2])=='string' && arguments[2].length) ?
				arguments[2] : fldObj.name
			msg = 'Invalid '+nm+' number.'
			fldObj.style.background = clr
		} else
			fldObj.value = tmp
	}
	return msg
}
function checkSSN (fldObj, clr) {
	var msg = ''
	if(fldObj && fldObj.type=='text') {
		var tmp = isSSN(fldObj.value)
		if(tmp.length==0) {
			var nm = (arguments.length>2 && typeof(arguments[2])=='string' && arguments[2].length) ?
				arguments[2] : fldObj.name
			msg = 'Invalid '+nm+' number.'
			fldObj.style.background = clr
		} else {
			fldObj.value = tmp
		}
	}
	return msg
}
function checkIntRange (fldObj, min, max, clr) {
	var i, msg = ''
	if(fldObj) {
		if(isEmpty(fldObj.value)) msg = 'Missing value\n'
		if(!isPosInt(fldObj.value)) msg = 'Invalid value\n'
		if((i=parseInt(fldObj.value,10))<min || i>max) msg = 'Out of range value\n'
		if(msg) doSelection (fldObj, clr)
	}
	return msg
}

function checkPwds (fldObj1, fldObj2, clr) {
	var passed = true, msg = '', tmp
	if(fldObj1 && fldObj2) {
		if(isEmpty(fldObj1.value))
		{	doSelection (fldObj1, clr); passed = false }
		if(isEmpty(fldObj2.value))
		{	doSelection (fldObj2, clr); passed = false }
		if(!passed)
			msg = 'Missing new password.'
		else if(fldObj1.value!=fldObj2.value) {
			doSelection (fldObj2, clr)
			passed = false
			msg = 'Mismatched passwords.'
			fldObj2.value=''
		}
	}
	return msg
}
function checkValidPwd (fldObj, mLen, dCnt, sCnt, clr) {
	var c, d, i, s, passed = true, msg = '', spChars = "!@#$%^&*()_-+=[]{}|;:<>,./?~"
	var len = Math.max(6,mLen)
	if(fldObj && !isEmpty(fldObj.value)) {
		var pwd = fldObj.value
		if(pwd.length<len) {
			doSelection (fldObj,clr);
			passed = false;
			msg = msg.addline('Password length is less than '+len+'.')
		}
		if(dCnt>0 || sCnt>0) {
			for(d=0,i=0,s=0; i<pwd.length; i++) {
				c = pwd.charAt(i)
				if(c >= '0' && c <= '9') d++
				if(spChars.indexOf(c)>=0) s++
			}
			if(dCnt>0 && d<dCnt) {
				doSelection (fldObj,clr); passed = false; c = (dCnt>1) ? 's' : ''
				msg = msg.addline('Password must contain at least '+dCnt+' digit'+c+'.')
			}
			if(sCnt>0 && s<sCnt) {
				doSelection (fldObj,clr); passed = false; c = (sCnt>1) ? 's' : ''
				msg = msg.addline('Password must contain at least '+sCnt+' special character'+c+'.')
			}
		}
	}
	return msg
}
function fldChkPwds (fldObj1, fldObj2, clr) {
	var passed = true
	if(fldObj1 && fldObj2) {
		if(isEmpty(fldObj1.value))
		{	doSelection (fldObj1, clr); passed = false }
		if(isEmpty(fldObj2.value))
		{	doSelection (fldObj2, clr); passed = false }
		if(!passed) alert('Missing password')
		else if(fldObj1.value!=fldObj2.value)
		{	doSelection (fldObj2, clr); passed = false; alert('Mismatched passwords'); fldObj2.value=''; }
	}
	return passed
}
function fldValidPwd (fldObj, mLen, dCnt, sCnt, clr) {
	var c, d, i, s, passed = true, spChars = "!@#$%^&*()_-+=[]{}|;:<>,./?~"
	var len = Math.max(6,mLen)
	if(fldObj && !isEmpty(fldObj.value)) {
		pwd = fldObj.value
		if(pwd.length<len)
		{	doSelection (fldObj,clr); passed = false; alert('Password length is less than '+len+'.'); }
		if(dCnt>0 || sCnt>0) {
			for(d=0,i=0,s=0; i<pwd.length; i++) {
				c = pwd.charAt(i)
				if(c >= '0' && c <= '9') d++
				if(spChars.indexOf(c)>=0) s++
			}
			if(dCnt>0 && d<dCnt) {
				doSelection (fldObj,clr); passed = false; c = (dCnt>1) ? 's' : ''
				alert('Password must contain at least '+dCnt+' digit'+c+'.')
			}
			if(sCnt>0 && s<sCnt) {
				doSelection (fldObj,clr); passed = false; c = (sCnt>1) ? 's' : ''
				alert('Password must contain at least '+sCnt+' special character'+c+'.')
			}
		}
	}
	return passed
}
function sortTable (fid, fld) {
	var obj
	if(obj=getObjectId(fid)) {
		obj.value = fld
		if(fid!='rec_id' && obj.form.rec_id) obj.form.rec_id.value = 0
		obj.form.submit()
	}
	return
}
function link2hidden (val, hdn) { // Obsolete use 'choice()'
	var obj
	if(obj=getObjectId(hdn)) {
		obj.value = val
		obj.form.submit()
	}
	return
}
function select2hidden (sel, hdn) { // Obsolete use 'choice()'
	var obj
	if(obj=getObjectId(hdn)) {
		obj.value = sel.options[sel.selectedIndex].value
		obj.form.submit()
	}
	return
}
function clrFld (fld) {
	var obj = getObjectId(fld)
	if(obj) obj.value = ''
	return
}
function toggle (fld) {
	var obj = getObjectId(fld)
	if(obj) obj.value = (obj.value==1)?0:1
	return obj
}
function choice (inp, hdn, val) {
	var obj
	if(obj=getObjectId(hdn)) {
		if(inp && typeof(inp)=='object') {
			switch(inp.type) {
				case 'button':
				case 'submit':
				case 'reset':
				case 'radio':
				case 'text':
					obj.value = inp.value; break
				case 'checkbox':
					obj.value = (inp.checked) ? inp.value : null; break					
				case 'select-one':
					obj.value = inp.options[inp.selectedIndex].value; break
				case 'image':
					obj.value = inp.src; break
				default:
					obj.value = val; break
			}
		}
		else obj.value = val
		obj.form.submit()
	}
	return
}
function reorder (form, recId, upFlg) {
	var rObj = form.elements['rec_id']
	var uObj = form.elements['up_flg']
	if(rObj && uObj) {
		rObj.value = recId
		uObj.value = (upFlg)?1:0
		form.submit()
	}
	return
}
function reorder2 (form, recId, slot) {
	var rObj = form.elements['rec_id']
	var uObj = form.elements['up_flg']
	if(rObj && uObj) {
		rObj.value = recId
		uObj.value = parseInt(slot,10)
		form.submit()
	}
	return
}
// function swFlds (form, offArr, onArr) => OBSOLETE - use swtchFlds below
function swtchFlds (offArr, onArr) {
	var cnt, fld
	if(offArr && isArray(offArr) && offArr.length) {
		for(cnt=0; cnt<offArr.length; cnt++) {
			if(fld=getObjectId(offArr[cnt])) {
				fld.style.display = 'none'
			}
		}
	}
	if(onArr && isArray(onArr) && onArr.length) {
		for(cnt=0; cnt<onArr.length; cnt++) {
			if(fld=getObjectId(onArr[cnt])) {
				fld.style.display = 'block'
			}
		}
	}
	return
}

function dispOnCmp (fld, val, dispArr) {
	var cnt, obj
	var set = (fld && dispArr && dispArr.length && fld.value!=val) ? 'visible' : 'hidden'
	for(cnt=0; cnt<dispArr.length; cnt++) {
		if(obj=getObjectId(dispArr[cnt])) {
			obj.style.visibility = set
		}
	}
	return
}
function chkbxCntrl (chxObj, dspArr) {
// dspArr = array of element ID's to switch on/off based on checkbox checked property value
	if(chxObj && chxObj.type=='checkbox') {
		var state = (chxObj.checked)?1:0
	// 0 - display, 1 - visibility, 2 - both
		pFlg = (arguments.length>3) ? ((parseInt(arguments[3],10)>1)?2:1) : 0
		if(dspArr && dspArr.length) {
			var obj
			for(cnt=0; cnt<dspArr.length; cnt++) {
				if(obj=getObjectId(dspArr[cnt])) {
					if(pFlg==0 || pFlg==2) {
						obj.style.display = (state) ? '' : 'none'
					}
					if(pFlg) {
						obj.style.visibility = (state) ? 'visible' : 'hidden'
					}
				}
			}
		}
	}
	return
}
// function updateCtl (form, prefix, updId) => Obsolete - Use updateCntrl() below
function updateCntrl (form, prefix, dspArr) {
// dspArr = array of element ID's to switch on/off based on compare
// Hidden fields with original values are named the same except they have an underscore('_') prefixed
	var hdn, fld, nam, obj
	if(form.elements) {
		var disp = 0;
		for(var cnt=0; cnt<form.elements.length; cnt++) {
			if((fld=form.elements[cnt]) && (nam=fld.name) && nam.indexOf(prefix)==0 &&
				(hdn=form.elements['_'+nam]) && hdn.type=='hidden')
				switch(fld.type) {
					case 'checkbox':
						if((fld.checked && hdn.value=='0') || (!fld.checked && hdn.value=='1')) disp = 1
						break
					case 'text':
					case 'hidden':
						if(fld.value!=hdn.value) disp = 1
						break
				}
				
			if(disp) break
		}
		pFlg = (arguments.length>3) ? ((arguments[3])?1:0) : 1
		nam = (pFlg) ? ((disp) ? 'visible' : 'hidden') : ((disp) ? '' : 'none')
		if(dspArr && dspArr.length) {
			for(cnt=0; cnt<dspArr.length; cnt++) {
				if(obj=getObjectId(dspArr[cnt])) {
					(pFlg) ? obj.style.visibility = nam : obj.style.display = nam
				}
			}
		}
	}
	return
}
function html_datetime_input (prefix, mtFlg) {
	var day, oday, mon, omon, yr, oyr, hr, ohr, min, omin, apm, oapm, obj
	day = getObjectId(prefix+'Day'); oday = getObjectId('_'+prefix+'Day')
	mon = getObjectId(prefix+'Mon'); omon = getObjectId('_'+prefix+'Mon')
	hr = getObjectId(prefix+'Hr');    ohr = getObjectId('_'+prefix+'Hr')
	min = getObjectId(prefix+'Min'); omin = getObjectId('_'+prefix+'Min')
	apm = getObjectId(prefix+'APm'); oapm = getObjectId('_'+prefix+'APm')
	yr = new Date().getFullYear()
	if(obj=getObjectId(prefix+'Yr')) {
		if(mon.selectedIndex>0 &&
			(mon.options[mon.selectedIndex].text=='Jan'||mon.options[mon.selectedIndex].text=='Feb'))
			yr++
		obj.value = yr
		if(obj=getObjectId(prefix+'Year')) {
			if(obj.childNodes.length)
				obj.childNodes[0].nodeValue = yr
			else
				obj.appendChild(document.createTextNode(yr))
		}
	}
	setDayNums(prefix, mtFlg)
	if(obj=getObjectId('set_time')) {
		obj.style.display =
			((day && oday && day.selectedIndex>=0 && day.options[day.selectedIndex].text!=oday.value) ||
			 (mon && omon && mon.options[mon.selectedIndex].text!=omon.value) ||
			 (hr && ohr && hr.options[hr.selectedIndex].text!=ohr.value) ||
			 (min && omin && min.options[min.selectedIndex].text!=omin.value) ||
			 (apm && oapm && apm.options[apm.selectedIndex].text!=oapm.value))?'':'none'
	}
	return;
}
function checkEnter (field, event) {
	var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
	if (keyCode == 13) {
		var i;
		for (i = 0; i < field.form.elements.length; i++)
			if (field == field.form.elements[i])
				break;
		i = (i + 1) % field.form.elements.length;
		field.form.elements[i].focus();
		return false;
	} 
	else
	return true;
}
// Disable all form elements on a page. If no form is passed, all forms in the document will be processed.
function disableAll (form) {
	var x, y, frmArr = (form) ? new Array(form) : document.forms;
	for(x=0; x<frmArr.length; x++)
		for(y=0; y<frmArr[x].elements.length; y++)
			frmArr[x].elements[y].disabled = true
	return
}
// LIMITED protection for images
function protect(e) {
	alert("Sorry, you don't have permission to right-click.")
	return false
}
function trap() {
	if(document.images)
		for(i=0;i<document.images.length;i++)
			document.images[i].onmousedown = protect;
}
function right(e) {
	if ((navigator.appName == 'Netscape' && e.which == 3) ||
		 (navigator.appName == 'Microsoft Internet Explorer' && event.button==2)) {
		alert(msg)
		return false
	}
	else return true
}
function trapclick() {
	if(document.images) {
		for(i=0;i<document.images.length;i++) {
			document.images[i].onmousedown = right
			document.images[i].onmouseup = right
		}
	}
}
function translateRGBcolor (rgbColor) {
	var hex, clr = ''
	if(rgbColor && rgbColor.indexOf('rgb(')==0) {
		var i = 0, cIndx = '', cArr = new Array()
		for(var c=4; c<rgbColor.length; c++) {
			if(rgbColor.charCodeAt(c)>='0'.charCodeAt() && rgbColor.charCodeAt(c)<='9'.charCodeAt()) {
				cIndx += rgbColor.charAt(c)
			} else if(cIndx.length) {
				cArr[i++] = parseInt(cIndx,10)
				cIndx = ''
			}
		}
		clr = cArr[0]*65536 + cArr[1]*256 + cArr[2]
	}
	return clr.toString(16)
}
 // Natural Sort algorithm for Javascript
 //  Version 0.2
 // Author: Jim Palmer (based on chunking idea from Dave Koelle)
 // Released under MIT license.
function naturalSort (a, b) {
// This function does case-insensitive sorting. This can easily be disabled by removing the .toLowerCase() calls on the x and y variables.
// setup temp-scope variables for comparison evauluation
	var x = a.toString().toLowerCase() || ''
	var y = b.toString().toLowerCase() || ''
	var nC = String.fromCharCode(0)
	var xN = x.replace(/([-]{0,1}[0-9.]{1,})/g, nC + '$1' + nC).split(nC)
	var yN = y.replace(/([-]{0,1}[0-9.]{1,})/g, nC + '$1' + nC).split(nC)
	var xD = (new Date(x)).getTime()
	var yD = (new Date(y)).getTime()
// natural sorting of dates
	if (xD && yD && xD < yD) {
		return -1
	} else if (xD && yD && xD > yD) {
		return 1
	}
// natural sorting through split numeric strings and default strings
	for (var cLoc=0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
		if ((parseFloat(xN[cLoc]) || xN[cLoc]) < (parseFloat(yN[cLoc]) || yN[cLoc])) {
			return -1
		} else if ((parseFloat(xN[cLoc]) || xN[cLoc]) > (parseFloat(yN[cLoc]) || yN[cLoc])) {
			return 1
		}
	}
	return 0
}
// -------------
function popupWindow (url, tag, wx, wy, ww, wh) {
	var win = window.open(url,tag,'left='+wx+',top='+wy+',screenX='+wx+',screenY='+wy+',width='+ww+',height='+wh+',location=0,menubar=0,resizable=1,scrollbars=1,status=0,toolbar=0')
	if(win.opener==null) win.opener = self
	win.focus()
	return
}
function panelEdit(className, selectCol, selectVal, property) {
	var url = 'admin_panel_edit.php?c='+className+'&s='+selectCol+'&v='+selectVal+'&p='+property
	var wx = 20, wy = 20, ww = 700, wh = 500
	popupWindow(url, 'panelEdit', wx, wy, ww, wh)
	return false
}
Array.prototype.remove = function(f) {
	if(f && this.length) {
		var found = 0
		for(var i=0; i<this.length; i++) {
			if(this[i]==f) {
				found = 1
			}
			if(found && (i+1)<this.length) {
				this[i] = this[i+1]
			}
		}
		if(found) {
			this.length--
			delete this[this.length]
		}
	}
	return
}
Array.prototype.in_array = function(f) {
	var r = 0
	if(f && this.length) {
		for(var i=0; i<this.length; i++) {
			if(this[i]===f) {	// BEWARE! Strict comparison being done here!
				r = 1
				break
			}
		}
	}
	return r
}
String.prototype.addline = function (a) {
	return (this.length) ? this+"\n"+a : a
}
String.prototype.basename = function () {
    var b = this.replace(/^.*[\/\\]/g, '');
    if (arguments.length && typeof(arguments[0])=='string' && b.substr(b.length-arguments[0].length)==arguments[0]) {
        b = b.substr(0, b.length-arguments[0].length);
    }
    return b;
}
String.prototype.dirname = function () {
	return this.replace(/\\/g,'/').replace(/\/[^\/]*\/?$/, '');
}
String.prototype.pad = function(l, s, t) {
	return s || (s = " "), (l -= this.length) > 0 ? (s = new Array(Math.ceil(l / s.length)
		+ 1).join(s)).substr(0, t = !t ? l : t == 1 ? 0 : Math.ceil(l / 2))
		+ this + s.substr(0, l - t) : this
}
Date.prototype.syncMins = function(up, intvl) {
	var min = this.getUTCMinutes()
	var now = Date.UTC(this.getUTCFullYear(),this.getUTCMonth(),this.getUTCDate(),this.getUTCHours(),0,0)
	var m = ((up) ? Math.ceil(min/intvl) : Math.floor(min/intvl)) * intvl;
	if(min==m && up) m += intvl;
	if(min<intvl && !up) m = -1*intvl;
	this.setTime(now+(m*60000))
	return
}
Date.prototype.getDBTime = function(secsFlg) {
	var tm = this.getUTCFullYear() + '-'
	var str = new String(this.getUTCMonth()+1)
	tm +=  str.pad(2,'0',0) + '-'
	str = new String(this.getUTCDate())
	tm +=  str.pad(2,'0',0) + ' '
	str = new String(this.getUTCHours())
	tm +=  str.pad(2,'0',0) + ':'
	str = new String(this.getUTCMinutes())
	tm +=  str.pad(2,'0',0) + ':'
	if(secsFlg) {
		str = new String(this.getUTCSeconds())
		tm +=  str.pad(2,'0',0)
	} else {
		tm += '00'
	}
	return tm
}
Date.prototype.setDBTime = function(txtFld) {
	if(typeof txtFld=='object' && (txtFld.type=='text' || txtFld.type=='hidden') && txtFld.value.length) {
		var cArr = txtFld.value.split(' ')
		var dArr = cArr[0].split('-')
		var tArr = cArr[1].split(':')
		this.setTime(
			Date.UTC(
				parseInt(dArr[0],10), parseInt(dArr[1],10)-1, parseInt(dArr[2],10),
				parseInt(tArr[0],10), parseInt(tArr[1],10), parseInt(tArr[2],10)
			)
		)
	}
	return
}
Date.prototype.toGmt = function(tzone) {
	// Transpose a local datetime to UTC to bypass faulty DST conversions by built-in JS functions
	var offset = (typeof tzone=="undefined") ? 0 : tzone*3600000
	this.setTime(
		Date.UTC(this.getFullYear(),this.getMonth(),this.getDate(),this.getHours(),this.getMinutes(),0)-offset
	)
	return
}
Date.prototype.toLocal = function(tzone, leadtime) {
// leadtime in minutes; tzone is timezone offset (ie. Pacific is -8)
	var l, offset = (typeof tzone=="undefined") ? 0 : tzone*3600000
	var ms = this.getTime()
	this.setTime(+offset)
	if(l=parseInt(leadtime,10)) {
		offset += (l*60000)
	}
	this.setTime(ms+offset)
	return
}
Date.prototype.getDisplayDate = function() {
	var dayArr = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
	var monArr = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
	var tm = dayArr[this.getUTCDay()] + ', ' + this.getUTCDate() + '-' + monArr[this.getUTCMonth()] + '-' + this.getUTCFullYear() + ' at '
	var h = this.getUTCHours();
	tm += ((h>12) ? h-12 : ((h==0) ? 12 : h)) + ':'
	str = new String(this.getUTCMinutes())
	tm +=  str.pad(2,'0',0) + ' ' + ((h>11) ? 'PM' : 'AM')
	return tm
}

