function JSQuotes(s)
{
	// fix quotes
	s = s.replace(/\'/, '\\x27');
	s = s.replace(/\"/, '\\x22');
	// return result
	return s;
}

function Trim(s)
{
	// trim
	s = s.replace(/ +$/, "");
	s = s.replace(/^ +/, "");
	// return result
	return s;
}

function G(UR, cfm)
{
	if (cfm) {
		if (!e)
			var e = window.event;
		if (e)
			e.cancelBubble = true;
		if (UR)
			document.location.href = UR;
	}
	return false;
}

function GC(UR, cfm)
{
	if (!e)
		var e = window.event;
	if (e)
		e.cancelBubble = true;
	if (UR.substr(0, 9) == 'login.php')
		parent.document.location.href = UR;
	else if (UR)
		parent.content.document.location.href = UR;
	return false;
}

function MO(e)
{
	if (!e)
		var e = window.event;
	var S = e.srcElement;
	SetTD(S, "BtnActive");
	return false;
}

function MU(e)
{
	if (!e)
		var e = window.event;
	var S = e.srcElement;
	SetTD(S, "Btn");
	return false;
}

function S(sa, cfm)
{
	if (cfm) {
		var frm = document.frmMain;
		frm.SubmitAction.value = sa;
		frm.submit();
	}
	return false;
}

function CheckLen(ctl, l, d)
{
// Initialize
dat = ctl.value;
// Limit length
if (dat.length > l) {
	dat = dat.substring(0, l);
	ctl.value = dat;
}
// Display remaining space
if (d)
document.getElementById(d).innerHTML = (l - dat.length);
// return result
return false;
}

function OpenBrowse(q)
{
	// Initialize
	var x = (screen.width / 2) - 325;
	var y = (screen.height / 2) - 275;
	var pos = 'left=' + x + ',top=' + y;
	// Display popup
	w = window.open('picklist.php?' + q, '',
		'width=550,height=400,location=no,scrollbars=yes,status=yes,' + pos);
	return false;
}

function OpenPopup(url)
{
	// Initialize
	var x = (screen.width / 2) - 325;
	var y = (screen.height / 2) - 275;
	var pos = 'left=' + x + ',top=' + y;
	// Display popup
	w = window.open(url, '',
		'width=550,height=400,location=no,scrollbars=yes,status=yes,' + pos);
	return false;
}

function EditSection(s)
{
	if (document.getElementById(s + '.view').style.display == 'block') {
		document.getElementById(s + '.img').src = '/img/menu_cancel.gif';
		document.getElementById(s + '.view').style.display = 'none';
		document.getElementById(s + '.edit').style.display = 'block';
		document.getElementById(s + '.status').value = 'edit';
	} else {
		document.getElementById(s + '.img').src = '/img/menu_edit.gif';
		document.getElementById(s + '.view').style.display = 'block';
		document.getElementById(s + '.edit').style.display = 'none';
		document.getElementById(s + '.status').value = '';
	}
	if (EditMode() == true) {
		document.getElementById('mnuView').style.display = 'none';
		document.getElementById('mnuEdit').style.display = 'block';
	} else {
		document.getElementById('mnuView').style.display = 'block';
		document.getElementById('mnuEdit').style.display = 'none';
	}
	return false;
}

function SetFocusFirst()
{
	var bFound = false;
	// for each form
	for (f = 0; f < document.forms.length; f++) {
		// for each element in each form
		for (i = 0; i < document.forms[f].length; i++) {
			// if it's not a hidden element
			if (document.forms[f][i].type != "hidden") {
				// and it's not disabled
				if (document.forms[f][i].disabled != true) {
					// and it's not in a hidden div
					if (document.forms[f][i].style.display != 'none') {
						// check if container is hidden DIV
//						var e = document.getElementById(document.forms[f][i].name);
//						while (e.tagName != "DIV")
//							e = e.parentNode;
//window.alert(e.name);
//						if (e.style.display != 'none') {
							// set the focus to it
							document.forms[f][i].focus();
							var bFound = true;
//						}
					}
				}
			}
			// if found in this element, stop looking
			if (bFound == true)
				break;
		}
		// if found in this form, stop looking
		if (bFound == true)
			break;
	}
}

function GoEdit(s)
{
	document.getElementById(s + '.txtView').style.display = 'none';
	document.getElementById(s + '.txtEdit').style.display = 'block';
	document.getElementById(s + '.mnuView').style.display = 'none';
	document.getElementById(s + '.mnuSave').style.display = 'block';
	document.getElementById(s + '.act').value = 'edit';
	return false;
}

function GoNew(s)
{
	document.getElementById(s + '.txtView').style.display = 'none';
	document.getElementById(s + '.txtNew').style.display = 'block';
	document.getElementById(s + '.mnuView').style.display = 'none';
	document.getElementById(s + '.mnuSave').style.display = 'block';
	document.getElementById(s + '.act').value = 'new';
	return false;
}

function GoEditSpecial(s)
{
	document.getElementById(s + '.txtEdit').style.display = 'block';
	document.getElementById(s + '.mnuView').style.display = 'none';
	document.getElementById(s + '.mnuSave').style.display = 'block';
	document.getElementById(s + '.act').value = 'special';
	return false;
}

function GoLink(s)
{
	document.getElementById(s + '.txtView').style.display = 'none';
	document.getElementById(s + '.txtLink').style.display = 'block';
	document.getElementById(s + '.mnuView').style.display = 'none';
	document.getElementById(s + '.mnuSave').style.display = 'block';
	document.getElementById(s + '.act').value = 'link';
	return false;
}

function GoLinkSpecial(s)
{
	document.getElementById(s + '.txtView').style.display = 'none';
	document.getElementById(s + '.txtLink').style.display = 'block';
	document.getElementById(s + '.mnuView').style.display = 'none';
	document.getElementById(s + '.mnuSave').style.display = 'block';
	document.getElementById(s + '.act').value = 'linkspecial';
	return false;
}


function GoCancel(s)
{
	document.getElementById(s + '.txtView').style.display = 'block';
	document.getElementById(s + '.txtNew').style.display = 'none';
	document.getElementById(s + '.txtEdit').style.display = 'none';
	document.getElementById(s + '.txtLink').style.display = 'none';
	document.getElementById(s + '.mnuView').style.display = 'block';
	document.getElementById(s + '.mnuSave').style.display = 'none';
	document.getElementById(s + '.act').value = '';
	return false;
}

function GoSave(s, cfm)
{
	if (cfm) {
		var frm = document[s];
		frm.submit();
	}
	return false;
}

function GoSaveSpecial(s, msg, cfm)
{
	if (cfm) {
		var frm = document[s];
		document.getElementById(s + '.act').value = msg;
		frm.submit();
	}
	return false;
}

function GoDelete(s, cfm)
{
	if (cfm) {
		var frm = document[s];
		document.getElementById(s + '.act').value = 'delete';
		frm.submit();
	}
	return false;
}

function GoDeleteRecord(s, id)
{
	if (confirm('Are you sure you want to delete this record?')) {
		var frm = document[s];
		document.getElementById(s + '.act').value = 'delete';
		document.getElementById(s + '.id').value = id;
		frm.submit();
	}
	return false;
}

function GoOldDeleteRecord(s, id)
{
	if (confirm('Are you sure you want to delete this record?')) {
		document.getElementById(s + '.act').value = 'delete';
		document.getElementById(s + '.id').value = id;
		frmMain.submit();
	}
	return false;
}

function GoEditRecord(s, id, url)
{
	document.getElementById(s + '.txtEdit').innerHTML = "Loading...";
	document.getElementById(s + '.txtEdit').style.display = 'block';
	document.getElementById(s + '.mnuView').style.display = 'none';
	document.getElementById(s + '.mnuSave').style.display = 'block';
	document.getElementById(s + '.act').value = 'edit';
	document.getElementById(s + '.id').value = id;
	document.frames(s + '.iframe').document.location = url;
	return false;
}

function GoShowEditRecord(s)
{
	var txt = document.frames(s + '.iframe').document.body.innerHTML;
	if (txt)
		document.getElementById(s + '.txtEdit').innerHTML = txt;
	return false;
}

function XMLLookup(s, cat)
{
    var xmlHttpReq = false;
    var self = this;
	var st = document.getElementById('lk_' + s + '_txtEdit').value;
	var query = "cat=" + cat + "&st=" + st;
	if (st) {
    	// IE
    	if (window.ActiveXObject) {
        	self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
    	}
    	// Mozilla/Safari
    	else if (window.XMLHttpRequest) {
        	self.xmlHttpReq = new XMLHttpRequest();
    	}
    	self.xmlHttpReq.open('POST', 'lookup.php', true);
    	self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    	self.xmlHttpReq.onreadystatechange = function() {
        	if (self.xmlHttpReq.readyState == 4) {
            	XMLShowLookupResult(s, self.xmlHttpReq.responseText);
        	}
    	}
    	self.xmlHttpReq.send(query);
		document.getElementById('lk_' + s + '_img').src = '/img/animload.gif';
	}
	return false;
}

function XMLShowLookupResult(s, txt)
{
	id = txt.substr(0, txt.indexOf("{}"));
	txt = txt.substr(txt.indexOf("{}") + 2);
	if (id == '*') {
		var out = '';
		while (txt) {
			id = txt.substr(0, txt.indexOf("{}"));
			txt = txt.substr(txt.indexOf("{}") + 2);
			value = txt.substr(0, txt.indexOf("{}"));
			JSvalue = JSQuotes(value);
			txt = txt.substr(txt.indexOf("{}") + 2);
			out += "<a href='' onClick=\"GoLookupSelect('" + s + "', '" + id +
					"', '" + JSvalue + "'); return false;\">" + value + "</a><br>";
		}
		document.getElementById(s + '.lk_view').innerHTML = out;
		document.getElementById(s + '.lk_view').style.display = 'block';
		document.getElementById(s + '.lk_edit').style.display = 'none';
	} else if (id) {
		GoLookupSelect(s, id, txt);
	} else {
		document.getElementById('lk_' + s + '_img').src = '/img/icon_x.gif';
	}
	return false;
}

function GoLookupSelect(s, id, value)
{
	document.getElementById(s).value = id;
	document.getElementById(s + '.lk_view').innerHTML = value +
		" <img src='/img/menu_edit.gif' alt='Edit' " +
		"onClick=\"GoEditLookup('" + s + "');\" style='cursor: hand;'>";
	document.getElementById(s + '.lk_view').style.display = 'block';
	document.getElementById(s + '.lk_edit').style.display = 'none';
	return false;
}

function GoEditLookup(s)
{
	document.getElementById(s).value = "";
	document.getElementById('lk_' + s + '_txtEdit').value = "";
	document.getElementById('lk_' + s + '_img').src = '/img/menu_check.gif';
	document.getElementById(s + '.lk_view').style.display = 'none';
	document.getElementById(s + '.lk_edit').style.display = 'block';
	return false;
}

function GoPrintView()
{
	var url = parent.content.document.location.href;
	if (url.indexOf("#") >= 0)
		url = url.substr(0, url.indexOf("#"));
	if (url.indexOf("?") >= 0)
		var sep = "&";
	else
		var sep = "?";
	parent.document.location.href = url + sep + "print=yes";
}

function EditMode()
{
	var result = false;
	for (var i = 0; i < frmMain.elements.length; i++) {
		var e = frmMain.elements[i];
		if ((e.name.indexOf('.status') >= 0) && (e.value != ''))
			result = true;
	}
	return result;
}

function SelectRow(chk)
{
	// select or deselect row
	if (chk.checked)
		SetTR(chk, "Select");
	else
		SetTR(chk, "");
}

function SelectAll(chkAll)
{
	var frm = chkAll;
	while (frm.tagName != "FORM")
		frm = frm.parentElement;
	for (var i = 0; i < frm.elements.length; i++) {
		var e = frm.elements[i];
		if ((e.name != chkAll.name) && (e.type == 'checkbox') && 
				(e.name.indexOf(chkAll.name) == 0)) {
			e.checked = chkAll.checked;
			if (e.checked)
				SetTR(e, "Select");
			else
				SetTR(e, "");
		}
	}
}

function SelectFirst(chkAll)
{
	var frm = chkAll;
	var val = true;
	while (frm.tagName != "FORM")
		frm = frm.parentElement;
	for (var i = 0; i < frm.elements.length; i++) {
		var e = frm.elements[i];
		if ((e.name != chkAll.name) && (e.type == 'checkbox') && 
				(e.name.indexOf(chkAll.name) == 0)) {
			e.checked = val;
			val = false;
			if (e.checked)
				SetTR(e, "Select");
			else
				SetTR(e, "");
		}
	}
}

function SetTD(e, cl)
{
	while (e.tagName != "TD")
		e = e.parentElement;
	e.className = cl;
}

function SetTR(e, cl)
{
	while (e.tagName != "TR")
		e = e.parentElement;
	e.className = cl;
}

function CheckTime(ctl)
{
	ctl.value = (ctl.value);
	return false;
}

function CheckPhone(ctl)
{
	ctl.value = (FormatPhone(ctl.value));
	return false;
}

function CheckAddress(ctl)
{
	ctl.value = (FormatAddress(ctl.value));
	return false;
}

function CheckEmail(ctl)
{
	if (validateEmail(ctl.value)) {
		ctl.value = (FormatEmail(ctl.value));
	} else {
		ctl.focus();
		ctl.select();
	}
	return false;
}

function CheckCurrency(ctl)
{
	ctl.value = (ctl.value);
	return false;
}

function CheckNumber(ctl, fmt)
{
	if (ctl.value) {
		ctl.value = formatNumber(ctl.value, fmt);
	}
	return false;
}

function FlagModified()
{
	// Indicate modified
	document.getElementById('Scores.txtLink').style.display = 'block';
}

function CheckGrade(ctl, max)
{
	// Initialize
	dat = ctl.value.toLowerCase();
	if ((dat == '') || (dat == '0')) return false;
	// check for Inc or Ex
	if (dat.indexOf('i') >= 0)
		dat = 'Inc';
	else if ((dat.indexOf('e') >= 0) || (dat.indexOf('x') >= 0))
		dat = 'Ex';
	else {
		// normalize to number
		dat = (Math.round(dat * 10) / 10);
		// Error checking
		if ((dat == '0') || (isNaN(dat)) || (dat < 0) || (dat > 1000)) {
			window.alert("Possible values: numeric, Inc (Incomplete) or Ex (Exempt).");
			dat = '';
			ctl.focus();
			ctl.select();
		} else if ((dat > max * 1.25) && (dat - max > 10)) {
			if (!confirm("This score is significantly more than the points possible for this " +
								"assignment.  Are you sure this score is correct?")) {
				ctl.focus();
				ctl.select();
			}
		}
	}
	// return result
	ctl.value = dat;
	return false;
}

function CheckDate(ctl)
{
	ctl.value = (FormatDate(ctl.value, 0, 0));
	return false;
}

function CheckMonth(ctl)
{
	ctl.value = (FormatDate(ctl.value, 1, 0));
	return false;
}

function CheckMonthDay(ctl)
{
	ctl.value = (FormatDate(ctl.value, 0, 1));
	return false;
}

function CheckTime(ctl)
{
	ctl.value = (FormatTime(ctl.value, 1));
	return false;
}

function FormatDate(dat, NoDay, NoYear)
{
var today = new Date();
if (dat.toLowerCase() == "today") {
	var dat = FormatDate(today.getDate() + "/" + (today.getMonth() + 1) + "/" + today.getFullYear());
}
// dimension
var strReturnDate;
dat = dat.toLowerCase();
var arrDate;
var arrMonths = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var sep;

// remove ordinals
dat = dat.replace(/st/gi, "");
dat = dat.replace(/nd/gi, "");
dat = dat.replace(/rd/gi, "");
dat = dat.replace(/th/gi, "");
dat = dat.replace(/,/gi, "");

// determine separator
if (dat.indexOf("/") > -1)
	sep = "/";
else if (dat.indexOf("-") > -1)
	sep = "-";
else if (dat.indexOf(".") > -1)
	sep = ".";
else if (dat.indexOf(" ") > -1)
	sep = " ";

// split into parts and clean up
arrDate = dat.split(sep);
dat = "";
for (var iSD = 0; iSD < arrDate.length; iSD++)
	if (arrDate[iSD] != "")
		dat += arrDate[iSD] + sep;
dat = dat.substring(0, dat.length - 1);
arrDate = dat.split(sep);

// check for less than 2 pieces of informaiton
if (arrDate.length < 2)
	return "";

var DAY = "";
var MONTH = "";
var YEAR = "";

// find textual month
for (var iSD = 0; iSD < arrMonths.length; iSD++) {
	var ShortMonth = arrMonths[iSD].substring(0, 3).toLowerCase();
	for (var iDat = 0; iDat < arrDate.length; iDat++) {
		if (arrDate[iDat].indexOf(ShortMonth) > -1) {
			MONTH = iSD + 1;
			// remove that element
			arrDate.splice(iDat, 1);
			break;
		}
	}
}

// find 4-digit year (and switch day/month if found)
for (var iDat = 0; iDat < arrDate.length; iDat++) {
	if (parseFloat(arrDate[iDat]) && arrDate[iDat].toString().length == 4) {
		YEAR = arrDate[iDat];
		arrDate.splice(iDat, 1);
		//arrDate.reverse();
	}
}

// find year (last number if not already)
if ((!YEAR) && (arrDate.length == 3 || (arrDate.length == 2 && (MONTH)) || NoDay)) {
	YEAR = arrDate.pop();
}

// find definitive day (number between 13 and 31)
for (var iDat = 0; iDat < arrDate.length; iDat++) {
	if (arrDate[iDat] > 12 && arrDate[iDat] < 32) {
		DAY = arrDate[iDat];
		arrDate.splice(iDat, 1);
	}
}

// get month (last number)
if ((!MONTH) && arrDate.length) {
	MONTH = arrDate.pop();
}

// get day (last number)
if ((!DAY) && arrDate.length) {
	DAY = arrDate.pop();
}

// get year (if missing, use current year)
if (!YEAR)
	YEAR = today.getYear();

// check for 2-digit year
var strTemp = YEAR.toString();
if (strTemp.length == 2)
	if (parseFloat(YEAR) > 70)
		YEAR = "19" + YEAR;
	else
		YEAR = "20" + YEAR;

// validate
if (isNaN(MONTH) || isNaN(DAY) || isNaN(YEAR) || MONTH < 1 || MONTH > 12 || (DAY < 1 && (!NoDay)) || DAY > 31 || YEAR < 1800)
	return "";

// return result
if (NoDay)
	return arrMonths[MONTH - 1].substring(0,3) + " " + YEAR;
else if (NoYear)
	return arrMonths[MONTH - 1].substring(0,3) + " " + parseFloat(DAY);
else
	return parseFloat(DAY) + "-" + arrMonths[MONTH - 1].substring(0,3) + "-" + YEAR;
}

function FormatTime(dat, NoSec)
{
var today = new Date();
if (dat.toLowerCase() == "now") {
	var dat = FormatDate(today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds());
}
// dimension
var strReturnTime;
dat = dat.toLowerCase();
var arrDate;
var sep;
var HOUR = "";
var MINUTE = "";
var SECOND = "";
var AMPM = "AM";

// determine separator
if (dat.indexOf(":") > -1)
	sep = ":";
else if (dat.indexOf(".") > -1)
	sep = ".";
else if (dat.indexOf(" ") > -1)
	sep = " ";

// find AM/PM
if (dat.indexOf("am") > -1) {
	dat = dat.substring(0, dat.indexOf("am")) + dat.substring(dat.indexOf("am") + 2);
} else if (dat.indexOf("pm") > -1) {
	AMPM = "PM";
	dat = dat.substring(0, dat.indexOf("pm")) + dat.substring(dat.indexOf("pm") + 2);
} else if (dat.indexOf("a.m.") > -1) {
	dat = dat.substring(0, dat.indexOf("a.m.")) + dat.substring(dat.indexOf("a.m.") + 4);
} else if (dat.indexOf("p.m.") > -1) {
	AMPM = "PM";
	dat = dat.substring(0, dat.indexOf("p.m.")) + dat.substring(dat.indexOf("p.m.") + 4);
}

// split into parts and clean up
arrDate = dat.split(sep);
dat = "";
for (var iSD = 0; iSD < arrDate.length; iSD++)
	if (arrDate[iSD] != "")
		dat += arrDate[iSD] + sep;
dat = dat.substring(0, dat.length - 1);
arrDate = dat.split(sep);

// check for less than 2 pieces of informaiton
if (arrDate.length < 2)
	return "";

// find hour
if ((!HOUR) && arrDate.length) {
	HOUR = arrDate[0];
	arrDate.splice(0, 1);
}

// check for included minute
if (HOUR.length > 2) {
	MINUTE = HOUR.substring(HOUR.length - 2);
	HOUR = HOUR.substring(0, HOUR.length - 2);
} else {
	MINUTE = arrDate[0];
	arrDate.splice(0, 1);
}

// find second
if ((!SECOND) && arrDate.length) {
	SECOND = arrDate[0];
	arrDate.splice(0, 1);
} else {
	SECOND = 0;
}

// check for military time
if (HOUR > 12) {
	AMPM = "PM";
	HOUR -= 12;
} else if (HOUR < 1) {
	AMPM = "AM";
	HOUR += 12;
}

// validate
if (isNaN(HOUR) || isNaN(MINUTE) || isNaN(SECOND) || HOUR < 1 || HOUR > 12 || MINUTE < 0 || MINUTE > 59 || SECOND < 0 || SECOND > 59)
	return "";

// return result
if (NoSec)
	return HOUR + ":" + formatNumber(MINUTE, "00") + " " + AMPM;
else
	return HOUR + ":" + formatNumber(MINUTE, "00") + " " + formatNumber(SECOND, "00") + " " + AMPM;
}

function FormatAddress(dat)
{
// dimension

// add one trailing space (makes search/replace easier later)
dat = " " + dat + " ";

// standard abbreviation
dat = dat.replace(/([0-9]) ?m(etro|t)r?s?\.? /gi, "$1m ");
dat = dat.replace(/([0-9]) ?c(uadra)s?\.? /gi, "$1c ");
dat = dat.replace(/([0-9]) ?v(aras|rs)?\.? /gi, "$1vs ");
dat = dat.replace(/ puente /gi, " Pte ");
dat = dat.replace(/ carretera /gi, " Carret ");
dat = dat.replace(/ mano izquierda /gi, " m/izq ");
dat = dat.replace(/ mano derecha /gi, " m/der ");

// remove space after #
dat = dat.replace(/# ([0-9])/g, "#$1");

// replace fractions
dat = dat.replace(/[ -]1\/4/g, String.fromCharCode(188));
dat = dat.replace(/[ -]1\/2/g, String.fromCharCode(189));
dat = dat.replace(/[ -]3\/4/g, String.fromCharCode(190));

// trim
dat = Trim(dat);

// return result
return dat;
}

function FormatPhone(dat)
{
// dimension

// add dash to 7-digit number, remove leading 0
dat = dat.replace(/0?([0-9]{2})-?([0-9]{1})-?([0-9]{4})/g, "$1$2-$3");

// return result
return dat;
}

function FormatEmail(dat)
{
	// change to lower case
	dat = dat.toLowerCase();
	// return result
	return dat;
}



// Copied from other places
  var separator = ",";  // use comma as 000's separator
  var decpoint = ".";  // use period as decimal point
  var percent = "%";
  var currency = "$";  // use dollar sign for currency

function formatNumber(number, format, print) {  // use: formatNumber(number, "format")
	if (print) document.write("formatNumber(" + number + ", \"" + format + "\")<br>");

	// parse format
	var useSeparator = format.indexOf(separator) != -1;  // use separators in number
	var usePercent = format.indexOf(percent) != -1;  // convert output to percentage
	var useCurrency = format.indexOf(currency) != -1;  // use currency format
	format = strip(format, separator + percent + currency);  // remove key characters

	// remove commas
	if (("" + number).indexOf(separator) != -1) {
		number = (strip("" + number, separator) - 0);  // remove commas
	}

	// handle percents
	if ((usePercent) && (("" + number).indexOf(percent) == -1) && (number > 1.05))
		number = number / 100;
	if (("" + number).indexOf(percent) != -1) {
		number = ((strip(number, percent) - 0) / 100);  // remove percent
	}
	if (usePercent) number *= 100;

	// handle negatives
	var isNegative = (number < 0);
	number = Math.abs (number - 0);

	// clean up number
	if (isNaN(number)) number = 0;//return '';
	number = strip("" + number, separator + percent + currency);  // remove key characters
	number = "" + number;  // convert number input to string

	// split input value into LHS and RHS using decpoint as divider
	var dec = number.indexOf(decpoint) != -1;
	var nleftEnd = (dec) ? number.substring(0, number.indexOf(".")) : number;
	var nrightEnd = (dec) ? number.substring(number.indexOf(".") + 1) : "";

	// split format string into LHS and RHS using decpoint as divider
	dec = format.indexOf(decpoint) != -1;
	var sleftEnd = (dec) ? format.substring(0, format.indexOf(".")) : format;
	var srightEnd = (dec) ? format.substring(format.indexOf(".") + 1) : "";

	// adjust decimal places by cropping or adding zeros to LHS of number
	if (srightEnd.length < nrightEnd.length) {
		var nextChar = nrightEnd.charAt(srightEnd.length) - 0;
		nrightEnd = nrightEnd.substring(0, srightEnd.length);
		if (nextChar >= 5) nrightEnd = "" + ((nrightEnd - 0) + 1);  // round up

 		// patch provided by Patti Marcoux 1999/08/06
		while (srightEnd.length > nrightEnd.length) {
			nrightEnd = "0" + nrightEnd;
		}

		if (srightEnd.length < nrightEnd.length) {
			nrightEnd = nrightEnd.substring(1);
			nleftEnd = (nleftEnd - 0) + 1;
		}
	} else {
		for (var i=nrightEnd.length; srightEnd.length > nrightEnd.length; i++) {
			if (srightEnd.charAt(i) == "0") nrightEnd += "0";  // append zero to RHS
			else break;
		}
	}

	// adjust leading zeros
	sleftEnd = strip(sleftEnd, "#");  // remove hashes from LHS of format
	while (sleftEnd.length > nleftEnd.length) {
		nleftEnd = "0" + nleftEnd;  // prepend zero to LHS of number
	}

	if (useSeparator) nleftEnd = separate(nleftEnd, separator);  // add separator
	var output = nleftEnd + ((nrightEnd != "") ? "." + nrightEnd : "");  // combine parts
	output = ((useCurrency) ? currency : "") + output + ((usePercent) ? percent : "");
	if (isNegative) {
		// patch suggested by Tom Denn 25/4/2001
		output = (useCurrency) ? "(" + output + ")" : "-" + output;
	}

	return output;
}

function strip(input, chars) {  // strip all characters in 'chars' from input
	var output = "";  // initialise output string
	for (var i=0; i < input.length; i++)
		if (chars.indexOf(input.charAt(i)) == -1)
			output += input.charAt(i);
	return output;
}

function separate(input, separator) {  // format input using 'separator' to mark 000's
	input = "" + input;
	var output = "";  // initialise output string
	for (var i=0; i < input.length; i++) {
		if (i != 0 && (input.length - i) % 3 == 0) output += separator;
			output += input.charAt(i);
	}
	return output;
}

function validateEmail(addr) {
	// allow blank e-mail address
	if (addr == '') return true;

	// check for invalid characters
	var invalidChars = '\/\'\\ ";:?!()[]\{\}^|';
	for (i = 0; i < invalidChars.length; i++) {
		if (addr.indexOf(invalidChars.charAt(i), 0) > -1) {
			alert('E-mail address contains invalid characters.');
      		return false;
   		}
	}
	for (i = 0; i < addr.length; i++) {
		if (addr.charCodeAt(i) > 127) {
			alert("E-mail address contains invalid characters.");
			return false;
		}
	}

	// make sure that it contains @ in proper format
	var atPos = addr.indexOf('@', 0);
	if (atPos == -1) {
		alert('E-mail address must contain an @.');
		return false;
	}
	if (atPos == 0) {
		alert('E-mail address must not start with @.');
		return false;
	}
	if (addr.indexOf('@', atPos + 1) > - 1) {
		alert('E-mail address may contain only one @.');
		return false;
	}
	if (addr.indexOf('.', atPos) == -1) {
		alert('E-mail address must contain a period in the domain name.');
		return false;
	}
	if (addr.indexOf('@.', 0) != -1) {
		alert('Period must not immediately follow @ in e-mail address.');
		return false;
	}
	if (addr.indexOf('.@', 0) != -1) {
		alert('Period must not immediately precede @ in e-mail address.');
		return false;
	}
	if (addr.indexOf('..',0) != -1) {
		alert('Two periods must not be adjacent in e-mail address.');
		return false;
	}

	// passed test
	return true;
}
