//RMP Protection Limited, March 2008
//http://www.carrot.org
//This Javascript library is provided for RMP Protected Content purpose only. 

document.write('<script type="text/javascript" src="http://localhost:11060/info"></script>');
if (typeof RMP == "undefined") {	var RMP = {}; }
var paymentId;
var formArray=new Array();
var lastComponent;
var batchPay=true;
var batchPayFormIndex=0;
//var strCarrotPurseLocation="http://www.test.carrot.org/en/GB/software";
function rmp_client_request_callback(id, status, return_url){
	if((status == 'pending')||(status == 'busy')||(status == 'unknown'))
	{
		//window.setTimeout(RMP.pollPayment(id), 1000);
		eval("window.setTimeout('RMP.pollPayment("+id+")',500)");
	}
	else if(status == 'ok'){
		rmp_payment_ok(id, return_url);
	}
	else {
		rmp_payment_failed(id, return_url);
	}
};
function rmp_payment_ok(id, url){
	var s1=url.indexOf("id=");
	var s2=url.indexOf("hash=");
	var s3=url.substring(s1+3,s2-1);
	var s4=url.substring(s2+5);
	if(!batchPay)	
		RMP.getContent(s3,s4);
	else	
	{
		document.getElementById("item_"+s3).appendChild(document.createTextNode(" OK!!!!!!"));
		document.getElementById("item_"+s3).style.color="#37B400";
		document.getElementById("iframeBatchPay").src=url;
		batchPayFormIndex++;
		if (batchPayFormIndex<formArray.length)	RMP.startPayment(formArray[batchPayFormIndex],false);	
	}
};

function rmp_payment_failed(id, url){
	self.location=url;
};
RMP.purseAvailable=function ()
{
	//alert(rmp_client_interface_version);
	return(typeof rmp_client_interface_version != 'undefined')
};


RMP.pollPayment=function(pId)
{
	var el = document.createElement("script");
	el.setAttribute("src","");
	el.src = 'http://localhost:11060/poll/' + pId;
	document.getElementById('poller').appendChild(el);
};


RMP.initialise = function()
{
	var rmp = "rmp";
	for (var tag in RMP.elements)
	{
		var components = RMP.Html.getElementsByTagNameNS(tag, rmp);
		for (var i=0; i<components.length; i++)
		{
			RMP.elements[tag].method(components[i]);
		}
	}
	var ele;	
	var container=document.createElement('div');
	container.setAttribute("id","poller");
	container.setAttribute("style","display: none");
	try{
		ele=document.createElement("<iframe id='paymentrequest' name='hidden' src='' style='DISPLAY: none'>");
	}
	catch(e){
		ele=document.createElement('iframe');
		ele.setAttribute("id","paymentrequest");
		ele.setAttribute("name","hidden");
		ele.setAttribute("src","");
		//ele.setAttribute("style","display: none");
		ele.style.display="none";
	}
	container.appendChild(ele);
	document.body.appendChild(container);
	if(location.href.indexOf("id=")>1 && location.href.indexOf("hash=")>1) 
		rmp_payment_ok("111",location.href);
	if(batchPay){
		try{
			ele=document.createElement("<input type='button' name='pay' value='Pay Now!' onclick=RMP.startPayment(formArray[0],false);>");
		}
		catch(e){
			ele=document.createElement('input');
			ele.setAttribute("type","button");
			ele.setAttribute("name","pay");
			ele.setAttribute("value","Pay Now!");
			ele.setAttribute("onclick","RMP.startPayment(formArray[0],false);");
		}
		lastComponent.insertAdjacentElement("afterEnd", ele);
		
		try{
			ele=document.createElement("<iframe id='iframeBatchPay' name='BatchPay' src='' style='DISPLAY: none'>");
		}
		catch(e){
			ele=document.createElement('iframe');
			ele.setAttribute("id","iframeBatchPay");
			ele.setAttribute("name","BatchPay");
			ele.setAttribute("src","http://localhost:11060/poll/1233124");
			//ele.setAttribute("style","display: none");
			ele.style.display="none";
		}
		document.body.appendChild(ele);
	}

};
RMP.createProtectedContent = function(declaration) {
	var encryptedContent;

	var itemString="";
	var container = document.createElement("form");
	container.setAttribute("method", "post");
	container.setAttribute("target", "hidden");
	RMP.forAttributes(declaration,function(attr) 
	{
		if(RMP.elements[attr.nodeName.toLowerCase()] != null)
		{
			if (attr.nodeName.toLowerCase() == "service_url")
			{
				container.setAttribute("action", attr.nodeValue);
			}
			else if (attr.nodeName.toLowerCase() == "id")
			{
				container.setAttribute("id", "form_" + attr.nodeValue);
			}
			else if(attr.nodeName.toLowerCase() == "buy_button")
			{
				batchPay=false;
				if (attr.nodeValue == "none")
				{
					if (declaration.getAttribute("trigger_id")!=null)
					{
						//document.getElementById(declaration.getAttribute("trigger_id")).setAttribute("onclick","RMP.startPayment('"+declaration.getAttribute("id")+"',false);");	
						document.getElementById(declaration.getAttribute("trigger_id")).onclick=function(){RMP.startPayment(declaration.getAttribute("id"),false);};
					}
				}
				else if (attr.nodeValue.toLowerCase() == "autosubmit")
				{
					RMP.autoSubmit(declaration.getAttribute("id"));
				}
				else
				{
					var ele;
					try{
						ele=document.createElement("<input type='image' name='submit' alt='CarrotPay - The fastest, easiest way to pay online!' src='"+ attr.nodeValue +"'>");
						ele.onclick=function(){RMP.startPayment(declaration.getAttribute("id"),true);};
					}
					catch(e){
						ele=document.createElement('input');
						ele.setAttribute("type","image");
						ele.setAttribute("src",attr.nodeValue);	
						ele.setAttribute("name","submit");	
						ele.setAttribute("onclick","RMP.startPayment('"+declaration.getAttribute("id")+"',true);");
						ele.setAttribute("alt","CarrotPay - The fastest, easiest way to pay online!");	
					}
					container.appendChild(ele);					
				}
			} 			
			else
			{
				if (attr.nodeName.toLowerCase() == "merchant_id")
				{
					itemString=attr.nodeValue+ "  "+itemString;
					var ele;
					try{
						ele=document.createElement("<input name='merchant' type='hidden' value='"+attr.nodeValue+"'>");
					}
					catch(e){
						ele=document.createElement('input');
						ele.setAttribute("type", "hidden");
						ele.setAttribute("name","merchant");
						ele.setAttribute("value",attr.nodeValue);
					}
					container.appendChild(ele);
				}
				else if (attr.nodeName.toLowerCase() == "price")
				{
					itemString=attr.nodeValue+ "  "+itemString;
					var ele;
					try{
						ele=document.createElement("<input name='total' type='hidden' value='"+attr.nodeValue+"'>");
					}
					catch(e){
						ele=document.createElement('input');
						ele.setAttribute("type", "hidden");
						ele.setAttribute("name","total");
						ele.setAttribute("value",attr.nodeValue);
					}
					container.appendChild(ele);
				}				
				else
				{
					if(attr.nodeName.toLowerCase()=="description")
						itemString=attr.nodeValue+ "  "+itemString;
					var ele;
					try{
						ele=document.createElement("<input name='"+attr.nodeName+"' type='hidden' value='"+attr.nodeValue+"'>");
					}
					catch(e){
						ele=document.createElement('input');
						ele.setAttribute("type", "hidden");
						if (attr.nodeName=="disputeresolution_url") 
							ele.setAttribute("name","disputeResolution_url");
						else
							ele.setAttribute("name",attr.nodeName);
						ele.setAttribute("value",attr.nodeValue);
					}
					container.appendChild(ele);
				}
			}
		}	
	});		
	var elePayment, eleTarget, eleDisableReturnUrl;
	try{
		elePayment=document.createElement("<input type='hidden' name='paymentId' value=''>");
		eleTarget=document.createElement("<input type='hidden' name='target' value='top'>");
		eleDisableReturnUrl=document.createElement("<input type='hidden' name='code' value='var temp'>");	
	}
	catch(e)
	{
		elePayment=document.createElement('input');
		elePayment.setAttribute("type", "hidden");
		elePayment.setAttribute("name","paymentId");
		elePayment.setAttribute("value","");
		
		eleTarget=document.createElement('input');
		eleTarget.setAttribute("type", "hidden");
		eleTarget.setAttribute("name","target");
		eleTarget.setAttribute("value","top");
		
		eleDisableReturnUrl=document.createElement('input');
		eleDisableReturnUrl.setAttribute("type", "hidden");
		eleDisableReturnUrl.setAttribute("name","code");
		eleDisableReturnUrl.setAttribute("value","var temp");				
	}

	container.appendChild(elePayment);
	container.appendChild(eleTarget);
	container.appendChild(eleDisableReturnUrl);
	declaration.insertAdjacentElement("afterEnd", container);
	if(batchPay){
		formArray[formArray.length]=declaration.getAttribute("id");
		itemString=formArray.length+".  "+itemString;	
		var p=document.createElement("P");
		p.setAttribute("id","item_"+declaration.getAttribute("id"));
		p.appendChild(document.createTextNode(itemString));
		declaration.insertAdjacentElement("afterEnd", p);
		lastComponent=p;
	}
};
RMP.elements = {
	  "protectedContent":{"method":RMP.createProtectedContent},
		"service_url":{"method":RMP.createInputElement},
		"merchant_id":{"method":RMP.createInputElement},
		"id":{"method":RMP.createInputElement},

		"price":{"method":RMP.createInputElement},
		"description":{"method":RMP.createInputElement},
		"return_url":{"method":RMP.createInputElement},
		"fail_url":{"method":RMP.createInputElement},
		"disputeresolution_url":{"method":RMP.createInputElement},
		"buy_button":{"method":RMP.createInputElement}
};
RMP.Browser = {};
RMP.Browser.IE = true;
RMP.Browser.MOZ = false;
if (document.implementation.createDocument)
{
	RMP.Browser.IE = false;
	RMP.Browser.MOZ = true;
}
if (RMP.Browser.MOZ)
{
	HTMLElement.prototype.insertAdjacentElement = function(pos,node)
	{
		switch (pos)
		{
			case "beforeBegin":
				this.parentNode.insertBefore(node,this)
				break;
			case "afterBegin":
				this.insertBefore(node,this.firstChild);
				break;
			case "beforeEnd":
				this.appendChild(node);
				break;
			case "afterEnd":
				if (this.nextSibling)
					this.parentNode.insertBefore(node,this.nextSibling);
				else
					this.parentNode.appendChild(node);
				break;
			case "appendChild":
				this.parentNode.appendChild(node);
				break;
		}
	}
	HTMLElement.prototype.insertAdjacentHTML = function(pos,s)
	{
		var r = this.ownerDocument.createRange();
		r.setStartBefore(this);
		var node = r.createContextualFragment(s);
		this.insertAdjacentElement(pos,node)
	}
};
RMP.Html = {};
RMP.Html.getElementsByTagNameNS = function(tag, ns, context)
{
	context = context || document;
  var qname = ns + ":" + tag;
  if (RMP.Browser.IE) 
  {
  	qname = tag;
  }
  var elems = context.getElementsByTagName(qname);

  if (RMP.Browser.IE) 
  {
    realElems = [];
    for (var i=0; i<elems.length; i++)
    {
	    if (elems[i].scopeName == ns)
		    realElems.push(elems[i]);
    }
    elems = realElems;
  }
  return elems;
};
RMP.Html.getFirstChild = function(node)
{
	var firstChild = null;
	for (var i=0; i<node.childNodes.length; i++)
	{
		if (node.childNodes[i].nodeType == 1)
		{
			firstChild = node.childNodes[i];
			break;
		}
	}
	return firstChild;
};
RMP.parseStyle = function(styles, declaration, container)
{
	for (var i=0; i<styles.length; i++)
	{
		container.style[styles[i]] = declaration.getAttribute(styles[i]);
	}
};
RMP.forAttributes = function(node, func)
{
	for (var i=0; i<node.attributes.length; i++)
	{
		func.call(this, node.attributes[i]);
	}
};
RMP.forChildren = function(node, func)
{
	for (var i=0; i<node.childNodes.length; i++)
	{
		if (node.childNodes[i].nodeType == 1)
			func.call(this, node.childNodes[i]);
		else if(node.childNodes[i].nodeType == 3)
		{
			func.call(this, node.attributes[i]);
		}
	}
};
RMP.isRootNode = function(node)
{
	node = node.parentNode;
	if (node == null || node == document)
		return true;
	if (node.scopeName == "rmp" || node.tagName.toLowerCase().indexOf("rmp:") == 0)
	{
		return false;
	}
	else
	{
		return RMP.isRootNode(node);
	}
};
RMP.formatName = function(name)
{
	if (name.indexOf("rmp:") == 0)
	{
		return name.substr(4, name.length-4);
	}
};
RMP.startPayment=function(id,buy_button)
{
	paymentId=Math.floor(Math.random()*10000);
	var orderForm=document.getElementById("form_"+id);
	orderForm.paymentId.setAttribute('value',paymentId);
	
	if (!buy_button)
		orderForm.submit();
	eval("window.setTimeout('RMP.pollPayment("+paymentId+")',2000)");
	//window.setTimeout(RMP.pollPayment(paymentId),2000);
};
RMP.autoSubmit = function(id)
{
	if (document.getElementById("form_"+id)==null)
	{
		window.setTimeout("RMP.autoSubmit('"+id+"')",2000);
	}
	else
	{
		eval("RMP.startPayment('"+id+"',false)");
	}
};
RMP.getContent = function(id,hash)
{
	var nodes=document.getElementById(id).childNodes;
	var cont;
	if((nodes.length>0)&&(nodes[0].nodeType==3))
	{
		cont=RMP.trim(nodes[0].nodeValue);
	}
	else
	{
		alert("Retrieve RMP Protected Content Failed! Please Contact the webmaster!");
		return;
	}
	
	var target_id=document.getElementById(id).getAttribute('target_id');
	if (cont.toLowerCase().indexOf(".txt") != (cont.toLowerCase().length-4))
	{
		document.getElementById(target_id).innerHTML=RMP.decrypt(hash,cont).replace(/\\"/g,"").replace(/\\'/g,"'"); 
	}
	else
	{ 
		var tempstr=cont.toLowerCase();
		if (tempstr.indexOf("http")!=0)	cont="http://"+cont;
		var xhr = false;
		/*@cc_on @*/
		/*@if (@_jscript_version >= 5)
		
		try 
		{
		  xhr = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
		  try {
		    xhr = new ActiveXObject("Microsoft.XMLHTTP");
		  } catch (e2) {
		    xhr = false;
		  }
		}
		@end @*/
		if (!xhr && typeof XMLHttpRequest != 'undefined') {
		  xhr = new XMLHttpRequest();
		}
		
		xhr.open("GET",cont,true);
		xhr.onreadystatechange= function()
		{
			if ((xhr.readyState==4)&&(xhr.status==200))
			{
				cont=xhr.responseText;					
				document.getElementById(target_id).innerHTML=RMP.decrypt(hash,RMP.checkBOM(cont)).replace(/\\"/g,"").replace(/\\'/g,"'"); //.replace(/"\\"/g,'"').replace(/\\""/g,'"');
			}
		}
		xhr.send(null);
	}
};
RMP.decrypt= function(key,str)
{
	return RMP.trimPadding(RMP.utf8to16(RMP.des(key,RMP.base64decode(str),0)));	
};
RMP.des= function(key, message, encrypt, mode, iv, padding) {
  var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004);
  var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000);
  var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200);
  var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
  var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100);
  var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010);
  var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002);
  var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000);
  var keys = RMP.des_createKeys (key);
  var m=0, i, j, temp, temp2, right1, right2, left, right, looping;
  var cbcleft, cbcleft2, cbcright, cbcright2
  var endloop, loopinc;
  var len = message.length;
  var chunk = 0;
  var iterations = keys.length == 32 ? 3 : 9; 
  if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);}
  else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);}
  if (padding == 2) message += "        ";
  else if (padding == 1) {temp = 8-(len%8); message += String.fromCharCode (temp,temp,temp,temp,temp,temp,temp,temp); if (temp==8) len+=8;} //PKCS7 padding
  else if (!padding) message += "\0\0\0\0\0\0\0\0";
  result = "";
  tempresult = "";
  if (mode == 1) {
    cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
    cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
    m=0;
  }
  while (m < len) {
    left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
    right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
    if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}}
    temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
    temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
    temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
    temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
    temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
    left = ((left << 1) | (left >>> 31)); 
    right = ((right << 1) | (right >>> 31)); 
    for (j=0; j<iterations; j+=3) {
      endloop = looping[j+1];
      loopinc = looping[j+2];
      for (i=looping[j]; i!=endloop; i+=loopinc) { //for efficiency
        right1 = right ^ keys[i]; 
        right2 = ((right >>> 4) | (right << 28)) ^ keys[i+1];
        //the result is attained by passing these bytes through the S selection functions
        temp = left;
        left = right;
        right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f]
              | spfunction6[(right1 >>>  8) & 0x3f] | spfunction8[right1 & 0x3f]
              | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f]
              | spfunction5[(right2 >>>  8) & 0x3f] | spfunction7[right2 & 0x3f]);
      }
      temp = left; left = right; right = temp; //unreverse left and right
    }
    left = ((left >>> 1) | (left << 31)); 
    right = ((right >>> 1) | (right << 31)); 
    temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
    temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
    temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
    temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
    temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
    if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}}
    tempresult += String.fromCharCode ((left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff));
    chunk += 8;
    if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 0;}
  }
  return result + tempresult;
};
RMP.des_createKeys = function(key) {
  //declaring this locally speeds things up a bit
  pc2bytes0  = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
  pc2bytes1  = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101);
  pc2bytes2  = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808);
  pc2bytes3  = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
  pc2bytes4  = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010);
  pc2bytes5  = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
  pc2bytes6  = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002);
  pc2bytes7  = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800);
  pc2bytes8  = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
  pc2bytes9  = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408);
  pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020);
  pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
  pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
  pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
  var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
  var keys = new Array (32 * iterations);
  var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
  var lefttemp, righttemp, m=0, n=0, temp;
  for (var j=0; j<iterations; j++) { //either 1 or 3 iterations
    left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
    right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
    temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
    temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
    temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2);
    temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
    temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
    temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
    temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
    temp = (left << 8) | ((right >>> 20) & 0x000000f0);
    left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
    right = temp;
    for (i=0; i < shifts.length; i++) {
      if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);}
      else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);}
      left &= -0xf; right &= -0xf;
      lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf]
              | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf]
              | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf]
              | pc2bytes6[(left >>> 4) & 0xf];
      righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf]
                | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf]
                | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf]
                | pc2bytes13[(right >>> 4) & 0xf];
      temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; 
      keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16);
    }
  }
  return keys;
};
RMP.stringToHex = function(s) {
  var r = "0x";
  var hexes = new Array ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
  for (var i=0; i<s.length; i++) {r += hexes [s.charCodeAt(i) >> 4] + hexes [s.charCodeAt(i) & 0xf];}
  return r;
};
RMP.hexToString = function(s) {
  var r = "";
  var hexes = new Array ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
  for (var i= (s.substr(0,2)=="0x")?2:0; i<s.length; i+=2)
  {
  	r += String.fromCharCode(RMP.base_convert(s.substr(i,2),16,10));  
  }
  return r;
};
RMP.base_convert=function(number, frombase, tobase) {
    return parseInt(number+'', frombase+0).toString(tobase+0);
};
RMP.strToLongs=function (s) {  
		// convert string to array of longs, each containing 4 chars
    // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
    var l = new Array(Math.ceil(s.length/4));
    for (var i=0; i<l.length; i++) {
        l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) + 
               (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
    }
    return l;
}; 
RMP.longsToStr=function (l) {  // convert array of longs back to string
    var a = new Array(l.length);
    for (var i=0; i<l.length; i++) {
        a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF, 
                                   l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
    }
    return a.join('');  
};
RMP.escCtrlCh=function (str) { 
    return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
};
RMP.unescCtrlCh=function (str) { 
    return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
};
RMP.checkBOM=function (str)
{
	if (str.charCodeAt(0)==65279)
		str=str.substring(1);
	return str;	
};
RMP.trimPadding=function (str)
{
	var n=str.length;
	while (n>0)
	{
		if (str.charCodeAt(n-1)==0)
			n--;
		else
			break;
	}
	return str.substr(0,n);	
};
RMP.utf16to8 =function(str)   
{  
	var   out,   i,   len,   c;  
	out = "";  
	len = str.length;  
	for(i = 0; i < len; i++)   
	{  
		c = str.charCodeAt(i);  
	  if ((c >= 0x0001) && (c <= 0x007F)) 
	  {  
	  	out += str.charAt(i);  
	  }   
	  else if (c > 0x07FF)   
	  {  
	    out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));  
	    out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));  
	    out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));  
	  }   
	  else
	  {  
	    out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));  
	    out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));  
	  }  
	}  
  return out;  
};  
RMP.utf8to16 = function(str)   
{  
	var   out,   i,   len,   c;  
	var   char2,   char3;  
	out   =   "";  
	len   =   str.length;  
	i   =   0;  
	while(i   <   len)   
	{  
	  c=str.charCodeAt(i++);  
	  switch(c   >>   4)  
	  {    
	      case   0:   case   1:   case   2:   case   3:   case   4:   case   5:   case   6:   case   7:  
	          out   +=   str.charAt(i-1);  
	          break;  
	      case   12:   case   13:  
	          char2   =   str.charCodeAt(i++);  
	          out   +=   String.fromCharCode(((c   &   0x1F)   <<   6)   |   (char2   &   0x3F));  
	          break;  
	      case   14:  
	          char2 =   str.charCodeAt(i++);  
	          char3 =   str.charCodeAt(i++);  
	          out   +=   String.fromCharCode(((c   &   0x0F)   <<   12)   |  
								        ((char2   &   0x3F)   <<   6)   |  
								        ((char3   &   0x3F)   <<   0));  
	          break;  
	  }  
	} 
  return   out;  
}; 
RMP.trim=function(str, chars) {
	return RMP.ltrim(RMP.rtrim(str, chars), chars);
};
RMP.ltrim=function(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
};
RMP.rtrim=function(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
};
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
RMP.base64encode=function(str) {
  var out, i, len;
  var c1, c2, c3;
  len = str.length;
  i = 0;
  out = "";
  while(i < len) {
		c1 = str.charCodeAt(i++) & 0xff;
		if(i == len)
		{
		   out += base64EncodeChars.charAt(c1 >> 2);
		   out += base64EncodeChars.charAt((c1 & 0x3) << 4);
		   out += "==";
		   break;
		}
		c2 = str.charCodeAt(i++);
		if(i == len)
		{
		   out += base64EncodeChars.charAt(c1 >> 2);
		   out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
		   out += base64EncodeChars.charAt((c2 & 0xF) << 2);
		   out += "=";
		   break;
		}
		c3 = str.charCodeAt(i++);
		out += base64EncodeChars.charAt(c1 >> 2);
		out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
		out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
		out += base64EncodeChars.charAt(c3 & 0x3F);
	}
	return out;
};
RMP.base64decode=function(str) {
	var c1, c2, c3, c4;
	var i, len, out;
	len = str.length;
	i = 0;
	out = "";
	while(i < len) {
		do {
		   c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
		} while(i < len && c1 == -1);
		if(c1 == -1)
		   break;
		do {
			c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
		} while(i < len && c2 == -1);
		if(c2 == -1)
			break;
		out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
		do {
		 	c3 = str.charCodeAt(i++) & 0xff;
			if(c3 == 61)
			return out;
		 	c3 = base64DecodeChars[c3];
		} while(i < len && c3 == -1);
		if(c3 == -1)
		 	break;
		out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
		do {
		 	c4 = str.charCodeAt(i++) & 0xff;
		 	if(c4 == 61)
			return out;
		 	c4 = base64DecodeChars[c4];
		} while(i < len && c4 == -1);
		if(c4 == -1)
		 	break;
			out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
		}
		return out;
};