/*****************************************************************************\

 Javascript "Base64" library

 @version: 1.0 - 2005.11.19
 @author: Matteo Casati - http://www.guru4.net/
 @notes: first release.

\*****************************************************************************/

// static class (Base64) declaration
function Base64() {}

// publics
Base64.encode = function(s)
{
	Base64._setStr(s);
	var result = new Array();	// use array as string builder
	var inBuffer = new Array(3);
	var lineCount = 0;
	var done = false;
	while(!done && (inBuffer[0] = Base64._getStr()) != Base64._inputEnd)
	{
		inBuffer[1] = Base64._getStr();
		inBuffer[2] = Base64._getStr();
		result[result.length] = (Base64._chars[ inBuffer[0] >> 2 ]);
		if (inBuffer[1] != Base64._inputEnd)
		{
			result[result.length] = (Base64._chars [(( inBuffer[0] << 4 ) & 0x30) | (inBuffer[1] >> 4) ]);
			if (inBuffer[2] != Base64._inputEnd)
			{
				result[result.length] = (Base64._chars [((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6) ]);
				result[result.length] = (Base64._chars [inBuffer[2] & 0x3F]);
			}
			else
			{
				result[result.length] = (Base64._chars [((inBuffer[1] << 2) & 0x3c)]);
				result[result.length] = ("=");
				done = true;
			}
		} 
		else
		{
			result[result.length] = (Base64._chars [(( inBuffer[0] << 4 ) & 0x30)]);
			result[result.length] = ("=");
			result[result.length] = ("=");
			done = true;
		}
		lineCount += 4;
		if (lineCount >= 76)
		{
			result[result.length] = ("\n");
			lineCount = 0;
		}
	}
	return result.join("");
}

Base64.decode = function(s)
{
	Base64._setStr(s);
	var result = new Array();	// use array as string builder
	var inBuffer = new Array(4);
	var done = false;
	while (!done && (inBuffer[0] = Base64._getReverse()) != Base64._inputEnd && (inBuffer[1] = Base64._getReverse()) != Base64._inputEnd)
	{
		inBuffer[2] = Base64._getReverse();
		inBuffer[3] = Base64._getReverse();
		result[result.length] = Base64._n2s((((inBuffer[0] << 2) & 0xff)| inBuffer[1] >> 4));
		if(inBuffer[2] != Base64._inputEnd)
		{
			result[result.length] = Base64._n2s((((inBuffer[1] << 4) & 0xff)| inBuffer[2] >> 2));
			if (inBuffer[3] != Base64._inputEnd)
				result[result.length] = Base64._n2s((((inBuffer[2] << 6)  & 0xff) | inBuffer[3]));
			else 
				done = true;
		}
		else
			done = true;
	}
	return result.join("");
}

// privates
Base64._inputEnd = -1;
Base64._chars = new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/");
Base64._reverseChars = new Array();
for(var i = 0; i < Base64._chars.length; i++)
    Base64._reverseChars[Base64._chars[i]] = i;
Base64._str = "";
Base64._count = 0;
Base64._setStr = function(s)
{
    Base64._str = s;
    Base64._count = 0;
}
Base64._getStr = function()
{    
    if(!Base64._str) 
		return Base64._inputEnd;
    if(Base64._count >= Base64._str.length) 
		return Base64._inputEnd;
    var c = Base64._str.charCodeAt(Base64._count) & 0xff;
    Base64._count++;
    return c;
}
Base64._getReverse = function()
{   
    if(!Base64._str)
		return Base64._inputEnd;
    while(true)
    {      
        if(Base64._count >= Base64._str.length) 
			return Base64._inputEnd;
        var nextCharacter = Base64._str.charAt(Base64._count);
        Base64._count++;
        if(Base64._reverseChars[nextCharacter])
            return Base64._reverseChars[nextCharacter];
        if (nextCharacter == "A") 
			return 0;
    }
    return Base64._inputEnd;
}
Base64._n2s = function(n)
{
    n = n.toString(16);
    if(n.length == 1)
		n = "0" + n;
    n = "%" + n;
    return unescape(n);
}