code: function (input) {
           var result = [], resIndex = 0;
           var type = JSZip.utils.getTypeOf(input);
           var isArray = type !== "string";
           var i = 0;
           var c = 0, c1 = 0, c2 = 0, c3 = 0;
  
           // check if we can use the TextDecoder API
           // see http://encoding.spec.whatwg.org/#api
           if (JSZip.support.uint8array && typeof TextDecoder === "function") {
              return TextDecoder("utf-8").decode(
                 JSZip.utils.transformTo("uint8array", input)
              );
           }
           if (JSZip.support.nodebuffer) {
              return JSZip.utils.transformTo("nodebuffer", input).toString("utf-8");
           }
  
           while ( i < input.length ) {
  
              c = isArray ? input[i] : input.charCodeAt(i);
  
              if (c < 128) {
                 result[resIndex++] = String.fromCharCode(c);
                 i++;
              } else if ((c > 191) && (c < 224)) {
                 c2 = isArray ? input[i+1] : input.charCodeAt(i+1);
                 result[resIndex++] = String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                 i += 2;
              } else {
                 c2 = isArray ? input[i+1] : input.charCodeAt(i+1);
                 c3 = isArray ? input[i+2] : input.charCodeAt(i+2);
                 result[resIndex++] = String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                 i += 3;
              }
  
           }
  
           return result.join("");
        }
docs: http://www.webtoolkit.info/javascript-utf8.html