// JavaScript Document/***    wForms 2.0    a javascript extension to web forms.     Build $Tue, 20 Mar 2007 15:17:28 UTC$    THIS FILE IS AUTOMATICALLY GENERATED.  If creating patches, please    diff against the source tree, not this file.    Copyright (c) 2005-2007 Cedric Savarese <cedric@veerwest.com> and contributors.    This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>    For more information, visit: http://www.formassembly.com/wForms     Build script by Troels Knak-Nielsen <troelskn@gmail.com>***/// wForms - a javascript extension to web forms.// see http://www.formassembly.com/wForms// This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>function wHELPERS() {};// addEvent adapated from http://ejohn.org/projects/flexible-javascript-events/// and  Andy Smith's (http://weblogs.asp.net/asmith/archive/2003/10/06/30744.aspx)wHELPERS.prototype.addEvent = function(obj, type, fn) {	if(!obj) { return; }		if (obj.attachEvent) {		obj['e'+type+fn] = fn;		obj[type+fn] = function(){obj['e'+type+fn]( window.event );}		obj.attachEvent( 'on'+type, obj[type+fn] );	} else if(obj.addEventListener) {					obj.addEventListener( type,fn, false );	} else {		var originalHandler = obj["on" + type]; 		if (originalHandler) { 		  obj["on" + type] = function(e){originalHandler(e);fn(e);}; 		} else { 		  obj["on" + type] = fn; 		} 	}}wHELPERS.prototype.removeEvent = function(obj, type, fn) {	if (obj.detachEvent) {		if(obj[type+fn]) {			obj.detachEvent( 'on'+type, obj[type+fn] );			obj[type+fn] = null;		}	} else if(obj.removeEventListener)		obj.removeEventListener( type, fn, false );	else {		obj["on" + type] = null;	}}// Returns the event's source element wHELPERS.prototype.getSourceElement = function(e) {		if(!e) e = window.event;		if(e.target)		var srcE = e.target;	else		var srcE = e.srcElement;	if(!srcE) return null;	if(srcE.nodeType == 3) srcE = srcE.parentNode; // safari weirdness			if(srcE.tagName.toUpperCase()=='LABEL' && e.type=='click') { 		// when clicking a label, firefox fires the input onclick event		// but the label remains the source of the event. In Opera and IE 		// the source of the event is the input element. Which is the 		// expected behavior, I suppose.				if(srcE.getAttribute('for')) {			srcE = document.getElementById(srcE.getAttribute('for'));		}	}	return srcE;}// Cancel the default execution of an event.wHELPERS.prototype.preventEvent = function(e) {	if (!e) e = window.event;	if (e.preventDefault) e.preventDefault();	else e.returnValue = false;	return false;}// Cancel the propagation of the eventwHELPERS.prototype.stopPropagation = function(e) {	if (!e) var e = window.event;	e.cancelBubble = true;	if (e.stopPropagation) e.stopPropagation();}// Generates a random IDwHELPERS.prototype.randomId = function () {	var seed = (new Date()).getTime();	seed = seed.toString().substr(6);	for (var i=0; i<6;i++)		seed += String.fromCharCode(48 + Math.floor((Math.random()*10)));	return "id-" + seed;}// Activating an Alternate Stylesheet (thx to: http://www.howtocreate.co.uk/tutorials/index.php?tut=0&part=27)// Use this to activate a CSS Stylesheet that shouldn't be used if javascript is turned off.// The stylesheet rel attribute should be 'alternate stylesheet'. The title attribute MUST be set.wHELPERS.prototype.activateStylesheet = function(sheetref) {	if(document.getElementsByTagName) {		var ss=document.getElementsByTagName('link');	} else if (document.styleSheets) {		var ss = document.styleSheets;	}	for(var i=0;ss[i];i++ ) {		if(ss[i].href.indexOf(sheetref) != -1) {			ss[i].disabled = true;			ss[i].disabled = false;					}	}}// hasClasswHELPERS.prototype.hasClass = function(element,className) {	if(element && element.className) {		if((' ' + element.className + ' ').indexOf(' ' + className +' ') != -1) {			return true;		}	}	return false;}wHELPERS.prototype.hasClassPrefix = function(element,className) {	if(element && element.className) {		if((' ' + element.className).indexOf(' ' + className) != -1) {			return true;		}	}	return false;}	wHELPERS.prototype.hasIdPrefix = function(element,idPrefix) {		if(element && element.id) {			if(element.id.indexOf(idPrefix) != -1) {				return true;			}		}		return false;	}// getTop / getLeft  // Returns pixel coordinates from the top-left window corner.wHELPERS.prototype.getTop = function(obj) {	var cur = 0;	if(obj.offsetParent) {				while(obj.offsetParent) {			if((new wHELPERS()).getComputedStyle(obj,'position') == 'relative' ) {				// relatively postioned element				return cur;			}			cur+=obj.offsetTop;			obj = obj.offsetParent;		}	}	return cur;}wHELPERS.prototype.getLeft = function(obj) {	var cur = 0;	if(obj.offsetParent) {				while(obj.offsetParent) {			if((new wHELPERS()).getComputedStyle(obj,'position') == 'relative' ) {				// relatively postioned element				return cur;			}			if((new wHELPERS()).getComputedStyle(obj,'position') == 'absolute' ) {				// relatively postioned element				return cur;			}			cur+=obj.offsetLeft;			obj = obj.offsetParent;		}	}	return cur;}wHELPERS.prototype.getComputedStyle = function(element, styleName) {	if(window.getComputedStyle) {		return window.getComputedStyle(element,"").getPropertyValue(styleName);	} else if(element.currentStyle) {			return element.currentStyle[styleName];	}	return false;}// backward compatibility	var wHelpers = wHELPERS;      /* 	* MISC FUNCTIONS    /* ------------------------------------------------------------------------------------------ */// Push implementation for IE5/macif (!Array.prototype.push) { 	Array.prototype.push = function() { 		for (var i = 0; i < arguments.length; ++i) { 			this[this.length] = arguments[i]; 		} 		return this.length; 	}; }  if(wHELPERS) {	  var wFORMS = { 	  	  debugLevel     : 0, /* 0: Inactive, 1+: Debug Level */	  	  helpers        : new wHELPERS(),     	  behaviors      : {},	  onLoadComplete : new Array(),  /* stack of functions to call once all behaviors have been applied */	  processedForm  : null,	  	  onLoadHandler  : function() {		  for(var behaviorName in  wFORMS.behaviors) {			   wFORMS.debug('wForms/loaded behavior: ' + behaviorName);		  }		 		  for (var i=0;i<document.forms.length;i++) {			  wFORMS.debug('wForms/initialize: '+ (document.forms[i].name || document.forms[i].id) );			  wFORMS.addBehaviors(document.forms[i]);		  }	  },	  	  addBehaviors : function (node) {		if(!node) return;				if(!node.nodeType) {			// argument is not a node. probably an id string. 			// (typeof not used for IE5/mac compatibility)			node = document.getElementById(node);		}		if(!node || node.nodeType!=1) return;				deep=(arguments.length>1)?arguments[1]:true;			wFORMS._addBehaviors(node, deep);						  },		  	  _addBehaviors : function (node, deep) {		 if(node.getAttribute('rel')=='no-behavior') {			  return false;		 }		 // Process element nodes only		 if(node.nodeType == 1) { 			  if(node.tagName == 'FORM') {				  wFORMS.processedForm = node;			  } 		 			  for(var behaviorName in wFORMS.behaviors) {				  wFORMS.behaviors[behaviorName].evaluate(node);			  }						  if(deep) {				  for (var i=0, cn=node.childNodes, l=cn.length; i<l; i++) {				  	 if(cn[i].nodeType==1)					 	wFORMS._addBehaviors(cn[i], deep);				  }			  }			  			  if(node.tagName == 'FORM') {				  // run the init stack				  for (var i=0;i<wFORMS.onLoadComplete.length;i++) {					  wFORMS.onLoadComplete[i].func(wFORMS.onLoadComplete[i].form);				  }				  // empty the stack					  				  if(wFORMS.onLoadComplete.length > 0) {					  wFORMS.onLoadComplete = new Array();				  }			  }		  }	  },	  	  hasBehavior: function(behaviorName) {		  if(wFORMS.behaviors[behaviorName]) return true;		  return false;	  },	  	  /* 	   * DEBUG FUNCTIONS 	   * ------------------------------------------------------------------------------------------ */	  debug : function(txt) { 		msgLevel = arguments[1] || 10; 	// 1 = least importance, X = most important				if(wFORMS.debugLevel > 0 && msgLevel >= wFORMS.debugLevel) {			if(!wFORMS.debugOutput)				wFORMS.initDebug();			if(wFORMS.debugOutput)				wFORMS.debugOutput.innerHTML += "<br />" + txt;		}	  },	  	  initDebug : function() {		var output = document.getElementById('debugOutput');		if(!output) {			output = document.createElement('div');			output.id = 'debugOutput';			output.style.position   = 'absolute';			output.style.right      = '10px';			output.style.top        = '10px';			output.style.zIndex     = '300';			output.style.fontSize   = 'x-small';			output.style.fontFamily = 'courier';			output.style.backgroundColor = '#DDD';			output.style.padding    = '5px';			if(document.body) // if page fully loaded				wFORMS.debugOutput = document.body.appendChild(output);		}		if(wFORMS.debugOutput)			wFORMS.debugOutput.ondblclick = function() { this.innerHTML = '' };	}  };    wFORMS.NAME     = "wForms";  wFORMS.VERSION  = "2.0";  wFORMS.__repr__ = function () {	return "[" + this.NAME + " " + this.VERSION + "]";  };  wFORMS.toString = function () {	return this.__repr__();  };    // For backward compatibility  wFORMS.utilities = wFORMS.helpers;  var wf           = wFORMS;   wf.utilities.getSrcElement				= wFORMS.helpers.getSourceElement;  wf.utilities.XBrowserPreventEventDefault	= wFORMS.helpers.preventEvent;    // Initializations:    // Attach JS only stylesheet.  wFORMS.helpers.activateStylesheet('wforms-jsonly.css');  // Parse document and apply wForms behavior  wFORMS.helpers.addEvent(window,'load',wFORMS.onLoadHandler);  } // ------------------------------------------------------------------------------------------// Field Hint / Tooltip Behavior// ------------------------------------------------------------------------------------------  if(wFORMS) {       // Component properties        wFORMS.idSuffix_fieldHint           = "-H";                     // a hint id is the associated field id (or name) plus this suffix       wFORMS.className_inactiveFieldHint  = "field-hint-inactive";    // visual effect depends on CSS stylesheet       wFORMS.className_activeFieldHint    = "field-hint";             // visual effect depends on CSS stylesheet                     wFORMS.behaviors['hint'] = {           name: 'hint',            		   // evaluate: check if the behavior applies to the given node. Adds event handlers if appropriate             evaluate: function(node) {               if(node.id) {               	   if(node.id.indexOf(wFORMS.idSuffix_fieldHint)>0) {               	                  	     // this looks like a field-hint. See if we have a matching field.               	                   	     // try first with the id, then with the name attribute.               	     var id     = node.id.replace(wFORMS.idSuffix_fieldHint, '');               	                    	     var hinted = document.getElementById(id) || wFORMS.processedForm[id];               	   }                    if(hinted) {					   // is hint placed on a radio group using the name attribute?					   if(hinted.length > 0 && hinted[0].type=='radio') {						   var hintedGroup = hinted;						   l = hinted.length;					   } else {						   var hintedGroup = new Array(hinted);						   l = 1;					   }					   					   for(var i=0;i<l;i++) {						   hinted = hintedGroup[i];						   wFORMS.debug('hint/evaluate: '+ (node.id || node.name));						   switch(hinted.tagName.toUpperCase()) {							   case 'SELECT': 							   case 'TEXTAREA':						   							   case 'INPUT':									wFORMS.helpers.addEvent(hinted,'focus',wFORMS.behaviors['hint'].run);									wFORMS.helpers.addEvent(hinted,'blur' ,wFORMS.behaviors['hint'].remove);									break;							   default:									wFORMS.helpers.addEvent(hinted,'mouseover',wFORMS.behaviors['hint'].run);									wFORMS.helpers.addEvent(hinted,'mouseout' ,wFORMS.behaviors['hint'].remove);									break;						   }						   					   }                   }                }           },		              // run: executed when the behavior is activated           run: function(e) {               var element   = wFORMS.helpers.getSourceElement(e);               var fieldHint = document.getElementById(element.id   + wFORMS.idSuffix_fieldHint);               if(!fieldHint) // try again with the element's name attribute                   fieldHint = document.getElementById(element.name + wFORMS.idSuffix_fieldHint);               if(fieldHint) {                   fieldHint.className = fieldHint.className.replace(wFORMS.className_inactiveFieldHint,                                                                     wFORMS.className_activeFieldHint);				   // Field Hint Absolute Positionning				   fieldHint.style.top  =  (wFORMS.helpers.getTop(element)+ element.offsetHeight).toString() + "px";				   if(element.tagName.toUpperCase() == 'SELECT') 					   fieldHint.style.left =  (wFORMS.helpers.getLeft(element) + (element.offsetWidth- 8)).toString() + "px";				   else 					   fieldHint.style.left =  (wFORMS.helpers.getLeft(element)).toString() + "px"; /* + element.offsetWidth *///				   wFORMS.debug('hint/run: ' + (element.id || element.name) , 5);				   			   }           },		              // remove: executed if the behavior should not be applied anymore           remove: function(e) {               var element   = wFORMS.helpers.getSourceElement(e);               var fieldHint = document.getElementById(element.id   + wFORMS.idSuffix_fieldHint);               if(!fieldHint) // try again with the element's name attribute                   fieldHint = document.getElementById(element.name + wFORMS.idSuffix_fieldHint);               if(fieldHint)                   fieldHint.className = fieldHint.className.replace(wFORMS.className_activeFieldHint,                                                                     wFORMS.className_inactiveFieldHint);//			   wFORMS.debug('hint/remove: ' + (element.id || element.name) , 5);				              }       }   }// ------------------------------------------------------------------------------------------// Form Paging Behavior// ------------------------------------------------------------------------------------------     if(wFORMS) {		// Component properties 		wFORMS.className_paging				= "wfPage";		wFORMS.className_pagingCurrent		= "wfCurrentPage";		wFORMS.className_pagingButtons		= "wfPageButton";		wFORMS.className_hideSubmit			= "wfHideSubmit";		wFORMS.idPrefix_pageIndex			= "wfPgIndex-";		wFORMS.runValidationOnPageNext   	= true;				if(!wFORMS.arrMsg) wFORMS.arrMsg 	= new Array();		wFORMS.arrMsg[4] 					= "Next Page";      //arrMsg[4] for backward compatibility		wFORMS.arrMsg[5] 					= "Previous Page";	//arrMsg[5] for backward compatibility		wFORMS.behaviors['paging'] = {			idSuffix_buttonsPlaceholder: "-buttons",			className_pageNextButton: wFORMS.className_pagingButtons + " wfPageNextButton",			className_pagePreviousButton: wFORMS.className_pagingButtons + " wfPagePreviousButton",						behaviorInUse : false,			allowNestedPages: false,			onPageChange : null, /* Function to run when the page is changed */			// ------------------------------------------------------------------------------------------			// evaluate: check if the behavior applies to the given node. Adds event handlers if appropriate			// ------------------------------------------------------------------------------------------			evaluate: function(node) {				if (wFORMS.helpers.hasClass(node,wFORMS.className_paging)) {										if(!wFORMS.behaviors['paging'].allowNestedPages && wFORMS.behaviors['paging'].getPageElement(node)) {						// found a parent node that is also a page element. 						// remove paging class so that the content is not hidden.						node.className = node.className.replace(wFORMS.className_paging,"");						return;					}											wFORMS.behaviors['paging'].behaviorInUse = true;										var currentPageIndex = wFORMS.behaviors['paging'].getPageIndex(node);					if(currentPageIndex > 1) {						// add previous page button							var placeholder = this.getButtonPlaceholder(node);						var button = placeholder.insertBefore(this.createPreviousPageButton(),placeholder.firstChild);												wFORMS.helpers.addEvent(button,'click',wFORMS.behaviors['paging'].pagingPrevious);											} else {						// set current page class						node.className += ' ' + wFORMS.className_pagingCurrent;												// get the corresponding form element						var form = wFORMS.behaviors['paging'].getFormElement(node);																																// prevent submission of form with enter key.						wFORMS.helpers.addEvent(form,'submit', function(e) { var element = wFORMS.helpers.getSourceElement(e);																			 if(element.type && element.type.toLowerCase()=='text') 																				return wFORMS.preventEvent(e); } );						wFORMS.preventSubmissionOnEnter = true; // for input validation behavior											}					if(document.getElementById(wFORMS.idPrefix_pageIndex+(currentPageIndex+1).toString())) {						// add next page button							var placeholder = this.getButtonPlaceholder(node);						var button = placeholder.appendChild(this.createNextPageButton());						wFORMS.helpers.addEvent(button,'click',wFORMS.behaviors['paging'].pagingNext);							// hide submit button until the last page of the form is reached (do it once on the 1st page)						if(currentPageIndex==1) {														wFORMS.behaviors['paging'].hideSubmitButton(form);						}											}				}			  			},			getButtonPlaceholder: function(page) {				var p = document.getElementById(page.id+this.idSuffix_buttonsPlaceholder);				if(!p) {					var buttonPlaceholder = document.createElement("div"); 						buttonPlaceholder = page.appendChild(buttonPlaceholder);						buttonPlaceholder.className = 'actions';					buttonPlaceholder.id = page.id+this.idSuffix_buttonsPlaceholder;					return buttonPlaceholder;				}								return p; 			},			createNextPageButton: function() {										var button = document.createElement("input"); 				button.setAttribute('value',wFORMS.arrMsg[4]);					button.setAttribute('type',"button");					button.className = this.className_pageNextButton;				return button;			},			createPreviousPageButton: function() {				// add previous page button							var button = document.createElement("input"); 				button.setAttribute('value',wFORMS.arrMsg[5]);					button.setAttribute('type',"button");					button.className = this.className_pagePreviousButton;				return button;			},									// ------------------------------------------------------------------------------------------			// pagingNext			// ------------------------------------------------------------------------------------------			pagingNext: function(e) {				var element  = wFORMS.helpers.getSourceElement(e);				if(!element) element = e								var pageElement     = wFORMS.behaviors['paging'].getPageElement(element);				var pageIndex       = wFORMS.behaviors['paging'].getPageIndex(pageElement) + 1;				var nextPageElement = document.getElementById(wFORMS.idPrefix_pageIndex+pageIndex.toString());								if(nextPageElement) {					if(!wFORMS.hasBehavior('validation') ||					   (wFORMS.hasBehavior('validation') && !wFORMS.runValidationOnPageNext) || 					   (wFORMS.hasBehavior('validation') &&  wFORMS.runValidationOnPageNext && wFORMS.functionName_formValidation(e, true))) {												pageElement.className      = pageElement.className.replace(new RegExp(wFORMS.className_pagingCurrent,"g"),"");						nextPageElement.className += ' ' + wFORMS.className_pagingCurrent;						// show submit button if the last page of the form is reached						if(wFORMS.behaviors['paging'].isLastPage(pageIndex)) {							var form = wFORMS.behaviors['paging'].getFormElement(nextPageElement);							wFORMS.behaviors['paging'].showSubmitButton(form);						}						// trigger onPageChange event												if(wFORMS.behaviors['paging'].onPageChange) {							wFORMS.behaviors['paging'].onPageChange(nextPageElement);						}						window.scroll(0,0);					}									}			},						// ------------------------------------------------------------------------------------------			// pagingPrevious			// ------------------------------------------------------------------------------------------							pagingPrevious: function(e) {				var element  = wFORMS.helpers.getSourceElement(e);				if(!element) element = e 				var pageElement         = wFORMS.behaviors['paging'].getPageElement(element);				var pageIndex           = wFORMS.behaviors['paging'].getPageIndex(pageElement) - 1;				var previousPageElement = document.getElementById(wFORMS.idPrefix_pageIndex+pageIndex.toString());				if(previousPageElement) {					pageElement.className          = pageElement.className.replace(new RegExp(wFORMS.className_pagingCurrent,"g"),"");					previousPageElement.className += ' ' + wFORMS.className_pagingCurrent;																														// hide submit button 					var form = wFORMS.behaviors['paging'].getFormElement(previousPageElement);										wFORMS.behaviors['paging'].hideSubmitButton(form);										// trigger onPageChange event					if(wFORMS.behaviors['paging'].onPageChange) {						wFORMS.behaviors['paging'].onPageChange(previousPageElement);					}					window.scroll(0,0);				}			},			// ------------------------------------------------------------------------------------------			// show/hide submit button			// ------------------------------------------------------------------------------------------											showSubmitButton: function(form) {				var buttons = form.getElementsByTagName('input');				for (var i=0;i<buttons.length;i++) {					if(buttons[i].type && buttons[i].type.toLowerCase() == 'submit') {						buttons[i].className = buttons[i].className.replace(wFORMS.className_hideSubmit,"");					}				}			},			hideSubmitButton: function(form) {				var buttons = form.getElementsByTagName('input');				for (var i=0;i<buttons.length;i++) {					if(buttons[i].type && buttons[i].type.toLowerCase() == 'submit' 				       && !wFORMS.helpers.hasClass(buttons[i],wFORMS.className_hideSubmit) ) {						buttons[i].className += ' ' + wFORMS.className_hideSubmit; 					}				}			},						// ------------------------------------------------------------------------------------------			// isLastPage			// ------------------------------------------------------------------------------------------								isLastPage: function(pageIndex) {				if(isNaN(pageIndex)) {					pageIndex = parseInt(pageIndex.replace(/[\D]*/,""));				}				pageIndex++;				var furtherPageElement = document.getElementById(wFORMS.idPrefix_pageIndex+pageIndex.toString());							if(!furtherPageElement) 					return true;				return false;			},			// ------------------------------------------------------------------------------------------			// gotoPage			// ------------------------------------------------------------------------------------------							gotoPage: function(pageIndex) { 								if(isNaN(pageIndex)) {					var pageElement = document.getElementById(pageIndex);									} else {					var pageElement = document.getElementById(wFORMS.idPrefix_pageIndex+pageIndex.toString());				}								if(!pageElement) return false;								// get the corresponding form element				var form = wFORMS.behaviors['paging'].getFormElement(pageElement);								// hide current page				var allElements = form.getElementsByTagName("*");				for(var i=0; i< allElements.length; i++) {					var n =  allElements[i];										if(wFORMS.helpers.hasClass(allElements[i],wFORMS.className_pagingCurrent)) {												n.className = n.className.replace(new RegExp(wFORMS.className_pagingCurrent,"g"),"");							break;					}				}				//show/hide submit button as necessary								if(wFORMS.behaviors['paging'].isLastPage(pageIndex)) 					wFORMS.behaviors['paging'].showSubmitButton(form);				else { 					wFORMS.behaviors['paging'].hideSubmitButton(form);				}				// Show the page				pageElement.className += ' ' + wFORMS.className_pagingCurrent;								// trigger onPageChange event				if(wFORMS.behaviors['paging'].onPageChange) {					wFORMS.behaviors['paging'].onPageChange(pageElement);				}			},			// ------------------------------------------------------------------------------------------			// getFormElement			// ------------------------------------------------------------------------------------------										getFormElement: function(element) {				var form = element.parentNode;				while(form && form.tagName != "FORM")					form = form.parentNode;				return form;			},			// ------------------------------------------------------------------------------------------			// getPageElement			// ------------------------------------------------------------------------------------------										getPageElement: function(element) {				var n = element.parentNode;				while(n && n.tagName != "FORM" && (!n.className || !wFORMS.helpers.hasClass(n,wFORMS.className_paging)))					n = n.parentNode;				if(n && wFORMS.helpers.hasClass(n,wFORMS.className_paging))					return n;				else					return null;			},			// ------------------------------------------------------------------------------------------			// getPageIndex			// ------------------------------------------------------------------------------------------												getPageIndex: function(element) {				if(element && element.id) 					return parseInt(element.id.replace(/[\D]*/,""));				else					return null;			}       } // End wFORMS.behaviors['paging']   }         // ------------------------------------------------------------------------------------------// Repeat Behavior// ------------------------------------------------------------------------------------------         if(wFORMS) {		// Component properties 		wFORMS.className_repeat 			= "repeat";		wFORMS.className_delete 			= "removeable";		wFORMS.className_duplicateLink 		= "duplicateLink";		wFORMS.className_removeLink 		= "removeLink";		wFORMS.className_preserveRadioName  = "preserveRadioName";				wFORMS.idSuffix_repeatCounter		= "-RC";		wFORMS.idSuffix_duplicateLink		= "-wfDL";									 		wFORMS.preserveRadioName			= false;									 // if true, Repeat behavior will preserve name attributes for radio input. 		wFORMS.limitSwitchScope				= true;									 	 // if true, Repeat behavior will limit the scope of nested switches.				if(!wFORMS.arrMsg) wFORMS.arrMsg 	= new Array();		wFORMS.arrMsg[0] 					= "Add another response"; 					 // repeat link		wFORMS.arrMsg[1] 					= "Will duplicate this question or section." // title attribute on the repeat link 		wFORMS.arrMsg[2] 					= "Remove"; 								 // remove link		wFORMS.arrMsg[3] 					= "Will remove this question or section." 	 // title attribute on the remove link				wFORMS.behaviors['repeat'] = {						onRepeat: null, /* Function to run after the element is repeated */			onRemove: null, 	/* Function to run after the element is removed  */			allowRepeat: null, /* Function for fine control on repeatable section */					   	// ------------------------------------------------------------------------------------------		   	// evaluate: check if the behavior applies to the given node. Adds event handlers if appropriate		   	// ------------------------------------------------------------------------------------------			evaluate: function(node) {								// Repeatable element				if(wFORMS.helpers.hasClass(node, wFORMS.className_repeat)) {					//wFORMS.debug('evaluate/repeat: '+ node.id,3);				   					 if(!node.id) 						node.id = wFORMS.helpers.randomId();											// Check if we have a 'repeat' link					var repeatLink = document.getElementById(node.id + wFORMS.idSuffix_duplicateLink);					if(!repeatLink) {										// create the repeat link						repeatLink = wFORMS.behaviors['repeat'].createRepeatLink(node.id);																		// find where to insert the link						if(node.tagName.toUpperCase()=="TR") {							// find the last TD							var n = node.lastChild;								while(n && n.nodeType != 1)  								n = n.previousSibling;							if(n && n.nodeType == 1) 								n.appendChild(repeatLink);							// Else Couldn't find the TD. Table row malformed ?						} else							node.appendChild(repeatLink);					}					// Add hidden counter field if necessary					var counterField = document.getElementById(node.id + wFORMS.idSuffix_repeatCounter);					if(!counterField) {						// IE Specific :-(						if(document.all && !window.opera) { 							// see http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp							var counterFieldId = node.id + wFORMS.idSuffix_repeatCounter;							if(navigator.appVersion.indexOf("MSIE") != -1 && navigator.appVersion.indexOf("Windows") == -1) // IE5 Mac								counterField   = document.createElement("INPUT NAME=\"" + counterFieldId + "\"");							else								counterField   = document.createElement("<INPUT NAME=\"" + counterFieldId + "\"></INPUT>"); 												counterField.type  ='hidden';							counterField.id    = counterFieldId; 							counterField.value = "1";						}						else {							counterField = document.createElement("INPUT"); 							counterField.setAttribute('type','hidden'); // hidden							counterField.setAttribute('value','1');							counterField.setAttribute('name', node.id + wFORMS.idSuffix_repeatCounter);							counterField.setAttribute('id', node.id + wFORMS.idSuffix_repeatCounter); 						}												// get the form element												var form = node.parentNode;						while(form && form.tagName.toUpperCase() != "FORM")							form = form.parentNode;												form.appendChild(counterField);					}										// Add event handler								wFORMS.helpers.addEvent(repeatLink,'click',wFORMS.behaviors['repeat'].duplicateFieldGroup);							}			 	  	// ------------------------------------------------------------------------------------------				// Removeable element				if(wFORMS.helpers.hasClass(node, wFORMS.className_delete)) {					var removeLink = wFORMS.behaviors['repeat'].createRemoveLink();					// find where to insert the link					if(node.tagName.toUpperCase()=="TR") {						// find the last TD						var n = node.lastChild;							while(n && n.nodeType != 1)  							n = n.previousSibling;						if(n && n.nodeType == 1) 							n.appendChild(removeLink);						// Else Couldn't find the TD. Table row malformed ?					} else						node.appendChild(removeLink);				}	           	},			createRepeatLink: function(id) {				var repeatLink = document.createElement("a"); 				var spanNode = document.createElement("span");  // could be used for CSS image replacement 				var textNode = document.createTextNode(wFORMS.arrMsg[0]);				repeatLink.id = id + wFORMS.idSuffix_duplicateLink;					repeatLink.setAttribute('href',"#");					repeatLink.className = wFORMS.className_duplicateLink;							repeatLink.setAttribute('title', wFORMS.arrMsg[1]);					spanNode.appendChild(textNode); 				repeatLink.appendChild(spanNode); 				return repeatLink;			},			createRemoveLink: function() {				var removeLink = document.createElement("a");				var spanNode   = document.createElement("span");  // could be used for CSS image replacement 				var textNode   = document.createTextNode(wFORMS.arrMsg[2]);				removeLink.setAttribute('href',"#");					removeLink.className = wFORMS.className_removeLink;				removeLink.setAttribute('title',wFORMS.arrMsg[3]);					spanNode.appendChild(textNode); 				removeLink.appendChild(spanNode);				wFORMS.helpers.addEvent(removeLink,'click',wFORMS.behaviors['repeat'].removeFieldGroup);				return removeLink;			},		   	duplicateFieldGroup: function(e) {		   									var element  = wFORMS.helpers.getSourceElement(e);				if(!element) element = e								// override of the wFORMS.preserveRadioName property using a class on the repeat link.				var preserveRadioName = wFORMS.helpers.hasClass(element,wFORMS.className_preserveRadioName) ? true : wFORMS.preserveRadioName;				//wFORMS.debug('preserveRadioName='+preserveRadioName);								// Get Element to duplicate.								while (element && !wFORMS.helpers.hasClass(element,wFORMS.className_duplicateLink)) {					element = element.parentNode;				}					var idOfRepeatedSection = element.id.replace(wFORMS.idSuffix_duplicateLink,"");				var element = document.getElementById(idOfRepeatedSection); 												if (element) {					var wBehavior = wFORMS.behaviors['repeat']; // shortcut										// Check if we have a custom function that prevents the repeat					if(wBehavior.allowRepeat) {												if(!wBehavior.allowRepeat(element)) return false;					}										// Extract row counter information					counterField = document.getElementById(element.id + wFORMS.idSuffix_repeatCounter);					if(!counterField) return; // should not happen.					var rowCount = parseInt(counterField.value) + 1;					// Prepare id suffix					var suffix = "-" + rowCount.toString()					// duplicate node tree 					var dupTree = wBehavior.replicateTree(element, null, suffix, preserveRadioName);  //  sourceNode.cloneNode(true); 					// find insert point in DOM tree (after existing repeated element)					var insertNode = element.nextSibling;										while(insertNode && 						 (insertNode.nodeType==3 ||       // skip text-node that can be generated server-side when populating a previously repeated group 						  wFORMS.helpers.hasClass(insertNode,wFORMS.className_delete))) {												insertNode = insertNode.nextSibling;					}					element.parentNode.insertBefore(dupTree,insertNode);	 // Buggy rendering in IE5/Mac					// if(navigator.appVersion.indexOf("MSIE") != -1 && navigator.appVersion.indexOf("Windows") == -1)								//										// the copy is not duplicable, it's removeable					dupTree.className = element.className.replace(wFORMS.className_repeat,wFORMS.className_delete);					// Save new row count 								document.getElementById(element.id + wFORMS.idSuffix_repeatCounter).value = rowCount;					// re-add wFORMS behaviors					wFORMS.addBehaviors(dupTree);										if(wBehavior.onRepeat)						wBehavior.onRepeat(element,dupTree);				}												return wFORMS.helpers.preventEvent(e);			},					   	removeFieldGroup: function(e) { 				var element  = wFORMS.helpers.getSourceElement(e);				if(!element) element = e				// Get Element to remove.				var element = element.parentNode;				while (element && !wFORMS.helpers.hasClass(element,wFORMS.className_delete)) {					element = element.parentNode;				}					element.parentNode.removeChild(element);				if(wFORMS.behaviors['repeat'].onRemove)						wFORMS.behaviors['repeat'].onRemove(element);				return wFORMS.helpers.preventEvent(e);			},							removeRepeatCountSuffix: function(str) {				return str.replace(/-\d+$/,'');			},				replicateTree: function(element,parentElement, idSuffix, preserveRadioName) {								// Duplicating TEXT-NODE (do not copy value of textareas)				if(element.nodeType==3) { 					if(element.parentNode.tagName.toUpperCase() != 'TEXTAREA')						var newElement = document.createTextNode(element.data); 				} 				// Duplicating ELEMENT-NODE				else if(element.nodeType==1) { 										// Do not copy repeat/remove links					if(wFORMS.helpers.hasClass(element,wFORMS.className_duplicateLink) ||					   wFORMS.helpers.hasClass(element,wFORMS.className_removeLink)) 													return null; 					// Exclude duplicated elements of a nested repeat group					if(wFORMS.helpers.hasClass(element,wFORMS.className_delete)) 						return null; 					// Adjust row suffix id if we find a nested repeat group 					if(wFORMS.helpers.hasClass(element,wFORMS.className_repeat) && parentElement!=null)						idSuffix = idSuffix.replace('-','__');										if(!document.all || window.opera) { 						// Common Branch						var newElement = document.createElement(element.tagName); 					} else {						// IE Branch 						// see http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp												var tagHtml = element.tagName;												if(element.name) 												if (element.tagName.toUpperCase() == "INPUT" && 								element.type.toLowerCase()    == "radio" && preserveRadioName)								tagHtml += " NAME='" + element.name + "' ";							else								tagHtml += " NAME='" + wFORMS.behaviors['repeat'].removeRepeatCountSuffix(element.name) + idSuffix + "' ";						if(element.type) {							tagHtml += " TYPE='" + element.type + "' ";						}						if(element.selected) 							tagHtml += " SELECTED='SELECTED' ";						if(element.checked)							tagHtml += " CHECKED='CHECKED' ";							if(navigator.appVersion.indexOf("MSIE") != -1 && navigator.appVersion.indexOf("Windows") == -1) // IE5 Mac							var newElement = document.createElement(tagHtml);						else							var newElement = document.createElement("<" + tagHtml + "></"+ element.tagName + ">"); 						try { newElement.type = element.type; } catch(e) {}; // nail it down for IE5 ?, breaks in IE6											}				 					// duplicate attributes															for(var i=0; i< element.attributes.length; i++) {						var attribute = element.attributes[i];												// Get attribute value. 						if(	attribute.specified || // in IE, the attributes array contains all attributes in the DTD							attribute.nodeName.toLowerCase() == 'value' ) { // attr.specified buggy in IE?  							// Add the row suffix if necessary.							if(	attribute.nodeName.toLowerCase() == "id" || 								attribute.nodeName.toLowerCase() == "name" ||								attribute.nodeName.toLowerCase() == "for") {																							if(wFORMS.hasBehavior('hint') && 								   attribute.nodeValue.indexOf(wFORMS.idSuffix_fieldHint) != -1)  {									//leave the field hint suffix at the end of the id.									var value = attribute.nodeValue;									value= wFORMS.behaviors['repeat'].removeRepeatCountSuffix(value.substr(0,value.indexOf(wFORMS.idSuffix_fieldHint))) + idSuffix + wFORMS.idSuffix_fieldHint;								}								else {									if(element.tagName.toUpperCase()=="INPUT" && 									   element.getAttribute('type',false).toLowerCase()=="radio" &&									   attribute.nodeName.toLowerCase() == "name" && 									   preserveRadioName) {										var value = attribute.nodeValue;															}									else {										// var value = wFORMS.behaviors['repeat'].removeRepeatCountSuffix(attribute.nodeValue) + idSuffix;										var value = attribute.nodeValue + idSuffix;									}								}							} else {								// Do not copy the value attribute for text/password/file input								if(attribute.nodeName.toLowerCase() == "value" &&								   element.tagName.toUpperCase()=='INPUT'      &&  								  (element.type.toLowerCase() == 'text'     || 								   element.type.toLowerCase() == 'password' || 								   element.type.toLowerCase() == 'hidden' ||								   element.type.toLowerCase() == 'file')) 									var value='';   								// Do not copy the switch behavior's 'event handled' flag, stored in the rel attribute								else if(attribute.nodeName.toLowerCase() == "rel" && 										attribute.nodeValue.indexOf('wfHandled') != -1) {									var value = attribute.nodeValue.replace('wfHandled','');								} else 									var value = attribute.nodeValue;							}							// Create attribute and assign value							switch(attribute.nodeName.toLowerCase()) {								case "class":									newElement.className = value; 									break;								case "style": // inline style attribute (fix for IE)									if(element.style && element.style.cssText) 										newElement.style.cssText = element.style.cssText; 									break;																case "onclick": // inline event handler (fix for IE)									newElement.onclick     = element.onclick;																break;															case "onchange":																newElement.onchange    = element.onchange;																break;															case "onsubmit":									newElement.onsubmit    = element.onsubmit;																break;															case "onmouseover":																newElement.onmouseover = element.onmouseover;																break;															case "onmouseout":																newElement.onmouseout  = element.onmouseout;																break;															case "onmousedown":									newElement.onmousedown = element.onmousedown;																break;															case "onmouseup":									newElement.onmouseup   = element.onmouseup;																break;															case "ondblclick":									newElement.ondblclick  = element.ondblclick;																break;															case "onkeydown":									newElement.onkeydown   = element.onkeydown;																break;															case "onkeyup":									newElement.onkeyup     = element.onkeyup;																break;															case "onblur": 									newElement.onblur      = element.onblur;																break;															case "onfocus":									newElement.onfocus     = element.onfocus;																break;								default:									newElement.setAttribute(attribute.name, value, 0);							}						}					}								}				if(parentElement && newElement) 					parentElement.appendChild(newElement);				for(var i=0; i<element.childNodes.length;i++) {					wFORMS.behaviors['repeat'].replicateTree(element.childNodes[i],newElement,idSuffix, preserveRadioName);				}				return newElement;			}       } // End wFORMS.behaviors['repeat']	      }// ------------------------------------------------------------------------------------------// Switch Behavior// ------------------------------------------------------------------------------------------ if(wFORMS) {		// Component properties 		wFORMS.classNamePrefix_switch 		= "switch";		wFORMS.className_switchIsOn         = "swtchIsOn";    // used to keep track of the switch state on buttons and links (where the checked attribute is not available)		wFORMS.className_switchIsOff        = "swtchIsOff";		wFORMS.classNamePrefix_offState		= "offstate";		wFORMS.classNamePrefix_onState		= "onstate";		wFORMS.switchScopeRootTag           = "";         	  // deprecated.					wFORMS.switchTriggers               = [];			  // associative multi-dimensional array (switchname->element Ids)		wFORMS.switchTargets                = [];			  // associative multi-dimensional array (switchname->element Ids)					wFORMS.behaviors['switch'] = {		   // ------------------------------------------------------------------------------------------		   // evaluate: check if the behavior applies to the given node. Adds event handlers if appropriate		   // ------------------------------------------------------------------------------------------		   evaluate: function(node) {                			    // Handle Switch Triggers				// add event handles and populate the wFORMS.switchTriggers 				// associative array (switchname->element Ids)				// ------------------------------------------------------------------------------------------								if (wFORMS.helpers.hasClassPrefix(node, wFORMS.classNamePrefix_switch)) {					if(!node.id) node.id = wFORMS.helpers.randomId();										if(!wFORMS.processedForm || !wFORMS.processedForm.id)						var formId = "undefined";					else						var formId = wFORMS.processedForm.id;										// Go through each class (one element can have more than one switch trigger).					var switchNames = wFORMS.behaviors['switch'].getSwitchNames(node);					for(var i=0; i < switchNames.length; i++) {						if(!wFORMS.switchTriggers[formId])							wFORMS.switchTriggers[formId] = new Array();						if(!wFORMS.switchTriggers[formId][switchNames[i]]) 							wFORMS.switchTriggers[formId][switchNames[i]] = new Array();						if(!wFORMS.switchTriggers[formId][switchNames[i]][node.id]) {							wFORMS.switchTriggers[formId][switchNames[i]].push(node.id);						}					}					switch(node.tagName.toUpperCase()) {													case "OPTION":							// get the SELECT element							var selectNode = node.parentNode;							while(selectNode && selectNode.tagName.toUpperCase() != 'SELECT') {								var selectNode = selectNode.parentNode;							}							if(!selectNode) { alert('Error: invalid markup in SELECT field ?'); return false;  } // invalid markup							if(!selectNode.id) selectNode.id = wFORMS.helpers.randomId();							// Make sure we have only one event handler for the select.							if(!selectNode.getAttribute('rel') || selectNode.getAttribute('rel').indexOf('wfHandled')==-1) {								//wFORMS.debug('switch/add event: '+ selectNode.className + ' ' + selectNode.tagName);								selectNode.setAttribute('rel', (selectNode.getAttribute('rel')||"") + ' wfHandled');								wFORMS.helpers.addEvent(selectNode, 'change', wFORMS.behaviors['switch'].run);							}														break;						case "INPUT":														if(node.type && node.type.toLowerCase() == 'radio') {								// Add the onclick event on radio inputs of the same group								var formElement = node.form;									for (var j=0; j<formElement[node.name].length; j++) {									var radioNode = formElement[node.name][j];									// prevents conflicts with elements with an id = name of radio group									if(radioNode.type.toLowerCase() == 'radio') {										// Make sure we have only one event handler for this radio input.										if(!radioNode.getAttribute('rel') || radioNode.getAttribute('rel').indexOf('wfHandled')==-1) {																			wFORMS.helpers.addEvent(radioNode, 'click', wFORMS.behaviors['switch'].run);											// flag the node 											radioNode.setAttribute('rel', (radioNode.getAttribute('rel')||"") + ' wfHandled');										} 									}								}							} else {								wFORMS.helpers.addEvent(node, 'click', wFORMS.behaviors['switch'].run);							}							break;												default:									wFORMS.helpers.addEvent(node, 'click', wFORMS.behaviors['switch'].run);							break;					}				}								// Push targets in the wFORMS.switchTargets array 				// (associative array with switchname -> element ids)				// ------------------------------------------------------------------------------------------				if (wFORMS.helpers.hasClassPrefix(node, wFORMS.classNamePrefix_offState) ||				    wFORMS.helpers.hasClassPrefix(node, wFORMS.classNamePrefix_onState)) {										if(!node.id) node.id = wFORMS.helpers.randomId();					if(!wFORMS.processedForm || !wFORMS.processedForm.id)						var formId = "undefined";					else						var formId = wFORMS.processedForm.id;										// Go through each class (one element can be the target of more than one switch).					var switchNames = wFORMS.behaviors['switch'].getSwitchNames(node);										for(var i=0; i < switchNames.length; i++) {						if(!wFORMS.switchTargets[formId])							wFORMS.switchTargets[formId] = new Array();						if(!wFORMS.switchTargets[formId][switchNames[i]]) 							wFORMS.switchTargets[formId][switchNames[i]] = new Array();						if(!wFORMS.switchTargets[formId][switchNames[i]][node.id]) 							wFORMS.switchTargets[formId][switchNames[i]].push(node.id);						//wFORMS.debug('switch/evaluate: [target] '+ switchNames[i],3);					}														}								if(node.tagName && node.tagName.toUpperCase()=='FORM') {					// function to be called when all behaviors have been applied					wFORMS.onLoadComplete.push({form:node, func: wFORMS.behaviors['switch'].init}); 					// clear existing triggers/targets for that form.					wFORMS.behaviors['switch'].clear(node.id);				}           },		   		   // ------------------------------------------------------------------------------------------           // init: executed once evaluate has been applied to all elements		   // ------------------------------------------------------------------------------------------	   		   init: function(form) {		  		   	   if(!form || !form.id)		   	   		var formId = "undefined";			   else			   		var formId = form.id; 			   // go through all switch triggers and activate those who are already ON			 			   			   for(var switchName in wFORMS.switchTriggers[formId]) {					// go through all triggers for the current switch					for(var i=0; i< wFORMS.switchTriggers[formId][switchName].length; i++) {											   	var element = document.getElementById(wFORMS.switchTriggers[formId][switchName][i]);					   												   	if(wFORMS.behaviors['switch'].isTriggerOn(element,switchName)) {							// if it's a select option, get the select element							if(element.tagName.toUpperCase()=='OPTION') {								var element = element.parentNode;								while(element && element.tagName.toUpperCase() != 'SELECT') {									var element = element.parentNode;								}							}							// run the trigger							wFORMS.behaviors['switch'].run(element);						}				   }			   }		   },		   		   // ------------------------------------------------------------------------------------------           // run: executed when the behavior is activated		   // ------------------------------------------------------------------------------------------	              run: function(e) {                var element   = wFORMS.helpers.getSourceElement(e);				if(!element) element = e;			    //wFORMS.debug('switch/run: ' + element.id , 5);									if(element.form)					var form = element.form;				else {					var form = element.parentNode;					while(form && form.tagName != "FORM")						form = form.parentNode;				}					if(!form || !form.id) {					// switch not within a form tag					var formId = "undefined";				} else					var formId = form.id;								var switches_ON  = new Array();				var switches_OFF = new Array();								// Get list of triggered switches (some ON, some OFF)				switch(element.tagName.toUpperCase()) {					case 'SELECT':						for(var i=0;i<element.options.length;i++) {							if(i==element.selectedIndex) {									switches_ON  = switches_ON.concat(wFORMS.behaviors['switch'].getSwitchNames(element.options[i]));							} else {								switches_OFF = switches_OFF.concat(wFORMS.behaviors['switch'].getSwitchNames(element.options[i]));							}						}						break;					case 'INPUT':						if(element.type.toLowerCase() == 'radio') {							// Go through the radio group.														for(var i=0;i <element.form[element.name].length;i++) { 								var radioElement = element.form[element.name][i];								if(radioElement.checked) {									switches_ON  = switches_ON.concat(wFORMS.behaviors['switch'].getSwitchNames(radioElement));								} else {									//wFORMS.debug(wFORMS.behaviors['switch'].getSwitchNames(radioElement).length,1);									switches_OFF = switches_OFF.concat(wFORMS.behaviors['switch'].getSwitchNames(radioElement));								}							}						} else {							if(element.checked || wFORMS.helpers.hasClass(element, wFORMS.className_switchIsOn)) {								switches_ON  = switches_ON.concat(wFORMS.behaviors['switch'].getSwitchNames(element));							} else {								switches_OFF = switches_OFF.concat(wFORMS.behaviors['switch'].getSwitchNames(element));							}													}						break;					default:						break;				}								// Turn off switches first				for(var i=0; i < switches_OFF.length; i++) {					// Go through all targets of the switch 					var elements = wFORMS.behaviors['switch'].getElementsBySwitchName(switches_OFF[i], formId);					for(var j=0;j<elements.length;j++) {																															// only turn off a target if all its triggers are off						var triggers = wFORMS.switchTriggers[formId][switches_OFF[i]];																		var doSwitch = true;													for (var k=0; k < triggers.length; k++) {							var trigger = document.getElementById(triggers[k]);							if(wFORMS.behaviors['switch'].isTriggerOn(trigger, switches_OFF[i])) {								// An element with the REPEAT behavior limits the scope of switches 								// targets outside of the scope of the switch are not affected. 								if(wFORMS.behaviors['switch'].isWithinSwitchScope(trigger, elements[j])) {									// one of the trigger is still ON. no switch off									doSwitch = false;								}							}													}						if(doSwitch) {							wFORMS.behaviors['switch'].switchState(elements[j], wFORMS.classNamePrefix_onState, wFORMS.classNamePrefix_offState);						}					}				}				// Turn on				for(var i=0; i < switches_ON.length; i++) {					var elements = wFORMS.behaviors['switch'].getElementsBySwitchName(switches_ON[i], formId);					for(var j=0;j<elements.length;j++) {						// An element with the REPEAT behavior limits the scope of switches 						// targets outside of the scope of the switch are not affected. 						if(wFORMS.behaviors['switch'].isWithinSwitchScope(element, elements[j])) {							wFORMS.behaviors['switch'].switchState(elements[j], wFORMS.classNamePrefix_offState, wFORMS.classNamePrefix_onState);							//wFORMS.debug('switch/run: [turn on ' + switches_ON[i] + '] ' + elements[j].id , 3);							}					}				}           },		   // ------------------------------------------------------------------------------------------           // clear: executed if the behavior should not be applied anymore		   // ------------------------------------------------------------------------------------------		   clear: function(form) {             	// @TODO: go through wFORMS.switchTriggers to remove events.             	if(form) {	             	wFORMS.switchTriggers[form] = [];		    	         	wFORMS.switchTargets[form] = [];             	} else {             		wFORMS.switchTriggers = [];	             		wFORMS.switchTargets = [];             	}           },		   		   		   // ------------------------------------------------------------------------------------------		   // Get the list of switches 		   // Note: potential conflict if an element is both a switch and a target.		   getSwitchNames: function(element) {				var switchNames = new Array();				var classNames  = element.className.split(' ');				for(var i=0; i < classNames.length; i++) {					// Note: Might be worth keeping a prefix on switchName to prevent collision with reserved names											if(classNames[i].indexOf(wFORMS.classNamePrefix_switch) == 0) {						switchNames.push(classNames[i].substr(wFORMS.classNamePrefix_switch.length+1));					}					if(classNames[i].indexOf(wFORMS.classNamePrefix_onState) == 0) {						switchNames.push(classNames[i].substr(wFORMS.classNamePrefix_onState.length+1));					}					else if(classNames[i].indexOf(wFORMS.classNamePrefix_offState) == 0) {						switchNames.push(classNames[i].substr(wFORMS.classNamePrefix_offState.length+1));					}				}				return switchNames;			},					   // ------------------------------------------------------------------------------------------			switchState: function(element, oldStateClass, newStateClass) {						if(!element || element.nodeType != 1) return;				if(element.className) {  							element.className = element.className.replace(oldStateClass, newStateClass);				}						// For  elements that don't have a native state variable (like checked, or selectedIndex)				if(wFORMS.helpers.hasClass(element, wFORMS.className_switchIsOff)) {					element.className = element.className.replace(wFORMS.className_switchIsOff, wFORMS.className_switchIsOn);				} else if(wFORMS.helpers.hasClass(element, wFORMS.className_switchIsOn)) {					element.className = element.className.replace(wFORMS.className_switchIsOn, wFORMS.className_switchIsOff);				}			},						// ------------------------------------------------------------------------------------------			getElementsBySwitchName: function(switchName, formId) {				var elements = new Array();				if(wFORMS.switchTargets[formId][switchName]) {					for (var i=0; i<wFORMS.switchTargets[formId][switchName].length; i++) {						var element = document.getElementById(wFORMS.switchTargets[formId][switchName][i]);						if(element)							elements.push(element);					}				}				return elements;			},						// ------------------------------------------------------------------------------------------			isTriggerOn: function(element, triggerName) {				if(!element) return false;				if(element.tagName.toUpperCase()=='OPTION') {					var selectElement = element.parentNode;					while(selectElement && selectElement.tagName.toUpperCase() != 'SELECT') {						var selectElement = selectElement.parentNode;					}					if(!selectElement) return false; // invalid markup										if(selectElement.selectedIndex==-1) return false; // nothing selected					// TODO: handle multiple-select					if(wFORMS.helpers.hasClass(selectElement.options[selectElement.selectedIndex],											   wFORMS.classNamePrefix_switch + '-' + triggerName)) {						return true;					}				} else {					if(element.checked || wFORMS.helpers.hasClass(element, wFORMS.className_switchIsOn)) 						return true;				}				return false;			},						// isWithinSwitchScope: An element with the REPEAT behavior limits the scope of switches 			// targets outside of the scope of the switch are not affected. 			// ------------------------------------------------------------------------------------------						isWithinSwitchScope: function(trigger, target) {								if(wFORMS.hasBehavior('repeat') && wFORMS.limitSwitchScope == true) { 					// check if the trigger is in a repeatable/removeable element					var scope = trigger;									while(scope && scope.tagName && scope.tagName.toUpperCase() != 'FORM' && 						  !wFORMS.helpers.hasClass(scope, wFORMS.className_repeat) &&					      !wFORMS.helpers.hasClass(scope, wFORMS.className_delete) ) {						scope = scope.parentNode;					}					if(wFORMS.helpers.hasClass(scope, wFORMS.className_repeat) || 					   wFORMS.helpers.hasClass(scope, wFORMS.className_delete)) {						// yes, the trigger is nested in a repeat/remove element												// check if the target is in the same element.						var scope2 = target;						while(scope2 && scope2.tagName && scope2.tagName.toUpperCase() != 'FORM' && 							  !wFORMS.helpers.hasClass(scope2, wFORMS.className_repeat) &&							  !wFORMS.helpers.hasClass(scope2, wFORMS.className_delete) ) {							scope2 = scope2.parentNode;						}						if(scope == scope2) {							return true;  // target & trigger are in the same repeat/remove element								} else {							return false; // target not in the same repeat/remove element,											}					} else {						return true;	  // trigger is not nested in a repeat/remove element, scope unaffected					}				} else 					return true;			}       } // END wFORMS.behaviors['switch'] object  	      }// ------------------------------------------------------------------------------------------// Form Validation Behavior// ------------------------------------------------------------------------------------------     if(wFORMS) {		// Component properties 		// wFORMS.functionName_formValidation  is defined at the bottom of this file		// Those should be moved inside wFORMS.behaviors['validation']. Stays here for now for backward compatibility       	wFORMS.preventSubmissionOnEnter   		= true; 			// prevents submission when pressing the 'enter' key. Set to true if pagination behavior is used.	   	wFORMS.showAlertOnError 			  	= true; 			// sets to false to not show the alert when a validation error occurs.		wFORMS.className_required 			 	= "required";		wFORMS.className_validationError_msg 	= "errMsg";		 		wFORMS.className_validationError_fld	= "errFld";  		wFORMS.classNamePrefix_validation 		= "validate";			wFORMS.idSuffix_fieldError				= "-E";		wFORMS.behaviors['validation'] = {						// Error messages. This may be overwritten in a separate js file for localization or customization purposes.						errMsg_required 	: "This field is required. ",			errMsg_alpha 		: "The text must use alphabetic characters only (a-z, A-Z). Numbers are not allowed.",			errMsg_email 		: "This does not appear to be a valid email address.",			errMsg_integer 		: "Please enter an integer.",			errMsg_float 		: "Please enter a number (ex. 1.9).",			errMsg_password 	: "Unsafe password. Your password should be between 4 and 12 characters long and use a combinaison of upper-case and lower-case letters.",			errMsg_alphanum 	: "Please use alpha-numeric characters only [a-z 0-9].",			errMsg_date 		: "This does not appear to be a valid date.",			errMsg_notification : "%% error(s) detected. Your form has not been submitted yet.\nPlease check the information you provided.",  // %% will be replaced by the actual number of errors.			errMsg_custom		: "Please enter a valid value.",						// Class Names			className_allRequired : "allrequired",						// first page w/ error in a multi-page form			jumpToErrorOnPage : null,			currentPageIndex  : -1,						// do not submit fields turned off by switch behavior			submitSwitchedOffFields : false,			switchedOffFields : [],					   // ------------------------------------------------------------------------------------------		   // evaluate: check if the behavior applies to the given node. Adds event handlers if appropriate		   // ------------------------------------------------------------------------------------------			evaluate: function(node) {               	if(node.tagName=="FORM") {				   	// functionName_formValidation can be a reference to a function, or a string with the name of the function.				   	// avoid using typeof				   	if(wFORMS.functionName_formValidation.toString()==wFORMS.functionName_formValidation) {					   	// this is a string, not a function						wFORMS.functionName_formValidation = eval(wFORMS.functionName_formValidation);				   	}                   	wFORMS.helpers.addEvent(node,'submit',wFORMS.functionName_formValidation);               	}               	// Add onkeydown handler on text inputs to prevent form submission when the enter key is pressed				if(wFORMS.preventSubmissionOnEnter) { 					if(node.tagName=='INPUT') {											if(!node.type || node.type.toLowerCase()=='text' ||						                 node.type.toLowerCase()=='password' ||						                 node.type.toLowerCase()=='file') {							wFORMS.helpers.addEvent(node,'keydown', function(e){								var evt = (e) ? e : window.event;								if(evt.keyCode==13) {									return wFORMS.helpers.preventEvent(evt);								}							});						}					}				}                          },		   // ------------------------------------------------------------------------------------------           // init: executed once evaluate has been applied to all elements		   // ------------------------------------------------------------------------------------------	   		   init: function() {		   },		   		   // ------------------------------------------------------------------------------------------           // run: executed when the behavior is activated		   // ------------------------------------------------------------------------------------------	   		              run: function(e) {				var element  = wFORMS.helpers.getSourceElement(e);				if(!element) element = e;				//wFORMS.debug('validation/run: ' + element.id , 5);									var currentPageOnly = arguments.length>1 ? arguments[1]:false;				// arguments[1] : (wFORMS.hasBehavior('paging') && wFORMS.behaviors['paging'].behaviorInUse);				wFORMS.behaviors['validation'].switchedOffFields = [];				wFORMS.behaviors['validation'].jumpToErrorOnPage = null;								// make sure we have the form element				while (element && element.tagName != 'FORM') {					element = element.parentNode;				}										var nbErrors = wFORMS.behaviors['validation'].validateElement(element, currentPageOnly, true);								// save the value in a property if someone else needs it.				wFORMS.behaviors['validation'].errorCount = nbErrors;								if (nbErrors > 0) {										if(wFORMS.behaviors['validation'].jumpToErrorOnPage) {											wFORMS.behaviors['paging'].gotoPage(wFORMS.behaviors['validation'].jumpToErrorOnPage);					}					if(wFORMS.showAlertOnError){ wFORMS.behaviors['validation'].showAlert(nbErrors); }					return wFORMS.helpers.preventEvent(e); 				}				// Remove switched-off content if any				// Note: in multi-page behavior the validation is run on "page next" without submitting the form.				//       In this situation (currentPageOnly==true) switched-off conditionals should not be removed. 				if(!wFORMS.behaviors['validation'].submitSwitchedOffFields && !currentPageOnly) {					for(var i=0; i < wFORMS.behaviors['validation'].switchedOffFields.length; i++) {						var element = wFORMS.behaviors['validation'].switchedOffFields[i];						while(element.childNodes[0]) 							element.removeChild(element.childNodes[0]);					}				}								return true;			},		   			// ------------------------------------------------------------------------------------------			// remove: executed if the behavior should not be applied anymore			// ------------------------------------------------------------------------------------------			remove: function() {			},		   		   			// ------------------------------------------------------------------------------------------			// validation functions			// ------------------------------------------------------------------------------------------			validateElement: function(element /*, currentPageOnly, deep */) {				if(!element) return;				var deep = arguments.length>2 ? arguments[2] : true;								// used in multi-page forms				var currentPageOnly = arguments[1] ? arguments[1] : false;												var wBehavior = wFORMS.behaviors['validation'];		// shortcut								// do not validate elements that are in a OFF-Switch				// Note: what happens if an element is the target of 2+ switches, some ON and some OFF ?				if(wFORMS.hasBehavior('switch') && wFORMS.helpers.hasClassPrefix(element,wFORMS.classNamePrefix_offState)) {					if(!wBehavior.submitSwitchedOffFields) {						wBehavior.switchedOffFields.push(element);					}					return 0;				}				// do not validate elements that are not in the current page (Paging Behavior)				if(wFORMS.hasBehavior('paging') && wFORMS.helpers.hasClass(element,wFORMS.className_paging)) {					if(!wFORMS.helpers.hasClass(element,wFORMS.className_pagingCurrent) && currentPageOnly)						return 0;					wBehavior.currentPageIndex = wFORMS.behaviors['paging'].getPageIndex(element);				}								var nbErrors = 0;								// check if required				if(!wBehavior.checkRequired(element)) {					wBehavior.showError(element, wBehavior.errMsg_required);					nbErrors++;					//wFORMS.debug('validation/error: [required]' + element.id + '('+nbErrors+')' , 5);				} else {									// input format validation					if (wFORMS.helpers.hasClassPrefix(element,wFORMS.classNamePrefix_validation)) {								var arrClasses = element.className.split(" ");						for (j=0;j<arrClasses.length;j++) {							switch(arrClasses[j]) {								case "validate-alpha":									if(!wBehavior.isAlpha(element.value)) {										wBehavior.showError(element, wBehavior.errMsg_alpha);										nbErrors++;									}									break;								case "validate-alphanum":									if(!wBehavior.isAlphaNum(element.value)) {										wBehavior.showError(element, wBehavior.errMsg_alphanum);										nbErrors++;									}									break;								case "validate-date":									if(!wBehavior.isDate(element.value)) {										wBehavior.showError(element, wBehavior.errMsg_date);										nbErrors++;									}									break;								case "validate-time":									/* NOT IMPLEMENTED */									break;								case "validate-email":									if(!wBehavior.isEmail(element.value)) {										wBehavior.showError(element, wBehavior.errMsg_email);										nbErrors++;									}									break;								case "validate-integer":									if(!wBehavior.isInteger(element.value)) {										wBehavior.showError(element, wBehavior.errMsg_integer);										nbErrors++;									}														break;								case "validate-float":									if(!wBehavior.isFloat(element.value)) {										wBehavior.showError(element,wBehavior.errMsg_float);										nbErrors++;									}									break;								case "validate-strongpassword": // NOT IMPLEMENTED									if(!wBehavior.isPassword(element.value)) {										wBehavior.showError(element, wBehavior.errMsg_password);										nbErrors++;									}									break;								case "validate-custom": 									var pattern = new RegExp("\/([^\/]*)\/([gi]*)");									var matches = element.className.match(pattern);									if(matches[0]) {																				var validationPattern = new RegExp(matches[1],matches[2]);										if(!element.value.match(validationPattern)) {											wBehavior.showError(element, wBehavior.errMsg_custom);											nbErrors++;																					}									}																								break;																} // end switch						} // end for					}				} // end validation check								// remove previous error flags if any.				if(nbErrors==0) {					wBehavior.removeErrorMessage(element);				} else {					// flag the first page with an error (if multi-page form)					if(wBehavior.currentPageIndex>0 && !wBehavior.jumpToErrorOnPage) {						wBehavior.jumpToErrorOnPage = wBehavior.currentPageIndex;					}				}									// recursive loop									if(deep) {					for(var i=0; i < element.childNodes.length; i++) {						if(element.childNodes[i].nodeType==1) { // Element Nodes only							nbErrors += wBehavior.validateElement(element.childNodes[i], currentPageOnly, deep);						}					}				}								return nbErrors;			},						// ------------------------------------------------------------------------------------------			checkRequired: function(element) {				var wBehavior = wFORMS.behaviors['validation'];		// shortcut								if(wFORMS.helpers.hasClass(element,wFORMS.className_required)) {					switch(element.tagName.toUpperCase()) {						case "INPUT":							var inputType = element.getAttribute("type");							if(!inputType) inputType = 'text'; // handles lame markup							switch(inputType.toLowerCase()) {								case "checkbox":									return element.checked; 									break;								case "radio":									return element.checked; 									break;								default:									return !wBehavior.isEmpty(element.value);							}							break;						case "SELECT":														if(element.selectedIndex==-1) {								// multiple select with no selection								return false;							} else 																				return !wBehavior.isEmpty(element.options[element.selectedIndex].value);							break;						case "TEXTAREA":							return !wBehavior.isEmpty(element.value);							break;						default:							return wBehavior.checkOneRequired(element);							break;					} 					} else if(wFORMS.helpers.hasClass(element,wBehavior.className_allRequired)) {					return wBehavior.checkAllRequired(element);				}				return true;			},			checkOneRequired: function(element) {					if(element.nodeType != 1) return false;				var tagName = element.tagName.toUpperCase();				var wBehavior = wFORMS.behaviors['validation'];								if(tagName == "INPUT" || tagName == "SELECT" || tagName == "TEXTAREA" ) {					var value = wBehavior.getFieldValue(element);						if(!wBehavior.isEmpty(value)) {											return true;					}							}				for(var i=0; i<element.childNodes.length;i++) {					if(wBehavior.checkOneRequired(element.childNodes[i])) return true;				}				return false;			},			checkAllRequired: function(element)	{								if(element.nodeType != 1) return true;				var tagName = element.tagName.toUpperCase();				var wBehavior = wFORMS.behaviors['validation'];				if(tagName == "INPUT" || tagName == "SELECT" || tagName == "TEXTAREA" ) {					var value = wBehavior.getFieldValue(element);						if(wBehavior.isEmpty(value)) {											return false;					}							}				for(var i=0; i<element.childNodes.length;i++) {					if(!wBehavior.checkAllRequired(element.childNodes[i])) return false;				}				return true;			},			getFieldValue: function(element) {				var value = null;				if(element && element.tagName) {					if(element.tagName.toUpperCase() == "INPUT") {						var inputType = element.getAttribute("type");						if(!inputType) inputType = 'text'; // handles lame markup											switch(inputType.toLowerCase()) {							case "checkbox": 								value = element.checked?element.value:null; 								break;							case "radio":																var radioGroup = element.form[element.name]; 															for (var i = 0; i< radioGroup.length; i++) {								    if (radioGroup[i].checked) {								    	if(!value) value = new Array();										value[value.length] = radioGroup[i].value;								    }								} 																break;							default:								value = element.value;						}					} else if(element.tagName.toUpperCase() == "SELECT") {							if(element.selectedIndex!=-1)																							value = element.options[element.selectedIndex].value												else							value = null; // multiple select with no selection					} else if(element.tagName.toUpperCase() == "TEXTAREA") {						value = element.value;					}				}				return value;			},			// ------------------------------------------------------------------------------------------			isEmpty: function(s) {								var regexpWhitespace = /^\s+$/;				return  ((s == null) || (s.length == 0) || regexpWhitespace.test(s));			},			isAlpha: function(s) {				var regexpAlphabetic = /^[a-zA-Z\s]+$/; // Add ' and - ?				return wFORMS.behaviors['validation'].isEmpty(s) || regexpAlphabetic.test(s);			},			isAlphaNum: function(s) {				var validChars = /^[\w\s]+$/;				return wFORMS.behaviors['validation'].isEmpty(s) || validChars.test(s);			},			isDate: function(s) {				var testDate = new Date(s);				return wFORMS.behaviors['validation'].isEmpty(s) || !isNaN(testDate);			},			isEmail: function(s) {				var regexpEmail = /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/;				return wFORMS.behaviors['validation'].isEmpty(s) || regexpEmail.test(s);			},			isInteger: function(s) {				var regexp = /^[+]?\d+$/;				return wFORMS.behaviors['validation'].isEmpty(s) || regexp.test(s);			},			isFloat: function(s) {						return wFORMS.behaviors['validation'].isEmpty(s) || !isNaN(parseFloat(s));			},			// NOT IMPLEMENTED			isPassword: function(s) {				// Matches strong password : at least 1 upper case letter, one lower case letter. 4 characters minimum. 12 max.				//var regexp = /^(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{4,12}$/;  // <= breaks in IE5/Mac				return wFORMS.behaviors['validation'].isEmpty(s);			},						// ------------------------------------------------------------------------------------------					// Error Alert Functions			// ------------------------------------------------------------------------------------------					showError: function (element,errorMsg) {						// remove existing error message if any.				wFORMS.behaviors['validation'].removeErrorMessage(element);								if (!element.id) element.id = wFORMS.helpers.randomId(); // we'll need an id here.						// Add error flag to the field				element.className += " " + wFORMS.className_validationError_fld;				// Prepare error message				var msgNode = document.createTextNode(" " + errorMsg);				// Find error message placeholder.				var fe = document.getElementById(element.id +  wFORMS.idSuffix_fieldError);				if(!fe) { // create placeholder.					fe = document.createElement("div"); 					fe.setAttribute('id', element.id +  wFORMS.idSuffix_fieldError);								// attach the error message after the field label if possible					var fl = document.getElementById(element.id +  wFORMS.idSuffix_fieldLabel);					if(fl)						fl.parentNode.insertBefore(fe,fl.nextSibling);					else						// otherwise, attach it after the field tag.						element.parentNode.insertBefore(fe,element.nextSibling);				}				// Finish the error message.				fe.appendChild(msgNode);  					fe.className += " " + wFORMS.className_validationError_msg;			},						showAlert: function (nbTotalErrors) {			   alert(wFORMS.behaviors['validation'].errMsg_notification.replace('%%',nbTotalErrors));			},						removeErrorMessage: function(element) {				if(wFORMS.helpers.hasClass(element,wFORMS.className_validationError_fld)) {					var rErrClass     = new RegExp(wFORMS.className_validationError_fld,"gi");					element.className = element.className.replace(rErrClass,"");					var errorMessage  = document.getElementById(element.id + wFORMS.idSuffix_fieldError);					if(errorMessage)  {										errorMessage.innerHTML=""; 					}				}			}					       } // End wFORMS.behaviors['validation']	   		wFORMS.functionName_formValidation = wFORMS.behaviors['validation'].run;		// ----------------------------------------------------------------------		// wForms 1.0 backward compatibility		// ----------------------------------------------------------------------		wFORMS.formValidation = wFORMS.behaviors['validation'].run;				// Error messages. 		wFORMS.arrErrorMsg = new Array(); 		wFORMS.arrErrorMsg[0] = wFORMS.behaviors['validation'].errMsg_required;			wFORMS.arrErrorMsg[1] = wFORMS.behaviors['validation'].errMsg_alpha; 					wFORMS.arrErrorMsg[2] = wFORMS.behaviors['validation'].errMsg_email;				wFORMS.arrErrorMsg[3] = wFORMS.behaviors['validation'].errMsg_integer;				wFORMS.arrErrorMsg[4] = wFORMS.behaviors['validation'].errMsg_float;		wFORMS.arrErrorMsg[5] = wFORMS.behaviors['validation'].errMsg_password;		wFORMS.arrErrorMsg[6] = wFORMS.behaviors['validation'].errMsg_alphanum;		wFORMS.arrErrorMsg[7] = wFORMS.behaviors['validation'].errMsg_date;		wFORMS.arrErrorMsg[8] = wFORMS.behaviors['validation'].errMsg_notification;		   }         