/* Debugging */

// assert function
function assert(fact) {
     if (!fact) {
          alert("Assert failure!");
     }
}

// show all the properties of element elm in a new window
function inspect(elm){
	var win0=window.open("","Inspector","width=500");
	var d = win0.document;
		d.write("<html><head><title>Inspector List</title></head><body>");
		d.writeln("<b>Properties of element: " + elm + "</b><br>");
	var str = "";
	for (var i in elm){
		str = i + ": " + elm.getAttribute(i) + "\n";
			d.write(str + '<br>')
	}
	d.write("</body></html>");
}

// show all the properties of theObject in a new window
function showProperties(theObject) {
	var win0=window.open("",theObject);
	var d = win0.document;
		d.write("<html><head><title>Properties List</title></head><body>");
		d.writeln("Properties of object: " + theObject.name);
		for (property in theObject) {
			d.write('<p><b>' + property + ':</b><br>' + theObject[property] + '</p>')
	}
	d.write("</body></html>");
}


// show all the plugins of the current browser in a new window
function showPlugins() {
	var win0=window.open("",'Plugins');
	var d = win0.document;
	var L = navigator.plugins.length
		d.write("<html><head><title>Plugins List</title></head><body>");
	d.write( L );
	d.write(" Plugins".bold());
	d.write("<BR>");
	d.write("Name | Filename | description".bold());
	d.write("<BR>");
	for(i=0; i<L; i++){
		d.write(navigator.plugins[i].name);
		d.write(" | ".bold());
		d.write(navigator.plugins[i].filename);
		d.write(" | ".bold());
		d.write(navigator.plugins[i].description);
		d.write("<BR><BR>");
	}
	d.write("</body></html>");
}



/* Misc. functions */

// return date & time formatted m/d/yyyy h:m:s A.M./P.M.

function today() {
	var date = new Date()
	
	var day = date.getDate()
	var month = date.getMonth() + 1
	var year = date.getFullYear()
	var dateF = "" + month + "/" +  day + "/" + year
	
	var hour = date.getHours()
	var minute = date.getMinutes()
	var second = date.getSeconds()
	var timeF = "" + ((hour > 12) ? hour - 12 :  hour)
	if (hour == 0)
	timeF = "12";
	timeF += ((minute < 10) ? ":0" : ":") +  minute
	timeF += ((second < 10) ? ":0" : ":") +  second
	timeF += (hour >= 12) ? " P.M." : " A.M."
	return dateF + " - " + timeF
} 


// create a one dimensional js array from comma delimited list of items

function createArray() {
	this.length = createArray.arguments.length;
	for (var i = 0; i < this.length; i++) {
	this[i] = createArray.arguments[i];
	}
}


// create JS associative array from comma delimited strings of keys & corresponding values

function createObject(keys, values) {
	this.length = values.length;
	for (var i = 0; i < this.length; i++) {
	this[i] = keys[i] + ":" + values[i];
	}
}


// preload images function

function preloadimages() {
	for (i=0;i<preloadimages.arguments.length;i++){
		myimages[i]=new Image()
		myimages[i].src=preloadimages.arguments[i]
	}
}


// Shadowed Text

function shadText(theText,font,color,size) {
	window.document.write("<font color='#999999' style=' font-size: " + size + "; font-family: " + font + "'><b>" + theText + "</b></font><br><font color='" + color + "' style='position: relative; left: -.15em; top: -1.25em; font-size: " + size + "; font-family: " + font + "'><b>" + theText + "</b></font>");
	window.document.write("<p>");
}


// black text fade in

function fadeInText(textID){ 
	hex = 230; // initialize text to white
	theID = textID;
	textFadeIn(textID);
}

function textFadeIn(){ 
	document.getElementById(theID).style.visibility="visible";
	if(hex>0) { //if color is not black yet
		hex-=11; // decrease color brightness
		document.getElementById(theID).style.color="rgb("+hex+","+hex+","+hex+")";
		setTimeout("textFadeIn()",30); 
	}
	else
	hex=255 //reset hex value
}


// item crossfade from acolor to bcolor

function crossFadeItem(itemID,acolor,bcolor){ 
	n=25; // number of increments
	theID=itemID;
	var acolor6=hex3to6(acolor);
	var bcolor6=hex3to6(bcolor);
	finalcolor="#"+bcolor6;
	var br="0x"+bcolor6.substr(0,2);
	var bg="0x"+bcolor6.substr(2,2);
	var bb="0x"+bcolor6.substr(4,2);
	curr="0x"+acolor6.substr(0,2);
	curg="0x"+acolor6.substr(2,2);
	curb="0x"+acolor6.substr(4,2);
	rdecr=(curr-br)/n;
	gdecr=(curg-bg)/n;
	bdecr=(curb-bb)/n;
	i=1; // initilize counter
	itemCrossFade();
}

function itemCrossFade(){ 
	if(i<n) { 
		curr-=rdecr;
		curg-=gdecr;
		curb-=bdecr;
		curcolor="rgb("+curr.toFixed()+","+curg.toFixed()+","+curb.toFixed()+")";
		i+=1; // increment counter
		
		document.getElementById(theID).style.color=curcolor;
		setTimeout("itemCrossFade()",20); 
	}
	else
	document.getElementById(theID).style.color=finalcolor;
}

function hex3to6(incolor) { 
	if (incolor.charAt(0)=='#') incolor=incolor.substring(1);
	var thecolor = incolor.charAt(0);
	if (incolor.length==3) {
	thecolor+=incolor.charAt(0)+
		incolor.charAt(1)+incolor.charAt(1)+
		incolor.charAt(2)+incolor.charAt(2)
	}
	else thecolor=incolor;
	return thecolor;
}


// black text fade out

function fadeOutText(textID){ 
	hex = 0; // initialize text to black
	theID = textID;
	textFadeOut(textID);
}

function textFadeOut(){ 
	if(hex<200) { //if color is not gone yet
		hex+=11; // increase color brightness
		document.getElementById(theID).style.color="rgb("+hex+","+hex+","+hex+")";
		setTimeout("textFadeOut()",20); 
	}
	else
	document.getElementById(theID).style.visibility="hidden";
}



// create new window with all forms data

function displayFormData() {
	win2=open("",'window2');
	win2.document.open('text/plain');
	win2.document.writeln('This document has '+ document.forms.length+'forms.<br>');
	for(i=0;i<document.forms.length;++i) {
		win2.document.writeln('form '+i+' has '+document.forms[i].elements.length+' elements.<br>');
		for(j=0;j<document.forms[i].elements.length;++j) {
			win2.document.writeln((j+1)+' A '+document.forms[i].elements[j].type+' element: '+document.forms[i].elements[j].name+' - value: '+document.forms[i].elements[j].value+'<br>');
		}
	}
	win2.document.close()
	return false	
} // end displayFormData


// not supported alert function
function notSupported(){ alert('this operation is not supported by your browser.'); }

// HTML Title element support check

function setDtext(str){
  if(document.title){
    document.title=str;
    if(document.title!=str) notSupported();
  }
  else notSupported();
}
function setTEtext(str){
  if(document.getElementsByTagName)
    (document.getElementsByTagName('TITLE'))[0].text=str;
  else notSupported();
}
function br(ids,attr){
  if(document.getElementById) document.getElementById(ids).clear=attr;
  else notSupported();
}


/* Popups */

// Popup Image - requires dummy <img name="popup">
function imgPopUp(curimage) { 
	document.popup.src = curimage; 
} 


// Popup Image in new window

function winPopUp(source,theTitle,NOwidth,NOheight) { 
	var win0 = window.open("",theTitle,"left=100,top=150,toolbar=no,dependent=yes,directories=no,menubar=no,scrollbars=no,resizable=no,dependent,width=0,height=0");
	win0.opener.focus();
	
	var d = win0.document;
	d.write("<html><head><title>" + theTitle + "</title></head>");
	d.write("<body onclick=self.close();onblur=self.close();>");
	d.write('<img src="' + source + '" onload="window.resizeTo(this.width+25, this.height+40);">');
	d.write("</body></html>");
	d.close();
//	win0.moveTo(100,150);
	win0.focus();
//	win0.stop();
} 


// Popup Image in new window - requiring width and height inputs
// works in Netscape & IE, but in Safari onblur=self.close doesn't work.

function winPopUpBESTSOFAR(source,theName,width,height) { 
	var win0=window.open("",theTitle,"toolbar=no,dependent=yes,directories=no,menubar=no,scrollbars=no,resizable=no,width=" + (Number(width) + 20) + ",height=" + (Number(height) + 35));
		var d = win0.document;
		d.write("<html><head><title>" + theTitle + "</title></head>");
		d.write("<body onclick=self.close() onblur=self.close();>");
		d.write("<img src=" + source + "></body></html>");
} 


// Popup Image in new window - DOM version
// ©2004 Ted R. King, Jr.
// Opens new window, theName, if not already open.
// Loads/replaces image from file source & matches widow size to fit.
// ***** works fine in Netscape - opens big blank windows in safari - gives js error in Mac MSIE 5.23

function winPopUpDOM(source,theName,width,height) { 

	var win0=window.open("",theName,'toolbar=no,directories=no,menubar=no,scrollbars=no,resizable=no');
	var d = win0.document;
	
		alert("node 0: " + d.childNodes[0].nodeName); // html
//		alert("node 1: " + d.childNodes[1].nodeName); // HTML
//		alert("node 1,0: " + d.childNodes[1].childNodes[0].nodeName); // HEAD
//		alert("node 1,1: " + d.childNodes[1].childNodes[1].nodeName); // BODY

	// create image element theImg with src source and id 'pic'
	var theImg = d.createElement("img");
	theImg.setAttribute('src', source);
	theImg.setAttribute('id', 'image1');
			
	if(d.images[0] == undefined) {
	
		// new window2 - has no images
		
		// load title (doesn't work)
		var title = d.createTextNode(source);
		d.childNodes[1].childNodes[0].childNodes[0].replaceChild(title, d.childNodes[1].childNodes[0].childNodes[0].childNodes[0]);

		// create image node with theImg
		d.childNodes[1].childNodes[1].appendChild(theImg);
	}
	else {
		// existing window2 - replace image id 'pic'
		d.childNodes[1].childNodes[1].replaceChild(theImg,d.getElementById('image1'));
	}
	
	with (win0) {
		if(sizeToContent) sizeToContent();
		
		moveTo(100,150);

		if(focus) focus();		
	}
}


// popup from old BTF site - modified 8/19/04 

function MM_openBrWindow(theURL,winName,features) 
{
/* 	window.open(theURL,winName,features); */
	window2=window.open(theURL,'newWindow','toolbar=no,directories=no,menubar=no,scrollbars=no,resizable=no,width=320,height=412');
		if(window2.focus) window2.focus();
		window2.moveTo(100,150);
		window2.resizeTo(width,height);
}


// popup window

function RefWindow(RefURL)
{ Ref_Window = window.open(RefURL,"plain","scrollbars,resizable,width=500,height=500"); }


// for layered popups


// Copyright © 2000 by Apple Computer, Inc., All Rights Reserved.
//
// You may incorporate this Apple sample code into your own code
// without restriction. This Apple sample code has been provided "AS IS"
// and the responsibility for its operation is yours. You may redistribute
// this code, but you are not permitted to redistribute it as
// "Apple sample code" after having made changes.
// ********************************
// application-specific functions *
// ********************************

// store variables to control where the popup will appear relative to the cursor position
// positive numbers are below and to the right of the cursor, negative numbers are above and to the left
var xOffset = 30;
var yOffset = -5;

function showPopup (targetObjectId, eventObj) {
    if(eventObj) {
	// hide any currently-visible popups
	hideCurrentPopup();
	// stop event from bubbling up any farther
	eventObj.cancelBubble = true;
	// move popup div to current cursor position 
	// (add scrollTop to account for scrolling for IE)
	var newXCoordinate = (eventObj.pageX)?eventObj.pageX + xOffset:eventObj.x + xOffset + ((document.body.scrollLeft)?document.body.scrollLeft:0);
	var newYCoordinate = (eventObj.pageY)?eventObj.pageY + yOffset:eventObj.y + yOffset + ((document.body.scrollTop)?document.body.scrollTop:0);
	moveObject(targetObjectId, newXCoordinate, newYCoordinate);
	// and make it visible
	if( changeObjectVisibility(targetObjectId, 'visible') ) {
	    // if we successfully showed the popup
	    // store its Id on a globally-accessible object
	    window.currentlyVisiblePopup = targetObjectId;
	    return true;
	} else {
	    // we couldn't show the popup, boo hoo!
	    return false;
	}
    } else {
	// there was no event object, so we won't be able to position anything, so give up
	return false;
    }
} // showPopup

function hideCurrentPopup() {
    // note: we've stored the currently-visible popup on the global object window.currentlyVisiblePopup
    if(window.currentlyVisiblePopup) {
	changeObjectVisibility(window.currentlyVisiblePopup, 'hidden');
	window.currentlyVisiblePopup = false;
    }
} // hideCurrentPopup



// ***********************
// hacks and workarounds *
// ***********************

// initialize hacks whenever the page loads
window.onload = initializeHacks;

// setup an event handler to hide popups for generic clicks on the document
document.onclick = hideCurrentPopup;

function initializeHacks() {
    // this ugly little hack resizes a blank div to make sure you can click
    // anywhere in the window for Mac MSIE 5
    if ((navigator.appVersion.indexOf('MSIE 5') != -1) 
	&& (navigator.platform.indexOf('Mac') != -1)
	&& getStyleObject('blankDiv')) {
	window.onresize = explorerMacResizeFix;
    }
    resizeBlankDiv();
    // this next function creates a placeholder object for older browsers
    createFakeEventObj();
}

function createFakeEventObj() {
    // create a fake event object for older browsers to avoid errors in function call
    // when we need to pass the event object to functions
    if (!window.event) {
	window.event = false;
    }
} // createFakeEventObj

function resizeBlankDiv() {
    // resize blank placeholder div so IE 5 on mac will get all clicks in window
    if ((navigator.appVersion.indexOf('MSIE 5') != -1) 
	&& (navigator.platform.indexOf('Mac') != -1)
	&& getStyleObject('blankDiv')) {
	getStyleObject('blankDiv').width = document.body.clientWidth - 20;
	getStyleObject('blankDiv').height = document.body.clientHeight - 20;
    }
}

function explorerMacResizeFix () {
    location.reload(false);
}



// Copyright © 2000 by Apple Computer, Inc., All Rights Reserved.
//
// You may incorporate this Apple sample code into your own code
// without restriction. This Apple sample code has been provided "AS IS"
// and the responsibility for its operation is yours. You may redistribute
// this code, but you are not permitted to redistribute it as
// "Apple sample code" after having made changes.
//
// ************************
// layer utility routines *
// ************************

function getStyleObject(objectId) {
    // cross-browser function to get an object's style object given its id
    if(document.getElementById && document.getElementById(objectId)) {
	// W3C DOM
	return document.getElementById(objectId).style;
    } else if (document.all && document.all(objectId)) {
	// MSIE 4 DOM
	return document.all(objectId).style;
    } else if (document.layers && document.layers[objectId]) {
	// NN 4 DOM.. note: this won't find nested layers
	return document.layers[objectId];
    } else {
	return false;
    }
} // getStyleObject

function changeObjectVisibility(objectId, newVisibility) {
    // get a reference to the cross-browser style object and make sure the object exists
    var styleObject = getStyleObject(objectId);
    if(styleObject) {
	styleObject.visibility = newVisibility;
	return true;
    } else {
	// we couldn't find the object, so we can't change its visibility
	return false;
    }
} // changeObjectVisibility

function moveObject(objectId, newXCoordinate, newYCoordinate) {
    // get a reference to the cross-browser style object and make sure the object exists
    var styleObject = getStyleObject(objectId);
    if(styleObject) {
	styleObject.left = newXCoordinate;
	styleObject.top = newYCoordinate;
	return true;
    } else {
	// we couldn't find the object, so we can't very well move it
	return false;
    }
} // moveObject


/* Forms Validation */

// DEFAULTS

var defaultEmptyOK = false

// VARIABLE DECLARATIONS

var digits = "0123456789";

var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz"

var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

// whitespace characters as defined by this sample code
var whitespace = " \t\n\r";


// non-digit characters which are allowed in phone numbers
var phoneNumberDelimiters = "()- ";


// characters which are allowed in US phone numbers
var validUSPhoneChars = digits + phoneNumberDelimiters;


// characters which are allowed in international phone numbers
// (a leading + is OK)
var validWorldPhoneChars = digits + phoneNumberDelimiters + "+";

// REGULAR EXPRESSION DECLARATIONS

// BOI, followed by one of these two patterns:    [trk 10/17/03]
// (a) zero or more digits, followed by ., followed by 2 digits
// (b) zero or more digits
// ... followed by EOI.

// (Rick) BOI, followed by 0 or more digits followed by either nothing or a decimal and 2 digits, followed by EOI.
//var reMoney = /^(\d*(\.\d{2})?)$/ // no commas
var reMoney = /^(((\d{0,3}(,\d\d\d)*)|((\d*)))(\.\d{2})?)$/ // with commas


// CONSTANT STRING DECLARATIONS
// (grouped for ease of translation and localization)

// m is an abbreviation for "missing"

var mPrefix = "You did not enter a value into the "
var mSuffix = " field. This is a required field. Please enter it now."

// i is an abbreviation for "invalid"

var iStateCode = "This field must be a valid two character U.S. state abbreviation (like CA for California). Please reenter it now."
var iZIPCode = "This field must be a 5 or 9 digit U.S. ZIP Code (like 94043). Please reenter it now."
var iUSPhone = "This field must be a 10 digit U.S. phone number (like 415 555 1212). Please reenter it now."
var iWorldPhone = "This field must be a valid international phone number. Please reenter it now."
var iSSN = "This field must be a 9 digit U.S. social security number (like 123 45 6789). Please reenter it now."
var iEmail = "This field must be a valid email address (like foo@bar.com). Please reenter it now."
var iCreditCardPrefix = "This is not a valid "
var iCreditCardSuffix = " credit card number. (Click the link on this form to see a list of sample numbers.) Please reenter it now."
var iDay = "This field must be a day number between 1 and 31.  Please reenter it now."
var iMonth = "This field must be a month number between 1 and 12.  Please reenter it now."
var iYear = "This field must be a 2 or 4 digit year number.  Please reenter it now."
var iDatePrefix = "The Day, Month, and Year for "
var iDateSuffix = " do not form a valid date.  Please reenter them now."
var iMoney = " must be in money format with no non-numeric characters except the decimal point."
var iPhone = " must be 8 to 11 digits."


// p is an abbreviation for "prompt"

var pEntryPrompt = "Please enter a "
var pStateCode = "2 character code (like CA)."
var pZIPCode = "5 or 9 digit U.S. ZIP Code (like 94043)."
var pUSPhone = "10 digit U.S. phone number (like 415 555 1212)."
var pWorldPhone = "international phone number."
var pSSN = "9 digit U.S. social security number (like 123 45 6789)."
var pEmail = "valid email address (like foo@bar.com)."
var pCreditCard = "valid credit card number."
var pDay = "day number between 1 and 31."
var pMonth = "month number between 1 and 12."
var pYear = "2 or 4 digit year number."
var pUSD = "US dollar amount in dollars or dollars and cents (without the dollar sign)."


// Check that string theField.value is in money format, with or without 2 decimals places [trk 10/17/03].
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

// Check whether string s is empty.

function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}

function checkMoney (theField, emptyOK)
{  
if (checkMoney.arguments.length == 1) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    if (!isMoney(theField.value)) 
      return warnInvalid(theField, theField.name + " " + iMoney);
    else return true;
}



// isMoney (STRING s [, BOOLEAN emptyOK])
// 
// True if string s is an unsigned floating point (real) number with two decimal places or none. 
//
// Does not accept exponential notation.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isMoney (s)

{   if (isEmpty(s)) 
       if (isMoney.arguments.length == 1) return defaultEmptyOK;
       else return (isMoney.arguments[1] == true);

    else {
	    return reMoney.test(s)
    }
}


// roundMoney (STRING s) (Rick)
//
// rounds amt to 2 decimal places 

function roundMoney(amt) {		
	num = (Math.round(amt*100)/100).toString();
	while(num.indexOf(".") + 3 > num.length) num += "0"; 
	return num
}


function checkPhone(theField) {

	formatPhone(theField)
}

// formatPhone (STRING s) (Rick)
// strips non-digits & requires 8-11 digits
// formats 8-11 digits with dashes as follows:
// 8: xx-xxx-xxx
// 9: xxx-xxx-xxx
// 10: xxx-xxx-xxxx
// 11: xxx-xxxx-xxxx

function formatPhone(theField) {

	var strippedFld = stripCharsNotInBag(theField.value, digits);
	var l = strippedFld.length;
	
	if(l > 0 && ((l < 8) || (l > 11)))
		return warnInvalid(theField, theField.name + " " + iPhone);
		
	if(l == 8) theField.value = reformat(strippedFld,"",2,"-",3,"-",3);
	if(l == 9) theField.value = reformat(strippedFld,"",3,"-",3,"-",3);
	if(l == 10) theField.value = reformat(strippedFld,"",3,"-",3,"-",4);
	if(l == 11) theField.value = reformat(strippedFld,"",3,"-",4,"-",4);
	
	return true;
}


// Display data entry prompt string s in status bar.

function promptEntry (s)
{   window.status = pEntryPrompt + s
}


// Notify user that contents of field theField are invalid.
// String s describes expected contents of theField.value.
// Put select theField, pu focus in it, and return false.

function warnInvalid (theField, s)
{   theField.focus()
    theField.select()
    alert(s)
    return false
}


// reformat (TARGETSTRING, STRING, INTEGER, STRING, INTEGER ... )       
//
// Handy function for arbitrarily inserting formatting characters
// or delimiters of various kinds within TARGETSTRING.
//
// reformat takes one named argument, a string s, and any number
// of other arguments.  The other arguments must be integers or
// strings.  These other arguments specify how string s is to be
// reformatted and how and where other strings are to be inserted
// into it.
//
// reformat processes the other arguments in order one by one.
// * If the argument is an integer, reformat appends that number 
//   of sequential characters from s to the resultString.
// * If the argument is a string, reformat appends the string
//   to the resultString.
//
// NOTE: The first argument after TARGETSTRING must be a string.
// (It can be empty.)  The second argument must be an integer.
// Thereafter, integers and strings must alternate.  This is to
// provide backward compatibility to Navigator 2.0.2 JavaScript
// by avoiding use of the typeof operator.
//
// It is the caller's responsibility to make sure that we do not
// try to copy more characters from s than s.length.
//
// EXAMPLES:
//
// * To reformat a 10-digit U.S. phone number from "1234567890"
//   to "(123) 456-7890" make this function call:
//   reformat("1234567890", "(", 3, ") ", 3, "-", 4)
//
// * To reformat a 9-digit U.S. Social Security number from
//   "123456789" to "123-45-6789" make this function call:
//   reformat("123456789", "", 3, "-", 2, "-", 4)
//
// HINT:
//
// If you have a string which is already delimited in one way
// (example: a phone number delimited with spaces as "123 456 7890")
// and you want to delimit it in another way using function reformat,
// call function stripCharsNotInBag to remove the unwanted 
// characters, THEN call function reformat to delimit as desired.
//
// EXAMPLE:
//
// reformat (stripCharsNotInBag ("123 456 7890", digits),
//           "(", 3, ") ", 3, "-", 4)

function reformat (s)

{   var arg;
    var sPos = 0;
    var resultString = "";

    for (var i = 1; i < reformat.arguments.length; i++) {
       arg = reformat.arguments[i];
       if (i % 2 == 1) resultString += arg;
       else {
           resultString += s.substring(sPos, sPos + arg);
           sPos += arg;
       }
    }
    return resultString;
}



// Removes all whitespace characters from s.
// Global variable whitespace (see above)
// defines which characters are considered whitespace.

function stripWhitespace (s)

{   return stripCharsInBag (s, whitespace)
}


// Removes initial (leading) whitespace characters from s.
// Global variable whitespace (see above)
// defines which characters are considered whitespace.

function stripInitialWhitespace (s)

{   var i = 0;

    while ((i < s.length) && charInString (s.charAt(i), whitespace))
       i++;
    
    return s.substring (i, s.length);
}



// Removes all characters which appear in string bag from string s.

function stripCharsInBag (s, bag)

{   var i;
    var returnString = "";

    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }

    return returnString;
}



// Removes all characters which do NOT appear in string bag 
// from string s.

function stripCharsNotInBag (s, bag)

{   var i;
    var returnString = "";

    // Search through string's characters one by one.
    // If character is in bag, append to returnString.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) != -1) returnString += c;
    }

    return returnString;
}
