//*********************************//
// BEGIN BASE 64
//*********************************//

var END_OF_INPUT = -1;

var base64Chars = 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','+','/'
    );

var reverseBase64Chars = new Array();
for (var i=0; i < base64Chars.length; i++){
    reverseBase64Chars[base64Chars[i]] = i;
}

var base64Str;
var base64Count;
function setBase64Str(str){
    base64Str = str;
    base64Count = 0;
}
function readBase64(){
    if (!base64Str) return END_OF_INPUT;
    if (base64Count >= base64Str.length) return END_OF_INPUT;
    var c = base64Str.charCodeAt(base64Count) & 0xff;
    base64Count++;
    return c;
}
function encodeBase64(str){
    setBase64Str(str);
    var result = '';
    var inBuffer = new Array(3);
    var lineCount = 0;
    var done = false;
    while (!done && (inBuffer[0] = readBase64()) != END_OF_INPUT){
        inBuffer[1] = readBase64();
        inBuffer[2] = readBase64();
        result += (base64Chars[ inBuffer[0] >> 2 ]);
        if (inBuffer[1] != END_OF_INPUT){
            result += (base64Chars [(( inBuffer[0] << 4 ) & 0x30) | (inBuffer[1] >> 4) ]);
            if (inBuffer[2] != END_OF_INPUT){
                result += (base64Chars [((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6) ]);
                result += (base64Chars [inBuffer[2] & 0x3F]);
            } else {
                result += (base64Chars [((inBuffer[1] << 2) & 0x3c)]);
                result += ('=');
                done = true;
            }
        } else {
            result += (base64Chars [(( inBuffer[0] << 4 ) & 0x30)]);
            result += ('=');
            result += ('=');
            done = true;
        }
        lineCount += 4;
        if (lineCount >= 76){
            result += ('\n');
            lineCount = 0;
        }
    }
    return result;
}
function readReverseBase64(){
    if (!base64Str) return END_OF_INPUT;
    while (true){
        if (base64Count >= base64Str.length) return END_OF_INPUT;
        var nextCharacter = base64Str.charAt(base64Count);
        base64Count++;
        if (reverseBase64Chars[nextCharacter]){
            return reverseBase64Chars[nextCharacter];
        }
        if (nextCharacter == 'A') return 0;
    }
    return END_OF_INPUT;
}

function ntos(n){
    n=n.toString(16);
    if (n.length == 1) n="0"+n;
    n="%"+n;
    return unescape(n);
}

function decodeBase64(str){
    setBase64Str(str);
    var result = "";
    var inBuffer = new Array(4);
    var done = false;
    while (!done && (inBuffer[0] = readReverseBase64()) != END_OF_INPUT
        && (inBuffer[1] = readReverseBase64()) != END_OF_INPUT){
        inBuffer[2] = readReverseBase64();
        inBuffer[3] = readReverseBase64();
        result += ntos((((inBuffer[0] << 2) & 0xff)| inBuffer[1] >> 4));
        if (inBuffer[2] != END_OF_INPUT){
            result +=  ntos((((inBuffer[1] << 4) & 0xff)| inBuffer[2] >> 2));
            if (inBuffer[3] != END_OF_INPUT){
                result +=  ntos((((inBuffer[2] << 6)  & 0xff) | inBuffer[3]));
            } else {
                done = true;
            }
        } else {
            done = true;
        }
    }
    return result;
}

//*********************************//
// end BASE 64
//*********************************//


/**
 *  UTF8 ENCODE E DECODE
 ***/
function utf8_decode(str_data) {
    // http://kevin.vanzonneveld.net
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +      input by: Aman Gupta
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: utf8_decode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'

    var tmp_arr = [], i = ac = c = c1 = c2 = 0;

    while (i < str_data.length) {
        c = str_data.charCodeAt(i);
        if (c < 128) {
            tmp_arr[ac++] = String.fromCharCode(c);
            i++;
        }
        else
        if ((c > 191) && (c < 224)) {
            c2 = str_data.charCodeAt(i + 1);
            tmp_arr[ac++] = String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        }
        else {
            c2 = str_data.charCodeAt(i + 1);
            c3 = str_data.charCodeAt(i + 2);
            tmp_arr[ac++] = String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }

    return tmp_arr.join('');
}

function utf8_encode ( string ) {
    // Encodes an ISO-8859-1 string to UTF-8
    //
    // version: 1004.2314
    // discuss at: http://phpjs.org/functions/utf8_encode    // +   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    // +   improved by: Yves Sucaet
    // +   bugfixed by: Onno Marsman
    // +   bugfixed by: Ulrich
    // *     example 1: utf8_encode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'    var string = (argString+''); // .replace(/\r\n/g, "\n").replace(/\r/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;
}
//****************//
// End UTF-8
//***************//


//***//
// BEGIN HEXADECIMAL
//***//

var digitArray = new Array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
function toHex(n){
    var result = ''
    var start = true;
    for (var i=32; i>0;){
        i-=4;
        var digit = (n>>i) & 0xf;
        if (!start || digit != 0){
            start = false;
            result += digitArray[digit];
        }
    }
    return (result==''?'0':result);
}

function pad(str, len, pad){
    var result = str;
    for (var i=str.length; i<len; i++){
        result = pad + result;
    }
    return result;
}

function encodeHex(str){
    var result = "";
    for (var i=0; i<str.length; i++){
        result += pad(toHex(str.charCodeAt(i)&0xff),2,'0');
    }
    return result;
}

var hexv = {
    "00":0,
    "01":1,
    "02":2,
    "03":3,
    "04":4,
    "05":5,
    "06":6,
    "07":7,
    "08":8,
    "09":9,
    "0A":10,
    "0B":11,
    "0C":12,
    "0D":13,
    "0E":14,
    "0F":15,
    "10":16,
    "11":17,
    "12":18,
    "13":19,
    "14":20,
    "15":21,
    "16":22,
    "17":23,
    "18":24,
    "19":25,
    "1A":26,
    "1B":27,
    "1C":28,
    "1D":29,
    "1E":30,
    "1F":31,
    "20":32,
    "21":33,
    "22":34,
    "23":35,
    "24":36,
    "25":37,
    "26":38,
    "27":39,
    "28":40,
    "29":41,
    "2A":42,
    "2B":43,
    "2C":44,
    "2D":45,
    "2E":46,
    "2F":47,
    "30":48,
    "31":49,
    "32":50,
    "33":51,
    "34":52,
    "35":53,
    "36":54,
    "37":55,
    "38":56,
    "39":57,
    "3A":58,
    "3B":59,
    "3C":60,
    "3D":61,
    "3E":62,
    "3F":63,
    "40":64,
    "41":65,
    "42":66,
    "43":67,
    "44":68,
    "45":69,
    "46":70,
    "47":71,
    "48":72,
    "49":73,
    "4A":74,
    "4B":75,
    "4C":76,
    "4D":77,
    "4E":78,
    "4F":79,
    "50":80,
    "51":81,
    "52":82,
    "53":83,
    "54":84,
    "55":85,
    "56":86,
    "57":87,
    "58":88,
    "59":89,
    "5A":90,
    "5B":91,
    "5C":92,
    "5D":93,
    "5E":94,
    "5F":95,
    "60":96,
    "61":97,
    "62":98,
    "63":99,
    "64":100,
    "65":101,
    "66":102,
    "67":103,
    "68":104,
    "69":105,
    "6A":106,
    "6B":107,
    "6C":108,
    "6D":109,
    "6E":110,
    "6F":111,
    "70":112,
    "71":113,
    "72":114,
    "73":115,
    "74":116,
    "75":117,
    "76":118,
    "77":119,
    "78":120,
    "79":121,
    "7A":122,
    "7B":123,
    "7C":124,
    "7D":125,
    "7E":126,
    "7F":127,
    "80":128,
    "81":129,
    "82":130,
    "83":131,
    "84":132,
    "85":133,
    "86":134,
    "87":135,
    "88":136,
    "89":137,
    "8A":138,
    "8B":139,
    "8C":140,
    "8D":141,
    "8E":142,
    "8F":143,
    "90":144,
    "91":145,
    "92":146,
    "93":147,
    "94":148,
    "95":149,
    "96":150,
    "97":151,
    "98":152,
    "99":153,
    "9A":154,
    "9B":155,
    "9C":156,
    "9D":157,
    "9E":158,
    "9F":159,
    "A0":160,
    "A1":161,
    "A2":162,
    "A3":163,
    "A4":164,
    "A5":165,
    "A6":166,
    "A7":167,
    "A8":168,
    "A9":169,
    "AA":170,
    "AB":171,
    "AC":172,
    "AD":173,
    "AE":174,
    "AF":175,
    "B0":176,
    "B1":177,
    "B2":178,
    "B3":179,
    "B4":180,
    "B5":181,
    "B6":182,
    "B7":183,
    "B8":184,
    "B9":185,
    "BA":186,
    "BB":187,
    "BC":188,
    "BD":189,
    "BE":190,
    "BF":191,
    "C0":192,
    "C1":193,
    "C2":194,
    "C3":195,
    "C4":196,
    "C5":197,
    "C6":198,
    "C7":199,
    "C8":200,
    "C9":201,
    "CA":202,
    "CB":203,
    "CC":204,
    "CD":205,
    "CE":206,
    "CF":207,
    "D0":208,
    "D1":209,
    "D2":210,
    "D3":211,
    "D4":212,
    "D5":213,
    "D6":214,
    "D7":215,
    "D8":216,
    "D9":217,
    "DA":218,
    "DB":219,
    "DC":220,
    "DD":221,
    "DE":222,
    "DF":223,
    "E0":224,
    "E1":225,
    "E2":226,
    "E3":227,
    "E4":228,
    "E5":229,
    "E6":230,
    "E7":231,
    "E8":232,
    "E9":233,
    "EA":234,
    "EB":235,
    "EC":236,
    "ED":237,
    "EE":238,
    "EF":239,
    "F0":240,
    "F1":241,
    "F2":242,
    "F3":243,
    "F4":244,
    "F5":245,
    "F6":246,
    "F7":247,
    "F8":248,
    "F9":249,
    "FA":250,
    "FB":251,
    "FC":252,
    "FD":253,
    "FE":254,
    "FF":255
};

function decodeHex(str){
    str = str.toUpperCase().replace(new RegExp("s/[^0-9A-Z]//g"));
    var result = "";
    var nextchar = "";
    for (var i=0; i<str.length; i++){
        nextchar += str.charAt(i);
        if (nextchar.length == 2){
            result += ntos(hexv[nextchar]);
            nextchar = "";
        }
    }
    return result;

}


//***//
// END HEXADECIMAL
//***//
