docs: function Base64lib(){
  
  var b64chars
      = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  
  var b64charcodes = function(){
      var a = [];
      var codeA = 'A'.charCodeAt(0);
      var codea = 'a'.charCodeAt(0);
      var code0 = '0'.charCodeAt(0);
      for (var i = 0; i < 26; i ++) a.push(codeA + i);
      for (var i = 0; i < 26; i ++) a.push(codea + i);
      for (var i = 0; i < 10; i ++) a.push(code0 + i);
      a.push('+'.charCodeAt(0));
      a.push('/'.charCodeAt(0));
      return a;
  }();
  
  var b64tab = function(bin){
      var t = {};
      for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
      return t;
  }(b64chars);
  
  var stringToArray = function(s){
      var a = [];
      for (var i = 0, l = s.length; i < l; i ++) a[i] = s.charCodeAt(i);
      return a;
  };
  
  this.convertUTF8ArrayToBase64 = function(bin){
      var padlen = 0;
      while (bin.length % 3){
          bin.push(0);
          padlen++;
      };
      var b64 = [];
      for (var i = 0, l = bin.length; i < l; i += 3){
          var c0 = bin[i], c1 = bin[i+1], c2 = bin[i+2];
          if (c0 >= 256 || c1 >= 256 || c2 >= 256)
              throw 'unsupported character found';
          var n = (c0 << 16) | (c1 << 8) | c2;
          b64.push(
              b64charcodes[ n >>> 18],
              b64charcodes[(n >>> 12) & 63],
              b64charcodes[(n >>>  6) & 63],
              b64charcodes[ n         & 63]
          );
      }
      while (padlen--) b64[b64.length - padlen - 1] = '='.charCodeAt(0);
      return String.fromCharCode.apply(String, b64);
  };
  
  var convertBase64ToUTF8Array = function(b64){
      b64 = b64.replace(/[^A-Za-z0-9+\/]+/g, '');
      var bin = [];
      var padlen = b64.length % 4;
      for (var i = 0, l = b64.length; i < l; i += 4){
          var n = ((b64tab[b64.charAt(i  )] || 0) << 18)
              |   ((b64tab[b64.charAt(i+1)] || 0) << 12)
              |   ((b64tab[b64.charAt(i+2)] || 0) <<  6)
              |   ((b64tab[b64.charAt(i+3)] || 0));
          bin.push(
              (  n >> 16 ),
              ( (n >>  8) & 0xff ),
              (  n        & 0xff )
          );
      }
      bin.length -= [0,0,2,1][padlen];
      return bin;
  };
  
  var convertUTF16ArrayToUTF8Array = function(uni){
      var bin = [];
      for (var i = 0, l = uni.length; i < l; i++){
          var n = uni[i];
          if (n < 0x80)
              bin.push(n);
          else if (n < 0x800)
              bin.push(
                  0xc0 | (n >>>  6),
                  0x80 | (n & 0x3f));
          else
              bin.push(
                  0xe0 | ((n >>> 12) & 0x0f),
                  0x80 | ((n >>>  6) & 0x3f),
                  0x80 |  (n         & 0x3f));
      }
      return bin;
  };
  
  var convertUTF8ArrayToUTF16Array = function(bin){
      var uni = [];
      for (var i = 0, l = bin.length; i < l; i++){
          var c0 = bin[i];
          if    (c0 < 0x80){
              uni.push(c0);
          }else{
              var c1 = bin[++i];
              if (c0 < 0xe0){
                  uni.push(((c0 & 0x1f) << 6) | (c1 & 0x3f));
              }else{
                  var c2 = bin[++i];
                  uni.push(
                         ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f)
                  );
              }
          }
      }
      return uni;
  };
  
  var convertUTF8StringToBase64 = function(bin){
      return convertUTF8ArrayToBase64(stringToArray(bin));
  };
  
  this.convertBase64ToUTF8String = function(b64){
      return String.fromCharCode.apply(String, convertBase64ToUTF8Array(b64));
  };
  
  var convertUTF8StringToUTF16Array = function(bin){
      return convertUTF8ArrayToUTF16Array(stringToArray(bin));
  };
  
  var convertUTF8ArrayToUTF16String = function(bin){
      return String.fromCharCode.apply(String, convertUTF8ArrayToUTF16Array(bin));
  };
  
  var convertUTF8StringToUTF16String = function(bin){
      return String.fromCharCode.apply(String, convertUTF8ArrayToUTF16Array(stringToArray(bin)));
  };
  
  var convertUTF16StringToUTF8Array = function(uni){
      return convertUTF16ArrayToUTF8Array(stringToArray(uni));
  };
  
  var convertUTF16ArrayToUTF8String = function(uni){
      return String.fromCharCode.apply(String, convertUTF16ArrayToUTF8Array(uni));
  };
  
  var convertUTF16StringToUTF8String = function(uni){
      return String.fromCharCode.apply(String, convertUTF16ArrayToUTF8Array(stringToArray(uni)));
  };
  
  }