2026-01-26 01:40:48 +03:00

831 lines
29 KiB
JavaScript

var UZIP = {};
if(typeof module == "object") module.exports = UZIP;
UZIP["parse"] = function(buf, onlyNames) // ArrayBuffer
{
var rUs = UZIP.bin.readUshort, rUi = UZIP.bin.readUint, o = 0, out = {};
var data = new Uint8Array(buf);
var eocd = data.length-4;
while(rUi(data, eocd)!=0x06054b50) eocd--;
var o = eocd;
o+=4; // sign = 0x06054b50
o+=4; // disks = 0;
var cnu = rUs(data, o); o+=2;
var cnt = rUs(data, o); o+=2;
var csize = rUi(data, o); o+=4;
var coffs = rUi(data, o); o+=4;
o = coffs;
for(var i=0; i<cnu; i++)
{
var sign = rUi(data, o); o+=4;
o += 4; // versions;
o += 4; // flag + compr
o += 4; // time
var crc32 = rUi(data, o); o+=4;
var csize = rUi(data, o); o+=4;
var usize = rUi(data, o); o+=4;
var nl = rUs(data, o), el = rUs(data, o+2), cl = rUs(data, o+4); o += 6; // name, extra, comment
o += 8; // disk, attribs
var roff = rUi(data, o); o+=4;
o += nl + el + cl;
UZIP._readLocal(data, roff, out, csize, usize, onlyNames);
}
//console.log(out);
return out;
}
UZIP._readLocal = function(data, o, out, csize, usize, onlyNames)
{
var rUs = UZIP.bin.readUshort, rUi = UZIP.bin.readUint;
var sign = rUi(data, o); o+=4;
var ver = rUs(data, o); o+=2;
var gpflg = rUs(data, o); o+=2;
//if((gpflg&8)!=0) throw "unknown sizes";
var cmpr = rUs(data, o); o+=2;
var time = rUi(data, o); o+=4;
var crc32 = rUi(data, o); o+=4;
//var csize = rUi(data, o); o+=4;
//var usize = rUi(data, o); o+=4;
o+=8;
var nlen = rUs(data, o); o+=2;
var elen = rUs(data, o); o+=2;
var name = UZIP.bin.readUTF8(data, o, nlen); o+=nlen; //console.log(name);
o += elen;
//console.log(sign.toString(16), ver, gpflg, cmpr, crc32.toString(16), "csize, usize", csize, usize, nlen, elen, name, o);
if(onlyNames) { out[name]={size:usize, csize:csize}; return; }
var file = new Uint8Array(data.buffer, o);
if(false) {}
else if(cmpr==0) out[name] = new Uint8Array(file.buffer.slice(o, o+csize));
else if(cmpr==8) {
var buf = new Uint8Array(usize); UZIP.inflateRaw(file, buf);
/*var nbuf = pako["inflateRaw"](file);
if(usize>8514000) {
//console.log(PUtils.readASCII(buf , 8514500, 500));
//console.log(PUtils.readASCII(nbuf, 8514500, 500));
}
for(var i=0; i<buf.length; i++) if(buf[i]!=nbuf[i]) { console.log(buf.length, nbuf.length, usize, i); throw "e"; }
*/
out[name] = buf;
}
else throw "unknown compression method: "+cmpr;
}
UZIP.inflateRaw = function(file, buf) { return UZIP.F.inflate(file, buf); }
UZIP.inflate = function(file, buf) {
var CMF = file[0], FLG = file[1];
var CM = (CMF&15), CINFO = (CMF>>>4);
//console.log(CM, CINFO,CMF,FLG);
return UZIP.inflateRaw(new Uint8Array(file.buffer, file.byteOffset+2, file.length-6), buf);
}
UZIP.deflate = function(data, opts/*, buf, off*/) {
if(opts==null) opts={level:6};
var off=0, buf=new Uint8Array(50+Math.floor(data.length*1.1));
buf[off]=120; buf[off+1]=156; off+=2;
off = UZIP.F.deflateRaw(data, buf, off, opts.level);
var crc = UZIP.adler(data, 0, data.length);
buf[off+0]=((crc>>>24)&255);
buf[off+1]=((crc>>>16)&255);
buf[off+2]=((crc>>> 8)&255);
buf[off+3]=((crc>>> 0)&255);
return new Uint8Array(buf.buffer, 0, off+4);
}
UZIP.deflateRaw = function(data, opts) {
if(opts==null) opts={level:6};
var buf=new Uint8Array(50+Math.floor(data.length*1.1));
var off = UZIP.F.deflateRaw(data, buf, off, opts.level);
return new Uint8Array(buf.buffer, 0, off);
}
UZIP.encode = function(obj, noCmpr) {
if(noCmpr==null) noCmpr=false;
var tot = 0, wUi = UZIP.bin.writeUint, wUs = UZIP.bin.writeUshort;
var zpd = {};
for(var p in obj) { var cpr = !UZIP._noNeed(p) && !noCmpr, buf = obj[p], crc = UZIP.crc.crc(buf,0,buf.length);
zpd[p] = { cpr:cpr, usize:buf.length, crc:crc, file: (cpr ? UZIP.deflateRaw(buf) : buf) }; }
for(var p in zpd) tot += zpd[p].file.length + 30 + 46 + 2*UZIP.bin.sizeUTF8(p);
tot += 22;
var data = new Uint8Array(tot), o = 0;
var fof = []
for(var p in zpd) {
var file = zpd[p]; fof.push(o);
o = UZIP._writeHeader(data, o, p, file, 0);
}
var i=0, ioff = o;
for(var p in zpd) {
var file = zpd[p]; fof.push(o);
o = UZIP._writeHeader(data, o, p, file, 1, fof[i++]);
}
var csize = o-ioff;
wUi(data, o, 0x06054b50); o+=4;
o += 4; // disks
wUs(data, o, i); o += 2;
wUs(data, o, i); o += 2; // number of c d records
wUi(data, o, csize); o += 4;
wUi(data, o, ioff ); o += 4;
o += 2;
return data.buffer;
}
// no need to compress .PNG, .ZIP, .JPEG ....
UZIP._noNeed = function(fn) { var ext = fn.split(".").pop().toLowerCase(); return "png,jpg,jpeg,zip".indexOf(ext)!=-1; }
UZIP._writeHeader = function(data, o, p, obj, t, roff)
{
var wUi = UZIP.bin.writeUint, wUs = UZIP.bin.writeUshort;
var file = obj.file;
wUi(data, o, t==0 ? 0x04034b50 : 0x02014b50); o+=4; // sign
if(t==1) o+=2; // ver made by
wUs(data, o, 20); o+=2; // ver
wUs(data, o, 0); o+=2; // gflip
wUs(data, o, obj.cpr?8:0); o+=2; // cmpr
wUi(data, o, 0); o+=4; // time
wUi(data, o, obj.crc); o+=4; // crc32
wUi(data, o, file.length); o+=4; // csize
wUi(data, o, obj.usize); o+=4; // usize
wUs(data, o, UZIP.bin.sizeUTF8(p)); o+=2; // nlen
wUs(data, o, 0); o+=2; // elen
if(t==1) {
o += 2; // comment length
o += 2; // disk number
o += 6; // attributes
wUi(data, o, roff); o+=4; // usize
}
var nlen = UZIP.bin.writeUTF8(data, o, p); o+= nlen;
if(t==0) { data.set(file, o); o += file.length; }
return o;
}
UZIP.crc = {
table : ( function() {
var tab = new Uint32Array(256);
for (var n=0; n<256; n++) {
var c = n;
for (var k=0; k<8; k++) {
if (c & 1) c = 0xedb88320 ^ (c >>> 1);
else c = c >>> 1;
}
tab[n] = c; }
return tab; })(),
update : function(c, buf, off, len) {
for (var i=0; i<len; i++) c = UZIP.crc.table[(c ^ buf[off+i]) & 0xff] ^ (c >>> 8);
return c;
},
crc : function(b,o,l) { return UZIP.crc.update(0xffffffff,b,o,l) ^ 0xffffffff; }
}
UZIP.adler = function(data,o,len) {
var a = 1, b = 0;
var off = o, end=o+len;
while(off<end) {
var eend = Math.min(off+5552, end);
while(off<eend) {
a += data[off++];
b += a;
}
a=a%65521;
b=b%65521;
}
return (b << 16) | a;
}
UZIP.bin = {
readUshort : function(buff,p) { return (buff[p]) | (buff[p+1]<<8); },
writeUshort: function(buff,p,n){ buff[p] = (n)&255; buff[p+1] = (n>>8)&255; },
readUint : function(buff,p) { return (buff[p+3]*(256*256*256)) + ((buff[p+2]<<16) | (buff[p+1]<< 8) | buff[p]); },
writeUint : 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; },
readASCII : function(buff,p,l){ var s = ""; for(var i=0; i<l; i++) s += String.fromCharCode(buff[p+i]); return s; },
writeASCII : function(data,p,s){ for(var i=0; i<s.length; i++) data[p+i] = s.charCodeAt(i); },
pad : function(n) { return n.length < 2 ? "0" + n : n; },
readUTF8 : function(buff, p, l) {
var s = "", ns;
for(var i=0; i<l; i++) s += "%" + UZIP.bin.pad(buff[p+i].toString(16));
try { ns = decodeURIComponent(s); }
catch(e) { return UZIP.bin.readASCII(buff, p, l); }
return ns;
},
writeUTF8 : function(buff, p, str) {
var strl = str.length, i=0;
for(var ci=0; ci<strl; ci++)
{
var code = str.charCodeAt(ci);
if ((code&(0xffffffff-(1<< 7)+1))==0) { buff[p+i] = ( code ); i++; }
else if((code&(0xffffffff-(1<<11)+1))==0) { buff[p+i] = (192|(code>> 6)); buff[p+i+1] = (128|((code>> 0)&63)); i+=2; }
else 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; }
else 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; }
else throw "e";
}
return i;
},
sizeUTF8 : function(str) {
var strl = str.length, i=0;
for(var ci=0; ci<strl; ci++)
{
var code = str.charCodeAt(ci);
if ((code&(0xffffffff-(1<< 7)+1))==0) { i++ ; }
else if((code&(0xffffffff-(1<<11)+1))==0) { i+=2; }
else if((code&(0xffffffff-(1<<16)+1))==0) { i+=3; }
else if((code&(0xffffffff-(1<<21)+1))==0) { i+=4; }
else throw "e";
}
return i;
}
}
UZIP.F = {};
UZIP.F.deflateRaw = function(data, out, opos, lvl) {
var opts = [
/*
ush good_length; /* reduce lazy search above this match length
ush max_lazy; /* do not perform lazy search above this match length
ush nice_length; /* quit search above this match length
*/
/* good lazy nice chain */
/* 0 */ [ 0, 0, 0, 0,0], /* store only */
/* 1 */ [ 4, 4, 8, 4,0], /* max speed, no lazy matches */
/* 2 */ [ 4, 5, 16, 8,0],
/* 3 */ [ 4, 6, 16, 16,0],
/* 4 */ [ 4, 10, 16, 32,0], /* lazy matches */
/* 5 */ [ 8, 16, 32, 32,0],
/* 6 */ [ 8, 16, 128, 128,0],
/* 7 */ [ 8, 32, 128, 256,0],
/* 8 */ [32, 128, 258, 1024,1],
/* 9 */ [32, 258, 258, 4096,1]]; /* max compression */
var opt = opts[lvl];
var U = UZIP.F.U, goodIndex = UZIP.F._goodIndex, hash = UZIP.F._hash, putsE = UZIP.F._putsE;
var i = 0, pos = opos<<3, cvrd = 0, dlen = data.length;
if(lvl==0) {
while(i<dlen) { var len = Math.min(0xffff, dlen-i);
putsE(out, pos, (i+len==dlen ? 1 : 0)); pos = UZIP.F._copyExact(data, i, len, out, pos+8); i += len; }
return pos>>>3;
}
var 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
if(dlen>2) { nc=UZIP.F._hash(data,0); strt[nc]=0; }
var nmch=0,nmci=0;
for(i=0; i<dlen; i++) {
c = nc;
//*
if(i+1<dlen-2) {
nc = UZIP.F._hash(data, i+1);
var ii = ((i+1)&0x7fff);
prev[ii]=strt[nc];
strt[nc]=ii;
} //*/
if(cvrd<=i) {
if((li>14000 || lc>26697) && (dlen-i)>100) {
if(cvrd<i) { lits[li]=i-cvrd; li+=2; cvrd=i; }
pos = 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;
}
var mch = 0;
//if(nmci==i) mch= nmch; else
if(i<dlen-2) mch = UZIP.F._bestMatch(data, i, prev, c, Math.min(opt[2],dlen-i), opt[3]);
/*
if(mch!=0 && opt[4]==1 && (mch>>>16)<opt[1] && i+1<dlen-2) {
nmch = UZIP.F._bestMatch(data, i+1, prev, nc, opt[2], opt[3]); nmci=i+1;
//var mch2 = UZIP.F._bestMatch(data, i+2, prev, nnc); //nmci=i+1;
if((nmch>>>16)>(mch>>>16)) mch=0;
}//*/
var len = mch>>>16, dst = mch&0xffff; //if(i-dst<0) throw "e";
if(mch!=0) {
var len = mch>>>16, dst = mch&0xffff; //if(i-dst<0) throw "e";
var lgi = goodIndex(len, U.of0); U.lhst[257+lgi]++;
var dgi = goodIndex(dst, U.df0); U.dhst[ dgi]++; ebits += U.exb[lgi] + U.dxb[dgi];
lits[li] = (len<<23)|(i-cvrd); lits[li+1] = (dst<<16)|(lgi<<8)|dgi; li+=2;
cvrd = i + len;
}
else { U.lhst[data[i]]++; }
lc++;
}
}
if(bs!=i || data.length==0) {
if(cvrd<i) { lits[li]=i-cvrd; li+=2; cvrd=i; }
pos = UZIP.F._writeBlock(1, lits, li, ebits, data,bs,i-bs, out, pos); li=0; lc=0; li=lc=ebits=0; bs=i;
}
while((pos&7)!=0) pos++;
return pos>>>3;
}
UZIP.F._bestMatch = function(data, i, prev, c, nice, chain) {
var ci = (i&0x7fff), pi=prev[ci];
//console.log("----", i);
var dif = ((ci-pi + (1<<15)) & 0x7fff); if(pi==ci || c!=UZIP.F._hash(data,i-dif)) return 0;
var tl=0, td=0; // top length, top distance
var dlim = Math.min(0x7fff, i);
while(dif<=dlim && --chain!=0 && pi!=ci /*&& c==UZIP.F._hash(data,i-dif)*/) {
if(tl==0 || (data[i+tl]==data[i+tl-dif])) {
var cl = UZIP.F._howLong(data, i, dif);
if(cl>tl) {
tl=cl; td=dif; if(tl>=nice) break; //*
if(dif+2<cl) cl = dif+2;
var maxd = 0; // pi does not point to the start of the word
for(var j=0; j<cl-2; j++) {
var ei = (i-dif+j+ (1<<15)) & 0x7fff;
var li = prev[ei];
var curd = (ei-li + (1<<15)) & 0x7fff;
if(curd>maxd) { maxd=curd; pi = ei; }
} //*/
}
}
ci=pi; pi = prev[ci];
dif += ((ci-pi + (1<<15)) & 0x7fff);
}
return (tl<<16)|td;
}
UZIP.F._howLong = function(data, i, dif) {
if(data[i]!=data[i-dif] || data[i+1]!=data[i+1-dif] || data[i+2]!=data[i+2-dif]) return 0;
var oi=i, l = Math.min(data.length, i+258); i+=3;
//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;
while(i<l && data[i]==data[i-dif]) i++;
return i-oi;
}
UZIP.F._hash = function(data, i) {
return (((data[i]<<8) | data[i+1])+(data[i+2]<<4))&0xffff;
//var hash_shift = 0, hash_mask = 255;
//var h = data[i+1] % 251;
//h = (((h << 8) + data[i+2]) % 251);
//h = (((h << 8) + data[i+2]) % 251);
//h = ((h<<hash_shift) ^ (c) ) & hash_mask;
//return h | (data[i]<<8);
//return (data[i] | (data[i+1]<<8));
}
//UZIP.___toth = 0;
UZIP.saved = 0;
UZIP.F._writeBlock = function(BFINAL, lits, li, ebits, data,o0,l0, out, pos) {
var U = UZIP.F.U, putsF = UZIP.F._putsF, putsE = UZIP.F._putsE;
//*
var T, ML, MD, MH, numl, numd, numh, lset, dset; U.lhst[256]++;
T = 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];
var cstSize = (((pos+3)&7)==0 ? 0 : 8-((pos+3)&7)) + 32 + (l0<<3);
var fxdSize = ebits + UZIP.F.contSize(U.fltree, U.lhst) + UZIP.F.contSize(U.fdtree, U.dhst);
var dynSize = ebits + UZIP.F.contSize(U.ltree , U.lhst) + UZIP.F.contSize(U.dtree , U.dhst);
dynSize += 14 + 3*numh + UZIP.F.contSize(U.itree, U.ihst) + (U.ihst[16]*2 + U.ihst[17]*3 + U.ihst[18]*7);
for(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;
//*/
var BTYPE = (cstSize<fxdSize && cstSize<dynSize) ? 0 : ( fxdSize<dynSize ? 1 : 2 );
putsF(out, pos, BFINAL); putsF(out, pos+1, BTYPE); pos+=3;
var opos = pos;
if(BTYPE==0) {
while((pos&7)!=0) pos++;
pos = UZIP.F._copyExact(data, o0, l0, out, pos);
}
else {
var ltree, dtree;
if(BTYPE==1) { ltree=U.fltree; dtree=U.fdtree; }
if(BTYPE==2) {
UZIP.F.makeCodes(U.ltree, ML); UZIP.F.revCodes(U.ltree, ML);
UZIP.F.makeCodes(U.dtree, MD); UZIP.F.revCodes(U.dtree, MD);
UZIP.F.makeCodes(U.itree, MH); UZIP.F.revCodes(U.itree, MH);
ltree = U.ltree; dtree = U.dtree;
putsE(out, pos,numl-257); pos+=5; // 286
putsE(out, pos,numd- 1); pos+=5; // 30
putsE(out, pos,numh- 4); pos+=4; // 19
for(var i=0; i<numh; i++) putsE(out, pos+i*3, U.itree[(U.ordr[i]<<1)+1]); pos+=3* numh;
pos = UZIP.F._codeTiny(lset, U.itree, out, pos);
pos = UZIP.F._codeTiny(dset, U.itree, out, pos);
}
var off=o0;
for(var si=0; si<li; si+=2) {
var qb=lits[si], len=(qb>>>23), end = off+(qb&((1<<23)-1));
while(off<end) pos = UZIP.F._writeLit(data[off++], ltree, out, pos);
if(len!=0) {
var qc = lits[si+1], dst=(qc>>16), lgi=(qc>>8)&255, dgi=(qc&255);
pos = UZIP.F._writeLit(257+lgi, ltree, out, pos);
putsE(out, pos, len-U.of0[lgi]); pos+=U.exb[lgi];
pos = UZIP.F._writeLit(dgi, dtree, out, pos);
putsF(out, pos, dst-U.df0[dgi]); pos+=U.dxb[dgi]; off+=len;
}
}
pos = UZIP.F._writeLit(256, ltree, out, pos);
}
//console.log(pos-opos, fxdSize, dynSize, cstSize);
return pos;
}
UZIP.F._copyExact = function(data,off,len,out,pos) {
var p8 = (pos>>>3);
out[p8]=(len); out[p8+1]=(len>>>8); out[p8+2]=255-out[p8]; out[p8+3]=255-out[p8+1]; p8+=4;
out.set(new Uint8Array(data.buffer, off, len), p8);
//for(var i=0; i<len; i++) out[p8+i]=data[off+i];
return pos + ((len+4)<<3);
}
/*
Interesting facts:
- decompressed block can have bytes, which do not occur in a Huffman tree (copied from the previous block by reference)
*/
UZIP.F.getTrees = function() {
var U = UZIP.F.U;
var ML = UZIP.F._hufTree(U.lhst, U.ltree, 15);
var MD = UZIP.F._hufTree(U.dhst, U.dtree, 15);
var lset = [], numl = UZIP.F._lenCodes(U.ltree, lset);
var dset = [], numd = UZIP.F._lenCodes(U.dtree, dset);
for(var i=0; i<lset.length; i+=2) U.ihst[lset[i]]++;
for(var i=0; i<dset.length; i+=2) U.ihst[dset[i]]++;
var MH = UZIP.F._hufTree(U.ihst, U.itree, 7);
var numh = 19; while(numh>4 && U.itree[(U.ordr[numh-1]<<1)+1]==0) numh--;
return [ML, MD, MH, numl, numd, numh, lset, dset];
}
UZIP.F.getSecond= function(a) { var b=[]; for(var i=0; i<a.length; i+=2) b.push (a[i+1]); return b; }
UZIP.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; }
UZIP.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; }
UZIP.F._codeTiny = function(set, tree, out, pos) {
for(var i=0; i<set.length; i+=2) {
var l = set[i], rst = set[i+1]; //console.log(l, pos, tree[(l<<1)+1]);
pos = UZIP.F._writeLit(l, tree, out, pos);
var rsl = l==16 ? 2 : (l==17 ? 3 : 7);
if(l>15) { UZIP.F._putsE(out, pos, rst, rsl); pos+=rsl; }
}
return pos;
}
UZIP.F._lenCodes = function(tree, set) {
var len=tree.length; while(len!=2 && tree[len-1]==0) len-=2; // when no distances, keep one code with length 0
for(var i=0; i<len; i+=2) {
var 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]);
if(l==0 && nxt==l && nnxt==l) {
var lz = i+5;
while(lz+2<len && tree[lz+2]==l) lz+=2;
var zc = Math.min((lz+1-i)>>>1, 138);
if(zc<11) set.push(17, zc-3);
else set.push(18, zc-11);
i += zc*2-2;
}
else if(l==prv && nxt==l && nnxt==l) {
var lz = i+5;
while(lz+2<len && tree[lz+2]==l) lz+=2;
var zc = Math.min((lz+1-i)>>>1, 6);
set.push(16, zc-3);
i += zc*2-2;
}
else set.push(l, 0);
}
return len>>>1;
}
UZIP.F._hufTree = function(hst, tree, MAXL) {
var list=[], hl = hst.length, tl=tree.length, i=0;
for(i=0; i<tl; i+=2) { tree[i]=0; tree[i+1]=0; }
for(i=0; i<hl; i++) if(hst[i]!=0) list.push({lit:i, f:hst[i]});
var end = list.length, l2=list.slice(0);
if(end==0) return 0; // empty histogram (usually for dist)
if(end==1) { var lit=list[0].lit, l2=lit==0?1:0; tree[(lit<<1)+1]=1; tree[(l2<<1)+1]=1; return 1; }
list.sort(function(a,b){return a.f-b.f;});
var 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};
while(i1!=end-1) {
if(i0!=i1 && (i2==end || list[i0].f<list[i2].f)) { a=list[i0++]; } else { a=list[i2++]; }
if(i0!=i1 && (i2==end || list[i0].f<list[i2].f)) { b=list[i0++]; } else { b=list[i2++]; }
list[i1++]={lit:-1,f:a.f+b.f, l:a,r:b};
}
var maxl = UZIP.F.setDepth(list[i1-1], 0);
if(maxl>MAXL) { UZIP.F.restrictDepth(l2, MAXL, maxl); maxl = MAXL; }
for(i=0; i<end; i++) tree[(l2[i].lit<<1)+1]=l2[i].d;
return maxl;
}
UZIP.F.setDepth = function(t, d) {
if(t.lit!=-1) { t.d=d; return d; }
return Math.max( UZIP.F.setDepth(t.l, d+1), UZIP.F.setDepth(t.r, d+1) );
}
UZIP.F.restrictDepth = function(dps, MD, maxl) {
var i=0, bCost=1<<(maxl-MD), dbt=0;
dps.sort(function(a,b){return b.d==a.d ? a.f-b.f : b.d-a.d;});
for(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;
dbt = dbt>>>(maxl-MD);
while(dbt>0) { var od=dps[i].d; if(od<MD) { dps[i].d++; dbt-=(1<<(MD-od-1)); } else i++; }
for(; i>=0; i--) if(dps[i].d==MD && dbt<0) { dps[i].d--; dbt++; } if(dbt!=0) console.log("debt left");
}
UZIP.F._goodIndex = function(v, arr) {
var 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;
}
UZIP.F._writeLit = function(ch, ltree, out, pos) {
UZIP.F._putsF(out, pos, ltree[ch<<1]);
return pos+ltree[(ch<<1)+1];
}
UZIP.F.inflate = function(data, buf) {
var u8=Uint8Array;
if(data[0]==3 && data[1]==0) return (buf ? buf : new u8(0));
var F=UZIP.F, bitsF = F._bitsF, bitsE = F._bitsE, decodeTiny = F._decodeTiny, makeCodes = F.makeCodes, codes2map=F.codes2map, get17 = F._get17;
var U = F.U;
var noBuf = (buf==null);
if(noBuf) buf = new u8((data.length>>>2)<<3);
var BFINAL=0, BTYPE=0, HLIT=0, HDIST=0, HCLEN=0, ML=0, MD=0;
var off = 0, pos = 0;
var lmap, dmap;
while(BFINAL==0) {
BFINAL = bitsF(data, pos , 1);
BTYPE = bitsF(data, pos+1, 2); pos+=3;
//console.log(BFINAL, BTYPE);
if(BTYPE==0) {
if((pos&7)!=0) pos+=8-(pos&7);
var p8 = (pos>>>3)+4, len = data[p8-4]|(data[p8-3]<<8); //console.log(len);//bitsF(data, pos, 16),
if(noBuf) buf=UZIP.F._check(buf, off+len);
buf.set(new u8(data.buffer, data.byteOffset+p8, len), off);
//for(var i=0; i<len; i++) buf[off+i] = data[p8+i];
//for(var i=0; i<len; i++) if(buf[off+i] != data[p8+i]) throw "e";
pos = ((p8+len)<<3); off+=len; continue;
}
if(noBuf) buf=UZIP.F._check(buf, off+(1<<17)); // really not enough in many cases (but PNG and ZIP provide buffer in advance)
if(BTYPE==1) { lmap = U.flmap; dmap = U.fdmap; ML = (1<<9)-1; MD = (1<<5)-1; }
if(BTYPE==2) {
HLIT = bitsE(data, pos , 5)+257;
HDIST = bitsE(data, pos+ 5, 5)+ 1;
HCLEN = bitsE(data, pos+10, 4)+ 4; pos+=14;
var ppos = pos;
for(var i=0; i<38; i+=2) { U.itree[i]=0; U.itree[i+1]=0; }
var tl = 1;
for(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);
makeCodes(U.itree, tl);
codes2map(U.itree, tl, U.imap);
lmap = U.lmap; dmap = U.dmap;
pos = decodeTiny(U.imap, (1<<tl)-1, HLIT+HDIST, data, pos, U.ttree);
var mx0 = F._copyOut(U.ttree, 0, HLIT , U.ltree); ML = (1<<mx0)-1;
var mx1 = F._copyOut(U.ttree, HLIT, HDIST, U.dtree); MD = (1<<mx1)-1;
//var ml = decodeTiny(U.imap, (1<<tl)-1, HLIT , data, pos, U.ltree); ML = (1<<(ml>>>24))-1; pos+=(ml&0xffffff);
makeCodes(U.ltree, mx0);
codes2map(U.ltree, mx0, lmap);
//var md = decodeTiny(U.imap, (1<<tl)-1, HDIST, data, pos, U.dtree); MD = (1<<(md>>>24))-1; pos+=(md&0xffffff);
makeCodes(U.dtree, mx1);
codes2map(U.dtree, mx1, dmap);
}
//var ooff=off, opos=pos;
while(true) {
var code = lmap[get17(data, pos) & ML]; pos += code&15;
var lit = code>>>4; //U.lhst[lit]++;
if((lit>>>8)==0) { buf[off++] = lit; }
else if(lit==256) { break; }
else {
var end = off+lit-254;
if(lit>264) { var ebs = U.ldef[lit-257]; end = off + (ebs>>>3) + bitsE(data, pos, ebs&7); pos += ebs&7; }
//UZIP.F.dst[end-off]++;
var dcode = dmap[get17(data, pos) & MD]; pos += dcode&15;
var dlit = dcode>>>4;
var dbs = U.ddef[dlit], dst = (dbs>>>4) + bitsF(data, pos, dbs&15); pos += dbs&15;
//var o0 = off-dst, stp = Math.min(end-off, dst);
//if(stp>20) while(off<end) { buf.copyWithin(off, o0, o0+stp); off+=stp; } else
//if(end-dst<=off) buf.copyWithin(off, off-dst, end-dst); else
//if(dst==1) buf.fill(buf[off-1], off, end); else
if(noBuf) buf=UZIP.F._check(buf, off+(1<<17));
while(off<end) { buf[off]=buf[off++-dst]; buf[off]=buf[off++-dst]; buf[off]=buf[off++-dst]; buf[off]=buf[off++-dst]; }
off=end;
//while(off!=end) { buf[off]=buf[off++-dst]; }
}
}
//console.log(off-ooff, (pos-opos)>>>3);
}
//console.log(UZIP.F.dst);
//console.log(tlen, dlen, off-tlen+tcnt);
return buf.length==off ? buf : buf.slice(0,off);
}
UZIP.F._check=function(buf, len) {
var bl=buf.length; if(len<=bl) return buf;
var nbuf = new Uint8Array(Math.max(bl<<1,len)); nbuf.set(buf,0);
//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]; }
return nbuf;
}
UZIP.F._decodeTiny = function(lmap, LL, len, data, pos, tree) {
var bitsE = UZIP.F._bitsE, get17 = UZIP.F._get17;
var i = 0;
while(i<len) {
var code = lmap[get17(data, pos)&LL]; pos+=code&15;
var lit = code>>>4;
if(lit<=15) { tree[i]=lit; i++; }
else {
var ll = 0, n = 0;
if(lit==16) {
n = (3 + bitsE(data, pos, 2)); pos += 2; ll = tree[i-1];
}
else if(lit==17) {
n = (3 + bitsE(data, pos, 3)); pos += 3;
}
else if(lit==18) {
n = (11 + bitsE(data, pos, 7)); pos += 7;
}
var ni = i+n;
while(i<ni) { tree[i]=ll; i++; }
}
}
return pos;
}
UZIP.F._copyOut = function(src, off, len, tree) {
var mx=0, i=0, tl=tree.length>>>1;
while(i<len) { var v=src[i+off]; tree[(i<<1)]=0; tree[(i<<1)+1]=v; if(v>mx)mx=v; i++; }
while(i<tl ) { tree[(i<<1)]=0; tree[(i<<1)+1]=0; i++; }
return mx;
}
UZIP.F.makeCodes = function(tree, MAX_BITS) { // code, length
var U = UZIP.F.U;
var max_code = tree.length;
var code, bits, n, i, len;
var bl_count = U.bl_count; for(var i=0; i<=MAX_BITS; i++) bl_count[i]=0;
for(i=1; i<max_code; i+=2) bl_count[tree[i]]++;
var next_code = U.next_code; // smallest code for each length
code = 0;
bl_count[0] = 0;
for (bits = 1; bits <= MAX_BITS; bits++) {
code = (code + bl_count[bits-1]) << 1;
next_code[bits] = code;
}
for (n = 0; n < max_code; n+=2) {
len = tree[n+1];
if (len != 0) {
tree[n] = next_code[len];
next_code[len]++;
}
}
}
UZIP.F.codes2map = function(tree, MAX_BITS, map) {
var max_code = tree.length;
var U=UZIP.F.U, r15 = U.rev15;
for(var i=0; i<max_code; i+=2) if(tree[i+1]!=0) {
var lit = i>>1;
var cl = tree[i+1], val = (lit<<4)|cl; // : (0x8000 | (U.of0[lit-257]<<7) | (U.exb[lit-257]<<4) | cl);
var rest = (MAX_BITS-cl), i0 = tree[i]<<rest, i1 = i0 + (1<<rest);
//tree[i]=r15[i0]>>>(15-MAX_BITS);
while(i0!=i1) {
var p0 = r15[i0]>>>(15-MAX_BITS);
map[p0]=val; i0++;
}
}
}
UZIP.F.revCodes = function(tree, MAX_BITS) {
var r15 = UZIP.F.U.rev15, imb = 15-MAX_BITS;
for(var i=0; i<tree.length; i+=2) { var i0 = (tree[i]<<(MAX_BITS-tree[i+1])); tree[i] = r15[i0]>>>imb; }
}
// used only in deflate
UZIP.F._putsE= function(dt, pos, val ) { val = val<<(pos&7); var o=(pos>>>3); dt[o]|=val; dt[o+1]|=(val>>>8); }
UZIP.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); }
UZIP.F._bitsE= function(dt, pos, length) { return ((dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) )>>>(pos&7))&((1<<length)-1); }
UZIP.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); }
/*
UZIP.F._get9 = function(dt, pos) {
return ((dt[pos>>>3] | (dt[(pos>>>3)+1]<<8))>>>(pos&7))&511;
} */
UZIP.F._get17= function(dt, pos) { // return at least 17 meaningful bytes
return (dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16) )>>>(pos&7);
}
UZIP.F._get25= function(dt, pos) { // return at least 17 meaningful bytes
return (dt[pos>>>3] | (dt[(pos>>>3)+1]<<8) | (dt[(pos>>>3)+2]<<16) | (dt[(pos>>>3)+3]<<24) )>>>(pos&7);
}
UZIP.F.U = function(){
var u16=Uint16Array, u32=Uint32Array;
return {
next_code : new u16(16),
bl_count : new u16(16),
ordr : [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ],
of0 : [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],
exb : [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],
ldef : new u16(32),
df0 : [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],
dxb : [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],
ddef : new u32(32),
flmap: new u16( 512), fltree: [],
fdmap: new u16( 32), fdtree: [],
lmap : new u16(32768), ltree : [], ttree:[],
dmap : new u16(32768), dtree : [],
imap : new u16( 512), itree : [],
//rev9 : new u16( 512)
rev15: new u16(1<<15),
lhst : new u32(286), dhst : new u32( 30), ihst : new u32(19),
lits : new u32(15000),
strt : new u16(1<<16),
prev : new u16(1<<15)
};
} ();
(function(){
var U = UZIP.F.U;
var len = 1<<15;
for(var i=0; i<len; i++) {
var x = i;
x = (((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1));
x = (((x & 0xcccccccc) >>> 2) | ((x & 0x33333333) << 2));
x = (((x & 0xf0f0f0f0) >>> 4) | ((x & 0x0f0f0f0f) << 4));
x = (((x & 0xff00ff00) >>> 8) | ((x & 0x00ff00ff) << 8));
U.rev15[i] = (((x >>> 16) | (x << 16)))>>>17;
}
function pushV(tgt, n, sv) { while(n--!=0) tgt.push(0,sv); }
for(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]; }
pushV(U.fltree, 144, 8); pushV(U.fltree, 255-143, 9); pushV(U.fltree, 279-255, 7); pushV(U.fltree,287-279,8);
/*
var i = 0;
for(; i<=143; i++) U.fltree.push(0,8);
for(; i<=255; i++) U.fltree.push(0,9);
for(; i<=279; i++) U.fltree.push(0,7);
for(; i<=287; i++) U.fltree.push(0,8);
*/
UZIP.F.makeCodes(U.fltree, 9);
UZIP.F.codes2map(U.fltree, 9, U.flmap);
UZIP.F.revCodes (U.fltree, 9)
pushV(U.fdtree,32,5);
//for(i=0;i<32; i++) U.fdtree.push(0,5);
UZIP.F.makeCodes(U.fdtree, 5);
UZIP.F.codes2map(U.fdtree, 5, U.fdmap);
UZIP.F.revCodes (U.fdtree, 5)
pushV(U.itree,19,0); pushV(U.ltree,286,0); pushV(U.dtree,30,0); pushV(U.ttree,320,0);
/*
for(var i=0; i< 19; i++) U.itree.push(0,0);
for(var i=0; i<286; i++) U.ltree.push(0,0);
for(var i=0; i< 30; i++) U.dtree.push(0,0);
for(var i=0; i<320; i++) U.ttree.push(0,0);
*/
})()