/*
JavaScript Validation Library v2.60
May 2006
Shawn Bailly (www.shawn-bailly.com)

Please report bugs at www.shawn-bailly.com.
This library is released as open source, if you develop some new or better methods, please submit them to me and I may put them in the next version.

This package should have included JavaScript Form Validation.doc, and Extending Validation Script.doc.
Check for online documentation at: www.shawn-bailly.com
*/
/*
Change Log
2.60 -
	Change: Default expressions are back in main script. This is to fix some weird bugs, and will be implemented better in the next major release.
2.50 -
	Change: Changed to require new JSXL.
2.48 -
	Bugfix 1: Radio required was not working.
2.47 -
	Bugfix 1: Validation was not ignoring disabled inputs (in mozilla).
	Added 1: Validation type time-us allows validation of an American time string (ex: 11:00 PM).
	Added 2: Validation type datetime-us allows validation of an American date time string (ex: 08/19/2006 11:00 PM).
	Added 3: Renamed validation type mmddyyyy to date-us for American date string.
	Added 4: Apply attribute on element allows JavaScript evaluations to take place before or after validation.
	Added 5: New attribute on FORM tag (autotrim) which defaults to true.
	Added 6: Default expressions for validation and inputmasks are now in a readable script for defaults.
2.3 -
	Bugfix 1: When pressing ENTER on a form element in mozilla, the form was submitted without validation.
2.25 -
   Added onValidate event.
   Added Validate.result object (this object is populated once onValidate is fired).
   Added message attribute on FORM element; to replace the default: "The following errors have occured."
	Bugfix 1: Validation was not ignoring disabled inputs
	Bugfix 2: Daterange support.
2.12 -
   Added onSuccess & onFail events.
   Added submitForm attribute, specify whether or not to actually submit the form.
2.0 - Completely new code (iteration from the Validation Form Script v1.0
*/
Validate = {
   requires : "JavaScript Extension Library",
   requires_version : "1.1",
   isSupported : function(){
      if (Object._toolkit != null && Object._toolkit.name == this.requires && Object._toolkit.version >= this.requires_version)return true;
      else this.error(this.name+" requires "+this.requires+" v"+this.requires_version+"+");
   },
   name : "JavaScript Validation Script",
   version : "2.60",
   verbose : false,
   defaultCountry : "us",
   country : "us",
   error : function(message){
      if (this.verbose)alert(message);
      var e = new Error(message);
      throw e;
   },
   expressions : new Object(),
   inputmasks : new Object(),
   result : new Object()
};
Validate.isSupported();
Validate.expressions.parent = Validate;
Validate.expressions.expressions = new Enum();
Validate.expressions.add = function(name,expression,flags){
	/* The constructor comparison is defined in this way with .toString() because mozilla did not report constructor function correctly when in loadDefaults */
   var rv = false;
   flags = (flags == null ? "ig" : flags);
   if (name != null && name.constructor == String && name.length > 0){
      if (expression != null){
         var re = null;
			switch (expression.constructor.toString()){
            case String.toString() :
               re = new RegExp(expression,flags);
               break;
            case Function.toString() :
					re = expression;
               break;
            case RegExp.toString() :
               re = expression;
               break;
            default :
               this.parent.error("Undefined expression type. Expressions can only be Regular Expressions, Strings, or Functions.\nValue passed is: "+expression.constructor);
               break;
         }
         if (re != null){
            if (!this.expressions.add(name,re))this.error(name+" already exists in expression list.");
            else rv = true;
         }
         else this.parent.error("Expression could not be evaluated.");
      }
      else this.parent.error("Expression can not be null.");
   }
   else this.parent.error("Name must be a non zero length string.");
   return rv;
};
Validate.expressions.remove = function(index){
   return this.expressions.remove(index);
};
Validate.expressions.item = function(index){
   return this.expressions.item(index);
};
Validate.expressions.names = function(){
   return this.expressions.keyArray();
};
Validate.expressions.values = function(){
   return this.expressions.valueArray();
};
Validate.expressions.length = function(){
   return this.expressions.length();
};
Validate.expressions.test = function(_index,str){
   var index = -1;
   var expression = this.item(_index);
   var rv = null;
   if (_index != null && str != null){
      if (expression != null){
			switch (expression.constructor){
            case Function :
					str = str.toString();
               rv = expression.apply(Object,[str]);
               break;
            case RegExp :
               rv = expression.$().test(str);
               break;
            default :
               this.parent.error("expression.test(): Expression is not valid. Don't know how this happened.");
               break;
         }
      }
      else this.parent.error("expression.test(): The specified index is not valid.");
   }
   else this.parent.error("expression.test(): This function takes two parameters. Parameter 1 is the index or name of the expression to test. Parameter 2 is the string to test with.");
   return rv;
};

Validate.inputmasks.parent = Validate;
Validate.inputmasks.inputmasks = new Enum();
Validate.inputmasks.add = function(name,expression,flags){
   var rv = false;
   flags = (flags == null ? "ig" : flags);
   if (name != null && name.constructor == String && name.length > 0){
      if (expression != null){
         var re = null;
         switch (expression.constructor.toString()){
            case String.toString() :
               re = new RegExp(expression,flags);
               break;
            case Function.toString() :
               re = expression;
               break;
            case RegExp.toString() :
               re = expression;
               break;
            default :
               this.parent.error("Undefined expression type. Inputmasks can only be Regular Expressions, Strings, or Functions.");
               break;
         }
         if (re != null){
            if (!this.inputmasks.add(name,re))Validate.error(name+" already exists in inputmask list.");
            else rv = true;
         }
         else this.parent.error("Inputmask could not be evaluated.");
      }
      else this.parent.error("Inputmask can not be null.");
   }
   else this.parent.error("Name must be a non zero length string.");
   return rv;
};
Validate.inputmasks.remove = function(index){
   return this.inputmasks.remove(index);
};
Validate.inputmasks.item = function(index){
   return this.inputmasks.item(index);
};
Validate.inputmasks.names = function(){
   return this.inputmasks.keyArray();
};
Validate.inputmasks.values = function(){
   return this.inputmasks.valueArray();
};
Validate.inputmasks.length = function(){
   return this.inputmasks.length;
};
Validate.inputmasks.test = function(_index,el,chr){
   var index = -1;
   var expression = this.item(_index);
   var rv = null;
	var str = el.value;
   if (_index != null && str != null && chr != null){
		if (expression != null){
			if (expression.constructor == RegExp){
				if (chr.constructor == Key)chr = chr.chr();
				rv = expression.substr(0,(str+chr).length).$().test(str+chr);
			}
			else{
				try{
					rv = expression(el,chr);
				}
				catch(e){
					this.parent.error("inputmasks.test(): Expression is not valid. Don't know how this happened.");
				};
			};
      }
      else this.parent.error("inputmasks.test(): The specified index is not valid.");
   }
   else this.parent.error("inputmasks.test(): This function takes three parameters. Parameter 1 is the index or name of the inputmask to test. Parameter 2 is the string to test with. Parameter 3 is the new character to be appended to the string.");
   return rv;
};
Validate.result.parent = Validate;
Validate.result.elements = new Enum();
Validate.result.getFail = function(){
   var r = new Array();
   var keys = this.elements.keyArray();
   for (var i=0; i<keys.length; i++){
	try{
		if (!this.elements.item(keys[i]).valid)r[r.length] = this.elements.item(keys[i]);
	}
	catch(e){
	};
   };
   return r;
};

function __validate_linkedelement(evt){
   var el = evt.srcElement;
   var code = evt.keyCode;
   Key.code = evt.keyCode;
   Key.shiftKey = evt.shiftKey;
   Key.altKey = evt.altKey;
   Key.ctrlKey = evt.ctrlKey;
   if (code == Keys.item("Backspace") && $A(el,"left") != null && el.value.length == 0){
      var left = el.form.elements[$A(el,"left")];
      left.value = left.value.substr(0,left.value.length);
      left.focus();
      if (navigator.userAgent.indexOf("MSIE") > -1)left.select();
   }
   if (Key.chr() != null && $A(el,"right") != null && $A(el,"maxlength") != null && el.value.length == $A(el,"maxlength")){
      var right = el.form.elements[$A(el,"right")];
      right.focus();
   }
};

function __validate_checkmask(evt){
   /* Known Issues:
   1. When using a mask with more than one consequetive static character editing the mask fails.
      Backspace will work fine, however; if the left or right arrow keys are used, and a backspace is performed with the
      caret after the static characters, the element will no longer be editable.
   */
   var el = evt.srcElement;
   var maxlength = ($A(el,"maxlength") == null ? -1 : $A(el,"maxlength"));
   var mask = $A(el,"inputmask");
   var flags = ($A(el,"inputmask_flags") != null ? $A(el,"inputmask_flags") : "i");
   var chr = "";
   Key.code = evt.keyCode;
   Key.shiftKey = evt.shiftKey;
   Key.altKey = evt.altKey;
   Key.ctrlKey = evt.ctrlKey;
   var isDefinedMask = false;
   try {
	   isDefinedMask = (Validate.inputmasks.item(mask) != null);
   }
   catch(e){
   };
   if (mask){
	   if (isDefinedMask){
		  evt.returnValue = Validate.inputmasks.test(mask,el,Key);
	   }
	   else{
		  var fullmask = new RegExp(mask,"ig");
		  var cursorStart = $Selection(el).start;
		  var cursorEnd = $Selection(el).end;
		  if ((Key.code == Keys.item("Left") || Key.code == Keys.item("Backspace")) && cursorStart > 0){
			 cursorStart--;
			 cursorEnd--;
		  }
		  if ((Key.code == Keys.item("Right") && cursorEnd < el.value.length) || (Key.chr() != null && cursorStart == el.value.length && el.value.length < maxlength)){
			 cursorStart++;
			 cursorEnd++;
		  }
		  if (Key.chr() != null){
			 evt.returnValue = false;
			 if (fullmask.charAt(0) != "" && el.value.length == 0){
				var counter = 0;
				while (fullmask.charAt(0+counter) != ""){
				   el.value += fullmask.charAt(0+counter);
				   counter++;
				   cursorStart++;
				   $Selection(el,cursorStart);
				}
			 }
			 var value = el.value;
			 var str = value.inject(Key.chr(),cursorStart);
			 var counter = 0;
			 while (fullmask.charAt(cursorStart+counter) != "")chr += fullmask.charAt(cursorStart+counter++);
			 str = str.inject(chr,cursorStart);
			 var re = new RegExp("^"+mask+"$",flags).substr(0,str.length);
			 var valid = re.test(str);
			 if (valid && ((maxlength > -1 && el.value.length < maxlength) || maxlength == -1)){
				$ReplaceSelection(el,(Key.chr()+chr));
				$Selection(el,cursorStart+1+chr.length);
			 }
		  }
		  else{
			 if (Key.code == Keys.item("Backspace")){
				evt.returnValue = true;
				counter = 0;
				while (fullmask.charAt(cursorStart-counter) != "")counter++;
				if (counter > 0){
				   el.value = el.value.remove(cursorStart-counter,counter);
				   if (cursorStart < el.value.length){
					  evt.returnValue = false;
					  $Selection(el,cursorStart-counter);
				   }
				}
			 }
			 else evt.returnValue = true;
		  }
	   }
   };
};
function __validate_checkform(evt){
   if (navigator.userAgent.indexOf("MSIE") > -1)var form = evt.srcElement;
	else var form = evt.currentTarget;
	if ($A(form,"validate") != null && $A(form,"validate").isBoolean()){
		var international = (form.getAttributeNode("international") == null || form.getAttributeNode("international").nodeValue.isBoolean());
      var cField = (form.getAttributeNode("country") == null ? "country" : form.getAttributeNode("country").nodeValue);
      if (international){
         if (form.elements[cField] != null)Validate.country = form.elements[cField].value;
         else{
            if (form.getAttributeNode("country") == null)Validate.country = Validate.defaultCountry;
            else Validate.error("Form is set in international mode with a country field specified, but the country field: "+form.getAttributeNode('country').nodeValue+" does not exist in the form.");
         }
      }
      else Validate.country = (form.getAttributeNode("country") == null ? Validate.defaultCountry : form.getAttributeNode("country").nodeValue);
      var isValid = function(feed,expression,flags){
         var return_value = false;
         var flags = (flags != null) ? flags : "ig";
         if (Validate.expressions.item(expression) != null)return Validate.expressions.test(expression,feed);
         else{
            var re = new RegExp(expression,flags);
            return re.test(feed);
         };
      };
      var getValue = function(el){
         var rv = false;
         if (el.nodeType == null && el.length > 0)el = el[0];
			var tag = (el.tagName == null ? null : el.tagName.toLowerCase());
         switch (tag){
            case "textarea" :
               rv = el.value;
               break;
            case "input" :
               switch (el.getAttribute("type")){
                  case "text" :
                     rv = el.value;
                     break;
                  case "password" :
                     rv = el.value;
                     break;
                  case "checkbox" :
                  case "radio" :
                     rv = null;
							var obj = el.form.elements[el.name];
							if (obj.length != null){
								for (var i=0; i<obj.length; i++)if (obj[i].checked)rv = obj[i].value;
							}
							else rv = obj.value;
							break;
                  case "file" :
                     rv = el.value;
                     break;
                  case "hidden" :
                     rv = el.value;
                     break;
               };
               break;
            case "select" :
               rv = (el.selectedIndex > -1 ? el.options[el.selectedIndex].value : null);
               break;
         };
         return rv;
      };
      var isBlank = function(el){
         var rv = false;
			if (el.nodeType == null && el.length > 0)el = el[0];
         var tag = (el.tagName == null ? null : el.tagName.toLowerCase());
         switch (tag){
            case "textarea" :
               rv = (el.value.length == 0);
               break;
            case "input" :
               switch (el.getAttribute("type")){
                  case "text" :
                     rv = (el.value.length == 0);
                     break;
                  case "password" :
                     rv = (el.value.length == 0);
                     break;
                  case "checkbox" :
							rv = (getValue(el) == null);
                     break;
                  case "radio" :
                     rv = (getValue(el) == null);
							break;
                  case "file" :
                     rv = (el.value.length == 0);
                     break;
                  case "hidden" :
                     rv = (el.value.length == 0);
                     break;
               };
               break;
            case "select" :
               rv = (el.value.length == 0);
               break;
         };
         return rv;
      };
      var message = "";
      var return_value = false;
      var submitForm = ($A(form,"submitForm") != null ? $A(form,"submitForm").isBoolean() : true);
      var report_mode = (form.getAttributeNode("reportmode") != null) ? form.getAttributeNode("reportmode").nodeValue : "all";
      var ignore_disabled = ($A(form,"ignoredisabled") == null ? true : $A(form,"ignoredisabled").isBoolean());
      for (var i=0; i<form.elements.length; i++){
         var el = form.elements[i];
         if ($A(el,"__save_class") != null){
            var obj = document.createAttribute("class");
            obj.nodeValue = $A(el,"__save_class");
            el.setAttributeNode(obj);
         }
         if ($A(el,"__save_style") != null){
            el.style.cssText = $A(el,"__save_style");
         }
      }
      Validate.result.elements = new Enum();
		for (var i=0; i<form.elements.length; i++){
         var el = form.elements[i];
			var disabled = false;
			if ($A(el,"disabled") != null && $A(el,"disabled") === true)disabled = true;
			if ($A(el,"disabled") === "")disabled = true;
         if (!disabled || (disabled && !ignore_disabled)){
			   var reportObj = {
               valid : true,
               failOn : "",
               message : "",
			   element : el
            };
            var fielderror = false;
            /* Check possible input type settings */
            var error_message = (el.getAttributeNode("message") != null) ? el.getAttributeNode("message").nodeValue : "The field: "+el.name+" is required.";
            var match_message = (el.getAttributeNode("match_message") == null) ? "The fields: "+el.name+" and "+(el.getAttributeNode("match") != null ? el.getAttributeNode("match").nodeValue : "unknown")+" do not match." : el.getAttributeNode("match_message").nodeValue;
            var validate_message = (el.getAttributeNode("validate_message") == null) ? "The field: "+el.name+" is not valid" : el.getAttributeNode("validate_message").nodeValue;
            var min_length_message = (el.getAttributeNode("minlength_message") != null) ? el.getAttributeNode("minlength_message").nodeValue : error_message;
            var required_if_message = (el.getAttributeNode("required_if_message") != null) ? el.getAttributeNode("required_if_message").nodeValue : error_message;
            var required_or_message = ($A(el,"required_or_message") != null ? $A(el,"required_or_message") : error_message);
            var range_message = (el.getAttributeNode("range_message") != null) ? el.getAttributeNode("range_message").nodeValue : "";
            var values_message = ($A(el,"values_message") != null ? $A(el,"values_message") : "The field: "+el.name+" does not contain a valid value.");
            if ($A(el,"combine") != null){
               var re = new RegExp("'|\"","ig");
               var fields = $A(el,"combine").split(",");
               el.value = "";
               for (var z=0; z<fields.length; z++){
                  if (re.test(fields[z])){
                     el.value += fields[z].replace(re,"");
                  }
                  else{
                     if (form.elements[fields[z]] != null)el.value += form.elements[fields[z]].value;
                     else el.value += fields[z];
                  }
               }
            }
				if ($A(form,"autotrim") == null || $A(form,"autotrim").isBoolean()){
					var aNode = document.createAttribute("apply");
					if ($A(el,"apply") != null)aNode.nodeValue = $A(el,"apply")+".trim()";
					else aNode.nodeValue = "this.value.trim()";
					el.setAttributeNode(aNode);
				};
				
            if ($A(el,"replace") != null && $A(el,"replaceon") == "before"){
               var re = /^\/(.*?)\/(.*?)?$/ig;
               var match = re.exec($A(el,"replace"));
               if (match != null)var regex = new RegExp(match[1],match[2]);
               else var regex = new RegExp($A(el,"replace"),"ig");
               var replacewith = ($A(el,"replacewith") == null ? "" : $A(el,"replacewith"));
               el.value = el.value.replace(regex,replacewith);
            }
            if ($A(el,"apply") != null && $A(el,"applyon") == "before"){
					var script = $A(el,"apply").replace(/\bthis\b/ig,"el");
					if (el.type != "file")el.value = eval(script);
            }
            if ($A(el,"required") != null){
               var required = $A(el,"required");
               var valid = ($A(el,"validate") != null ? isValid(el.value,$A(el,"validate"),$A(el,"flags")) : false);
               if ((required.isBoolean() && valid != null && isBlank(el)) || (required == "absolute" && isBlank(el))){
                  message += error_message+"\n\n";
                  fielderror = true;
                  reportObj.valid = false;
                  reportObj.failOn = "required";
                  reportObj.message = error_message;
               }
            }
            if ($A(el,"minlength") != null && el.value.length < $A(el,"minlength")){
               message += min_length_message+"\n\n";
               fielderror = true;
               reportObj.valid = false;
               reportObj.failOn = "minlength";
               reportObj.message = min_length_message;
            }
            if ($A(el,"validate") != null && !isBlank(el) && isValid(el.value,$A(el,"validate"),$A(el,"flags")) == false){
               message += validate_message+"\n\n";
               fielderror = true;
               reportObj.valid = false;
               reportObj.failOn = "validate";
               reportObj.message = validate_message;
            }
            if ($A(el,"match") != null){
               var re = /!|@/g;
               var v1 = ($A(el,"match").indexOf("@") > -1 ? el.value : el.value.toLowerCase());
               var v2 = ($A(el,"match").indexOf("@") > -1 ? form.elements[$A(el,"match").replace(re,"")].value : form.elements[$A(el,"match").replace(re,"")].value.toLowerCase());
               var valid = false;
               if ($A(el,"match").indexOf("!") > -1)valid = (v1 != v2);
               else valid = (v1 == v2);
               if (!valid){
                  message += match_message+"\n\n";
                  fielderror = true;
                  reportObj.valid = false;
                  reportObj.failOn = "match";
                  reportObj.message = match_message;
               }
            }
            if ($A(el,"required_or") != null){
					if (el.value.length == 0 || (el.checked != null && !el.checked)){
                  var fields = $A(el,"required_or").split(",");
                  var valid = false;
						for (var z=0; z<fields.length; z++){
							if (!isBlank(form.elements[fields[z]]))valid = true;
                  }
               }
               else valid = true;
               if (!valid){
                  message += required_or_message+"\n\n";
                  fielderror = true;
                  reportObj.valid = false;
                  reportObj.failOn = "required_or";
                  reportObj.message = required_or_message;
               }
            }
				  if ($A(el,"required_if") != null && isBlank(el)){
				     var re = /!|#/g;
				     var iffield = $A(el,"required_if").replace(re,"").split(",");
				     var valid = null;
				     var bool = ($A(el,"required_if").indexOf("#") > -1 ? true : false);
					  var negate = ($A(el,"required_if").indexOf("!") > -1 ? true : false);
					
					for (var z=0; z<iffield.length; z++){
						if (valid == null || valid){
							if (negate){
					         if (bool)valid = (getValue(form.elements[iffield[z]]) != null ? getValue(form.elements[iffield[z]]).isBoolean() : false);
					         else valid = !isBlank(form.elements[iffield[z]]);
					      }
					      else{
					         if (bool)valid = (getValue(form.elements[iffield[z]]) != null ? !getValue(form.elements[iffield[z]]).isBoolean() : true);
					         else valid = isBlank(form.elements[iffield[z]]);
					      };
						};
					};
				     if (!valid){
				        message += required_if_message+"\n\n";
				        fielderror = true;
				        reportObj.valid = false;
				        reportObj.failOn = "required_if";
				        reportObj.message = required_if_message;
				     }
				  }
            if ($A(el,"range") != null && el.value.length > 0){
					var re = /!|@/g;
               var ranges = $A(el,"range").split(",");
					var valid = false;
               for (var z=0; z<ranges.length; z++){
						var cRange = ranges[z].trim();
                  var negate = (cRange.indexOf("!") > -1 ? true : false);
                  var range = (cRange.indexOf("@") > -1 ? cRange.replace(re,"") : cRange.replace(re,"").toLowerCase());
						var value = (cRange.indexOf("@") > -1 ? el.value : el.value.toLowerCase()).toIntrinsic();
                  var comparemode = ((range.substring(0,range.indexOf("-")).length > 0 && range.substr(range.indexOf("-")+1).length > 0) ? "full" : (range.substring(0,range.indexOf("-")).length > 0 ? "right" : "left"));
                  var left = (range.split("-")[0].indexOf("(") > -1 ? range.split("-")[0].substr(1,range.split("-")[0].length-2)*-1 : range.split("-")[0].toIntrinsic());
                  var right = (range.split("-")[1].indexOf("(") > -1 ? range.split("-")[1].substr(1,range.split("-")[1].length-2)*-1 : range.split("-")[1].toIntrinsic());
						switch (comparemode){
                     case "full" :
                        if (!valid)valid = (negate ? (value < left || value > right) : (value >= left && value <= right));
                        break;
                     case "left" :
                        if (!valid)valid = (negate ? value > right : value <= right);
                        break;
                     case "right" :
                        if (!valid)valid = (negate ? value < left : value >= left);
                        break;
                  }
               }
               if (!valid){
						message += range_message+"\n\n";
                  fielderror = true;
                  reportObj.valid = false;
                  reportObj.failOn = "range";
                  reportObj.message = range_message;
               }
            }
            if ($A(el,"values") != null){
               var valid = false;
               try {
                  eval("var values = "+$A(el,"values"));
               }
               catch (e){
                  Validate.error("Values: "+$A(el,"values")+" could not be evaluated. It may contain invalid JavaScript Identifiers.");
               }
               for (var z=0; z<values.length; z++){
                  if (el.value == values[z])valid = true;
               }
               if (!valid){
                  message += values_message+"\n\n";
                  fielderror = true;
                  reportObj.valid = false;
                  reportObj.failOn = "values";
                  reportObj.message = values_message;
               }
            }
            if (fielderror){
					var className = $A(el,"errorclass") || $A(form,"errorclass");
               var style = $A(el,"errorstyle") || $A(form,"errorstyle");
               if (className != null){
                  var obj = document.createAttribute("__save_class");
                  obj.nodeValue = $A(el,"class");
                  el.setAttributeNode(obj);
                  obj = document.createAttribute("class");
                  obj.nodeValue = className;
                  el.setAttributeNode(obj);
               }
               if (style != null){
                  var obj = document.createAttribute("__save_style");
                  obj.nodeValue = el.style.cssText;
                  el.setAttributeNode(obj);
                  el.style.cssText = $A(el,"errorstyle");
               }
            }
            Validate.result.elements.add(el.name,reportObj);
            if (message.length > 0 && report_mode == "single")break;
         };
      };
      if (document.createEvent != null){
         var event = document.createEvent("Events");
         event.initEvent("validate",false,true);
         form.dispatchEvent(event);
      };
      if (document.createEventObject != null && $A(form,"onValidate") != null){
         var event = {
            type : "onValidate",
            message : message,
            srcElement : form
         };
         var fName = $A(form,"onValidate").replace(/\(.*?\)/,"");
         eval(fName+"(event)");
      };
      if (message.length){
			if (document.createEvent != null){
            var event = document.createEvent("Events");
            event.initEvent("fail",false,true);
            form.dispatchEvent(event);
         };
         if (document.createEventObject != null && $A(form,"onFail") != null){
            var event = {
               type : "onFail",
               message : message,
               srcElement : form
            };
            var fName = $A(form,"onFail").replace(/\(.*?\)/,"");
            eval(fName+"(event)");
         };
         switch (report_mode){
            case "all" :
               var msgHeader = ($A(form,"message") == null ? "The following errors have occured." : $A(form,"message"));
               alert(msgHeader+"\n"+message);
               break;
            case "single" :
               alert(message);
               break;
         }
         evt.returnValue = false;
      }
      else{
			for (var i=0; i<form.elements.length; i++){
            var el = form.elements[i];
            if ($A(el,"replace") != null && ($A(el,"replaceon") == "after" || $A(el,"replaceon") == null)){
               var re = /^\/(.*?)\/(.*?)?$/ig;
               var match = re.exec($A(el,"replace"));
               if (match != null)var regex = new RegExp(match[1],match[2]);
               else var regex = new RegExp($A(el,"replace"),"ig");
               var replacewith = ($A(el,"replacewith") == null ? "" : $A(el,"replacewith"));
               el.value = el.value.replace(regex,replacewith);
            };
            if ($A(el,"apply") != null && ($A(el,"applyon") == "after" || $A(el,"applyon") == null)){
					var script = $A(el,"apply").replace(/\bthis\b/ig,"el");
					if (el.tagName.toLowerCase() == "input" && (el.type != null && el.type.toLowerCase() != "file"))el.value = eval(script);
	         };
         };
         if (document.createEvent != null){
            var event = document.createEvent("Events");
            event.initEvent("success",false,true);
            if (submitForm)submitForm = form.dispatchEvent(event);
            else form.dispatchEvent(event);
         };
         if (document.createEventObject != null && $A(form,"onSuccess") != null){
            var event = {
               type : "onSuccess",
               message : message,
               srcElement : form
            };
            var fName = $A(form,"onSuccess").replace(/\(.*?\)/,"");
            eval(fName+"(event)");
         };
         evt.returnValue = submitForm;
      }
      Validate.country = null;
   };
};
function __validate_init(e){
   var forms = document.forms;
	/* Set default recognized validation expressions */
	Validate.expressions.add("string",/^\D*$/ig);
   Validate.expressions.add("integer",/^\d*$/ig);
   Validate.expressions.add("number",/^\d*?(?:\.\d+?$|$)/ig);
   Validate.expressions.add("float",/^\d*?\.\d+$/ig);
   Validate.expressions.add("social",/^\d{3}-\d{2}-\d{4}$/ig);
   //Validate.expressions.add("email",/^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$/ig);
   Validate.expressions.add("email",/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2,})\b/ig);
   Validate.expressions.add("emaillist",/^(([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})+(?:;\s?|,\s?)?)*$/ig);
   Validate.expressions.add("date",/^\d{4}-(?:(?:01|02|03|04|05|06|07|08|09|10|11|12)|(?:jan|feb|apr|may|jun|jul|aug|sep|oct|nov|dec))-\d{2}$/ig);
   Validate.expressions.add("mmddyyyy",/^\d{2}(\/|-)\d{2}(\/|-)\d{4}$/ig);/*Depreciated, will be removed in next major release (use date-us instead)*/
   Validate.expressions.add("time",/^(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23):(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)(:(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)(\.\d+)?)?$/ig);
   Validate.expressions.add("datetime",/^\d{4}-(?:(?:01|02|03|04|05|06|07|08|09|10|11|12)|(?:jan|feb|apr|may|jun|jul|aug|sep|oct|nov|dec))-\d{2}\s(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23):(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)(:(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)(\.\d+)?)?$/ig);
	Validate.expressions.add("time-us",/^(?:01|02|03|04|05|06|07|08|09|10|11|12):(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)(:(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)(\.\d+)?)?\s(?:am|pm)$/ig);
   Validate.expressions.add("datetime-us",/^(?:01|02|03|04|05|06|07|08|09|10|11|12)(?:-|\/)\d{2}(?:-|\/)\d{4}\s(?:01|02|03|04|05|06|07|08|09|10|11|12):(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)(:(?:00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)(\.\d+)?)?\s(?:am|pm)$/ig);
   Validate.expressions.add("date-us",/^\d{2}(\/|-)\d{2}(\/|-)\d{4}$/ig);
   Validate.expressions.add("money",/^(?:\u0024|\u20AC|\u00A3|\u00A4|\u00A5)\d*(\.\d{2})?$/ig);
   Validate.expressions.add("creditcard",function (number){
   	var ccnum = number.replace("\D","");
   	var cctyp = false;
   	var cclen = ccnum.length;
   	var luhn = 0;
   	var mult = 1;
   	if (cclen >= 13 && cclen <= 16){
   		ccval8 = parseInt(ccnum.substr(0,8));
   		cardranges = new Array();
   		cardranges[0] = "mastercard,MC,16,50000000,59999999";
   		cardranges[1] = "visa,VS,13,40000000,49999999";
   		cardranges[2] = "visa,VS,16,40000000,49999999";
   		cardranges[3] = "american express,AX,15,34000000,34999999";
   		cardranges[4] = "american express,AX,15,37000000,37999999";
         cardranges[5] = "discover,DC,14,30000000,30999999";
         cardranges[6] = "discover,DC,14,36000000,36999999";
         cardranges[7] = "discover,DC,14,38000000,38999999";
         cardranges[8] = "discover,DC,14,39000000,39009999";
         cardranges[9] = "discover,DC,15,20140000,20149999";
         cardranges[10] = "discover,DC,15,21490000,21499999";
         cardranges[11] = "jc,JC,16,30880000,30949999";      
         cardranges[12] = "jc,JC,16,30960000,31029999";      
         cardranges[13] = "jc,JC,16,31120000,31209999";      
         cardranges[14] = "jc,JC,16,31580000,31599999";      
         cardranges[15] = "jc,JC,16,33370000,33499999";      
         cardranges[16] = "jc,JC,16,35280000,35899999";      
   		cardranges[17] = "ns,NS,16,60110000,60110999";
   		cardranges[18] = "ns,NS,16,60112000,60119999";
   		for (var i=0; i<=cardranges.length-1; i++){
   			range = cardranges[i].split(",");
   			if (cclen == range[2]){
   				if (ccval8 >= range[3] && ccval8 <= range[4]){
   					for (var z=cclen-1; z >= 0; z--){
   						tmp = ccnum.substr(z,1)*mult;
   						while (tmp > 0){
   							luhn = luhn+(tmp % 10);
   							tmp = Math.floor(tmp/10);
   						};
   						mult = 3-mult;
   					};
   					luhn = (10-(luhn % 10)) % 10;
   					if (luhn == 0)cctyp = range[0];
   				};
   			};
   		};
   	};
   	return cctyp;
   });
   Validate.expressions.add("phone",function(number){
      var rv = false;
      if (Validate.country != ""){
			try{
	         if (Locales.keyExists(Validate.country)){
	            var formats = Locales.item(Validate.country).phone;
					if (formats != null){
	               if (formats.constructor == Array)rv = formats.doUntilTrue(function(item){return item.$().test(number)});
	               else rv = formats.$().test(number);
	            }
	            else{
	               rv = formats;
	            }
	         }
	         else Validate.error("Attempting to validate a phone number, but the country: "+Validate.country+" does not have a locale. For more information on how to add the locale for this country please see the document entitled: Extending Validation Script.");
	      }
	      catch (e){
	         Validate.error("No Locale Pack has been installed. You must include a Locale Pack on this page for phone number validation. A Locale Pack should have come with this version of the Validation Script, if it did not you may create your own by reading: Extending Validation Script.");
	      }
		};
      return rv;
   });
   Validate.expressions.add("zip",function(number){
      var rv = false;
		if (Validate.country != ""){
			try{
	         if (Locales.keyExists(Validate.country)){
	            var formats = Locales.item(Validate.country).postal;
	            if (formats != null){
	               if (formats.constructor == Array)rv = formats.doUntilTrue(function(item){return item.$().test(number)});
	               else rv = formats.$().test(number);
	            }
	            else{
	               rv = formats;
	            }
	         }
	         else Validate.error("Attempting to validate a postal code, but the country: "+Validate.country+" does not have a locale. For more information on how to add the locale for this country please see the document entitled: Extending Validation Script.");
	      }
	      catch (e){
	         Validate.error("No Locale Pack has been installed. You must include a Locale Pack on this page for postal code validation. A Locale Pack should have come with this version of the Validation Script, if it did not you may create your own by reading: Extending Validation Script.");
	      }
		};
      return rv;
   });
	
	/* Set default recognized inputmasks */
	/*
	Validation.inputmasks.add("date",function(chr){
		alert(chr);
		return true;
	});
	*/
   for (var i=0; i<forms.length; i++){
      var form = forms[i];
      $Bind(form,"submit",__validate_checkform);
      if ($A(form,"onFail") != null){
         var fName = $A(form,"onFail").replace(/\(.*?\)/,"");
         $Bind(form,"fail",eval(fName));
      }
      if ($A(form,"onSuccess") != null){
         var fName = $A(form,"onSuccess").replace(/\(.*?\)/,"");
         $Bind(form,"success",eval(fName));
      }
      if ($A(form,"onValidate") != null){
         var fName = $A(form,"onValidate").replace(/\(.*?\)/,"");
         $Bind(form,"validate",eval(fName));
      }
      for (var z=0; z<form.elements.length; z++){
         var el = form.elements[z];
         if ($A(el,"inputmask") != null){
            $Bind(el,"keydown",__validate_checkmask);
         }
         if ($A(el,"left") != null || $A(el,"right") != null){
            $Bind(el,"keydown",__validate_linkedelement);
            $Bind(el,"keyup",__validate_linkedelement);
         }
      }
   };
};
if (navigator.userAgent.indexOf("MSIE") > -1)window.attachEvent("onload",__validate_init);
else window.addEventListener("load",__validate_init,false);
