// redirect if we're not using a secure connection (in case the user forgot to specify https as the protocol)// this can also be used to force a particular subdomain, in this case secure	function require_SSL() {		if (document.URL.indexOf("https://secure.") == -1) { 			document.write("<p class=subheading>Redirecting to a secure port...</p>");			location = "https://secure." + document.URL.substr(document.URL.indexOf("typea.net"), document.URL.length);		}	}// redirect if we no longer need a secure connection	function avoid_SSL() {		if (document.URL.indexOf("https://") != -1) { 			document.write("<p class=subheading>Redirecting to a standard port...</p>")			// use the same subdomain we're on right now; just change the protocol			location = "http://www." + document.URL.substr(document.URL.indexOf("typea.net"), document.URL.length);		}	}// load a different stylesheet for Mac or Windows// in your content file, just use a hard link to the platform that the files will most often be edited on// - you can set it to styles_mac.css during development, then change to styles_win.css at delivery// - since this runs on every page load, we've commented it out here; comment it back in if you need it	//platform = (navigator.platform.indexOf("Win") == -1) ? "mac" : "win" ;	//document.write("<link rel=stylesheet href=../content/styles_" + platform + ".css type=text/css>");// construct Flash object and embed tags// FlashVars should be a string of name/value pairs separated by ampersands	function get_flash_tags(filename, width, height, bgcolor, flashvars) {		name = filename;		if (name.indexOf("/")) { name = name.substring(name.lastIndexOf("/") + 1); }		if (name.indexOf(".")) { name = name.substring(0, name.indexOf(".")); }				output = '<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';		output += ' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"';		output += ' WIDTH="' + String(width) + '" HEIGHT="' + String(height) + '" id="' + name + '" name="' + name + '" ALIGN="">';		output += '<PARAM NAME=movie VALUE="' + filename + '"> <PARAM NAME=quality VALUE=high> <PARAM NAME=bgcolor VALUE=' + bgcolor + '> <EMBED src="' + filename + '" quality=high bgcolor=' + bgcolor + ' WIDTH="' + String(width) + '" HEIGHT="' + String(height) + '" NAME="' + name + '" ALIGN=""';		output += ' TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer" swLiveConnect="true"';		output += ' FlashVars="' + flashvars + '"></EMBED>';		output += '<PARAM NAME="FlashVars" VALUE="' + flashvars + '">';		output += '</OBJECT>';		return output;	}// try to do a LiveConnect command, or show an alert if that's not available			function try_live_connect(command) {		if (((navigator.appName.indexOf("Microsoft") != -1)&&(navigator.platform.indexOf("Mac") != -1)) || (navigator.appVersion.indexOf("Safari") != -1)) {			alert("We're sorry, that feature is not available in this browser.")		} else {			eval(command);		}	}	// set a cookie		// 02/15/03 - initial development	// 05/14/04 - expanded to allow saving multiple values within a single cookie	function set_cookie_OLD(name, value) {		// specify a default key-name prefix for this project		name_prefix = "projectname_";				// the following are cookie parameters are optional ... change values to null if you don't need them		hours = 43800;		path = "/";								domain = null;				key = name_prefix + name;				(hours) ? expiration_date = new Date((new Date()).getTime() + hours*3600000).toGMTString() : expiration_date = false;		cookie_string = key + '=' + escape(value) + ((expiration_date)?(';expires=' +expiration_date):'') + ((path)?(';path='+path):'') + ((domain)?(';domain='+domain):'');		document.cookie = cookie_string;	}		function set_cookie(name, key, value) {		// specify a default cookie name prefix for this project, to group cookies together		name_prefix = "project_";		value_exists = 0;				// the following cookie parameters are optional ... change values to null if you don't need them		hours = 43800;		path = "/";								domain = null;				cookie_value = get_cookie(name, "all"); // get the entire cookie string so we can update the values		key_value_array = cookie_value.split("&"); // split the cookie string into an array of key=value strings				// search through the list of key=value strings for the presence of the specified key		for (key_value=0; key_value<key_value_array.length; key_value++) {			if (key_value_array[key_value].indexOf(key + "=") == 0) {							// when we find it, overwrite the value of that array element				key_value_pair = key_value_array[key_value].split("=");				key_value_key = key_value_pair[0];				key_value_array[key_value] = key_value_key + "=" + escape(value);								// then combine the key=value strings back into a single string				cookie_value = key_value_array.join('&');				value_exists = 1; // flag this key as already being in the cookie string so that you don't add it to the cookie string again				break;			}		}				// if the cookie string doesn't already contain this key, add the key=value string		if (value_exists == 0) {			ampersand = (cookie_value != "") ? "&" : "" ;			cookie_value += ampersand + key + "=" + escape(value);		}				expiration_date = (hours) ? new Date((new Date()).getTime() + hours*3600000).toGMTString() : false ;		cookie_string = name_prefix + name + "=" + escape(cookie_value) + ((expiration_date)?(';expires=' +expiration_date):'') + ((path)?(';path='+path):'') + ((domain)?(';domain='+domain):'');		document.cookie = cookie_string;		}// get values from a cookie	// 02/15/03 - initial development	// 05/14/04 - expanded to allow saving multiple values within a single cookie	function get_cookie_OLD(name) {		var output_value;		if (document.cookie != "") {			// specify a default key-name prefix for this project			name_prefix = "projectname_";			cookie_array = document.cookie.split("; ");			for (n = 0; n < cookie_array.length; n++) {				cookie_pair = cookie_array[n].split("=");				key = cookie_pair[0];				value = cookie_pair[1];										if (key == (name_prefix + name)) {					output_value = unescape(value);					break;				} else {					output_value = "";				}			}		} else {			output_value = "";		}		return output_value;	}		function get_cookie(name, key) {			name_prefix = "project_"; // specify a default cookie name prefix for this project, to group cookies together		output_value = "";				if (document.cookie != "") {			cookie_array = document.cookie.split("; ");			// search for the cookie with this name			for (cookie=0; cookie < cookie_array.length; cookie++) {				if (cookie_array[cookie].indexOf(name_prefix + name + "=") == 0) {					cookie_pair = cookie_array[cookie].split("=");					cookie_value = unescape(cookie_pair[1]); // the value is the list of key=value strings that we saved into this cookie						if (key == "all") {						output_value = cookie_value;						break;					} else {						key_value_array = cookie_value.split("&");											// search through the list of key=value strings for the value of the requested key						for (key_value=0; key_value<key_value_array.length; key_value++) {							if (key_value_array[key_value].indexOf(key + "=") == 0) {															key_value_pair = key_value_array[key_value].split("=");								output_value = unescape(key_value_pair[1]);								break;																	}							}											}									}			}					}				return output_value;			}		// provide buttons for saving and loading form values with a cookie// this is primarily used to streamline development and testing, but it could have real-world applications as well	// 03/01/05 - initial development	// 07/15/05 - added length check to checkbox and radio button groups to avoid an error when those groups only contain one element	function show_form_cookie_buttons(form_name) {		output = "";		output += "<a href=\"JavaScript:form_cookie_save('" + form_name + "')\">Save form values</a><br>";		output += "<a href=\"JavaScript:form_cookie_load('" + form_name + "')\">Load form values</a>";		return output;	}	function form_cookie_save(form_name) {		last_name = "";		eval("this_form = document." + form_name);		for (n=0; n<this_form.length; n++) {			value = "";			if (this_form[n].type != "hidden") { // don't save hidden values				if (this_form[n].name != last_name) { // don't process the checkbox and radio groups more than once					if ((this_form[n].type == "text")||(this_form[n].type == "textarea")||(this_form[n].type == "password")) {						value = this_form[n].value;					} else if (this_form[n].type == "select-one") {						value = this_form[n].selectedIndex;					} else if (this_form[n].type == "select-multiple") {						values = new Array();						for (nn=0; nn<this_form[n].options.length; nn++) {							if (this_form[n].options[nn].selected) {								values[values.length] = nn;							}						}						value = values.join(",");					} else if (this_form[n].type == "checkbox") {						eval("this_group = this_form." + this_form[n].name);						if (this_group.length > 0) {							values = new Array();							for (nn=0; nn<this_group.length; nn++) {								if (this_group[nn].checked) {									values[values.length] = nn;								}							}							value = values.join(",");						} else {							value = "0";						}					} else if (this_form[n].type == "radio") {						eval("this_group = this_form." + this_form[n].name);						if (this_group.length > 0) {							for (nn=0; nn<this_group.length; nn++) {								if (this_group[nn].checked) {									value = nn;									break;								}							}						} else {							value = "0";						}					}					//alert(this_form[n].name + " = " + value);					set_cookie(form_name, this_form[n].name, value);					last_name = this_form[n].name;				}			}		}	}		function form_cookie_load(form_name) {		last_name = "";		eval("this_form = document." + form_name);		for (n=0; n<this_form.length; n++) {			value = "";			if (this_form[n].type != "hidden") { // don't load hidden values				if (this_form[n].name != last_name) { // don't process the checkbox and radio groups more than once					value = get_cookie(form_name, this_form[n].name, value);					//alert(this_form[n].name + " = " + value);					if ((this_form[n].type == "text")||(this_form[n].type == "textarea")||(this_form[n].type == "password")) {						this_form[n].value = value;					} else if (this_form[n].type == "select-one") {						this_form[n].selectedIndex = value;					} else if (this_form[n].type == "select-multiple") {						values = value.split(",");						for (nn=0; nn<values.length; nn++) {							this_form[n].options[values[nn]].selected = true;						}					} else if (this_form[n].type == "checkbox") {						eval("this_group = this_form." + this_form[n].name);						if (this_group.length > 0) {							values = value.split(",");							for (nn=0; nn<values.length; nn++) {								this_group[values[nn]].checked = true;							}						} else {							if (value === "0") {								this_group.checked = true;							}						}					} else if (this_form[n].type == "radio") {						eval("this_group = this_form." + this_form[n].name);						if (this_group.length > 0) {							this_group[value].checked = true;						} else {							if (value === "0") {								this_group.checked = true;							}						}					}					last_name = this_form[n].name;				}			}		}	}// grab all name/value pairs from the URL and create JavaScript variables from them	function get_vars() {			if (location.href.indexOf('?') != -1) {					query_string = location.href.substring(location.href.indexOf('?') + 1, location.href.length);			query_pairs = query_string.split("&");						for (n=0; n < query_pairs.length; n++) {				pair = query_pairs[n].split("=");				key = pair[0];				value = pair[1];				eval(key + " = '" + value + "'");			}						if (query_string.indexOf("args=") != -1) {				args_pieces = args.split(",");				for (n=0; n < args_pieces.length; n++) {					nn = n + 1;					eval("arg" + nn + " = '" + args_pieces[n] + "'");				}			}				} else {			query_string = ""; query_pairs = ""; template = ""; args = "";		}				}	// decide whether we've been flattened or not	function is_flattened() {		return ((location.href.indexOf("flattened") != -1)&&(location.href.indexOf(".html") != -1));	}// return a path to a page, given a page name, in either a flattened or unflattened format// change script_extension depending on what version of Contemplate we're using	function format_page_name(page_name) {		script_extension = "php";		if (is_flattened()) {			page_name_formatted = "../flattened/" + page_name + ".html";		} else {			page_name_formatted = "../contemplate/assembler." + script_extension + "?page=" + page_name;		}		return page_name_formatted;	}			// gets the name of the current page, even if we're rewriting URLs	function get_page_name() {		if (location.href.indexOf("page=") != -1) {			page_name = location.href.substring(location.href.indexOf('page=') + 5, location.href.length);		} else {			page_name = location.href.substring(location.href.lastIndexOf('/') + 1, location.href.indexOf('.htm'));		}		return page_name;	}		// trim whitespace from before and after a string	function trim(string) {		string = String(string);		//string = string.replace(/^\s*(.*?)\s*$/, "$1"); // this single line should work instead of the following two lines, but the ? to make the middle part less greedy throws an error in Mac IE, where that modifier is apparently not supported		string = string.replace(/^\s*/, "");		string = string.replace(/\s*$/, "");		return string;	}		// return a value up to the delimiter, or the original value if the delimiter isn't there// - this is used most often when parsing an argstring to set button states	function crop(value, delimiter) {		result = (value.indexOf(delimiter) != -1) ? value.substring(0, value.indexOf(delimiter)) : value ;		return result;	}	// open a popup window, specifying source, width, and height, and optionally a name; if no name, choose a random one	function popup(source, width, height, window_name) {			if (! window_name) { 				now = new Date();				window_name = now.getTime();			} else {				window_name = window_name.replace(/ /g, "_");			}						popup_window = window.open(source, window_name, "width=" + String(width) + ",height=" + String(height) + ",location=no,menubar=no,directories=no,toolbar=no,scrollbars=yes,resizable=yes,status=yes");			popup_window.focus();			// return popup_window; // oops, this creates a weird behavior in Firefox and Win/IE	}// show an email link on a page in a way that spam harvesters can't see	function email(user, domain, tld) {		location = "mailto:" + user + "@" + domain + "." + tld;	}// write a random element from the specified array	function write_random(array_name) {		which = (Math.round(Math.random() * (arrayName.length - 1)));		document.write(array_name[which]);	}// the simplest possible rollover function	function swap(name, state) {		eval('document.images.' + name + '.src = ' + name + '_' + String(state) + '.src');	}		// rollover function for type="image"	function swap_submit(name, state) {			eval('this_image = ' + name.id + '_' + String(state) + '.src');		name.src = this_image;	}	// rollovers with sticky highlights// - used in navigation frames where the buttons persist but other pages are changing	var previous = null;	var current = null;	function sticky_swap(name, state, hold) {		if (hold == 1) {			// set previously lit button to normal			previous = current;			if (previous != null) {				eval('document.images.' + previous + '.src = ' + previous + '_0.src');			}		}		if ((name != null) && (name != current)) {			// set new button state			eval('document.images.' + name + '.src = ' + name + '_' + String(state) + '.src');			if (hold == 1) { current = name; }		}	}	// rollovers with separate but linked button and label graphics// - highlights both the button and label if you mouse over either one // - requires graphics to be named like "button_0.gif" and "button_label_0.gif"	function label_swap(name, state) {		eval('document.images.' + name + '.src = ' + name + '_' + String(state) + '.src');				// change the label if one exists		if (eval('document.images.' + name + '_label')) {			eval('document.images.' + name + '_label.src = ' + name + '_label_' + String(state) + '.src');		}				// change the button if this is a label		if (name.indexOf("_label") != -1) {			name = name.substr(0, (name.length - 6));			if (eval('document.images.' + name)) {				eval('document.images.' + name + '.src = ' + name + '_' + String(state) + '.src');			}		}	}	// write a block of code that preloads a list of graphics// - this version makes on and off states and is most often used for button rollovers// names - a comma-delimited list of button names (e.g. "home,about,contact")// path - the path to the graphics; defaults to "../graphics" if not set (e.g. "../graphics/menus/home")// extension - the file extension of the graphics files; defaults to "gif" if not set (e.g. "jpg")	function preload_buttons(names, path, extension) {		names = names.split(",");		path = (path) ? path : "../graphics" ;		extension = (extension) ? extension : "gif" ;		for (n=0; n < names.length; n++) {			this_name = names[n];			this_path = path + "/" + this_name;			eval(this_name + "_0 = new Image()");			eval(this_name + "_0.src = '" + this_path + "_0." + extension + "'");			eval(this_name + "_1 = new Image()");			eval(this_name + "_1.src = '" + this_path + "_1." + extension + "'");			eval(this_name + "_2 = new Image()");			eval(this_name + "_2.src = '" + this_path + "_2." + extension + "'");			eval(this_name + "_3 = new Image()");			eval(this_name + "_3.src = '" + this_path + "_3." + extension + "'");			eval(this_name + "_5 = new Image()");			eval(this_name + "_5.src = '" + this_path + "_5." + extension + "'");		}	}	// write a block of code that preloads a list of graphics// - this version just makes an on state and is most often used for tips associated with button rollovers// names - a comma-delimited list of button names (e.g. "home,about,contact")// path - the path to the graphics; defaults to "../graphics" if not set (e.g. "../graphics/menus/home")// extension - the file extension of the graphics files; defaults to "gif" if not set (e.g. "jpg")	function preload_tips(names, path, extension) {		names = names.split(",");		path = (path) ? path : "../graphics" ;		extension = (extension) ? extension : "gif" ;		for (n=0; n < names.length; n++) {			this_name = names[n];			this_path = path + "/" + this_name;			eval(this_name + " = new Image()");			eval(this_name + ".src = '" + this_path + "." + extension + "'");		}	}	// write a block of code that preloads a list of graphics// - this version uses the same source file for each instance and is most often used for markers associated with button rollovers// names - a comma-delimited list of instance names (e.g. "home_marker,about_marker,contact_marker")// marker_name - the base name of the marker graphic// path - the path to the graphics; defaults to "../graphics" if not set (e.g. "../graphics/menus/home")// extension - the file extension of the graphics files; defaults to "gif" if not set (e.g. "jpg")	function preload_markers(names, marker_name, path, extension) {		names = names.split(",");		path = (path) ? path : "../graphics" ;		extension = (extension) ? extension : "gif" ;		for (n=0; n < names.length; n++) {			this_name = names[n];			this_path = path + "/" + marker_name;			eval(this_name + "_0 = new Image()");			eval(this_name + "_0.src = '" + this_path + "_0." + extension + "'");			eval(this_name + "_1 = new Image()");			eval(this_name + "_1.src = '" + this_path + "_1." + extension + "'");		}	}	// leave this here to catch calls to the original preload script	function make_preloads(names, path) {		preload_buttons(names, path);	}	// figure out whether a variable has been set or not without generating an undefined error if it hasn't	function isset(variable) {		eval("result = (typeof(" + variable + ") != 'undefined')");		return result;	}	// returns the index of an array element, something that ought to be built into JavaScript but isn't!// returns -1 if not present	function get_position(string, array) {		for (n=0; n < array.length; n++) {			if (array[n] == string) {				return n;				break;			}		}		return -1;	}// sets a menu to a given text or value	function set_menu(form_name, field_name, text_or_value, key) {		eval("these_options = document." + form_name + "." + field_name + ".options");		for (n=0; n < these_options.length; n++) {			eval("this_text_or_value = these_options[n]." + text_or_value);			if (this_text_or_value == key) {				eval("document." + form_name + "." + field_name + ".selectedIndex = " + n);				break;			}		}		return "";	}// set date menus to a new SQL-standard date// leave date blank to select today's date// set to -1 to clear the menu	function select_date(form_and_menu, new_date) {		if (new_date != "-1") {			if (new_date == "") {				date = new Date();								day = date.getDate();				month = date.getMonth() + 1;				year = date.getFullYear();							} else {				date = new_date;								year = date.substring(0, date.indexOf("-"));				month = date.substring(date.indexOf("-") + 1, date.lastIndexOf("-"));				day = date.substring(date.lastIndexOf("-") + 1);							}								eval("document." + form_and_menu + "_month.selectedIndex = month");			eval("document." + form_and_menu + "_day.selectedIndex = day");			eval("document." + form_and_menu + "_year.selectedIndex = year - document." + form_and_menu + "_year.options[1].value + 1");		} else {			eval("document." + form_and_menu + "_month.selectedIndex = 0");			eval("document." + form_and_menu + "_day.selectedIndex = 0");			eval("document." + form_and_menu + "_year.selectedIndex = 0");		}	}// set time menus to a new SQL-standard time// leave time blank to select the current time	function select_time(form_and_menu, new_time) {		if (new_time != "-1") {			if (new_time == "") {				time = new Date();								hours = time.getHours();				minutes = time.getMinutes();				seconds = time.getSeconds();							} else {				time = new_time;								hours = time.substring(0, time.indexOf(":"));				minutes = time.substring(time.indexOf(":") + 1, time.lastIndexOf(":"));				seconds = time.substring(time.lastIndexOf(":") + 1);							}								if (hours >= 12) {				ampm_index = 2;				if (hours > 12) {					hours = hours - 12;				}			} else {				ampm_index = 1;				if (hours == 0) {					hours = 12;				}			}			eval("document." + form_and_menu + "_hours.selectedIndex = hours");			eval("document." + form_and_menu + "_minutes.selectedIndex = minutes + 1");			eval("document." + form_and_menu + "_seconds.selectedIndex = seconds + 1");			eval("document." + form_and_menu + "_ampm.selectedIndex = " + ampm_index);		}	}// set a base text size for each platform; can be used in conjunction with static font tags for face and color// remember to close this tag with a static </font> later in your document		function text_size(mac, win) {		if (navigator.appVersion.indexOf("Mac") != -1) {			document.write("<font face=geneva,arial size=" + mac + ">");		} else {			document.write("<font face=geneva,arial size=" + win + ">");		}	}// jumble up some text for safer transfer in places where cookies or PHP encryption can't go	// 08-27-04 - we're no longer removing and restoring spaces; that should be the job of the code before and after calling this function, since it is not always desirable	function pseudo_crypt(input, direction, key) { 		output = "";		palette = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+&=:/"; // any other characters will be untouched		key = "everygoodboydeservesfudge"; // can only contain members of palette		key_position = 0;		for (n=0; n < input.length; n++) {			input_char = palette.indexOf(input.charAt(n));			if (input_char != -1) {				key_char = key.charAt(key_position);				offset = palette.indexOf(key_char);				if (direction == 1) {					offset = ((input_char + offset) > (palette.length - 1)) ? offset - palette.length : offset ;					output += palette.charAt(input_char + offset);				} else {					offset = ((input_char - offset) < 0) ? offset - palette.length : offset ;					output += palette.charAt(input_char - offset);				}				key_position++;				key_position = (key_position > key.length) ? 0 : key_position ;			} else {				output += input.charAt(n);			}		}		return output;	}		// pass arguments into a frameset document to automatically set any of the frame locations// place  onload=setFrames()  into the frameset tag, then include  framename=location.html  in your URL	function set_frames() {		if (location.href.indexOf('?') != -1) {			query_string = location.href.substring(location.href.indexOf('?') + 1, location.href.length);			query_pairs = query_string.split("&");						for (n=0; n < query_pairs.length; n++) {								pair = query_pairs[n].split("=");				key = pair[0];				value = pair[1];								for (nn=0; nn < frames.length; nn++) {					if (key == frames[nn].name) {						eval(key + ".location = '" + value + "'");						break;					}				}							}		}	}		// create list of form element names and store in hidden variable to be used to validate the form	function set_form_elements(this_form) {		var form_elements = ""		var num_elements = eval("document."+this_form+".elements.length");				// loop through all form elements		for(i=0;i<num_elements;i++){			element_array = form_elements.split(",");						// loop through element list to see if element already exists in list			this_element = eval("document."+this_form+".elements[i].name");			exists = 0;			for(j=0; j<element_array.length; j++){				if (this_element == element_array[j])	{					exists = 1;					j = element_array.length;				}			}						if((exists == 0) && (this_element != 'form_elements')  && (this_element != 'submit') && (this_element != 'form_name') && (this_element != 'next_page')  && (this_element != 'button_view') && (this_element != 'this_action') && (this_element != 'button_submit')){				form_elements += this_element;				form_elements += ",";			}		}				form_elements = form_elements.substring(0,form_elements.length - 1); // remove trailing ,		eval("document."+this_form+".form_elements.value = form_elements"); // set hidden variable	}	// this is handy for preventing the Return key from submitting forms (set form action to "JavaScript:nothing()")		function nothing() {}		