Utilities = {};

Utilities.initialize = function() {
	Utilities.alertDiv = '';
	Utilities.alertEncloseDiv = '';
	Utilities.ie6HackFixiFrame = '';
}

Utilities.initialize();

Utilities.includeJS = function(filepaths)
{
	for(var i=0; i<filepaths.length; i++)
	{
		if (!document.getElementById(filepaths[i])) {
			document.write('<script type="text/javascript" src="'+filepaths[i]+'"  id="'+filepaths[i]+'"></script>');
		}
	}
}

Utilities.includeCSS = function(filepaths)
{
	var foo;
	for(var i=0; i<filepaths.length; i++)
	{
		if (!document.getElementById(filepaths[i])) {
			document.write('<link href="'+filepaths[i]+'" id="'+filepaths[i]+'" rel="stylesheet" type="text/css" />');
		}
	}
}

Utilities.doNothing = function() {
	
}

Utilities.getElement = function(i) { 
	return document.getElementById(i); 
}

Utilities.getChecked = function(checkBox) { 
	return (document.getElementById(checkBox).checked ? 1 : 0);
}

Utilities.debug = function(val)
{
	this.getElement('debug').innerHTML += val +"<br/>";
}

Utilities.toggle = function(id)
{
	this.getElement(id).style.display = (this.getElement(id).style.display == '') ? 'none' : '';
}

Utilities.createElement = function(e, obj)
{
	var a = document.createElement(e);
	for(prop in obj)
	{
		a[prop] = obj[prop];
	}
	return a;
}

Utilities.appendChild = function()
{
	if(this.appendChild.arguments.length > 1)
	{
		var a = this.appendChild.arguments[0];
		for(i=1; i<this.appendChild.arguments.length; i++)
		{
			if(arguments[i])
			{
				a.appendChild(this.appendChild.arguments[i]);
			}
		}
		return a;
	}
	else
	{
		return null;
	}
}

Utilities.childHeight = function()
{
	var childrenHeight = 0;
	if(this.childHeight.arguments.length > 1)
	{
		var a = this.childHeight.arguments[0];
		for(i=1; i<this.childHeight.arguments.length; i++)
		{
			if(arguments[i])
			{
				childrenHeight += this.childHeight.arguments[i].clientHeight;
			}
		}
	}
	
	return childrenHeight;
}

Utilities.childWidth = function()
{
	var childrenWidth = 0;
	if(this.childWidth.arguments.length > 1)
	{
		var foo = 0;
		var a = this.childWidth.arguments[0];
		for(i=1; i<this.childWidth.arguments.length; i++)
		{
			if(arguments[i])
			{
				foo = this.childWidth.arguments[i];
				childrenWidth = (childrenWidth > this.childWidth.arguments[i].clientWidth ? childrenWidth : this.childWidth.arguments[i].clientWidth);
			}
		}
	}
	
	return childrenWidth;
}

Utilities.ajaxDelay = function(phpClass, jsFunction) {
	var params = '';
	var url = "/_fnd/plugins/AjaxSupport/include/serviceConnector.php?object=" + phpClass + "&method=ajaxDelay&params="+ params;
	AjaxUpdater.Update("GET", url, jsFunction); 	
}


Utilities.incLetter = function(letter) {
	var alphaString = "abcdefghijklmnopqrstuvwxyz";
	
	var index = alphaString.search(letter);
	if (index+1 < alphaString.length) {
		return alphaString.charAt(index+1);
	} else{
		return "a";
	}
}

Utilities.removeChildren = function(node)
{
	if(node == null)
	{
		return;
	}
	
	while(node.hasChildNodes())
	{
		node.removeChild(node.firstChild);
	}
}

Utilities.insertAfter = function( referenceNode, newNode )
{
    referenceNode.parentNode.insertBefore( newNode, referenceNode.nextSibling );
}


Utilities.addDocumentListener = function(eventName, listener)
{
	if (document.attachEvent)
	{
		document.attachEvent("on"+eventName, listener);
	}
	else if(document.addEventListener)
	{
		document.addEventListener(eventName, listener, false);
		if (document.addEventListener) {
			document.addEventListener(eventName, listener, false);
		}  else if (document.attachEvent) {
			document.attachEvent(eventName, listener);
		}		
	}
	else
	{
		return false;
	}
	return true;
}

Utilities.addListener = function(obj, eventName, listener)
{
	if (obj.attachEvent)
	{
		obj.attachEvent("on"+eventName, listener);
	}
	else if(obj.addEventListener)
	{
		obj.addEventListener(eventName, listener, false);
		if (obj.addEventListener) {
			obj.addEventListener(eventName, listener, false);
		}  else if (obj.attachEvent) {
			obj.attachEvent(eventName, listener);
		}		
	}
	else
	{
		return false;
	}
	return true;
}

Utilities.removeListener = function(obj, eventName, listener)
{
	if(obj.detachEvent)
	{
		obj.detachEvent("on"+eventName, listener);
	}
	else if(obj.removeEventListener)
	{
		obj.removeEventListener(eventName, listener, false);
	}
	else
	{
		return false;
	}
	
	return true;
}

Utilities.changeOpac = function(opacity, id)
{
	var object = Utils.ge(id).style;
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "alpha(opacity=" + opacity + ")";
}

Utilities.stripBlank = function (str)
{
	var newStr = "";
	if (str != " ") { newStr = str; }
	
	return newStr;
}

Utilities.getNewValue = function() {
	var newValue = '', value = '', defaultValue = '';
	for( var i = 0; i < arguments.length; i++ ) {
		value = document.getElementById(arguments[i]).value;
		defaultValue = document.getElementById(arguments[i]).defaultValue;
		if (defaultValue!=value) {
			newValue += value;
		}
	}
		
	return newValue;
}

Utilities.getValue = function() 
{ 
	var value = '';
	for( var i = 0; i < arguments.length; i++ ) {
		value += Utilities.replaceSpecialChars(document.getElementById(arguments[i]).value);
	}
	
	return value;
}

Utilities.getTextArea = function() { 
	var value = '';
	for( var i = 0; i < arguments.length; i++ ) {
		value += Utilities.replaceReturns(Utilities.replaceSpecialChars(document.getElementById(arguments[i]).value));
	}
	
	return value;
}

Utilities.replaceSpecialChars = function(str) { 
	str = str.replace(/&/g,"ampersand");
	str = str.replace(/\+/g,"__plussign__");
	str = str.replace(/#/g,"__poundsign__");
	
	return  str;
}

Utilities.replaceReturns = function(str) { 
	str = str.replace("\n","<br>");
	
	return  str;
}

Utilities.isInternetExplorer = function () {
	var nAgt = navigator.userAgent;
	var verOffset=nAgt.indexOf("MSIE")
	if (navigator.appName == "Microsoft Internet Explorer")  {
		return true;
	} else {
		return false;
	}
}

Utilities.isInternetExplorer6 = function () {
	var nAgt = navigator.userAgent;
	var verOffset=nAgt.indexOf("MSIE")
	if (navigator.appName == "Microsoft Internet Explorer" && parseFloat(nAgt.substring(verOffset+5)) <= 6)  {
		return true;
	} else {
		return false;
	}
}

Utilities.message = function(message, encloseDiv) {
	Utilities.alertEncloseDiv = encloseDiv;
	Utilities.alertDiv = Utilities.buildArea (200, 500, Utilities.alertDiv, 'alertDiv', encloseDiv);
	
	// PAGE HEADER
	var headerContent = "<div class='halfContentSpacer'></div>";
	headerContent += "<div class='editTitleRow'>";
		headerContent += "<div class='editPageTitle'>Notice!!</div>";	
	headerContent += "</div>";	
		
	var headerArea = Utilities.createElement("div", {id: 'headerArea', innerHTML: headerContent });
	
	// Title
	var updateContent = "<div class='fullContentSpacer'>&nbsp;</div>";	
	updateContent += "<div class='fullContentSpacer'></div>";
	updateContent += "<div class='messageRow'>";
		updateContent += "<div>" + message + "</div>";		
	updateContent += "</div>";	
	updateContent += "<div class='fullContentSpacer'>&nbsp;</div>";
	
	var updateArea = Utilities.createElement("div", {id: 'updateArea', className: 'utilityMessageArea', innerHTML: updateContent });
	
	// FOOTER
	var footerContent = "<div class='editFooterRow'>";
		footerContent += "<div class='editButtonSpacer'>&nbsp;</div>";
		footerContent += "<div class='editButtonLeft'><a class='editButton' href=\"javascript:Utilities.closeMessage()\">Cancel</a>&nbsp;&nbsp;&nbsp;</div>";

	footerContent += "</div>";	
		
	
	var footerArea = Utilities.createElement("div", {id: 'footerArea', innerHTML: footerContent });

	Utilities.appendChild(Utilities.alertDiv , headerArea, updateArea, footerArea);
		
}

Utilities.closeMessage = function() {
	if (Utilities.alertDiv) {
		Utilities.removeChildren(Utilities.alertDiv);
		document.body.removeChild(Utilities.alertDiv);
		
		Utilities.alertDiv = "";
	}
	
	if (Utilities.alertEncloseDiv) {
		document.getElementById(Utilities.alertEncloseDiv).style.cssText = '';
		Utilities.alertEncloseDiv = "";
	}
}

// GENERIC EDITING UTILITIES

Utilities.buildArea = function (height, width, newdiv, divName, enclosingDiv, constrain, eventListener) {
	return Utilities.buildPositionedArea(height, width, newdiv, divName, enclosingDiv, 2, constrain);
}

Utilities.buildPositionedArea = function (height, width, newdiv, divName, enclosingDiv, topPosition, constrain, eventListener, areaClass) {
	if (!constrain) constrain=false;
	var makenewdiv = newdiv;
	if (!makenewdiv) {
		var winheight = 0;
		var winwidth = 0;
		if (typeof (window.innerHeight) == 'number') {
			winheight = window.innerHeight;
			winwidth = window.innerWidth;
		} else if (document.documentElement.clientHeight) {
			winheight = document.documentElement.clientHeight;
			winwidth = document.documentElement.clientWidth
		} else{
			winheight = document.body.clientHeight;
			winwidth = document.body.clientWidth;
		}
		var posx = 0;
		var posy = 0;
		if (typeof (window.pageXOffset) =='number') {
			posx = window.pageXOffset;
			posy = window.pageYOffset;
		} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
			posx = document.body.scrollLeft;
			posy = document.body.scrollTop;
		} else{
			posx = document.documentElement.scrollLeft;
			posy = document.documentElement.scrollTop;
		}
		

		var top = (winheight-height)/topPosition + posy;
		if (top <0) {
			top = 0;
		}
		var left = (winwidth-width)/2 + posx;
		if (left<0) {
			left = 0;
		}
		
		// The div 'enclosingDiv' encloses the entire site, as the name suggests. This line dims the screen.
		// If you remove this, you must also remove it from closeDiv().
		if (enclosingDiv) {
			document.getElementById(enclosingDiv).style.cssText = 'opacity: .5; filter: alpha(opacity=50); height: 100%; width: 100%;';
		}
		
		if (constrain && winheight<height) 
			height = winheight-30;
			
		// 'makenewdiv' is the actual popup.
		makenewdiv = document.createElement("div");
		if (eventListener) {
			if (document.addEventListener) {
				document.addEventListener("keydown", eventListener, true);
			}  else if (document.attachEvent) {
				document.attachEvent('keydown', eventListener);
			}
		}
		
		var cssText = 'position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: ' + width + 'px; height: ' + height + 'px; opacity: 1; filter: alpha(opacity=100); z-index: 20;';
		areaClass = (areaClass ? areaClass : 'positionedAreaClass');
		if (Utilities.isInternetExplorer()) {
			var areaStyle = Utilities.getStyle('.' + areaClass);
			cssText += areaStyle;
		} else {			
			makenewdiv.setAttribute('class', areaClass);
		}
		makenewdiv.style.cssText = cssText;
		
//		makenewdiv.style.cssText = 'border: 1px solid #000000; position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: ' + width + 'px; height: ' + height + 'px; opacity: 1; filter: alpha(opacity=100); z-index: 20; background-color: white;';
		makenewdiv.setAttribute('id', divName);
		
		document.body.appendChild(makenewdiv);
		
		Utilities.InternetExplorer6SelectFix(makenewdiv);		
	}
	
	return makenewdiv;	
}

Utilities.getStyle = function (findClassName) {
	var styleSheets = document.styleSheets;
	var className = '';
	var styleStr = '';
	for(var y=0;y<styleSheets.length;y++) {
		var classes = document.styleSheets[y].rules || document.styleSheets[y].cssRules
		for(var x=0;x<classes.length;x++) {
			className = classes[x].selectorText;
			if(classes[x].selectorText.toLowerCase() == findClassName.toLowerCase()) {
				styleStr += (classes[x].cssText) ? (classes[x].cssText) : (classes[x].style.cssText) + ";";
			}
		}
	}
	
	return styleStr;
}

Utilities.buildOffsetArea = function (height, offsetDiv, adjustDiv, newdiv, divName, enclosingDiv) {
	var makenewdiv = newdiv;
	
	if (!makenewdiv) {
		var offsetParent = (document.getElementById(offsetDiv).offsetTop > 0 ? document.getElementById(offsetDiv) :
			document.getElementById(offsetDiv).offsetParent);
		
		var adjustTop = (adjustDiv ? document.getElementById(adjustDiv).offsetHeight : 0);
		if (navigator.appName == "Microsoft Internet Explorer") {
			adjustTop +=  document.getElementById(offsetDiv).offsetTop + 5;
		} else if (document.getElementById(offsetDiv).offsetTop < offsetParent.offsetTop) {
			adjustTop += document.getElementById(offsetDiv).offsetTop;
		}

		var width = offsetParent.offsetWidth;
		
		var top = offsetParent.offsetTop - adjustTop;
		var left = offsetParent.offsetLeft;
		
		// if we are on IE, we need to go up the offsetParent tree to get the total offset
		if (navigator.appName == "Microsoft Internet Explorer") {
			while (offsetParent = offsetParent.offsetParent) {
				top += offsetParent.offsetTop;
				left += offsetParent.offsetLeft;
			}
		}
		
		// The div 'enclosingDiv' encloses the entire site, as the name suggests. This line dims the screen.
		// If you remove this, you must also remove it from closeDiv().
		if (enclosingDiv) {
			document.getElementById(enclosingDiv).style.cssText = 'opacity: .5; filter: alpha(opacity=50); height: 100%; width: 100%;';
		}
		
		// 'makenewdiv' is the actual popup.
		makenewdiv = document.createElement("div");
	 	// newdiv.innerHTML = contents;
		makenewdiv.style.cssText = 'z-index: -1; border: 1px solid #000000; position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: ' + width + 'px; height: ' + height + 'px; opacity: 1; filter: alpha(opacity=100); z-index: 9; background-color: white;';
		makenewdiv.setAttribute('id', divName);
		document.body.appendChild(makenewdiv);
		
		Utilities.InternetExplorer6SelectFix(makenewdiv);
	}
	
	return makenewdiv;
}


Utilities.buildFullScreen = function (newdiv, divName) {
	makenewdiv = newdiv;
	if (!makenewdiv) {
		
		// 'makenewdiv' is the actual popup.
		 makenewdiv = document.createElement("div");
		// newdiv.innerHTML = contents;
		makenewdiv.style.cssText = "border: 1px solid #000000; position: absolute; top: 0px; left: 0px; width: 99%; height: 99%; opacity: 1; filter: alpha(opacity=100); z-index: 7; background-color: white;";
		makenewdiv.setAttribute('id', divName);
		document.body.appendChild(makenewdiv);
		
		Utilities.InternetExplorer6SelectFix(makenewdiv);
	}
	
	return makenewdiv;
}

Utilities.InternetExplorer6SelectFix = function(makenewdiv) {
	if (Utilities.isInternetExplorer6()) {
		var ie6HackFixiFrame = document.createElement("IFRAME");
		ie6HackFixiFrame.setAttribute("src", "");
		ie6HackFixiFrame.setAttribute("id", "ie6HackFixiFrame");
		
		//Match IFrame position with divPopup
		ie6HackFixiFrame.style.position="absolute";
		ie6HackFixiFrame.style.left =makenewdiv.offsetLeft + 'px';
		ie6HackFixiFrame.style.top =makenewdiv.offsetTop + 'px';
		ie6HackFixiFrame.style.width =makenewdiv.offsetWidth + 'px';
		ie6HackFixiFrame.style.height =makenewdiv.offsetHeight + 'px';
		
		document.body.appendChild(ie6HackFixiFrame);
		Utilities.ie6HackFixiFrame = ie6HackFixiFrame; 
	}
}

Utilities.dialogListener = function(key, buttonName, returnFunction, closeFunction) {
	var keynum=0;
	var keynum= (key.charCode > 0 ? key.charCode : key.keyCode);

	if (keynum == 27) {eval(closeFunction);}
	if (keynum == 13) {
		var buttonDisplay = document.getElementById(buttonName).style.display;
		if (buttonDisplay == "" || buttonDisplay == "block") {
			eval(returnFunction);
		}
	}
}

Utilities.closeDiv = function(newdiv, bodyenclose, eventListener) {
	Utilities.removeChildren(newdiv);
	document.body.removeChild(newdiv);
	if (bodyenclose) { 
		document.getElementById(bodyenclose).style.cssText = '';
	}
	
	if (eventListener) {
		if (document.removeEventListener) {
			document.removeEventListener("keydown", eventListener, true);
		}  else if (document.detachEvent) {
			document.detachEvent('keydown', eventListener);
		}
		
	}
	
	//ie6HackFixiFrame
	if (Utilities.isInternetExplorer6() && document.getElementById('ie6HackFixiFrame')) {
		document.body.removeChild(Utilities.ie6HackFixiFrame);
	}
}

Utilities.evalFunction = function(runFunction) {
	try {
		return eval(runFunction);
	} catch (err){
		return '';
	}

}

Utilities.trueFalseSelector = function (value) {
	if(value == null) {
		var trueSelected = 'selected';
		var falseSelected = '';
	} else {
		trueSelected = (value=='1' ? 'selected' : '');
		falseSelected = (value=='0' ? 'selected' : '');
	}
	var selector = "<option " + trueSelected + " value=1>True</option>";
	selector += "<option " + falseSelected + " value=0>False</option>";
	
	return selector;
}

Utilities.maleFemaleSelector = function (value) {
	if(value == null) {
		var maleSelected = 'selected';
		var femaleSelected = '';
	} else {
		maleSelected = (value=='1' ? 'selected' : '');
		femaleSelected = (value=='2' ? 'selected' : '');
	}
	var selector = "<option " + maleSelected + " value=1>Male</option>";
	selector += "<option " + femaleSelected + " value=2>Female</option>";
	
	return selector;
}

/*
	Build a selector based on an XML feed as follows:
		<arrayName>
			<idname>x</idname>
			<itemName>x</itemName>
		</arrayName>
		
	where selectedItem is the item to be selected
*/
Utilities.buildSelector = function (baseSelector, selectedItem, arrayName, idName, itemName) {
	var itemID, item;
	var selector = baseSelector;
	try {
		var items = Ajax.getResponse().getElementsByTagName(arrayName)[0].childNodes;
		var itemLen = items.length / 2; 	
		for (var i=0; i < itemLen; i++) {
			itemID = Ajax.getResponse().getElementsByTagName(idName)[i].firstChild.data;
			item = Ajax.getResponse().getElementsByTagName(itemName)[i].firstChild.data;
			if (itemID == selectedItem) {
				selector += "<option selected value='" + itemID +"'>" + item + "</option>";
			} else {
				selector += "<option value='" + itemID +"'>" + item + "</option>";
			}
		}
	}
	catch (err) {
		var foo = err;
	}
	return selector;
}


/*
	Build a selector based on an XML feed as follows:
		<arrayName>
			<itemName>x</itemName>
		</arrayName>
		
	where selectedItem is the item to be selected
*/
Utilities.buildSingleSelector = function (baseSelector, selectedItem, arrayName, itemName) {
	var item;
	var selector = baseSelector;
	try {
		var items = Ajax.getResponse().getElementsByTagName(arrayName)[0].childNodes;
		var itemLen = items.length; 
		for (var i=0; i < itemLen; i++) {
			item = Ajax.getResponse().getElementsByTagName(itemName)[i].firstChild.data;
			if (item == selectedItem) {
				selector += "<option selected value='" + item +"'>" + item + "</option>";
			} else {
				selector += "<option value='" + item +"'>" + item + "</option>";
			}
		}
	}
	catch (err) {
		var foo = err;
	}
	
	return selector;
}

/*
 * 
 * Text Entry Functions
 * 
 */
Utilities.fieldErase = function (el) {
  if (el.defaultValue==el.value) el.value = ""
  if (el.style) el.style.cssText = ""
}

Utilities.fieldRestore = function (el) {
	if (el.value == "") el.value = el.defaultValue
	if (el.value == el.defaultValue) el.style.cssText = "color: grey;"
}
 
Utilities.isValidClassName = function (key)
{
	var keynum=0;
	var keynum= (key.charCode > 0 ? key.charCode : key.keyCode);

	if (keynum==8 || keynum==9 || keynum==45 || (keynum>=48 && keynum<=57) || (keynum>=65 && keynum<=90) || keynum==95 || (keynum>=97 && keynum<=122)) return true;

	return false;
}
 
Utilities.isNumber = function (key)
{
	var keynum=0;
	var keynum= (key.charCode > 0 ? key.charCode : key.keyCode);

	if (keynum==8 || keynum==9 || (keynum>=48 && keynum<=57)) return true;

	return false;
}
 
Utilities.isFloat = function (key, item, decimals)
{
	var keynum=0;
	var keynum= (key.charCode > 0 ? key.charCode : key.keyCode);
	
	var selStart = Utilities.getSelectionStart(item);
	var selEnd = Utilities.getSelectionEnd(item);
	var value = item.value;
	
	var decimalLocation = value.indexOf('.');
	decimalLocation = (decimalLocation >= selStart && decimalLocation <= selEnd ? -1 : decimalLocation);
	
	var decimalLength = (decimalLocation == -1 ? 0 : value.length - (decimalLocation + 1) - (selEnd-selStart));
	
	var validLocation = (keynum==8 || keynum==9 || keynum==37 || keynum==39 || decimalLocation == -1 || selStart < decimalLocation || decimalLength < decimals ? true : false);
	
	var decimalExists = (decimalLocation >= 0 ? true : false);
	if (validLocation && (keynum==8 || keynum==9 || keynum==37 || keynum==39 || (!decimalExists && keynum==46) || (keynum>=48 && keynum<=57))) return true;

	return false;
}

Utilities.getSelectionStart= function (item) {
	if (item.createTextRange) {
		var r = document.selection.createRange().duplicate()
		r.moveEnd('character', item.value.length)
		if (r.text == '') return item.value.length
		return item.value.lastIndexOf(r.text)
	} else return item.selectionStart
}

Utilities.getSelectionEnd= function (item) {
	if (item.createTextRange) {
		var r = document.selection.createRange().duplicate()
		r.moveStart('character', -o.value.length)
		return r.text.length
	} else return item.selectionEnd
}

Utilities.checkMaxFloat = function (field,places)
{
	var keynum=0;
	var keynum= (key.charCode > 0 ? key.charCode : key.keyCode);

	if (keynum==8 || keynum==9 || (keynum>=48 && keynum<=57)) return true;
	
	var value = document.getElementById(field).value;
}

Utilities.checkLen = function (x,y,id)
{
	if (y.length==x.maxLength && id)
		{
			document.getElementById(id).focus();
		}
}

Utilities.checkDate = function (x,y,field,key)
{
	var keynum=0;
	var keynum= (key.charCode > 0 ? key.charCode : key.keyCode);
	
	
	if (keynum!=8 && (y.length==4 || y.length==7)) {
		var date = y += '/';
		document.getElementById(field).value = date;
	}
}
 
Utilities.isDateNumber = function (y,key)
{
	var keynum=0;
	var keynum= (key.charCode > 0 ? key.charCode : key.keyCode);

	if (keynum==8 || keynum==9) return true;
	if ((y.length <= 3 || y.length == 6  || y.length == 9) && (keynum>=48 && keynum<=57)) return true;
	if (y.length == 5 && (keynum>=48 && keynum<=49)) return true;
	if (y.length == 8 && (keynum>=48 && keynum<=51)) return true;

	return false;
}

Utilities.setFieldValue = function (field, fieldValue, clearCSS, fieldRestore) {
	if (fieldValue) {
		document.getElementById(field).value = fieldValue;
		if (clearCSS) {
			document.getElementById(field).style.cssText = '';
		}
	} else if (fieldRestore) {
		document.getElementById(field).value = fieldValue;
		Utilities.fieldRestore (document.getElementById(field));
	}
}

/*
 * PHP Function equivalents
 */
 function date ( format, timestamp ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: MeEtc (http://yass.meetcweb.com)
    // +   improved by: Brad Touesnard
    // +   improved by: Tim Wiel
    // *     example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    // *     returns 1: '09:09:40 m is month'
    // *     example 2: date('F j, Y, g:i a', 1062462400);
    // *     returns 2: 'September 2, 2003, 2:26 am'
 
    var a, jsdate=((timestamp) ? new Date(timestamp*1000) : new Date());
    var pad = function(n, c){
        if( (n = n + "").length < c ) {
            return new Array(++c - n.length).join("0") + n;
        } else {
            return n;
        }
    };
    var txt_weekdays = ["Sunday","Monday","Tuesday","Wednesday",
        "Thursday","Friday","Saturday"];
    var txt_ordin = {1:"st",2:"nd",3:"rd",21:"st",22:"nd",23:"rd",31:"st"};
    var txt_months =  ["", "January", "February", "March", "April",
        "May", "June", "July", "August", "September", "October", "November",
        "December"];
 
    var f = {
        // Day
            d: function(){
                return pad(f.j(), 2);
            },
            D: function(){
                t = f.l(); return t.substr(0,3);
            },
            j: function(){
                return jsdate.getDate();
            },
            l: function(){
                return txt_weekdays[f.w()];
            },
            N: function(){
                return f.w() + 1;
            },
            S: function(){
                return txt_ordin[f.j()] ? txt_ordin[f.j()] : 'th';
            },
            w: function(){
                return jsdate.getDay();
            },
            z: function(){
                return (jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5 >> 0;
            },
 
        // Week
            W: function(){
                var a = f.z(), b = 364 + f.L() - a;
                var nd2, nd = (new Date(jsdate.getFullYear() + "/1/1").getDay() || 7) - 1;
 
                if(b <= 2 && ((jsdate.getDay() || 7) - 1) <= 2 - b){
                    return 1;
                } else{
 
                    if(a <= 2 && nd >= 4 && a >= (6 - nd)){
                        nd2 = new Date(jsdate.getFullYear() - 1 + "/12/31");
                        return date("W", Math.round(nd2.getTime()/1000));
                    } else{
                        return (1 + (nd <= 3 ? ((a + nd) / 7) : (a - (7 - nd)) / 7) >> 0);
                    }
                }
            },
 
        // Month
            F: function(){
                return txt_months[f.n()];
            },
            m: function(){
                return pad(f.n(), 2);
            },
            M: function(){
                t = f.F(); return t.substr(0,3);
            },
            n: function(){
                return jsdate.getMonth() + 1;
            },
            t: function(){
                var n;
                if( (n = jsdate.getMonth() + 1) == 2 ){
                    return 28 + f.L();
                } else{
                    if( n & 1 && n < 8 || !(n & 1) && n > 7 ){
                        return 31;
                    } else{
                        return 30;
                    }
                }
            },
 
        // Year
            L: function(){
                var y = f.Y();
                return (!(y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0;
            },
            //o not supported yet
            Y: function(){
                return jsdate.getFullYear();
            },
            y: function(){
                return (jsdate.getFullYear() + "").slice(2);
            },
 
        // Time
            a: function(){
                return jsdate.getHours() > 11 ? "pm" : "am";
            },
            A: function(){
                return f.a().toUpperCase();
            },
            B: function(){
                // peter paul koch:
                var off = (jsdate.getTimezoneOffset() + 60)*60;
                var theSeconds = (jsdate.getHours() * 3600) +
                                 (jsdate.getMinutes() * 60) +
                                  jsdate.getSeconds() + off;
                var beat = Math.floor(theSeconds/86.4);
                if (beat > 1000) beat -= 1000;
                if (beat < 0) beat += 1000;
                if ((String(beat)).length == 1) beat = "00"+beat;
                if ((String(beat)).length == 2) beat = "0"+beat;
                return beat;
            },
            g: function(){
                return jsdate.getHours() % 12 || 12;
            },
            G: function(){
                return jsdate.getHours();
            },
            h: function(){
                return pad(f.g(), 2);
            },
            H: function(){
                return pad(jsdate.getHours(), 2);
            },
            i: function(){
                return pad(jsdate.getMinutes(), 2);
            },
            s: function(){
                return pad(jsdate.getSeconds(), 2);
            },
            //u not supported yet
 
        // Timezone
            //e not supported yet
            //I not supported yet
            O: function(){
               var t = pad(Math.abs(jsdate.getTimezoneOffset()/60*100), 4);
               if (jsdate.getTimezoneOffset() > 0) t = "-" + t; else t = "+" + t;
               return t;
            },
            P: function(){
                var O = f.O();
                return (O.substr(0, 3) + ":" + O.substr(3, 2));
            },
            //T not supported yet
            //Z not supported yet
 
        // Full Date/Time
            c: function(){
                return f.Y() + "-" + f.m() + "-" + f.d() + "T" + f.h() + ":" + f.i() + ":" + f.s() + f.P();
            },
            //r not supported yet
            U: function(){
                return Math.round(jsdate.getTime()/1000);
            }
    };
 
    return format.replace(/[\\]?([a-zA-Z])/g, function(t, s){
        if( t!=s ){
            // escaped
            ret = s;
        } else if( f[s] ){
            // a date function exists
            ret = f[s]();
        } else{
            // nothing special
            ret = s;
        }
 
        return ret;
    });
}

function mktime() {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: baris ozdil
    // +      input by: gabriel paderni 
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: FGFEmperor
    // +      input by: Yannoo
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: jakes
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: mktime(14, 10, 2, 2, 1, 2008);
    // *     returns 1: 1201871402
    // *     example 2: mktime(0, 0, 0, 0, 1, 2008);
    // *     returns 2: 1196463600
    
    var no, ma = 0, mb = 0, i = 0, d = new Date(), argv = arguments, argc = argv.length;
    d.setHours(0,0,0); d.setDate(1); d.setMonth(1); d.setYear(1972);
 
    var dateManip = {
        0: function(tt){ return d.setHours(tt); },
        1: function(tt){ return d.setMinutes(tt); },
        2: function(tt){ set = d.setSeconds(tt); mb = d.getDate() - 1; return set; },
        3: function(tt){ set = d.setMonth(parseInt(tt)-1); ma = d.getFullYear() - 1972; return set; },
        4: function(tt){ return d.setDate(tt+mb); },
        5: function(tt){ return d.setYear(tt+ma); }
    };
    
    for( i = 0; i < argc; i++ ){
        no = parseInt(argv[i]*1);
        if (isNaN(no)) {
            return false;
        } else {
            // arg is number, let's manipulate date object
            if(!dateManip[i](no)){
                // failed
                return false;
            }
        }
    }
 
    return Math.floor(d.getTime()/1000);
}

function rand( min, max ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Leslie Hoare
    // +   bugfixed by: Onno Marsman
    // *     example 1: rand(1, 1);
    // *     returns 1: 1
    var argc = arguments.length;
    if (argc == 0) {
        min = 0;
        max = 2147483647;
    } else if (argc == 1) {
        throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');
    }
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function serialize( mixed_value ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Arpad Ray (mailto:arpad@php.net)
    // +   improved by: Dino
    // +   bugfixed by: Andrej Pavlovic
    // +   bugfixed by: Garagoth
    // %          note: We feel the main purpose of this function should be to ease the transport of data between php & js
    // %          note: Aiming for PHP-compatibility, we have to translate objects to arrays
    // *     example 1: serialize(['Kevin', 'van', 'Zonneveld']);
    // *     returns 1: 'a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}'
    // *     example 2: serialize({firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'});
    // *     returns 2: 'a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}'
 
    var _getType = function( inp ) {
        var type = typeof inp, match;
        var key;
        if (type == 'object' && !inp) {
            return 'null';
        }
        if (type == "object") {
            if (!inp.constructor) {
                return 'object';
            }
            var cons = inp.constructor.toString();
            match = cons.match(/(\w+)\(/);
            if (match) {
                cons = match[1].toLowerCase();
            }
            var types = ["boolean", "number", "string", "array"];
            for (key in types) {
                if (cons == types[key]) {
                    type = types[key];
                    break;
                }
            }
        }
        return type;
    };
    var type = _getType(mixed_value);
    var val, ktype = '';
    
    switch (type) {
        case "function": 
            val = ""; 
            break;
        case "undefined":
            val = "N";
            break;
        case "boolean":
            val = "b:" + (mixed_value ? "1" : "0");
            break;
        case "number":
            val = (Math.round(mixed_value) == mixed_value ? "i" : "d") + ":" + mixed_value;
            break;
        case "string":
            val = "s:" + mixed_value.length + ":\"" + mixed_value + "\"";
            break;
        case "array":
        case "object":
            val = "a";
            /*
            if (type == "object") {
                var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/);
                if (objname == undefined) {
                    return;
                }
                objname[1] = serialize(objname[1]);
                val = "O" + objname[1].substring(1, objname[1].length - 1);
            }
            */
            var count = 0;
            var vals = "";
            var okey;
            var key;
            for (key in mixed_value) {
                ktype = _getType(mixed_value[key]);
                if (ktype == "function") { 
                    continue; 
                }
                
                okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key);
                vals += serialize(okey) +
                        serialize(mixed_value[key]);
                count++;
            }
            val += ":" + count + ":{" + vals + "}";
            break;
    }
    if (type != "object" && type != "array") {
      val += ";";
  }
    return val;
}

function unserialize ( inp ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Arpad Ray (mailto:arpad@php.net)
    // +   improved by: Pedro Tainha (http://www.pedrotainha.com)
    // +   bugfixed by: dptr1988
    // *     example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
    // *     returns 1: ['Kevin', 'van', 'Zonneveld']
 
    error = 0;
    if (inp == "" || inp.length < 2) {
        errormsg = "input is too short";
        return;
    }
    var val, kret, vret, cval;
    var type = inp.charAt(0);
    var cont = inp.substring(2);
    var size = 0, divpos = 0, endcont = 0, rest = "", next = "";
 
    switch (type) {
    case "N": // null
        if (inp.charAt(1) != ";") {
            errormsg = "missing ; for null";
        }
        // leave val undefined
        rest = cont;
        break;
    case "b": // boolean
        if (!/[01];/.test(cont.substring(0,2))) {
            errormsg = "value not 0 or 1, or missing ; for boolean";
        }
        val = (cont.charAt(0) == "1");
        rest = cont.substring(2);  //changed...
        break;
    case "s": // string
        val = "";
        divpos = cont.indexOf(":");
        if (divpos == -1) {
            errormsg = "missing : for string";
            break;
        }
        size = parseInt(cont.substring(0, divpos));
        if (size == 0) {
            if (cont.length - divpos < 4) {
                errormsg = "string is too short";
                break;
            }
            rest = cont.substring(divpos + 4);
            break;
        }
        if ((cont.length - divpos - size) < 4) {
            errormsg = "string is too short";
            break;
        }
        if (cont.substring(divpos + 2 + size, divpos + 4 + size) != "\";") {
            errormsg = "string is too long, or missing \";";
        }
        val = cont.substring(divpos + 2, divpos + 2 + size);
        rest = cont.substring(divpos + 4 + size);
        break;
    case "i": // integer
    case "d": // float
        var dotfound = 0;
        for (var i = 0; i < cont.length; i++) {
            cval = cont.charAt(i);
            if (isNaN(parseInt(cval)) && !(type == "d" && cval == "." && !dotfound++)) {
                endcont = i;
                break;
            }
        }
        if (!endcont || cont.charAt(endcont) != ";") {
            errormsg = "missing or invalid value, or missing ; for int/float";
        }
        val = cont.substring(0, endcont);
        val = (type == "i" ? parseInt(val) : parseFloat(val));
        rest = cont.substring(endcont + 1);
        break;
    case "a": // array
        if (cont.length < 4) {
            errormsg = "array is too short";
            return;
        }
        divpos = cont.indexOf(":", 1);
        if (divpos == -1) {
            errormsg = "missing : for array";
            return;
        }
        size = parseInt(cont.substring(1*divpos, 0));  //changed...
        cont = cont.substring(divpos + 2);
        val = new Array();
        if (cont.length < 1) {
            errormsg = "array is too short";
            return;
        }
        for (var i = 0; i + 1 < size * 2; i += 2) {
            kret = unserialize(cont, 1);
            if (error || kret[0] == undefined || kret[1] == "") {
                errormsg = "missing or invalid key, or missing value for array";
                return;
            }
            vret = unserialize(kret[1], 1);
            if (error) {
                errormsg = "invalid value for array";
                return;
            }
            val[kret[0]] = vret[0];
            cont = vret[1];
        }
        if (cont.charAt(0) != "}") {
            errormsg = "missing ending }, or too many values for array";
            return;
        }
        rest = cont.substring(1);
        break;
    case "O": // object
        divpos = cont.indexOf(":");
        if (divpos == -1) {
            errormsg = "missing : for object";
            return;
        }
        size = parseInt(cont.substring(0, divpos));
        var objname = cont.substring(divpos + 2, divpos + 2 + size);
        if (cont.substring(divpos + 2 + size, divpos + 4 + size) != "\":") {
            errormsg = "object name is too long, or missing \":";
            return;
        }
        var objprops = unserialize("a:" + cont.substring(divpos + 4 + size), 1);
        if (error) {
            errormsg = "invalid object properties";
            return;
        }
        rest = objprops[1];
        var objout = "function " + objname + "(){";
        for (key in objprops[0]) {
            objout += "this['" + key + "']=objprops[0]['" + key + "'];";
        }
        objout += "}val=new " + objname + "();";
        eval(objout);
        break;
    default:
        errormsg = "invalid input type";
    }
    return (arguments.length == 1 ? val : [val, rest]);
}

function md5 ( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // + namespaced by: Michael White (http://getsprink.com)
    // +    tweaked by: Jack
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // -    depends on: utf8_encode
    // *     example 1: md5('Kevin van Zonneveld');
    // *     returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
 
    var RotateLeft = function(lValue, iShiftBits) {
        return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
    };
 
    var AddUnsigned = function(lX,lY) {
        var lX4,lY4,lX8,lY8,lResult;
        lX8 = (lX & 0x80000000);
        lY8 = (lY & 0x80000000);
        lX4 = (lX & 0x40000000);
        lY4 = (lY & 0x40000000);
        lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
        if (lX4 & lY4) {
            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
        }
        if (lX4 | lY4) {
            if (lResult & 0x40000000) {
                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
            } else {
                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
            }
        } else {
            return (lResult ^ lX8 ^ lY8);
        }
    };
 
    var F = function(x,y,z) { return (x & y) | ((~x) & z); };
    var G = function(x,y,z) { return (x & z) | (y & (~z)); };
    var H = function(x,y,z) { return (x ^ y ^ z); };
    var I = function(x,y,z) { return (y ^ (x | (~z))); };
 
    var FF = function(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    var GG = function(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    var HH = function(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    var II = function(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    var ConvertToWordArray = function(str) {
        var lWordCount;
        var lMessageLength = str.length;
        var lNumberOfWords_temp1=lMessageLength + 8;
        var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
        var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
        var lWordArray=Array(lNumberOfWords-1);
        var lBytePosition = 0;
        var lByteCount = 0;
        while ( lByteCount < lMessageLength ) {
            lWordCount = (lByteCount-(lByteCount % 4))/4;
            lBytePosition = (lByteCount % 4)*8;
            lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount)<<lBytePosition));
            lByteCount++;
        }
        lWordCount = (lByteCount-(lByteCount % 4))/4;
        lBytePosition = (lByteCount % 4)*8;
        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
        lWordArray[lNumberOfWords-2] = lMessageLength<<3;
        lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
        return lWordArray;
    };
 
    var WordToHex = function(lValue) {
        var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
        for (lCount = 0;lCount<=3;lCount++) {
            lByte = (lValue>>>(lCount*8)) & 255;
            WordToHexValue_temp = "0" + lByte.toString(16);
            WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
        }
        return WordToHexValue;
    };
 
    var x=Array();
    var k,AA,BB,CC,DD,a,b,c,d;
    var S11=7, S12=12, S13=17, S14=22;
    var S21=5, S22=9 , S23=14, S24=20;
    var S31=4, S32=11, S33=16, S34=23;
    var S41=6, S42=10, S43=15, S44=21;
 
    str = utf8_encode(str);
    x = ConvertToWordArray(str);
    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
    
    xl = x.length;
    for (k=0;k<xl;k+=16) {
        AA=a; BB=b; CC=c; DD=d;
        a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
        d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
        c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
        b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
        a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
        d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
        c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
        b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
        a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
        d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
        c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
        b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
        a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
        d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
        c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
        b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
        a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
        d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
        c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
        b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
        a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
        d=GG(d,a,b,c,x[k+10],S22,0x2441453);
        c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
        b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
        a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
        d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
        c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
        b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
        a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
        d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
        c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
        b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
        a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
        d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
        c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
        b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
        a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
        d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
        c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
        b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
        a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
        d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
        c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
        b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
        a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
        d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
        c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
        b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
        a=II(a,b,c,d,x[k+0], S41,0xF4292244);
        d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
        c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
        b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
        a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
        d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
        c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
        b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
        a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
        d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
        c=II(c,d,a,b,x[k+6], S43,0xA3014314);
        b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
        a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
        d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
        c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
        b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
        a=AddUnsigned(a,AA);
        b=AddUnsigned(b,BB);
        c=AddUnsigned(c,CC);
        d=AddUnsigned(d,DD);
    }
 
    var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
 
    return temp.toLowerCase();
}

function utf8_encode ( string ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: sowberry
    // +    tweaked by: Jack
    // +   bugfixed by: Onno Marsman
    // *     example 1: utf8_encode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'
 
    string = (string+'').replace(/\r\n/g,"\n");
    var utftext = "";
    var start, end;
    var stringl = 0;
 
    start = end = 0;
    stringl = string.length;
    for (var n = 0; n < stringl; n++) {
        var c1 = string.charCodeAt(n);
        var enc = null;
 
        if (c1 < 128) {
            end++;
        } else if((c1 > 127) && (c1 < 2048)) {
            enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
        } else {
            enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
        }
        if (enc != null) {
            if (end > start) {
                utftext += string.substring(start, end);
            }
            utftext += enc;
            start = end = n+1;
        }
    }
 
    if (end > start) {
        utftext += string.substring(start, string.length);
    }
 
    return utftext;
}

function htmlspecialchars_decode(string, quote_style) {
    // http://kevin.vanzonneveld.net
    // +   original by: Mirek Slugen
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Mateusz "loonquawl" Zalega
    // +      input by: ReverseSyntax
    // +      input by: Slawomir Kaniecki
    // +      input by: Scott Cariss
    // +      input by: Francois
    // +   bugfixed by: Onno Marsman
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // -    depends on: get_html_translation_table
    // *     example 1: htmlspecialchars_decode("<p>this -&gt; &quot;</p>", 'ENT_NOQUOTES');
    // *     returns 1: '<p>this -> &quot;</p>'
 
    var histogram = {}, symbol = '', tmp_str = '', i = 0;
    tmp_str = string.toString();
    
    if (false === (histogram = get_html_translation_table('HTML_SPECIALCHARS', quote_style))) {
        return false;
    }
    
    for (symbol in histogram) {
        entity = histogram[symbol];
        tmp_str = tmp_str.split(entity).join(symbol);
    }
    
    return tmp_str;
}

function htmlspecialchars (string, quote_style) {
    // http://kevin.vanzonneveld.net
    // +   original by: Mirek Slugen
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Nathan
    // +   bugfixed by: Arno
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // -    depends on: get_html_translation_table
    // *     example 1: htmlspecialchars("<a href='test'>Test</a>", 'ENT_QUOTES');
    // *     returns 1: '&lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;'
 
    var histogram = {}, symbol = '', tmp_str = '', entity = '';
    tmp_str = string.toString();
    
    if (false === (histogram = get_html_translation_table('HTML_SPECIALCHARS', quote_style))) {
        return false;
    }
    
    for (symbol in histogram) {
        entity = histogram[symbol];
        tmp_str = tmp_str.split(symbol).join(entity);
    }
    
    return tmp_str;
}

function get_html_translation_table(table, quote_style) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // %          note: It has been decided that we're not going to add global
    // %          note: dependencies to php.js. Meaning the constants are not
    // %          note: real constants, but strings instead. integers are also supported if someone
    // %          note: chooses to create the constants themselves.
    // %          note: Table from http://www.the-art-of-web.com/html/character-codes/
    // *     example 1: get_html_translation_table('HTML_SPECIALCHARS');
    // *     returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
    
    var entities = {}, histogram = {}, decimal = 0, symbol = '';
    var constMappingTable = {}, constMappingQuoteStyle = {};
    var useTable = {}, useQuoteStyle = {};
    
    useTable      = (table ? table.toUpperCase() : 'HTML_SPECIALCHARS');
    useQuoteStyle = (quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT');
    
    // Translate arguments
    constMappingTable[0]      = 'HTML_SPECIALCHARS';
    constMappingTable[1]      = 'HTML_ENTITIES';
    constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
    constMappingQuoteStyle[2] = 'ENT_COMPAT';
    constMappingQuoteStyle[3] = 'ENT_QUOTES';
    
    // Map numbers to strings for compatibilty with PHP constants
    if (!isNaN(useTable)) {
        useTable = constMappingTable[useTable];
    }
    if (!isNaN(useQuoteStyle)) {
        useQuoteStyle = constMappingQuoteStyle[useQuoteStyle];
    }
    
    if (useTable == 'HTML_SPECIALCHARS') {
        // ascii decimals for better compatibility
        entities['60'] = '&lt;';
        entities['62'] = '&gt;';
        entities['38'] = '&amp;';
    } else if (useTable == 'HTML_ENTITIES') {
        // ascii decimals for better compatibility
      entities['38'] = '&amp;';
      entities['60'] = '&lt;';
      entities['62'] = '&gt;';
      entities['160'] = '&nbsp;';
      entities['161'] = '&iexcl;';
      entities['162'] = '&cent;';
      entities['163'] = '&pound;';
      entities['164'] = '&curren;';
      entities['165'] = '&yen;';
      entities['166'] = '&brvbar;';
      entities['167'] = '&sect;';
      entities['168'] = '&uml;';
      entities['169'] = '&copy;';
      entities['170'] = '&ordf;';
      entities['171'] = '&laquo;';
      entities['172'] = '&not;';
      entities['173'] = '&shy;';
      entities['174'] = '&reg;';
      entities['175'] = '&macr;';
      entities['176'] = '&deg;';
      entities['177'] = '&plusmn;';
      entities['178'] = '&sup2;';
      entities['179'] = '&sup3;';
      entities['180'] = '&acute;';
      entities['181'] = '&micro;';
      entities['182'] = '&para;';
      entities['183'] = '&middot;';
      entities['184'] = '&cedil;';
      entities['185'] = '&sup1;';
      entities['186'] = '&ordm;';
      entities['187'] = '&raquo;';
      entities['188'] = '&frac14;';
      entities['189'] = '&frac12;';
      entities['190'] = '&frac34;';
      entities['191'] = '&iquest;';
      entities['192'] = '&Agrave;';
      entities['193'] = '&Aacute;';
      entities['194'] = '&Acirc;';
      entities['195'] = '&Atilde;';
      entities['196'] = '&Auml;';
      entities['197'] = '&Aring;';
      entities['198'] = '&AElig;';
      entities['199'] = '&Ccedil;';
      entities['200'] = '&Egrave;';
      entities['201'] = '&Eacute;';
      entities['202'] = '&Ecirc;';
      entities['203'] = '&Euml;';
      entities['204'] = '&Igrave;';
      entities['205'] = '&Iacute;';
      entities['206'] = '&Icirc;';
      entities['207'] = '&Iuml;';
      entities['208'] = '&ETH;';
      entities['209'] = '&Ntilde;';
      entities['210'] = '&Ograve;';
      entities['211'] = '&Oacute;';
      entities['212'] = '&Ocirc;';
      entities['213'] = '&Otilde;';
      entities['214'] = '&Ouml;';
      entities['215'] = '&times;';
      entities['216'] = '&Oslash;';
      entities['217'] = '&Ugrave;';
      entities['218'] = '&Uacute;';
      entities['219'] = '&Ucirc;';
      entities['220'] = '&Uuml;';
      entities['221'] = '&Yacute;';
      entities['222'] = '&THORN;';
      entities['223'] = '&szlig;';
      entities['224'] = '&agrave;';
      entities['225'] = '&aacute;';
      entities['226'] = '&acirc;';
      entities['227'] = '&atilde;';
      entities['228'] = '&auml;';
      entities['229'] = '&aring;';
      entities['230'] = '&aelig;';
      entities['231'] = '&ccedil;';
      entities['232'] = '&egrave;';
      entities['233'] = '&eacute;';
      entities['234'] = '&ecirc;';
      entities['235'] = '&euml;';
      entities['236'] = '&igrave;';
      entities['237'] = '&iacute;';
      entities['238'] = '&icirc;';
      entities['239'] = '&iuml;';
      entities['240'] = '&eth;';
      entities['241'] = '&ntilde;';
      entities['242'] = '&ograve;';
      entities['243'] = '&oacute;';
      entities['244'] = '&ocirc;';
      entities['245'] = '&otilde;';
      entities['246'] = '&ouml;';
      entities['247'] = '&divide;';
      entities['248'] = '&oslash;';
      entities['249'] = '&ugrave;';
      entities['250'] = '&uacute;';
      entities['251'] = '&ucirc;';
      entities['252'] = '&uuml;';
      entities['253'] = '&yacute;';
      entities['254'] = '&thorn;';
      entities['255'] = '&yuml;';
    } else {
        throw Error("Table: "+useTable+' not supported');
        return false;
    }
    
    if (useQuoteStyle != 'ENT_NOQUOTES') {
        entities['34'] = '&quot;';
    }
    
    if (useQuoteStyle == 'ENT_QUOTES') {
        entities['39'] = '&#039;';
    }
    
    // ascii decimals to real symbols
    for (decimal in entities) {
        symbol = String.fromCharCode(decimal)
        histogram[symbol] = entities[decimal];
    }
    
    return histogram;
}