var downloader = function() { "use strict";var __defProp = Object.defineProperty; var __typeError = (msg) => { throw TypeError(msg); }; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var __privateWrapper = (obj, member, setter, getter) => ({ set _(value) { __privateSet(obj, member, value, setter); }, get _() { return __privateGet(obj, member, getter); } }); var _head, _tail, _size; var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null; const MAX_32_BITS = 4294967295; const MAX_16_BITS = 65535; const MAX_8_BITS = 255; const COMPRESSION_METHOD_DEFLATE = 8; const COMPRESSION_METHOD_DEFLATE_64 = 9; const COMPRESSION_METHOD_STORE = 0; const COMPRESSION_METHOD_AES = 99; const LOCAL_FILE_HEADER_SIGNATURE = 67324752; const SPLIT_ZIP_FILE_SIGNATURE = 134695760; const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE; const CENTRAL_FILE_HEADER_SIGNATURE = 33639248; const END_OF_CENTRAL_DIR_SIGNATURE = 101010256; const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 101075792; const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE = 117853008; const END_OF_CENTRAL_DIR_LENGTH = 22; const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH = 20; const ZIP64_END_OF_CENTRAL_DIR_LENGTH = 56; const ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH = END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LENGTH; const DATA_DESCRIPTOR_RECORD_LENGTH = 12; const DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH = 20; const DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH = 4; const EXTRAFIELD_TYPE_ZIP64 = 1; const EXTRAFIELD_TYPE_AES = 39169; const EXTRAFIELD_TYPE_NTFS = 10; const EXTRAFIELD_TYPE_NTFS_TAG1 = 1; const EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP = 21589; const EXTRAFIELD_TYPE_UNICODE_PATH = 28789; const EXTRAFIELD_TYPE_UNICODE_COMMENT = 25461; const EXTRAFIELD_TYPE_USDZ = 6534; const EXTRAFIELD_TYPE_INFOZIP = 30837; const EXTRAFIELD_TYPE_UNIX = 30805; const BITFLAG_ENCRYPTED = 1; const BITFLAG_LEVEL = 6; const BITFLAG_LEVEL_MAX_MASK = 2; const BITFLAG_LEVEL_FAST_MASK = 4; const BITFLAG_LEVEL_SUPER_FAST_MASK = 6; const BITFLAG_DATA_DESCRIPTOR = 8; const BITFLAG_LANG_ENCODING_FLAG = 2048; const FILE_ATTR_MSDOS_DIR_MASK = 16; const FILE_ATTR_MSDOS_READONLY_MASK = 1; const FILE_ATTR_MSDOS_HIDDEN_MASK = 2; const FILE_ATTR_MSDOS_SYSTEM_MASK = 4; const FILE_ATTR_MSDOS_ARCHIVE_MASK = 32; const FILE_ATTR_UNIX_TYPE_MASK = 61440; const FILE_ATTR_UNIX_TYPE_DIR = 16384; const FILE_ATTR_UNIX_EXECUTABLE_MASK = 73; const FILE_ATTR_UNIX_DEFAULT_MASK = 420; const FILE_ATTR_UNIX_SETUID_MASK = 2048; const FILE_ATTR_UNIX_SETGID_MASK = 1024; const FILE_ATTR_UNIX_STICKY_MASK = 512; const VERSION_DEFLATE = 20; const VERSION_ZIP64 = 45; const VERSION_AES = 51; const DIRECTORY_SIGNATURE = "/"; const HEADER_SIZE = 30; const HEADER_OFFSET_SIGNATURE = 10; const HEADER_OFFSET_COMPRESSED_SIZE = 14; const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18; const MAX_DATE = new Date(2107, 11, 31); const MIN_DATE = new Date(1980, 0, 1); const UNDEFINED_VALUE = void 0; const UNDEFINED_TYPE = "undefined"; const FUNCTION_TYPE = "function"; const OBJECT_TYPE = "object"; const MINIMUM_CHUNK_SIZE = 64; let maxWorkers = 2; try { if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) { maxWorkers = navigator.hardwareConcurrency; } } catch { } const DEFAULT_CONFIGURATION = { workerURI: "./core/web-worker-wasm.js", wasmURI: "./core/streams/zlib-wasm/zlib-streams.wasm", chunkSize: 64 * 1024, maxWorkers, terminateWorkerTimeout: 5e3, useWebWorkers: true, useCompressionStream: true, CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream, DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream }; const config = Object.assign({}, DEFAULT_CONFIGURATION); function getConfiguration() { return config; } function getChunkSize(config2) { return Math.max(config2.chunkSize, MINIMUM_CHUNK_SIZE); } function configure(configuration) { const { baseURI, chunkSize, maxWorkers: maxWorkers2, terminateWorkerTimeout, useCompressionStream, useWebWorkers, CompressionStream: CompressionStream2, DecompressionStream: DecompressionStream2, CompressionStreamZlib: CompressionStreamZlib2, DecompressionStreamZlib: DecompressionStreamZlib2, workerURI, wasmURI } = configuration; setIfDefined("baseURI", baseURI); setIfDefined("wasmURI", wasmURI); setIfDefined("workerURI", workerURI); setIfDefined("chunkSize", chunkSize); setIfDefined("maxWorkers", maxWorkers2); setIfDefined("terminateWorkerTimeout", terminateWorkerTimeout); setIfDefined("useCompressionStream", useCompressionStream); setIfDefined("useWebWorkers", useWebWorkers); setIfDefined("CompressionStream", CompressionStream2); setIfDefined("DecompressionStream", DecompressionStream2); setIfDefined("CompressionStreamZlib", CompressionStreamZlib2); setIfDefined("DecompressionStreamZlib", DecompressionStreamZlib2); } function setIfDefined(propertyName, propertyValue) { if (propertyValue !== UNDEFINED_VALUE) { config[propertyName] = propertyValue; } } function t(t2) { let e; t2({ workerURI: () => (e || (e = "data:text/javascript," + encodeURIComponent('(t=>{"function"==typeof define&&define.amd?define(t):t()})(function(){"use strict";const{Array:t,Object:e,Number:n,Math:s,Error:r,Uint8Array:o,Uint16Array:i,Uint32Array:c,Int32Array:a,Map:h,DataView:f,Promise:l,TextEncoder:u,crypto:w,postMessage:p,TransformStream:d,ReadableStream:y,WritableStream:m,CompressionStream:g,DecompressionStream:S}=self,b=void 0,v="undefined",k="function",z=[];for(let t=0;256>t;t++){let e=t;for(let t=0;8>t;t++)1&e?e=e>>>1^3988292384:e>>>=1;z[t]=e}class C{constructor(t){this.t=t||-1}append(t){let e=0|this.t;for(let n=0,s=0|t.length;s>n;n++)e=e>>>8^z[255&(e^t[n])];this.t=e}get(){return~this.t}}class A extends d{constructor(){let t;const e=new C;super({transform(t,n){e.append(t),n.enqueue(t)},flush(){const n=new o(4);new f(n.buffer).setUint32(0,e.get()),t.value=n}}),t=this}}const x={concat(t,e){if(0===t.length||0===e.length)return t.concat(e);const n=t[t.length-1],s=x.o(n);return 32===s?t.concat(e):x.i(e,s,0|n,t.slice(0,t.length-1))},h(t){const e=t.length;if(0===e)return 0;const n=t[e-1];return 32*(e-1)+x.o(n)},l(t,e){if(32*t.length0&&e&&(t[n-1]=x.u(e,t[n-1]&2147483648>>e-1,1)),t},u:(t,e,n)=>32===t?e:(n?0|e:e<<32-t)+1099511627776*t,o:t=>s.round(t/1099511627776)||32,i(t,e,n,s){for(void 0===s&&(s=[]);e>=32;e-=32)s.push(n),n=0;if(0===e)return s.concat(t);for(let r=0;r>>e),n=t[r]<<32-e;const r=t.length?t[t.length-1]:0,o=x.o(r);return s.push(x.u(e+o&31,e+o>32?n:s.pop(),1)),s}},I={bytes:{p(t){const e=x.h(t)/8,n=new o(e);let s;for(let r=0;e>r;r++)3&r||(s=t[r/4]),n[r]=s>>>24,s<<=8;return n},m(t){const e=[];let n,s=0;for(n=0;n9007199254740991)throw new r("Cannot hash more than 2^53 - 1 bits");const i=new c(n);let a=0;for(let t=e.blockSize+s-(e.blockSize+s&e.blockSize-1);o>=t;t+=e.blockSize)e.R(i.subarray(16*a,16*(a+1))),a+=1;return n.splice(0,16*a),e}P(){const t=this;let e=t.C;const n=t.k;e=x.concat(e,[x.u(1,1)]);for(let t=e.length+2;15&t;t++)e.push(0);for(e.push(s.floor(t.A/4294967296)),e.push(0|t.A);e.length;)t.R(e.splice(0,16));return t.reset(),n}U(t,e,n,s){return t>19?t>39?t>59?t>79?void 0:e^n^s:e&n|e&s|n&s:e^n^s:e&n|~e&s}V(t,e){return e<>>32-t}R(e){const n=this,r=n.k,o=t(80);for(let t=0;16>t;t++)o[t]=e[t];let i=r[0],c=r[1],a=r[2],h=r[3],f=r[4];for(let t=0;79>=t;t++){16>t||(o[t]=n.V(1,o[t-3]^o[t-8]^o[t-14]^o[t-16]));const e=n.V(5,i)+n.U(t,c,a,h)+f+o[t]+n.v[s.floor(t/20)]|0;f=h,h=a,a=n.V(30,c),c=i,i=e}r[0]=r[0]+i|0,r[1]=r[1]+c|0,r[2]=r[2]+a|0,r[3]=r[3]+h|0,r[4]=r[4]+f|0}},P={getRandomValues(t){const e=new c(t.buffer),n=t=>{let e=987654321;const n=4294967295;return()=>(e=36969*(65535&e)+(e>>16)&n,(((e<<16)+(t=18e3*(65535&t)+(t>>16)&n)&n)/4294967296+.5)*(s.random()>.5?1:-1))};for(let r,o=0;onew U.M(I.bytes.m(t)),_(t,e,n,s){if(n=n||1e4,0>s||0>n)throw new r("invalid params to pbkdf2");const o=1+(s>>5)<<2;let i,c,a,h,l;const u=new ArrayBuffer(o),w=new f(u);let p=0;const d=x;for(e=I.bytes.m(e),l=1;(o||1)>p;l++){for(i=c=t.encrypt(d.concat(e,[l])),a=1;n>a;a++)for(c=t.encrypt(c),h=0;hp&&ar&&(t=(new n).update(t).P());for(let e=0;r>e;e++)s[0][e]=909522486^t[e],s[1][e]=1549556828^t[e];e.D[0].update(s[0]),e.D[1].update(s[1]),e.W=new n(e.D[0])}reset(){const t=this;t.W=new t.B(t.D[0]),t.K=!1}update(t){this.K=!0,this.W.update(t)}digest(){const t=this,e=t.W.P(),n=new t.B(t.D[1]).update(e).P();return t.reset(),n}encrypt(t){if(this.K)throw new r("encrypt on already updated hmac called!");return this.update(t),this.digest(t)}}},V=typeof w!=v&&typeof w.getRandomValues==k,M="Invalid password",_="Invalid signature",B="zipjs-abort-check-password";function D(t){return V?w.getRandomValues(t):P.getRandomValues(t)}const W=16,K={name:"PBKDF2"},E=e.assign({hash:{name:"HMAC"}},K),L=e.assign({iterations:1e3,hash:{name:"SHA-1"}},K),O=["deriveBits"],T=[8,12,16],j=[16,24,32],H=10,Z=[0,0,0,0],F=typeof w!=v,N=F&&w.subtle,q=F&&typeof N!=v,G=I.bytes,J=class{constructor(t){const e=this;e.L=[[[],[],[],[],[]],[[],[],[],[],[]]],e.L[0][0][0]||e.O();const n=e.L[0][4],s=e.L[1],o=t.length;let i,c,a,h=1;if(4!==o&&6!==o&&8!==o)throw new r("invalid aes key size");for(e.v=[c=t.slice(0),a=[]],i=o;4*o+28>i;i++){let t=c[i-1];(i%o===0||8===o&&i%o===4)&&(t=n[t>>>24]<<24^n[t>>16&255]<<16^n[t>>8&255]<<8^n[255&t],i%o===0&&(t=t<<8^t>>>24^h<<24,h=h<<1^283*(h>>7))),c[i]=c[i-o]^t}for(let t=0;i;t++,i--){const e=c[3&t?i:i-4];a[t]=4>=i||4>t?e:s[0][n[e>>>24]]^s[1][n[e>>16&255]]^s[2][n[e>>8&255]]^s[3][n[255&e]]}}encrypt(t){return this.T(t,0)}decrypt(t){return this.T(t,1)}O(){const t=this.L[0],e=this.L[1],n=t[4],s=e[4],r=[],o=[];let i,c,a,h;for(let t=0;256>t;t++)o[(r[t]=t<<1^283*(t>>7))^t]=t;for(let f=i=0;!n[f];f^=c||1,i=o[i]||1){let o=i^i<<1^i<<2^i<<3^i<<4;o=o>>8^255&o^99,n[f]=o,s[o]=f,h=r[a=r[c=r[f]]];let l=16843009*h^65537*a^257*c^16843008*f,u=257*r[o]^16843008*o;for(let n=0;4>n;n++)t[n][f]=u=u<<24^u>>>8,e[n][o]=l=l<<24^l>>>8}for(let n=0;5>n;n++)t[n]=t[n].slice(0),e[n]=e[n].slice(0)}T(t,e){if(4!==t.length)throw new r("invalid aes block size");const n=this.v[e],s=n.length/4-2,o=[0,0,0,0],i=this.L[e],c=i[0],a=i[1],h=i[2],f=i[3],l=i[4];let u,w,p,d=t[0]^n[0],y=t[e?3:1]^n[1],m=t[2]^n[2],g=t[e?1:3]^n[3],S=4;for(let t=0;s>t;t++)u=c[d>>>24]^a[y>>16&255]^h[m>>8&255]^f[255&g]^n[S],w=c[y>>>24]^a[m>>16&255]^h[g>>8&255]^f[255&d]^n[S+1],p=c[m>>>24]^a[g>>16&255]^h[d>>8&255]^f[255&y]^n[S+2],g=c[g>>>24]^a[d>>16&255]^h[y>>8&255]^f[255&m]^n[S+3],S+=4,d=u,y=w,m=p;for(let t=0;4>t;t++)o[e?3&-t:t]=l[d>>>24]<<24^l[y>>16&255]<<16^l[m>>8&255]<<8^l[255&g]^n[S++],u=d,d=y,y=m,m=g,g=u;return o}},Q=class{constructor(t,e){this.j=t,this.H=e,this.Z=e}reset(){this.Z=this.H}update(t){return this.F(this.j,t,this.Z)}N(t){if(255&~(t>>24))t+=1<<24;else{let e=t>>16&255,n=t>>8&255,s=255&t;255===e?(e=0,255===n?(n=0,255===s?s=0:++s):++n):++e,t=0,t+=e<<16,t+=n<<8,t+=s}return t}q(t){0===(t[0]=this.N(t[0]))&&(t[1]=this.N(t[1]))}F(t,e,n){let s;if(!(s=e.length))return[];const r=x.h(e);for(let r=0;s>r;r+=4){this.q(n);const s=t.encrypt(n);e[r]^=s[0],e[r+1]^=s[1],e[r+2]^=s[2],e[r+3]^=s[3]}return x.l(e,r)}},X=U.M;let Y=F&&q&&typeof N.importKey==k,$=F&&q&&typeof N.deriveBits==k;class tt extends d{constructor({password:t,rawPassword:n,signed:s,encryptionStrength:i,checkPasswordOnly:c}){super({start(){e.assign(this,{ready:new l(t=>this.G=t),password:rt(t,n),signed:s,J:i-1,pending:new o})},async transform(t,e){const n=this,{password:s,J:i,G:a,ready:h}=n;s?(await(async(t,e,n,s)=>{const o=await st(t,e,n,it(s,0,T[e])),i=it(s,T[e]);if(o[0]!=i[0]||o[1]!=i[1])throw new r(M)})(n,i,s,it(t,0,T[i]+2)),t=it(t,T[i]+2),c?e.error(new r(B)):a()):await h;const f=new o(t.length-H-(t.length-H)%W);e.enqueue(nt(n,t,f,0,H,!0))},async flush(t){const{signed:e,X:n,Y:s,pending:i,ready:c}=this;if(s&&n){await c;const a=it(i,0,i.length-H),h=it(i,i.length-H);let f=new o;if(a.length){const t=at(G,a);s.update(t);const e=n.update(t);f=ct(G,e)}if(e){const t=it(ct(G,s.digest()),0,H);for(let e=0;H>e;e++)if(t[e]!=h[e])throw new r(_)}t.enqueue(f)}}})}}class et extends d{constructor({password:t,rawPassword:n,encryptionStrength:s}){let r;super({start(){e.assign(this,{ready:new l(t=>this.G=t),password:rt(t,n),J:s-1,pending:new o})},async transform(t,e){const n=this,{password:s,J:r,G:i,ready:c}=n;let a=new o;s?(a=await(async(t,e,n)=>{const s=D(new o(T[e]));return ot(s,await st(t,e,n,s))})(n,r,s),i()):await c;const h=new o(a.length+t.length-t.length%W);h.set(a,0),e.enqueue(nt(n,t,h,a.length,0))},async flush(t){const{X:e,Y:n,pending:s,ready:i}=this;if(n&&e){await i;let c=new o;if(s.length){const t=e.update(at(G,s));n.update(t),c=ct(G,t)}r.signature=ct(G,n.digest()).slice(0,H),t.enqueue(ot(c,r.signature))}}}),r=this}}function nt(t,e,n,s,r,i){const{X:c,Y:a,pending:h}=t,f=e.length-r;let l;for(h.length&&(e=ot(h,e),n=((t,e)=>{if(e&&e>t.length){const n=t;(t=new o(e)).set(n,0)}return t})(n,f-f%W)),l=0;f-W>=l;l+=W){const t=at(G,it(e,l,l+W));i&&a.update(t);const r=c.update(t);i||a.update(r),n.set(ct(G,r),l+s)}return t.pending=it(e,l),n}async function st(n,s,r,i){n.password=null;const c=await(async(t,e,n,s,r)=>{if(!Y)return U.importKey(e);try{return await N.importKey("raw",e,n,!1,r)}catch{return Y=!1,U.importKey(e)}})(0,r,E,0,O),a=await(async(t,e,n)=>{if(!$)return U._(e,t.salt,L.iterations,n);try{return await N.deriveBits(t,e,n)}catch{return $=!1,U._(e,t.salt,L.iterations,n)}})(e.assign({salt:i},L),c,8*(2*j[s]+2)),h=new o(a),f=at(G,it(h,0,j[s])),l=at(G,it(h,j[s],2*j[s])),u=it(h,2*j[s]);return e.assign(n,{keys:{key:f,$:l,passwordVerification:u},X:new Q(new J(f),t.from(Z)),Y:new X(l)}),u}function rt(t,e){return e===b?(t=>{if(typeof u==v){const e=new o((t=unescape(encodeURIComponent(t))).length);for(let n=0;n>>24]),o=~t.et.get(),t.keys=[n,r,o]}function dt(t){const e=2|t.keys[2];return yt(s.imul(e,1^e)>>>8)}function yt(t){return 255&t}function mt(t){return 4294967295&t}class gt extends d{constructor(t,{chunkSize:e,nt:n,CompressionStream:s}){super({});const{compressed:r,encrypted:o,useCompressionStream:i,zipCrypto:c,signed:a,level:h}=t,l=this;let u,w,p=super.readable;o&&!c||!a||(u=new A,p=kt(p,u)),r&&(p=vt(p,i,{level:h,chunkSize:e},s,n,s)),o&&(c?p=kt(p,new ft(t)):(w=new et(t),p=kt(p,w))),bt(l,p,()=>{let t;o&&!c&&(t=w.signature),o&&!c||!a||(t=new f(u.value.buffer).getUint32(0)),l.signature=t})}}class St extends d{constructor(t,{chunkSize:e,st:n,DecompressionStream:s}){super({});const{zipCrypto:o,encrypted:i,signed:c,signature:a,compressed:h,useCompressionStream:l,rt:u}=t;let w,p,d=super.readable;i&&(o?d=kt(d,new ht(t)):(p=new tt(t),d=kt(d,p))),h&&(d=vt(d,l,{chunkSize:e,rt:u},s,n,s)),i&&!o||!c||(w=new A,d=kt(d,w)),bt(this,d,()=>{if((!i||o)&&c){const t=new f(w.value.buffer);if(a!=t.getUint32(0,!1))throw new r(_)}})}}function bt(t,n,s){n=kt(n,new d({flush:s})),e.defineProperty(t,"readable",{get:()=>n})}function vt(t,e,n,s,r,o){const i=e&&s?s:r||o,c=n.rt?"deflate64-raw":"deflate-raw";try{t=kt(t,new i(c,n))}catch(s){if(!e)throw s;if(r)t=kt(t,new r(c,n));else{if(!o)throw s;t=kt(t,new o(c,n))}}return t}function kt(t,e){return t.pipeThrough(e)}const zt="data",Ct="close";class At extends d{constructor(t,n){super({});const s=this,{codecType:o}=t;let i;o.startsWith("deflate")?i=gt:o.startsWith("inflate")&&(i=St),s.outputSize=0;let c=0;const a=new i(t,n),h=super.readable,f=new d({transform(t,e){t&&t.length&&(c+=t.length,e.enqueue(t))},flush(){e.assign(s,{inputSize:c})}}),l=new d({transform(e,n){if(e&&e.length&&(n.enqueue(e),s.outputSize+=e.length,t.outputSize!==b&&s.outputSize>t.outputSize))throw new r("Invalid uncompressed size")},flush(){const{signature:t}=a;e.assign(s,{signature:t,inputSize:c})}});e.defineProperty(s,"readable",{get:()=>h.pipeThrough(f).pipeThrough(a).pipeThrough(l)})}}class xt extends d{constructor(t){let e;super({transform:function n(s,r){if(e){const t=new o(e.length+s.length);t.set(e),t.set(s,e.length),s=t,e=null}s.length>t?(r.enqueue(s.slice(0,t)),n(s.slice(t),r)):e=s},flush(t){e&&e.length&&t.enqueue(e)}})}}const It=new h,Rt=new h;let Pt,Ut,Vt,Mt,_t,Bt=0;async function Dt(t){try{const{options:e,config:s}=t;if(!e.useCompressionStream)try{await self.initModule(t.config)}catch{e.useCompressionStream=!0}s.CompressionStream=self.CompressionStream,s.DecompressionStream=self.DecompressionStream;const r={highWaterMark:1},o=t.readable||new y({async pull(t){const e=new l(t=>It.set(Bt,t));Wt({type:"pull",messageId:Bt}),Bt=(Bt+1)%n.MAX_SAFE_INTEGER;const{value:s,done:r}=await e;t.enqueue(s),r&&t.close()}},r),i=t.writable||new m({async write(t){let e;const s=new l(t=>e=t);Rt.set(Bt,e),Wt({type:zt,value:t,messageId:Bt}),Bt=(Bt+1)%n.MAX_SAFE_INTEGER,await s}},r),c=new At(e,s);Pt=new AbortController;const{signal:a}=Pt;await o.pipeThrough(c).pipeThrough(new xt(s.chunkSize)).pipeTo(i,{signal:a,preventClose:!0,preventAbort:!0}),await i.getWriter().close();const{signature:h,inputSize:f,outputSize:u}=c;Wt({type:Ct,result:{signature:h,inputSize:f,outputSize:u}})}catch(t){t.outputSize=0,Kt(t)}}function Wt(t){let{value:e}=t;if(e)if(e.length)try{e=new o(e),t.value=e.buffer,p(t,[t.value])}catch{p(t)}else p(t);else p(t)}function Kt(t=new r("Unknown error")){const{message:e,stack:n,code:s,name:o,outputSize:i}=t;p({error:{message:e,stack:n,code:s,name:o,outputSize:i}})}function Et(t,e,n={}){const i="number"==typeof n.level?n.level:-1,c="number"==typeof n.ot?n.ot:65536,a="number"==typeof n.it?n.it:65536;return new d({start(){let n;if(this.ct=Vt(c),this.in=Vt(a),this.it=a,this.ht=new o(c),t?(this.ft=Ut.deflate_process,this.lt=Ut.deflate_last_consumed,this.ut=Ut.deflate_end,this.wt=Ut.deflate_new(),n="gzip"===e?Ut.deflate_init_gzip(this.wt,i):"deflate-raw"===e?Ut.deflate_init_raw(this.wt,i):Ut.deflate_init(this.wt,i)):"deflate64-raw"===e?(this.ft=Ut.inflate9_process,this.lt=Ut.inflate9_last_consumed,this.ut=Ut.inflate9_end,this.wt=Ut.inflate9_new(),n=Ut.inflate9_init_raw(this.wt)):(this.ft=Ut.inflate_process,this.lt=Ut.inflate_last_consumed,this.ut=Ut.inflate_end,this.wt=Ut.inflate_new(),n="deflate-raw"===e?Ut.inflate_init_raw(this.wt):"gzip"===e?Ut.inflate_init_gzip(this.wt):Ut.inflate_init(this.wt)),0!==n)throw new r("init failed:"+n)},transform(e,n){try{const i=e,a=new o(_t.buffer),h=this.ft,f=this.lt,l=this.ct,u=this.ht;let w=0;for(;w=e||(this.in&&Mt&&Mt(this.in),this.in=Vt(e),this.it=e),a.set(i.subarray(w,w+e),this.in);const o=h(this.wt,this.in,e,l,c,0),p=16777215&o;if(p&&(u.set(a.subarray(l,l+p),0),n.enqueue(u.slice(0,p))),!t){const t=o>>24&255,e=128&t?t-256:t;if(0>e)throw new r("process error:"+e)}const d=f(this.wt);if(0===d)break;w+=d}}catch(t){this.ut&&this.wt&&this.ut(this.wt),this.in&&Mt&&Mt(this.in),this.ct&&Mt&&Mt(this.ct),n.error(t)}},flush(e){try{const n=new o(_t.buffer),s=this.ft,i=this.ct,a=this.ht;for(;;){const o=s(this.wt,0,0,i,c,4),h=16777215&o,f=o>>24&255;if(!t){const t=128&f?f-256:f;if(0>t)throw new r("process error:"+t)}if(h&&(a.set(n.subarray(i,i+h),0),e.enqueue(a.slice(0,h))),1===f||0===h)break}}catch(t){e.error(t)}finally{if(this.ut&&this.wt){const t=this.ut(this.wt);0!==t&&e.error(new r("end error:"+t))}this.in&&Mt&&Mt(this.in),this.ct&&Mt&&Mt(this.ct)}}})}addEventListener("message",({data:t})=>{const{type:e,messageId:n,value:s,done:r}=t;try{if("start"==e&&Dt(t),e==zt){const t=It.get(n);It.delete(n),t({value:new o(s),done:r})}if("ack"==e){const t=Rt.get(n);Rt.delete(n),t()}e==Ct&&Pt.abort()}catch(t){Kt(t)}});class Lt{constructor(t="deflate",e){return Et(!0,t,e)}}class Ot{constructor(t="deflate",e){return Et(!1,t,e)}}let Tt=!1;self.initModule=async t=>{try{const e=await(async(t,{baseURI:e})=>{if(!Tt){let n,s;try{try{s=new URL(t,e)}catch{}const r=await fetch(s);n=await r.arrayBuffer()}catch(e){if(!t.startsWith("data:application/wasm;base64,"))throw e;n=(t=>{const e=t.split(",")[1],n=atob(e),s=n.length,r=new o(s);for(let t=0;s>t;++t)r[t]=n.charCodeAt(t);return r.buffer})(t)}(t=>{if(Ut=t,({malloc:Vt,free:Mt,memory:_t}=Ut),"function"!=typeof Vt||"function"!=typeof Mt||!_t)throw Ut=Vt=Mt=_t=null,new r("Invalid WASM module")})((await WebAssembly.instantiate(n)).instance.exports),Tt=!0}})(t.wasmURI,t);return t.nt=Lt,t.st=Ot,e}catch{}}});\n')), e) }); } const table$1 = []; for (let i = 0; i < 256; i++) { let t2 = i; for (let j = 0; j < 8; j++) { if (t2 & 1) { t2 = t2 >>> 1 ^ 3988292384; } else { t2 = t2 >>> 1; } } table$1[i] = t2; } class Crc32 { constructor(crc) { this.crc = crc || -1; } append(data) { let crc = this.crc | 0; for (let offset = 0, length = data.length | 0; offset < length; offset++) { crc = crc >>> 8 ^ table$1[(crc ^ data[offset]) & 255]; } this.crc = crc; } get() { return ~this.crc; } } class Crc32Stream extends TransformStream { constructor() { let stream; const crc32 = new Crc32(); super({ transform(chunk, controller) { crc32.append(chunk); controller.enqueue(chunk); }, flush() { const value = new Uint8Array(4); const dataView = new DataView(value.buffer); dataView.setUint32(0, crc32.get()); stream.value = value; } }); stream = this; } } function encodeText(value) { if (typeof TextEncoder == UNDEFINED_TYPE) { value = unescape(encodeURIComponent(value)); const result = new Uint8Array(value.length); for (let i = 0; i < result.length; i++) { result[i] = value.charCodeAt(i); } return result; } else { return new TextEncoder().encode(value); } } const bitArray = { /** * Concatenate two bit arrays. * @param {bitArray} a1 The first array. * @param {bitArray} a2 The second array. * @return {bitArray} The concatenation of a1 and a2. */ concat(a1, a2) { if (a1.length === 0 || a2.length === 0) { return a1.concat(a2); } const last = a1[a1.length - 1], shift = bitArray.getPartial(last); if (shift === 32) { return a1.concat(a2); } else { return bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1)); } }, /** * Find the length of an array of bits. * @param {bitArray} a The array. * @return {Number} The length of a, in bits. */ bitLength(a) { const l = a.length; if (l === 0) { return 0; } const x = a[l - 1]; return (l - 1) * 32 + bitArray.getPartial(x); }, /** * Truncate an array. * @param {bitArray} a The array. * @param {Number} len The length to truncate to, in bits. * @return {bitArray} A new array, truncated to len bits. */ clamp(a, len) { if (a.length * 32 < len) { return a; } a = a.slice(0, Math.ceil(len / 32)); const l = a.length; len = len & 31; if (l > 0 && len) { a[l - 1] = bitArray.partial(len, a[l - 1] & 2147483648 >> len - 1, 1); } return a; }, /** * Make a partial word for a bit array. * @param {Number} len The number of bits in the word. * @param {Number} x The bits. * @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side. * @return {Number} The partial word. */ partial(len, x, _end) { if (len === 32) { return x; } return (_end ? x | 0 : x << 32 - len) + len * 1099511627776; }, /** * Get the number of bits used by a partial word. * @param {Number} x The partial word. * @return {Number} The number of bits used by the partial word. */ getPartial(x) { return Math.round(x / 1099511627776) || 32; }, /** Shift an array right. * @param {bitArray} a The array to shift. * @param {Number} shift The number of bits to shift. * @param {Number} [carry=0] A byte to carry in * @param {bitArray} [out=[]] An array to prepend to the output. * @private */ _shiftRight(a, shift, carry, out) { if (out === void 0) { out = []; } for (; shift >= 32; shift -= 32) { out.push(carry); carry = 0; } if (shift === 0) { return out.concat(a); } for (let i = 0; i < a.length; i++) { out.push(carry | a[i] >>> shift); carry = a[i] << 32 - shift; } const last2 = a.length ? a[a.length - 1] : 0; const shift2 = bitArray.getPartial(last2); out.push(bitArray.partial(shift + shift2 & 31, shift + shift2 > 32 ? carry : out.pop(), 1)); return out; } }; const codec = { bytes: { /** Convert from a bitArray to an array of bytes. */ fromBits(arr) { const bl = bitArray.bitLength(arr); const byteLength = bl / 8; const out = new Uint8Array(byteLength); let tmp; for (let i = 0; i < byteLength; i++) { if ((i & 3) === 0) { tmp = arr[i / 4]; } out[i] = tmp >>> 24; tmp <<= 8; } return out; }, /** Convert from an array of bytes to a bitArray. */ toBits(bytes) { const out = []; let i; let tmp = 0; for (i = 0; i < bytes.length; i++) { tmp = tmp << 8 | bytes[i]; if ((i & 3) === 3) { out.push(tmp); tmp = 0; } } if (i & 3) { out.push(bitArray.partial(8 * (i & 3), tmp)); } return out; } } }; const hash = {}; hash.sha1 = class { constructor(hash2) { const sha1 = this; sha1.blockSize = 512; sha1._init = [1732584193, 4023233417, 2562383102, 271733878, 3285377520]; sha1._key = [1518500249, 1859775393, 2400959708, 3395469782]; if (hash2) { sha1._h = hash2._h.slice(0); sha1._buffer = hash2._buffer.slice(0); sha1._length = hash2._length; } else { sha1.reset(); } } /** * Reset the hash state. * @return this */ reset() { const sha1 = this; sha1._h = sha1._init.slice(0); sha1._buffer = []; sha1._length = 0; return sha1; } /** * Input several words to the hash. * @param {bitArray|String} data the data to hash. * @return this */ update(data) { const sha1 = this; if (typeof data === "string") { data = codec.utf8String.toBits(data); } const b = sha1._buffer = bitArray.concat(sha1._buffer, data); const ol = sha1._length; const nl = sha1._length = ol + bitArray.bitLength(data); if (nl > 9007199254740991) { throw new Error("Cannot hash more than 2^53 - 1 bits"); } const c = new Uint32Array(b); let j = 0; for (let i = sha1.blockSize + ol - (sha1.blockSize + ol & sha1.blockSize - 1); i <= nl; i += sha1.blockSize) { sha1._block(c.subarray(16 * j, 16 * (j + 1))); j += 1; } b.splice(0, 16 * j); return sha1; } /** * Complete hashing and output the hash value. * @return {bitArray} The hash value, an array of 5 big-endian words. TODO */ finalize() { const sha1 = this; let b = sha1._buffer; const h = sha1._h; b = bitArray.concat(b, [bitArray.partial(1, 1)]); for (let i = b.length + 2; i & 15; i++) { b.push(0); } b.push(Math.floor(sha1._length / 4294967296)); b.push(sha1._length | 0); while (b.length) { sha1._block(b.splice(0, 16)); } sha1.reset(); return h; } /** * The SHA-1 logical functions f(0), f(1), ..., f(79). * @private */ _f(t2, b, c, d) { if (t2 <= 19) { return b & c | ~b & d; } else if (t2 <= 39) { return b ^ c ^ d; } else if (t2 <= 59) { return b & c | b & d | c & d; } else if (t2 <= 79) { return b ^ c ^ d; } } /** * Circular left-shift operator. * @private */ _S(n, x) { return x << n | x >>> 32 - n; } /** * Perform one cycle of SHA-1. * @param {Uint32Array|bitArray} words one block of words. * @private */ _block(words) { const sha1 = this; const h = sha1._h; const w = Array(80); for (let j = 0; j < 16; j++) { w[j] = words[j]; } let a = h[0]; let b = h[1]; let c = h[2]; let d = h[3]; let e = h[4]; for (let t2 = 0; t2 <= 79; t2++) { if (t2 >= 16) { w[t2] = sha1._S(1, w[t2 - 3] ^ w[t2 - 8] ^ w[t2 - 14] ^ w[t2 - 16]); } const tmp = sha1._S(5, a) + sha1._f(t2, b, c, d) + e + w[t2] + sha1._key[Math.floor(t2 / 20)] | 0; e = d; d = c; c = sha1._S(30, b); b = a; a = tmp; } h[0] = h[0] + a | 0; h[1] = h[1] + b | 0; h[2] = h[2] + c | 0; h[3] = h[3] + d | 0; h[4] = h[4] + e | 0; } }; const cipher = {}; cipher.aes = class { constructor(key) { const aes = this; aes._tables = [[[], [], [], [], []], [[], [], [], [], []]]; if (!aes._tables[0][0][0]) { aes._precompute(); } const sbox = aes._tables[0][4]; const decTable = aes._tables[1]; const keyLen = key.length; let i, encKey, decKey, rcon = 1; if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) { throw new Error("invalid aes key size"); } aes._key = [encKey = key.slice(0), decKey = []]; for (i = keyLen; i < 4 * keyLen + 28; i++) { let tmp = encKey[i - 1]; if (i % keyLen === 0 || keyLen === 8 && i % keyLen === 4) { tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255]; if (i % keyLen === 0) { tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24; rcon = rcon << 1 ^ (rcon >> 7) * 283; } } encKey[i] = encKey[i - keyLen] ^ tmp; } for (let j = 0; i; j++, i--) { const tmp = encKey[j & 3 ? i : i - 4]; if (i <= 4 || j < 4) { decKey[j] = tmp; } else { decKey[j] = decTable[0][sbox[tmp >>> 24]] ^ decTable[1][sbox[tmp >> 16 & 255]] ^ decTable[2][sbox[tmp >> 8 & 255]] ^ decTable[3][sbox[tmp & 255]]; } } } // public /* Something like this might appear here eventually name: "AES", blockSize: 4, keySizes: [4,6,8], */ /** * Encrypt an array of 4 big-endian words. * @param {Array} data The plaintext. * @return {Array} The ciphertext. */ encrypt(data) { return this._crypt(data, 0); } /** * Decrypt an array of 4 big-endian words. * @param {Array} data The ciphertext. * @return {Array} The plaintext. */ decrypt(data) { return this._crypt(data, 1); } /** * Expand the S-box tables. * * @private */ _precompute() { const encTable = this._tables[0]; const decTable = this._tables[1]; const sbox = encTable[4]; const sboxInv = decTable[4]; const d = []; const th = []; let xInv, x2, x4, x8; for (let i = 0; i < 256; i++) { th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i; } for (let x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) { let s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4; s = s >> 8 ^ s & 255 ^ 99; sbox[x] = s; sboxInv[s] = x; x8 = d[x4 = d[x2 = d[x]]]; let tDec = x8 * 16843009 ^ x4 * 65537 ^ x2 * 257 ^ x * 16843008; let tEnc = d[s] * 257 ^ s * 16843008; for (let i = 0; i < 4; i++) { encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8; decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8; } } for (let i = 0; i < 5; i++) { encTable[i] = encTable[i].slice(0); decTable[i] = decTable[i].slice(0); } } /** * Encryption and decryption core. * @param {Array} input Four words to be encrypted or decrypted. * @param dir The direction, 0 for encrypt and 1 for decrypt. * @return {Array} The four encrypted or decrypted words. * @private */ _crypt(input, dir) { if (input.length !== 4) { throw new Error("invalid aes block size"); } const key = this._key[dir]; const nInnerRounds = key.length / 4 - 2; const out = [0, 0, 0, 0]; const table2 = this._tables[dir]; const t0 = table2[0]; const t1 = table2[1]; const t2 = table2[2]; const t3 = table2[3]; const sbox = table2[4]; let a = input[0] ^ key[0]; let b = input[dir ? 3 : 1] ^ key[1]; let c = input[2] ^ key[2]; let d = input[dir ? 1 : 3] ^ key[3]; let kIndex = 4; let a2, b2, c2; for (let i = 0; i < nInnerRounds; i++) { a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex]; b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1]; c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2]; d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3]; kIndex += 4; a = a2; b = b2; c = c2; } for (let i = 0; i < 4; i++) { out[dir ? 3 & -i : i] = sbox[a >>> 24] << 24 ^ sbox[b >> 16 & 255] << 16 ^ sbox[c >> 8 & 255] << 8 ^ sbox[d & 255] ^ key[kIndex++]; a2 = a; a = b; b = c; c = d; d = a2; } return out; } }; const random = { /** * Generate random words with pure js, cryptographically not as strong & safe as native implementation. * @param {TypedArray} typedArray The array to fill. * @return {TypedArray} The random values. */ getRandomValues(typedArray) { const words = new Uint32Array(typedArray.buffer); const r = (m_w) => { let m_z = 987654321; const mask = 4294967295; return function() { m_z = 36969 * (m_z & 65535) + (m_z >> 16) & mask; m_w = 18e3 * (m_w & 65535) + (m_w >> 16) & mask; const result = ((m_z << 16) + m_w & mask) / 4294967296 + 0.5; return result * (Math.random() > 0.5 ? 1 : -1); }; }; for (let i = 0, rcache; i < typedArray.length; i += 4) { const _r = r((rcache || Math.random()) * 4294967296); rcache = _r() * 987654071; words[i / 4] = _r() * 4294967296 | 0; } return typedArray; } }; const mode = {}; mode.ctrGladman = class { constructor(prf, iv) { this._prf = prf; this._initIv = iv; this._iv = iv; } reset() { this._iv = this._initIv; } /** Input some data to calculate. * @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last. */ update(data) { return this.calculate(this._prf, data, this._iv); } incWord(word) { if ((word >> 24 & 255) === 255) { let b1 = word >> 16 & 255; let b2 = word >> 8 & 255; let b3 = word & 255; if (b1 === 255) { b1 = 0; if (b2 === 255) { b2 = 0; if (b3 === 255) { b3 = 0; } else { ++b3; } } else { ++b2; } } else { ++b1; } word = 0; word += b1 << 16; word += b2 << 8; word += b3; } else { word += 1 << 24; } return word; } incCounter(counter) { if ((counter[0] = this.incWord(counter[0])) === 0) { counter[1] = this.incWord(counter[1]); } } calculate(prf, data, iv) { let l; if (!(l = data.length)) { return []; } const bl = bitArray.bitLength(data); for (let i = 0; i < l; i += 4) { this.incCounter(iv); const e = prf.encrypt(iv); data[i] ^= e[0]; data[i + 1] ^= e[1]; data[i + 2] ^= e[2]; data[i + 3] ^= e[3]; } return bitArray.clamp(data, bl); } }; const misc = { importKey(password) { return new misc.hmacSha1(codec.bytes.toBits(password)); }, pbkdf2(prf, salt, count, length) { count = count || 1e4; if (length < 0 || count < 0) { throw new Error("invalid params to pbkdf2"); } const byteLength = (length >> 5) + 1 << 2; let u, ui, i, j, k; const arrayBuffer = new ArrayBuffer(byteLength); const out = new DataView(arrayBuffer); let outLength = 0; const b = bitArray; salt = codec.bytes.toBits(salt); for (k = 1; outLength < (byteLength || 1); k++) { u = ui = prf.encrypt(b.concat(salt, [k])); for (i = 1; i < count; i++) { ui = prf.encrypt(ui); for (j = 0; j < ui.length; j++) { u[j] ^= ui[j]; } } for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) { out.setInt32(outLength, u[i]); outLength += 4; } } return arrayBuffer.slice(0, length / 8); } }; misc.hmacSha1 = class { constructor(key) { const hmac = this; const Hash = hmac._hash = hash.sha1; const exKey = [[], []]; hmac._baseHash = [new Hash(), new Hash()]; const bs = hmac._baseHash[0].blockSize / 32; if (key.length > bs) { key = new Hash().update(key).finalize(); } for (let i = 0; i < bs; i++) { exKey[0][i] = key[i] ^ 909522486; exKey[1][i] = key[i] ^ 1549556828; } hmac._baseHash[0].update(exKey[0]); hmac._baseHash[1].update(exKey[1]); hmac._resultHash = new Hash(hmac._baseHash[0]); } reset() { const hmac = this; hmac._resultHash = new hmac._hash(hmac._baseHash[0]); hmac._updated = false; } update(data) { const hmac = this; hmac._updated = true; hmac._resultHash.update(data); } digest() { const hmac = this; const w = hmac._resultHash.finalize(); const result = new hmac._hash(hmac._baseHash[1]).update(w).finalize(); hmac.reset(); return result; } encrypt(data) { if (!this._updated) { this.update(data); return this.digest(data); } else { throw new Error("encrypt on already updated hmac called!"); } } }; const GET_RANDOM_VALUES_SUPPORTED = typeof crypto != UNDEFINED_TYPE && typeof crypto.getRandomValues == FUNCTION_TYPE; const ERR_INVALID_PASSWORD = "Invalid password"; const ERR_INVALID_SIGNATURE = "Invalid signature"; const ERR_ABORT_CHECK_PASSWORD = "zipjs-abort-check-password"; function getRandomValues(array) { if (GET_RANDOM_VALUES_SUPPORTED) { return crypto.getRandomValues(array); } else { return random.getRandomValues(array); } } const BLOCK_LENGTH = 16; const RAW_FORMAT = "raw"; const PBKDF2_ALGORITHM = { name: "PBKDF2" }; const HASH_ALGORITHM = { name: "HMAC" }; const HASH_FUNCTION = "SHA-1"; const BASE_KEY_ALGORITHM = Object.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM); const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: 1e3, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM); const DERIVED_BITS_USAGE = ["deriveBits"]; const SALT_LENGTH = [8, 12, 16]; const KEY_LENGTH = [16, 24, 32]; const SIGNATURE_LENGTH = 10; const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0]; const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE; const subtle = CRYPTO_API_SUPPORTED && crypto.subtle; const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE; const codecBytes = codec.bytes; const Aes = cipher.aes; const CtrGladman = mode.ctrGladman; const HmacSha1 = misc.hmacSha1; let IMPORT_KEY_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE; let DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.deriveBits == FUNCTION_TYPE; class AESDecryptionStream extends TransformStream { constructor({ password, rawPassword, signed, encryptionStrength, checkPasswordOnly }) { super({ start() { Object.assign(this, { ready: new Promise((resolve) => this.resolveReady = resolve), password: encodePassword(password, rawPassword), signed, strength: encryptionStrength - 1, pending: new Uint8Array() }); }, async transform(chunk, controller) { const aesCrypto = this; const { password: password2, strength, resolveReady, ready } = aesCrypto; if (password2) { await createDecryptionKeys(aesCrypto, strength, password2, subarray(chunk, 0, SALT_LENGTH[strength] + 2)); chunk = subarray(chunk, SALT_LENGTH[strength] + 2); if (checkPasswordOnly) { controller.error(new Error(ERR_ABORT_CHECK_PASSWORD)); } else { resolveReady(); } } else { await ready; } const output = new Uint8Array(chunk.length - SIGNATURE_LENGTH - (chunk.length - SIGNATURE_LENGTH) % BLOCK_LENGTH); controller.enqueue(append(aesCrypto, chunk, output, 0, SIGNATURE_LENGTH, true)); }, async flush(controller) { const { signed: signed2, ctr, hmac, pending, ready } = this; if (hmac && ctr) { await ready; const chunkToDecrypt = subarray(pending, 0, pending.length - SIGNATURE_LENGTH); const originalSignature = subarray(pending, pending.length - SIGNATURE_LENGTH); let decryptedChunkArray = new Uint8Array(); if (chunkToDecrypt.length) { const encryptedChunk = toBits(codecBytes, chunkToDecrypt); hmac.update(encryptedChunk); const decryptedChunk = ctr.update(encryptedChunk); decryptedChunkArray = fromBits(codecBytes, decryptedChunk); } if (signed2) { const signature = subarray(fromBits(codecBytes, hmac.digest()), 0, SIGNATURE_LENGTH); for (let indexSignature = 0; indexSignature < SIGNATURE_LENGTH; indexSignature++) { if (signature[indexSignature] != originalSignature[indexSignature]) { throw new Error(ERR_INVALID_SIGNATURE); } } } controller.enqueue(decryptedChunkArray); } } }); } } class AESEncryptionStream extends TransformStream { constructor({ password, rawPassword, encryptionStrength }) { let stream; super({ start() { Object.assign(this, { ready: new Promise((resolve) => this.resolveReady = resolve), password: encodePassword(password, rawPassword), strength: encryptionStrength - 1, pending: new Uint8Array() }); }, async transform(chunk, controller) { const aesCrypto = this; const { password: password2, strength, resolveReady, ready } = aesCrypto; let preamble = new Uint8Array(); if (password2) { preamble = await createEncryptionKeys(aesCrypto, strength, password2); resolveReady(); } else { await ready; } const output = new Uint8Array(preamble.length + chunk.length - chunk.length % BLOCK_LENGTH); output.set(preamble, 0); controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0)); }, async flush(controller) { const { ctr, hmac, pending, ready } = this; if (hmac && ctr) { await ready; let encryptedChunkArray = new Uint8Array(); if (pending.length) { const encryptedChunk = ctr.update(toBits(codecBytes, pending)); hmac.update(encryptedChunk); encryptedChunkArray = fromBits(codecBytes, encryptedChunk); } stream.signature = fromBits(codecBytes, hmac.digest()).slice(0, SIGNATURE_LENGTH); controller.enqueue(concat(encryptedChunkArray, stream.signature)); } } }); stream = this; } } function append(aesCrypto, input, output, paddingStart, paddingEnd, verifySignature) { const { ctr, hmac, pending } = aesCrypto; const inputLength = input.length - paddingEnd; if (pending.length) { input = concat(pending, input); output = expand(output, inputLength - inputLength % BLOCK_LENGTH); } let offset; for (offset = 0; offset <= inputLength - BLOCK_LENGTH; offset += BLOCK_LENGTH) { const inputChunk = toBits(codecBytes, subarray(input, offset, offset + BLOCK_LENGTH)); if (verifySignature) { hmac.update(inputChunk); } const outputChunk = ctr.update(inputChunk); if (!verifySignature) { hmac.update(outputChunk); } output.set(fromBits(codecBytes, outputChunk), offset + paddingStart); } aesCrypto.pending = subarray(input, offset); return output; } async function createDecryptionKeys(decrypt2, strength, password, preamble) { const passwordVerificationKey = await createKeys$1(decrypt2, strength, password, subarray(preamble, 0, SALT_LENGTH[strength])); const passwordVerification = subarray(preamble, SALT_LENGTH[strength]); if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) { throw new Error(ERR_INVALID_PASSWORD); } } async function createEncryptionKeys(encrypt2, strength, password) { const salt = getRandomValues(new Uint8Array(SALT_LENGTH[strength])); const passwordVerification = await createKeys$1(encrypt2, strength, password, salt); return concat(salt, passwordVerification); } async function createKeys$1(aesCrypto, strength, password, salt) { aesCrypto.password = null; const baseKey = await importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE); const derivedBits = await deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, 8 * (KEY_LENGTH[strength] * 2 + 2)); const compositeKey = new Uint8Array(derivedBits); const key = toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[strength])); const authentication = toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[strength], KEY_LENGTH[strength] * 2)); const passwordVerification = subarray(compositeKey, KEY_LENGTH[strength] * 2); Object.assign(aesCrypto, { keys: { key, authentication, passwordVerification }, ctr: new CtrGladman(new Aes(key), Array.from(COUNTER_DEFAULT_VALUE)), hmac: new HmacSha1(authentication) }); return passwordVerification; } async function importKey(format, password, algorithm, extractable, keyUsages) { if (IMPORT_KEY_SUPPORTED) { try { return await subtle.importKey(format, password, algorithm, extractable, keyUsages); } catch { IMPORT_KEY_SUPPORTED = false; return misc.importKey(password); } } else { return misc.importKey(password); } } async function deriveBits(algorithm, baseKey, length) { if (DERIVE_BITS_SUPPORTED) { try { return await subtle.deriveBits(algorithm, baseKey, length); } catch { DERIVE_BITS_SUPPORTED = false; return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length); } } else { return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length); } } function encodePassword(password, rawPassword) { if (rawPassword === UNDEFINED_VALUE) { return encodeText(password); } else { return rawPassword; } } function concat(leftArray, rightArray) { let array = leftArray; if (leftArray.length + rightArray.length) { array = new Uint8Array(leftArray.length + rightArray.length); array.set(leftArray, 0); array.set(rightArray, leftArray.length); } return array; } function expand(inputArray, length) { if (length && length > inputArray.length) { const array = inputArray; inputArray = new Uint8Array(length); inputArray.set(array, 0); } return inputArray; } function subarray(array, begin, end) { return array.subarray(begin, end); } function fromBits(codecBytes2, chunk) { return codecBytes2.fromBits(chunk); } function toBits(codecBytes2, chunk) { return codecBytes2.toBits(chunk); } const HEADER_LENGTH = 12; class ZipCryptoDecryptionStream extends TransformStream { constructor({ password, passwordVerification, checkPasswordOnly }) { super({ start() { Object.assign(this, { password, passwordVerification }); createKeys(this, password); }, transform(chunk, controller) { const zipCrypto = this; if (zipCrypto.password) { const decryptedHeader = decrypt(zipCrypto, chunk.subarray(0, HEADER_LENGTH)); zipCrypto.password = null; if (decryptedHeader.at(-1) != zipCrypto.passwordVerification) { throw new Error(ERR_INVALID_PASSWORD); } chunk = chunk.subarray(HEADER_LENGTH); } if (checkPasswordOnly) { controller.error(new Error(ERR_ABORT_CHECK_PASSWORD)); } else { controller.enqueue(decrypt(zipCrypto, chunk)); } } }); } } class ZipCryptoEncryptionStream extends TransformStream { constructor({ password, passwordVerification }) { super({ start() { Object.assign(this, { password, passwordVerification }); createKeys(this, password); }, transform(chunk, controller) { const zipCrypto = this; let output; let offset; if (zipCrypto.password) { zipCrypto.password = null; const header = getRandomValues(new Uint8Array(HEADER_LENGTH)); header[HEADER_LENGTH - 1] = zipCrypto.passwordVerification; output = new Uint8Array(chunk.length + header.length); output.set(encrypt(zipCrypto, header), 0); offset = HEADER_LENGTH; } else { output = new Uint8Array(chunk.length); offset = 0; } output.set(encrypt(zipCrypto, chunk), offset); controller.enqueue(output); } }); } } function decrypt(target, input) { const output = new Uint8Array(input.length); for (let index = 0; index < input.length; index++) { output[index] = getByte(target) ^ input[index]; updateKeys(target, output[index]); } return output; } function encrypt(target, input) { const output = new Uint8Array(input.length); for (let index = 0; index < input.length; index++) { output[index] = getByte(target) ^ input[index]; updateKeys(target, input[index]); } return output; } function createKeys(target, password) { const keys = [305419896, 591751049, 878082192]; Object.assign(target, { keys, crcKey0: new Crc32(keys[0]), crcKey2: new Crc32(keys[2]) }); for (let index = 0; index < password.length; index++) { updateKeys(target, password.charCodeAt(index)); } } function updateKeys(target, byte) { let [key0, key1, key2] = target.keys; target.crcKey0.append([byte]); key0 = ~target.crcKey0.get(); key1 = getInt32(Math.imul(getInt32(key1 + getInt8(key0)), 134775813) + 1); target.crcKey2.append([key1 >>> 24]); key2 = ~target.crcKey2.get(); target.keys = [key0, key1, key2]; } function getByte(target) { const temp = target.keys[2] | 2; return getInt8(Math.imul(temp, temp ^ 1) >>> 8); } function getInt8(number) { return number & 255; } function getInt32(number) { return number & 4294967295; } const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size"; const FORMAT_DEFLATE_RAW = "deflate-raw"; const FORMAT_DEFLATE64_RAW = "deflate64-raw"; class DeflateStream extends TransformStream { constructor(options, { chunkSize, CompressionStreamZlib: CompressionStreamZlib2, CompressionStream: CompressionStream2 }) { super({}); const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level } = options; const stream = this; let crc32Stream, encryptionStream; let readable = super.readable; if ((!encrypted || zipCrypto) && signed) { crc32Stream = new Crc32Stream(); readable = pipeThrough(readable, crc32Stream); } if (compressed) { readable = pipeThroughCommpressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream2, CompressionStreamZlib2, CompressionStream2); } if (encrypted) { if (zipCrypto) { readable = pipeThrough(readable, new ZipCryptoEncryptionStream(options)); } else { encryptionStream = new AESEncryptionStream(options); readable = pipeThrough(readable, encryptionStream); } } setReadable(stream, readable, () => { let signature; if (encrypted && !zipCrypto) { signature = encryptionStream.signature; } if ((!encrypted || zipCrypto) && signed) { signature = new DataView(crc32Stream.value.buffer).getUint32(0); } stream.signature = signature; }); } } class InflateStream extends TransformStream { constructor(options, { chunkSize, DecompressionStreamZlib: DecompressionStreamZlib2, DecompressionStream: DecompressionStream2 }) { super({}); const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream, deflate64 } = options; let crc32Stream, decryptionStream; let readable = super.readable; if (encrypted) { if (zipCrypto) { readable = pipeThrough(readable, new ZipCryptoDecryptionStream(options)); } else { decryptionStream = new AESDecryptionStream(options); readable = pipeThrough(readable, decryptionStream); } } if (compressed) { readable = pipeThroughCommpressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream2, DecompressionStreamZlib2, DecompressionStream2); } if ((!encrypted || zipCrypto) && signed) { crc32Stream = new Crc32Stream(); readable = pipeThrough(readable, crc32Stream); } setReadable(this, readable, () => { if ((!encrypted || zipCrypto) && signed) { const dataViewSignature = new DataView(crc32Stream.value.buffer); if (signature != dataViewSignature.getUint32(0, false)) { throw new Error(ERR_INVALID_SIGNATURE); } } }); } } function setReadable(stream, readable, flush) { readable = pipeThrough(readable, new TransformStream({ flush })); Object.defineProperty(stream, "readable", { get() { return readable; } }); } function pipeThroughCommpressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamZlib2, CompressionStream2) { const Stream2 = useCompressionStream && CompressionStreamNative ? CompressionStreamNative : CompressionStreamZlib2 || CompressionStream2; const format = options.deflate64 ? FORMAT_DEFLATE64_RAW : FORMAT_DEFLATE_RAW; try { readable = pipeThrough(readable, new Stream2(format, options)); } catch (error) { if (useCompressionStream) { if (CompressionStreamZlib2) { readable = pipeThrough(readable, new CompressionStreamZlib2(format, options)); } else if (CompressionStream2) { readable = pipeThrough(readable, new CompressionStream2(format, options)); } else { throw error; } } else { throw error; } } return readable; } function pipeThrough(readable, transformStream) { return readable.pipeThrough(transformStream); } const MESSAGE_EVENT_TYPE = "message"; const MESSAGE_START = "start"; const MESSAGE_PULL = "pull"; const MESSAGE_DATA = "data"; const MESSAGE_ACK_DATA = "ack"; const MESSAGE_CLOSE = "close"; const CODEC_DEFLATE = "deflate"; const CODEC_INFLATE = "inflate"; class CodecStream extends TransformStream { constructor(options, config2) { super({}); const codec2 = this; const { codecType } = options; let Stream2; if (codecType.startsWith(CODEC_DEFLATE)) { Stream2 = DeflateStream; } else if (codecType.startsWith(CODEC_INFLATE)) { Stream2 = InflateStream; } codec2.outputSize = 0; let inputSize = 0; const stream = new Stream2(options, config2); const readable = super.readable; const inputSizeStream = new TransformStream({ transform(chunk, controller) { if (chunk && chunk.length) { inputSize += chunk.length; controller.enqueue(chunk); } }, flush() { Object.assign(codec2, { inputSize }); } }); const outputSizeStream = new TransformStream({ transform(chunk, controller) { if (chunk && chunk.length) { controller.enqueue(chunk); codec2.outputSize += chunk.length; if (options.outputSize !== UNDEFINED_VALUE && codec2.outputSize > options.outputSize) { throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE); } } }, flush() { const { signature } = stream; Object.assign(codec2, { signature, inputSize }); } }); Object.defineProperty(codec2, "readable", { get() { return readable.pipeThrough(inputSizeStream).pipeThrough(stream).pipeThrough(outputSizeStream); } }); } } class ChunkStream extends TransformStream { constructor(chunkSize) { let pendingChunk; super({ transform, flush(controller) { if (pendingChunk && pendingChunk.length) { controller.enqueue(pendingChunk); } } }); function transform(chunk, controller) { if (pendingChunk) { const newChunk = new Uint8Array(pendingChunk.length + chunk.length); newChunk.set(pendingChunk); newChunk.set(chunk, pendingChunk.length); chunk = newChunk; pendingChunk = null; } if (chunk.length > chunkSize) { controller.enqueue(chunk.slice(0, chunkSize)); transform(chunk.slice(chunkSize), controller); } else { pendingChunk = chunk; } } } } let WEB_WORKERS_SUPPORTED = typeof Worker != UNDEFINED_TYPE; let initModule$1 = () => { }; function configureWorker({ initModule: initModuleFunction }) { initModule$1 = initModuleFunction; } class CodecWorker { constructor(workerData, { readable, writable }, { options, config: config2, streamOptions, useWebWorkers, transferStreams, workerURI }, onTaskFinished) { const { signal } = streamOptions; Object.assign(workerData, { busy: true, readable: readable.pipeThrough(new ChunkStream(config2.chunkSize)).pipeThrough(new ProgressWatcherStream(streamOptions), { signal }), writable, options: Object.assign({}, options), workerURI, transferStreams, terminate() { return new Promise((resolve) => { const { worker, busy } = workerData; if (worker) { if (busy) { workerData.resolveTerminated = resolve; } else { worker.terminate(); resolve(); } workerData.interface = null; } else { resolve(); } }); }, onTaskFinished() { const { resolveTerminated } = workerData; if (resolveTerminated) { workerData.resolveTerminated = null; workerData.terminated = true; workerData.worker.terminate(); resolveTerminated(); } workerData.busy = false; onTaskFinished(workerData); } }); return (useWebWorkers && WEB_WORKERS_SUPPORTED ? createWebWorkerInterface : createWorkerInterface)(workerData, config2); } } class ProgressWatcherStream extends TransformStream { constructor({ onstart, onprogress, size, onend }) { let chunkOffset = 0; super({ async start() { if (onstart) { await callHandler(onstart, size); } }, async transform(chunk, controller) { chunkOffset += chunk.length; if (onprogress) { await callHandler(onprogress, chunkOffset, size); } controller.enqueue(chunk); }, async flush() { if (onend) { await callHandler(onend, chunkOffset); } } }); } } async function callHandler(handler, ...parameters) { try { await handler(...parameters); } catch { } } function createWorkerInterface(workerData, config2) { return { run: () => runWorker$1(workerData, config2) }; } function createWebWorkerInterface(workerData, config2) { const { baseURI, chunkSize } = config2; let { wasmURI } = config2; if (!workerData.interface) { if (typeof wasmURI == FUNCTION_TYPE) { wasmURI = wasmURI(); } let worker; try { worker = getWebWorker(workerData.workerURI, baseURI, workerData); } catch { WEB_WORKERS_SUPPORTED = false; return createWorkerInterface(workerData, config2); } Object.assign(workerData, { worker, interface: { run: () => runWebWorker(workerData, { chunkSize, wasmURI, baseURI }) } }); } return workerData.interface; } async function runWorker$1({ options, readable, writable, onTaskFinished }, config2) { let codecStream; try { if (!options.useCompressionStream) { try { await initModule$1(config2); } catch { options.useCompressionStream = true; } } codecStream = new CodecStream(options, config2); await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true }); const { signature, inputSize, outputSize } = codecStream; return { signature, inputSize, outputSize }; } catch (error) { if (codecStream) { error.outputSize = codecStream.outputSize; } throw error; } finally { onTaskFinished(); } } async function runWebWorker(workerData, config2) { let resolveResult, rejectResult; const result = new Promise((resolve, reject) => { resolveResult = resolve; rejectResult = reject; }); Object.assign(workerData, { reader: null, writer: null, resolveResult, rejectResult, result }); const { readable, options } = workerData; const { writable, closed } = watchClosedStream(workerData.writable); const streamsTransferred = sendMessage({ type: MESSAGE_START, options, config: config2, readable, writable }, workerData); if (!streamsTransferred) { Object.assign(workerData, { reader: readable.getReader(), writer: writable.getWriter() }); } const resultValue = await result; if (!streamsTransferred) { await writable.getWriter().close(); } await closed; return resultValue; } function watchClosedStream(writableSource) { let resolveStreamClosed; const closed = new Promise((resolve) => resolveStreamClosed = resolve); const writable = new WritableStream({ async write(chunk) { const writer = writableSource.getWriter(); await writer.ready; await writer.write(chunk); writer.releaseLock(); }, close() { resolveStreamClosed(); }, abort(reason) { const writer = writableSource.getWriter(); return writer.abort(reason); } }); return { writable, closed }; } let transferStreamsSupported = true; function getWebWorker(url, baseURI, workerData) { const workerOptions = { type: "module" }; let scriptUrl, worker; if (typeof url == FUNCTION_TYPE) { url = url(); } if (url.startsWith("data:") || url.startsWith("blob:")) { try { worker = new Worker(url); } catch { worker = new Worker(url, workerOptions); } } else { try { scriptUrl = new URL(url, baseURI); } catch { scriptUrl = url; } worker = new Worker(scriptUrl, workerOptions); } worker.addEventListener(MESSAGE_EVENT_TYPE, (event) => onMessage(event, workerData)); return worker; } function sendMessage(message, { worker, writer, onTaskFinished, transferStreams }) { try { const { value, readable, writable } = message; const transferables = []; if (value) { message.value = value; transferables.push(message.value.buffer); } if (transferStreams && transferStreamsSupported) { if (readable) { transferables.push(readable); } if (writable) { transferables.push(writable); } } else { message.readable = message.writable = null; } if (transferables.length) { try { worker.postMessage(message, transferables); return true; } catch { transferStreamsSupported = false; message.readable = message.writable = null; worker.postMessage(message); } } else { worker.postMessage(message); } } catch (error) { if (writer) { writer.releaseLock(); } onTaskFinished(); throw error; } } async function onMessage({ data }, workerData) { const { type, value, messageId, result, error } = data; const { reader, writer, resolveResult, rejectResult, onTaskFinished } = workerData; try { if (error) { const { message, stack, code, name, outputSize } = error; const responseError = new Error(message); Object.assign(responseError, { stack, code, name, outputSize }); close(responseError); } else { if (type == MESSAGE_PULL) { const { value: value2, done } = await reader.read(); sendMessage({ type: MESSAGE_DATA, value: value2, done, messageId }, workerData); } if (type == MESSAGE_DATA) { await writer.ready; await writer.write(new Uint8Array(value)); sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData); } if (type == MESSAGE_CLOSE) { close(null, result); } } } catch (error2) { sendMessage({ type: MESSAGE_CLOSE, messageId }, workerData); close(error2); } function close(error2, result2) { if (error2) { rejectResult(error2); } else { resolveResult(result2); } if (writer) { writer.releaseLock(); } onTaskFinished(); } } let pool = []; const pendingRequests = []; let indexWorker = 0; async function runWorker(stream, workerOptions) { const { options, config: config2 } = workerOptions; const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options; const { workerURI, maxWorkers: maxWorkers2 } = config2; workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE; const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams; workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || useWebWorkers === UNDEFINED_VALUE && config2.useWebWorkers); workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE; options.useCompressionStream = useCompressionStream || useCompressionStream === UNDEFINED_VALUE && config2.useCompressionStream; return (await getWorker()).run(); async function getWorker() { const workerData = pool.find((workerData2) => !workerData2.busy); if (workerData) { clearTerminateTimeout(workerData); return new CodecWorker(workerData, stream, workerOptions, onTaskFinished); } else if (pool.length < maxWorkers2) { const workerData2 = { indexWorker }; indexWorker++; pool.push(workerData2); return new CodecWorker(workerData2, stream, workerOptions, onTaskFinished); } else { return new Promise((resolve) => pendingRequests.push({ resolve, stream, workerOptions })); } } function onTaskFinished(workerData) { if (pendingRequests.length) { const [{ resolve, stream: stream2, workerOptions: workerOptions2 }] = pendingRequests.splice(0, 1); resolve(new CodecWorker(workerData, stream2, workerOptions2, onTaskFinished)); } else if (workerData.worker) { clearTerminateTimeout(workerData); terminateWorker(workerData, workerOptions); } else { pool = pool.filter((data) => data != workerData); } } } function terminateWorker(workerData, workerOptions) { const { config: config2 } = workerOptions; const { terminateWorkerTimeout } = config2; if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) { if (workerData.terminated) { workerData.terminated = false; } else { workerData.terminateTimeout = setTimeout(async () => { pool = pool.filter((data) => data != workerData); try { await workerData.terminate(); } catch { } }, terminateWorkerTimeout); } } } function clearTerminateTimeout(workerData) { const { terminateTimeout } = workerData; if (terminateTimeout) { clearTimeout(terminateTimeout); workerData.terminateTimeout = null; } } const ERR_HTTP_STATUS = "HTTP error "; const ERR_HTTP_RANGE = "HTTP Range not supported"; const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon"; const HTTP_HEADER_CONTENT_LENGTH = "Content-Length"; const HTTP_HEADER_CONTENT_RANGE = "Content-Range"; const HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges"; const HTTP_HEADER_RANGE = "Range"; const HTTP_HEADER_CONTENT_TYPE = "Content-Type"; const HTTP_METHOD_HEAD = "HEAD"; const HTTP_METHOD_GET = "GET"; const HTTP_RANGE_UNIT = "bytes"; const DEFAULT_CHUNK_SIZE = 64 * 1024; const PROPERTY_NAME_WRITABLE = "writable"; class Stream { constructor() { this.size = 0; } init() { this.initialized = true; } } class Reader extends Stream { get readable() { const reader = this; const { chunkSize = DEFAULT_CHUNK_SIZE } = reader; const readable = new ReadableStream({ start() { this.chunkOffset = 0; }, async pull(controller) { const { offset = 0, size, diskNumberStart } = readable; const { chunkOffset } = this; const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset); const data = await readUint8Array(reader, offset + chunkOffset, dataSize, diskNumberStart); controller.enqueue(data); if (chunkOffset + chunkSize > size || size === UNDEFINED_VALUE && !data.length && dataSize) { controller.close(); } else { this.chunkOffset += chunkSize; } } }); return readable; } } class BlobReader extends Reader { constructor(blob) { super(); Object.assign(this, { blob, size: blob.size }); } async readUint8Array(offset, length) { const reader = this; const offsetEnd = offset + length; const blob = offset || offsetEnd < reader.size ? reader.blob.slice(offset, offsetEnd) : reader.blob; let arrayBuffer = await blob.arrayBuffer(); if (arrayBuffer.byteLength > length) { arrayBuffer = arrayBuffer.slice(offset, offsetEnd); } return new Uint8Array(arrayBuffer); } } class BlobWriter extends Stream { constructor(contentType) { super(); const writer = this; const transformStream = new TransformStream(); const headers = []; if (contentType) { headers.push([HTTP_HEADER_CONTENT_TYPE, contentType]); } Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, { get() { return transformStream.writable; } }); writer.blob = new Response(transformStream.readable, { headers }).blob(); } getData() { return this.blob; } } class FetchReader extends Reader { constructor(url, options) { super(); createHttpReader(this, url, options); } async init() { await initHttpReader(this, sendFetchRequest, getFetchRequestData); super.init(); } readUint8Array(index, length) { return readUint8ArrayHttpReader(this, index, length, sendFetchRequest, getFetchRequestData); } } class XHRReader extends Reader { constructor(url, options) { super(); createHttpReader(this, url, options); } async init() { await initHttpReader(this, sendXMLHttpRequest, getXMLHttpRequestData); super.init(); } readUint8Array(index, length) { return readUint8ArrayHttpReader(this, index, length, sendXMLHttpRequest, getXMLHttpRequestData); } } function createHttpReader(httpReader, url, options) { const { preventHeadRequest, useRangeHeader, forceRangeRequests, combineSizeEocd } = options; options = Object.assign({}, options); delete options.preventHeadRequest; delete options.useRangeHeader; delete options.forceRangeRequests; delete options.combineSizeEocd; delete options.useXHR; Object.assign(httpReader, { url, options, preventHeadRequest, useRangeHeader, forceRangeRequests, combineSizeEocd }); } async function initHttpReader(httpReader, sendRequest, getRequestData2) { const { url, preventHeadRequest, useRangeHeader, forceRangeRequests, combineSizeEocd } = httpReader; if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == "undefined" || preventHeadRequest)) { const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -END_OF_CENTRAL_DIR_LENGTH : void 0)); const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES); if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) { throw new Error(ERR_HTTP_RANGE); } else { if (combineSizeEocd) { httpReader.eocdCache = new Uint8Array(await response.arrayBuffer()); } let contentSize; const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE); if (contentRangeHeader) { const splitHeader = contentRangeHeader.trim().split(/\s*\/\s*/); if (splitHeader.length) { const headerValue = splitHeader[1]; if (headerValue && headerValue != "*") { contentSize = Number(headerValue); } } } if (contentSize === UNDEFINED_VALUE) { await getContentLength(httpReader, sendRequest, getRequestData2); } else { httpReader.size = contentSize; } } } else { await getContentLength(httpReader, sendRequest, getRequestData2); } } async function readUint8ArrayHttpReader(httpReader, index, length, sendRequest, getRequestData2) { const { useRangeHeader, forceRangeRequests, eocdCache, size, options } = httpReader; if (useRangeHeader || forceRangeRequests) { if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) { return eocdCache; } if (index >= size) { return new Uint8Array(); } else { if (index + length > size) { length = size - index; } const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length)); if (response.status != 206) { throw new Error(ERR_HTTP_RANGE); } return new Uint8Array(await response.arrayBuffer()); } } else { const { data } = httpReader; if (!data) { await getRequestData2(httpReader, options); } return new Uint8Array(httpReader.data.subarray(index, index + length)); } } function getRangeHeaders(httpReader, index = 0, length = 1) { return Object.assign({}, getHeaders(httpReader), { [HTTP_HEADER_RANGE]: HTTP_RANGE_UNIT + "=" + (index < 0 ? index : index + "-" + (index + length - 1)) }); } function getHeaders({ options }) { const { headers } = options; if (headers) { if (Symbol.iterator in headers) { return Object.fromEntries(headers); } else { return headers; } } } async function getFetchRequestData(httpReader) { await getRequestData(httpReader, sendFetchRequest); } async function getXMLHttpRequestData(httpReader) { await getRequestData(httpReader, sendXMLHttpRequest); } async function getRequestData(httpReader, sendRequest) { const response = await sendRequest(HTTP_METHOD_GET, httpReader, getHeaders(httpReader)); httpReader.data = new Uint8Array(await response.arrayBuffer()); if (!httpReader.size) { httpReader.size = httpReader.data.length; } } async function getContentLength(httpReader, sendRequest, getRequestData2) { if (httpReader.preventHeadRequest) { await getRequestData2(httpReader, httpReader.options); } else { const response = await sendRequest(HTTP_METHOD_HEAD, httpReader, getHeaders(httpReader)); const contentLength = response.headers.get(HTTP_HEADER_CONTENT_LENGTH); if (contentLength) { httpReader.size = Number(contentLength); } else { await getRequestData2(httpReader, httpReader.options); } } } async function sendFetchRequest(method, { options, url }, headers) { const response = await fetch(url, Object.assign({}, options, { method, headers })); if (response.status < 400) { return response; } else { throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status)); } } function sendXMLHttpRequest(method, { url }, headers) { return new Promise((resolve, reject) => { const request = new XMLHttpRequest(); request.addEventListener("load", () => { if (request.status < 400) { const headers2 = []; request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach((header) => { const splitHeader = header.trim().split(/\s*:\s*/); splitHeader[0] = splitHeader[0].trim().replace(/^[a-z]|-[a-z]/g, (value) => value.toUpperCase()); headers2.push(splitHeader); }); resolve({ status: request.status, arrayBuffer: () => request.response, headers: new Map(headers2) }); } else { reject(request.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (request.statusText || request.status))); } }, false); request.addEventListener("error", (event) => reject(event.detail ? event.detail.error : new Error("Network error")), false); request.open(method, url); if (headers) { for (const entry of Object.entries(headers)) { request.setRequestHeader(entry[0], entry[1]); } } request.responseType = "arraybuffer"; request.send(); }); } class HttpReader extends Reader { constructor(url, options = {}) { super(); Object.assign(this, { url, reader: options.useXHR ? new XHRReader(url, options) : new FetchReader(url, options) }); } set size(value) { } get size() { return this.reader.size; } async init() { await this.reader.init(); super.init(); } readUint8Array(index, length) { return this.reader.readUint8Array(index, length); } } class SplitDataReader extends Reader { constructor(readers) { super(); this.readers = readers; } async init() { const reader = this; const { readers } = reader; reader.lastDiskNumber = 0; reader.lastDiskOffset = 0; await Promise.all(readers.map(async (diskReader, indexDiskReader) => { await diskReader.init(); if (indexDiskReader != readers.length - 1) { reader.lastDiskOffset += diskReader.size; } reader.size += diskReader.size; })); super.init(); } async readUint8Array(offset, length, diskNumber = 0) { const reader = this; const { readers } = this; let result; let currentDiskNumber = diskNumber; if (currentDiskNumber == -1) { currentDiskNumber = readers.length - 1; } let currentReaderOffset = offset; while (readers[currentDiskNumber] && currentReaderOffset >= readers[currentDiskNumber].size) { currentReaderOffset -= readers[currentDiskNumber].size; currentDiskNumber++; } const currentReader = readers[currentDiskNumber]; if (currentReader) { const currentReaderSize = currentReader.size; if (currentReaderOffset + length <= currentReaderSize) { result = await readUint8Array(currentReader, currentReaderOffset, length); } else { const chunkLength = currentReaderSize - currentReaderOffset; result = new Uint8Array(length); const firstPart = await readUint8Array(currentReader, currentReaderOffset, chunkLength); result.set(firstPart, 0); const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength, diskNumber); result.set(secondPart, chunkLength); if (firstPart.length + secondPart.length < length) { result = result.subarray(0, firstPart.length + secondPart.length); } } } else { result = new Uint8Array(); } reader.lastDiskNumber = Math.max(currentDiskNumber, reader.lastDiskNumber); return result; } } class SplitDataWriter extends Stream { constructor(writerGenerator, maxSize = 4294967295) { super(); const writer = this; Object.assign(writer, { diskNumber: 0, diskOffset: 0, size: 0, maxSize, availableSize: maxSize }); let diskSourceWriter, diskWritable, diskWriter; const writable = new WritableStream({ async write(chunk) { const { availableSize } = writer; if (!diskWriter) { const { value, done } = await writerGenerator.next(); if (done && !value) { throw new Error(ERR_ITERATOR_COMPLETED_TOO_SOON); } else { diskSourceWriter = value; diskSourceWriter.size = 0; if (diskSourceWriter.maxSize) { writer.maxSize = diskSourceWriter.maxSize; } writer.availableSize = writer.maxSize; await initStream(diskSourceWriter); diskWritable = value.writable; diskWriter = diskWritable.getWriter(); } await this.write(chunk); } else if (chunk.length >= availableSize) { await writeChunk(chunk.subarray(0, availableSize)); await closeDisk(); writer.diskOffset += diskSourceWriter.size; writer.diskNumber++; diskWriter = null; await this.write(chunk.subarray(availableSize)); } else { await writeChunk(chunk); } }, async close() { await diskWriter.ready; await closeDisk(); } }); Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, { get() { return writable; } }); async function writeChunk(chunk) { const chunkLength = chunk.length; if (chunkLength) { await diskWriter.ready; await diskWriter.write(chunk); diskSourceWriter.size += chunkLength; writer.size += chunkLength; writer.availableSize -= chunkLength; } } async function closeDisk() { await diskWriter.close(); } } } class GenericReader { constructor(reader) { if (Array.isArray(reader)) { reader = new SplitDataReader(reader); } if (reader instanceof ReadableStream) { reader = { readable: reader }; } return reader; } } class GenericWriter { constructor(writer) { if (writer.writable === UNDEFINED_VALUE && typeof writer.next == FUNCTION_TYPE) { writer = new SplitDataWriter(writer); } if (writer instanceof WritableStream) { writer = { writable: writer }; } if (writer.size === UNDEFINED_VALUE) { writer.size = 0; } if (!(writer instanceof SplitDataWriter)) { Object.assign(writer, { diskNumber: 0, diskOffset: 0, availableSize: Infinity, maxSize: Infinity }); } return writer; } } function isHttpFamily(url) { const { baseURI } = getConfiguration(); const { protocol } = new URL(url, baseURI); return protocol == "http:" || protocol == "https:"; } async function initStream(stream, initSize) { if (stream.init && !stream.initialized) { await stream.init(initSize); } else { return Promise.resolve(); } } function readUint8Array(reader, offset, size, diskNumber) { return reader.readUint8Array(offset, size, diskNumber); } const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split(""); const VALID_CP437 = CP437.length == 256; function decodeCP437(stringValue) { if (VALID_CP437) { let result = ""; for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) { result += CP437[stringValue[indexCharacter]]; } return result; } else { return new TextDecoder().decode(stringValue); } } function decodeText(value, encoding) { if (encoding && encoding.trim().toLowerCase() == "cp437") { return decodeCP437(value); } else { return new TextDecoder(encoding).decode(value); } } const PROPERTY_NAME_FILENAME = "filename"; const PROPERTY_NAME_RAW_FILENAME = "rawFilename"; const PROPERTY_NAME_COMMENT = "comment"; const PROPERTY_NAME_RAW_COMMENT = "rawComment"; const PROPERTY_NAME_UNCOMPRESSED_SIZE = "uncompressedSize"; const PROPERTY_NAME_COMPRESSED_SIZE = "compressedSize"; const PROPERTY_NAME_OFFSET = "offset"; const PROPERTY_NAME_DISK_NUMBER_START = "diskNumberStart"; const PROPERTY_NAME_LAST_MODIFICATION_DATE = "lastModDate"; const PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE = "rawLastModDate"; const PROPERTY_NAME_LAST_ACCESS_DATE = "lastAccessDate"; const PROPERTY_NAME_RAW_LAST_ACCESS_DATE = "rawLastAccessDate"; const PROPERTY_NAME_CREATION_DATE = "creationDate"; const PROPERTY_NAME_RAW_CREATION_DATE = "rawCreationDate"; const PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES = "internalFileAttributes"; const PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttributes"; const PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW = "msdosAttributesRaw"; const PROPERTY_NAME_MSDOS_ATTRIBUTES = "msdosAttributes"; const PROPERTY_NAME_MS_DOS_COMPATIBLE = "msDosCompatible"; const PROPERTY_NAME_ZIP64 = "zip64"; const PROPERTY_NAME_ENCRYPTED = "encrypted"; const PROPERTY_NAME_VERSION = "version"; const PROPERTY_NAME_VERSION_MADE_BY = "versionMadeBy"; const PROPERTY_NAME_ZIPCRYPTO = "zipCrypto"; const PROPERTY_NAME_DIRECTORY = "directory"; const PROPERTY_NAME_EXECUTABLE = "executable"; const PROPERTY_NAME_COMPRESSION_METHOD = "compressionMethod"; const PROPERTY_NAME_SIGNATURE = "signature"; const PROPERTY_NAME_EXTRA_FIELD = "extraField"; const PROPERTY_NAME_EXTRA_FIELD_INFOZIP = "extraFieldInfoZip"; const PROPERTY_NAME_EXTRA_FIELD_UNIX = "extraFieldUnix"; const PROPERTY_NAME_UID = "uid"; const PROPERTY_NAME_GID = "gid"; const PROPERTY_NAME_UNIX_MODE = "unixMode"; const PROPERTY_NAME_SETUID = "setuid"; const PROPERTY_NAME_SETGID = "setgid"; const PROPERTY_NAME_STICKY = "sticky"; const PROPERTY_NAME_BITFLAG = "bitFlag"; const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8"; const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8"; const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField"; const PROPERTY_NAME_EXTRA_FIELD_ZIP64 = "extraFieldZip64"; const PROPERTY_NAME_EXTRA_FIELD_UNICODE_PATH = "extraFieldUnicodePath"; const PROPERTY_NAME_EXTRA_FIELD_UNICODE_COMMENT = "extraFieldUnicodeComment"; const PROPERTY_NAME_EXTRA_FIELD_AES = "extraFieldAES"; const PROPERTY_NAME_EXTRA_FIELD_NTFS = "extraFieldNTFS"; const PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP = "extraFieldExtendedTimestamp"; const PROPERTY_NAMES = [ PROPERTY_NAME_FILENAME, PROPERTY_NAME_RAW_FILENAME, PROPERTY_NAME_UNCOMPRESSED_SIZE, PROPERTY_NAME_COMPRESSED_SIZE, PROPERTY_NAME_LAST_MODIFICATION_DATE, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE, PROPERTY_NAME_COMMENT, PROPERTY_NAME_RAW_COMMENT, PROPERTY_NAME_LAST_ACCESS_DATE, PROPERTY_NAME_CREATION_DATE, PROPERTY_NAME_RAW_CREATION_DATE, PROPERTY_NAME_OFFSET, PROPERTY_NAME_DISK_NUMBER_START, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW, PROPERTY_NAME_MSDOS_ATTRIBUTES, PROPERTY_NAME_MS_DOS_COMPATIBLE, PROPERTY_NAME_ZIP64, PROPERTY_NAME_ENCRYPTED, PROPERTY_NAME_VERSION, PROPERTY_NAME_VERSION_MADE_BY, PROPERTY_NAME_ZIPCRYPTO, PROPERTY_NAME_DIRECTORY, PROPERTY_NAME_EXECUTABLE, PROPERTY_NAME_COMPRESSION_METHOD, PROPERTY_NAME_SIGNATURE, PROPERTY_NAME_EXTRA_FIELD, PROPERTY_NAME_EXTRA_FIELD_UNIX, PROPERTY_NAME_EXTRA_FIELD_INFOZIP, PROPERTY_NAME_UID, PROPERTY_NAME_GID, PROPERTY_NAME_UNIX_MODE, PROPERTY_NAME_SETUID, PROPERTY_NAME_SETGID, PROPERTY_NAME_STICKY, PROPERTY_NAME_BITFLAG, PROPERTY_NAME_FILENAME_UTF8, PROPERTY_NAME_COMMENT_UTF8, PROPERTY_NAME_RAW_EXTRA_FIELD, PROPERTY_NAME_EXTRA_FIELD_ZIP64, PROPERTY_NAME_EXTRA_FIELD_UNICODE_PATH, PROPERTY_NAME_EXTRA_FIELD_UNICODE_COMMENT, PROPERTY_NAME_EXTRA_FIELD_AES, PROPERTY_NAME_EXTRA_FIELD_NTFS, PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP ]; class Entry { constructor(data) { PROPERTY_NAMES.forEach((name) => this[name] = data[name]); } } const OPTION_FILENAME_ENCODING = "filenameEncoding"; const OPTION_COMMENT_ENCODING = "commentEncoding"; const OPTION_DECODE_TEXT = "decodeText"; const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData"; const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData"; const OPTION_PASSWORD = "password"; const OPTION_RAW_PASSWORD = "rawPassword"; const OPTION_PASS_THROUGH = "passThrough"; const OPTION_SIGNAL = "signal"; const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly"; const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly"; const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry"; const OPTION_CHECK_SIGNATURE = "checkSignature"; const OPTION_USE_WEB_WORKERS = "useWebWorkers"; const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream"; const OPTION_TRANSFER_STREAMS = "transferStreams"; const OPTION_PREVENT_CLOSE = "preventClose"; const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength"; const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp"; const OPTION_KEEP_ORDER = "keepOrder"; const OPTION_LEVEL = "level"; const OPTION_BUFFERED_WRITE = "bufferedWrite"; const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature"; const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames"; const OPTION_DATA_DESCRIPTOR = "dataDescriptor"; const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile"; const OPTION_ENCODE_TEXT = "encodeText"; const OPTION_OFFSET = "offset"; const OPTION_USDZ = "usdz"; const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType"; const ERR_BAD_FORMAT = "File format is not recognized"; const ERR_EOCDR_NOT_FOUND = "End of central directory not found"; const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found"; const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found"; const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found"; const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found"; const ERR_ENCRYPTED = "File contains encrypted entry"; const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported"; const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported"; const ERR_SPLIT_ZIP_FILE = "Split zip file"; const ERR_OVERLAPPING_ENTRY = "Overlapping entry found"; const CHARSET_UTF8 = "utf-8"; const PROPERTY_NAME_UTF8_SUFFIX = "UTF8"; const CHARSET_CP437 = "cp437"; const ZIP64_PROPERTIES = [ [PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS], [PROPERTY_NAME_COMPRESSED_SIZE, MAX_32_BITS], [PROPERTY_NAME_OFFSET, MAX_32_BITS], [PROPERTY_NAME_DISK_NUMBER_START, MAX_16_BITS] ]; const ZIP64_EXTRACTION = { [MAX_16_BITS]: { getValue: getUint32, bytes: 4 }, [MAX_32_BITS]: { getValue: getBigUint64, bytes: 8 } }; class ZipReader { constructor(reader, options = {}) { Object.assign(this, { reader: new GenericReader(reader), options, config: getConfiguration(), readRanges: [] }); } async *getEntriesGenerator(options = {}) { const zipReader = this; let { reader } = zipReader; const { config: config2 } = zipReader; await initStream(reader); if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) { reader = new BlobReader(await new Response(reader.readable).blob()); await initStream(reader); } if (reader.size < END_OF_CENTRAL_DIR_LENGTH) { throw new Error(ERR_BAD_FORMAT); } reader.chunkSize = getChunkSize(config2); const endOfDirectoryInfo = await seekSignature(reader, END_OF_CENTRAL_DIR_SIGNATURE, reader.size, END_OF_CENTRAL_DIR_LENGTH, MAX_16_BITS * 16); if (!endOfDirectoryInfo) { const signatureArray = await readUint8Array(reader, 0, 4); const signatureView = getDataView$1(signatureArray); if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) { throw new Error(ERR_SPLIT_ZIP_FILE); } else { throw new Error(ERR_EOCDR_NOT_FOUND); } } const endOfDirectoryView = getDataView$1(endOfDirectoryInfo); let directoryDataLength = getUint32(endOfDirectoryView, 12); let directoryDataOffset = getUint32(endOfDirectoryView, 16); const commentOffset = endOfDirectoryInfo.offset; const commentLength = getUint16(endOfDirectoryView, 20); const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength; let lastDiskNumber = getUint16(endOfDirectoryView, 4); const expectedLastDiskNumber = reader.lastDiskNumber || 0; let diskNumber = getUint16(endOfDirectoryView, 6); let filesLength = getUint16(endOfDirectoryView, 8); let prependedDataLength = 0; let startOffset = 0; if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS) { const endOfDirectoryLocatorArray = await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH); const endOfDirectoryLocatorView = getDataView$1(endOfDirectoryLocatorArray); if (getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) { directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8); let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1); let endOfDirectoryView2 = getDataView$1(endOfDirectoryArray); const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH; if (getUint32(endOfDirectoryView2, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) { const originalDirectoryDataOffset = directoryDataOffset; directoryDataOffset = expectedDirectoryDataOffset; if (directoryDataOffset > originalDirectoryDataOffset) { prependedDataLength = directoryDataOffset - originalDirectoryDataOffset; } endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1); endOfDirectoryView2 = getDataView$1(endOfDirectoryArray); } if (getUint32(endOfDirectoryView2, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) { throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND); } if (lastDiskNumber == MAX_16_BITS) { lastDiskNumber = getUint32(endOfDirectoryView2, 16); } if (diskNumber == MAX_16_BITS) { diskNumber = getUint32(endOfDirectoryView2, 20); } if (filesLength == MAX_16_BITS) { filesLength = getBigUint64(endOfDirectoryView2, 32); } if (directoryDataLength == MAX_32_BITS) { directoryDataLength = getBigUint64(endOfDirectoryView2, 40); } directoryDataOffset -= directoryDataLength; } } if (directoryDataOffset >= reader.size) { prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH; directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH; } if (expectedLastDiskNumber != lastDiskNumber) { throw new Error(ERR_SPLIT_ZIP_FILE); } if (directoryDataOffset < 0) { throw new Error(ERR_BAD_FORMAT); } let offset = 0; let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber); let directoryView = getDataView$1(directoryArray); if (directoryDataLength) { const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - directoryDataLength; if (getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) { const originalDirectoryDataOffset = directoryDataOffset; directoryDataOffset = expectedDirectoryDataOffset; if (directoryDataOffset > originalDirectoryDataOffset) { prependedDataLength += directoryDataOffset - originalDirectoryDataOffset; } directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber); directoryView = getDataView$1(directoryArray); } } const expectedDirectoryDataLength = endOfDirectoryInfo.offset - directoryDataOffset - (reader.lastDiskOffset || 0); if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0) { directoryDataLength = expectedDirectoryDataLength; directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber); directoryView = getDataView$1(directoryArray); } if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) { throw new Error(ERR_BAD_FORMAT); } const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING); const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING); for (let indexFile = 0; indexFile < filesLength; indexFile++) { const fileEntry = new ZipEntry(reader, config2, zipReader.options); if (getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) { throw new Error(ERR_CENTRAL_DIRECTORY_NOT_FOUND); } readCommonHeader(fileEntry, directoryView, offset + 6); const languageEncodingFlag = Boolean(fileEntry.bitFlag.languageEncodingFlag); const filenameOffset = offset + 46; const extraFieldOffset = filenameOffset + fileEntry.filenameLength; const commentOffset2 = extraFieldOffset + fileEntry.extraFieldLength; const versionMadeBy = getUint16(directoryView, offset + 4); const msDosCompatible = versionMadeBy >> 8 == 0; const unixCompatible = versionMadeBy >> 8 == 3; const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset); const commentLength2 = getUint16(directoryView, offset + 32); const endOffset = commentOffset2 + commentLength2; const rawComment = directoryArray.subarray(commentOffset2, endOffset); const filenameUTF8 = languageEncodingFlag; const commentUTF8 = languageEncodingFlag; const externalFileAttributes = getUint32(directoryView, offset + 38); const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS; const msdosAttributes = { readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK), hidden: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_HIDDEN_MASK), system: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_SYSTEM_MASK), directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK), archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK) }; const offsetFileEntry = getUint32(directoryView, offset + 42) + prependedDataLength; const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText; const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437; const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437; let filename = decode(rawFilename, rawFilenameEncoding); if (filename === UNDEFINED_VALUE) { filename = decodeText(rawFilename, rawFilenameEncoding); } let comment = decode(rawComment, rawCommentEncoding); if (comment === UNDEFINED_VALUE) { comment = decodeText(rawComment, rawCommentEncoding); } Object.assign(fileEntry, { versionMadeBy, msDosCompatible, compressedSize: 0, uncompressedSize: 0, commentLength: commentLength2, offset: offsetFileEntry, diskNumberStart: getUint16(directoryView, offset + 34), internalFileAttributes: getUint16(directoryView, offset + 36), externalFileAttributes, msdosAttributesRaw, msdosAttributes, rawFilename, filenameUTF8, commentUTF8, rawExtraField: directoryArray.subarray(extraFieldOffset, commentOffset2), rawComment, filename, comment }); startOffset = Math.max(offsetFileEntry, startOffset); readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6); const unixExternalUpper = fileEntry.externalFileAttributes >> 16 & MAX_16_BITS; if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) { fileEntry.unixMode = unixExternalUpper; } const setuid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETUID_MASK); const setgid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETGID_MASK); const sticky = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_STICKY_MASK); const executable = fileEntry.unixMode !== UNDEFINED_VALUE ? (fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0 : unixCompatible && (unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0; const modeIsDir = fileEntry.unixMode !== UNDEFINED_VALUE && (fileEntry.unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR; const upperIsDir = (unixExternalUpper & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR; Object.assign(fileEntry, { setuid, setgid, sticky, unixExternalUpper, internalFileAttribute: fileEntry.internalFileAttributes, externalFileAttribute: fileEntry.externalFileAttributes, executable, directory: modeIsDir || upperIsDir || msDosCompatible && msdosAttributes.directory || filename.endsWith(DIRECTORY_SIGNATURE) && !fileEntry.uncompressedSize, zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES }); const entry = new Entry(fileEntry); entry.getData = (writer, options2) => fileEntry.getData(writer, entry, zipReader.readRanges, options2); entry.arrayBuffer = async (options2) => { const writer = new TransformStream(); const [arrayBuffer] = await Promise.all([ new Response(writer.readable).arrayBuffer(), fileEntry.getData(writer, entry, zipReader.readRanges, options2) ]); return arrayBuffer; }; offset = endOffset; const { onprogress } = options; if (onprogress) { try { await onprogress(indexFile + 1, filesLength, new Entry(fileEntry)); } catch { } } yield entry; } const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA); const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA); if (extractPrependedData) { zipReader.prependedData = startOffset > 0 ? await readUint8Array(reader, 0, startOffset) : new Uint8Array(); } zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : new Uint8Array(); if (extractAppendedData) { zipReader.appendedData = appendedDataOffset < reader.size ? await readUint8Array(reader, appendedDataOffset, reader.size - appendedDataOffset) : new Uint8Array(); } return true; } async getEntries(options = {}) { const entries = []; for await (const entry of this.getEntriesGenerator(options)) { entries.push(entry); } return entries; } async close() { } } class ZipEntry { constructor(reader, config2, options) { Object.assign(this, { reader, config: config2, options }); } async getData(writer, fileEntry, readRanges, options = {}) { const zipEntry = this; const { reader, offset, diskNumberStart, extraFieldAES, extraFieldZip64, compressionMethod, config: config2, bitFlag, signature, rawLastModDate, uncompressedSize, compressedSize } = zipEntry; const { dataDescriptor } = bitFlag; const localDirectory = fileEntry.localDirectory = {}; const dataArray = await readUint8Array(reader, offset, HEADER_SIZE, diskNumberStart); const dataView = getDataView$1(dataArray); let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD); let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD); const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH); password = password && password.length && password; rawPassword = rawPassword && rawPassword.length && rawPassword; if (extraFieldAES) { if (extraFieldAES.originalCompressionMethod != COMPRESSION_METHOD_AES) { throw new Error(ERR_UNSUPPORTED_COMPRESSION); } } if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !passThrough) { throw new Error(ERR_UNSUPPORTED_COMPRESSION); } if (getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) { throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND); } readCommonHeader(localDirectory, dataView, 4); const { extraFieldLength, filenameLength, lastAccessDate, creationDate } = localDirectory; localDirectory.rawExtraField = extraFieldLength ? await readUint8Array(reader, offset + HEADER_SIZE + filenameLength, extraFieldLength, diskNumberStart) : new Uint8Array(); readCommonFooter(zipEntry, localDirectory, dataView, 4, true); Object.assign(fileEntry, { lastAccessDate, creationDate }); const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough; const zipCrypto = encrypted && !extraFieldAES; if (!passThrough) { fileEntry.zipCrypto = zipCrypto; } if (encrypted) { if (!zipCrypto && extraFieldAES.strength === UNDEFINED_VALUE) { throw new Error(ERR_UNSUPPORTED_ENCRYPTION); } else if (!password && !rawPassword) { throw new Error(ERR_ENCRYPTED); } } const dataOffset = offset + HEADER_SIZE + filenameLength + extraFieldLength; const size = compressedSize; const readable = reader.readable; Object.assign(readable, { diskNumberStart, offset: dataOffset, size }); const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL); const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY); let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY); const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY); if (checkOverlappingEntryOnly) { checkOverlappingEntry = true; } const { onstart, onprogress, onend } = options; const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64; let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM); if (deflate64) { useCompressionStream = false; } const workerOptions = { options: { codecType: CODEC_INFLATE, password, rawPassword, zipCrypto, encryptionStrength: extraFieldAES && extraFieldAES.strength, signed: getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) && !passThrough, passwordVerification: zipCrypto && (dataDescriptor ? rawLastModDate >>> 8 & MAX_8_BITS : signature >>> 24 & MAX_8_BITS), outputSize: passThrough ? compressedSize : uncompressedSize, signature, compressed: compressionMethod != 0 && !passThrough, encrypted: zipEntry.encrypted && !passThrough, useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS), useCompressionStream, transferStreams: getOptionValue$1(zipEntry, options, OPTION_TRANSFER_STREAMS), deflate64, checkPasswordOnly }, config: config2, streamOptions: { signal, size, onstart, onprogress, onend } }; if (checkOverlappingEntry) { await detectOverlappingEntry({ reader, fileEntry, offset, diskNumberStart, signature, compressedSize, uncompressedSize, dataOffset, dataDescriptor: dataDescriptor || localDirectory.bitFlag.dataDescriptor, extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64, readRanges }); } let writable; try { if (!checkOverlappingEntryOnly) { if (checkPasswordOnly) { writer = new WritableStream(); } writer = new GenericWriter(writer); await initStream(writer, passThrough ? compressedSize : uncompressedSize); ({ writable } = writer); const { outputSize } = await runWorker({ readable, writable }, workerOptions); writer.size += outputSize; if (outputSize != (passThrough ? compressedSize : uncompressedSize)) { throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE); } } } catch (error) { if (error.outputSize !== UNDEFINED_VALUE) { writer.size += error.outputSize; } if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) { throw error; } } finally { const preventClose = getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE); if (!preventClose && writable && !writable.locked) { await writable.getWriter().close(); } } return checkPasswordOnly || checkOverlappingEntryOnly ? UNDEFINED_VALUE : writer.getData ? writer.getData() : writable; } } function readCommonHeader(directory, dataView, offset) { const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2); const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED; const rawLastModDate = getUint32(dataView, offset + 6); Object.assign(directory, { encrypted, version: getUint16(dataView, offset), bitFlag: { level: (rawBitFlag & BITFLAG_LEVEL) >> 1, dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR, languageEncodingFlag: (rawBitFlag & BITFLAG_LANG_ENCODING_FLAG) == BITFLAG_LANG_ENCODING_FLAG }, rawLastModDate, lastModDate: getDate(rawLastModDate), filenameLength: getUint16(dataView, offset + 22), extraFieldLength: getUint16(dataView, offset + 24) }); } function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) { const { rawExtraField } = directory; const extraField = directory.extraField = /* @__PURE__ */ new Map(); const rawExtraFieldView = getDataView$1(new Uint8Array(rawExtraField)); let offsetExtraField = 0; try { while (offsetExtraField < rawExtraField.length) { const type = getUint16(rawExtraFieldView, offsetExtraField); const size = getUint16(rawExtraFieldView, offsetExtraField + 2); extraField.set(type, { type, data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size) }); offsetExtraField += 4 + size; } } catch { } const compressionMethod = getUint16(dataView, offset + 4); Object.assign(directory, { signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE), compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE), uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE) }); const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64); if (extraFieldZip64) { readExtraFieldZip64(extraFieldZip64, directory); directory.extraFieldZip64 = extraFieldZip64; } const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH); if (extraFieldUnicodePath) { readExtraFieldUnicode(extraFieldUnicodePath, PROPERTY_NAME_FILENAME, PROPERTY_NAME_RAW_FILENAME, directory, fileEntry); directory.extraFieldUnicodePath = extraFieldUnicodePath; } const extraFieldUnicodeComment = extraField.get(EXTRAFIELD_TYPE_UNICODE_COMMENT); if (extraFieldUnicodeComment) { readExtraFieldUnicode(extraFieldUnicodeComment, PROPERTY_NAME_COMMENT, PROPERTY_NAME_RAW_COMMENT, directory, fileEntry); directory.extraFieldUnicodeComment = extraFieldUnicodeComment; } const extraFieldAES = extraField.get(EXTRAFIELD_TYPE_AES); if (extraFieldAES) { readExtraFieldAES(extraFieldAES, directory, compressionMethod); directory.extraFieldAES = extraFieldAES; } else { directory.compressionMethod = compressionMethod; } const extraFieldNTFS = extraField.get(EXTRAFIELD_TYPE_NTFS); if (extraFieldNTFS) { readExtraFieldNTFS(extraFieldNTFS, directory); directory.extraFieldNTFS = extraFieldNTFS; } const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX); if (extraFieldUnix) { readExtraFieldUnix(extraFieldUnix, directory, false); directory.extraFieldUnix = extraFieldUnix; } else { const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP); if (extraFieldInfoZip) { readExtraFieldUnix(extraFieldInfoZip, directory, true); directory.extraFieldInfoZip = extraFieldInfoZip; } } const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP); if (extraFieldExtendedTimestamp) { readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory); directory.extraFieldExtendedTimestamp = extraFieldExtendedTimestamp; } const extraFieldUSDZ = extraField.get(EXTRAFIELD_TYPE_USDZ); if (extraFieldUSDZ) { directory.extraFieldUSDZ = extraFieldUSDZ; } } function readExtraFieldZip64(extraFieldZip64, directory) { directory.zip64 = true; const extraFieldView = getDataView$1(extraFieldZip64.data); const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max); for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) { const [propertyName, max] = missingProperties[indexMissingProperty]; if (directory[propertyName] == max) { const extraction = ZIP64_EXTRACTION[max]; directory[propertyName] = extraFieldZip64[propertyName] = extraction.getValue(extraFieldView, offset); offset += extraction.bytes; } else if (extraFieldZip64[propertyName]) { throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND); } } } function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) { const extraFieldView = getDataView$1(extraFieldUnicode.data); const crc32 = new Crc32(); crc32.append(fileEntry[rawPropertyName]); const dataViewSignature = getDataView$1(new Uint8Array(4)); dataViewSignature.setUint32(0, crc32.get(), true); const signature = getUint32(extraFieldView, 1); Object.assign(extraFieldUnicode, { version: getUint8(extraFieldView, 0), [propertyName]: decodeText(extraFieldUnicode.data.subarray(5)), valid: !fileEntry.bitFlag.languageEncodingFlag && signature == getUint32(dataViewSignature, 0) }); if (extraFieldUnicode.valid) { directory[propertyName] = extraFieldUnicode[propertyName]; directory[propertyName + PROPERTY_NAME_UTF8_SUFFIX] = true; } } function readExtraFieldAES(extraFieldAES, directory, compressionMethod) { const extraFieldView = getDataView$1(extraFieldAES.data); const strength = getUint8(extraFieldView, 4); Object.assign(extraFieldAES, { vendorVersion: getUint8(extraFieldView, 0), vendorId: getUint8(extraFieldView, 2), strength, originalCompressionMethod: compressionMethod, compressionMethod: getUint16(extraFieldView, 5) }); directory.compressionMethod = extraFieldAES.compressionMethod; } function readExtraFieldNTFS(extraFieldNTFS, directory) { const extraFieldView = getDataView$1(extraFieldNTFS.data); let offsetExtraField = 4; let tag1Data; try { while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) { const tagValue = getUint16(extraFieldView, offsetExtraField); const attributeSize = getUint16(extraFieldView, offsetExtraField + 2); if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) { tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize); } offsetExtraField += 4 + attributeSize; } } catch { } try { if (tag1Data && tag1Data.length == 24) { const tag1View = getDataView$1(tag1Data); const rawLastModDate = tag1View.getBigUint64(0, true); const rawLastAccessDate = tag1View.getBigUint64(8, true); const rawCreationDate = tag1View.getBigUint64(16, true); Object.assign(extraFieldNTFS, { rawLastModDate, rawLastAccessDate, rawCreationDate }); const lastModDate = getDateNTFS(rawLastModDate); const lastAccessDate = getDateNTFS(rawLastAccessDate); const creationDate = getDateNTFS(rawCreationDate); const extraFieldData = { lastModDate, lastAccessDate, creationDate }; Object.assign(extraFieldNTFS, extraFieldData); Object.assign(directory, extraFieldData); } } catch { } } function readExtraFieldUnix(extraField, directory, isInfoZip) { try { const view = getDataView$1(new Uint8Array(extraField.data)); let offset = 0; const version = getUint8(view, offset++); const uidSize = getUint8(view, offset++); const uidBytes = extraField.data.subarray(offset, offset + uidSize); offset += uidSize; const uid = unpackUnixId(uidBytes); const gidSize = getUint8(view, offset++); const gidBytes = extraField.data.subarray(offset, offset + gidSize); offset += gidSize; const gid = unpackUnixId(gidBytes); let unixMode = UNDEFINED_VALUE; if (!isInfoZip && offset + 2 <= extraField.data.length) { const base = extraField.data; const modeView = new DataView(base.buffer, base.byteOffset + offset, 2); unixMode = modeView.getUint16(0, true); } Object.assign(extraField, { version, uid, gid, unixMode }); if (uid !== UNDEFINED_VALUE) { directory.uid = uid; } if (gid !== UNDEFINED_VALUE) { directory.gid = gid; } if (unixMode !== UNDEFINED_VALUE) { directory.unixMode = unixMode; } } catch { } } function unpackUnixId(bytes) { const buffer = new Uint8Array(4); buffer.set(bytes, 0); const view = new DataView(buffer.buffer, buffer.byteOffset, 4); return view.getUint32(0, true); } function readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory) { const extraFieldView = getDataView$1(extraFieldExtendedTimestamp.data); const flags = getUint8(extraFieldView, 0); const timeProperties = []; const timeRawProperties = []; if (localDirectory) { if ((flags & 1) == 1) { timeProperties.push(PROPERTY_NAME_LAST_MODIFICATION_DATE); timeRawProperties.push(PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE); } if ((flags & 2) == 2) { timeProperties.push(PROPERTY_NAME_LAST_ACCESS_DATE); timeRawProperties.push(PROPERTY_NAME_RAW_LAST_ACCESS_DATE); } if ((flags & 4) == 4) { timeProperties.push(PROPERTY_NAME_CREATION_DATE); timeRawProperties.push(PROPERTY_NAME_RAW_CREATION_DATE); } } else if (extraFieldExtendedTimestamp.data.length >= 5) { timeProperties.push(PROPERTY_NAME_LAST_MODIFICATION_DATE); timeRawProperties.push(PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE); } let offset = 1; timeProperties.forEach((propertyName, indexProperty) => { if (extraFieldExtendedTimestamp.data.length >= offset + 4) { const time = getUint32(extraFieldView, offset); directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date(time * 1e3); const rawPropertyName = timeRawProperties[indexProperty]; extraFieldExtendedTimestamp[rawPropertyName] = time; } offset += 4; }); } async function detectOverlappingEntry({ reader, fileEntry, offset, diskNumberStart, signature, compressedSize, uncompressedSize, dataOffset, dataDescriptor, extraFieldZip64, readRanges }) { let diskOffset = 0; if (diskNumberStart) { for (let indexReader = 0; indexReader < diskNumberStart; indexReader++) { const diskReader = reader.readers[indexReader]; diskOffset += diskReader.size; } } let dataDescriptorLength = 0; if (dataDescriptor) { if (extraFieldZip64) { dataDescriptorLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH; } else { dataDescriptorLength = DATA_DESCRIPTOR_RECORD_LENGTH; } } if (dataDescriptorLength) { const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, diskNumberStart); const dataDescriptorSignature = getUint32(getDataView$1(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE; if (dataDescriptorSignature) { const readSignature = getUint32(getDataView$1(dataDescriptorArray), 4); let readCompressedSize; let readUncompressedSize; if (extraFieldZip64) { readCompressedSize = getBigUint64(getDataView$1(dataDescriptorArray), 8); readUncompressedSize = getBigUint64(getDataView$1(dataDescriptorArray), 16); } else { readCompressedSize = getUint32(getDataView$1(dataDescriptorArray), 8); readUncompressedSize = getUint32(getDataView$1(dataDescriptorArray), 12); } const matchSignature = fileEntry.encrypted && !fileEntry.zipCrypto || readSignature == signature; if (matchSignature && readCompressedSize == compressedSize && readUncompressedSize == uncompressedSize) { dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH; } } } const range = { start: diskOffset + offset, end: diskOffset + dataOffset + compressedSize + dataDescriptorLength, fileEntry }; for (const otherRange of readRanges) { if (otherRange.fileEntry != fileEntry && range.start >= otherRange.start && range.start < otherRange.end) { const error = new Error(ERR_OVERLAPPING_ENTRY); error.overlappingEntry = otherRange.fileEntry; throw error; } } readRanges.push(range); } async function seekSignature(reader, signature, startOffset, minimumBytes, maximumLength) { const signatureArray = new Uint8Array(4); const signatureView = getDataView$1(signatureArray); setUint32$1(signatureView, 0, signature); const maximumBytes = minimumBytes + maximumLength; return await seek(minimumBytes) || await seek(Math.min(maximumBytes, startOffset)); async function seek(length) { const offset = startOffset - length; const bytes = await readUint8Array(reader, offset, length); for (let indexByte = bytes.length - minimumBytes; indexByte >= 0; indexByte--) { if (bytes[indexByte] == signatureArray[0] && bytes[indexByte + 1] == signatureArray[1] && bytes[indexByte + 2] == signatureArray[2] && bytes[indexByte + 3] == signatureArray[3]) { return { offset: offset + indexByte, buffer: bytes.slice(indexByte, indexByte + minimumBytes).buffer }; } } } } function getOptionValue$1(zipReader, options, name) { return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name]; } function getDate(timeRaw) { const date = (timeRaw & 4294901760) >> 16, time = timeRaw & MAX_16_BITS; try { return new Date(1980 + ((date & 65024) >> 9), ((date & 480) >> 5) - 1, date & 31, (time & 63488) >> 11, (time & 2016) >> 5, (time & 31) * 2, 0); } catch { } } function getDateNTFS(timeRaw) { return new Date(Number(timeRaw / BigInt(1e4) - BigInt(116444736e5))); } function getUint8(view, offset) { return view.getUint8(offset); } function getUint16(view, offset) { return view.getUint16(offset, true); } function getUint32(view, offset) { return view.getUint32(offset, true); } function getBigUint64(view, offset) { return Number(view.getBigUint64(offset, true)); } function setUint32$1(view, offset, value) { view.setUint32(offset, value, true); } function getDataView$1(array) { return new DataView(array.buffer); } const ERR_DUPLICATED_NAME = "File already exists"; const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB"; const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB"; const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB"; const ERR_INVALID_VERSION = "Version exceeds 65535"; const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3"; const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535"; const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB"; const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')"; const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size"; const ERR_ZIP_NOT_EMPTY = "Zip file not empty"; const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)"; const ERR_INVALID_GID = "Invalid gid (must be integer 0..2^32-1)"; const ERR_INVALID_UNIX_MODE = "Invalid UNIX mode (must be integer 0..65535)"; const ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = "Invalid unixExtraFieldType (must be 'infozip' or 'unix')"; const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)"; const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)"; const EXTRAFIELD_DATA_AES = new Uint8Array([7, 0, 2, 0, 65, 69, 3, 0, 0]); const INFOZIP_EXTRA_FIELD_TYPE = "infozip"; const UNIX_EXTRA_FIELD_TYPE = "unix"; let workers = 0; const pendingEntries = []; class ZipWriter { constructor(writer, options = {}) { writer = new GenericWriter(writer); const addSplitZipSignature = writer.availableSize !== UNDEFINED_VALUE && writer.availableSize > 0 && writer.availableSize !== Infinity && writer.maxSize !== UNDEFINED_VALUE && writer.maxSize > 0 && writer.maxSize !== Infinity; Object.assign(this, { writer, addSplitZipSignature, options, config: getConfiguration(), files: /* @__PURE__ */ new Map(), filenames: /* @__PURE__ */ new Set(), offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET], pendingEntriesSize: 0, pendingAddFileCalls: /* @__PURE__ */ new Set(), bufferedWrites: 0 }); } async prependZip(reader) { if (this.filenames.size) { throw new Error(ERR_ZIP_NOT_EMPTY); } reader = new GenericReader(reader); const zipReader = new ZipReader(reader.readable); const entries = await zipReader.getEntries(); await zipReader.close(); await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true }); this.writer.size = this.offset = reader.size; this.filenames = new Set(entries.map((entry) => entry.filename)); this.files = new Map(entries.map((entry) => { const { version, compressionMethod, lastModDate, lastAccessDate, creationDate, rawFilename, bitFlag, encrypted, uncompressedSize, compressedSize, diskOffset, diskNumber, zip64 } = entry; let { rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField } = entry; const { level, languageEncodingFlag, dataDescriptor } = bitFlag; rawExtraFieldZip64 = rawExtraFieldZip64 || new Uint8Array(); rawExtraFieldAES = rawExtraFieldAES || new Uint8Array(); rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || new Uint8Array(); rawExtraFieldNTFS = rawExtraFieldNTFS || new Uint8Array(); rawExtraFieldUnix = entry.rawExtraFieldUnix || new Uint8Array(); rawExtraField = rawExtraField || new Uint8Array(); const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField); const zip64UncompressedSize = zip64 && uncompressedSize > MAX_32_BITS; const zip64CompressedSize = zip64 && compressedSize > MAX_32_BITS; const { headerArray, headerView } = getHeaderArrayData({ version, bitFlag: getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod), compressionMethod, uncompressedSize, compressedSize, lastModDate, rawFilename, zip64CompressedSize, zip64UncompressedSize, extraFieldLength }); Object.assign(entry, { zip64UncompressedSize, zip64CompressedSize, zip64Offset: zip64 && this.offset - diskOffset > MAX_32_BITS, zip64DiskNumberStart: zip64 && diskNumber > MAX_16_BITS, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0, extraFieldExtendedTimestampFlag: 1 + (lastAccessDate ? 2 : 0) + (creationDate ? 4 : 0), headerArray, headerView }); return [entry.filename, entry]; })); } async add(name = "", reader, options = {}) { const zipWriter = this; const { pendingAddFileCalls, config: config2 } = zipWriter; if (workers < config2.maxWorkers) { workers++; } else { await new Promise((resolve) => pendingEntries.push(resolve)); } let promiseAddFile; try { name = name.trim(); if (zipWriter.filenames.has(name)) { throw new Error(ERR_DUPLICATED_NAME); } zipWriter.filenames.add(name); promiseAddFile = addFile(zipWriter, name, reader, options); pendingAddFileCalls.add(promiseAddFile); return await promiseAddFile; } catch (error) { zipWriter.filenames.delete(name); throw error; } finally { pendingAddFileCalls.delete(promiseAddFile); const pendingEntry = pendingEntries.shift(); if (pendingEntry) { pendingEntry(); } else { workers--; } } } remove(entry) { const { filenames, files } = this; if (typeof entry == "string") { entry = files.get(entry); } if (entry && entry.filename !== UNDEFINED_VALUE) { const { filename } = entry; if (filenames.has(filename) && files.has(filename)) { filenames.delete(filename); files.delete(filename); return true; } } return false; } async close(comment = new Uint8Array(), options = {}) { const zipWriter = this; const { pendingAddFileCalls, writer } = this; const { writable } = writer; while (pendingAddFileCalls.size) { await Promise.allSettled(Array.from(pendingAddFileCalls)); } await closeFile(zipWriter, comment, options); const preventClose = getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE); if (!preventClose) { await writable.getWriter().close(); } return writer.getData ? writer.getData() : writable; } } async function addFile(zipWriter, name, reader, options) { name = name.trim(); let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE); let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768); const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE); const uid = getOptionValue(zipWriter, options, PROPERTY_NAME_UID); const gid = getOptionValue(zipWriter, options, PROPERTY_NAME_GID); let unixMode = getOptionValue(zipWriter, options, PROPERTY_NAME_UNIX_MODE); const unixExtraFieldType = getOptionValue(zipWriter, options, OPTION_UNIX_EXTRA_FIELD_TYPE); let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID); let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID); let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY); if (uid !== UNDEFINED_VALUE && (uid < 0 || uid > MAX_32_BITS)) { throw new Error(ERR_INVALID_UID); } if (gid !== UNDEFINED_VALUE && (gid < 0 || gid > MAX_32_BITS)) { throw new Error(ERR_INVALID_GID); } if (unixMode !== UNDEFINED_VALUE && (unixMode < 0 || unixMode > MAX_16_BITS)) { throw new Error(ERR_INVALID_UNIX_MODE); } if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) { throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE); } let msdosAttributesRaw = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW); let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES); const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType; const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE; if (hasUnixMetadata) { msDosCompatible = false; versionMadeBy = versionMadeBy & MAX_16_BITS | 3 << 8; } else if (hasMsDosProvided) { msDosCompatible = true; versionMadeBy = versionMadeBy & MAX_8_BITS; } if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) { throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES); } if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) { throw new Error(ERR_INVALID_MSDOS_DATA); } if (versionMadeBy > MAX_16_BITS) { throw new Error(ERR_INVALID_VERSION); } let externalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES, 0); if (!options[PROPERTY_NAME_DIRECTORY] && name.endsWith(DIRECTORY_SIGNATURE)) { options[PROPERTY_NAME_DIRECTORY] = true; } const directory = getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY); if (directory) { if (!name.endsWith(DIRECTORY_SIGNATURE)) { name += DIRECTORY_SIGNATURE; } if (externalFileAttributes === 0) { externalFileAttributes = FILE_ATTR_MSDOS_DIR_MASK; if (!msDosCompatible) { externalFileAttributes |= (FILE_ATTR_UNIX_TYPE_DIR | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_DEFAULT_MASK) << 16; } } } else if (!msDosCompatible && externalFileAttributes === 0) { if (executable) { externalFileAttributes = (FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_DEFAULT_MASK) << 16; } else { externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16; } } let unixExternalUpper; if (!msDosCompatible) { unixExternalUpper = externalFileAttributes >> 16 & MAX_16_BITS; unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : unixMode & MAX_16_BITS; if (setuid) { unixMode |= FILE_ATTR_UNIX_SETUID_MASK; } else { setuid = Boolean(unixMode & FILE_ATTR_UNIX_SETUID_MASK); } if (setgid) { unixMode |= FILE_ATTR_UNIX_SETGID_MASK; } else { setgid = Boolean(unixMode & FILE_ATTR_UNIX_SETGID_MASK); } if (sticky) { unixMode |= FILE_ATTR_UNIX_STICKY_MASK; } else { sticky = Boolean(unixMode & FILE_ATTR_UNIX_STICKY_MASK); } if (directory) { unixMode |= FILE_ATTR_UNIX_TYPE_DIR; } externalFileAttributes = (unixMode & MAX_16_BITS) << 16 | externalFileAttributes & MAX_8_BITS; } ({ msdosAttributesRaw, msdosAttributes } = normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes)); if (hasMsDosProvided) { externalFileAttributes = externalFileAttributes & MAX_32_BITS | msdosAttributesRaw & MAX_8_BITS; } const encode = getOptionValue(zipWriter, options, OPTION_ENCODE_TEXT, encodeText); let rawFilename = encode(name); if (rawFilename === UNDEFINED_VALUE) { rawFilename = encodeText(name); } if (getLength(rawFilename) > MAX_16_BITS) { throw new Error(ERR_INVALID_ENTRY_NAME); } const comment = options[PROPERTY_NAME_COMMENT] || ""; let rawComment = encode(comment); if (rawComment === UNDEFINED_VALUE) { rawComment = encodeText(comment); } if (getLength(rawComment) > MAX_16_BITS) { throw new Error(ERR_INVALID_ENTRY_COMMENT); } const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION, VERSION_DEFLATE); if (version > MAX_16_BITS) { throw new Error(ERR_INVALID_VERSION); } const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, /* @__PURE__ */ new Date()); const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE); const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE); const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0); const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH); let password, rawPassword; if (!passThrough) { password = getOptionValue(zipWriter, options, OPTION_PASSWORD); rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD); } const encryptionStrength = getOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3); const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO); const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true); const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true); const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS); const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE); const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, false); const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL); const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true); const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD); let level = getOptionValue(zipWriter, options, OPTION_LEVEL); let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM); let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR); if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) { dataDescriptor = false; } if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) { dataDescriptor = true; } if (level !== UNDEFINED_VALUE && level != 6) { useCompressionStream = false; } if (!useCompressionStream && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamZlib === UNDEFINED_VALUE)) { level = 0; } let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64); if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) { throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH); } let rawExtraField = new Uint8Array(); const extraField = options[PROPERTY_NAME_EXTRA_FIELD]; if (extraField) { let extraFieldSize = 0; let offset = 0; extraField.forEach((data) => extraFieldSize += 4 + getLength(data)); rawExtraField = new Uint8Array(extraFieldSize); extraField.forEach((data, type) => { if (type > MAX_16_BITS) { throw new Error(ERR_INVALID_EXTRAFIELD_TYPE); } if (getLength(data) > MAX_16_BITS) { throw new Error(ERR_INVALID_EXTRAFIELD_DATA); } arraySet(rawExtraField, new Uint16Array([type]), offset); arraySet(rawExtraField, new Uint16Array([getLength(data)]), offset + 2); arraySet(rawExtraField, data, offset + 4); offset += 4 + getLength(data); }); } let maximumCompressedSize = 0; let maximumEntrySize = 0; let uncompressedSize = 0; if (passThrough) { uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE]; if (uncompressedSize === UNDEFINED_VALUE) { throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE); } } const zip64Enabled = zip64 === true; if (reader) { reader = new GenericReader(reader); await initStream(reader); if (!passThrough) { if (reader.size === UNDEFINED_VALUE) { dataDescriptor = true; if (zip64 || zip64 === UNDEFINED_VALUE) { zip64 = true; uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1; } } else { options.uncompressedSize = uncompressedSize = reader.size; maximumCompressedSize = getMaximumCompressedSize(uncompressedSize); } } else { options.uncompressedSize = uncompressedSize; maximumCompressedSize = getMaximumCompressedSize(uncompressedSize); } } const { diskOffset, diskNumber, maxSize } = zipWriter.writer; const zip64UncompressedSize = zip64Enabled || uncompressedSize > MAX_32_BITS; const zip64CompressedSize = zip64Enabled || maximumCompressedSize > MAX_32_BITS; const zip64Offset = zip64Enabled || zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset > MAX_32_BITS; const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true); const zip64DiskNumberStart = supportZip64SplitFile && zip64Enabled || diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) > MAX_16_BITS; if (zip64Offset || zip64UncompressedSize || zip64CompressedSize || zip64DiskNumberStart) { if (zip64 === false || !keepOrder) { throw new Error(ERR_UNSUPPORTED_FORMAT); } else { zip64 = true; } } zip64 = zip64 || false; const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED); options = Object.assign({}, options, { rawFilename, rawComment, version, versionMadeBy, lastModDate, lastAccessDate, creationDate, rawExtraField, zip64, zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart, password, rawPassword, level, useWebWorkers, encryptionStrength, extendedTimestamp, zipCrypto, bufferedWrite, keepOrder, useUnicodeFileNames, dataDescriptor, dataDescriptorSignature, signal, msDosCompatible, internalFileAttribute: internalFileAttributes, internalFileAttributes, externalFileAttribute: externalFileAttributes, externalFileAttributes, useCompressionStream, passThrough, encrypted: Boolean(password && getLength(password) || rawPassword && getLength(rawPassword)) || passThrough && encrypted, signature: options[PROPERTY_NAME_SIGNATURE], compressionMethod, uncompressedSize, offset: zipWriter.offset - diskOffset, diskNumberStart: diskNumber, uid, gid, setuid, setgid, sticky, unixMode, msdosAttributesRaw, msdosAttributes, unixExternalUpper }); const headerInfo = getHeaderInfo(options); const dataDescriptorInfo = getDataDescriptorInfo(options); const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray); maximumEntrySize = metadataSize + maximumCompressedSize; if (zipWriter.options[OPTION_USDZ]) { maximumEntrySize += maximumEntrySize + 64; } zipWriter.pendingEntriesSize += maximumEntrySize; let fileEntry; try { fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options); } finally { zipWriter.pendingEntriesSize -= maximumEntrySize; } Object.assign(fileEntry, { name, comment, extraField }); return new Entry(fileEntry); } async function getFileEntry(zipWriter, name, reader, entryInfo, options) { const { files, writer } = zipWriter; const { keepOrder, dataDescriptor, signal } = options; const { headerInfo } = entryInfo; const usdz = zipWriter.options[OPTION_USDZ]; const previousFileEntry = Array.from(files.values()).pop(); let fileEntry = {}; let bufferedWrite; let releaseLockWriter; let releaseLockCurrentFileEntry; let writingBufferedEntryData; let writingEntryData; let fileWriter; let blobPromise; files.set(name, fileEntry); try { let lockPreviousFileEntry; if (keepOrder) { lockPreviousFileEntry = previousFileEntry && previousFileEntry.lock; requestLockCurrentFileEntry(); } if ((options.bufferedWrite || zipWriter.writerLocked || zipWriter.bufferedWrites && keepOrder || !dataDescriptor) && !usdz) { fileWriter = new TransformStream(); fileWriter.size = 0; bufferedWrite = true; zipWriter.bufferedWrites++; await initStream(writer); } else { fileWriter = writer; await requestLockWriter(); } await initStream(fileWriter); const { writable, diskOffset } = writer; if (zipWriter.addSplitZipSignature) { delete zipWriter.addSplitZipSignature; const signatureArray = new Uint8Array(4); const signatureArrayView = getDataView(signatureArray); setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE); await writeData(writer, signatureArray); zipWriter.offset += 4; } if (usdz) { appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset); } const { localHeaderView, localHeaderArray } = headerInfo; if (!bufferedWrite) { await lockPreviousFileEntry; await skipDiskIfNeeded(writable); } const { diskNumber } = writer; writingEntryData = true; fileEntry.diskNumberStart = diskNumber; if (bufferedWrite) { blobPromise = new Response(fileWriter.readable).blob(); } else { await writeData(fileWriter, localHeaderArray); } fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options); const { zip64 } = fileEntry; writingEntryData = false; files.set(name, fileEntry); fileEntry.filename = name; if (bufferedWrite) { const [blob] = await Promise.all([blobPromise, fileWriter.writable.getWriter().close(), lockPreviousFileEntry]); await requestLockWriter(); writingBufferedEntryData = true; fileEntry.diskNumberStart = writer.diskNumber; fileEntry.offset = zipWriter.offset - writer.diskOffset; if (zip64) { updateZip64ExtraField(fileEntry); } updateLocalHeader(fileEntry, localHeaderView, options); await skipDiskIfNeeded(writable); await writeData(writer, localHeaderArray); await blob.stream().pipeTo(writable, { preventClose: true, preventAbort: true, signal }); writer.size += fileWriter.size; writingBufferedEntryData = false; } else { fileEntry.offset = zipWriter.offset - diskOffset; if (zip64) { updateZip64ExtraField(fileEntry); } } if (fileEntry.offset > MAX_32_BITS && !zip64) { throw new Error(ERR_UNSUPPORTED_FORMAT); } zipWriter.offset += fileEntry.size; return fileEntry; } catch (error) { if (bufferedWrite && writingBufferedEntryData || !bufferedWrite && writingEntryData) { zipWriter.hasCorruptedEntries = true; if (error) { try { error.corruptedEntry = true; } catch { } } if (bufferedWrite) { zipWriter.offset += fileWriter.size; } else { zipWriter.offset = fileWriter.size; } } files.delete(name); throw error; } finally { if (bufferedWrite) { zipWriter.bufferedWrites--; } if (releaseLockCurrentFileEntry) { releaseLockCurrentFileEntry(); } if (releaseLockWriter) { releaseLockWriter(); } } function requestLockCurrentFileEntry() { fileEntry.lock = new Promise((resolve) => releaseLockCurrentFileEntry = resolve); } async function requestLockWriter() { zipWriter.writerLocked = true; const { lockWriter } = zipWriter; zipWriter.lockWriter = new Promise((resolve) => releaseLockWriter = () => { zipWriter.writerLocked = false; resolve(); }); await lockWriter; } async function skipDiskIfNeeded(writable) { if (getLength(headerInfo.localHeaderArray) > writer.availableSize) { writer.availableSize = 0; await writeData(writable, new Uint8Array()); } } } async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryInfo, config2, options) { const { headerInfo, dataDescriptorInfo, metadataSize } = entryInfo; const { headerArray, headerView, lastModDate, rawLastModDate, encrypted, compressed, version, compressionMethod, rawExtraFieldZip64, localExtraFieldZip64Length, rawExtraFieldExtendedTimestamp, extraFieldExtendedTimestampFlag, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraFieldAES } = headerInfo; const { dataDescriptorArray } = dataDescriptorInfo; const { rawFilename, lastAccessDate, creationDate, password, rawPassword, level, zip64, zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart, zipCrypto, dataDescriptor, directory, executable, versionMadeBy, rawComment, rawExtraField, useWebWorkers, onstart, onprogress, onend, signal, encryptionStrength, extendedTimestamp, msDosCompatible, internalFileAttributes, externalFileAttributes, uid, gid, unixMode, setuid, setgid, sticky, unixExternalUpper, msdosAttributesRaw, msdosAttributes, useCompressionStream, passThrough } = options; const fileEntry = { lock, versionMadeBy, zip64, directory: Boolean(directory), executable: Boolean(executable), filenameUTF8: true, rawFilename, commentUTF8: true, rawComment, rawExtraFieldZip64, localExtraFieldZip64Length, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraFieldAES, rawExtraField, extendedTimestamp, msDosCompatible, internalFileAttributes, externalFileAttributes, diskNumberStart, uid, gid, unixMode, setuid, setgid, sticky, unixExternalUpper, msdosAttributesRaw, msdosAttributes }; let { signature, uncompressedSize } = options; let compressedSize = 0; if (!passThrough) { uncompressedSize = 0; } const { writable } = writer; if (reader) { reader.chunkSize = getChunkSize(config2); const readable = reader.readable; const size = reader.size; const workerOptions = { options: { codecType: CODEC_DEFLATE, level, rawPassword, password, encryptionStrength, zipCrypto: encrypted && zipCrypto, passwordVerification: encrypted && zipCrypto && rawLastModDate >> 8 & MAX_8_BITS, signed: !passThrough, compressed: compressed && !passThrough, encrypted: encrypted && !passThrough, useWebWorkers, useCompressionStream, transferStreams: false }, config: config2, streamOptions: { signal, size, onstart, onprogress, onend } }; try { const result = await runWorker({ readable, writable }, workerOptions); compressedSize = result.outputSize; writer.size += compressedSize; if (!passThrough) { uncompressedSize = result.inputSize; signature = result.signature; } } catch (error) { if (error.outputSize !== UNDEFINED_VALUE) { writer.size += error.outputSize; } throw error; } } setEntryInfo({ signature, compressedSize, uncompressedSize, headerInfo, dataDescriptorInfo }, options); if (dataDescriptor) { await writeData(writer, dataDescriptorArray); } Object.assign(fileEntry, { uncompressedSize, compressedSize, lastModDate, rawLastModDate, creationDate, lastAccessDate, encrypted, zipCrypto, size: metadataSize + compressedSize, compressionMethod, version, headerArray, headerView, signature, extraFieldExtendedTimestampFlag, zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart }); return fileEntry; } function getHeaderInfo(options) { const { rawFilename, lastModDate, lastAccessDate, creationDate, level, zip64, zipCrypto, useUnicodeFileNames, dataDescriptor, directory, rawExtraField, encryptionStrength, extendedTimestamp, passThrough, encrypted, zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart, uncompressedSize, offset, diskNumberStart } = options; let { version, compressionMethod } = options; const compressed = !directory && (level > 0 || level === UNDEFINED_VALUE && compressionMethod !== 0); let rawExtraFieldZip64; const uncompressedFile = passThrough || !compressed; const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || (!zip64UncompressedSize && !zip64CompressedSize || uncompressedFile)); if (zip64) { let rawExtraFieldZip64Length = 4; if (zip64UncompressedSize) { rawExtraFieldZip64Length += 8; } if (zip64CompressedSize) { rawExtraFieldZip64Length += 8; } if (zip64Offset) { rawExtraFieldZip64Length += 8; } if (zip64DiskNumberStart) { rawExtraFieldZip64Length += 4; } rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length); const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64); setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64); setUint16(rawExtraFieldZip64View, 2, getLength(rawExtraFieldZip64) - 4); if (zip64ExtraFieldComplete) { const rawExtraFieldZip64View2 = getDataView(rawExtraFieldZip64); let rawExtraFieldZip64Offset = 4; if (zip64UncompressedSize) { setBigUint64(rawExtraFieldZip64View2, rawExtraFieldZip64Offset, BigInt(uncompressedSize)); rawExtraFieldZip64Offset += 8; } if (zip64CompressedSize && uncompressedFile) { setBigUint64(rawExtraFieldZip64View2, rawExtraFieldZip64Offset, BigInt(uncompressedSize)); rawExtraFieldZip64Offset += 8; } if (zip64Offset) { setBigUint64(rawExtraFieldZip64View2, rawExtraFieldZip64Offset, BigInt(offset)); rawExtraFieldZip64Offset += 8; } if (zip64DiskNumberStart) { setUint32(rawExtraFieldZip64View2, rawExtraFieldZip64Offset, diskNumberStart); rawExtraFieldZip64Offset += 4; } } } else { rawExtraFieldZip64 = new Uint8Array(); } let rawExtraFieldAES; if (encrypted && !zipCrypto) { rawExtraFieldAES = new Uint8Array(getLength(EXTRAFIELD_DATA_AES) + 2); const extraFieldAESView = getDataView(rawExtraFieldAES); setUint16(extraFieldAESView, 0, EXTRAFIELD_TYPE_AES); arraySet(rawExtraFieldAES, EXTRAFIELD_DATA_AES, 2); setUint8(extraFieldAESView, 8, encryptionStrength); } else { rawExtraFieldAES = new Uint8Array(); } let rawExtraFieldNTFS; let rawExtraFieldExtendedTimestamp; let extraFieldExtendedTimestampFlag; if (extendedTimestamp) { rawExtraFieldExtendedTimestamp = new Uint8Array(9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0)); const extraFieldExtendedTimestampView = getDataView(rawExtraFieldExtendedTimestamp); setUint16(extraFieldExtendedTimestampView, 0, EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP); setUint16(extraFieldExtendedTimestampView, 2, getLength(rawExtraFieldExtendedTimestamp) - 4); extraFieldExtendedTimestampFlag = 1 + (lastAccessDate ? 2 : 0) + (creationDate ? 4 : 0); setUint8(extraFieldExtendedTimestampView, 4, extraFieldExtendedTimestampFlag); let offset2 = 5; setUint32(extraFieldExtendedTimestampView, offset2, Math.floor(lastModDate.getTime() / 1e3)); offset2 += 4; if (lastAccessDate) { setUint32(extraFieldExtendedTimestampView, offset2, Math.floor(lastAccessDate.getTime() / 1e3)); offset2 += 4; } if (creationDate) { setUint32(extraFieldExtendedTimestampView, offset2, Math.floor(creationDate.getTime() / 1e3)); } try { rawExtraFieldNTFS = new Uint8Array(36); const extraFieldNTFSView = getDataView(rawExtraFieldNTFS); const lastModTimeNTFS = getTimeNTFS(lastModDate); setUint16(extraFieldNTFSView, 0, EXTRAFIELD_TYPE_NTFS); setUint16(extraFieldNTFSView, 2, 32); setUint16(extraFieldNTFSView, 8, EXTRAFIELD_TYPE_NTFS_TAG1); setUint16(extraFieldNTFSView, 10, 24); setBigUint64(extraFieldNTFSView, 12, lastModTimeNTFS); setBigUint64(extraFieldNTFSView, 20, getTimeNTFS(lastAccessDate) || lastModTimeNTFS); setBigUint64(extraFieldNTFSView, 28, getTimeNTFS(creationDate) || lastModTimeNTFS); } catch { rawExtraFieldNTFS = new Uint8Array(); } } else { rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array(); } let rawExtraFieldUnix; try { const { uid, gid, unixMode, setuid, setgid, sticky, unixExtraFieldType } = options; if (unixExtraFieldType && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE)) { const uidBytes = packUnixId(uid); const gidBytes = packUnixId(gid); let modeArray = new Uint8Array(); if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && unixMode !== UNDEFINED_VALUE) { let modeToWrite = unixMode & MAX_16_BITS; if (setuid) { modeToWrite |= FILE_ATTR_UNIX_SETUID_MASK; } if (setgid) { modeToWrite |= FILE_ATTR_UNIX_SETGID_MASK; } if (sticky) { modeToWrite |= FILE_ATTR_UNIX_STICKY_MASK; } modeArray = new Uint8Array(2); const modeDataView = new DataView(modeArray.buffer); modeDataView.setUint16(0, modeToWrite, true); } const payloadLength = 3 + uidBytes.length + gidBytes.length + modeArray.length; rawExtraFieldUnix = new Uint8Array(4 + payloadLength); const rawExtraFieldUnixView = getDataView(rawExtraFieldUnix); setUint16(rawExtraFieldUnixView, 0, unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE ? EXTRAFIELD_TYPE_INFOZIP : EXTRAFIELD_TYPE_UNIX); setUint16(rawExtraFieldUnixView, 2, payloadLength); setUint8(rawExtraFieldUnixView, 4, 1); setUint8(rawExtraFieldUnixView, 5, uidBytes.length); let offset2 = 6; arraySet(rawExtraFieldUnix, uidBytes, offset2); offset2 += uidBytes.length; setUint8(rawExtraFieldUnixView, offset2, gidBytes.length); offset2++; arraySet(rawExtraFieldUnix, gidBytes, offset2); offset2 += gidBytes.length; arraySet(rawExtraFieldUnix, modeArray, offset2); } else { rawExtraFieldUnix = new Uint8Array(); } } catch { rawExtraFieldUnix = new Uint8Array(); } if (compressionMethod === UNDEFINED_VALUE) { compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE; } if (zip64) { version = version > VERSION_ZIP64 ? version : VERSION_ZIP64; } if (encrypted && !zipCrypto) { version = version > VERSION_AES ? version : VERSION_AES; rawExtraFieldAES[9] = compressionMethod; compressionMethod = COMPRESSION_METHOD_AES; } const localExtraFieldZip64Length = zip64ExtraFieldComplete ? getLength(rawExtraFieldZip64) : 0; const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField); const { headerArray, headerView, rawLastModDate } = getHeaderArrayData({ version, bitFlag: getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod), compressionMethod, uncompressedSize, lastModDate: lastModDate < MIN_DATE ? MIN_DATE : lastModDate > MAX_DATE ? MAX_DATE : lastModDate, rawFilename, zip64CompressedSize, zip64UncompressedSize, extraFieldLength }); let localHeaderOffset = HEADER_SIZE; const localHeaderArray = new Uint8Array(localHeaderOffset + getLength(rawFilename) + extraFieldLength); const localHeaderView = getDataView(localHeaderArray); setUint32(localHeaderView, 0, LOCAL_FILE_HEADER_SIGNATURE); arraySet(localHeaderArray, headerArray, 4); arraySet(localHeaderArray, rawFilename, localHeaderOffset); localHeaderOffset += getLength(rawFilename); if (zip64ExtraFieldComplete) { arraySet(localHeaderArray, rawExtraFieldZip64, localHeaderOffset); } localHeaderOffset += localExtraFieldZip64Length; arraySet(localHeaderArray, rawExtraFieldAES, localHeaderOffset); localHeaderOffset += getLength(rawExtraFieldAES); arraySet(localHeaderArray, rawExtraFieldExtendedTimestamp, localHeaderOffset); localHeaderOffset += getLength(rawExtraFieldExtendedTimestamp); arraySet(localHeaderArray, rawExtraFieldNTFS, localHeaderOffset); localHeaderOffset += getLength(rawExtraFieldNTFS); arraySet(localHeaderArray, rawExtraFieldUnix, localHeaderOffset); localHeaderOffset += getLength(rawExtraFieldUnix); arraySet(localHeaderArray, rawExtraField, localHeaderOffset); if (dataDescriptor) { setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + 4, 0); setUint32(localHeaderView, HEADER_OFFSET_UNCOMPRESSED_SIZE + 4, 0); } return { localHeaderArray, localHeaderView, headerArray, headerView, lastModDate, rawLastModDate, encrypted, compressed, version, compressionMethod, extraFieldExtendedTimestampFlag, rawExtraFieldZip64, localExtraFieldZip64Length, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraFieldAES, extraFieldLength }; } function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) { const { headerInfo } = entryInfo; let { localHeaderArray, extraFieldLength } = headerInfo; let localHeaderArrayView = getDataView(localHeaderArray); let extraBytesLength = 64 - (zipWriterOffset + getLength(localHeaderArray)) % 64; if (extraBytesLength < 4) { extraBytesLength += 64; } const rawExtraFieldUSDZ = new Uint8Array(extraBytesLength); const extraFieldUSDZView = getDataView(rawExtraFieldUSDZ); setUint16(extraFieldUSDZView, 0, EXTRAFIELD_TYPE_USDZ); setUint16(extraFieldUSDZView, 2, extraBytesLength - 2); const previousLocalHeaderArray = localHeaderArray; headerInfo.localHeaderArray = localHeaderArray = new Uint8Array(getLength(previousLocalHeaderArray) + extraBytesLength); arraySet(localHeaderArray, previousLocalHeaderArray); arraySet(localHeaderArray, rawExtraFieldUSDZ, getLength(previousLocalHeaderArray)); localHeaderArrayView = getDataView(localHeaderArray); setUint16(localHeaderArrayView, 28, extraFieldLength + extraBytesLength); entryInfo.metadataSize += extraBytesLength; } function packUnixId(id) { if (id === UNDEFINED_VALUE) { return new Uint8Array(); } else { const dataArray = new Uint8Array(4); const dataView = getDataView(dataArray); dataView.setUint32(0, id, true); let length = 4; while (length > 1 && dataArray[length - 1] === 0) { length--; } return dataArray.subarray(0, length); } } function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) { if (msdosAttributesRaw !== UNDEFINED_VALUE) { msdosAttributesRaw = msdosAttributesRaw & MAX_8_BITS; } else if (msdosAttributes !== UNDEFINED_VALUE) { const { readOnly, hidden, system, directory: msdDir, archive } = msdosAttributes; let raw = 0; if (readOnly) raw |= FILE_ATTR_MSDOS_READONLY_MASK; if (hidden) raw |= FILE_ATTR_MSDOS_HIDDEN_MASK; if (system) raw |= FILE_ATTR_MSDOS_SYSTEM_MASK; if (msdDir) raw |= FILE_ATTR_MSDOS_DIR_MASK; if (archive) raw |= FILE_ATTR_MSDOS_ARCHIVE_MASK; msdosAttributesRaw = raw & MAX_8_BITS; } if (msdosAttributes === UNDEFINED_VALUE) { msdosAttributes = { readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK), hidden: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_HIDDEN_MASK), system: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_SYSTEM_MASK), directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK), archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK) }; } return { msdosAttributesRaw, msdosAttributes }; } function getDataDescriptorInfo({ zip64, dataDescriptor, dataDescriptorSignature }) { let dataDescriptorArray = new Uint8Array(); let dataDescriptorView, dataDescriptorOffset = 0; let dataDescriptorLength = zip64 ? DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH : DATA_DESCRIPTOR_RECORD_LENGTH; if (dataDescriptorSignature) { dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH; } if (dataDescriptor) { dataDescriptorArray = new Uint8Array(dataDescriptorLength); dataDescriptorView = getDataView(dataDescriptorArray); if (dataDescriptorSignature) { dataDescriptorOffset = DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH; setUint32(dataDescriptorView, 0, DATA_DESCRIPTOR_RECORD_SIGNATURE); } } return { dataDescriptorArray, dataDescriptorView, dataDescriptorOffset }; } function setEntryInfo({ signature, compressedSize, uncompressedSize, headerInfo, dataDescriptorInfo }, { zip64, zipCrypto, dataDescriptor }) { const { headerView, encrypted } = headerInfo; const { dataDescriptorView, dataDescriptorOffset } = dataDescriptorInfo; if ((!encrypted || zipCrypto) && signature !== UNDEFINED_VALUE) { setUint32(headerView, HEADER_OFFSET_SIGNATURE, signature); if (dataDescriptor) { setUint32(dataDescriptorView, dataDescriptorOffset, signature); } } if (zip64) { if (dataDescriptor) { setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize)); setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize)); } } else { setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, compressedSize); setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize); if (dataDescriptor) { setUint32(dataDescriptorView, dataDescriptorOffset + 4, compressedSize); setUint32(dataDescriptorView, dataDescriptorOffset + 8, uncompressedSize); } } } function updateLocalHeader({ rawFilename, encrypted, zip64, localExtraFieldZip64Length, signature, compressedSize, uncompressedSize, offset, diskNumberStart, zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart }, localHeaderView, { dataDescriptor }) { if (!dataDescriptor) { if (!encrypted) { setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + 4, signature); } if (!zip64) { setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + 4, compressedSize); setUint32(localHeaderView, HEADER_OFFSET_UNCOMPRESSED_SIZE + 4, uncompressedSize); } } if (zip64) { if (localExtraFieldZip64Length) { let localHeaderOffset = HEADER_SIZE + getLength(rawFilename) + 4; if (zip64UncompressedSize) { setBigUint64(localHeaderView, localHeaderOffset, BigInt(uncompressedSize)); localHeaderOffset += 8; } if (zip64CompressedSize) { setBigUint64(localHeaderView, localHeaderOffset, BigInt(compressedSize)); localHeaderOffset += 8; } if (zip64Offset) { setBigUint64(localHeaderView, localHeaderOffset, BigInt(offset)); localHeaderOffset += 8; } if (zip64DiskNumberStart) { setUint32(localHeaderView, localHeaderOffset, diskNumberStart); } } } } function updateZip64ExtraField({ compressedSize, uncompressedSize, offset, diskNumberStart, zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart, rawExtraFieldZip64 }) { const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64); let rawExtraFieldZip64Offset = 4; if (zip64UncompressedSize) { setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize)); rawExtraFieldZip64Offset += 8; } if (zip64CompressedSize) { setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize)); rawExtraFieldZip64Offset += 8; } if (zip64Offset) { setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset)); rawExtraFieldZip64Offset += 8; } if (zip64DiskNumberStart) { setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart); } } async function closeFile(zipWriter, comment, options) { const { files, writer } = zipWriter; const { diskOffset } = writer; let { diskNumber } = writer; let offset = 0; let directoryDataLength = 0; let directoryOffset = zipWriter.offset - diskOffset; let filesLength = files.size; for (const [, fileEntry] of files) { const { rawFilename, rawExtraFieldZip64, rawExtraFieldAES, rawComment, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, extendedTimestamp, extraFieldExtendedTimestampFlag, lastModDate } = fileEntry; let rawExtraFieldTimestamp; if (extendedTimestamp) { rawExtraFieldTimestamp = new Uint8Array(9); const extraFieldExtendedTimestampView = getDataView(rawExtraFieldTimestamp); setUint16(extraFieldExtendedTimestampView, 0, EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP); setUint16(extraFieldExtendedTimestampView, 2, 5); setUint8(extraFieldExtendedTimestampView, 4, extraFieldExtendedTimestampFlag); setUint32(extraFieldExtendedTimestampView, 5, Math.floor(lastModDate.getTime() / 1e3)); } else { rawExtraFieldTimestamp = new Uint8Array(); } fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp; directoryDataLength += 46 + getLength( rawFilename, rawComment, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraFieldTimestamp, rawExtraField ); } const directoryArray = new Uint8Array(directoryDataLength); const directoryView = getDataView(directoryArray); await initStream(writer); let directoryDiskOffset = 0; for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) { const { offset: fileEntryOffset, rawFilename, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawComment, versionMadeBy, headerArray, headerView, zip64: zip642, zip64UncompressedSize, zip64CompressedSize, zip64DiskNumberStart, zip64Offset, internalFileAttributes, externalFileAttributes, diskNumberStart, uncompressedSize, compressedSize } = fileEntry; const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField); setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE); setUint16(directoryView, offset + 4, versionMadeBy); if (!zip64UncompressedSize) { setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize); } if (!zip64CompressedSize) { setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, compressedSize); } arraySet(directoryArray, headerArray, offset + 6); let directoryOffset2 = offset + HEADER_SIZE; setUint16(directoryView, directoryOffset2, extraFieldLength); directoryOffset2 += 2; setUint16(directoryView, directoryOffset2, getLength(rawComment)); directoryOffset2 += 2; setUint16(directoryView, directoryOffset2, zip642 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart); directoryOffset2 += 2; setUint16(directoryView, directoryOffset2, internalFileAttributes); directoryOffset2 += 2; if (externalFileAttributes) { setUint32(directoryView, directoryOffset2, externalFileAttributes); } directoryOffset2 += 4; setUint32(directoryView, directoryOffset2, zip642 && zip64Offset ? MAX_32_BITS : fileEntryOffset); directoryOffset2 += 4; arraySet(directoryArray, rawFilename, directoryOffset2); directoryOffset2 += getLength(rawFilename); arraySet(directoryArray, rawExtraFieldZip64, directoryOffset2); directoryOffset2 += getLength(rawExtraFieldZip64); arraySet(directoryArray, rawExtraFieldAES, directoryOffset2); directoryOffset2 += getLength(rawExtraFieldAES); arraySet(directoryArray, rawExtraFieldExtendedTimestamp, directoryOffset2); directoryOffset2 += getLength(rawExtraFieldExtendedTimestamp); arraySet(directoryArray, rawExtraFieldNTFS, directoryOffset2); directoryOffset2 += getLength(rawExtraFieldNTFS); arraySet(directoryArray, rawExtraFieldUnix, directoryOffset2); directoryOffset2 += getLength(rawExtraFieldUnix); arraySet(directoryArray, rawExtraField, directoryOffset2); directoryOffset2 += getLength(rawExtraField); arraySet(directoryArray, rawComment, directoryOffset2); directoryOffset2 += getLength(rawComment); if (offset - directoryDiskOffset > writer.availableSize) { writer.availableSize = 0; await writeData(writer, directoryArray.slice(directoryDiskOffset, offset)); directoryDiskOffset = offset; } offset = directoryOffset2; if (options.onprogress) { try { await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry)); } catch { } } } await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray); let lastDiskNumber = writer.diskNumber; const { availableSize } = writer; if (availableSize < END_OF_CENTRAL_DIR_LENGTH) { lastDiskNumber++; } let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64); if (directoryOffset > MAX_32_BITS || directoryDataLength > MAX_32_BITS || filesLength > MAX_16_BITS || lastDiskNumber > MAX_16_BITS) { if (zip64 === false) { throw new Error(ERR_UNSUPPORTED_FORMAT); } else { zip64 = true; } } const endOfdirectoryArray = new Uint8Array(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH); const endOfdirectoryView = getDataView(endOfdirectoryArray); offset = 0; if (zip64) { setUint32(endOfdirectoryView, 0, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE); setBigUint64(endOfdirectoryView, 4, BigInt(44)); setUint16(endOfdirectoryView, 12, 45); setUint16(endOfdirectoryView, 14, 45); setUint32(endOfdirectoryView, 16, lastDiskNumber); setUint32(endOfdirectoryView, 20, diskNumber); setBigUint64(endOfdirectoryView, 24, BigInt(filesLength)); setBigUint64(endOfdirectoryView, 32, BigInt(filesLength)); setBigUint64(endOfdirectoryView, 40, BigInt(directoryDataLength)); setBigUint64(endOfdirectoryView, 48, BigInt(directoryOffset)); setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE); setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength)); setUint32(endOfdirectoryView, 72, lastDiskNumber + 1); const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true); if (supportZip64SplitFile) { lastDiskNumber = MAX_16_BITS; diskNumber = MAX_16_BITS; } filesLength = MAX_16_BITS; directoryOffset = MAX_32_BITS; directoryDataLength = MAX_32_BITS; offset += ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH; } setUint32(endOfdirectoryView, offset, END_OF_CENTRAL_DIR_SIGNATURE); setUint16(endOfdirectoryView, offset + 4, lastDiskNumber); setUint16(endOfdirectoryView, offset + 6, diskNumber); setUint16(endOfdirectoryView, offset + 8, filesLength); setUint16(endOfdirectoryView, offset + 10, filesLength); setUint32(endOfdirectoryView, offset + 12, directoryDataLength); setUint32(endOfdirectoryView, offset + 16, directoryOffset); const commentLength = getLength(comment); if (commentLength) { if (commentLength <= MAX_16_BITS) { setUint16(endOfdirectoryView, offset + 20, commentLength); } else { throw new Error(ERR_INVALID_COMMENT); } } await writeData(writer, endOfdirectoryArray); if (commentLength) { await writeData(writer, comment); } } async function writeData(writer, array) { const { writable } = writer; const streamWriter = writable.getWriter(); try { await streamWriter.ready; writer.size += getLength(array); await streamWriter.write(array); } finally { streamWriter.releaseLock(); } } function getTimeNTFS(date) { if (date) { return (BigInt(date.getTime()) + BigInt(116444736e5)) * BigInt(1e4); } } function getOptionValue(zipWriter, options, name, defaultValue) { const result = options[name] === UNDEFINED_VALUE ? zipWriter.options[name] : options[name]; return result === UNDEFINED_VALUE ? defaultValue : result; } function getMaximumCompressedSize(uncompressedSize) { return uncompressedSize + 5 * (Math.floor(uncompressedSize / 16383) + 1); } function setUint8(view, offset, value) { view.setUint8(offset, value); } function setUint16(view, offset, value) { view.setUint16(offset, value, true); } function setUint32(view, offset, value) { view.setUint32(offset, value, true); } function setBigUint64(view, offset, value) { view.setBigUint64(offset, value, true); } function arraySet(array, typedArray, offset) { array.set(typedArray, offset); } function getDataView(array) { return new DataView(array.buffer); } function getLength(...arrayLikes) { let result = 0; arrayLikes.forEach((arrayLike) => arrayLike && (result += arrayLike.length)); return result; } function getHeaderArrayData({ version, bitFlag, compressionMethod, uncompressedSize, compressedSize, lastModDate, rawFilename, zip64CompressedSize, zip64UncompressedSize, extraFieldLength }) { const headerArray = new Uint8Array(HEADER_SIZE - 4); const headerView = getDataView(headerArray); setUint16(headerView, 0, version); setUint16(headerView, 2, bitFlag); setUint16(headerView, 4, compressionMethod); const dateArray = new Uint32Array(1); const dateView = getDataView(dateArray); setUint16(dateView, 0, (lastModDate.getHours() << 6 | lastModDate.getMinutes()) << 5 | lastModDate.getSeconds() / 2); setUint16(dateView, 2, (lastModDate.getFullYear() - 1980 << 4 | lastModDate.getMonth() + 1) << 5 | lastModDate.getDate()); const rawLastModDate = dateArray[0]; setUint32(headerView, 6, rawLastModDate); if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) { setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, zip64CompressedSize ? MAX_32_BITS : compressedSize); } if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) { setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, zip64UncompressedSize ? MAX_32_BITS : uncompressedSize); } setUint16(headerView, 22, getLength(rawFilename)); setUint16(headerView, 24, extraFieldLength); return { headerArray, headerView, rawLastModDate }; } function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) { let bitFlag = 0; if (useUnicodeFileNames) { bitFlag = bitFlag | BITFLAG_LANG_ENCODING_FLAG; } if (dataDescriptor) { bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR; } if (compressionMethod == COMPRESSION_METHOD_DEFLATE || compressionMethod == COMPRESSION_METHOD_DEFLATE_64) { if (level >= 0 && level <= 3) { bitFlag = bitFlag | BITFLAG_LEVEL_SUPER_FAST_MASK; } if (level > 3 && level <= 5) { bitFlag = bitFlag | BITFLAG_LEVEL_FAST_MASK; } if (level == 9) { bitFlag = bitFlag | BITFLAG_LEVEL_MAX_MASK; } } if (encrypted) { bitFlag = bitFlag | BITFLAG_ENCRYPTED; } return bitFlag; } try { configure({ baseURI: _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("downloader.js", document.baseURI).href }); } catch { } const A = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; function g(g2) { let B; g2({ wasmURI: () => (B || (B = "data:application/wasm;base64," + ((g3) => { g3 = ((g4) => { const B3 = (g4 = (g4 + "").replace(/[^A-Za-z0-9+/=]/g, "")).length, E2 = []; for (let I2 = 0; B3 > I2; I2 += 4) { const B4 = A.indexOf(g4[I2]) << 18 | A.indexOf(g4[I2 + 1]) << 12 | (63 & A.indexOf(g4[I2 + 2])) << 6 | 63 & A.indexOf(g4[I2 + 3]); E2.push(B4 >> 16 & 255), "=" !== g4[I2 + 2] && E2.push(B4 >> 8 & 255), "=" !== g4[I2 + 3] && E2.push(255 & B4); } return new Uint8Array(E2); })(g3); let B2 = new Uint8Array(1024), E = 0; for (let A2 = 0; A2 < g3.length; ) { const C = g3[A2++]; if (128 & C) { const Q = 3 + (127 & C), D = g3[A2++] << 8 | g3[A2++], o = E - D; I(E + Q); for (let A3 = 0; Q > A3; A3++) B2[E++] = B2[o + A3]; } else { const Q = C; I(E + Q); for (let I2 = 0; Q > I2 && A2 < g3.length; I2++) B2[E++] = g3[A2++]; } } return ((g4) => { let B3 = ""; const E2 = g4.length; let I2 = 0; for (; E2 > I2 + 2; I2 += 3) { const E3 = g4[I2] << 16 | g4[I2 + 1] << 8 | g4[I2 + 2]; B3 += A[E3 >> 18 & 63] + A[E3 >> 12 & 63] + A[E3 >> 6 & 63] + A[63 & E3]; } const C = E2 - I2; if (1 === C) { const E3 = g4[I2] << 16; B3 += A[E3 >> 18 & 63] + A[E3 >> 12 & 63] + "=="; } else if (2 === C) { const E3 = g4[I2] << 16 | g4[I2 + 1] << 8; B3 += A[E3 >> 18 & 63] + A[E3 >> 12 & 63] + A[E3 >> 6 & 63] + "="; } return B3; })(new Uint8Array(B2.buffer.slice(0, E))); function I(A2) { if (B2.length < A2) { let g4 = 2 * B2.length; for (; A2 > g4; ) g4 *= 2; const I2 = new Uint8Array(g4); I2.set(B2.subarray(0, E)), B2 = I2; } } })("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BAGZgAAEAVmAAAQB2YAABAE5gAAEAbmAAAQBeYAABAH5gAAEAQWAAAQBhYAABAFFgAAEAcWAAAQBJYAABAGlgAAEAWWAAAQB5YAABAEVgAAEAZWAAAQBVYAABAHVgAAEATWAAAQBtYAABAF1gAAEAfWAAAQBDYAABAGNgAAEAU2AAAQBzYAABIARMwIArYAABAFtgAAEAe2AAAQBHYAABAGdgAAEAV2AAAQB3YAABAE9gAAEAb2AAAQBfYAABAH9gAAEAROAAMIFEwEJAJOAAAgBk4AACAFTgAAIAVOAAAgB04AACAHTgAAIATOAAAgBM4AACAGzgAAIAbOAAAgBc4AACAFzgAAIAfOAAAgB84AACAELgAAIgBDagAQCgAAEgAAIAUuAAAgBS4AACAHLgAAIAcuAAAgBK4AACAErgAAIAauAAAgBq4AACAFrgAAIAWuAAAgB64AACAHrgAAIARuAAAgBG4AACAGbgAAIAZuAAAgBW4AACAFbgAAIAduAAAgB24AACAE7gAAIATuAAAgBu4AACAG7gAAIAXuAAAgBe4AACAH7gAAIAfuAAAiBA7YBB4AACAGHgAAIAYeAAAgBR4AACAFHgAAIAceAAAgBx4AACAEngAAIASeAAAgBp4AACAGngAAIAWeAAAgBZ4AACAHngAAIAeeAAAgBF4AACAEXgAAIAZeAAAgBl4AACAFXgAAIAVeAAAgB14AACAHXgAAIATeAAAgBN4AACAG3gAAIAbeAAAgBd4AACAF3gAAIAfeAAAgB94AACAEPgAAIAQ+AAAgBj4AACAGPgAAIAU+AAAgBT4AACAHPgAAIAc+AAAgBL4AACAEvgAAIAa+AAAgBr4AACAFvgAAIAW+AAAgB74AACAHvgAAIAR+AAAgBH4AACAGfgAAIAZ+AAAgBX4AACAFfgAAIAd+AAAgB34AACAE/gAAIAT+AAAgBv4AACAG/gAAIAX+AAAgBf4AACAH/gAAIAf+AAAiBBAoBQIAABAEggAAEAWCAAAQBEIAABAFQgAAEATCAAAQBcIIFVgMHAEiAAAQBKIAABAFogAAEARiAAAQBWIAABAE4gAAEAXiAAAQBBIAABAFEgAAEASSAAAQBZIAABAEUgAAEAVSAAAQBNIAABAF0gAAEAQOAAEIBg4AABAFDgAAEAcOAAAQBI4AABAGjgAAEAWOAAAQB44AABIC+K4AAdIECxgEFgABcAQWCBUoBFIAABAEMgAAEARyAAASAvlaABEQBBYIGBAEaggXqAQWAA9QBBYADuAEFgAOcgE92gAAEARGAAAQBCYAABAEZgAAEgQACARWAAAQBDYAABAEdgAAEgL59gAKkgQZAAQWAAiyBBaYBBYABtAEFgD3fAxsLTYMfuYcABIC+rooABIEHUYkABAEEjAAEAQWKAAQEQbAcC4C9CosAS40AO4UALwEGhAAEgQWIgQAEgQEKgQAEgQGSgQAEgIS2ggAEAQuEAAQBDIQABIAF24FHeQTgHQsjhQBfhQXLAhARgAVtBgcJBgoFC4A6uAQNAg4BgAclBJQeC2mFAJCFAIiFAICFAHiBAGiBAFyBBh8BEIAABAEUgAAEARiAAAQBHIAABAEggAAEASiAAAQBMIAABAE4gAAEAUCAAAQBUIAABIEGvQFwgAAEAYCAAAQBoIAABAHAgAAEAeCAAG8DHwtyjQBvgQBrgQBngQBjgQBfgQBbgQBXgQBTgQBPgQBLgQBHgQBDgQE8AYCvAEGAUc0CC22BAMcBBIAAAgEIgAAEgQEzgQJLARCAAA6DAAyBnqyAqmuEACSBB3OBAE8BCIAACIEAGIUADIEIt4MADAEggQCUgDKEgQBrAYCBCC8BBIMADIA/SAoBABAMAEGRIQv/gCUfgMDAgIKxBQgJCQoKgEk3gAABAQ2AAAEBDoAAAQEPgAABARCEAAEBEYQAAQEShAABAROEAAEBFIwAAQEVjAABARaMAAEBF4wAAQEYnAABARmcAAEBGpwAAQEbmwABARyBffsEBAQFBYHB1QEHgAABAQiEAAGAXSqCAAEBCowAAYAnsooAAYEBMJkAAYEBTJkAAYEBaLkAAYEBpLkAAYIDdYABzoUBvI0BqJ0BkLwBgAIbHLwAAQEdvAABgA9PgH05A9AqAQ==")), B) }); } let wasm, malloc, free, memory; function setWasmExports(wasmAPI) { wasm = wasmAPI; ({ malloc, free, memory } = wasm); if (typeof malloc !== "function" || typeof free !== "function" || !memory) { wasm = malloc = free = memory = null; throw new Error("Invalid WASM module"); } } function _make(isCompress, type, options = {}) { const level = typeof options.level === "number" ? options.level : -1; const outBufferSize = typeof options.outBuffer === "number" ? options.outBuffer : 64 * 1024; const inBufferSize = typeof options.inBufferSize === "number" ? options.inBufferSize : 64 * 1024; return new TransformStream({ start() { let result; this.out = malloc(outBufferSize); this.in = malloc(inBufferSize); this.inBufferSize = inBufferSize; this._scratch = new Uint8Array(outBufferSize); if (isCompress) { this._process = wasm.deflate_process; this._last_consumed = wasm.deflate_last_consumed; this._end = wasm.deflate_end; this.streamHandle = wasm.deflate_new(); if (type === "gzip") { result = wasm.deflate_init_gzip(this.streamHandle, level); } else if (type === "deflate-raw") { result = wasm.deflate_init_raw(this.streamHandle, level); } else { result = wasm.deflate_init(this.streamHandle, level); } } else { if (type === "deflate64-raw") { this._process = wasm.inflate9_process; this._last_consumed = wasm.inflate9_last_consumed; this._end = wasm.inflate9_end; this.streamHandle = wasm.inflate9_new(); result = wasm.inflate9_init_raw(this.streamHandle); } else { this._process = wasm.inflate_process; this._last_consumed = wasm.inflate_last_consumed; this._end = wasm.inflate_end; this.streamHandle = wasm.inflate_new(); if (type === "deflate-raw") { result = wasm.inflate_init_raw(this.streamHandle); } else if (type === "gzip") { result = wasm.inflate_init_gzip(this.streamHandle); } else { result = wasm.inflate_init(this.streamHandle); } } } if (result !== 0) { throw new Error("init failed:" + result); } }, transform(chunk, controller) { try { const buffer = chunk; const heap = new Uint8Array(memory.buffer); const process = this._process; const last_consumed = this._last_consumed; const out = this.out; const scratch = this._scratch; let offset = 0; while (offset < buffer.length) { const toRead = Math.min(buffer.length - offset, 32 * 1024); if (!this.in || this.inBufferSize < toRead) { if (this.in && free) { free(this.in); } this.in = malloc(toRead); this.inBufferSize = toRead; } heap.set(buffer.subarray(offset, offset + toRead), this.in); const result = process(this.streamHandle, this.in, toRead, out, outBufferSize, 0); const prod = result & 16777215; if (prod) { scratch.set(heap.subarray(out, out + prod), 0); controller.enqueue(scratch.slice(0, prod)); } if (!isCompress) { const code = result >> 24 & 255; const signedCode = code & 128 ? code - 256 : code; if (signedCode < 0) { throw new Error("process error:" + signedCode); } } const consumed = last_consumed(this.streamHandle); if (consumed === 0) { break; } offset += consumed; } } catch (error) { if (this._end && this.streamHandle) { this._end(this.streamHandle); } if (this.in && free) { free(this.in); } if (this.out && free) { free(this.out); } controller.error(error); } }, flush(controller) { try { const heap = new Uint8Array(memory.buffer); const process = this._process; const out = this.out; const scratch = this._scratch; while (true) { const result = process(this.streamHandle, 0, 0, out, outBufferSize, 4); const produced = result & 16777215; const code = result >> 24 & 255; if (!isCompress) { const signedCode = code & 128 ? code - 256 : code; if (signedCode < 0) { throw new Error("process error:" + signedCode); } } if (produced) { scratch.set(heap.subarray(out, out + produced), 0); controller.enqueue(scratch.slice(0, produced)); } if (code === 1 || produced === 0) { break; } } } catch (error) { controller.error(error); } finally { if (this._end && this.streamHandle) { const result = this._end(this.streamHandle); if (result !== 0) { controller.error(new Error("end error:" + result)); } } if (this.in && free) { free(this.in); } if (this.out && free) { free(this.out); } } } }); } class CompressionStreamZlib { constructor(type = "deflate", options) { return _make(true, type, options); } } class DecompressionStreamZlib { constructor(type = "deflate", options) { return _make(false, type, options); } } let initializedModule = false; async function initModule(wasmURI, { baseURI }) { if (!initializedModule) { let arrayBuffer, uri; try { try { uri = new URL(wasmURI, baseURI); } catch { } const response = await fetch(uri); arrayBuffer = await response.arrayBuffer(); } catch (error) { if (wasmURI.startsWith("data:application/wasm;base64,")) { arrayBuffer = arrayBufferFromDataURI(wasmURI); } else { throw error; } } const wasmInstance = await WebAssembly.instantiate(arrayBuffer); setWasmExports(wasmInstance.instance.exports); initializedModule = true; } } function arrayBufferFromDataURI(dataURI) { const base64 = dataURI.split(",")[1]; const binary = atob(base64); const len = binary.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; ++i) { bytes[i] = binary.charCodeAt(i); } return bytes.buffer; } let modulePromise; g(configure); configureWorker({ initModule: (config2) => { if (!modulePromise) { let { wasmURI } = config2; if (typeof wasmURI == FUNCTION_TYPE) { wasmURI = wasmURI(); } modulePromise = initModule(wasmURI, config2); } return modulePromise; } }); configure({ CompressionStreamZlib, DecompressionStreamZlib }); const table = { "application": { "andrew-inset": "ez", "annodex": "anx", "atom+xml": "atom", "atomcat+xml": "atomcat", "atomserv+xml": "atomsrv", "bbolin": "lin", "cu-seeme": "cu", "davmount+xml": "davmount", "dsptype": "tsp", "ecmascript": [ "es", "ecma" ], "futuresplash": "spl", "hta": "hta", "java-archive": "jar", "java-serialized-object": "ser", "java-vm": "class", "m3g": "m3g", "mac-binhex40": "hqx", "mathematica": [ "nb", "ma", "mb" ], "msaccess": "mdb", "msword": [ "doc", "dot", "wiz" ], "mxf": "mxf", "oda": "oda", "ogg": "ogx", "pdf": "pdf", "pgp-keys": "key", "pgp-signature": [ "asc", "sig" ], "pics-rules": "prf", "postscript": [ "ps", "ai", "eps", "epsi", "epsf", "eps2", "eps3" ], "rar": "rar", "rdf+xml": "rdf", "rss+xml": "rss", "rtf": "rtf", "xhtml+xml": [ "xhtml", "xht" ], "xml": [ "xml", "xsl", "xsd", "xpdl" ], "xspf+xml": "xspf", "zip": "zip", "vnd.android.package-archive": "apk", "vnd.cinderella": "cdy", "vnd.google-earth.kml+xml": "kml", "vnd.google-earth.kmz": "kmz", "vnd.mozilla.xul+xml": "xul", "vnd.ms-excel": [ "xls", "xlb", "xlt", "xlm", "xla", "xlc", "xlw" ], "vnd.ms-pki.seccat": "cat", "vnd.ms-pki.stl": "stl", "vnd.ms-powerpoint": [ "ppt", "pps", "pot", "ppa", "pwz" ], "vnd.oasis.opendocument.chart": "odc", "vnd.oasis.opendocument.database": "odb", "vnd.oasis.opendocument.formula": "odf", "vnd.oasis.opendocument.graphics": "odg", "vnd.oasis.opendocument.graphics-template": "otg", "vnd.oasis.opendocument.image": "odi", "vnd.oasis.opendocument.presentation": "odp", "vnd.oasis.opendocument.presentation-template": "otp", "vnd.oasis.opendocument.spreadsheet": "ods", "vnd.oasis.opendocument.spreadsheet-template": "ots", "vnd.oasis.opendocument.text": "odt", "vnd.oasis.opendocument.text-master": [ "odm", "otm" ], "vnd.oasis.opendocument.text-template": "ott", "vnd.oasis.opendocument.text-web": "oth", "vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx", "vnd.openxmlformats-officedocument.spreadsheetml.template": "xltx", "vnd.openxmlformats-officedocument.presentationml.presentation": "pptx", "vnd.openxmlformats-officedocument.presentationml.slideshow": "ppsx", "vnd.openxmlformats-officedocument.presentationml.template": "potx", "vnd.openxmlformats-officedocument.wordprocessingml.document": "docx", "vnd.openxmlformats-officedocument.wordprocessingml.template": "dotx", "vnd.smaf": "mmf", "vnd.stardivision.calc": "sdc", "vnd.stardivision.chart": "sds", "vnd.stardivision.draw": "sda", "vnd.stardivision.impress": "sdd", "vnd.stardivision.math": [ "sdf", "smf" ], "vnd.stardivision.writer": [ "sdw", "vor" ], "vnd.stardivision.writer-global": "sgl", "vnd.sun.xml.calc": "sxc", "vnd.sun.xml.calc.template": "stc", "vnd.sun.xml.draw": "sxd", "vnd.sun.xml.draw.template": "std", "vnd.sun.xml.impress": "sxi", "vnd.sun.xml.impress.template": "sti", "vnd.sun.xml.math": "sxm", "vnd.sun.xml.writer": "sxw", "vnd.sun.xml.writer.global": "sxg", "vnd.sun.xml.writer.template": "stw", "vnd.symbian.install": [ "sis", "sisx" ], "vnd.visio": [ "vsd", "vst", "vss", "vsw", "vsdx", "vssx", "vstx", "vssm", "vstm" ], "vnd.wap.wbxml": "wbxml", "vnd.wap.wmlc": "wmlc", "vnd.wap.wmlscriptc": "wmlsc", "vnd.wordperfect": "wpd", "vnd.wordperfect5.1": "wp5", "x-123": "wk", "x-7z-compressed": "7z", "x-abiword": "abw", "x-apple-diskimage": "dmg", "x-bcpio": "bcpio", "x-bittorrent": "torrent", "x-cbr": [ "cbr", "cba", "cbt", "cb7" ], "x-cbz": "cbz", "x-cdf": [ "cdf", "cda" ], "x-cdlink": "vcd", "x-chess-pgn": "pgn", "x-cpio": "cpio", "x-csh": "csh", "x-director": [ "dir", "dxr", "cst", "cct", "cxt", "w3d", "fgd", "swa" ], "x-dms": "dms", "x-doom": "wad", "x-dvi": "dvi", "x-httpd-eruby": "rhtml", "x-font": "pcf.Z", "x-freemind": "mm", "x-gnumeric": "gnumeric", "x-go-sgf": "sgf", "x-graphing-calculator": "gcf", "x-gtar": [ "gtar", "taz" ], "x-hdf": "hdf", "x-httpd-php": [ "phtml", "pht", "php" ], "x-httpd-php-source": "phps", "x-httpd-php3": "php3", "x-httpd-php3-preprocessed": "php3p", "x-httpd-php4": "php4", "x-httpd-php5": "php5", "x-ica": "ica", "x-info": "info", "x-internet-signup": [ "ins", "isp" ], "x-iphone": "iii", "x-iso9660-image": "iso", "x-java-jnlp-file": "jnlp", "x-jmol": "jmz", "x-killustrator": "kil", "x-latex": "latex", "x-lyx": "lyx", "x-lzx": "lzx", "x-maker": [ "frm", "fb", "fbdoc" ], "x-ms-wmd": "wmd", "x-msdos-program": [ "com", "exe", "bat", "dll" ], "x-netcdf": [ "nc" ], "x-ns-proxy-autoconfig": [ "pac", "dat" ], "x-nwc": "nwc", "x-object": "o", "x-oz-application": "oza", "x-pkcs7-certreqresp": "p7r", "x-python-code": [ "pyc", "pyo" ], "x-qgis": [ "qgs", "shp", "shx" ], "x-quicktimeplayer": "qtl", "x-redhat-package-manager": [ "rpm", "rpa" ], "x-ruby": "rb", "x-sh": "sh", "x-shar": "shar", "x-shockwave-flash": [ "swf", "swfl" ], "x-silverlight": "scr", "x-stuffit": "sit", "x-sv4cpio": "sv4cpio", "x-sv4crc": "sv4crc", "x-tar": "tar", "x-tex-gf": "gf", "x-tex-pk": "pk", "x-texinfo": [ "texinfo", "texi" ], "x-trash": [ "~", "%", "bak", "old", "sik" ], "x-ustar": "ustar", "x-wais-source": "src", "x-wingz": "wz", "x-x509-ca-cert": [ "crt", "der", "cer" ], "x-xcf": "xcf", "x-xfig": "fig", "x-xpinstall": "xpi", "applixware": "aw", "atomsvc+xml": "atomsvc", "ccxml+xml": "ccxml", "cdmi-capability": "cdmia", "cdmi-container": "cdmic", "cdmi-domain": "cdmid", "cdmi-object": "cdmio", "cdmi-queue": "cdmiq", "docbook+xml": "dbk", "dssc+der": "dssc", "dssc+xml": "xdssc", "emma+xml": "emma", "epub+zip": "epub", "exi": "exi", "font-tdpfr": "pfr", "gml+xml": "gml", "gpx+xml": "gpx", "gxf": "gxf", "hyperstudio": "stk", "inkml+xml": [ "ink", "inkml" ], "ipfix": "ipfix", "jsonml+json": "jsonml", "lost+xml": "lostxml", "mads+xml": "mads", "marc": "mrc", "marcxml+xml": "mrcx", "mathml+xml": [ "mathml", "mml" ], "mbox": "mbox", "mediaservercontrol+xml": "mscml", "metalink+xml": "metalink", "metalink4+xml": "meta4", "mets+xml": "mets", "mods+xml": "mods", "mp21": [ "m21", "mp21" ], "mp4": "mp4s", "oebps-package+xml": "opf", "omdoc+xml": "omdoc", "onenote": [ "onetoc", "onetoc2", "onetmp", "onepkg" ], "oxps": "oxps", "patch-ops-error+xml": "xer", "pgp-encrypted": "pgp", "pkcs10": "p10", "pkcs7-mime": [ "p7m", "p7c" ], "pkcs7-signature": "p7s", "pkcs8": "p8", "pkix-attr-cert": "ac", "pkix-crl": "crl", "pkix-pkipath": "pkipath", "pkixcmp": "pki", "pls+xml": "pls", "prs.cww": "cww", "pskc+xml": "pskcxml", "reginfo+xml": "rif", "relax-ng-compact-syntax": "rnc", "resource-lists+xml": "rl", "resource-lists-diff+xml": "rld", "rls-services+xml": "rs", "rpki-ghostbusters": "gbr", "rpki-manifest": "mft", "rpki-roa": "roa", "rsd+xml": "rsd", "sbml+xml": "sbml", "scvp-cv-request": "scq", "scvp-cv-response": "scs", "scvp-vp-request": "spq", "scvp-vp-response": "spp", "sdp": "sdp", "set-payment-initiation": "setpay", "set-registration-initiation": "setreg", "shf+xml": "shf", "sparql-query": "rq", "sparql-results+xml": "srx", "srgs": "gram", "srgs+xml": "grxml", "sru+xml": "sru", "ssdl+xml": "ssdl", "ssml+xml": "ssml", "tei+xml": [ "tei", "teicorpus" ], "thraud+xml": "tfi", "timestamped-data": "tsd", "vnd.3gpp.pic-bw-large": "plb", "vnd.3gpp.pic-bw-small": "psb", "vnd.3gpp.pic-bw-var": "pvb", "vnd.3gpp2.tcap": "tcap", "vnd.3m.post-it-notes": "pwn", "vnd.accpac.simply.aso": "aso", "vnd.accpac.simply.imp": "imp", "vnd.acucobol": "acu", "vnd.acucorp": [ "atc", "acutc" ], "vnd.adobe.air-application-installer-package+zip": "air", "vnd.adobe.formscentral.fcdt": "fcdt", "vnd.adobe.fxp": [ "fxp", "fxpl" ], "vnd.adobe.xdp+xml": "xdp", "vnd.adobe.xfdf": "xfdf", "vnd.ahead.space": "ahead", "vnd.airzip.filesecure.azf": "azf", "vnd.airzip.filesecure.azs": "azs", "vnd.amazon.ebook": "azw", "vnd.americandynamics.acc": "acc", "vnd.amiga.ami": "ami", "vnd.anser-web-certificate-issue-initiation": "cii", "vnd.anser-web-funds-transfer-initiation": "fti", "vnd.antix.game-component": "atx", "vnd.apple.installer+xml": "mpkg", "vnd.apple.mpegurl": "m3u8", "vnd.aristanetworks.swi": "swi", "vnd.astraea-software.iota": "iota", "vnd.audiograph": "aep", "vnd.blueice.multipass": "mpm", "vnd.bmi": "bmi", "vnd.businessobjects": "rep", "vnd.chemdraw+xml": "cdxml", "vnd.chipnuts.karaoke-mmd": "mmd", "vnd.claymore": "cla", "vnd.cloanto.rp9": "rp9", "vnd.clonk.c4group": [ "c4g", "c4d", "c4f", "c4p", "c4u" ], "vnd.cluetrust.cartomobile-config": "c11amc", "vnd.cluetrust.cartomobile-config-pkg": "c11amz", "vnd.commonspace": "csp", "vnd.contact.cmsg": "cdbcmsg", "vnd.cosmocaller": "cmc", "vnd.crick.clicker": "clkx", "vnd.crick.clicker.keyboard": "clkk", "vnd.crick.clicker.palette": "clkp", "vnd.crick.clicker.template": "clkt", "vnd.crick.clicker.wordbank": "clkw", "vnd.criticaltools.wbs+xml": "wbs", "vnd.ctc-posml": "pml", "vnd.cups-ppd": "ppd", "vnd.curl.car": "car", "vnd.curl.pcurl": "pcurl", "vnd.dart": "dart", "vnd.data-vision.rdz": "rdz", "vnd.dece.data": [ "uvf", "uvvf", "uvd", "uvvd" ], "vnd.dece.ttml+xml": [ "uvt", "uvvt" ], "vnd.dece.unspecified": [ "uvx", "uvvx" ], "vnd.dece.zip": [ "uvz", "uvvz" ], "vnd.denovo.fcselayout-link": "fe_launch", "vnd.dna": "dna", "vnd.dolby.mlp": "mlp", "vnd.dpgraph": "dpg", "vnd.dreamfactory": "dfac", "vnd.ds-keypoint": "kpxx", "vnd.dvb.ait": "ait", "vnd.dvb.service": "svc", "vnd.dynageo": "geo", "vnd.ecowin.chart": "mag", "vnd.enliven": "nml", "vnd.epson.esf": "esf", "vnd.epson.msf": "msf", "vnd.epson.quickanime": "qam", "vnd.epson.salt": "slt", "vnd.epson.ssf": "ssf", "vnd.eszigno3+xml": [ "es3", "et3" ], "vnd.ezpix-album": "ez2", "vnd.ezpix-package": "ez3", "vnd.fdf": "fdf", "vnd.fdsn.mseed": "mseed", "vnd.fdsn.seed": [ "seed", "dataless" ], "vnd.flographit": "gph", "vnd.fluxtime.clip": "ftc", "vnd.framemaker": [ "fm", "frame", "maker", "book" ], "vnd.frogans.fnc": "fnc", "vnd.frogans.ltf": "ltf", "vnd.fsc.weblaunch": "fsc", "vnd.fujitsu.oasys": "oas", "vnd.fujitsu.oasys2": "oa2", "vnd.fujitsu.oasys3": "oa3", "vnd.fujitsu.oasysgp": "fg5", "vnd.fujitsu.oasysprs": "bh2", "vnd.fujixerox.ddd": "ddd", "vnd.fujixerox.docuworks": "xdw", "vnd.fujixerox.docuworks.binder": "xbd", "vnd.fuzzysheet": "fzs", "vnd.genomatix.tuxedo": "txd", "vnd.geogebra.file": "ggb", "vnd.geogebra.tool": "ggt", "vnd.geometry-explorer": [ "gex", "gre" ], "vnd.geonext": "gxt", "vnd.geoplan": "g2w", "vnd.geospace": "g3w", "vnd.gmx": "gmx", "vnd.grafeq": [ "gqf", "gqs" ], "vnd.groove-account": "gac", "vnd.groove-help": "ghf", "vnd.groove-identity-message": "gim", "vnd.groove-injector": "grv", "vnd.groove-tool-message": "gtm", "vnd.groove-tool-template": "tpl", "vnd.groove-vcard": "vcg", "vnd.hal+xml": "hal", "vnd.handheld-entertainment+xml": "zmm", "vnd.hbci": "hbci", "vnd.hhe.lesson-player": "les", "vnd.hp-hpgl": "hpgl", "vnd.hp-hpid": "hpid", "vnd.hp-hps": "hps", "vnd.hp-jlyt": "jlt", "vnd.hp-pcl": "pcl", "vnd.hp-pclxl": "pclxl", "vnd.hydrostatix.sof-data": "sfd-hdstx", "vnd.ibm.minipay": "mpy", "vnd.ibm.modcap": [ "afp", "listafp", "list3820" ], "vnd.ibm.rights-management": "irm", "vnd.ibm.secure-container": "sc", "vnd.iccprofile": [ "icc", "icm" ], "vnd.igloader": "igl", "vnd.immervision-ivp": "ivp", "vnd.immervision-ivu": "ivu", "vnd.insors.igm": "igm", "vnd.intercon.formnet": [ "xpw", "xpx" ], "vnd.intergeo": "i2g", "vnd.intu.qbo": "qbo", "vnd.intu.qfx": "qfx", "vnd.ipunplugged.rcprofile": "rcprofile", "vnd.irepository.package+xml": "irp", "vnd.is-xpr": "xpr", "vnd.isac.fcs": "fcs", "vnd.jam": "jam", "vnd.jcp.javame.midlet-rms": "rms", "vnd.jisp": "jisp", "vnd.joost.joda-archive": "joda", "vnd.kahootz": [ "ktz", "ktr" ], "vnd.kde.karbon": "karbon", "vnd.kde.kchart": "chrt", "vnd.kde.kformula": "kfo", "vnd.kde.kivio": "flw", "vnd.kde.kontour": "kon", "vnd.kde.kpresenter": [ "kpr", "kpt" ], "vnd.kde.kspread": "ksp", "vnd.kde.kword": [ "kwd", "kwt" ], "vnd.kenameaapp": "htke", "vnd.kidspiration": "kia", "vnd.kinar": [ "kne", "knp" ], "vnd.koan": [ "skp", "skd", "skt", "skm" ], "vnd.kodak-descriptor": "sse", "vnd.las.las+xml": "lasxml", "vnd.llamagraphics.life-balance.desktop": "lbd", "vnd.llamagraphics.life-balance.exchange+xml": "lbe", "vnd.lotus-1-2-3": "123", "vnd.lotus-approach": "apr", "vnd.lotus-freelance": "pre", "vnd.lotus-notes": "nsf", "vnd.lotus-organizer": "org", "vnd.lotus-screencam": "scm", "vnd.lotus-wordpro": "lwp", "vnd.macports.portpkg": "portpkg", "vnd.mcd": "mcd", "vnd.medcalcdata": "mc1", "vnd.mediastation.cdkey": "cdkey", "vnd.mfer": "mwf", "vnd.mfmp": "mfm", "vnd.micrografx.flo": "flo", "vnd.micrografx.igx": "igx", "vnd.mif": "mif", "vnd.mobius.daf": "daf", "vnd.mobius.dis": "dis", "vnd.mobius.mbk": "mbk", "vnd.mobius.mqy": "mqy", "vnd.mobius.msl": "msl", "vnd.mobius.plc": "plc", "vnd.mobius.txf": "txf", "vnd.mophun.application": "mpn", "vnd.mophun.certificate": "mpc", "vnd.ms-artgalry": "cil", "vnd.ms-cab-compressed": "cab", "vnd.ms-excel.addin.macroenabled.12": "xlam", "vnd.ms-excel.sheet.binary.macroenabled.12": "xlsb", "vnd.ms-excel.sheet.macroenabled.12": "xlsm", "vnd.ms-excel.template.macroenabled.12": "xltm", "vnd.ms-fontobject": "eot", "vnd.ms-htmlhelp": "chm", "vnd.ms-ims": "ims", "vnd.ms-lrm": "lrm", "vnd.ms-officetheme": "thmx", "vnd.ms-powerpoint.addin.macroenabled.12": "ppam", "vnd.ms-powerpoint.presentation.macroenabled.12": "pptm", "vnd.ms-powerpoint.slide.macroenabled.12": "sldm", "vnd.ms-powerpoint.slideshow.macroenabled.12": "ppsm", "vnd.ms-powerpoint.template.macroenabled.12": "potm", "vnd.ms-project": [ "mpp", "mpt" ], "vnd.ms-word.document.macroenabled.12": "docm", "vnd.ms-word.template.macroenabled.12": "dotm", "vnd.ms-works": [ "wps", "wks", "wcm", "wdb" ], "vnd.ms-wpl": "wpl", "vnd.ms-xpsdocument": "xps", "vnd.mseq": "mseq", "vnd.musician": "mus", "vnd.muvee.style": "msty", "vnd.mynfc": "taglet", "vnd.neurolanguage.nlu": "nlu", "vnd.nitf": [ "ntf", "nitf" ], "vnd.noblenet-directory": "nnd", "vnd.noblenet-sealer": "nns", "vnd.noblenet-web": "nnw", "vnd.nokia.n-gage.data": "ngdat", "vnd.nokia.n-gage.symbian.install": "n-gage", "vnd.nokia.radio-preset": "rpst", "vnd.nokia.radio-presets": "rpss", "vnd.novadigm.edm": "edm", "vnd.novadigm.edx": "edx", "vnd.novadigm.ext": "ext", "vnd.oasis.opendocument.chart-template": "otc", "vnd.oasis.opendocument.formula-template": "odft", "vnd.oasis.opendocument.image-template": "oti", "vnd.olpc-sugar": "xo", "vnd.oma.dd2+xml": "dd2", "vnd.openofficeorg.extension": "oxt", "vnd.openxmlformats-officedocument.presentationml.slide": "sldx", "vnd.osgeo.mapguide.package": "mgp", "vnd.osgi.dp": "dp", "vnd.osgi.subsystem": "esa", "vnd.palm": [ "pdb", "pqa", "oprc" ], "vnd.pawaafile": "paw", "vnd.pg.format": "str", "vnd.pg.osasli": "ei6", "vnd.picsel": "efif", "vnd.pmi.widget": "wg", "vnd.pocketlearn": "plf", "vnd.powerbuilder6": "pbd", "vnd.previewsystems.box": "box", "vnd.proteus.magazine": "mgz", "vnd.publishare-delta-tree": "qps", "vnd.pvi.ptid1": "ptid", "vnd.quark.quarkxpress": [ "qxd", "qxt", "qwd", "qwt", "qxl", "qxb" ], "vnd.realvnc.bed": "bed", "vnd.recordare.musicxml": "mxl", "vnd.recordare.musicxml+xml": "musicxml", "vnd.rig.cryptonote": "cryptonote", "vnd.rn-realmedia": "rm", "vnd.rn-realmedia-vbr": "rmvb", "vnd.route66.link66+xml": "link66", "vnd.sailingtracker.track": "st", "vnd.seemail": "see", "vnd.sema": "sema", "vnd.semd": "semd", "vnd.semf": "semf", "vnd.shana.informed.formdata": "ifm", "vnd.shana.informed.formtemplate": "itp", "vnd.shana.informed.interchange": "iif", "vnd.shana.informed.package": "ipk", "vnd.simtech-mindmapper": [ "twd", "twds" ], "vnd.smart.teacher": "teacher", "vnd.solent.sdkm+xml": [ "sdkm", "sdkd" ], "vnd.spotfire.dxp": "dxp", "vnd.spotfire.sfs": "sfs", "vnd.stepmania.package": "smzip", "vnd.stepmania.stepchart": "sm", "vnd.sus-calendar": [ "sus", "susp" ], "vnd.svd": "svd", "vnd.syncml+xml": "xsm", "vnd.syncml.dm+wbxml": "bdm", "vnd.syncml.dm+xml": "xdm", "vnd.tao.intent-module-archive": "tao", "vnd.tcpdump.pcap": [ "pcap", "cap", "dmp" ], "vnd.tmobile-livetv": "tmo", "vnd.trid.tpt": "tpt", "vnd.triscape.mxs": "mxs", "vnd.trueapp": "tra", "vnd.ufdl": [ "ufd", "ufdl" ], "vnd.uiq.theme": "utz", "vnd.umajin": "umj", "vnd.unity": "unityweb", "vnd.uoml+xml": "uoml", "vnd.vcx": "vcx", "vnd.visionary": "vis", "vnd.vsf": "vsf", "vnd.webturbo": "wtb", "vnd.wolfram.player": "nbp", "vnd.wqd": "wqd", "vnd.wt.stf": "stf", "vnd.xara": "xar", "vnd.xfdl": "xfdl", "vnd.yamaha.hv-dic": "hvd", "vnd.yamaha.hv-script": "hvs", "vnd.yamaha.hv-voice": "hvp", "vnd.yamaha.openscoreformat": "osf", "vnd.yamaha.openscoreformat.osfpvg+xml": "osfpvg", "vnd.yamaha.smaf-audio": "saf", "vnd.yamaha.smaf-phrase": "spf", "vnd.yellowriver-custom-menu": "cmp", "vnd.zul": [ "zir", "zirz" ], "vnd.zzazz.deck+xml": "zaz", "voicexml+xml": "vxml", "widget": "wgt", "winhlp": "hlp", "wsdl+xml": "wsdl", "wspolicy+xml": "wspolicy", "x-ace-compressed": "ace", "x-authorware-bin": [ "aab", "x32", "u32", "vox" ], "x-authorware-map": "aam", "x-authorware-seg": "aas", "x-blorb": [ "blb", "blorb" ], "x-bzip": "bz", "x-bzip2": [ "bz2", "boz" ], "x-cfs-compressed": "cfs", "x-chat": "chat", "x-conference": "nsc", "x-dgc-compressed": "dgc", "x-dtbncx+xml": "ncx", "x-dtbook+xml": "dtb", "x-dtbresource+xml": "res", "x-eva": "eva", "x-font-bdf": "bdf", "x-font-ghostscript": "gsf", "x-font-linux-psf": "psf", "x-font-pcf": "pcf", "x-font-snf": "snf", "x-font-ttf": [ "ttf", "ttc" ], "x-font-type1": [ "pfa", "pfb", "pfm", "afm" ], "x-freearc": "arc", "x-gca-compressed": "gca", "x-glulx": "ulx", "x-gramps-xml": "gramps", "x-install-instructions": "install", "x-lzh-compressed": [ "lzh", "lha" ], "x-mie": "mie", "x-mobipocket-ebook": [ "prc", "mobi" ], "x-ms-application": "application", "x-ms-shortcut": "lnk", "x-ms-xbap": "xbap", "x-msbinder": "obd", "x-mscardfile": "crd", "x-msclip": "clp", "application/x-ms-installer": "msi", "x-msmediaview": [ "mvb", "m13", "m14" ], "x-msmetafile": [ "wmf", "wmz", "emf", "emz" ], "x-msmoney": "mny", "x-mspublisher": "pub", "x-msschedule": "scd", "x-msterminal": "trm", "x-mswrite": "wri", "x-nzb": "nzb", "x-pkcs12": [ "p12", "pfx" ], "x-pkcs7-certificates": [ "p7b", "spc" ], "x-research-info-systems": "ris", "x-silverlight-app": "xap", "x-sql": "sql", "x-stuffitx": "sitx", "x-subrip": "srt", "x-t3vm-image": "t3", "x-tex-tfm": "tfm", "x-tgif": "obj", "x-xliff+xml": "xlf", "x-xz": "xz", "x-zmachine": [ "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8" ], "xaml+xml": "xaml", "xcap-diff+xml": "xdf", "xenc+xml": "xenc", "xml-dtd": "dtd", "xop+xml": "xop", "xproc+xml": "xpl", "xslt+xml": "xslt", "xv+xml": [ "mxml", "xhvml", "xvml", "xvm" ], "yang": "yang", "yin+xml": "yin", "envoy": "evy", "fractals": "fif", "internet-property-stream": "acx", "olescript": "axs", "vnd.ms-outlook": "msg", "vnd.ms-pkicertstore": "sst", "x-compress": "z", "x-perfmon": [ "pma", "pmc", "pmr", "pmw" ], "ynd.ms-pkipko": "pko", "gzip": [ "gz", "tgz" ], "smil+xml": [ "smi", "smil" ], "vnd.debian.binary-package": [ "deb", "udeb" ], "vnd.hzn-3d-crossword": "x3d", "vnd.sqlite3": [ "db", "sqlite", "sqlite3", "db-wal", "sqlite-wal", "db-shm", "sqlite-shm" ], "vnd.wap.sic": "sic", "vnd.wap.slc": "slc", "x-krita": [ "kra", "krz" ], "x-perl": [ "pm", "pl" ], "yaml": [ "yaml", "yml" ] }, "audio": { "amr": "amr", "amr-wb": "awb", "annodex": "axa", "basic": [ "au", "snd" ], "flac": "flac", "midi": [ "mid", "midi", "kar", "rmi" ], "mpeg": [ "mpga", "mpega", "mp3", "m4a", "mp2a", "m2a", "m3a" ], "mpegurl": "m3u", "ogg": [ "oga", "ogg", "spx" ], "prs.sid": "sid", "x-aiff": "aifc", "x-gsm": "gsm", "x-ms-wma": "wma", "x-ms-wax": "wax", "x-pn-realaudio": "ram", "x-realaudio": "ra", "x-sd2": "sd2", "adpcm": "adp", "mp4": "mp4a", "s3m": "s3m", "silk": "sil", "vnd.dece.audio": [ "uva", "uvva" ], "vnd.digital-winds": "eol", "vnd.dra": "dra", "vnd.dts": "dts", "vnd.dts.hd": "dtshd", "vnd.lucent.voice": "lvp", "vnd.ms-playready.media.pya": "pya", "vnd.nuera.ecelp4800": "ecelp4800", "vnd.nuera.ecelp7470": "ecelp7470", "vnd.nuera.ecelp9600": "ecelp9600", "vnd.rip": "rip", "webm": "weba", "x-caf": "caf", "x-matroska": "mka", "x-pn-realaudio-plugin": "rmp", "xm": "xm", "aac": "aac", "aiff": [ "aiff", "aif", "aff" ], "opus": "opus", "wav": "wav" }, "chemical": { "x-alchemy": "alc", "x-cache": [ "cac", "cache" ], "x-cache-csf": "csf", "x-cactvs-binary": [ "cbin", "cascii", "ctab" ], "x-cdx": "cdx", "x-chem3d": "c3d", "x-cif": "cif", "x-cmdf": "cmdf", "x-cml": "cml", "x-compass": "cpa", "x-crossfire": "bsd", "x-csml": [ "csml", "csm" ], "x-ctx": "ctx", "x-cxf": [ "cxf", "cef" ], "x-embl-dl-nucleotide": [ "emb", "embl" ], "x-gamess-input": [ "inp", "gam", "gamin" ], "x-gaussian-checkpoint": [ "fch", "fchk" ], "x-gaussian-cube": "cub", "x-gaussian-input": [ "gau", "gjc", "gjf" ], "x-gaussian-log": "gal", "x-gcg8-sequence": "gcg", "x-genbank": "gen", "x-hin": "hin", "x-isostar": [ "istr", "ist" ], "x-jcamp-dx": [ "jdx", "dx" ], "x-kinemage": "kin", "x-macmolecule": "mcm", "x-macromodel-input": "mmod", "x-mdl-molfile": "mol", "x-mdl-rdfile": "rd", "x-mdl-rxnfile": "rxn", "x-mdl-sdfile": "sd", "x-mdl-tgf": "tgf", "x-mmcif": "mcif", "x-mol2": "mol2", "x-molconn-Z": "b", "x-mopac-graph": "gpt", "x-mopac-input": [ "mop", "mopcrt", "zmt" ], "x-mopac-out": "moo", "x-ncbi-asn1": "asn", "x-ncbi-asn1-ascii": [ "prt", "ent" ], "x-ncbi-asn1-binary": "val", "x-rosdal": "ros", "x-swissprot": "sw", "x-vamas-iso14976": "vms", "x-vmd": "vmd", "x-xtel": "xtel", "x-xyz": "xyz" }, "font": { "otf": "otf", "woff": "woff", "woff2": "woff2" }, "image": { "gif": "gif", "ief": "ief", "jpeg": [ "jpeg", "jpg", "jpe", "jfif", "jfif-tbnl", "jif" ], "pcx": "pcx", "png": "png", "svg+xml": [ "svg", "svgz" ], "tiff": [ "tiff", "tif" ], "vnd.djvu": [ "djvu", "djv" ], "vnd.wap.wbmp": "wbmp", "x-canon-cr2": "cr2", "x-canon-crw": "crw", "x-cmu-raster": "ras", "x-coreldraw": "cdr", "x-coreldrawpattern": "pat", "x-coreldrawtemplate": "cdt", "x-corelphotopaint": "cpt", "x-epson-erf": "erf", "x-icon": "ico", "x-jg": "art", "x-jng": "jng", "x-nikon-nef": "nef", "x-olympus-orf": "orf", "x-portable-anymap": "pnm", "x-portable-bitmap": "pbm", "x-portable-graymap": "pgm", "x-portable-pixmap": "ppm", "x-rgb": "rgb", "x-xbitmap": "xbm", "x-xpixmap": "xpm", "x-xwindowdump": "xwd", "bmp": "bmp", "cgm": "cgm", "g3fax": "g3", "ktx": "ktx", "prs.btif": "btif", "sgi": "sgi", "vnd.dece.graphic": [ "uvi", "uvvi", "uvg", "uvvg" ], "vnd.dwg": "dwg", "vnd.dxf": "dxf", "vnd.fastbidsheet": "fbs", "vnd.fpx": "fpx", "vnd.fst": "fst", "vnd.fujixerox.edmics-mmr": "mmr", "vnd.fujixerox.edmics-rlc": "rlc", "vnd.ms-modi": "mdi", "vnd.ms-photo": "wdp", "vnd.net-fpx": "npx", "vnd.xiff": "xif", "webp": "webp", "x-3ds": "3ds", "x-cmx": "cmx", "x-freehand": [ "fh", "fhc", "fh4", "fh5", "fh7" ], "x-pict": [ "pic", "pct" ], "x-tga": "tga", "cis-cod": "cod", "avif": "avifs", "heic": [ "heif", "heic" ], "pjpeg": [ "pjpg" ], "vnd.adobe.photoshop": "psd", "x-adobe-dng": "dng", "x-fuji-raf": "raf", "x-icns": "icns", "x-kodak-dcr": "dcr", "x-kodak-k25": "k25", "x-kodak-kdc": "kdc", "x-minolta-mrw": "mrw", "x-panasonic-raw": [ "raw", "rw2", "rwl" ], "x-pentax-pef": [ "pef", "ptx" ], "x-sigma-x3f": "x3f", "x-sony-arw": "arw", "x-sony-sr2": "sr2", "x-sony-srf": "srf" }, "message": { "rfc822": [ "eml", "mime", "mht", "mhtml", "nws" ] }, "model": { "iges": [ "igs", "iges" ], "mesh": [ "msh", "mesh", "silo" ], "vrml": [ "wrl", "vrml" ], "x3d+vrml": [ "x3dv", "x3dvz" ], "x3d+xml": "x3dz", "x3d+binary": [ "x3db", "x3dbz" ], "vnd.collada+xml": "dae", "vnd.dwf": "dwf", "vnd.gdl": "gdl", "vnd.gtw": "gtw", "vnd.mts": "mts", "vnd.usdz+zip": "usdz", "vnd.vtu": "vtu" }, "text": { "cache-manifest": [ "manifest", "appcache" ], "calendar": [ "ics", "icz", "ifb" ], "css": "css", "csv": "csv", "h323": "323", "html": [ "html", "htm", "shtml", "stm" ], "iuls": "uls", "plain": [ "txt", "text", "brf", "conf", "def", "list", "log", "in", "bas", "diff", "ksh" ], "richtext": "rtx", "scriptlet": [ "sct", "wsc" ], "texmacs": "tm", "tab-separated-values": "tsv", "vnd.sun.j2me.app-descriptor": "jad", "vnd.wap.wml": "wml", "vnd.wap.wmlscript": "wmls", "x-bibtex": "bib", "x-boo": "boo", "x-c++hdr": [ "h++", "hpp", "hxx", "hh" ], "x-c++src": [ "c++", "cpp", "cxx", "cc" ], "x-component": "htc", "x-dsrc": "d", "x-diff": "patch", "x-haskell": "hs", "x-java": "java", "x-literate-haskell": "lhs", "x-moc": "moc", "x-pascal": [ "p", "pas", "pp", "inc" ], "x-pcs-gcd": "gcd", "x-python": "py", "x-scala": "scala", "x-setext": "etx", "x-tcl": [ "tcl", "tk" ], "x-tex": [ "tex", "ltx", "sty", "cls" ], "x-vcalendar": "vcs", "x-vcard": "vcf", "n3": "n3", "prs.lines.tag": "dsc", "sgml": [ "sgml", "sgm" ], "troff": [ "t", "tr", "roff", "man", "me", "ms" ], "turtle": "ttl", "uri-list": [ "uri", "uris", "urls" ], "vcard": "vcard", "vnd.curl": "curl", "vnd.curl.dcurl": "dcurl", "vnd.curl.scurl": "scurl", "vnd.curl.mcurl": "mcurl", "vnd.dvb.subtitle": "sub", "vnd.fly": "fly", "vnd.fmi.flexstor": "flx", "vnd.graphviz": "gv", "vnd.in3d.3dml": "3dml", "vnd.in3d.spot": "spot", "x-asm": [ "s", "asm" ], "x-c": [ "c", "h", "dic" ], "x-fortran": [ "f", "for", "f77", "f90" ], "x-opml": "opml", "x-nfo": "nfo", "x-sfv": "sfv", "x-uuencode": "uu", "webviewhtml": "htt", "javascript": "js", "json": "json", "markdown": [ "md", "markdown", "mdown", "markdn" ], "vnd.wap.si": "si", "vnd.wap.sl": "sl" }, "video": { "avif": "avif", "3gpp": "3gp", "annodex": "axv", "dl": "dl", "dv": [ "dif", "dv" ], "fli": "fli", "gl": "gl", "mpeg": [ "mpeg", "mpg", "mpe", "m1v", "m2v", "mp2", "mpa", "mpv2" ], "mp4": [ "mp4", "mp4v", "mpg4" ], "quicktime": [ "qt", "mov" ], "ogg": "ogv", "vnd.mpegurl": [ "mxu", "m4u" ], "x-flv": "flv", "x-la-asf": [ "lsf", "lsx" ], "x-mng": "mng", "x-ms-asf": [ "asf", "asx", "asr" ], "x-ms-wm": "wm", "x-ms-wmv": "wmv", "x-ms-wmx": "wmx", "x-ms-wvx": "wvx", "x-msvideo": "avi", "x-sgi-movie": "movie", "x-matroska": [ "mpv", "mkv", "mk3d", "mks" ], "3gpp2": "3g2", "h261": "h261", "h263": "h263", "h264": "h264", "jpeg": "jpgv", "jpm": [ "jpm", "jpgm" ], "mj2": [ "mj2", "mjp2" ], "vnd.dece.hd": [ "uvh", "uvvh" ], "vnd.dece.mobile": [ "uvm", "uvvm" ], "vnd.dece.pd": [ "uvp", "uvvp" ], "vnd.dece.sd": [ "uvs", "uvvs" ], "vnd.dece.video": [ "uvv", "uvvv" ], "vnd.dvb.file": "dvb", "vnd.fvt": "fvt", "vnd.ms-playready.media.pyv": "pyv", "vnd.uvvu.mp4": [ "uvu", "uvvu" ], "vnd.vivo": "viv", "webm": "webm", "x-f4v": "f4v", "x-m4v": "m4v", "x-ms-vob": "vob", "x-smv": "smv", "mp2t": "ts" }, "x-conference": { "x-cooltalk": "ice" }, "x-world": { "x-vrml": [ "vrm", "flr", "wrz", "xaf", "xof" ] } }; (() => { const mimeTypes = {}; for (const type of Object.keys(table)) { for (const subtype of Object.keys(table[type])) { const value = table[type][subtype]; if (typeof value == "string") { mimeTypes[value] = type + "/" + subtype; } else { for (let indexMimeType = 0; indexMimeType < value.length; indexMimeType++) { mimeTypes[value[indexMimeType]] = type + "/" + subtype; } } } } return mimeTypes; })(); t(configure); class Node { constructor(value) { __publicField(this, "value"); __publicField(this, "next"); this.value = value; } } class Queue { constructor() { __privateAdd(this, _head); __privateAdd(this, _tail); __privateAdd(this, _size); this.clear(); } enqueue(value) { const node = new Node(value); if (__privateGet(this, _head)) { __privateGet(this, _tail).next = node; __privateSet(this, _tail, node); } else { __privateSet(this, _head, node); __privateSet(this, _tail, node); } __privateWrapper(this, _size)._++; } dequeue() { const current = __privateGet(this, _head); if (!current) { return; } __privateSet(this, _head, __privateGet(this, _head).next); __privateWrapper(this, _size)._--; if (!__privateGet(this, _head)) { __privateSet(this, _tail, void 0); } return current.value; } peek() { if (!__privateGet(this, _head)) { return; } return __privateGet(this, _head).value; } clear() { __privateSet(this, _head, void 0); __privateSet(this, _tail, void 0); __privateSet(this, _size, 0); } get size() { return __privateGet(this, _size); } *[Symbol.iterator]() { let current = __privateGet(this, _head); while (current) { yield current.value; current = current.next; } } *drain() { while (__privateGet(this, _head)) { yield this.dequeue(); } } } _head = new WeakMap(); _tail = new WeakMap(); _size = new WeakMap(); function pLimit(concurrency) { validateConcurrency(concurrency); const queue = new Queue(); let activeCount = 0; const resumeNext = () => { if (activeCount < concurrency && queue.size > 0) { activeCount++; queue.dequeue()(); } }; const next = () => { activeCount--; resumeNext(); }; const run = async (function_, resolve, arguments_) => { const result = (async () => function_(...arguments_))(); resolve(result); try { await result; } catch { } next(); }; const enqueue = (function_, resolve, arguments_) => { new Promise((internalResolve) => { queue.enqueue(internalResolve); }).then(run.bind(void 0, function_, resolve, arguments_)); if (activeCount < concurrency) { resumeNext(); } }; const generator = (function_, ...arguments_) => new Promise((resolve) => { enqueue(function_, resolve, arguments_); }); Object.defineProperties(generator, { activeCount: { get: () => activeCount }, pendingCount: { get: () => queue.size }, clearQueue: { value() { queue.clear(); } }, concurrency: { get: () => concurrency, set(newConcurrency) { validateConcurrency(newConcurrency); concurrency = newConcurrency; queueMicrotask(() => { while (activeCount < concurrency && queue.size > 0) { resumeNext(); } }); } }, map: { async value(iterable, function_) { const promises = Array.from(iterable, (value, index) => this(function_, value, index)); return Promise.all(promises); } } }); return generator; } function validateConcurrency(concurrency) { if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { throw new TypeError("Expected `concurrency` to be a number from 1 and up"); } } async function downloader2(options) { const writer = new ZipWriter(new BlobWriter("application/zip")); const limit = pLimit(options.concurrency || 10); await Promise.all(options.resources.map(async (resource) => limit(async () => { return writer.add(resource.name, new HttpReader(resource.url)); }))); const blob = await writer.close(); const url = URL.createObjectURL(blob); GM_download(url, options.filename); } return downloader2; }();