// This file is included into the HEAD section of each generated HTML document.
// It is written in JavaScript.
// It includes some inline code for sensing the browser type
// plus some useful functions.

// --- The inline sniffer code ---
var agt      = navigator.userAgent.toLowerCase(); 
var appVer   = navigator.appVersion.toLowerCase();
var isMINOR  = parseFloat(appVer); 
var isMAJOR  = parseInt(isMINOR); 

// For IE get isMINOR from further in the string
var isMac    = (agt.indexOf('mac') != -1);
var iePos    = appVer.indexOf('msie');
if (iePos != -1) {
   if(isMac) {
      var iePos = agt.indexOf('msie');
      isMINOR   = parseFloat(agt.substring(iePos + 5, agt.indexOf(';', iePos)));
   }
   else
      isMINOR   = parseFloat(appVer.substring(iePos + 5, appVer.indexOf(';', iePos)));
   isMAJOR      = parseInt(isMINOR);
}
// Same for Konqueror
var kqPos    = agt.indexOf('konqueror');
if (kqPos != -1) {                 
   isMINOR   = parseFloat(agt.substring(kqPos + 10, agt.indexOf(';', kqPos)));
   isMAJOR   = parseInt(isMINOR);
}
                                 
var isSafari = ((agt.indexOf('safari')!= -1) && (agt.indexOf('mac') != -1)) ? true : false;
var isKonq   = (agt.indexOf('konqueror') != -1);
var isKhtml  = (isSafari || isKonq);
var isGecko  = ((!isKhtml) && (navigator.product) && (navigator.product.toLowerCase() == "gecko")) ? true : false;
var isMoz    = ((agt.indexOf('mozilla/5') != -1) && (agt.indexOf('spoofer') == -1) &&
                (agt.indexOf('compatible') == -1) && (agt.indexOf('opera') == -1)  &&
                (agt.indexOf('webtv') == -1) && (agt.indexOf('hotjava') == -1)     &&
                (isGecko) && 
                ((navigator.vendor == '') || (navigator.vendor == 'Mozilla') || (navigator.vendor == 'Debian')));
var isFb     = ((agt.indexOf('mozilla/5') != -1) && (agt.indexOf('spoofer') == -1) &&
                (agt.indexOf('compatible') == -1) && (agt.indexOf('opera') == -1)  &&
                (agt.indexOf('webtv') == -1) && (agt.indexOf('hotjava') == -1)     &&
                (isGecko) && (navigator.vendor == "Firebird"));
var isFx     = ((agt.indexOf('mozilla/5') != -1) && (agt.indexOf('spoofer') == -1) &&
                (agt.indexOf('compatible') == -1) && (agt.indexOf('opera' )== -1)  &&
                (agt.indexOf('webtv') == -1) && (agt.indexOf('hotjava') == -1)     &&
                (isGecko) && (navigator.vendor == "Firefox"));

var isOpera  = (agt.indexOf('opera') != -1);
var isOpera2 = (agt.indexOf('opera 2') != -1 || agt.indexOf('opera/2') != -1);
var isOpera3 = (agt.indexOf('opera 3') != -1 || agt.indexOf('opera/3') != -1);
var isOpera4 = (agt.indexOf('opera 4') != -1 || agt.indexOf('opera/4') != -1);
var isOpera5 = (agt.indexOf('opera 5') != -1 || agt.indexOf('opera/5') != -1);
var isOpera6 = (agt.indexOf('opera 6') != -1 || agt.indexOf('opera/6') != -1);
var isOpera7 = (agt.indexOf('opera 7') != -1 || agt.indexOf('opera/7') != -1);
var isOpera5up = (isOpera && !isOpera2 && !isOpera3 && !isOpera4);
var isOpera6up = (isOpera && !isOpera2 && !isOpera3 && !isOpera4 && !isOpera5);
var isOpera7up = (isOpera && !isOpera2 && !isOpera3 && !isOpera4 && !isOpera5 && !isOpera6);

var isNN     = ((agt.indexOf('mozilla') != -1) && (agt.indexOf('spoofer') == -1) 
             && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera') == -1)
             && (agt.indexOf('webtv') == -1) && (agt.indexOf('hotjava') == -1)
             && (!isKhtml) && (!(isMoz)) && (!isFb) && (!isFx));
if ((navigator.vendor) &&
    ((navigator.vendor == "Netscape6") || (navigator.vendor == "Netscape")) &&
    (isNN)) {
   isMAJOR   = parseInt(navigator.vendorSub);
   isMINOR   = parseFloat(navigator.vendorSub);
}
var isNN2    = (isNN && isMAJOR == 2);
var isNN4    = (isNN && isMAJOR == 4); 
var isNN4up  = (isNN && isMINOR >= 4);
var isNNonly = (isNN && ((agt.indexOf(';nav') != -1) || (agt.indexOf('; nav') != -1)));
var isNN6    = (isNN && isMAJOR == 6); 
var isNN6up  = (isNN && isMINOR >= 6);
var isNN5    = (isNN && isMAJOR == 5 && !isNN6);
var isNN5up  = (isNN && isMINOR >= 5);
var isNN7    = (isNN && isMAJOR == 7); 
var isNN7up  = (isNN && isMINOR >= 7);
 
var isMS     = ((iePos != -1) && (!isOpera) && (!isKhtml));
var isMS3    = (isMS && isMAJOR < 4);
var isMS4    = (isMS && isMAJOR == 4); 
var isMS4up  = (isMS && isMINOR >= 4); 
var isMS5    = (isMS && isMAJOR == 5); 
var isMS5up  = (isMS && isMINOR >= 5); 
var isMS55   = (isMS && (agt.indexOf('msie 5.5') != -1));
var isMS55up = (isMS && isMINOR >= 5.5); 
var isMS6    = (isMS && isMAJOR == 6);
var isMS6up  = (isMS && isMINOR >= 6); 
var isAol    = (agt.indexOf("aol") != -1); 
var isWebtv  = (agt.indexOf("webtv") != -1);
var isTVNavigator = ((agt.indexOf("navio") != -1) || (agt.indexOf("navio_aoltv") != -1)); 
var isAOLTV       = isTVNavigator;
var isHotjava     = (agt.indexOf("hotjava") != -1);
var isHotjava3    = (isHotjava && isMAJOR == 3);
var isHotjava3up  = (isHotjava && isMAJOR >= 3);
//=======================================================

// -- The functions
//------------------------------------------------------------------------------
function ObjectDiv(idName, od)
{
	var p, i, x, d = document;
	if (!od)
		od = d;
	if ((p = idName.indexOf('?')) > 0 && parent.frames.length)
	{
		od = parent.frames[idName.substring(p + 1)].document;
		idName = idName.substring(0, p);
	}
	if (!(x = od[idName]) && d.all)
		x = od.all[idName];
	if (!x && d.getElementById)
		x = d.getElementById(idName);
	for (i=0; !x && i < od.forms.length; i++)
		x = od.forms[i][idName];
	for (i=0; !x && od.layers && i < od.layers.length; i++)
		x = ObjectDiv(idName, od.layers[i].document);
	return x;
}
//------------------------------------------------------------------------------
function ObjectStyle(idName, nestName)
{
	var oReference;
	oReference = ObjectDiv(idName);
	if (!oReference)
		return false;
	if (oReference.style)
		oReference = oReference.style;
	return oReference;
}
//------------------------------------------------------------------------------
function ObjectForm(formName, nestName)
{
	var formObj;
	if (isMS)
		eval('formObj = document.' + formName);
	else if (isNN)
	{
		if (nestName)
			eval('formObj = document.' + nestName + '.document.' + formName);
		else
			eval('formObj = document.' + formName);
	}
	else
		eval('formObj = document.' + formName);
	return formObj;
}
//------------------------------------------------------------------------------
	function getInt(n)
	{
		n = parseInt(n);
		if (isNaN(n)) n = 0;
		return n;
	}
	
function GetImgLocation(imgPrefix)
{
	// Get the top left for the image
	var d = document;
	var obj = d.images[imgPrefix + 'Img'];
	var oImg = obj;
	var nHeight = obj.offsetHeight || obj.height;
	var nLeft = 0, nTop = 0;
	
	if (d.all && !isKonq)
	{
		var seenTable = 0;
		var noCpos = {'BODY' : 1, 'TABLE' : 1};
		var noOpos = {};
		if (!isOpera) noOpos['A'] = -1;
		if (isMac && !isOpera)
		{
			noOpos = noCpos;
			noCpos = {'DIV' : 1, 'TD' : 1, 'TH' : 1};
		}
		if (isMac && oImg.offsetParent.tagName == 'BODY')
		{
			if (getInt(oImg.clientLeft) + getInt(oImg.clientTop))
			{
				nLeft = oImg.clientLeft;
				nTop  = oImg.clientTop;
			}
			else
			{
				nLeft = oImg.offsetLeft;
				nTop  = oImg.offsetTop;
			}
			eval(imgPrefix + 'Left = nLeft + 1');
			eval(imgPreFix + 'Top  = nTop + nHeight + 1');
			return;
		}
		for (; obj; obj = obj.offsetParent)
		{
			var tag = obj.tagName;
			var noEnt = noCpos[tag];
			if (!noEnt && (!isMac || obj != oImg) && !isOpera)
			{
				nLeft += getInt(obj.clientLeft);
				nTop  += getInt(obj.clientTop);
			}
			var noEnt = noOpos[tag];
			if (!noEnt || (noEnt < 0 && obj.currentStyle && obj.currentStyle.display != 'block'))
			{
				nLeft += getInt(obj.offsetLeft);
				nTop  += getInt(obj.offsetTop);
			}
			if (isMac && tag == 'TABLE')
				if (seenTable++)
					nTop += getInt(obj.cellSpacing);
		}
	}
	else if (d.getElementById)
	{
		for (; obj; obj = obj.offsetParent)
		{
			if (obj.tagName == 'TABLE')
			{
				var bord = parseInt(obj.border);
				if (isNaN(bord))
				{
					if (obj.getAttribute('frame'))
					{
						++nLeft;
						++nTop;
					}
				}
				else if (bord > 0)
				{
					nLeft += bord;
					nTop  += bord;
				}
			}
			nLeft += obj.offsetLeft;
			nTop  += obj.offsetTop;
		}
	}
	else
	{
		nLeft = obj.x;
		nTop  = obj.y;
	}
	eval(imgPrefix + 'Left = nLeft');
	eval(imgPrefix + 'Top  = nTop');
} // GetImgLocation
//------------------------------------------------------------------------------
function isVisible(idName, nestName)
{
	var oStyle = ObjectStyle(idName, nestName);
	if (!oStyle) return false;
	var vis = oStyle.visibility;
	return (vis != 'hidden' && vis != 'hide');
}
//------------------------------------------------------------------------------
function ShowObject(idName, nestName)
{
	var oStyle = ObjectStyle(idName, nestName);
	if (oStyle)
		oStyle.visibility = (isNN4)? 'show' : 'visible';
}
//------------------------------------------------------------------------------
function HideObject(idName, nestName)
{
	var oStyle = ObjectStyle(idName, nestName);
	if (oStyle)
		oStyle.visibility = (isNN4)? 'hide' :'hidden';
}
//------------------------------------------------------------------------------
function WriteInnerHTML(idName, nestName, str)
{
	var x, lyr;
	var d = document;
	if (d.getElementById)
	{
		x = d.getElementById(idName);
		x.innerHTML = '';
		x.innerHTML = str;
	}
	else if (d.all)
	{
		x = d.all[idName];
		x.innerHTML = str;
	}
	else if (d.layers)
	{
		lyr = 'document.layers["' + idName + '"].document';
		if (nestName)
			lyr = 'document.' + nestName + '.' + lyr;
		eval('x = ' + lyr);
		x.open();
		x.write(str);
		x.close();
	}
}
//------------------------------------------------------------------------------
function ResizeFix()
{
	if (widthCheck != window.innerWidth || heightCheck != window.innerHeight)
		document.location.href = document.location.href;
} // ResizeFix
//------------------------------------------------------------------------------
function ReplaceImage(idName, img)
{
	// assumes the IMG with name idName is contained in a DIV with ID idName+"ID"
	if (isNN)
		document.layers[idName+"ID"].document.images[0].src = eval(img + ".src");
	else if (isMS)
		document.all   [idName     ]                   .src = eval(img + ".src");
} // ReplaceImage
//------------------------------------------------------------------------------
function SaveListState(list,optionsField,valuesField,selectionField)
{
	// Save contents of a list box as option string for regenerating form
	//	and also as plain values for persisting as session data.
	// Also save the values associated with the selection.
	var s1 = "";
	var s2 = "";
	var s3 = "";
	for(i=0; i<list.length; i++)
	{
		if (list.options[i].value == "<filler>")
			continue;	// ignore the ____ lines
		if (optionsField)
		{
			s1 += '<option value="' + XFUNC_ConvertToHTMLString(list.options[i].value) + '"';
			if (list.options[i].selected)
				s1 += ' selected';
			s1 += '>';
			s1 += XFUNC_ConvertToHTMLString(list.options[i].text)+'\n';
		}
		if (valuesField)
		{
			if (s2)
				s2 += ",";
			s2 += list.options[i].value;
		}
		if (selectionField)
		{
			if (list.options[i].selected)
			{
				if (s3)
					s3 += ",";
				s3 += list.options[i].value;	// assume no commas inside values (usually numeric IDs)
			}
		}
	}
	if (optionsField)
		optionsField  .value = s1;
	if (valuesField)
		valuesField   .value = s2;
	if (selectionField)
		selectionField.value = s3;
		
} // SaveListState
//------------------------------------------------------------------------------
function ConvertToHTMLString(s) // DEPRECATED
{
	return XFUNC_ConvertToHTMLString(s);
} // ConvertToHTMLString
//------------------------------------------------------------------------------
function XFUNC_ConvertToHTMLString(s)
{
	// Equiv to Server.HTMLEncode()
	var s1 = s;
	s1 = s1.replace(/\&/g, "&amp;");	// must be first
	s1 = s1.replace(/\"/g, "&quot;");
	s1 = s1.replace(/\</g, "&lt;");
	s1 = s1.replace(/\>/g, "&gt;");
	s1 = s1.replace(/\'/g, "&#39;");
	return s1;
} // XFUNC_ConvertToHTMLString
//------------------------------------------------------------------------------
function ConvertFromHTMLEncode(s) // DEPRECATED
{
	return XFUNC_ConvertFromHTMLEncode(s);
} // ConvertFromHTMLEncode(s)
//------------------------------------------------------------------------------
function XFUNC_ConvertFromHTMLEncode(s)
{
	var s1 = s;
	s1 = s1.replace(/\&#39;/g	, "\'");
	s1 = s1.replace(/\&quot;/g	, "\"");
	s1 = s1.replace(/\&lt;/g	, "<");
	s1 = s1.replace(/\&gt;/g	, ">");
	s1 = s1.replace(/\&amp;/g	, "\&"); // must be last
	return s1;
} // XFUNC_ConvertFromHTMLEncode
//------------------------------------------------------------------------------
function GetRadioValue(radioGroup)
{
	if (radioGroup.length)
	{
		for (var i = 0; i < radioGroup.length; i++)
			if (radioGroup[i].checked)
				return radioGroup[i].value;
	}
	else
	{
		// radio group with only one element has no length
		if (radioGroup.checked)
			return radioGroup.value;		
	}
	return "";
} // getRadioValue
//------------------------------------------------------------------------------
function XFUNC_IsNumber(num)
{
	// Returns true if string is acceptable as input to parseFloat.
	// Number can be +ve or -ve, with optional dec pt
	var val = num.toString();
	if (val.length == 0)
		return false;
	var i, bDotSeen = false, bDigitSeen = false;
	for (i=0; i < val.length; i++)
	{
		c = val.charAt(i);
		if (c == '-')
			if (i == 0)
				continue;
		if (c == '.')
		{
			if (bDotSeen)
				return false;
			else
			{
				bDotSeen = true;
				continue;
			}
		}
		if ((c < '0') || (c > '9'))
			return false;
		bDigitSeen = true;
	}
	return bDigitSeen;
} // XFUNC_IsNumber
//------------------------------------------------------------------------------
function XFUNC_Format (Val, sFormat)
{
   // Negative number were being formatted like: -,300
   // (extraneous comma)
   var isNegative = (Val < 0);
   if (isNegative == true)
   {
      Val *= -1;
   }


	var Units;var Decimals;var UnitFmt;var DecFmt;var i;var iUpper;
	sFormat=''+sFormat;
	switch (sFormat.toUpperCase()) {
		case 'UNDEFINED':
		case '':sFormat='###,###,###,##0';break;
		case 'CURRENCY':sFormat='$###,###,###,##0.00';break;
		case 'PERCENT':Val=100*Val;sFormat='%##0.00';break;
		default:
	}
	if (sFormat.indexOf ('.', 0)!=-1) {
		UnitFmt = sFormat.substring(0, sFormat.indexOf ('.', 0));
		DecFmt = sFormat.substring(sFormat.indexOf ('.', 0)+1, sFormat.length);
	} else {
		Val=Math.round(Val);UnitFmt = sFormat;DecFmt = '';
	}
	Val=''+Val;
	if (Val.indexOf ('.', 0)!=-1) {
		Units = Val.substring(0, Val.indexOf ('.', 0));Decimals = Val.substring(Val.indexOf ('.', 0)+1, Val.length);
	} else {
		Units = Val;Decimals = '';
	}
	var sHead=UnitFmt.slice(0,1);
	switch (sHead) {
		case '0':
		case '#':sHead='';break;
		default:UnitFmt=UnitFmt.slice(1);
	}
	var fmtLeft = '################################';
	if (Units.length > UnitFmt.length) {
		for (i=UnitFmt.length;i<Units.length;i++){
			UnitFmt='#' + UnitFmt;
		}
	} else {
		fmtLeft=fmtLeft + UnitFmt.slice(0,UnitFmt.length-Units.length);UnitFmt=UnitFmt.slice(UnitFmt.length-Units.length);
	}
	var OutString='';
	var num;
	var fmt;
	if (Units.length==0) {
		for (i=UnitFmt.length-1;i>-1;i--){
			if (UnitFmt.slice(i,i+1)!='#') {
				OutString=UnitFmt.slice(i,i+1) + OutString;
			} else {
				break;
			}
		}
	} else {
		for (i=Units.length-1;i>-1;i--){
			num=Units.slice(i,i+1);fmt=UnitFmt.slice(i,i+1);
			switch (fmt) {
				case '#':
				case '0':OutString=num + OutString;break;
				default:
					UnitFmt=fmtLeft.slice(fmtLeft.length-1) + UnitFmt;fmtLeft=fmtLeft.slice(0,fmtLeft.length-1);
					OutString=fmt + OutString;i++;
			}
		}
	Filler:
		for (i=fmtLeft.length-1;i>-1;i--){
			switch (fmtLeft.slice(i,i+1)) {
				case '#':
				case ',':break Filler;
				default:OutString = fmtLeft.slice(i, i + 1) + OutString
			}
		}
	}
	switch (sHead) {
		case '#':break;
		default:OutString=sHead + OutString;
	}
	if (DecFmt.length!=0) {
		OutString=OutString+'.';
		for (i=0;i<DecFmt.length;i++){
			num=Decimals.slice(i,i+1);fmt=DecFmt.slice(i,i+1);
			switch (fmt) {
				case '0':
					if (num.length==0) {OutString= OutString+'0';}
				case '#':OutString= OutString+num;break;
				default:
			}
		}
	}
	
	if (isNegative == true)
	{
	   OutString = '-' + OutString;
	}
	
	return OutString;
} // XFUNC_Format
//------------------------------------------------------------------------------
function XFUNC_Trim(str)
{
	var len = str.length;
	for (start=0; start < len    && str.charAt(start) == ' '; start++);
	for (end=len-1; end >= start && str.charAt(end  ) == ' '; end--);
	newStr = new String(str.substring(start, end+1));
	return newStr;
} // XFUNC_Trim
//------------------------------------------------------------------------------
function XFUNC_SelectOptionByValue(selectObject, val)
{
	var iSel = 0;	// default to first
	for (var i=0; i < selectObject.options.length; i++)
	{
		if (selectObject.options[i].value == val)
		{
			iSel = i;
			break;
		}
	}
	if (iSel < selectObject.options.length)
		selectObject.options.selectedIndex = iSel;
} // XFUNC_SelectOptionByValue
//------------------------------------------------------------------------------
function XFUNC_GetSelectedIndexList(selObj)
{
	var retVal = '';	// default to blank string
	for (var i=0; i<selObj.length; i++)
	{
		if (selObj.options[i].selected)
		{
			if (retVal.length > 0)
				retVal += ',';
			retVal += ''+i;
		}
	}
	return retVal;
}	// XFUNC_GetSelectedIndexList
//------------------------------------------------------------------------------
function XFUNC_GetSelectedOptionsList(selObj)
{
	var retVal = '';	// default to blank string
	for (var i=0; i<selObj.length; i++)
	{
		if (selObj.options[i].selected)
		{
			if (retVal.length > 0)
				retVal += ',';
			retVal += selObj.options[i].value;
		}
	}
	return retVal;
}	// XFUNC_GetSelectedOptionsList
//------------------------------------------------------------------------------
function XFUNC_IsValidNumber(num, decimalPt)
{
	// Returns true if string is acceptable as input to parseFloat.
	// Number can be +ve or -ve, with optional one decimal symbol
	// Decimal symbol is provided so it is internationally-aware
	var val = num.toString();
	if (val.length == 0)
		return false;
	var i, bDecimalSeen = false, bDigitSeen = false;
	for (i=0; i < val.length; i++)
	{
		c = val.charAt(i);
		if (c == '-')
			if (i == 0)
				continue;
		if (c == decimalPt)
		{
			if (bDecimalSeen)
				return false;
			else
			{
				bDecimalSeen = true;
				continue;
			}
		}
		if ((c < '0') || (c > '9'))
			return false;
		bDigitSeen = true;
	}
	return bDigitSeen;
} // XFUNC_IsValidNumber
//------------------------------------------------------------------------------
function XFUNC_NumericValue(str, decimalPt) 
{
	// Returns the numeric equivalent of a formatted number string.
	// replace the decimal symbol with decimal point recognized in javascript
	var val = str.toString();
	var re = eval("/["+decimalPt+"]/");
	var ret = val.replace(re, ".");
	return ret;
} // XFUNC_NumericValue
//------------------------------------------------------------------------------
function XFUNC_CurrencyValue(str, decimalPt)
{
	// Returns the numeric equivalent of a formatted number string.
	// replace the decimal symbol with decimal point recognized in javascript
	var val = str.toString();
	var re1 = eval("/[^0-9"+decimalPt+"]/g");
	val = val.replace(re1, "");
	
	var re2 = eval("/["+decimalPt+"]/");
	return val.replace(re2, ".");
} // XFUNC_NumericValue
//------------------------------------------------------------------------------
function XFUNC_FormatValue(num, sCurrency, sGrouping, sDecimal, iDigits)
{
	// DS: This function is too full of tricky code that I dare not rewrite.
	
	var sign = (num == (num = Math.abs(num)));
	
	// determine fraction part
	var frac = '';
	var strDec = '';
	var numDigits = 1;
	if	(iDigits > 0)
	{
		numDigits = Math.pow(10, iDigits);
		num = Math.floor(num*numDigits+0.50000000001);
		frac = num%numDigits;
		var len = frac.toString().length;
		if	(len < iDigits)
		{
			for	(var ix = 0; ix < (iDigits - len); ix++)
				frac = "0" + frac.toString();
		}
		strDec = sDecimal;
	}
		
	num = Math.floor(num/numDigits).toString();
	for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
	num = num.substring(0,num.length-(4*i+3))+sGrouping+num.substring(num.length-(4*i+3));
	
	return (((sign)?'':'-') + sCurrency + num + strDec + frac);
}
//------------------------------------------------------------------------------
function XFUNC_RoundValue(num, decimalDigits)
{
	// Returns the value rounded to the decimalDigits.
	return (Math.round(num*Math.pow(10,decimalDigits)))/Math.pow(10,decimalDigits)
} // XFUNC_RoundValue
//------------------------------------------------------------------------------
function XFUNC_IsValidInteger(num)
{
	// Returns true if string is acceptable as input to parseInt.
	var val = num.toString();
	if (val.length == 0)
		return false;
	var i, bDigitSeen = false;
	for (i=0; i < val.length; i++)
	{
		c = val.charAt(i);
		if (c == '-')
			if (i == 0)
				continue;
		if ((c < '0') || (c > '9'))
			return false;
	}
	return true;
} // XFUNC_IsValidInteger
//------------------------------------------------------------------------------
function XFUNC_IsValidEmail(emailStr)
{
	// The following variable tells the rest of the function whether or not
	// to verify that the address ends in a two-letter country or well-known
	// TLD.  1 means check it, 0 means don't.
	var checkTLD=0;

	// The following is the list of known TLDs that an e-mail address must end with.
	var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;

	// The following pattern is used to check if the entered e-mail address
	// fits the user@domain format.  It also is used to separate the username
	// from the domain.
	var emailPat=/^(.+)@(.+)$/;

	// The following string represents the pattern for matching all special
	// characters.  We don't want to allow special characters in the address. 
	// These characters include ( ) < > @ , ; : \ " . [ ]
	var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";

	// The following string represents the range of characters allowed in a 
	// username or domainname.  It really states which chars aren't allowed.
	var validChars="\[^\\s" + specialChars + "\]";

	// The following pattern applies if the "user" is a quoted string (in
	// which case, there are no rules about which characters are allowed
	// and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
	// is a legal e-mail address.
	var quotedUser="(\"[^\"]*\")";

	// The following pattern applies for domains that are IP addresses,
	// rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
	// e-mail address. NOTE: The square brackets are required.
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;

	// The following string represents an atom (basically a series of non-special characters.)
	var atom=validChars + '+';

	// The following string represents one word in the typical username.
	// For example, in john.doe@somewhere.com, john and doe are words.
	// Basically, a word is either an atom or quoted string.
	var word="(" + atom + "|" + quotedUser + ")";

	// The following pattern describes the structure of the user
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$");

	// The following pattern describes the structure of a normal symbolic
	// domain, as opposed to ipDomainPat, shown above.
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");

	// Break up string into user@domain
	var matchArray=emailStr.match(emailPat);
	if (matchArray==null)
	{
		return false;
	}

	var user=matchArray[1];
	var domain=matchArray[2];

	// Check that only basic ASCII characters are in the strings (0-127).
	for (i=0; i<user.length; i++)
	{
		if (user.charCodeAt(i)>127)
		{
			return false;
		}
	}
	
	for (i=0; i<domain.length; i++)
	{
		if (domain.charCodeAt(i)>127)
		{
			return false;
	   }
	}

	// Check if "user" portion is valid 
	if (user.match(userPat)==null)
	{
		return false;
	}

	// Check if "domain" portion is an IP address as opposed to a symbolic host name.
	var IPArray=domain.match(ipDomainPat);
	// "domain" portion is IP address, check if valid
	if (IPArray!=null)	
	{
		for (var i=1;i<=4;i++)
		{
			if (parseInt(IPArray[i])>255)
			{
				return false;
		   }
		}
		return true;
	}

	// "domain" portion is symbolic name, check if valid
	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)
		{
			return false;
	   }
	}

	// domain name seems valid, but now make sure that it ends in a
	// known top-level domain (like com, edu, gov) or a two-letter word,
	// representing country (uk, nl), and that there's a hostname preceding 
	// the domain or country.
	if (checkTLD && domArr[domArr.length-1].length!=2 && domArr[domArr.length-1].search(knownDomsPat)==-1)
	{
		return false;
	}

	// Make sure there's a host name preceding the domain.
	if (len<2)
	{
		return false;
	}

	// Everything's valid, at this point
	return true;
} // XFUNC_IsValidEmail
//------------------------------------------------------------------------------
function XFUNC_ResizeDialog(win,width,height)
{
	var leftX = ((screen.width  - width ) / 2);
	var topY  = ((screen.height - height) / 2);
	win.moveTo  (leftX, topY);
	win.resizeTo(width, height);
} // XFUNC_ResizeDialog
//-------------------------------------------------------------------------------
function XFUNC_SelectRadioOptionByValue(radioName, val)
{
	var a = document.getElementsByTagName("input");
	for (var i=0; i<a.length; i++)
	{
		var e = a[i];
		if (e.type == "radio" && e.name == radioName)
			e.checked = (e.value == val);
	}
} // XFUNC_SelectRadioOptionByValue
//------------------------------------------------------------------------------
function XFUNC_GetSerializedArrayMember(strArray, sep, index)
{
	// index is 1-origin
	if (strArray.length == 0) return "";
	var arr = strArray.split(sep);
	if (index > arr.length) return "";
	return arr[index-1];
} // XFUNC_GetSerializedArrayMember
//------------------------------------------------------------------------------
function XFUNC_PageTransitionEffect(iOpt)
{
	// iOpt reserved for future use

	var s;
	s = "<center>";
	s += '<table border="0" width="100%" height="100%" bgcolor="white">';
	s += '<tr><td valign="middle" align="center">';
	s += '<table border="0">';
	s += '<tr><td valign="middle" align="center">';
	// image is relative to 1033 directory
	s += '<img src="../images/spinner.gif" border="0" height="140" width="140&quot;/"><br><br>';
	s += PAG_TRANSITION_HTML;	// defined in incGlobalStrings.js	
	s += '</td></tr>';
	s += '</table></td></tr></table></center>';


	if (document.frmMain)
		document.frmMain.innerHTML = s; 
	else
		document.body.innerHTML = s;
} // XFUNC_PageTransitionEffect
//-------------------------------------------------------------------------------
function XFUNC_Left(s, n)
{
	return s.substr(0, n);
} // XFUNC_Left
//------------------------------------------------------------------------------
function XFUNC_Right(s, n)
{
	return (s.length <= n) ? s : s.substr(s.length-n);
} // XFUNC_Right
//------------------------------------------------------------------------------
function XFUNC_CDATAEncode(s)
{
	return '<![CDATA[' + s + ']]>';
} // XFUNC_CDATAEncode
//------------------------------------------------------------------------------
function XFUNC_QuoteString(str, q)
{
	var r = new RegExp("\\" + q, "g"); // works on ' and "
	return (q + str.replace(r, q+q) + q);
} // XFUNC_QuoteString
//-------------------------------------------------------------------------------
function XFUNC_EncodeApostrophes(name)
{
	var s = name;
	s = s.replace(/\'/g, '&#39;');
	return s;
} // XFUNC_EncodeApostrophes
//-------------------------------------------------------------------------------
function XFUNC_HTMLAttributeEncode(s)
{
	// This string is going to go into an HTML (or XML) attribute
	// All instances of the quote char used to surround it must be encoded
	// So we encode both single and double quote chars so caller can use either.
	// Also cannot use < and >
	
	var s1 = s;
	s1 = s.replace(/\&/g, '&#38;');
	s1 = s1.replace(/\'/g, '&#39;');
	s1 = s1.replace(/\"/g, '&#34;');
	s1 = s1.replace(/\</g, '&#60;');
	s1 = s1.replace(/\>/g, '&#62;');
	return s1;
} // XFUNC_HTMLAttributeEncode
//-------------------------------------------------------------------------------
function XFUNC_SameStringIgnoringCase(a,b)
{
	return a.toLowerCase() == b.toLowerCase();
} // XFUNC_SameStringIgnoringCase
//------------------------------------------------------------------------------
