browser-image-compression
Version:
Compress images in the browser
1 lines • 365 kB
Source Map (JSON)
{"version":3,"file":"browser-image-compression.mjs","sources":["../lib/copyExifWithoutOrientation.js","../node_modules/uzip/UZIP.js","../lib/UPNG.js","../lib/canvastobmp.js","../lib/config/browser-name.js","../lib/config/max-canvas-size.js","../lib/utils.js","../lib/image-compression.js","../lib/web-worker.js","../lib/index.js"],"sourcesContent":["// https://gist.github.com/tonytonyjan/ffb7cd0e82cb293b843ece7e79364233\n// Copyright (c) 2022 Weihang Jian <tonytonyjan@gmail.com>\n\nexport default async function copyExifWithoutOrientation(srcBlob, destBlob) {\n const exif = await getApp1Segment(srcBlob);\n return new Blob([destBlob.slice(0, 2), exif, destBlob.slice(2)], {\n type: 'image/jpeg',\n });\n}\n\nconst SOI = 0xffd8;\nconst SOS = 0xffda;\nconst APP1 = 0xffe1;\nconst EXIF = 0x45786966;\nconst LITTLE_ENDIAN = 0x4949;\nconst BIG_ENDIAN = 0x4d4d;\nconst TAG_ID_ORIENTATION = 0x0112;\nconst TAG_TYPE_SHORT = 3;\nconst getApp1Segment = (blob) => new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.addEventListener('load', ({ target: { result: buffer } }) => {\n const view = new DataView(buffer);\n let offset = 0;\n if (view.getUint16(offset) !== SOI) return reject('not a valid JPEG');\n offset += 2;\n\n while (true) {\n const marker = view.getUint16(offset);\n if (marker === SOS) break;\n\n const size = view.getUint16(offset + 2);\n if (marker === APP1 && view.getUint32(offset + 4) === EXIF) {\n const tiffOffset = offset + 10;\n let littleEndian;\n switch (view.getUint16(tiffOffset)) {\n case LITTLE_ENDIAN:\n littleEndian = true;\n break;\n case BIG_ENDIAN:\n littleEndian = false;\n break;\n default:\n return reject('TIFF header contains invalid endian');\n }\n if (view.getUint16(tiffOffset + 2, littleEndian) !== 0x2a) { return reject('TIFF header contains invalid version'); }\n\n const ifd0Offset = view.getUint32(tiffOffset + 4, littleEndian);\n const endOfTagsOffset = tiffOffset\n + ifd0Offset\n + 2\n + view.getUint16(tiffOffset + ifd0Offset, littleEndian) * 12;\n for (\n let i = tiffOffset + ifd0Offset + 2;\n i < endOfTagsOffset;\n i += 12\n ) {\n const tagId = view.getUint16(i, littleEndian);\n if (tagId == TAG_ID_ORIENTATION) {\n if (view.getUint16(i + 2, littleEndian) !== TAG_TYPE_SHORT) { return reject('Orientation data type is invalid'); }\n\n if (view.getUint32(i + 4, littleEndian) !== 1) { return reject('Orientation data count is invalid'); }\n\n view.setUint16(i + 8, 1, littleEndian);\n break;\n }\n }\n return resolve(buffer.slice(offset, offset + 2 + size));\n }\n offset += 2 + size;\n }\n return resolve(new Blob());\n });\n reader.readAsArrayBuffer(blob);\n});\n","\r\n\r\nvar UZIP = {};\r\nif(typeof module == \"object\") module.exports = UZIP;\r\n\r\n\r\nUZIP[\"parse\"] = function(buf, onlyNames)\t// ArrayBuffer\r\n{\r\n\tvar rUs = UZIP.bin.readUshort, rUi = UZIP.bin.readUint, o = 0, out = {};\r\n\tvar data = new Uint8Array(buf);\r\n\tvar eocd = data.length-4;\r\n\t\r\n\twhile(rUi(data, eocd)!=0x06054b50) eocd--;\r\n\t\r\n\tvar o = eocd;\r\n\to+=4;\t// sign = 0x06054b50\r\n\to+=4; // disks = 0;\r\n\tvar cnu = rUs(data, o); o+=2;\r\n\tvar cnt = rUs(data, o); o+=2;\r\n\t\t\t\r\n\tvar csize = rUi(data, o); o+=4;\r\n\tvar coffs = rUi(data, o); o+=4;\r\n\t\r\n\to = coffs;\r\n\tfor(var i=0; i<cnu; i++)\r\n\t{\r\n\t\tvar sign = rUi(data, o); o+=4;\r\n\t\to += 4; // versions;\r\n\t\to += 4; // flag + compr\r\n\t\to += 4; // time\r\n\t\t\r\n\t\tvar crc32 = rUi(data, o); o+=4;\r\n\t\tvar csize = rUi(data, o); o+=4;\r\n\t\tvar usize = rUi(data, o); o+=4;\r\n\t\t\r\n\t\tvar nl = rUs(data, o), el = rUs(data, o+2), cl = rUs(data, o+4); o += 6; // name, extra, comment\r\n\t\to += 8; // disk, attribs\r\n\t\t\r\n\t\tvar roff = rUi(data, o); o+=4;\r\n\t\to += nl + el + cl;\r\n\t\t\r\n\t\tUZIP._readLocal(data, roff, out, csize, usize, onlyNames);\r\n\t}\r\n\t//console.log(out);\r\n\treturn out;\r\n}\r\n\r\nUZIP._readLocal = function(data, o, out, csize, usize, onlyNames)\r\n{\r\n\tvar rUs = UZIP.bin.readUshort, rUi = UZIP.bin.readUint;\r\n\tvar sign = rUi(data, o); o+=4;\r\n\tvar ver = rUs(data, o); o+=2;\r\n\tvar gpflg = rUs(data, o); o+=2;\r\n\t//if((gpflg&8)!=0) throw \"unknown sizes\";\r\n\tvar cmpr = rUs(data, o); o+=2;\r\n\t\r\n\tvar time = rUi(data, o); o+=4;\r\n\t\r\n\tvar crc32 = rUi(data, o); o+=4;\r\n\t//var csize = rUi(data, o); o+=4;\r\n\t//var usize = rUi(data, o); o+=4;\r\n\to+=8;\r\n\t\t\r\n\tvar nlen = rUs(data, o); o+=2;\r\n\tvar elen = rUs(data, o); o+=2;\r\n\t\t\r\n\tvar name = UZIP.bin.readUTF8(data, o, nlen); o+=nlen; //console.log(name);\r\n\to += elen;\r\n\t\t\t\r\n\t//console.log(sign.toString(16), ver, gpflg, cmpr, crc32.toString(16), \"csize, usize\", csize, usize, nlen, elen, name, o);\r\n\tif(onlyNames) { out[name]={size:usize, csize:csize}; return; } \r\n\tvar file = new Uint8Array(data.buffer, o);\r\n\tif(false) {}\r\n\telse if(cmpr==0) out[name] = new Uint8Array(file.buffer.slice(o, o+csize));\r\n\telse if(cmpr==8) {\r\n\t\tvar buf = new Uint8Array(usize); UZIP.inflateRaw(file, buf);\r\n\t\t/*var nbuf = pako[\"inflateRaw\"](file);\r\n\t\tif(usize>8514000) {\r\n\t\t\t//console.log(PUtils.readASCII(buf , 8514500, 500));\r\n\t\t\t//console.log(PUtils.readASCII(nbuf, 8514500, 500));\r\n\t\t}\r\n\t\tfor(var i=0; i<buf.length; i++) if(buf[i]!=nbuf[i]) { console.log(buf.length, nbuf.length, usize, i); throw \"e\"; }\r\n\t\t*/\r\n\t\tout[name] = buf;\r\n\t}\r\n\telse throw \"unknown compression method: \"+cmpr;\r\n}\r\n\r\nUZIP.inflateRaw = function(file, buf) { return UZIP.F.inflate(file, buf); }\r\nUZIP.inflate = function(file, buf) { \r\n\tvar CMF = file[0], FLG = file[1];\r\n\tvar CM = (CMF&15), CINFO = (CMF>>>4);\r\n\t//console.log(CM, CINFO,CMF,FLG);\r\n\treturn UZIP.inflateRaw(new Uint8Array(file.buffer, file.byteOffset+2, file.length-6), buf); \r\n}\r\nUZIP.deflate = function(data, opts/*, buf, off*/) {\r\n\tif(opts==null) opts={level:6};\r\n\tvar off=0, buf=new Uint8Array(50+Math.floor(data.length*1.1));\r\n\tbuf[off]=120; buf[off+1]=156; off+=2;\r\n\toff = UZIP.F.deflateRaw(data, buf, off, opts.level);\r\n\tvar crc = UZIP.adler(data, 0, data.length);\r\n\tbuf[off+0]=((crc>>>24)&255); \r\n\tbuf[off+1]=((crc>>>16)&255); \r\n\tbuf[off+2]=((crc>>> 8)&255); \r\n\tbuf[off+3]=((crc>>> 0)&255); \t\r\n\treturn new Uint8Array(buf.buffer, 0, off+4);\r\n}\r\nUZIP.deflateRaw = function(data, opts) {\r\n\tif(opts==null) opts={level:6};\r\n\tvar buf=new Uint8Array(50+Math.floor(data.length*1.1));\r\n\tvar off = UZIP.F.deflateRaw(data, buf, off, opts.level);\r\n\treturn new Uint8Array(buf.buffer, 0, off);\r\n}\r\n\r\n\r\nUZIP.encode = function(obj, noCmpr) {\r\n\tif(noCmpr==null) noCmpr=false;\r\n\tvar tot = 0, wUi = UZIP.bin.writeUint, wUs = UZIP.bin.writeUshort;\r\n\tvar zpd = {};\r\n\tfor(var p in obj) { var cpr = !UZIP._noNeed(p) && !noCmpr, buf = obj[p], crc = UZIP.crc.crc(buf,0,buf.length); \r\n\t\tzpd[p] = { cpr:cpr, usize:buf.length, crc:crc, file: (cpr ? UZIP.deflateRaw(buf) : buf) }; }\r\n\t\r\n\tfor(var p in zpd) tot += zpd[p].file.length + 30 + 46 + 2*UZIP.bin.sizeUTF8(p);\r\n\ttot += 22;\r\n\t\r\n\tvar data = new Uint8Array(tot), o = 0;\r\n\tvar fof = []\r\n\t\r\n\tfor(var p in zpd) {\r\n\t\tvar file = zpd[p]; fof.push(o);\r\n\t\to = UZIP._writeHeader(data, o, p, file, 0);\r\n\t}\r\n\tvar i=0, ioff = o;\r\n\tfor(var p in zpd) {\r\n\t\tvar file = zpd[p]; fof.push(o);\r\n\t\to = UZIP._writeHeader(data, o, p, file, 1, fof[i++]);\t\t\r\n\t}\r\n\tvar csize = o-ioff;\r\n\t\r\n\twUi(data, o, 0x06054b50); o+=4;\r\n\to += 4; // disks\r\n\twUs(data, o, i); o += 2;\r\n\twUs(data, o, i); o += 2;\t// number of c d records\r\n\twUi(data, o, csize); o += 4;\r\n\twUi(data, o, ioff ); o += 4;\r\n\to += 2;\r\n\treturn data.buffer;\r\n}\r\n// no need to compress .PNG, .ZIP, .JPEG ....\r\nUZIP._noNeed = function(fn) { var ext = fn.split(\".\").pop().toLowerCase(); return \"png,jpg,jpeg,zip\".indexOf(ext)!=-1; }\r\n\r\nUZIP._writeHeader = function(data, o, p, obj, t, roff)\r\n{\r\n\tvar wUi = UZIP.bin.writeUint, wUs = UZIP.bin.writeUshort;\r\n\tvar file = obj.file;\r\n\t\r\n\twUi(data, o, t==0 ? 0x04034b50 : 0x02014b50); o+=4; // sign\r\n\tif(t==1) o+=2; // ver made by\r\n\twUs(data, o, 20); o+=2;\t// ver\r\n\twUs(data, o, 0); o+=2; // gflip\r\n\twUs(data, o, obj.cpr?8:0); o+=2;\t// cmpr\r\n\t\t\r\n\twUi(data, o, 0); o+=4;\t// time\t\t\r\n\twUi(data, o, obj.crc); o+=4;\t// crc32\r\n\twUi(data, o, file.length); o+=4;\t// csize\r\n\twUi(data, o, obj.usize); o+=4;\t// usize\r\n\t\t\r\n\twUs(data, o, UZIP.bin.sizeUTF8(p)); o+=2;\t// nlen\r\n\twUs(data, o, 0); o+=2;\t// elen\r\n\t\r\n\tif(t==1) {\r\n\t\to += 2; // comment length\r\n\t\to += 2; // disk number\r\n\t\to += 6; // attributes\r\n\t\twUi(data, o, roff); o+=4;\t// usize\r\n\t}\r\n\tvar nlen = UZIP.bin.writeUTF8(data, o, p); o+= nlen;\t\r\n\tif(t==0) { data.set(file, o); o += file.length; }\r\n\treturn o;\r\n}\r\n\r\n\r\n\r\n\r\n\r\nUZIP.crc = {\r\n\ttable : ( function() {\r\n\t var tab = new Uint32Array(256);\r\n\t for (var n=0; n<256; n++) {\r\n\t\t\tvar c = n;\r\n\t\t\tfor (var k=0; k<8; k++) {\r\n\t\t\t\tif (c & 1) c = 0xedb88320 ^ (c >>> 1);\r\n\t\t\t\telse c = c >>> 1;\r\n\t\t\t}\r\n\t\t\ttab[n] = c; } \r\n\t\treturn tab; })(),\r\n\tupdate : function(c, buf, off, len) {\r\n\t\tfor (var i=0; i<len; i++) c = UZIP.crc.table[(c ^ buf[off+i]) & 0xff] ^ (c >>> 8);\r\n\t\treturn c;\r\n\t},\r\n\tcrc : function(b,o,l) { return UZIP.crc.update(0xffffffff,b,o,l) ^ 0xffffffff; }\r\n}\r\nUZIP.adler = function(data,o,len) {\r\n\tvar a = 1, b = 0;\r\n\tvar off = o, end=o+len;\r\n\twhile(off<end) {\r\n\t\tvar eend = Math.min(off+5552, end);\r\n\t\twhile(off<eend) {\r\n\t\t\ta += data[off++];\r\n\t\t\tb += a;\r\n\t\t}\r\n\t\ta=a%65521;\r\n\t\tb=b%65521;\r\n\t}\r\n return (b << 16) | a;\r\n}\r\n\r\nUZIP.bin = {\r\n\treadUshort : function(buff,p) { return (buff[p]) | (buff[p+1]<<8); },\r\n\twriteUshort: function(buff,p,n){ buff[p] = (n)&255; buff[p+1] = (n>>8)&255; },\r\n\treadUint : function(buff,p) { return (buff[p+3]*(256*256*256)) + ((buff[p+2]<<16) | (buff[p+1]<< 8) | buff[p]); },\r\n\twriteUint : function(buff,p,n){ buff[p]=n&255; buff[p+1]=(n>>8)&255; buff[p+2]=(n>>16)&255; buff[p+3]=(n>>24)&255; },\r\n\treadASCII : function(buff,p,l){ var s = \"\"; for(var i=0; i<l; i++) s += String.fromCharCode(buff[p+i]); return s; },\r\n\twriteASCII : function(data,p,s){ for(var i=0; i<s.length; i++) data[p+i] = s.charCodeAt(i); },\r\n\tpad : function(n) { return n.length < 2 ? \"0\" + n : n; },\r\n\treadUTF8 : function(buff, p, l) {\r\n\t\tvar s = \"\", ns;\r\n\t\tfor(var i=0; i<l; i++) s += \"%\" + UZIP.bin.pad(buff[p+i].toString(16));\r\n\t\ttry { ns = decodeURIComponent(s); }\r\n\t\tcatch(e) { return UZIP.bin.readASCII(buff, p, l); }\r\n\t\treturn ns;\r\n\t},\r\n\twriteUTF8 : function(buff, p, str) {\r\n\t\tvar strl = str.length, i=0;\r\n\t\tfor(var ci=0; ci<strl; ci++)\r\n\t\t{\r\n\t\t\tvar code = str.charCodeAt(ci);\r\n\t\t\tif ((code&(0xffffffff-(1<< 7)+1))==0) { buff[p+i] = ( code ); i++; }\r\n\t\t\telse if((code&(0xffffffff-(1<<11)+1))==0) { buff[p+i] = (192|(code>> 6)); buff[p+i+1] = (128|((code>> 0)&63)); i+=2; }\r\n\t\t\telse if((code&(0xffffffff-(1<<16)+1))==0) { buff[p+i] = (224|(code>>12)); buff[p+i+1] = (128|((code>> 6)&63)); buff[p+i+2] = (128|((code>>0)&63)); i+=3; }\r\n\t\t\telse if((code&(0xffffffff-(1<<21)+1))==0) { buff[p+i] = (240|(code>>18)); buff[p+i+1] = (128|((code>>12)&63)); buff[p+i+2] = (128|((code>>6)&63)); buff[p+i+3] = (128|((code>>0)&63)); i+=4; }\r\n\t\t\telse throw \"e\";\r\n\t\t}\r\n\t\treturn i;\r\n\t},\r\n\tsizeUTF8 : function(str) {\r\n\t\tvar strl = str.length, i=0;\r\n\t\tfor(var ci=0; ci<strl; ci++)\r\n\t\t{\r\n\t\t\tvar code = str.charCodeAt(ci);\r\n\t\t\tif ((code&(0xffffffff-(1<< 7)+1))==0) { i++ ; }\r\n\t\t\telse if((code&(0xffffffff-(1<<11)+1))==0) { i+=2; }\r\n\t\t\telse if((code&(0xffffffff-(1<<16)+1))==0) { i+=3; }\r\n\t\t\telse if((code&(0xffffffff-(1<<21)+1))==0) { i+=4; }\r\n\t\t\telse throw \"e\";\r\n\t\t}\r\n\t\treturn i;\r\n\t}\r\n}\r\n\r\n\r\n\r\n\r\n\r\nUZIP.F = {};\r\n\r\nUZIP.F.deflateRaw = function(data, out, opos, lvl) {\t\r\n\tvar opts = [\r\n\t/*\r\n\t\t ush good_length; /* reduce lazy search above this match length \r\n\t\t ush max_lazy; /* do not perform lazy search above this match length \r\n ush nice_length; /* quit search above this match length \r\n\t*/\r\n\t/* good lazy nice chain */\r\n\t/* 0 */ [ 0, 0, 0, 0,0], /* store only */\r\n\t/* 1 */ [ 4, 4, 8, 4,0], /* max speed, no lazy matches */\r\n\t/* 2 */ [ 4, 5, 16, 8,0],\r\n\t/* 3 */ [ 4, 6, 16, 16,0],\r\n\r\n\t/* 4 */ [ 4, 10, 16, 32,0], /* lazy matches */\r\n\t/* 5 */ [ 8, 16, 32, 32,0],\r\n\t/* 6 */ [ 8, 16, 128, 128,0],\r\n\t/* 7 */ [ 8, 32, 128, 256,0],\r\n\t/* 8 */ [32, 128, 258, 1024,1],\r\n\t/* 9 */ [32, 258, 258, 4096,1]]; /* max compression */\r\n\t\r\n\tvar opt = opts[lvl];\r\n\t\r\n\t\r\n\tvar U = UZIP.F.U, goodIndex = UZIP.F._goodIndex, hash = UZIP.F._hash, putsE = UZIP.F._putsE;\r\n\tvar i = 0, pos = opos<<3, cvrd = 0, dlen = data.length;\r\n\t\r\n\tif(lvl==0) {\r\n\t\twhile(i<dlen) { var len = Math.min(0xffff, dlen-i);\r\n\t\t\tputsE(out, pos, (i+len==dlen ? 1 : 0)); pos = UZIP.F._copyExact(data, i, len, out, pos+8); i += len; }\r\n\t\treturn pos>>>3;\r\n\t}\r\n\r\n\tvar lits = U.lits, strt=U.strt, prev=U.prev, li=0, lc=0, bs=0, ebits=0, c=0, nc=0; // last_item, literal_count, block_start\r\n\tif(dlen>2) { nc=UZIP.F._hash(data,0); strt[nc]=0; }\r\n\tvar nmch=0,nmci=0;\r\n\t\r\n\tfor(i=0; i<dlen; i++) {\r\n\t\tc = nc;\r\n\t\t//*\r\n\t\tif(i+1<dlen-2) {\r\n\t\t\tnc = UZIP.F._hash(data, i+1);\r\n\t\t\tvar ii = ((i+1)&0x7fff);\r\n\t\t\tprev[ii]=strt[nc];\r\n\t\t\tstrt[nc]=ii;\r\n\t\t} //*/\r\n\t\tif(cvrd<=i) {\r\n\t\t\tif((li>14000 || lc>26697) && (dlen-i)>100) {\r\n\t\t\t\tif(cvrd<i) { lits[li]=i-cvrd; li+=2; cvrd=i; }\r\n\t\t\t\tpos = UZIP.F._writeBlock(((i==dlen-1) || (cvrd==dlen))?1:0, lits, li, ebits, data,bs,i-bs, out, pos); li=lc=ebits=0; bs=i;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tvar mch = 0;\r\n\t\t\t//if(nmci==i) mch= nmch; else \r\n\t\t\tif(i<dlen-2) mch = UZIP.F._bestMatch(data, i, prev, c, Math.min(opt[2],dlen-i), opt[3]);\r\n\t\t\t/*\r\n\t\t\tif(mch!=0 && opt[4]==1 && (mch>>>16)<opt[1] && i+1<dlen-2) {\r\n\t\t\t\tnmch = UZIP.F._bestMatch(data, i+1, prev, nc, opt[2], opt[3]); nmci=i+1;\r\n\t\t\t\t//var mch2 = UZIP.F._bestMatch(data, i+2, prev, nnc); //nmci=i+1;\r\n\t\t\t\tif((nmch>>>16)>(mch>>>16)) mch=0;\r\n\t\t\t}//*/\r\n\t\t\tvar len = mch>>>16, dst = mch&0xffff; //if(i-dst<0) throw \"e\";\r\n\t\t\tif(mch!=0) { \r\n\t\t\t\tvar len = mch>>>16, dst = mch&0xffff; //if(i-dst<0) throw \"e\";\r\n\t\t\t\tvar lgi = goodIndex(len, U.of0); U.lhst[257+lgi]++; \r\n\t\t\t\tvar dgi = goodIndex(dst, U.df0); U.dhst[ dgi]++; ebits += U.exb[lgi] + U.dxb[dgi]; \r\n\t\t\t\tlits[li] = (len<<23)|(i-cvrd); lits[li+1] = (dst<<16)|(lgi<<8)|dgi; li+=2;\r\n\t\t\t\tcvrd = i + len; \r\n\t\t\t}\r\n\t\t\telse {\tU.lhst[data[i]]++; }\r\n\t\t\tlc++;\r\n\t\t}\r\n\t}\r\n\tif(bs!=i || data.length==0) {\r\n\t\tif(cvrd<i) { lits[li]=i-cvrd; li+=2; cvrd=i; }\r\n\t\tpos = UZIP.F._writeBlock(1, lits, li, ebits, data,bs,i-bs, out, pos); li=0; lc=0; li=lc=ebits=0; bs=i;\r\n\t}\r\n\twhile((pos&7)!=0) pos++;\r\n\treturn pos>>>3;\r\n}\r\nUZIP.F._bestMatch = function(data, i, prev, c, nice, chain) {\r\n\tvar ci = (i&0x7fff), pi=prev[ci]; \r\n\t//console.log(\"----\", i);\r\n\tvar dif = ((ci-pi + (1<<15)) & 0x7fff); if(pi==ci || c!=UZIP.F._hash(data,i-dif)) return 0;\r\n\tvar tl=0, td=0; // top length, top distance\r\n\tvar dlim = Math.min(0x7fff, i);\r\n\twhile(dif<=dlim && --chain!=0 && pi!=ci /*&& c==UZIP.F._hash(data,i-dif)*/) {\r\n\t\tif(tl==0 || (data[i+tl]==data[i+tl-dif])) {\r\n\t\t\tvar cl = UZIP.F._howLong(data, i, dif);\r\n\t\t\tif(cl>tl) { \r\n\t\t\t\ttl=cl; td=dif; if(tl>=nice) break; //* \r\n\t\t\t\tif(dif+2<cl) cl = dif+2;\r\n\t\t\t\tvar maxd = 0; // pi does not point to the start of the word\r\n\t\t\t\tfor(var j=0; j<cl-2; j++) {\r\n\t\t\t\t\tvar ei = (i-dif+j+ (1<<15)) & 0x7fff;\r\n\t\t\t\t\tvar li = prev[ei];\r\n\t\t\t\t\tvar curd = (ei-li + (1<<15)) & 0x7fff;\r\n\t\t\t\t\tif(curd>maxd) { maxd=curd; pi = ei; }\r\n\t\t\t\t} //*/\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tci=pi; pi = prev[ci];\r\n\t\tdif += ((ci-pi + (1<<15)) & 0x7fff);\r\n\t}\r\n\treturn (tl<<16)|td;\r\n}\r\nUZIP.F._howLong = function(data, i, dif) {\r\n\tif(data[i]!=data[i-dif] || data[i+1]!=data[i+1-dif] || data[i+2]!=data[i+2-dif]) return 0;\r\n\tvar oi=i, l = Math.min(data.length, i+258); i+=3;\r\n\t//while(i+4<l && data[i]==data[i-dif] && data[i+1]==data[i+1-dif] && data[i+2]==data[i+2-dif] && data[i+3]==data[i+3-dif]) i+=4;\r\n\twhile(i<l && data[i]==data[i-dif]) i++;\r\n\treturn i-oi;\r\n}\r\nUZIP.F._hash = function(data, i) {\r\n\treturn (((data[i]<<8) | data[i+1])+(data[i+2]<<4))&0xffff;\r\n\t//var hash_shift = 0, hash_mask = 255;\r\n\t//var h = data[i+1] % 251;\r\n\t//h = (((h << 8) + data[i+2]) % 251);\r\n\t//h = (((h << 8) + data[i+2]) % 251);\r\n\t//h = ((h<<hash_shift) ^ (c) ) & hash_mask;\r\n\t//return h | (data[i]<<8);\r\n\t//return (data[i] | (data[i+1]<<8));\r\n}\r\n//UZIP.___toth = 0;\r\nUZIP.saved = 0;\r\nUZIP.F._writeBlock = function(BFINAL, lits, li, ebits, data,o0,l0, out, pos) {\r\n\tvar U = UZIP.F.U, putsF = UZIP.F._putsF, putsE = UZIP.F._putsE;\r\n\t\r\n\t//*\r\n\tvar T, ML, MD, MH, numl, numd, numh, lset, dset; U.lhst[256]++;\r\n\tT = UZIP.F.getTrees(); ML=T[0]; MD=T[1]; MH=T[2]; numl=T[3]; numd=T[4]; numh=T[5]; lset=T[6]; dset=T[7];\r\n\t\r\n\tvar cstSize = (((pos+3)&7)==0 ? 0 : 8-((pos+3)&7)) + 32 + (l0<<3);\r\n\tvar fxdSize = ebits + UZIP.F.contSize(U.fltree, U.lhst) + UZIP.F.contSize(U.fdtree, U.dhst);\r\n\tvar dynSize = ebits + UZIP.F.contSize(U.ltree , U.lhst) + UZIP.F.contSize(U.dtree , U.dhst);\r\n\tdynSize += 14 + 3*numh + UZIP.F.contSize(U.itree, U.ihst) + (U.ihst[16]*2 + U.ihst[17]*3 + U.ihst[18]*7);\r\n\t\r\n\tfor(var j=0; j<286; j++) U.lhst[j]=0; for(var j=0; j<30; j++) U.dhst[j]=0; for(var j=0; j<19; j++) U.ihst[j]=0;\r\n\t//*/\r\n\tvar BTYPE = (cstSize<fxdSize && cstSize<dynSize) ? 0 : ( fxdSize<dynSize ? 1 : 2 );\r\n\tputsF(out, pos, BFINAL); putsF(out, pos+1, BTYPE); pos+=3;\r\n\t\r\n\tvar opos = pos;\r\n\tif(BTYPE==0) {\r\n\t\twhile((pos&7)!=0) pos++;\r\n\t\tpos = UZIP.F._copyExact(data, o0, l0, out, pos);\r\n\t}\r\n\telse {\r\n\t\tvar ltree, dtree;\r\n\t\tif(BTYPE==1) { ltree=U.fltree; dtree=U.fdtree; }\r\n\t\tif(BTYPE==2) {\t\r\n\t\t\tUZIP.F.makeCodes(U.ltree, ML); UZIP.F.revCodes(U.ltree, ML);\r\n\t\t\tUZIP.F.makeCodes(U.dtree, MD); UZIP.F.revCodes(U.dtree, MD);\r\n\t\t\tUZIP.F.makeCodes(U.itree, MH); UZIP.F.revCodes(U.itree, MH);\r\n\t\t\t\r\n\t\t\tltree = U.ltree; dtree = U.dtree;\r\n\t\t\t\r\n\t\t\tputsE(out, pos,numl-257); pos+=5; // 286\r\n\t\t\tputsE(out, pos,numd- 1); pos+=5; // 30\r\n\t\t\tputsE(out, pos,numh- 4); pos+=4; // 19\r\n\t\t\t\r\n\t\t\tfor(var i=0; i<numh; i++) putsE(out, pos+i*3, U.itree[(U.ordr[i]<<1)+1]); pos+=3* numh;\r\n\t\t\tpos = UZIP.F._codeTiny(lset, U.itree, out, pos);\r\n\t\t\tpos = UZIP.F._codeTiny(dset, U.itree, out, pos);\r\n\t\t}\r\n\t\t\r\n\t\tvar off=o0;\r\n\t\tfor(var si=0; si<li; si+=2) {\r\n\t\t\tvar qb=lits[si], len=(qb>>>23), end = off+(qb&((1<<23)-1));\r\n\t\t\twhile(off<end) pos = UZIP.F._writeLit(data[off++], ltree, out, pos);\r\n\t\t\t\r\n\t\t\tif(len!=0) {\r\n\t\t\t\tvar qc = lits[si+1], dst=(qc>>16), lgi=(qc>>8)&255, dgi=(qc&255);\r\n\t\t\t\tpos = UZIP.F._writeLit(257+lgi, ltree, out, pos);\r\n\t\t\t\tputsE(out, pos, len-U.of0[lgi]); pos+=U.exb[lgi];\r\n\t\t\t\t\r\n\t\t\t\tpos = UZIP.F._writeLit(dgi, dtree, out, pos);\r\n\t\t\t\tputsF(out, pos, dst-U.df0[dgi]); pos+=U.dxb[dgi]; off+=len;\r\n\t\t\t}\r\n\t\t}\r\n\t\tpos = UZIP.F._writeLit(256, ltree, out, pos);\r\n\t}\r\n\t//console.log(pos-opos, fxdSize, dynSize, cstSize);\r\n\treturn pos;\r\n}\r\nUZIP.F._copyExact = function(data,off,len,out,pos) {\r\n\tvar p8 = (pos>>>3);\r\n\tout[p8]=(len); out[p8+1]=(len>>>8); out[p8+2]=255-out[p8]; out[p8+3]=255-out[p8+1]; p8+=4;\r\n\tout.set(new Uint8Array(data.buffer, off, len), p8);\r\n\t//for(var i=0; i<len; i++) out[p8+i]=data[off+i];\r\n\treturn pos + ((len+4)<<3);\r\n}\r\n/*\r\n\tInteresting facts:\r\n\t- decompressed block can have bytes, which do not occur in a Huffman tree (copied from the previous block by reference)\r\n*/\r\n\r\nUZIP.F.getTrees = function() {\r\n\tvar U = UZIP.F.U;\r\n\tvar ML = UZIP.F._hufTree(U.lhst, U.ltree, 15);\r\n\tvar MD = UZIP.F._hufTree(U.dhst, U.dtree, 15);\r\n\tvar lset = [], numl = UZIP.F._lenCodes(U.ltree, lset);\r\n\tvar dset = [], numd = UZIP.F._lenCodes(U.dtree, dset);\r\n\tfor(var i=0; i<lset.length; i+=2) U.ihst[lset[i]]++;\r\n\tfor(var i=0; i<dset.length; i+=2) U.ihst[dset[i]]++;\r\n\tvar MH = UZIP.F._hufTree(U.ihst, U.itree, 7);\r\n\tvar numh = 19; while(numh>4 && U.itree[(U.ordr[numh-1]<<1)+1]==0) numh--;\r\n\treturn [ML, MD, MH, numl, numd, numh, lset, dset];\r\n}\r\nUZIP.F.getSecond= function(a) { var b=[]; for(var i=0; i<a.length; i+=2) b.push (a[i+1]); return b; }\r\nUZIP.F.nonZero = function(a) { var b= \"\"; for(var i=0; i<a.length; i+=2) if(a[i+1]!=0)b+=(i>>1)+\",\"; return b; }\r\nUZIP.F.contSize = function(tree, hst) { var s=0; for(var i=0; i<hst.length; i++) s+= hst[i]*tree[(i<<1)+1]; return s; }\r\nUZIP.F._codeTiny = function(set, tree, out, pos) {\r\n\tfor(var i=0; i<set.length; i+=2) {\r\n\t\tvar l = set[i], rst = set[i+1]; //console.log(l, pos, tree[(l<<1)+1]);\r\n\t\tpos = UZIP.F._writeLit(l, tree, out, pos);\r\n\t\tvar rsl = l==16 ? 2 : (l==17 ? 3 : 7);\r\n\t\tif(l>15) { UZIP.F._putsE(out, pos, rst, rsl); pos+=rsl; }\r\n\t}\r\n\treturn pos;\r\n}\r\nUZIP.F._lenCodes = function(tree, set) {\r\n\tvar len=tree.length; while(len!=2 && tree[len-1]==0) len-=2; // when no distances, keep one code with length 0\r\n\tfor(var i=0; i<len; i+=2) {\r\n\t\tvar l = tree[i+1], nxt = (i+3<len ? tree[i+3]:-1), nnxt = (i+5<len ? tree[i+5]:-1), prv = (i==0 ? -1 : tree[i-1]);\r\n\t\tif(l==0 && nxt==l && nnxt==l) {\r\n\t\t\tvar lz = i+5;\r\n\t\t\twhile(lz+2<len && tree[lz+2]==l) lz+=2;\r\n\t\t\tvar zc = Math.min((lz+1-i)>>>1, 138);\r\n\t\t\tif(zc<11) set.push(17, zc-3);\r\n\t\t\telse set.push(18, zc-11);\r\n\t\t\ti += zc*2-2;\r\n\t\t}\r\n\t\telse if(l==prv && nxt==l && nnxt==l) {\r\n\t\t\tvar lz = i+5;\r\n\t\t\twhile(lz+2<len && tree[lz+2]==l) lz+=2;\r\n\t\t\tvar zc = Math.min((lz+1-i)>>>1, 6);\r\n\t\t\tset.push(16, zc-3);\r\n\t\t\ti += zc*2-2;\r\n\t\t}\r\n\t\telse set.push(l, 0);\r\n\t}\r\n\treturn len>>>1;\r\n}\r\nUZIP.F._hufTree = function(hst, tree, MAXL) {\r\n\tvar list=[], hl = hst.length, tl=tree.length, i=0;\r\n\tfor(i=0; i<tl; i+=2) { tree[i]=0; tree[i+1]=0; }\t\r\n\tfor(i=0; i<hl; i++) if(hst[i]!=0) list.push({lit:i, f:hst[i]});\r\n\tvar end = list.length, l2=list.slice(0);\r\n\tif(end==0) return 0; // empty histogram (usually for dist)\r\n\tif(end==1) { var lit=list[0].lit, l2=lit==0?1:0; tree[(lit<<1)+1]=1; tree[(l2<<1)+1]=1; return 1; }\r\n\tlist.sort(function(a,b){return a.f-b.f;});\r\n\tvar a=list[0], b=list[1], i0=0, i1=1, i2=2; list[0]={lit:-1,f:a.f+b.f,l:a,r:b,d:0};\r\n\twhile(i1!=end-1) {\r\n\t\tif(i0!=i1 && (i2==end || list[i0].f<list[i2].f)) { a=list[i0++]; } else { a=list[i2++]; }\r\n\t\tif(i0!=i1 && (i2==end || list[i0].f<list[i2].f)) { b=list[i0++]; } else { b=list[i2++]; }\r\n\t\tlist[i1++]={lit:-1,f:a.f+b.f, l:a,r:b};\r\n\t}\r\n\tvar maxl = UZIP.F.setDepth(list[i1-1], 0);\r\n\tif(maxl>MAXL) { UZIP.F.restrictDepth(l2, MAXL, maxl); maxl = MAXL; }\r\n\tfor(i=0; i<end; i++) tree[(l2[i].lit<<1)+1]=l2[i].d;\r\n\treturn maxl;\r\n}\r\n\r\nUZIP.F.setDepth = function(t, d) {\r\n\tif(t.lit!=-1) { t.d=d; return d; }\r\n\treturn Math.max( UZIP.F.setDepth(t.l, d+1), UZIP.F.setDepth(t.r, d+1) );\r\n}\r\n\r\nUZIP.F.restrictDepth = function(dps, MD, maxl) {\r\n\tvar i=0, bCost=1<<(maxl-MD), dbt=0;\r\n\tdps.sort(function(a,b){return b.d==a.d ? a.f-b.f : b.d-a.d;});\r\n\t\r\n\tfor(i=0; i<dps.length; i++) if(dps[i].d>MD) { var od=dps[i].d; dps[i].d=MD; dbt+=bCost-(1<<(maxl-od)); } else break;\r\n\tdbt = dbt>>>(maxl-MD);\r\n\twhile(dbt>0) { var od=dps[i].d; if(od<MD) { dps[i].d++; dbt-=(1<<(MD-od-1)); } else i++; }\r\n\tfor(; i>=0; i--) if(dps[i].d==MD && dbt<0) { dps[i].d--; dbt++; } if(dbt!=0) console.log(\"debt left\");\r\n}\r\n\r\nUZIP.F._goodIndex = function(v, arr) {\r\n\tvar i=0; if(arr[i|16]<=v) i|=16; if(arr[i|8]<=v) i|=8; if(arr[i|4]<=v) i|=4; if(arr[i|2]<=v) i|=2; if(arr[i|1]<=v) i|=1; return i;\r\n}\r\nUZIP.F._writeLit = function(ch, ltree, out, pos) {\r\n\tUZIP.F._putsF(out, pos, ltree[ch<<1]);\r\n\treturn pos+ltree[(ch<<1)+1];\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nUZIP.F.inflate = function(data, buf) {\r\n\tvar u8=Uint8Array;\r\n\tif(data[0]==3 && data[1]==0) return (buf ? buf : new u8(0));\r\n\tvar F=UZIP.F, bitsF = F._bitsF, bitsE = F._bitsE, decodeTiny = F._decodeTiny, makeCodes = F.makeCodes, codes2map=F.codes2map, get17 = F._get17;\r\n\tvar U = F.U;\r\n\t\r\n\tvar noBuf = (buf==null);\r\n\tif(noBuf) buf = new u8((data.length>>>2)<<3);\r\n\t\r\n\tvar BFINAL=0, BTYPE=0, HLIT=0, HDIST=0, HCLEN=0, ML=0, MD=0; \t\r\n\tvar off = 0, pos = 0;\r\n\tvar lmap, dmap;\r\n\t\r\n\twhile(BFINAL==0) {\t\t\r\n\t\tBFINAL = bitsF(data, pos , 1);\r\n\t\tBTYPE = bitsF(data, pos+1, 2); pos+=3;\r\n\t\t//console.log(BFINAL, BTYPE);\r\n\t\t\r\n\t\tif(BTYPE==0) {\r\n\t\t\tif((pos&7)!=0) pos+=8-(pos&7);\r\n\t\t\tvar p8 = (pos>>>3)+4, len = data[p8-4]|(data[p8-3]<<8); //console.log(len);//bitsF(data, pos, 16), \r\n\t\t\tif(noBuf) buf=UZIP.F._check(buf, off+len);\r\n\t\t\tbuf.set(new u8(data.buffer, data.byteOffset+p8, len), off);\r\n\t\t\t//for(var i=0; i<len; i++) buf[off+i] = data[p8+i];\r\n\t\t\t//for(var i=0; i<len; i++) if(buf[off+i] != data[p8+i]) throw \"e\";\r\n\t\t\tpos = ((p8+len)<<3); off+=len; continue;\r\n\t\t}\r\n\t\tif(noBuf) buf=UZIP.F._check(buf, off+(1<<17)); // really not enough in many cases (but PNG and ZIP provide buffer in advance)\r\n\t\tif(BTYPE==1) { lmap = U.flmap; dmap = U.fdmap; ML = (1<<9)-1; MD = (1<<5)-1; }\r\n\t\tif(BTYPE==2) {\r\n\t\t\tHLIT = bitsE(data, pos , 5)+257; \r\n\t\t\tHDIST = bitsE(data, pos+ 5, 5)+ 1; \r\n\t\t\tHCLEN = bitsE(data, pos+10, 4)+ 4; pos+=14;\r\n\t\t\t\r\n\t\t\tvar ppos = pos;\r\n\t\t\tfor(var i=0; i<38; i+=2) { U.itree[i]=0; U.itree[i+1]=0; }\r\n\t\t\tvar tl = 1;\r\n\t\t\tfor(var i=0; i<HCLEN; i++) { var l=bitsE(data, pos+i*3, 3); U.itree[(U.ordr[i]<<1)+1] = l; if(l>tl)tl=l; } pos+=3*HCLEN; //console.log(itree);\r\n\t\t\tmakeCodes(U.itree, tl);\r\n\t\t\tcodes2map(U.itree, tl, U.imap);\r\n\t\t\t\r\n\t\t\tlmap = U.lmap; dmap = U.dmap;\r\n\t\t\t\r\n\t\t\tpos = decodeTiny(U.imap, (1<<tl)-1, HLIT+HDIST, data, pos, U.ttree);\r\n\t\t\tvar mx0 = F._copyOut(U.ttree, 0, HLIT , U.ltree); ML = (1<<mx0)-1;\r\n\t\t\tvar mx1 = F._copyOut(U.ttree, HLIT, HDIST, U.dtree); MD = (1<<mx1)-1;\r\n\t\t\t\r\n\t\t\t//var ml = decodeTiny(U.imap, (1<<tl)-1, HLIT , data, pos, U.ltree); ML = (1<<(ml>>>24))-1; pos+=(ml&0xffffff);\r\n\t\t\tmakeCodes(U.ltree, mx0);\r\n\t\t\tcodes2map(U.ltree, mx0, lmap);\r\n\t\t\t\r\n\t\t\t//var md = decodeTiny(U.imap, (1<<tl)-1, HDIST, data, pos, U.dtree); MD = (1<<(md>>>24))-1; pos+=(md&0xffffff);\r\n\t\t\tmakeCodes(U.dtree, mx1);\r\n\t\t\tcodes2map(U.dtree, mx1, dmap);\r\n\t\t}\r\n\t\t//var ooff=off, opos=pos;\r\n\t\twhile(true) {\r\n\t\t\tvar code = lmap[get17(data, pos) & ML]; pos += code&15;\r\n\t\t\tvar lit = code>>>4; //U.lhst[lit]++; \r\n\t\t\tif((lit>>>8)==0) { buf[off++] = lit; }\r\n\t\t\telse if(lit==256) { break; }\r\n\t\t\telse {\r\n\t\t\t\tvar end = off+lit-254;\r\n\t\t\t\tif(lit>264) { var ebs = U.ldef[lit-257]; end = off + (ebs>>>3) + bitsE(data, pos, ebs&7); pos += ebs&7; }\r\n\t\t\t\t//UZIP.F.dst[end-off]++;\r\n\t\t\t\t\r\n\t\t\t\tvar dcode = dmap[get17(data, pos) & MD]; pos += dcode&15;\r\n\t\t\t\tvar dlit = dcode>>>4;\r\n\t\t\t\tvar dbs = U.ddef[dlit], dst = (dbs>>>4) + bitsF(data, pos, dbs&15); pos += dbs&15;\r\n\t\t\t\t\r\n\t\t\t\t//var o0 = off-dst, stp = Math.min(end-off, dst);\r\n\t\t\t\t//if(stp>20) while(off<end) { buf.copyWithin(off, o0, o0+stp); off+=stp; } else\r\n\t\t\t\t//if(end-dst<=off) buf.copyWithin(off, off-dst, end-dst); else\r\n\t\t\t\t//if(dst==1) buf.fill(buf[off-1], off, end); else\r\n\t\t\t\tif(noBuf) buf=UZIP.F._check(buf, off+(1<<17));\r\n\t\t\t\twhile(off<end) { buf[off]=buf[off++-dst]; buf[off]=buf[off++-dst]; buf[off]=buf[off++-dst]; buf[off]=buf[off++-dst]; } \r\n\t\t\t\toff=end;\r\n\t\t\t\t//while(off!=end) { buf[off]=buf[off++-dst]; }\r\n\t\t\t}\r\n\t\t}\r\n\t\t//console.log(off-ooff, (pos-opos)>>>3);\r\n\t}\r\n\t//console.log(UZIP.F.dst);\r\n\t//console.log(tlen, dlen, off-tlen+tcnt);\r\n\treturn buf.length==off ? buf : buf.slice(0,off);\r\n}\r\nUZIP.F._check=function(buf, len) {\r\n\tvar bl=buf.length; if(len<=bl) return buf;\r\n\tvar nbuf = new Uint8Array(Math.max(bl<<1,len)); nbuf.set(buf,0);\r\n\t//for(var i=0; i<bl; i+=4) { nbuf[i]=buf[i]; nbuf[i+1]=buf[i+1]; nbuf[i+2]=buf[i+2]; nbuf[i+3]=buf[i+3]; }\r\n\treturn nbuf;\r\n}\r\n\r\nUZIP.F._decodeTiny = function(lmap, LL, len, data, pos, tree) {\r\n\tvar bitsE = UZIP.F._bitsE, get17 = UZIP.F._get17;\r\n\tvar i = 0;\r\n\twhile(i<len) {\r\n\t\tvar code = lmap[get17(data, pos)&LL]; pos+=code&15;\r\n\t\tvar lit = code>>>4; \r\n\t\tif(lit<=15) { tree[i]=lit; i++; }\r\n\t\telse {\r\n\t\t\tvar ll = 0, n = 0;\r\n\t\t\tif(lit==16) {\r\n\t\t\t\tn = (3 + bitsE(data, pos, 2)); pos += 2; ll = tree[i-1];\r\n\t\t\t}\r\n\t\t\telse if(lit==17) {\r\n\t\t\t\tn = (3 + bitsE(data, pos, 3)); pos += 3;\r\n\t\t\t}\r\n\t\t\telse if(lit==18) {\r\n\t\t\t\tn = (11 + bitsE(data, pos, 7)); pos += 7;\r\n\t\t\t}\r\n\t\t\tvar ni = i+n;\r\n\t\t\twhile(i<ni) { tree[i]=ll; i++; }\r\n\t\t}\r\n\t}\r\n\treturn pos;\r\n}\r\nUZIP.F._copyOut = function(src, off, len, tree) {\r\n\tvar mx=0, i=0, tl=tree.length>>>1;\r\n\twhile(i<len) { var v=src[i+off]; tree[(i<<1)]=0; tree[(i<<1)+1]=v; if(v>mx)mx=v; i++; }\r\n\twhile(i<tl ) { tree[(i<<1)]=0; tree[(i<<1)+1]=0; i++; }\r\n\treturn mx;\r\n}\r\n\r\nUZIP.F.makeCodes = function(tree, MAX_BITS) { // code, length\r\n\tvar U = UZIP.F.U;\r\n\tvar max_code = tree.length;\r\n\tvar code, bits, n, i, len;\r\n\t\r\n\tvar bl_count = U.bl_count; for(var i=0; i<=MAX_BITS; i++) bl_count[i]=0;\r\n\tfor(i=1; i<max_code; i+=2) bl_count[tree[i]]++;\r\n\t\r\n\tvar next_code = U.next_code;\t// smallest code for each length\r\n\t\r\n\tcode = 0;\r\n\tbl_count[0] = 0;\r\n\tfor (bits = 1; bits <= MAX_BITS; bits++) {\r\n\t\tcode = (code + bl_count[bits-1]) << 1;\r\n\t\tnext_code[bits] = code;\r\n\t}\r\n\t\r\n\tfor (n = 0; n < max_code; n+=2) {\r\n\t\tlen = tree[n+1];\r\n\t\tif (len != 0) {\r\n\t\t\ttree[n] = next_code[len];\r\n\t\t\tnext_code[len]++;\r\n\t\t}\r\n\t}\r\n}\r\nUZIP.F.codes2map = function(tree, MAX_BITS, map) {\r\n\tvar max_code = tree.length;\r\n\tvar U=UZIP.F.U, r15 = U.rev15;\r\n\tfor(var i=0; i<max_code; i+=2) if(tree[i+1]!=0) {\r\n\t\tvar lit = i>>1;\r\n\t\tvar cl = tree[i+1], val = (lit<<4)|cl; // : (0x8000 | (U.of0[lit-257]<<7) | (U.exb[lit-257]<<4) | cl);\r\n\t\tvar rest = (MAX_BITS-cl), i0 = tree[i]<<rest, i1 = i0 + (1<<rest);\r\n\t\t//tree[i]=r15[i0]>>>(15-MAX_BITS);\r\n\t\twhile(i0!=i1) {\r\n\t\t\tvar p0 = r15[i0]>>>(15-MAX_BITS);\r\n\t\t\tmap[p0]=val; i0++;\r\n\t\t}\r\n\t}\r\n}\r\nUZIP.F.revCodes = function(tree, MAX_BITS) {\r\n\tvar r15 = UZIP.F.U.rev15, imb = 15-MAX_BITS;\r\n\tfor(var i=0; i<tree.length; i+=2) { var i0 = (tree[i]<<(MAX_BITS-tree[i+1])); tree[i] = r15[i0]>>>imb; }\r\n}\r\n\r\n// used only in deflate\r\nUZIP.F._putsE= function(dt, pos, val ) { val = val<<(pos&7); var o=(pos>>>3); dt[o]|=val; dt[o+1]|=(val>>>8); }\r\nUZIP.F._putsF= function(dt, pos, val ) { val = val<<(pos&7); var o=(pos>>>3); dt[o]|=val; dt[o+1]|=(val>>>8); dt[o+2]|=(val>>>16); }\r\n\r\nUZIP.F._bitsE= function(dt, pos, length) { return ((dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) )>>>(pos&7))&((1<<length)-1); }\r\nUZIP.F._bitsF= function(dt, pos, length) { return ((dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16))>>>(pos&7))&((1<<length)-1); }\r\n/*\r\nUZIP.F._get9 = function(dt, pos) {\r\n\treturn ((dt[pos>>>3] | (dt[(pos>>>3)+1]<<8))>>>(pos&7))&511;\r\n} */\r\nUZIP.F._get17= function(dt, pos) {\t// return at least 17 meaningful bytes\r\n\treturn (dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16) )>>>(pos&7);\r\n}\r\nUZIP.F._get25= function(dt, pos) {\t// return at least 17 meaningful bytes\r\n\treturn (dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16) | (dt[(pos>>>3)+3]<<24) )>>>(pos&7);\r\n}\r\nUZIP.F.U = function(){\r\n\tvar u16=Uint16Array, u32=Uint32Array;\r\n\treturn {\r\n\t\tnext_code : new u16(16),\r\n\t\tbl_count : new u16(16),\r\n\t\tordr : [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ],\r\n\t\tof0 : [3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],\r\n\t\texb : [0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0],\r\n\t\tldef : new u16(32),\r\n\t\tdf0 : [1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 65535, 65535],\r\n\t\tdxb : [0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0],\r\n\t\tddef : new u32(32),\r\n\t\tflmap: new u16( 512), fltree: [],\r\n\t\tfdmap: new u16( 32), fdtree: [],\r\n\t\tlmap : new u16(32768), ltree : [], ttree:[],\r\n\t\tdmap : new u16(32768), dtree : [],\r\n\t\timap : new u16( 512), itree : [],\r\n\t\t//rev9 : new u16( 512)\r\n\t\trev15: new u16(1<<15),\r\n\t\tlhst : new u32(286), dhst : new u32( 30), ihst : new u32(19),\r\n\t\tlits : new u32(15000),\r\n\t\tstrt : new u16(1<<16),\r\n\t\tprev : new u16(1<<15)\r\n\t}; \r\n} ();\r\n\r\n(function(){\t\r\n\tvar U = UZIP.F.U;\r\n\tvar len = 1<<15;\r\n\tfor(var i=0; i<len; i++) {\r\n\t\tvar x = i;\r\n\t\tx = (((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1));\r\n\t\tx = (((x & 0xcccccccc) >>> 2) | ((x & 0x33333333) << 2));\r\n\t\tx = (((x & 0xf0f0f0f0) >>> 4) | ((x & 0x0f0f0f0f) << 4));\r\n\t\tx = (((x & 0xff00ff00) >>> 8) | ((x & 0x00ff00ff) << 8));\r\n\t\tU.rev15[i] = (((x >>> 16) | (x << 16)))>>>17;\r\n\t}\r\n\t\r\n\tfunction pushV(tgt, n, sv) { while(n--!=0) tgt.push(0,sv); }\r\n\t\r\n\tfor(var i=0; i<32; i++) { U.ldef[i]=(U.of0[i]<<3)|U.exb[i]; U.ddef[i]=(U.df0[i]<<4)|U.dxb[i]; }\r\n\t\r\n\tpushV(U.fltree, 144, 8); pushV(U.fltree, 255-143, 9); pushV(U.fltree, 279-255, 7); pushV(U.fltree,287-279,8);\r\n\t/*\r\n\tvar i = 0;\r\n\tfor(; i<=143; i++) U.fltree.push(0,8);\r\n\tfor(; i<=255; i++) U.fltree.push(0,9);\r\n\tfor(; i<=279; i++) U.fltree.push(0,7);\r\n\tfor(; i<=287; i++) U.fltree.push(0,8);\r\n\t*/\r\n\tUZIP.F.makeCodes(U.fltree, 9);\r\n\tUZIP.F.codes2map(U.fltree, 9, U.flmap);\r\n\tUZIP.F.revCodes (U.fltree, 9)\r\n\t\r\n\tpushV(U.fdtree,32,5);\r\n\t//for(i=0;i<32; i++) U.fdtree.push(0,5);\r\n\tUZIP.F.makeCodes(U.fdtree, 5);\r\n\tUZIP.F.codes2map(U.fdtree, 5, U.fdmap);\r\n\tUZIP.F.revCodes (U.fdtree, 5)\r\n\t\r\n\tpushV(U.itree,19,0); pushV(U.ltree,286,0); pushV(U.dtree,30,0); pushV(U.ttree,320,0);\r\n\t/*\r\n\tfor(var i=0; i< 19; i++) U.itree.push(0,0);\r\n\tfor(var i=0; i<286; i++) U.ltree.push(0,0);\r\n\tfor(var i=0; i< 30; i++) U.dtree.push(0,0);\r\n\tfor(var i=0; i<320; i++) U.ttree.push(0,0);\r\n\t*/\r\n})()\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n","// https://github.com/photopea/UPNG.js/blob/f6e5f93da01094b1ffb3cef364abce4d9e758cbf/UPNG.js\n\n// import * as pako from 'pako'\nimport * as UZIP from 'uzip';\n\nconst UPNG = (function () {\n var _bin = {\n nextZero(data, p) { while (data[p] != 0) p++; return p; },\n readUshort(buff, p) { return (buff[p] << 8) | buff[p + 1]; },\n writeUshort(buff, p, n) { buff[p] = (n >> 8) & 255; buff[p + 1] = n & 255; },\n readUint(buff, p) { return (buff[p] * (256 * 256 * 256)) + ((buff[p + 1] << 16) | (buff[p + 2] << 8) | buff[p + 3]); },\n writeUint(buff, p, n) { buff[p] = (n >> 24) & 255; buff[p + 1] = (n >> 16) & 255; buff[p + 2] = (n >> 8) & 255; buff[p + 3] = n & 255; },\n readASCII(buff, p, l) { let s = ''; for (let i = 0; i < l; i++) s += String.fromCharCode(buff[p + i]); return s; },\n writeASCII(data, p, s) { for (let i = 0; i < s.length; i++) data[p + i] = s.charCodeAt(i); },\n readBytes(buff, p, l) { const arr = []; for (let i = 0; i < l; i++) arr.push(buff[p + i]); return arr; },\n pad(n) { return n.length < 2 ? `0${n}` : n; },\n readUTF8(buff, p, l) {\n let s = '';\n let ns;\n for (let i = 0; i < l; i++) s += `%${_bin.pad(buff[p + i].toString(16))}`;\n try { ns = decodeURIComponent(s); } catch (e) { return _bin.readASCII(buff, p, l); }\n return ns;\n },\n };\n\n function toRGBA8(out) {\n const w = out.width; const\n h = out.height;\n if (out.tabs.acTL == null) return [decodeImage(out.data, w, h, out).buffer];\n\n const frms = [];\n if (out.frames[0].data == null) out.frames[0].data = out.data;\n\n const len = w * h * 4; const img = new Uint8Array(len); const empty = new Uint8Array(len); const\n prev = new Uint8Array(len);\n for (let i = 0; i < out.frames.length; i++) {\n const frm = out.frames[i];\n const fx = frm.rect.x; const fy = frm.rect.y; const fw = frm.rect.width; const\n fh = frm.rect.height;\n const fdata = decodeImage(frm.data, fw, fh, out);\n\n if (i != 0) for (var j = 0; j < len; j++) prev[j] = img[j];\n\n if (frm.blend == 0) _copyTile(fdata, fw, fh, img, w, h, fx, fy, 0);\n else if (frm.blend == 1) _copyTile(fdata, fw, fh, img, w, h, fx, fy, 1);\n\n frms.push(img.buffer.slice(0));\n\n if (frm.dispose == 0) {} else if (frm.dispose == 1) _copyTile(empty, fw, fh, img, w, h, fx, fy, 0);\n else if (frm.dispose == 2) for (var j = 0; j < len; j++) img[j] = prev[j];\n }\n return frms;\n }\n function decodeImage(data, w, h, out) {\n const area = w * h; const\n bpp = _getBPP(out);\n const bpl = Math.ceil(w * bpp / 8);\t// bytes per line\n\n const bf = new Uint8Array(area * 4); const\n bf32 = new Uint32Array(bf.buffer);\n const { ctype } = out;\n const { depth } = out;\n const rs = _bin.readUshort;\n\n // console.log(ctype, depth);\n const time = Date.now();\n\n if (ctype == 6) { // RGB + alpha\n const qarea = area << 2;\n if (depth == 8) for (var i = 0; i < qarea; i += 4) { bf[i] = data[i]; bf[i + 1] = data[i + 1]; bf[i + 2] = data[i + 2]; bf[i + 3] = data[i + 3]; }\n if (depth == 16) for (var i = 0; i < qarea; i++) { bf[i] = data[i << 1]; }\n } else if (ctype == 2) {\t// RGB\n const ts = out.tabs.tRNS;\n if (ts == null) {\n if (depth == 8) for (var i = 0; i < area; i++) { var ti = i * 3; bf32[i] = (255 << 24) | (data[ti + 2] << 16) | (data[ti + 1] << 8) | data[ti]; }\n if (depth == 16) for (var i = 0; i < area; i++) { var ti = i * 6; bf32[i] = (255 << 24) | (data[ti + 4] << 16) | (data[ti + 2] << 8) | data[ti]; }\n } else {\n var tr = ts[0]; const tg = ts[1]; const\n tb = ts[2];\n if (depth == 8) {\n for (var i = 0; i < area; i++) {\n var qi = i << 2; var\n ti = i * 3; bf32[i] = (255 << 24) | (data[ti + 2] << 16) | (data[ti + 1] << 8) | data[ti];\n if (data[ti] == tr && data[ti + 1] == tg && data[ti + 2] == tb) bf[qi + 3] = 0;\n }\n }\n if (depth == 16) {\n for (var i = 0; i < area; i++) {\n var qi = i << 2; var\n ti = i * 6; bf32[i] = (255 << 24) | (data[ti + 4] << 16) | (data[ti + 2] << 8) | data[ti];\n if (rs(data, ti) == tr && rs(data, ti + 2) == tg && rs(data, ti + 4) == tb) bf[qi + 3] = 0;\n }\n }\n }\n } else if (ctype == 3) {\t// palette\n const p = out.tabs.PLTE;\n const ap = out.tabs.tRNS;\n const tl = ap ? ap.length : 0;\n // console.log(p, ap);\n if (depth == 1) {\n for (var y = 0; y < h; y++) {\n var s0 = y * bpl; var\n t0 = y * w;\n for (var i = 0; i < w; i++) {\n var qi = (t0 + i) << 2; var j = ((data[s0 + (i >> 3)] >> (7 - ((i & 7) << 0))) & 1); var\n cj = 3 * j; bf[qi] = p[cj]; bf[qi + 1] = p[cj + 1]; bf[qi + 2] = p[cj + 2]; bf[qi + 3] = (j < tl) ? ap[j] : 255;\n }\n }\n }\n if (depth == 2) {\n for (var y = 0; y < h; y++) {\n var s0 = y * bpl; var\n t0 = y * w;\n for (var i = 0; i < w; i++) {\n var qi = (t0 + i) << 2; var j = ((data[s0 + (i >> 2)] >> (6 - ((i & 3) << 1))) & 3); var\n cj = 3 * j; bf[qi] = p[cj]; bf[qi + 1] = p[cj + 1]; bf[qi + 2] = p[cj + 2]; bf[qi + 3] = (j < tl) ? ap[j] : 255;\n }\n }\n }\n if (depth == 4) {\n for (var y = 0; y < h; y++) {\n var s0 = y * bpl; var\n t0 = y * w;\n for (var i = 0; i < w; i++) {\n var qi = (t0 + i) << 2; var j = ((data[s0 + (i >> 1)] >> (4 - ((i & 1) << 2))) & 15); var\n cj = 3 * j; bf[qi] = p[cj]; bf[qi + 1] = p[cj + 1]; bf[qi + 2] = p[cj + 2]; bf[qi + 3] = (j < tl) ? ap[j] : 255;\n }\n }\n }\n if (depth == 8) {\n for (var i = 0; i < area; i++) {\n var qi = i << 2; var j = data[i]; var\n cj = 3 * j; bf[qi] = p[cj]; bf[qi + 1] = p[cj + 1]; bf[qi + 2] = p[cj + 2]; bf[qi + 3] = (j < tl) ? ap[j] : 255;\n }\n }\n } else if (ctype == 4) {\t// gray + alpha\n if (depth == 8) {\n for (var i = 0; i < area; i++) {\n var qi = i << 2; var di = i << 1; var\n gr = data[di]; bf[qi] = gr; bf[qi + 1] = gr; bf[qi + 2] = gr; bf[qi + 3] = data[di + 1];\n }\n }\n if (depth == 16) {\n for (var i = 0; i < area; i++) {\n var qi = i << 2; var di = i << 2; var\n gr = data[di]; bf[qi] = gr; bf[qi + 1] = gr; bf[qi + 2] = gr; bf[qi + 3] = data[di + 2];\n }\n }\n } else if (ctype == 0) {\t// gray\n var tr = out.tabs.tRNS ? out.tabs.tRNS : -1;\n for (var y = 0; y < h; y++) {\n const off = y * bpl; const\n to = y * w;\n if (depth == 1) {\n for (var x = 0; x < w; x++) {\n var gr = 255 * ((data[off + (x >>> 3)] >>> (7 - ((x & 7)))) & 1); var\n al = (gr == tr * 255) ? 0 : 255; bf32[to + x] = (al << 24) | (gr << 16) | (gr << 8) | gr;\n }\n } else if (depth == 2) {\n for (var x = 0; x < w; x++) {\n var gr = 85 * ((data[off + (x >>> 2)] >>> (6 - ((x & 3) << 1))) & 3); var\n al = (gr == tr * 85) ? 0 : 255; bf32[to + x] = (al << 24) | (gr << 16) | (gr << 8) | gr;\n }\n } else if (depth == 4) {\n for (var x = 0; x < w; x++) {\n var gr = 17 * ((data[off + (x >>> 1)] >>> (4 - ((x & 1) << 2))) & 15); var\n al = (gr == tr * 17) ? 0 : 255; bf32[to + x] = (al << 24) | (gr << 16) | (gr << 8) | gr;\n }\n } else if (depth == 8) {\n for (var x = 0; x < w; x++) {\n var gr = data[off + x]; var\n al = (gr == tr) ? 0 : 255; bf32[to + x] = (al << 24) | (gr << 16) | (gr << 8) | gr;\n }\n } else if (depth == 16) {\n for (var x = 0; x < w; x++) {\n var gr = data[off + (x << 1)]; var\n al = (rs(data, off + (x << 1)) == tr) ? 0 : 255; bf32[to + x] = (al << 24) | (gr << 16) | (gr << 8) | gr;\n }\n }\n }\n }\n // console.log(Date.now()-time);\n return bf;\n }\n\n function decode(buff) {\n const data = new Uint8Array(buff); let offset = 8; const bin = _bin; const rUs = bin.readUshort; const\n rUi = bin.readUint;\n const out = { tabs: {}, frames: [] };\n const dd = new Uint8Array(data.length); let\n doff = 0;\t // put all IDAT data into it\n let fd; let\n foff = 0;\t// frames\n\n const mgck = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];\n for (var i = 0; i < 8; i++) if (data[i] != mgck[i]) throw 'The input is not a PNG file!';\n\n while (offset < data.length) {\n const len = bin.readUint(data, offset); offset += 4;\n const type = bin.readASCII(data, offset, 4); offset += 4;\n // console.log(type,len);\n\n if (type == 'IHDR') { _IHDR(data, offset, out); } else if (type == 'iCCP') {\n var off = offset; while (data[off] != 0) off++;\n const nam = bin.readASCII(data, offset, off - offset);\n const cpr = data[off + 1];\n const fil = data.slice(off + 2, offset + len);\n let res = null;\n try { res = _inflate(fil); } catch (e) { res = inflateRaw(fil); }\n out.tabs[type] = res;\n } else if (type == 'CgBI') { out.tabs[type] = data.slice(offset, offset + 4); } else if (type == 'IDAT') {\n for (var i = 0; i < len; i++) dd[doff + i] = data[offset + i];\n doff += len;\n } else if (type == 'acTL') {\n out.tabs[type] = { num_frames: rUi(data, offset), num_plays: rUi(data, offset + 4) };\n fd = new Uint8Array(data.length);\n } else if (type == 'fcTL') {\n if (foff != 0) {\n var fr = out.frames[out.frames.length - 1];\n fr.data = _decompress(out, fd.slice(0, foff), fr.rect.width, fr.rect.height); foff = 0;\n }\n const rct = {\n x: rUi(data, offset + 12), y: rUi(data, offset + 16), width: rUi(data, offset + 4), height: rUi(data, offset + 8),\n };\n let del = rUs(data, offset + 22); del = rUs(data, offset + 20) / (del == 0 ? 100 : del);\n const frm = {\n rect: rct, delay: Math.round(del * 1000), dispose: data[offset + 24], blend: data[offset + 25],\n };\n // console.log(frm);\n out.frames.push(frm);\n } else if (type == 'fdAT') {\n for (var i = 0; i < len - 4; i++) fd[foff + i] = data[offset + i + 4];\n foff += len - 4;\n } else if (type == 'pHYs') {\n out.tabs[type] = [bin.readUint(data, offset), bin.readUint(data, offset + 4), data[offset + 8]];\n } else if (type == 'cHRM') {\n out.tabs[type] = [];\n for (var i = 0; i < 8; i++) out.tabs[type].push(bin.readUint(data, offset + i * 4));\n } else if (type == 'tEXt' || type == 'zTXt') {\n if (out.tabs[type] == null) out.tabs[type] = {};\n var nz = bin.nextZero(data, offset);\n var keyw = bin.readASCII(data, offset, nz - offset);\n var text; var\n tl = offset + len - nz - 1;\n if (type == 'tEXt') text = bin.readASCII(data, nz + 1, tl);\n else {\n var bfr = _inflate(data.slice(nz + 2, nz + 2 + tl));\n text = bin.readUTF8(bfr, 0, bfr.length);\n }\n out.tabs[type][keyw] = text;\n } else if (type == 'iTXt') {\n if (out.tabs[type] == null) out.tabs[type] = {};\n var nz = 0; var\n off = offset;\n nz = bin.nextZero(data, off);\n var keyw = bin.readASCII(data, off, nz - off); off = nz + 1;\n const cflag = data[off]; const\n cmeth = data[off + 1]; off += 2;\n nz = bin.nextZero(data, off);\n const ltag = bin.readASCII(data, off, nz - off); off = nz + 1;\n nz = bin.nextZero(data, off);\n const tkeyw = bin.readUTF8(data, off, nz - off); off = nz + 1;\n var text; var\n tl = len - (off - offset);\n if (cflag == 0) text = bin.readUTF8(data, off, tl);\n else {\n var bfr = _inflate(data.slice(off, off + tl));\n text = bin.readUTF8(bfr, 0, bfr.length);\n }\n out.tabs[type][keyw] = text;\n } else if (type == 'PLTE') {\n out.tabs[type] = bin.readBytes(data, offset, len);\n } else if (type == 'hIST') {\n const pl = out.tabs.PLTE.length / 3;\n out.tabs[type] = []; for (var i = 0; i < pl; i++) out.tabs[type].push(rUs(data, offset + i * 2));\n } else if (type == 'tRNS') {\n if (out.ctype == 3) out.tabs[type] = bin.readBytes(data, offset, len);\n else if (out.ctype == 0) out.tabs[type] = rUs(data, offset);\n else if (out.ctype == 2) out.tabs[type] = [rUs(data, offset), rUs(data, offset + 2), rUs(data, offset + 4)];\n // else console.log(\"tRNS for unsupported color type\",out.ctype, len);\n } else if (type == 'gAMA') out.tabs[type] = bin.readUint(data, offset) / 100000;\n else if (type == 'sRGB') out.tabs[type] = data[offset];\n else if (type == 'bKGD') {\n if (out.ctype == 0 || out.ctype == 4) out.tabs[type] = [rUs(data, offset)];\n else if (out.ctype == 2 || out.ctype == 6) out.tabs[type] = [rUs(data, offset), rUs(data, offset + 2), rUs(data, offset + 4)];\n else if (out.ctype == 3) out.tabs[type] = data[offset];\n } else if (type == 'IEND') {\n break;\n }\n // else { console.log(\"unknown chunk type\", type, len); out.tabs[type]=data.slice(offset,offset+len); }\n offset += len;\n const crc = bin.readUint(data, offset); offset += 4;\n }\n if (foff != 0) {\n var fr = out.frames[out.frames.length - 1];\n fr.data = _decompress(out, fd.slice(0, foff), fr.rect.width