		
		// remote scripting library
		// (c) copyright 2005 modernmethod, inc
		var sajax_debug_mode = false;
		var sajax_request_type = "POST";
		var sajax_target_id = "";
		var sajax_failure_redirect = "";
		
		function sajax_debug(text) {
			if (sajax_debug_mode)
				alert(text);
		}
		
 		function sajax_init_object() {
 			sajax_debug("sajax_init_object() called..")
 			
 			var A;
 			
 			/* 
 				Section below changed by Jamie Whitney 4/1/2009 - 5.0 shouldn't be used and causes a warning in IE 8
 				http://www.modernmethod.com/sajax/forum/viewtopic.php?t=2082&highlight=msxml
 			*/
 			/*
 			var msxmlhttp = new Array(
				'Msxml2.XMLHTTP.5.0',
				'Msxml2.XMLHTTP.4.0',
				'Msxml2.XMLHTTP.3.0',
				'Msxml2.XMLHTTP',
				'Microsoft.XMLHTTP');
			*/

 			var msxmlhttp = new Array(
				'Msxml2.XMLHTTP.6.0',
				'Msxml2.XMLHTTP.3.0',
				'Msxml2.XMLHTTP',
				'Microsoft.XMLHTTP');
							
			for (var i = 0; i < msxmlhttp.length; i++) {
				try {
					A = new ActiveXObject(msxmlhttp[i]);
				} catch (e) {
					A = null;
				}
			}
 			
			if(!A && typeof XMLHttpRequest != "undefined")
				A = new XMLHttpRequest();
			if (!A)
				sajax_debug("Could not create connection object.");
			return A;
		}
		
		var sajax_requests = new Array();
		
		function sajax_cancel() {
			for (var i = 0; i < sajax_requests.length; i++) 
				sajax_requests[i].abort();
		}
		
		function sajax_do_call(func_name, args) {
			var i, x, n;
			var uri;
			var post_data;
			var target_id;
			
			sajax_debug("in sajax_do_call().." + sajax_request_type + "/" + sajax_target_id);
			target_id = sajax_target_id;
			if (typeof(sajax_request_type) == "undefined" || sajax_request_type == "") 
				sajax_request_type = "GET";
			
			uri = "/wholesale/squirrelcart/js/storefront.js.php";
			if (sajax_request_type == "GET") {
			
				if (uri.indexOf("?") == -1) 
					uri += "?rs=" + escape(func_name);
				else
					uri += "&rs=" + escape(func_name);
				uri += "&rst=" + escape(sajax_target_id);
				uri += "&rsrnd=" + new Date().getTime();
				
				for (i = 0; i < args.length-1; i++) 
					uri += "&rsargs[]=" + escape(args[i]);

				post_data = null;
			} 
			else if (sajax_request_type == "POST") {
				post_data = "rs=" + escape(func_name);
				post_data += "&rst=" + escape(sajax_target_id);
				post_data += "&rsrnd=" + new Date().getTime();
				
				for (i = 0; i < args.length-1; i++) 
					post_data = post_data + "&rsargs[]=" + escape(args[i]);
			}
			else {
				alert("Illegal request type: " + sajax_request_type);
			}
			
			x = sajax_init_object();
			if (x == null) {
				if (sajax_failure_redirect != "") {
					location.href = sajax_failure_redirect;
					return false;
				} else {
					sajax_debug("NULL sajax object for user agent:\n" + navigator.userAgent);
					return false;
				}
			} else {
				x.open(sajax_request_type, uri, true);
				// window.open(uri);
				
				sajax_requests[sajax_requests.length] = x;
				
				if (sajax_request_type == "POST") {
					x.setRequestHeader("Method", "POST " + uri + " HTTP/1.1");
					x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				}
			
				x.onreadystatechange = function() {
					if (x.readyState != 4) 
						return;

					sajax_debug("received " + x.responseText);
				
					var status;
					var data;
					var txt = x.responseText.replace(/^\s*|\s*$/g,"");
					status = txt.charAt(0);
					data = txt.substring(2);

					if (status == "") {
						// let's just assume this is a pre-response bailout and let it slide for now
					} else if (status == "-") 
						alert("Error: " + data);
					else {
						if (target_id != "") 
							document.getElementById(target_id).innerHTML = eval(data);
						else {
							try {
								var callback;
								var extra_data = false;
								if (typeof args[args.length-1] == "object") {
									callback = args[args.length-1].callback;
									extra_data = args[args.length-1].extra_data;
								} else {
									callback = args[args.length-1];
								}
								callback(eval(data), extra_data);
							} catch (e) {
								sajax_debug("Caught error " + e + ": Could not eval " + data );
							}
						}
					}
				}
			}
			
			sajax_debug(func_name + " uri = " + uri + "/post = " + post_data);
			x.send(post_data);
			sajax_debug(func_name + " waiting..");
			delete x;
			return true;
		}
		
				
		// wrapper for get_discount		
		function x_get_discount() {
			sajax_do_call("get_discount",
				x_get_discount.arguments);
		}
		
		
var isMac		 	= navigator.appVersion.indexOf("Mac")!=-1 		? true : false;		// detect Mac OS
var isFireFox		= navigator.userAgent.indexOf("Firefox")!=-1 	? true : false;		// detect FireFox
var isFF 			= isFireFox;
var isSafari		= navigator.userAgent.indexOf("Safari")!=-1 	? true : false;		// detect Safari
var isNetscape		= navigator.appName == "Netscape"				? true : false;		// detect Netscape
var isOpera			= navigator.userAgent.indexOf("Opera")!=-1 		? true : false;		// detect Opera
var isIE			= document.all && !isOpera						? true : false;		// detect IE
var isMoz			= isFF || (isNetscape && !isSafari)				? true : false;		// this is set for any mozilla based browser
/**********************************************************************************************************

	Purpose:
		This file contains javascript functions that are not Squirrelcart specific
	
	History:
		File modified on 09/19/2005 for v2.0.1 - general improvements to data grid load appearance
		File modified on 10/26/2005 - added "addRow" function
		File modified on 11/04/2005 - IE 5 and 5.5 treat a comment tag as nodeType 1, which caused problems
		File modified on 03/08/2006 - added formatDecimal and formatCommas functions
		File modified on 05/11/2006 - bug fix for v2.2.2 - getNextElement and getPreviousElement causing problems moving option choices up and down in Mozilla
		File modified on 05/27/2006 - added trim() function
		File modified on 06/15/2006 - added validURL() and validEmail() functions
		File modified on 07/28/2006 - bug fix for v2.3.1 - option detail button on order detail page in control panel not working
		File modified on 07/15/2008 - added validInteger() function
		File modified on 08/18/2008 - added functions to deal with cookies
		File modified on 05/12/2009 - bug fix for v3.0.0 - Links records not appearing in IE due to id conflict with 'content' div
		
**********************************************************************************************************/

// way to grab a reference to an element via ID that
// works in all browsers
function getRefToDivMod( divID, oDoc ) {
	if( !oDoc ) { oDoc = document; }
	if( document.layers ) {
		if( oDoc.layers[divID] ) { return oDoc.layers[divID]; } else {
			for( var x = 0, y; !y && x < oDoc.layers.length; x++ ) {
				y = getRefToDivNest(divID,oDoc.layers[x].document); }
				return y; } }
				if( document.getElementById ) { return oDoc.getElementById(divID); }
				if( document.all ) { return oDoc.all[divID]; }
				return document[divID];
}









/***********************************************************************************************************

	Function adds JS to an eventhandler on any element, maintaining existing JS in eventhandler
	
	Parameters:
		elem	id OR ref. to element to add event JS to
		evtName	name event, including the "on" part at the begininning
		func	func reference (not a string! also can't pass params, or parenthesis)

***********************************************************************************************************/
function addEventJS(elem,evtName,func) {
	// if elem is an id, grab ref.
	if (typeof(elem) == 'string') elem = document.getElementById(elem);
	// for IE
	if (document.all) {
		elem.attachEvent(evtName,func);
	} else {
		// for DOM compliant browsers
		elem.addEventListener(evtName.replace('on',''),func,false);
	}
}





// purpose of function is to return the inside dimensions of the window
// returns an object with height and width properties set
function getWindowDims() {
	var x = window;
	var myW = 0, myH = 0, d = x.document.documentElement, b = x.document.body;
	var dims = new Object();
	// for NS
	if( x.innerWidth ) {
		myW = x.innerWidth; myH = x.innerHeight;
	} else if ( d && d.clientWidth ) {
		myW = d.clientWidth; myH = d.clientHeight;
	} else if( b && b.clientWidth ) {
		// for IE
		myW = b.clientWidth; myH = b.clientHeight;
	}

	if( window.opera && !document.childNodes ) { myW += 16; }
	dims.height = myH;
	dims.width = myW;
	return dims;
}




/******************************************************************************************
	Purpose of function is to return the position of any element on screen...looping
	thru all offsetParents until it hits the top, or hits one that is positioned relative
	
	This returns an object that has a x and y property
	
	Based on this: http://www.quirksmode.org/js/findpos.html
	
	Parameters:
		obj					can be a ref. to OR id of an element
		stopAtRelative		when set to 1, the coordinates will be returned based on the first
		parent element that has a relative position
******************************************************************************************/
function getCoordinates(obj,stopAtRelative) {
	var coordinates = new Object();

	// if element id is passed, grab ref. to it
	if (typeof(obj)=='string') obj = document.getElementById(obj);

	var parentStyle;
	var curleft = 0;
	var curtop = 0;
	var checkObj = obj;
	if (checkObj.offsetParent) {
		while (checkObj.offsetParent) {
			curleft += checkObj.offsetLeft;
			curtop += checkObj.offsetTop;

			if (checkObj.offsetParent) {

				if (stopAtRelative) {
					// grab current style for this objects parent
					parentStyle = getCurrentStyle(checkObj.offsetParent);

					// bail if the parent is relative, because we can't move the object outside of it
					if (parentStyle.position=='relative') {
						break;
					}
				}

				// obj is now its parent
				checkObj = checkObj.offsetParent;
			} else {
				break;
			}

		}
	} else if (checkObj.x) {
		curleft += checkObj.x;
		curtop += checkObj.y;
	}

	coordinates.xLeft 		= curleft;
	coordinates.xRight 		= coordinates.xLeft + obj.offsetWidth;
	coordinates.yTop 		= curtop;
	coordinates.yBottom 	= coordinates.yTop + obj.offsetHeight;
	return coordinates;
}








/**********************************************************************************************************
	Function getCurrentStyle()
	
	Purpose is to return a CSSStyleDeclaration object representing the current applied style, plus CSS
	stylesheets. The style property of an element strictly returns the inline style. This returns the CSS
	actually being used at the time this is called.
	
	The only reason for this function is because IE does not support the DOM2 window.getComputedStyle()
	function, so we have to use the currentStyle property instead.
	
	Params: ref. to OR id of an element
**********************************************************************************************************/
function getCurrentStyle(elem) {
	if (typeof(elem)=='string') elem=document.getElementById(elem);

	// if IE and getComputedStyle() is not available (in case IE 7+ adds it)
	if (elem.currentStyle) {
		return elem.currentStyle;
	} else {
		return document.defaultView.getComputedStyle(elem,'');
	}
}




// function takes an object as a parameter, and returns
// a copy of the object
// called like this:
// myNewObj = new cloneObject(origObj);
function cloneObject(what) {

	if (what.valueOf) {
		// this does not work in IE
		return what.valueOf();
	} else {
		// this does work in IE
		for (i in what) {
			this[i] = what[i];
		}
	}
}




// Purpose of function is to return a reference to the element that triggered an event
function getEventTarget(evt) {
	evt = (evt) ? evt : ((window.event) ? event : null);
	if (!evt) return false;

	var elem = (evt.target) ? evt.target :
	((evt.srcElement) ? evt.srcElement : null);
	if (elem.nodeType == 3) {
		elem = elem.parentNode;
	}

	return elem;
}






// purpose of function is to move an element in an array up or down
function moveArrayPos(arr,old_i,jump) {
	// arr 		the array
	// old_i 	the index of the element u want to move
	// jump 	a pos or neg integer representing how may moves to make in which direction
	//
	// function will return the new array

	// calculate new index
	new_i = old_i + jump;

	// account for fact that new index can't be above or below the top or bottom options
	new_i = new_i < 0 ? 0 : 						// if new position is above the top option, set it to 0 (top)
	new_i > arr.length - 1 ? arr.length - 1: // if new position is below the last option, set it to the last index
	new_i;

	if (new_i >= 0) {
		// cut the option from the list
		cut_opt = arr.splice(old_i,1);
		// put back, in the new position
		arr.splice(new_i,0,cut_opt);
	}

	//alert("moving index: " + old_i + "(" + jump + "), new i: " + new_i);
	return arr;
}



// purpose of function is to take an element and swap it's class on different event
// this is here, because IE doesn't support CSS pseudo classes "hover, active, etc..."
// on none <a> tags!
// elemRef is optional...if left out, the element that was moused over will get it's className swapped
// if specified, then that element will have its class swapped
// elemId is the ID of the elemnt you want to swap.
function swapClass(evtRef, elemRef, elemId) {
	if (!evtRef) return;

	// try to grab by ID first, if elemRef is not passed
	if (!elemRef && elemId) elemRef = document.getElementById(elemId);

	// else, grab it from the evt. itself
	if (!elemRef) var elemRef = evtRef.target ? evtRef.target : evtRef.srcElement;

	if (!elemRef.oldClassName) elemRef.oldClassName = elemRef.className;

	if (evtRef.type == "mouseover" || evtRef.type == "mousedown") {
		// if here, only change class if the element wasn't clicked (selected)
		if (elemRef.className.indexOf('click') == -1) elemRef.className = elemRef.oldClassName + "-" + evtRef.type;
	} else if (evtRef.type == "click"){
		// if clicked on, change row color
		if (elemRef.className.indexOf('click') == -1) {
			elemRef.className = elemRef.oldClassName + "-click"
		} else {
			// else put it back
			elemRef.className = elemRef.oldClassName;
		}
	} else {
		// if here, only put original class back if the element wasn't clicked (selected)
		if (elemRef.className.indexOf('click') == -1) elemRef.className = elemRef.oldClassName;
	}
	
}



// purpose is to toggle visibility of an element
function swapVis(elemRef) {
	elemRef = typeof(elemRef) == 'object' ? elemRef : document.getElementById(elemRef);

	if (elemRef && elemRef.style) {
		elemRef.style.visibility = elemRef.style.visibility == 'hidden' ? 'visible' : 'hidden';
	}
}

// purpose is to toggle display of an element
function swapDisplay(elemRef) {
	elemRef = typeof(elemRef) == 'object' ? elemRef : document.getElementById(elemRef);

	//if (elemRef && elemRef.style) {
	if (elemRef) {
		// if run for the first time on something that 
		// doesn't have an inline style, set one based on class if possible
		//if (!elemRef.style.display) {
		if (!elemRef.style.display && (elemRef.className.indexOf('sc_hide') != -1 || elemRef.className.indexOf('sc_show') != -1)) {
			if (elemRef.className.indexOf('sc_hide') != -1) {
				elemRef.className = elemRef.className.replace('sc_hide','sc_show');
			} else if (elemRef.className.indexOf('sc_show') != -1) {
				elemRef.className = elemRef.className.replace('sc_show','sc_hide');
			}
		} else {
			elemRef.style.display = elemRef.style.display == 'none' ? '' : 'none';
		}
		
		elemRef.style.zoom = '1';
		
	}
}



// submit form on enter
function submitEnter(myfield,e) {
	var keycode;
	if (window.event) {
		keycode = window.event.keyCode;
	} else if (e) {
		keycode = e.which;
	} else {
		return true;
	}
	if (keycode == 13)	{
		myfield.form.submit();
		return false;
	} else {
		return true;
	}
}



/*
Purpose:
Swap the src of all images that are specified by the imgName var.

Parameters:
imgName			name of image(s) to swap src
excludeRef		ref. to an image to exclude
forceNewSrc		URL to use for new src, if you don't want to use the one set in the swapsrc attribute
*/
function swapAllSrc(imgName,excludeRef,forceNewSrc) {

	// grab all images with imgName
	imgs = document.getElementsByName(imgName);

	for(i=0; i < imgs.length; i++) {
		img = imgs[i];

		if(excludeRef != img) {
			newSrc = forceNewSrc ? forceNewSrc : img.getAttribute('swapsrc');
			// store current src as swapsrc
			img.setAttribute('swapsrc',img.src);
			img.src = newSrc;
		}
	}
}




function getNextElement(elemRef) {
	/*************************************************************************
	Purpose:
	Grab the next sibling node of elemRef, excluding any text, comments,
	or other non tag nodes

	Parameters:
	elemRef	= a element reference, OR id
	*************************************************************************/
	if (typeof(elemRef) == 'string') elemRef = document.getElementById(elemRef);

	if (elemRef) {
		// node Type 1 is for an element...tag only. (not a comment, text, etc...)
		nextSib = elemRef.nextSibling;
		if (nextSib) {
			// we only want node Type 1, and no comments...loop until we run out of siblings
			// OR until the next sib is one we want
			while(nextSib.nodeType != 1 || nextSib.nodeName == '!') {
				nextSib = nextSib.nextSibling;
				// bail if we ran out of siblings
				if (!nextSib) return false;
			}
		}

		if (nextSib) return nextSib;
	}

}


function getPreviousElement(elemRef) {
	/*************************************************************************
	Purpose:
	Grab the previous sibling node of elemRef, excluding any text,
	comments, or other non tag nodes

	Parameters:
	elemRef	= a element reference, OR id
	*************************************************************************/
	if (typeof(elemRef) == 'string') elemRef = document.getElementById(elemRef);

	if (elemRef) {
		// node Type 1 is for an element...tag only. (not a comment, text, etc...)
		previousSib = elemRef.previousSibling;
		
		if (previousSib) {
			// we only want node type 1...this will loop until we find the right node or run out of siblings
			while(previousSib.nodeType != 1 || previousSib.nodeName == '!') {
				previousSib = previousSib.previousSibling;
				// bail if we ran out of siblings
				if (!previousSib) return false;
			}
		}
		if (previousSib) return previousSib;
	}

}





function getLastChildElement(parentRef) {
	/*************************************************************************
	Purpose:
	Grab the last child element of parent node parentRef, excluding any text,
	comments, or other non tag nodes

	Parameters:
	parentRef	= an element reference, OR id
	*************************************************************************/
	if (typeof(parentRef) == 'string') parentRef = document.getElementById(parentRef);

	if (parentRef) {
		// node Type 1 is for an element...tag only. (not a comment, text, etc...)
		lastChildRef = parentRef.lastChild;
		if (lastChildRef) {
			if (lastChildRef.nodeType != 1 || lastChildRef.nodeName == '!') {
				lastChildRef = getPreviousElement(lastChildRef);
			}

			if (lastChildRef.nodeType == 1 && lastChildRef.nodeName != '!') return lastChildRef;
		}
	}
}





/***************************************************************************
	Purpose:
		To return a reference to the first child node that is an actual
		element (tag).
	
	Parameters:
		elemRef		- reference to element OR id
***************************************************************************/
function getFirstChildElement(elemRef) {

	if (typeof(elemRef) == 'string') elemRef = document.getElementById(elemRef);

	if (elemRef) {
		// node Type 1 is for an element...tag only. (not a comment, text, etc...)
		// IE prior to 6.0 still treats a comment as node type 1, so we add something to throw that out by nodeName
		firstChildRef = elemRef.firstChild;
		if (firstChildRef) {
			if (firstChildRef.nodeType != 1 || firstChildRef.nodeName == '!') {
				firstChildRef = firstChildRef.nextSibling;
			}
			if (firstChildRef) {
				if (firstChildRef.nodeType != 1 || firstChildRef.nodeName == '!') {
					firstChildRef = firstChildRef.nextSibling;
				}
			}
			if (firstChildRef) {
				if (firstChildRef.nodeType != 1 || firstChildRef.nodeName == '!') {
					firstChildRef = firstChildRef.nextSibling;
				}
			}
		}

		if (firstChildRef) return firstChildRef;
	}

}





/*********************************************************************************************************

	Function returns all elements that have a name that contains the string passed as 'match'.
	Example:
	HTML:
	<div id="parentDiv">
	<input name="test_1" /><br />
	<input name="test_2" /><br />
	<input name="test_3" /><br />
	</div>
	
	JS:
	var testFlds = getElementsByPartialName('parentDiv','input','test_');
	
	The above JS will return an array containing all 3 inputs that start with 'test_'
	
	Parameters:
	parent	- a reference to OR an id of an element to search inside
	tag		- type of tag to look for
	match	- string to match

*********************************************************************************************************/
function getElementsByPartialName(parent,tag,match) {
	var i;
	var matches = new Array();

	if (typeof (parent) == 'string') {
		parent = document.getElementById(parent);
	}

	var allTags = parent.getElementsByTagName(tag);

	if (!allTags) return matches;

	// loop thru all tags looking for match
	for(i=0;allTags[i];i++) {
		if (allTags[i].name.indexOf(match) != -1) {
			matches[matches.length] = allTags[i];
		}
	}
	return matches;
}





/*********************************************************************************************************

	Function returns all elements that have an id that contains the string passed as 'match'.
	Example:
		HTML:
		<div id="parentDiv">
		<input id="test_1" /><br />
		<input id="test_2" /><br />
		<input id="test_3" /><br />
		</div>
	
	JS:
		var testFlds = getElementsByPartialId('parentDiv','input','test_');
		
		The above JS will return an array containing all 3 inputs that start with 'test_'
		
	Parameters:
		parent	- a reference to OR an id of an element to search inside
		tag		- type of tag to look for
		match	- string to match

*********************************************************************************************************/
function getElementsByPartialId(parent,tag,match) {
	var i;
	var matches = new Array();
	if (typeof (parent) == 'string') {
		parent = document.getElementById(parent);
	}
	if (!parent) return false;
	
	var allTags = parent.getElementsByTagName(tag);

	if (!allTags) return matches;

	// loop thru all tags looking for match
	for(i=0;allTags[i];i++) {
		if (allTags[i].id.indexOf(match) != -1) {
			matches[matches.length] = allTags[i];
		}
	}
	return matches;
}





/* the function below was obtained via Robert Nyman and can go away once all browsers support this natively */
/*
	Developed by Robert Nyman, http://www.robertnyman.com
	Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/	
var getElementsByClassName = function (className, tag, elm){
	if (document.getElementsByClassName) {
		getElementsByClassName = function (className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className),
				nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
				returnElements = [],
				current;
			for(var i=0, il=elements.length; i<il; i+=1){
				current = elements[i];
				if(!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	else if (document.evaluate) {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = "",
				xhtmlNamespace = "http://www.w3.org/1999/xhtml",
				namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
				returnElements = [],
				elements,
				node;
			for(var j=0, jl=classes.length; j<jl; j+=1){
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			}
			try	{
				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			}
			catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			}
			while ((node = elements.iterateNext())) {
				returnElements.push(node);
			}
			return returnElements;
		};
	}
	else {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = [],
				elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
				current,
				returnElements = [],
				match;
			for(var k=0, kl=classes.length; k<kl; k+=1){
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for(var l=0, ll=elements.length; l<ll; l+=1){
				current = elements[l];
				match = false;
				for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};





/*********************************************************************************************************

	Function toggleCheckboxes()
	
	Purpose:
		Toggle check box state for all fields with the given name
	
	Parameters:
		fieldName		- string - name of field, or string that occurs in the field
		state			- state - true for checked, false for unchecked
		partial			- optional. set to true to make this work for all fields that contain the string
		specified as fieldName
		insideEleme		- optional - either the id of or a reference to an element that is the parent of
		all the fields we want to toggle. This should improve performance a bit for pages
		with large numbers of inputs

*********************************************************************************************************/
function toggleCheckboxes (fieldName, state, partial, parent) {
	// grab reference to parent if needed
	if (parent) {
		if (typeof(parent) == 'string') parent = document.getElementById(parent);
	} else {
		parent = document;
	}

	// grab fields...either ALL input fields, or the ones with the given name
	fields = partial ? parent.getElementsByTagName('INPUT') : parent.getElementsByName(fieldName);

	// store the count so we don't have to keep accessing it
	var count = fields.length;
	var datarow;
	
	// loop through them
	//for(i=0;i<fields.length;i++){
	for(i=0;i<count;i++){
		if (
		(
		(partial && fields[i].name.indexOf(fieldName) != -1)
		|| !partial
		)
		&& fields[i].type == "checkbox"
		)
		{
			fields[i].checked = state;

			// this is for IE...without it, if you try to move this field via the DOM, it loses it's value :(
			fields[i].defaultChecked = state;
			
			// if we are on a records table, change the class for the rows in that table to highlight them
			if (fieldName == 'selected_record[]') {
				// grab corresponding data table row
				datarow = document.getElementById('data_row_'+i);
				if (datarow) {
					if (state) {
						// if row was already selected manually, put it back first to original class name
						if (datarow.oldClassName) datarow.className = datarow.oldClassName;
						// save original class name so we can puts it backs my pretty
						datarow.oldClassName = datarow.className;
						// change row so it's highlighted
						datarow.className = datarow.className + '-click';
					} else {
						if (datarow.oldClassName) datarow.className = datarow.oldClassName;
					}
				} 
			}			
		}
	}
}





function dumpElement(elemRef) {
	// purpose of function is to dump the element passed
	// into a table showing each prop and its value
	// this does not recurse through objects

	var t; // for text output from this function
	var dumpArr = new Array();
	var propArr = new Array();
	var prop;

	for(prop in elemRef) {
		dumpArr[prop] = elemRef[prop];
		propArr[propArr.length] = prop;
	}
	propArr.sort();

	t += '<html><head><style>td {font-size: 10px; font-family: tahoma}</style></head><body><table border="1">';

	for(i=0; i < propArr.length; i++) {
		prop = propArr[i];
		t += '<tr><td>' + prop + '</td><td>';
		if (prop == 'innerHTML' || prop == 'outerHTML') {
			t += 'HTML ...';
		} else {
			t += dumpArr[prop];
		}
		t += '&nbsp;</td></tr>';
	}
	t += '</table></body></html>';
	var newWin = window.open();
	newWin.document.write(t);
}






/***********************************************************************
	Purpose:
		To loop through all rows in a table, and alternate the className
	
	Parameters:
		tableRef	- element reference OR id of table
		class1		- string - name of 1st class to use
		class2		- string - name of 2nd clas to use
***********************************************************************/
function altRowClass(tableRef, class1, class2) {
	var currentClass;

	// check if tableRef is an ID
	if (typeof(tableRef) == 'string') tableRef = document.getElementById(tableRef);

	// grab TBODY tag (inside <table>)
	tBodyRef = getFirstChildElement(tableRef);
	if (tBodyRef) {
		// table rows AND text nodes
		rows = tBodyRef.childNodes;

		if (rows) {
			// loop through children, and alternate className on the TR tags only
			// we are skipping the first row, assuming it is a header
			for(i=1; i < rows.length; i++) {
				if (rows[i].tagName == "TR") {
					currentClass = currentClass == class1 ? class2 : class1;
					rows[i].className = currentClass;
				}
			}
		}
	}
}





/********************************************************************************************************

	Function addRow
	
	Purpose: to add 1 or more rows to a table before another row
	
	Parameters:
		beforeRow		ref. OR id of the row to insert the new row before
		rowTag			(string) row tag(s) to add. Example: <tr><td>stuff</td></tr>

********************************************************************************************************/
function addRow(beforeRow,rowTag) {
	// if beforeRow was passed as an id, grab a ref. to that row
	if (typeof(beforeRow) == 'string') beforeRow = document.getElementById(beforeRow);

	//var tb 		= document.getElementById('tbl');
	//var beforeRow = document.getElementById('prod_opts_last_row');
	var tbody 	= beforeRow.parentNode;

	// create new div to receive the dummy table
	var dummy_div = document.createElement('div');

	// add dummy table to dummy div
	dummy_div.innerHTML = '<table>'+ rowTag + '</table>';

	// grab reference to the content div
	var contentDiv = document.getElementById('cp_content');

	// store the scrollHeight before the row is added
	contentDiv.oldScrollHeight = contentDiv.scrollHeight;

	// grab reference to the row inside the dummy table
	var newRow, newRowCloned, newRowRef, i, scriptTags,scriptToEval;
	var dummyTbody = getFirstChildElement(getFirstChildElement(dummy_div));
	var numRows = dummyTbody.rows.length;
	for(i=0; i < numRows; i++) {
		newRow = dummyTbody.rows[0];

		// insert row in table, right before row specified
		// this in effect moves the row from dummyTbody to the target table,
		// which is why the index for dummyTbody.rows above doesn't increment
		newRowRef = tbody.insertBefore(newRow,beforeRow);

		/*********************************************************************
		When replacing the innerHTML in mozilla based browsers,
		any JS inside the new HTML is executed automatically. In IE and
		Safari, it is not. This fixes that by grabbing the JS and
		evaluating it.
		*********************************************************************/
		if (!isMoz) {
			// grab any script tags that are inside the new row
			scriptTags = newRowRef.getElementsByTagName('script');

			// loop thru them, and store the JS inside in a variable
			for(var s=0; s < scriptTags.length; s++) {
				scriptToEval += scriptTags[s].innerHTML;
			}
		}
	}

	// evaluate any JS found in new rows
	if (scriptToEval) eval(scriptToEval);

	// scroll up as needed, so the new row doesn't affect the scroll position
	var newScrollTop = contentDiv.scrollTop + contentDiv.scrollHeight - contentDiv.oldScrollHeight;
	if (newScrollTop > 0) contentDiv.scrollTop = newScrollTop;

	// return reference to new row
	return newRowRef;
}









/***************************************************************************************************************
	
	Purpose: to remove an element from the DOM
	
	Parameters:
		elem		- a reference to node to remove OR it's ID
		fixScroll	- adjust content area scroll to account for change in content height. Set to 0 to disable

***************************************************************************************************************/
function removeElement(elem,fixScroll){
	// bail if nothing passed
	if (!elem) return;

	// if id is passed, grab that element's reference
	if (typeof(elem) == 'string') elem = document.getElementById(elem);

	// bail if element not found
	if (!elem) return;

	// grab reference to the content div
	var contentDiv = document.getElementById('cp_content');

	// store the scrollHeight before the row is added
	contentDiv.oldScrollHeight = contentDiv.scrollHeight;

	// remove element via a call to removeChild
	elem.parentNode.removeChild(elem);

	// scroll up as needed, so the new row doesn't affect the scroll position
	var newScrollTop = contentDiv.scrollTop + contentDiv.scrollHeight - contentDiv.oldScrollHeight;
	if (newScrollTop > 0 && fixScroll != 0) contentDiv.scrollTop = newScrollTop;

	// For some reason, Safari goes crazy under certain circumstances, and causes the main content area to drop off screen
	// ONLY when DHTML menu builder code is in place. It has something to do with the scrolling for the main content div....
	// If enough vertical scrolling is present, the problem doesn't happen.
	// This makes a hack div appear below the copright notice only for Safari :(
	if (isSafari) {
		document.getElementById('safari_remove_element_hack').style.display = '';
	}
}









/***************************************************************************************************************

	Purpose:
		To loop through a collection of input fields, and return true IF value passed as needle matches (exactly)
		one of the field values
	
	Parameters:
		needle		(string)	string to look for
		haystack	(object)	array of input fields

***************************************************************************************************************/
function inFieldValues(needle,haystack) {
	// bail if parameters are ng
	if (typeof(needle) != 'string') return false;
	if (typeof(haystack) != 'object') return false;

	// loop thru each form field
	for(x=0;haystack[x];x++) {
		// if we found a match, return true
		if (haystack[x].value == needle) return true;
	}

	// if here, no matches where found
	return false;
}







/**************************************************************
	setfocus
	Delayed focus setting to get around IE bug
**************************************************************/
function setFocusDelayed()
{
	glb_vfld.focus()
}

function setFocus(vfld)
{
	// save vfld in global variable so value retained when routine exits
	glb_vfld = vfld;
	setTimeout( 'setFocusDelayed()', 100 );
}





/*************************************************************************************************

	Function formatDecimal
	
	Purpose: to take a number and format it to specified number of decimal places.
	
	From:
		Example File From "JavaScript and DHTML Cookbook"
		Published by O'Reilly & Associates
		Copyright 2003 Danny Goodman
	
	Parameters:
		num			(mixed) 	number in string or numeric format
		decplace	(integer)	number of decimal places for output
	
	Returns a string representation of the number

*************************************************************************************************/
function formatDecimal (num, decplaces) {
	// convert in case it arrives as a string value
	num = parseFloat(num);
	// make sure it passes conversion
	if (!isNaN(num)) {
		// multiply value by 10 to the decplaces power;
		// round the result to the nearest integer;
		// convert the result to a string
		var str = "" + Math.round (eval(num) * Math.pow(10,decplaces));
		// exponent means value is too big or small for this routine
		if (str.indexOf("e") != -1) {          return "Out of Range";
		}
		// if needed for small values, pad zeros
		// to the left of the number
		while (str.length <= decplaces) {
			str = "0" + str;
		}
		// calculate decimal point position
		var decpoint = str.length - decplaces;
		// assemble final result from: (a) the string up to the position of
		// the decimal point; (b) the decimal point; and (c) the balance
		// of the string. Return finished product.
		return str.substring(0,decpoint) + "." + str.substring(decpoint,str.length);
	} else {
		return "NaN";
	}
}



/********************************************************************************************************

	Function formatCommas
	
	Purpose:
		To return a string with commas inserted in appropriate places
	
	Parameters:
		numString	(string)	string representing integer portion of number.
	
	From:
		Example File From "JavaScript and DHTML Cookbook"
		Published by O'Reilly & Associates
		Copyright 2003 Danny Goodman

********************************************************************************************************/
function formatCommas(numString) {
	// strip out anything after a decimal, if present
	var re = /(\.\d*)/;
	var dec = numString.match(re)[0];

	// replace decimal in numString so it won't receive commas
	numString = numString.replace(dec,'');

	// add commas
	re = /(-?\d+)(\d{3})/;
	while (re.test(numString)) {
		numString = numString.replace(re, "$1,$2");
	}

	// add decimal back
	numString += dec;

	return numString;
}





/**********************************************************************************************************

	Function formatCurrency
	
	Purpose: to add commas and 2 decimal places to a number
	
	Parameters:
		num		(mixed)	string OR number

**********************************************************************************************************/
function formatCurrency(num) {
	if (typeof(num) != 'string') num = num.toString();
	return formatCommas(formatDecimal(num,2));
}




/**********************************************************************************************************

	Function setIFrameHeight
	
	Purpose:
		 to set the height of an iframe to match the contents of it's src
		 
	Info:
		To call this function, add it to the onload event handler of the <iframe /> tag, like this:
		<iframe onload="setIFrameHeight(this)" ...
	
	Parameters:
		iFrame - string id or reference to iframe

**********************************************************************************************************/
function setIFrameHeight(iFrame) {
	if (!iFrame) return;
	if (typeof(iFrame) == 'string') iFrame = document.getElementById(iFrame);
	var extraHeight = 0;
	if (isOpera) extraHeight = 16;
	iFrame.style.height = (iFrame.contentWindow.document.body.scrollHeight + extraHeight) + 'px';
	
	// hide the wait indicator
	var waitDiv = document.getElementById(iFrame.id.replace('post_frame_','post_frame_wait_'));
	if (waitDiv) waitDiv.style.display = 'none';
	
	// iframe is initially hidden...this displays it now that it's size is OK
	iFrame.style.visibility = 'visible';
}



// Trim whitespace from string
function trim(str)
{
   return str.replace(/^\s*|\s*$/g,"");
}

// function to validate an email address
function validEmail(str){
	return str.match(/^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/);
}


// doesn't allow HTML
function validNonHTML(str) {
	return !str.match(/<(\"[^\"]*\"|'[^']*'|[^'\">])*>/);
}

// function to validate a URL
function validURL(str) {
	return str.match(/^(ht|f)tp(s?)\:\/\/[a-zA-Z0-9-\._]+([a-zA-Z0-9\-\._]*(\.[a-zA-Z0-9\-\._]+){2,})?(\/?)([a-zA-Z0-9:\-\.\?\,\'\/\\\+&%\$#_~]*)?$/);	
}

// function to validate a folder portion of a URL
function validURLFolder(str) {
	return str.match(/^[_a-zA-Z0-9-]*$/);	
}

// function to validate integer - 0-9
function validInteger(str) {
	return str.match(/^[0-9]*$/); 
}

// function to validate integer OR decimal
// matches:
// 0
// 1
// 1.2
// 1.245
function validAmount(str) {
	return str.match(/^[0-9]*(\.[0-9]*)?$/); 
}






// return an array with only unique members
function arrayUnique(arr) {
    var newArray = [];
    var existingItems = {};
    var prefix = String(Math.random() * 9e9);
    for (var ii = 0; ii < arr.length; ++ii) {
        if (!existingItems[prefix + arr[ii]]) {
            newArray.push(arr[ii]);
            existingItems[prefix + arr[ii]] = true;
        }
    }
    return newArray;
}





/****************************************************************************************************
	Cookie functions
****************************************************************************************************/
function scCreateCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function scReadCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function scEraseCookie(name) {
	createCookie(name,"",-1);
}



// return the value of the radio button that is checked
// return an empty string if none are checked, or
// there are no radio buttons
function getRadioValue(radioObj) {
	if(!radioObj)
		return "";
	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

// set the radio button with the given value as being checked
// do nothing if there are no radio buttons
// if the given value does not exist, all the radio buttons
// are reset to unchecked
function setRadioValue(radioObj, newValue) {
	if(!radioObj)
		return;
	var radioLength = radioObj.length;
	if(radioLength == undefined) {
		radioObj.checked = (radioObj.value == newValue.toString());
		return;
	}
	for(var i = 0; i < radioLength; i++) {
		radioObj[i].checked = false;
		if(radioObj[i].value == newValue.toString()) {
			radioObj[i].checked = true;
		}
	}
}



/******************************************************************************************

	Purpose: to return a value entered as a CSS class name
	
	This is only here to get around XHTML validation when using custom attributes.
	While putting this info in a class name is not very semantic, it is 
	better than dealing with the problem of some validators not reading custom DTDs
	
	Example
		With HTML: <input id="fld1" class="fld price-5.95" ... />
		
		calling this will set a string eq. to '5.95':
		str = getPseudoAttribute('fld1', 'price-')
		
		
		With HTML: <input id="fld1" class="fld price" ... />
		
		calling this will set a string eq. to 'price':
		str = getPseudoAttribute('fld1', 'price')

******************************************************************************************/
function getPseudoAttribute(elemRef, attr) {
	elemRef = typeof(elemRef) == 'object' ? elemRef : document.getElementById(elemRef);

	// bail if object not found
	if (typeof(elemRef) != 'object') return null;
		
	var className = elemRef.className;
	
	if (!className) return null;
	
	// this will match attribute name, and anything after it up to a space
	// example, attribute name is "price_point-"
	// and class is setup like: class="blah price_point-5.59 yada"
	// this will return an array with the 2nd element set to "5.59"
	var re = new RegExp(attr + "([^\\s]*)\\s?");
	
	var attrMatch = className.match(re);
	
	// bail if we didn't get a match
	if (!attrMatch) return null;

	if (attrMatch[1]) {
		return attrMatch[1];
	} else if (attrMatch[0]) {
		return attrMatch[0];
	} else {
		return null;
	}
	
}




function ieFixDisabledOptions(sel) {

	// loop through options, and create an array representing them
	for(i=0; i < sel.options.length; i++) {
		if (sel.options[i].disabled) sel.options[i].selected = false;
	}	
}


/****************************************************************************************************
	Purpose of function is to toggle the display of option detail sections on the checkout form
****************************************************************************************************/
function toggleOptionDetail() {
	// grab all option detail divs
	var optDetailULs = getElementsByPartialId(document.body,'ul','opt_detail_');
	
	// loop thru all option detail sections
	if (optDetailULs) {
		for(var i=0;optDetailULs[i];i++) {
			swapDisplay(optDetailULs[i]);
		}
	}
}




/*************************************************************
	Handle things specific to account form
*************************************************************/
function acctForm(elem, evt) {
	if (elem.id == 'State_Other' && evt.type == 'keyup') {
		if (elem.value.length) {
			// set state or province field to 'Other'
			if (document.getElementById('State_or_Province')) document.getElementById('State_or_Province').value = 2
		}
	} else if (elem.id == 'State_or_Province' && evt.type == 'change') {
		if (document.getElementById('State_Other')) {
			var stateOther = document.getElementById('State_Other');
			if (elem.options[elem.selectedIndex].value == '2') {
				stateOther.value = '';
				stateOther.focus();
			} else {
				stateOther.value='';
			}
		}
	}
}




/*************************************************************
	Handle things specific to address form
*************************************************************/
function addrForm(elem, evt) {
	if (elem.id == 'Bill_State_Other' && evt.type == 'keyup') {
		if (elem.value.length) {
			// set state or province field to 'Other'
			if (document.getElementById('Bill_State_or_Province')) document.getElementById('Bill_State_or_Province').value = 2
		}
	} else if (elem.id == 'Ship_State_Other' && evt.type == 'keyup') {
		if (elem.value.length) {
			// set state or province field to 'Other'
			if (document.getElementById('Ship_State_or_Province')) document.getElementById('Ship_State_or_Province').value = 2
		}
	} else if (elem.id == 'Bill_State_or_Province' && evt.type == 'change') {
		if (document.getElementById('Bill_State_Other')) {
			var stateOther = document.getElementById('Bill_State_Other');
			if (elem.options[elem.selectedIndex].value == '2') {
				stateOther.value = '';
				stateOther.focus();
			} else {
				stateOther.value='';
			}
		}
	} else if (elem.id == 'Ship_State_or_Province' && evt.type == 'change') {
		if (document.getElementById('Ship_State_Other')) {
			var stateOther = document.getElementById('Ship_State_Other');
			if (elem.options[elem.selectedIndex].value == '2') {
				stateOther.value = '';
				stateOther.focus();
			} else {
				stateOther.value='';
			}
		}
	}
}






/*************************************************************
	Function copies fields from billing to shipping address
*************************************************************/
function addressCopy() {
	var form 	= document.address_form;
	var billFldId, shipFldId, billFld, shipFld;
	
	// loop thru fields
	for(x=0; x < form.elements.length; x++) {
		billFldId 	= form.elements[x].id;
		billFld		= form.elements[x];
		
		// if we are on a bill field
		if (billFldId.indexOf('Bill_') != -1) {
			// change id to matching ship field
			shipFldId = billFldId.replace('Bill_','Ship_');
			
			// grab ship field and set it
			shipFld = document.getElementById(shipFldId);
			if (shipFld) shipFld.value = billFld.value;
		}
	}
	
}



/*************************************************************
	On shipping rate page, shows/hides detailed info
*************************************************************/
var rateInfoState;
function toggleRateInfo(courierDivId){
	// grab all rate detail divs
	var rateDetails = getElementsByPartialId(courierDivId,'div','rate_detail_');
	
	for(x=0; x < rateDetails.length; x++) {
		swapDisplay(rateDetails[x]);
	}
}


/*************************************************************
	Payment method form stuff
*************************************************************/
function payMethodOn(fldId,methodType) {
	// grab radio option, and check it
	radio = document.getElementById(fldId);
	if (radio.type == 'radio') radio.checked = 1;
	
	paySectionOn(methodType);
}

function paySectionOn(methodType) {
	var ccSection = document.getElementById('pay_cc');
	var echeckSection = document.getElementById('pay_echeck');

	// first, hide them all
	if (ccSection && ccSection.className) ccSection.className =  ccSection.className.replace('sc_show','sc_hide');
	if (echeckSection && echeckSection.className) echeckSection.className =  echeckSection.className.replace('sc_show','sc_hide');
	
	if (methodType) {
		if (methodType == 'cc')	ccSection.className =  ccSection.className.replace('sc_hide','sc_show');
		if (methodType == 'echeck')	echeckSection.className =  echeckSection.className.replace('sc_hide','sc_show');
	}
}


/*************************************************************
	Unobtrusive popups via class="popup"
	
	Credit for this goes here:
	http://mar.anomy.net/entry/2004/02/09/12.17.47/
	
*************************************************************/
var popupLinkConfig = new Array;
// keys to array below represent class assigned to <a/>, to control popup appearance
popupLinkConfig["cvv2popup"] 			= new Array ( "", "width=650,height=400,scrollbars=1,menubar=1,resizable=1");
popupLinkConfig["ship_detail_popup"] 	= new Array ( "", "width=500,height=170,scrollbars=1,menubar=1,resizable=1");
popupLinkConfig["order_status_popup"] 	= new Array ( "", "width=300,height=150,scrollbars=1,menubar=1,resizable=1");
popupLinkConfig["medium_popup"] 		= new Array ( "", "width=625,height=400,scrollbars=1,menubar=1,resizable=1");

function scInitPopupLinks()
{
  if (!document.getElementsByTagName) return true;
  var pageLinks = document.getElementsByTagName("a");
  for (var i = 0; i < pageLinks.length; i++) 
  {
    if (((pageLinks[i].className != null) && 
         (pageLinks[i].className != "")) ||
        ((pageLinks[i].parentNode.className != null) && 
         (pageLinks[i].parentNode.className != "")))
    {
      var linkClass = " " + pageLinks[i].className + " ";
      if ((linkClass == "  ") && (pageLinks[i].parentNode.className != ""))
      {
        linkClass = " " + pageLinks[i].parentNode.className + " ";
      }
      for (var theKey in popupLinkConfig) 
      {
        if (linkClass.indexOf(" " + theKey + " ") > -1)
        {
          if ((pageLinks[i].target == "") || (pageLinks[i].target == null))
          {
            pageLinks[i].target = (popupLinkConfig[theKey][0] != "") ? popupLinkConfig[theKey][0] : theKey;
          }
          pageLinks[i].settings = popupLinkConfig[theKey][1];
          pageLinks[i].onclick = scPopUp;
        }
      }
    }
  }
  return true;
}

function scPopUp()
{
  newWin = window.open(this.href, this.target, this.settings);
  newWin.focus();
  return false;
} 





/*************************************************************
	This is used to manually show/hide a tooltip
*************************************************************/
function scShowToolTip(tipId) {
	var tipElem = document.getElementById(tipId);
	if (tipElem) tipElem.onmouseover();
}

function scHideToolTip(tipId) {
	var tipElem = document.getElementById(tipId);
	if (tipElem) tipElem.onmouseout();
}





/*************************************************************
	On storefront body load
*************************************************************/
function scOnLoad() {

	// disable auto complete for some fields without making XHTML invalid :(
	var qty = document.getElementById("quantity");
	if (qty) qty.setAttribute("autocomplete", "off");
	
	var cardNumber = document.getElementById("card_number");
	if (cardNumber) cardNumber.setAttribute("autocomplete", "off");
	
	var idNumber = document.getElementById("id_number");
	if (idNumber) idNumber.setAttribute("autocomplete", "off");
	
	var routeNumber = document.getElementById("bank_routing_number");
	if (routeNumber) routeNumber.setAttribute("autocomplete", "off");

	var bnkAcctNumber = document.getElementById("bank_account_number");
	if (bnkAcctNumber) bnkAcctNumber.setAttribute("autocomplete", "off");

		
	scInitPopupLinks();
}