		var NS4 = (document.layers);
		var IE4 = (document.all);
		
		function jfGetSource() {
			if(IE4) {
				return event.srcElement;
			}
			else if(NS4) {
				return event;
			}
		
		}
		function IsText(pstrSource) {
			// Test for a string
			if (pstrSource.length > 0) {
				return true;
			}
			return false;
		}
		function AutoTrimText(pctlSource) {
			var strTemp = pctlSource.value;

			if (IsText(strTemp)) {
				// Trim leading spaces from the original string
				while (1) {
					if (strTemp.substring(0, 1) != " ")
						break;

					strTemp = strTemp.substring(1, strTemp.length);
				}

				// Trim trailing spaces from the original string
				while (1) {
					if (strTemp.substring(strTemp.length - 1, strTemp.length) != " ")
						break;

					strTemp = strTemp.substring(0, strTemp.length - 1);
				}

				pctlSource.value = strTemp;
				return strTemp;
			}
		}
		function ResetControl(pctlSource, pstrMessage) {
			if (IsText(pstrMessage)) {
				alert(pstrMessage);
			}

//			pctlSource.value = "";
			pctlSource.focus();
		}
		function IsPhone(pctlSource) {
		
		    var strValue = pctlSource.value;
		    var strChar = "";
		    var intBookMark = -1;
		
			// is this phone number 'escaped' by a leading plus?
			if (0 < strValue.length && '+' != strValue.charAt(0)) {	// format it
			    // count number of digits
			    var intCounter = 0;
				if ('1' == strValue.charAt(0)) {	// skip it
					strValue = strValue.substring(1, strValue.length);
				}
		
			    for (i = 0; i < strValue.length; i++) {
			        var intCounter2 = strValue.charAt(i);
		
			        // build up formatted number
			        if (intCounter2 >= '0' && intCounter2 <= '9') {
			            if (intCounter == 0) strChar += "(";
			            else if (intCounter == 3) strChar += ") ";
			            else if (intCounter == 6) strChar += "-";
			            strChar += intCounter2;
			            intCounter++;
			        }
			        // check for extension type section; 
			        // are spaces, dots, dashes and parentheses the only valid non-digits in a phone number?
			        if (! (intCounter2 >= '0' && intCounter2 <= '9') && intCounter2 != ' ' && intCounter2 != '-' && intCounter2 != '.' && intCounter2 != '(' && intCounter2 != ')') {
			            intBookMark = i;
			            break;
			        }
			    }
			    // add the extension
			    if (intBookMark >= 0) strChar += " " + strValue.substring(intBookMark, strValue.length);
		
			    // if we recognize the number, then format it
			    if (intCounter == 10 && strChar.length <= 40) pctlSource.value = strChar;
			}
		    return true;
		}
		function IsEmail(pctlSource) {
			strSource = pctlSource.value;
			if (strSource.length == 0) {
				return true;
			}
			/* 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 +")*$")

			/* Finally, let's start trying to figure out if the supplied address is valid. */

			/* Begin with the coarse pattern to simply break up user@domain into different pieces that are easy to analyze. */
			var matchArray = strSource.match(emailPat)
			if (matchArray == null) {
				/* Too many/few @'s or something; basically, this address doesn't even fit the general mould of a valid e-mail address. */
				return false
			}

			var user = matchArray[1]
			var domain = matchArray[2]

			// See if "user" is valid 
			if (user.match(userPat) == null) {
			    // user is not valid
			    return false
			}

			/* if the e-mail address is at an IP address (as opposed to a symbolic host name) make sure the IP address is valid. */
			var IPArray = domain.match(ipDomainPat)
			if (IPArray != null) {
			    // this is an IP address
				  for (var i = 1; i <= 4; i++) {
				    if (IPArray[i] > 255) {
						return false
				    }
			    }
			    return true
			}

			// Domain is symbolic name
			var domainArray = domain.match(domainPat)
			if (domainArray == null) {
			    return false
			}

			/* domain name seems valid, but now make sure that it ends in a three-letter word (like com, edu, gov) or a two-letter word,
				representing country (uk, nl), and that there's a hostname preceding the domain or country. */

			/* Now we need to break up the domain to get a count of how many atoms it consists of. */
			var atomPat = new RegExp(atom,"g")
			var domArr = domain.match(atomPat)
			var len = domArr.length
			if (domArr[domArr.length-1].length < 2 || domArr[domArr.length-1].length > 3) {
				// the address must end in a two letter or three letter word.
				return false
			}

			// Make sure there's a host name preceding the domain.
			if (len < 2) {
				return false
			}

			// If we've gotten this far, everything's valid!
			return true;
		}
		function IsDate(pctlSource,pstrFix) {
			strSource = pctlSource.value;
			if (strSource.length = 0) {
				return true;
			}
			
			var maxDays = 0
			var datePat = /^\d{2}\/\d{2}\/\d{4}$/
			
			//If the general format is not correct, return false
			if (!strSource.match(datePat)) {
				return false;
			}
			if (pstrFix == "FIX") {	
			//Adjust mistyped date
				var intMonth = strSource.substr(0,2)
				var intDay = strSource.substr(3,2)
				var intYear = strSource.substr(6,4)
				//Put values into a date object (rolls extra days or months into next period)
				var dtDate = new Date(intYear,intMonth-1,intDay);
				//Reformat date for control
				var strMonth = new String(dtDate.getMonth() + 1)
				var strDay = new String(dtDate.getDate())
				var strYear = new String(dtDate.getYear())
				if (strMonth.length == 2) {
					strMonth = strMonth + "/"
				}
				else {
					strMonth = "0" + strMonth + "/"
				}
				if (strDay.length == 2) {
					strDay = strDay + "/"
				}
				else {
					strDay = "0" + strDay + "/"
				}
				pctlSource.value = strMonth + strDay + strYear
			}
			else {
			//Alert if date is mistyped
				//Validate month
				var strTemp = strSource.substr(0,2)
				if (strTemp < 1 || strTemp > 12) {
					return false;
				}
				//Validate day
				switch (strTemp) {
					case "02" :
						//workout leapyear
						if (strSource.substr(6,4) % 4 == 0) {
						maxDays = 29;
						}
						else {
						maxDays = 28;
						}
						break;
					case "04" :
						maxDays = 30;
						break;
					case "06" :
						maxDays = 30;
						break;
					case "09" :
						maxDays = 30;
						break;
					case "11" :
						maxDays = 30;
						break;
					default :
						maxDays = 31;
						break;
				}
				var strTemp = strSource.substr(3,2)
				if (strTemp < 1 || strTemp > maxDays) {
					return false;
				}
			}
			return true;
		}
		function FormatWithMask(pctlSource, pintMaskID) {
			AutoTrimText(pctlSource);

			if (pintMaskID == 0) {
				//==============================
				// Email mask
				//==============================
	
				if (IsEmail(pctlSource) == false) {
					ResetControl(pctlSource, 'Please enter a valid email address.');
				}
				return;
			}
			else if (pintMaskID == 1) {
				//==============================
				// Phone mask
				//==============================
	
				if (IsPhone(pctlSource) == false) {
					ResetControl(pctlSource, 'Please enter a valid phone number.');
				}
				return;
			}
			else if (pintMaskID == 2) {
				//==============================
				// Date mask
				//==============================
	
				if (IsDate(pctlSource) == false) {
					ResetControl(pctlSource, 'Please enter a valid date. (##/##/####)');
				}
				return;
			}

		}
