@zip.js/zip.js 2.11.4 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +549 -139
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +559 -136
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +615 -260
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +628 -257
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +615 -260
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +630 -259
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +631 -260
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +561 -138
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +561 -138
  19. package/dist/zip-native.min.js +1 -1
  20. package/dist/zip-web-worker-native.js +1 -1
  21. package/dist/zip-web-worker.js +1 -1
  22. package/dist/zip.js +562 -139
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +630 -259
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +631 -260
  27. package/index.d.cts +474 -59
  28. package/index.d.ts +474 -59
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-worker-web.js +72 -22
  31. package/lib/core/codec-worker.js +18 -5
  32. package/lib/core/configuration.js +20 -5
  33. package/lib/core/constants.js +2 -0
  34. package/lib/core/io.js +13 -5
  35. package/lib/core/options.js +16 -0
  36. package/lib/core/streams/codec-stream.js +6 -0
  37. package/lib/core/util/error.js +35 -0
  38. package/lib/core/util/warnings.js +42 -0
  39. package/lib/core/version.js +1 -1
  40. package/lib/core/web-worker-base.js +46 -9
  41. package/lib/core/web-worker-inline-native.js +1 -1
  42. package/lib/core/web-worker-inline-wasm.js +1 -1
  43. package/lib/core/zip-entry.js +49 -1
  44. package/lib/core/zip-fs.js +45 -133
  45. package/lib/core/zip-reader.js +115 -52
  46. package/lib/core/zip-writer.js +244 -57
  47. package/lib/zip-core-base.js +9 -3
  48. package/lib/zip-core-reader.js +2 -0
  49. package/lib/zip-core-writer.js +6 -1
  50. package/lib/zip-module-wasm-base.js +2 -2
  51. package/package.json +5 -3
  52. package/worker-message-property-names.js +1 -1
package/index-native.cjs CHANGED
@@ -128,6 +128,7 @@ const NUMBER_TYPE = "number";
128
128
  const BOOLEAN_TYPE = "boolean";
129
129
 
130
130
  const EMPTY_UINT8_ARRAY = new Uint8Array();
131
+ const SYMBOL_ASYNC_DISPOSE = Symbol.asyncDispose || Symbol();
131
132
 
132
133
  /*
133
134
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
@@ -172,6 +173,7 @@ const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
172
173
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
173
174
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
174
175
  const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
176
+ const OPTION_CHECK_LOCAL_FILENAME = "checkLocalFilename";
175
177
  const OPTION_CHECK_SIGNATURE = "checkSignature";
176
178
  const OPTION_CHECK_CRC32 = "checkCrc32";
177
179
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -202,15 +204,18 @@ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
202
204
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
203
205
  const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
204
206
  const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
207
+ const OPTION_ENTRY = "entry";
205
208
  const TEXT_TYPE_FILENAME = "filename";
206
209
  const TEXT_TYPE_COMMENT = "comment";
207
210
  const STRICTNESS_STRICT = "strict";
208
211
  const STRICTNESS_BALANCED = "balanced";
209
212
  const STRICTNESS_TOLERANT = "tolerant";
213
+ const PASS_THROUGH_COMPRESSED = "compressed";
210
214
 
211
215
  const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
212
216
  const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
213
217
  const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
218
+ const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
214
219
  const ERR_ABORTED = "The operation was aborted";
215
220
  const ABORT_ERROR_NAME = "AbortError";
216
221
 
@@ -240,6 +245,13 @@ function checkPasswordOption(password, rawPassword) {
240
245
  }
241
246
  }
242
247
 
248
+ function checkPassThroughOption(passThrough) {
249
+ if (passThrough !== UNDEFINED_VALUE && typeof passThrough != BOOLEAN_TYPE && passThrough !== PASS_THROUGH_COMPRESSED) {
250
+ throw new Error(ERR_INVALID_PASS_THROUGH_VALUE);
251
+ }
252
+ return passThrough;
253
+ }
254
+
243
255
  function checkInteger(value, maxValue, errorMessage) {
244
256
  if (!Number.isInteger(value) || value < 0 || value > maxValue) {
245
257
  throw new Error(errorMessage);
@@ -289,6 +301,8 @@ const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
289
301
  const MINIMUM_CHUNK_SIZE = 64;
290
302
  const MINIMUM_PROPERTY_VALUE = 1;
291
303
  const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
304
+ const ERR_INVALID_BASE_URI = "Invalid baseURI (must be a string)";
305
+ const ERR_INVALID_URI = "Invalid URI (must be a string or a function returning a string)";
292
306
  let maxWorkers = 2;
293
307
  try {
294
308
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -313,9 +327,9 @@ const DEFAULT_CONFIGURATION = {
313
327
  };
314
328
 
315
329
  const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
330
+ const PROPERTY_NAME_BASE_URI = "baseURI";
316
331
 
317
- const STRING_PROPERTY_NAMES = [
318
- "baseURI",
332
+ const URI_PROPERTY_NAMES = [
319
333
  "wasmURI",
320
334
  "workerURI"
321
335
  ];
@@ -339,7 +353,8 @@ const FUNCTION_PROPERTY_NAMES = [
339
353
  "DecompressionStreamFallback"
340
354
  ];
341
355
  const CONFIGURABLE_PROPERTY_NAMES = [
342
- ...STRING_PROPERTY_NAMES,
356
+ PROPERTY_NAME_BASE_URI,
357
+ ...URI_PROPERTY_NAMES,
343
358
  ...BOOLEAN_PROPERTY_NAMES,
344
359
  ...NUMBER_PROPERTY_NAMES,
345
360
  ...FUNCTION_PROPERTY_NAMES
@@ -383,6 +398,14 @@ function checkPropertyValue(propertyName, propertyValue) {
383
398
  }
384
399
  } else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
385
400
  checkFunctionOption(propertyValue);
401
+ } else if (propertyName == PROPERTY_NAME_BASE_URI) {
402
+ if (propertyValue && typeof propertyValue != STRING_TYPE) {
403
+ throw new Error(ERR_INVALID_BASE_URI);
404
+ }
405
+ } else if (URI_PROPERTY_NAMES.includes(propertyName)) {
406
+ if (propertyValue && typeof propertyValue != STRING_TYPE && typeof propertyValue != FUNCTION_TYPE) {
407
+ throw new Error(ERR_INVALID_URI);
408
+ }
386
409
  }
387
410
  return propertyValue;
388
411
  }
@@ -416,7 +439,7 @@ function resetConfiguration() {
416
439
  Object.assign(config, DEFAULT_CONFIGURATION);
417
440
  }
418
441
 
419
- const o=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],t=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],e=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],s=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],r=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],n=new Uint8Array(288);n.fill(8,0,144),n.fill(9,144,256),n.fill(7,256,280),n.fill(8,280,288);const i=new Uint8Array(30).fill(5);function A(o){const t=new Uint16Array(16);for(const e of o)t[e]++;t[0]=0;const e=new Uint16Array(17);for(let o=1;o<=15;o++)e[o+1]=e[o]+t[o];const s=new Uint16Array(o.length);for(let t=0;t<o.length;t++)o[t]&&(s[e[o[t]]++]=t);return {o:t,symbols:s}}const g$1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=(O=()=>function(g){let c=0,O=0,B=0,f=new Uint8Array(1024),C=0,u=0;for(;!u;){u=w(1);const o=w(2);if(0==o)m();else if(1==o)d(A(n),A(i));else {if(2!=o)throw new Error("invalid deflate block type");d(...p());}}return f.subarray(0,C);function q(){if(c>=g.length)throw new Error("unexpected end of deflate data");return g[c++]}function w(o){for(;B<o;)O|=q()<<B,B+=8;const t=O&(1<<o)-1;return O>>>=o,B-=o,t}function m(){O=0,B=0;const o=q()|q()<<8;c+=2,z(C+o);for(let t=0;t<o;t++)f[C++]=q();}function d(r,n){let i=F(r);for(;256!=i;){if(i<256)z(C+1),f[C++]=i;else {const r=i-257,A=o[r]+w(t[r]),g=F(n),c=e[g]+w(s[g]);z(C+A);const O=C-c;for(let o=0;o<A;o++)f[C++]=f[O+o];}i=F(r);}}function p(){const o=w(5)+257,t=w(5)+1,e=w(4)+4,s=new Uint8Array(19);for(let o=0;o<e;o++)s[r[o]]=w(3);const n=A(s),i=new Uint8Array(o+t);let g=0;for(;g<i.length;){const o=F(n);if(o<16)i[g++]=o;else if(16==o){const o=i[g-1];let t=w(2)+3;for(;t--;)i[g++]=o;}else g+=17==o?w(3)+3:w(7)+11;}return [A(i.subarray(0,o)),A(i.subarray(o))]}function F(o){const{o:t,symbols:e}=o;let s=0,r=0,n=0;for(let o=1;o<=15;o++){s|=w(1);const i=t[o];if(s-r<i)return e[n+(s-r)];n+=i,r=r+i<<1,s<<=1;}throw new Error("invalid huffman code")}function z(o){if(f.length<o){let t=2*f.length;for(;t<o;)t*=2;const e=new Uint8Array(t);e.set(f.subarray(0,C)),f=e;}}}(function(o){const t=(o=String(o).replace(/[^A-Za-z0-9+/=]/g,"")).length,e=[];for(let s=0;s<t;s+=4){const t=g$1.indexOf(o[s])<<18|g$1.indexOf(o[s+1])<<12|(63&g$1.indexOf(o[s+2]))<<6|63&g$1.indexOf(o[s+3]);e.push(t>>16&255),"="!==o[s+2]&&e.push(t>>8&255),"="!==o[s+3]&&e.push(255&t);}return new Uint8Array(e)}("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")),o=>o({workerURI:o=>{const t="text/javascript";let e=O();if("string"==typeof e&&(e=(new TextEncoder).encode(e)),o){const o=new Blob([e],{type:t});return URL.createObjectURL(o)}return "data:"+t+";base64,"+function(o){let t="";const e=o.length;let s=0;for(;s+2<e;s+=3){const e=o[s]<<16|o[s+1]<<8|o[s+2];t+=g$1[e>>18&63]+g$1[e>>12&63]+g$1[e>>6&63]+g$1[63&e];}const r=e-s;if(1===r){const e=o[s]<<16;t+=g$1[e>>18&63]+g$1[e>>12&63]+"==";}else if(2===r){const e=o[s]<<16|o[s+1]<<8;t+=g$1[e>>18&63]+g$1[e>>12&63]+g$1[e>>6&63]+"=";}return t}(e)}}));var O;
442
+ const t=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],o=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],r=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],e=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],n=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],A=new Uint8Array(288);A.fill(8,0,144),A.fill(9,144,256),A.fill(7,256,280),A.fill(8,280,288);const s=new Uint8Array(30).fill(5);function B(t){const o=new Uint16Array(16);for(const r of t)o[r]++;o[0]=0;const r=new Uint16Array(17);for(let t=1;t<=15;t++)r[t+1]=r[t]+o[t];const e=new Uint16Array(t.length);for(let o=0;o<t.length;o++)t[o]&&(e[r[t[o]]++]=o);return {o:o,symbols:e}}const l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=(z$1=()=>function(l){let i=0,z=0,V=0,w=new Uint8Array(1024),F=0,a=0;for(;!a;){a=d(1);const t=d(2);if(0==t)b();else if(1==t)f(B(A),B(s));else {if(2!=t)throw new Error("invalid deflate block type");f(...N());}}return w.subarray(0,F);function g(){if(i>=l.length)throw new Error("unexpected end of deflate data");return l[i++]}function d(t){for(;V<t;)z|=g()<<V,V+=8;const o=z&(1<<t)-1;return z>>>=t,V-=t,o}function b(){z=0,V=0;const t=g()|g()<<8;i+=2,v(F+t);for(let o=0;o<t;o++)w[F++]=g();}function f(n,A){let s=u(n);for(;256!=s;){if(s<256)v(F+1),w[F++]=s;else {const n=s-257,B=t[n]+d(o[n]),l=u(A),i=r[l]+d(e[l]);v(F+B);const z=F-i;for(let t=0;t<B;t++)w[F++]=w[z+t];}s=u(n);}}function N(){const t=d(5)+257,o=d(5)+1,r=d(4)+4,e=new Uint8Array(19);for(let t=0;t<r;t++)e[n[t]]=d(3);const A=B(e),s=new Uint8Array(t+o);let l=0;for(;l<s.length;){const t=u(A);if(t<16)s[l++]=t;else if(16==t){const t=s[l-1];let o=d(2)+3;for(;o--;)s[l++]=t;}else l+=17==t?d(3)+3:d(7)+11;}return [B(s.subarray(0,t)),B(s.subarray(t))]}function u(t){const{o:o,symbols:r}=t;let e=0,n=0,A=0;for(let t=1;t<=15;t++){e|=d(1);const s=o[t];if(e-n<s)return r[A+(e-n)];A+=s,n=n+s<<1,e<<=1;}throw new Error("invalid huffman code")}function v(t){if(w.length<t){let o=2*w.length;for(;o<t;)o*=2;const r=new Uint8Array(o);r.set(w.subarray(0,F)),w=r;}}}(function(t){const o=(t=String(t).replace(/[^A-Za-z0-9+/=]/g,"")).length,r=[];for(let e=0;e<o;e+=4){const o=l.indexOf(t[e])<<18|l.indexOf(t[e+1])<<12|(63&l.indexOf(t[e+2]))<<6|63&l.indexOf(t[e+3]);r.push(o>>16&255),"="!==t[e+2]&&r.push(o>>8&255),"="!==t[e+3]&&r.push(255&o);}return new Uint8Array(r)}("zL0Jc9s40jD8VyzXrIoYglySOixTglSJc4wncZLJMUdUSkqmQIuxBCoQFMWxtL/9q26AJCTLmezu83zPW0lZJIiz0Wj0hUYtXYlEZblwOLk9Ll6OGVM3C56nRxOeZoLX6/rXH88nA/3ocBJzh2ydsgJye7xa8qOlklmijrtJLpbq9oGU45uY05eXn3iiYkVfrOaXXMaCXozVNJb0sZS5jHP6LhOqo3Nn+BK29VuKb41IvyX0vHpZ0ovxIh7TR2M1/j3j63hGX8l8ni15vKJv+Vf1WCT5hMt4TRN5s1B5PKWLfKku+HI5vuLxhL6VY7FMczl/oyQfz+MFfc3Hk/HljJuEG/qHzJSVMKdn+Xwh+XKZ5cKkXdNHPLmTerllSz5L6Rf2Jc8mRwG9YscroaE3OaZvWAVu+o0Jvj7K6BkbDkf00P9RN82lM+PqiLOgy3tRq93lrktuIUkxvve5gx8VC+tqoPr9fvihcdrpRKdRo9OMMaF7NgxGQz5ianu45iJVsbCrep2ugtZwVo8EOxsqL4Ti3bOhwmpEv9/vfMBKo1arLkZbzDv8RF/Rr/QBPafv6Gv6ccTOuslsvFwePdaVyVWicgnop6bZ0s8Z32y8cDteLLiYQLLuQ7DRn7tFD4IN92dcXKlpF3JIFnSz1BF91qnXuX+5SlMui/7mCN6ZU6RT7l/eKP4yTZdcUUFoxoTXQRB2ZY9lXemyTlGYM/Uh96+4QsxzJK0FhApmJ7lNSOwq9hHHzkcfXg85wKMetVqjD+/wJWzrt3N8i5r67YGB1oevQ1GVeIUvRYlP+GZKbLemm6IrcYoVAv4T1uOoD3woR2TUNcBU2yuuHHIruVpJ8S+dut3qGfjriH9VXEyWR4ududAw5wbUCoH3uLtcLbh0blWxZBxOBblVfjlTVPhcfF7xFRCHLU1nq+XUqVAGMdxpkq6eC1HMkb/kSi9xJ6DKx/4Syv0v49mKM7HdEsoZdHy7LRbM0SOHU7VfdYEPrjIPpKuHfSSgDd1DeFC0yEqoqCq9AGwrSnwHX/TLc12BxvKjhww6k4yV7liWOgFjrGhms4G3slumDe6bIoqUWM2HRRkvHFHJHvozR5TjaESMMTmwCsYP/amjqKTBRlDuL2dZwp2AVpUQsqWXmdK9hQEWk1quHtNXVXQrsDoDi7xq/GdHeSFxdZ+2dF6OtRH9XFTXK+vhZT0OZ1XXpJ/wbOaofzYiQkjRCVNG1VkjpKIf1OuqXnf4UHjhiD30v8Cc4Us9CpsnzU6j3ez0+8oLaQjIsqVfYugNFYT1EUp8oGJHDIKNilWv14g8TtwwOD1thWE7Ojk5af/M6SzmrC99ma8Af/+585lsNo2ITnWlVJJbWHWakMMc1OuOZMMR6ao+a0Rd5bFGRKS/AJQXQB6CO3CVxaxxUhLrnAXdvFdORe66ZSUbPsxH/X5fQW3wjKNQ3YKiFYUGOygTBzRDpMlLpDEVIhDdrN4IqXKzfiMaiFj6i3zhEISh3G7pW3YLqL2Mb9/YqPLQtzHonx1arDhFNO3dG4/CgTTq+WbjSOj7P5sjQsUwHzGJhIzKXo91ytW5pWd2c8MR1ioo0HSoGaApKigJgBKTvV5nw4diRBv1f4nNxlF6nJJAuWrJ1EW9rioQdH52GnVBqCSEqu12S58wJIb7m1HRGSA8XeVfzvLk+k32jbNWGFHlf2LD8KQRtTrN8LRBm0HUiBqNZnhCo1Y7anQaYRDR6CQ8aTQ6Jx3aiDqtxslJKwpGVPmv2DBshZ1WEETNUxp2WqcnJ63GaYNGzSA4bZ2eBB3aaJy2mu3Tk040onzgKP8B4/6DYhERqvxzxv1zO+Ed4/47EitfciByZGt+q20MhlLSHqjwU1We++dsOKLcf8cCyrerxWSs+B1AHAN3J64q/pDDKmVv/dc+TGFFx6B/D0sy5Z9TDtOi/Hc0g79MurtIBasl658GwUl4ehq1mifN4PQ0JGoq8zUS49w5PhsLkauj6Xg5PZrnkh+p6VgcRR9ajSPvKDy6zNTyuOhBihiaAO0EXFoaTNJcjjWdrvScnde69eaFpMuBHeCuXYYo/6OT+svV5RjYUCds/7ykYftnZ+mGhBC6dFlo7TwLQ/ggG+DcX/tTYjg4/7wivP6DrrLgR4eAukDrRmRnHGbDi7phq841y6dRPdD5ijXhp7Mc8Np/989mdNo8bZ9Ep21YASb3BlCnW9TXJdz/6Ci764RUmGPwiorto4o8Fl97LDwdqLrY/EvVZcx7rHE6UB/EB3xu6U+qLjdCfz0pvmrSur3Qe0qxHfR6fAP8DdDv7UfH2vIBcjRnwn9AM8adTkD2OOBQc7EZsrjAqMKnlOXDYEQTlg/DEV2yfBiN6Jjlw8aIzlg+bO6z2ezkVLPZvM/Cdr3uYH3Cv3BCmg251xh9gJ+O/gmb5rc9KteCwtwtmhJX+ACwhC7pmLgzF6pyhf9qWE7PP6OAjDZBd8bGdMyWdIllGwFNCE1YSlOmtjAAHIWbbgIK48DBuAm+RSMck7vEt8YIh+aO8a05whG6s02w3dIX7DabL3KpnvEb2AdhvbzwHzpvkbtZ6vVM31YzDNw1E5tNyIF+B5uN6AW7CzQTX8azbHK0GMvxfHmk8qPF5fUkjcpVmbHQdWS/3yK9XqQnRIODrkyONa5bFO8eIuvlZIRODfu+1ot5wgoWZcEeajRnVa8VoSsWdic9J9tsQtJdwexBppQljPtcoCjoLKzFtRrBqmVhd9kT3aURfezMCaFjFnTHvaRYIWPINRyPPrBkONZIAzSmaLVeX/bSIi/UOAXGU0sLE5oOlyNCJy5rbg2iryv26J8dsqUP47/dlCgQ2SfsCZVGZhx1lf+CDQFUguLfUcksKP/FMBhVJOyfjahb7Kf9HGm4g0WIX1J+/y+HVItKsaCrejlKgRKEPDVip8FpK4qanfYHPlQjKochJoet5mmr1e5EHUzvmsZNxVAYCM+LYWilhZj2O060cHSJe3YwbrJx/4nDdUbK/V9YLbR2LRR0fmG1gOLT79WwtpPsii/3a6VAgH+HIRvmpqg9HJUgUQiSQ3SwwBOOq0S3vbs0TI6jXByNZ5KPJzdHutbJ0XQ+To6S8WzGJ7XjsnqspOy0HoXpOSfAt/xebMHTGruq14sXkJ9ej8Ukn/8O8tOSsTf0F3Z8Xi7N5XKdy8kx/Y0df8sWn5be+DKXykumPLn2ys/dUir6w4zq94KPvdMEbN+7GzUqW44evDo/gg17uVoAneGT40JaesbCNn3ObsV4zuPjVw+fPXoSHW/pZ6b88XKZXQnnFnb52GT45eLB2fF2S58T+tLKkikux9DHZRzyBrVLvPnlgReaIj+x4fGEy+wLfwgcwoj+yoYdGkY0bI/on2wYtmnUpI1oRN+zMKBP2TCg+G9EObeBTBVnnNfrU9j61YxTod9NFsUhj+QFLaI5/yHW8g823FP6jOh+ArCNf8Cqw/+bjfKfOTazhd+aI2Sx/oCtLWM72hFDZlkIfFazxlhWr7f1Twd+DtPxMV8eXfObo2X2jR8XDMUrNkwqcQ7oJnQ4ZVk37TV/ztyo000LvRRnyTAFEdJJ/5ExxoLNpsOwVf3eJEh6hNGIjHq9qPkB34zqo9cL2zqhY947H4TRsVBTJ1bB4Yuu5cMYqqFjNu71wg9Rp/GzM+73T4AzS4bpCLuUjT7wHbVXCrs8TT2vmp5k2KjzQRqnXnPUXcK2n/ZYc7PhveZAxUgDxVDpjo8+IPHDd9N1SIpMUqdMaUAK9F+NRlubbtjL/rnDaUC2E37v15Bsn+1RMMQBqorncIRio8YJ+MmBvc8K4cogxD1KxWzo5DBgXkKQIwQ/QFpZZsZSFnRrYjgbdWcfWLLZhIAHw3QEWyAiQMbSDylUkvZ6EfxpwJ9mN2MZKK0AENmH01MKdbCMymE2YjNkyIA3AzZtNhrpHq9Y2O40G0Fw+vP4Q7vVapz8vPwQtU5+Tj6YD52fZ3TNICkfZqMqNSt7rAXJJkqQIDpCq2u2RrRbgxqNKkjNRmzFVpi6gtTtbvlWWZ7BH0sGgyRlJ22flzoSWHWl2une5YY7dLHgbF7Xf4VbLBOmin82vQims6RVaTHzCvjbFJBhyVLAgzFLgc2dsRTY3BVLgc2F4azplE7ogvFhMPogoMQN6HwGjTiE93BE54wPI3iORvQav4VxA94bI3rJmnvoIxF51iwZLvSy+LAc3lRqzPFwXio4Z7gIrqGqyxGdsgQymiJzu8j1XpEFFnHDEZ2wBLKaQtd2ocVeoRtdCAeRQFZTaGEXutkrNNeFYKQua9IFW9MbNqVzNtkbdtOsGTVo1D0e8xFbFQDQOGQBAQnaqgIEkK2VBQvXHdE1W9AFu6E3bE7n7Jpes3XBFWTbLc0ObiuAZYgALxnX3MJPTOmHX5kqOakiATNY/JJNYP7UHMxLair6lWzfGyYAOvovIAZRkxDushAG2OWzJS/sEMVIgfqYQVLJkGJ3o1YLFGIDR7GA6hcxAO2OeZEDyYLYdSWJXVfAH0U5qCNcpgBw8CB6vQ78yoJ15tun0DlQtTmAyHps7/GZ4P4CIlKZGI4I2f5pdIW3WnuVpU7NkZV+1nA6w4p/tpUVal99J7u5y5oGtk9B5aCLSUuCEKSrhvnoA5NIpYe5G+JLqF8ifIn0SwNfGqNihA/9uaNoTrZbmnL2wn+IizfRzIewGRC/lOiA7VseylFxQoy9MZaYMb/HEHBb8IMxp3K8flW8KWrGZaxdAJdYUOQhi0wvxewmljrtwUpNuVBZguzaWT7hccpqwZbcGqPCUo0loOeKI+5RPT1bOl7eiOTINjnsqwCqLqZ0WXQloZzHS4p8djzeMtFNB854Pc7Uka6xsnoW0m0hoOpcU26+LLgjaUB/HSqQEVOG7/iGGqthMKohrd1ssmGIz+Foh7r/QraOoAlNoSqOVSUjNwKlNcMU807lQPkcjKGOLvgbIfHSISQ2/TZINdszdnjvPeuZ/OMZqHEKM8yaO4JyOqMBfQ8WqhKi2jZT8KK3iseKCh4LKnksDdyyreZQQe6v1xW51R3JTEcSZmAjq9bpUidaSYirY/YNqimk54pxmXNHcpqQrqhknXL1KCttzG4wqyxEiBm0pNNEIRgRAgMlhl0oOtF7PwjjYI9mv0eavdqw2ZDDTsBH0MFVvZ7u7s2F3DTeweAjMCsfky4vIT0GmYwUhrXZ/8yC+p9dH7JaHzmsj9TMcwLrQytJv3XlwFmy+1dKUblkfzgaD/XKKPanR46keytIElwBOZWEphU+J2aaxwafl4Uus0Tm4gFQeox2uyVFRfcedo9pUZb+mxieH8bwvKtZV8RZeQdnS7ScG4zcwV6aGUzlBaam7A6altqe9zYOPXIymhKDSKX8DdZUACPN0diqZV9Ob/UQAHgrR7E+90FYJbSc7glARxJr0r0QBv9tS6rK1+Us0ZymFrASABZQUCCfvDs2UKjXHcUeOWOqSv3mrNw3PQ24lbHZ2Jij9SL1uurzPXgKxrsgAhp7ElqDHQHiT7m/wzhcZ+bN/vGMgHIv6K56bOY9665c9myfliy4o+iKrtxnoLyq15d3CEvOEist3WzKLHlhINYTlhO6cmXVEV8iyVZ0BTqf3eUB+F5CUfjFLDCxms1Kgvm9HQimF/iQhBd6lhfVbg48h5I3BZem67G3e+dYjtfHWFMtBFYhGatkWuRPOKuFdLe+7dYJaE4/04D+BHT7e2se+rW0+vUWLejL8UzRl36lhaHicC8rlsNUuNu7pend/bVut06l9YEMcbqlLwlNaOdnJ/r5z6HUO2pJSwidVegwpgGFLIg7ViqkUV2aEGC6IdG8l1q4ollBb6/5zTKGv/GM5uBhVEzy71xmqdkZ4vWWKo7LMuN6J+fODBSUqcznzlNCkArx9VHKnRXZErquVuOE71o/GGNfBraDFiwizcmtGbsit5ytBF8mY2Ak0NXp3etzcE/KBRfKssepPaaB7EnEyjatohTL/WQ6lsCpPVCWA4IyiwFHtia+bhU0kuAPpqqhLHiBPOXqKe1liAJlzpvdQXP/DWBn+Xm+/xk0/Gabvf73t9mDc3aQc727+X7Z23y/s+3illJSgc1G+FY3KhXTFe5gFWQCGkaE7BZmO2WRoNCgxhw1DEFK9w+NiOyxoF10wCjtlRHZHuI2q51V9wu2opKlufyfgvV/B1cU2Gj+N/D9LvTKNVGwMAhzBCc7DE5Qu9zjYUQlbhhvAGCKAH+SszDagkR8tF8KvgVdqwAnsMdUYJdkd+v/cs/WX0Jc7EBcHoZ4viXUouiWtJOzYSNoNcPTzmmbtk7Dk1YYNE9p56QTdKLwNEKe2G4YSWBOM03BHjs5Gl/S6jUaAUmTZNdqVPBQaDz6BoOSKEEhlHazijtZhU2JFDCTegwVmK74IW8wdYfWgTuJrGgdeM+JoRyxMyBgHxRsB7pFewew/MPe/A+3o+5p55tpZ8bVkCItBrh3uZ/xwtkOwVdM4r/wC/rNdQV7xR3pZ/PVzHnFHeF+AraG0LDRPDlpdcIGcUPcjaqqtG/hqLLR/gs/6/p022yYU0GzUdXHsx3fkGij8w2j0lvsU9kNRcMPioAe1ZqzT7bWCbVD1bdX9rfSXWEny1dutkN+lImlGosENsWbfdczMOqBsYqPJ1xWpjuYuBvnVjM7i9VsVskJ6HQYCzrJBY/l1rBF4FMznkAF4Hs3y5fcIXHFuAPRSqAP6FCmfP0Mu2IhAzzQHO64Mqud24N8oMFdigzveGWxW4nCtZhPtGKYvubseMLT2VhxD/m+j5wdX33LFsf0MWfDRkjDxintjIx656/7SDent8l0JdAiHKu7js1PxrPZ5Ti5jsUBp2drg9wa3LmtegoippZo+STO6GrJ79aQ0m/ZQtsK44RC2ZXiZzJpRPGSzvgXPovH1Iyz3YxXFPaEsQJv7qquC66m+SSe0kwsVgpHMtkyThfVfnFD5/SaXjLsLc4k+HMbFPnC1vX6OXfWhF6xZb2e1+u1Vb1e+1KvO7Vss0lIvf4wz2d8LJy0Xpda71Ov15LNprbcbK42G+cGJ/cvesl+584lvSFA17PU+UIu2S+Q8oQ7X/w7AKBrelsM056HQ6OzscAMkhgCmqXOFbnGLjzi1LQIb9L5CC4cplfXJjtw6JfsBSSlB9vfUlny6KX/NTL2mo3Eag0Lr9kMvjWtqrI13Ruyzep1JxlYiZeA9yR25tqnA0Vm83kOJrq33FnQS+oQ1r+1wAz+GoAZ7GpwrZ9i7RNyo/2ES2fiq8qZmJCKfXnEv+/rTBXYfguaHpBD3s5aQrM2AOnPM2F7E+N+6TFBa84OxyVKR1dDobYFrRX7ag9Erx7rFKQM/KIcwR5phqz0bsu8Dk1MB1Iqyg7kljZB2IxlQnYZzdRLANxYc5W+mwvz7DtyK3YBAgE386FsiKNrPPf3kXUnE7rK207deoIufpBIHThpYZGpQ+cwDhGqivCkFp1KtBxQkCCNZmNqUbX1YUo2tcjUpCBT8wML+RoYtoeZejIbX8WXNF+pgmhdgZoFUPEN/UbP9mkVKE/rdScdnMFSOcOVdG1Wkj47MsaVZD5/g6ldW6oRJHFzxE9OzmCxngFR4v4BgNH5LsT/dhR3aNNVSZuAapwBsTmj091aLYDtE5wsdSabzRVIv0aO0ZD5OyJ0xu5TVuoDDLYjREBnrBbuOJ2tHGS7WP82YZwumdqS7trXvUJytCVUbDZJ6Xih3dIWhSBj8UNGroAjIcjtP+awLIqVqe7KOGrn5MSeBnMGbkw3jlauaIZkvU0zMZ7Nbm7nTsE0FM12QM64AJVRvnO0QmqWDteo/aUJSqNgv4MlD3O7RIcjQifFcPf6Lq0TIGO3tHHTcZ+JQeKQeFav3zi2nMMP1V/6VQEKczolFH4BVaEVOiEV73TjEBg3TdmSq7fZnOcrhVO0NNLsO9j3Wrxh6xGAgM34WBb5U1ArnVFFr8gO5tgnJH6Ud0RNCk6P2OMYd7Caw8mkuT58VmK2PXmWwcFi+iZjNT4uXKyAu1yBZY+qrc2ySs2yZqDMzw5yqfI7XKpzRrbLet15YzgZQ0fe6A0ZpfMzsyenzrIiLHoPfrO7BwOVGdc0+KqdISSHLStnr88a0bFRNeizNHeY5be8EFwFdEy7Ny6cW1wiQOABu/TJulcyX3CpbhxOjwvyeUxvr7iKof/C1n4/4baGk+95m1dk72iOdG/fmc1GCb6n1XrBbcVusdurel0OZJxvNpKmTPglERwcl4/I0cevNclLEKkSs7LTfTJZU5tNLd9sMsbyCqEMKmFu00VcRYnVv9931WooT/mLbMHfTmW+upru6OB+2RN8lb82hyJhiuGAJKwQKg+vmD2dMrmFIeEZtm5hcRG4Wm66BVrpVFlIXbB0fEDvKr9B7+6l5OPrbZEK3YJdDdER8KmA1X3abd0Z/ZX76AmJ6kXcV7ZbraP5scJmOdmlJRiBtkj6ClQ0KP4bSHCwrOkfnB3jYI7ps0qsOzai2/P7uSJxh6sBkyma/EAnm7y9WSA50IiUdjMft6nlH5maOs84GaTsLx7vpB5nQrcObhMpu4AzG37Fo7BA42Tpfr1ETEuxM+CvvsOz0Nk9+wVSwdKclFg7hr1DWHxnqYGS9LaS8pIt7kqru60UKxrsTVVDwtredobllgYsyq3kGmNf6nU7Y9/+vEvN3t058HiruUe+ZeDjWQ3AJNP9gXTvEDB5kICNd1bpbHfRLndfV5YA9PleTKrYJOMbmLOAgmdfuf4TZ5+14drILsyxGjid1a20iujjkjHuiW5eGOFZBqeYgBnKAVuEy4pPoEKdZinYReMiiy2pZAQKSDz2UKVnWEdWUrjcwy3RqQk/Wz7JBBICAt6aoXYyBZfBNqF35DrEFhiEOSenCM0rlOjmfd4lqcu4dbo1cSr05OQW/OdTl+UWB7VLJvYUhqQ8sIznDDRgj+AwFSnOp8IhNqsTpY7Qge0E9fJ3Nzxc+8cVhlpIkwIeQKMvOYs0F63NSGL8Jbsaq1yiD3n55k/HcrIeS36Wi2QlJRfJTb3uvOTsu1lK0ldizk+2lqtQo3BSrx/nGBDAOkhmKOOvZvOnfxYP7znb2zwKwyGi8EryydksF8baRix9YL5jaKyFQIsR9k855aBv3rPhKlXqO2hGU7334mLOF9rPHNRUIs2u4iUQVnRp0dIeqbaCQxtF7QH3p+MlDl3V6wfQ4/auVHmfOMtUtzIEihp7U/p3yRp7c5jLwi3haJ5PVjNwXHnA9Ylo+m80i5p3HKKjDcmgjSfbEgQ08bGVd6/Pd7kURAIEENc5zrH4k3E24xNwAzNYU8hxwGLe1ZZhMIUDSrTlIRlWZz4k3EInC84a1EvF/OFcHhLuNaN1x5mhVtjDa6EhhQ8LJW4XTqMKg70PC0gLUqx7gfkU8jUSpVzEasNGAh9VwkTCqZaKKBTETgLUy11+f2M/ALz4IJToazMvGnERZkA5LxBNHDxmnmZXFUdTyvQ/VuAwQGF0tQN9LNQ44LNx5+P7WXZZrzvfKcbuKUVo7eDg7eYOfC4b/E5Rdm/JyjnmdppdTf8YKy4vxvI6Drd0zXjJJA2A8S7fSHy/ZcJsvSuHs/6vBqcUqgSFcpCcx8dQ4JgaAfN8EnMFajbFHK7ckPxD+BcP/vz45sGTxx/PX7x9/PTx6+4BCTIvjR5dW3akObBthu3ebumMdFPGS0Fg301hxy4zv8cuU0gOtiA1d26Ri9cyqmHoCcWGcS9TRScosus6n+bctShbdUrDc17As6jMaLRt5RCCVTFOun+WsIWD9wVof+NUA4n/O+A1koNEcFE9gc+5k9AlRhzh66PPNqtQbpQ52z9n7SiWo0+GUaDBNuIrmc0dMhAQBkJR4HvOheJXXDo5qdfzPgsH0p+Pvzo5bTdJjAxQ98tYHimab50lIfSp3mMfAPTOcqFkPptxabACONbxLJ5u2VPeNWqnPRFx5zUzryB5loXpQvIvXKgznL9aULxjkzG4ABsgpTZClOKdzUpPLJ55YatOr2FHLKfqD04lX65mKv77cltroyowMxtkFpsfYxwHewez5CFVEMYsBdtQLfXh9AafWDT14LCKYlJHC7Es/kLtmyKVYTRwhyptzborOkKKIxjMfhWgBNwhqgglNVZEWrESB5oVFSQWpIhxMnE4HZpKR0UfQaunyT48dasnwCPLZm2GYrpu1kgs6FKBYl5S2KzijOLpvNSehISiPgvU7fusAbgeVqujUJC9E9ciX4sj9F45JuWiwTkaaFeE3HmD6wflSCAfM/Zv9Qkdr1ScbAHyoBebGa2bPl649OGnoATxstDpATLrzAe4HELfc2Jxr3jgfeLc4jjiGcVfPFAZm6nnJX7ebquMW7IdTyaPYRE9z5aKCy6dY9OBY+rcgloh5lvUY2tvTlgVyqJbgu4TfI6sbpY6x8hKANmp15Ebpoqx33il8PtVMzmCdH8Fx74ZV2D+ptwpNpHNRkeyMlUTWBvH4+Qa6qyq+bOs5s/dashWMfYHr9efFuoYa4lqEg+q6GLHQ7XR8RbR8dYKIZarnRhimbLDhqXqTtyvROl4ZEtlApKNFdWZZ2rLrmb55Xj2FuSrlcIDo+EJDTs0oB16Qk9pm4YBbdEwpE04V9qgYYNGNGzSkIatEV0b5a6CM2JTI0LjywSDnex6pusTeBMTmYHTAGLZdOIm6RZpAQ31+lscKB7q00iL3fLNONJFbsrmhwENKXS2SdvUnIfVB2Fps0PbTXrapmHUoeFpBEFNaKPTpBD75KTdoWEQNWnYarRpFDQ7tBGcRLQZnLZpO2w2aQeKhFHU6dCwDcWiZuukPSJ0fqjxFm3TE+hAgH1oYjcC6EnUwc4E0J9WG7rUCbBXkA961g5076ImDUaWfeBa7XnVBqAf1evO+Hbv8Ce5KuiG+pGQT6C63StumVAllW5OiuoK2rtDoF3oFyjkuHJSamtaL1WhkQ5qTIDe4r/oJ/HTbDaDoFpUubZy+ksVEew24fFa0SWPAzqGPzP4s8LENTxO4c8E/sB6O6YKIgzFAb2BpDkv4nZY3liq9F46EnBATBn27vYa2KdVCRlCL4EaX8eKfoHKrrCROKBveGxX+KaSym10vxMUiEXmPBeeyqQ5/Ljh/vrI7SgplURl8FKRLaySb+q7R+y+8eKM3RkvDtl94gyiapzdU7J048OjnGX5r2X5z0zohwecSf10zlm+3VZo/ck+CvxeDXnPa282vB8NTuPI46PN5vjY8qJSlY6a+wvOPlWqbUcQnXb8bZZd6q306Ng1m6Yi7vGRc+wK95gcb0vP38r5ameG4dB1UIZqqgCtENAYpynchHVBwc+sCowjq/oemPq4/w5iWb3mrotRCUtXKfMd8+HZaUJ1mSJgnoXb79TO2T48eShojuq/Vl3hwfiP3OX+Y15FcnjH4cwvZAUlHry5EFalqL5Ii0YM1ttj7rIGzVnuhXWsloIdfZiAk5/7h3LDkf8XnCbn/gUfPlZOTsqExxwOAT+0PNle7wATR4eGlEN9lCM4DIlP0L/yORoxUfYL+yK+0+JHG424f8m9XyxgP975CifCB0sx5KN4CefW264+CW55Av5lLc8nyj2hetFTyRz4JV5Ic7ZUJsSNo9wXEETuny8UyEBhr9dxn5QUwvd9JB9hi1CkFm953IzoE6AMLwpaQ3/ncSM6aZ/QX4Cv+Q2IyB/AzTzjcU6fG+d75UCeDqGfywRB6Etg+N6VRNRk+Qnq/1XX2qGv4e1P+PMe/jyFPxzInoA/uYrh4DU8pvAngT9L+DODPyv4s4Y/U/hzA3+u4c8l/PkCf67gzxv4803pkwDKiX5+BjIkPVNF14qUT6ro/k/4/hi68xD+vFJApD/C41eo7QH8OVdxh75TxVAg6SP8eQx/HumBz5TzUhWbA/Hn4wUaz53bv6CuvzAn/LlQcQCm1YuyWPTzc+jEjxd9qKqin/+9om9V/BDcFZ6Y3xf61w4C+d9tDDRjF+Dimvl/KSZp5l8olhcRsSrDgrU2Lqx981Cvq5wPq5y4tXxTznCEVusz5aAL/1rpg/vEol1viwGhBS9WdFYcBNzxT9AjXiqU7X3f50XMmplybBhXsXu0cUFBWEUxVCPXLTSRulDpv1aUpPmh+mi2Q+RDCI+lqXzGMldA3Cs4304xdES2FzmI247dxdYB0YEMowMe4SwfipHrFqDXUJAFFPgWRTlZ8JBVzEntWF+0B73MqvayKhiJGGajzQaMW0o/deUwh82GD74CJ8ZJHNAiaY8zkJozeKJYh75QrEF/Vyxqdegviv0ONM0N6W/wSP+A9DZ9phhsBW50Sp8r1gjoZ8XCU/pSMb2y6U+KhS36q879p2JeSN8rNjwWHFw+Mpztsbw5pqAL4uP5EReTY3p8TI/TDM6XovhbfTSvIP2VL5lYrtI0SzIu1NGcz3OsTvONZabjEX2q2BvlTBShXMDTQhGqRAHn8JR0lRiG7RGLKDycjFgDHzojdqIVAYK9VXYkaANvs/Q7nQM4iVjBwmYDMQJQgXWsr2GzCd+jVqv6fmp9h1Al8P3ktPp+Yn/vYP1R58SuvzpTCBEvsdemk43A9LEF3ruCPVKOEISm+CQFocn+iUbbAFq5/XPb7f9Wm1PB0X8Am+FQjuIQWBDgFHIv7GZ9wH0BdkzRi1odfIlaHWItUOCV3XA/6AATGGTzXqLnFgFY4DiXblxA4ykSQdBr5H2W1ut5j6Vu5oXkVkJ8TmE8KrZFS4cb8MKqCbnfRIZNuBLHB8bR3LLTYitVNVRunbmiTxWhS3GAyhkAtMIIw6BWze9CHbABoyEDjyR7TAwAxDEOtcqJuQBysqJBst8/6SrN2oh+1GoNolYrFmSEk2TFCIpaJ13ea4URUryAYVBBOA9rAgx6oXVscOv8r+LK/zVyVGaoGzi5TizZe2yfGi3j5arNpnwWhTUgNEiuWXMOG7MOeq2Z6qx0LugH3ZKk9CPeGES8EYuu8BjvTvJbyaSrhpnrjiDMIctduQm262k2447ncdKV/4AmopDm5qE4xJhDUJGNhLMpAVL3mfjfiL9eRV7/gJHXTfz1mfhPArDr+ZyJMv46PFoB2HWtJgL7l7EcrgRdCzoVdCLoQtAbQeeCXosRm4lq1i5BwRpUvnBWMOhq3hD7quNOBo83/+K4/Wap4wjkSjI4LlsFU+lDKHVrQ4B4q1p1oe6Pwp5D2NXcLYoqJj/wKuB6bmKw20kmBrtk10WArQ9zHZ/LRPW50W9FwJ9FEbxLv05EEYh9KuxI7GuxE4p9JQ7EYs97er1JDG/cgUwYjF1+gJgvpDgT5VRnmT4YpKtUMkjzwjYIa2/4wEGZl/sLcMtdoKT3hrMA3DnfcAxx7zywc/T7rIN5PGafsrrCWrFMZ1BWqSsJ6nW7iq8KYnNiFWH9ZLdZSxdTrm6sI2x7YuBAVr2G4XEDQVv9N5zQ3TFgZDQPvpRC8xuI5+OFbRLfW4fJZI3pG45pn7l8tMNfogysQAa2aG6R9WIv68X9WR+q3awPVZkVm/hVv4WU++/hwMdTjFYEMjf3wcHEOi8n9s5DA/J+UxD/x/zqd+5/VJ43oq90/nAnQP0ncTferu5Qz4j8m00xGGZS6nXgrHtMDoUltL8Su1oSbBtlI9HrheUShN7A/t3TD5/0YZdvOnyReYLfMwUGR9elNcwidz8RiCf8zRwr1+mC5TTv9UCGMF8sfdBXe9PEmAoQM/obB77dP+P+K04T/fQA/PQNMwBd1NBX7KWies9LcLMLaizT0ABk/aaGrgu5R2yJepMz7EBAYsx0oYp9B/L0oi7J2W6hXjRw3SXoQYd5Of9nMC5s/z33PJqC7tZ/yj2WQqYLVYRP/MQZhG4tFSJQ5z8j0hWgGxOeR3BqMoilkLMEtjfBzookKnexxvNguFr7Y73Ksmdm2G42lPBb9tMxo+4zfJCjgUmIzTtxIb6xGPmPFMPCjxQ6uGlUhak2/QyJ2WphIH0Wke5OV4ruHmCH9MxSPJGh53fMAD50Vk7zSj995XStnz7TqX4453Ri5knLe+wnhaIe9z+BcGe+LYdmVT1WIz21uGs8Vm7YFb2XysSSL9A/Y8vhUo8WcgMM+uA7mrEpnbguofjxQrGM1hzZH6NnoW4QokeygMo+nCd0UrYaSm89grDNyxL277nLkp+dzE0JnRkEwZSZrtZNiT79H9TYhNxO8ls9PuB3wYyjW+qSzPO65sXzqH5yw5HLIv0yheSJxyIzNZO+EbwyNgV5O+tmnofshSwrDWpMlqjueWJEa06uR7jUGFyDuJ2OHoWTeSaV/LzUuEZNAssIlZ4Hjs94cGP/TI45wY+hKLWbKfYjBM78J4WscMpSVwylUScA+rEUsxnuVt8vUHBeulkYgL4yAnqj2FflZKjqgFA1262TUcQtGK61mTw40C0vRAVBALXShAV0yU7o2AQ7DBjwxc6ShY0OHbMGBn0Eje+F0vsX1ay9ETJyHbQb9bVQXc1x3aQHx0wZSwG2SW88wH0FYeiyJA5qLB84OULb+gK63IcKpHB8I3HSY2Ggy4YnOjHWbx1TAPqesRwsgOnA6nKcm4S2fnXMAG1V1Pk+YAAsWQkWQPWEndAlawJm4ilPrH/JGpUwomNmM4HRstHZLcM6xhY00l5Sr0sIQYucZ9pbkkl+i3wGjgbWjiofL1RBboIa87zUeCQA8g4cWWMgbX6nLAZ4pVUGhKaqniELfk29Bo0IiVMEslUlglpVzzslGuDBbOXtWHk7O3nDkJ6A1MRAYJEwQ9nAgmAsTUJbvzoG1rb2850VOogFRIMscCVtEIp8n+a/hPn9Fzhdo/MpWEf9d9DH11ABumOj1YVZrMbruwsDKLW51gQO9zzmBGUvPLzvv1LDZAQ+y0717oYjAtEagajgezSiCZgoAgj1qFlJvVr174UisZOxBC4KoeZzVhhUlPWCM8meAt2CUCiwIHOPzfEdy0EUJqRCNGOPQXenk0H/BzXhr66EC6sS6bGbqhIJlRTolvRwxF3TLWT8lHm4MFbDj4INb39X8Z+C/gI64d/gzx/w5xlohyl8e4/fmvCtCd868K1551sLvoWgRYw7dz624WMjgo+NSH99uletLhq27a8d+BreW9j6DMb1Z/hzJ0MjsjJErZ0GGhFWEXUgC+hGoY4gat7NAx+rPOA5sB1Vwuhj2xcu+pl7Du83B6dxYNGnv/b4acdBkeEZ/yBInft/8D356pEobIxTxf7SS3QKa3M1VK6DJqlRcaaB+8/5UNW5/zuEO/Y/g1FyqkaVKa5IAb8ryzpghC38+hvogxiYfRxIoQF1dCL5Gd79h3+9ffzm46vHrz8+fv744vGLt9bYHlb6L1jeDGx05poDqKOrQB+iPA9Zmc8Yet/8MtFnciA8aeIdKiZ3cz83uZ/v5bZsEJaMoRVK3B+XZsi8L1GfJwks4nwQgOQ25h7L6TW4KAMjmgBslxg+LQSmZc79J3zA/YyBbsjPqNFbHVQDuALK5SSOyqLIdGTs8scL4yF2rk9kzPA3t0/9HQLvJNf3W3D/nfK4n8CfVMEgRb2OvFeqzEOiBoLJ2Avxm0AOLFV9Jl20rNbrDlLYFQVhYEUllZ6msMpD83FqfjPzKyAoXoq8iy8UtkQo4gCccNGQhvAq/pgT1L+hOyCDifKvObYBZVzomabliXKZ0r9YPXuhSm4JmodEIzNNIWmlkeLAygCdJuTGzh34DgsHr184uGLozlJRyMMIQMWaU3au9wIFxO62FCMS1fsFYF0rR60PAH7hPZidcupYOeoufhQDXCDvlCeo6v+mMFbhbxCSQk8HBmiCnEy4CpQgUMY1+eDBgyQKs/FOP+OX8q2sSGfTdblsx3/zReH/DDY+xsozAkF5yc+8WEtwdlP517wGFx42oxpT/lter7dOiqf2afF00iieTsPiKQzKxDAsH9vttn60TnoKy3sCYtEb5wntSGEd8rSXhe7ojm8yaqi2BKzocKXNaw2paQGkKSfUsOAa/QFP1nBq6h38+dNAbA0Qw3eNohPzO+Uepr/GX1h2/muOp/bgHJD/E7eZ0992tOrYVeG/gFDH/gvuP1cHKQZ0pHLG+om7pjlw89a/Vgt/7Aqquo0sdXB+NxvVb202qhcUWlL0tfEiRNQajH2zQfQd83q9BhRxs2m324xJnKRmrboUzi6J63zKdz+1dDg4Jv1cwbFFBeCpMem/1oiG00b3imK+PxUNtkWEGMwA3XkM7uI99lg4ghzqim7P6q0ZyKFczajMBA9IquGdhWGD0OJrhVQd15H+tdfp9ZrAGGo6Jv1r0BtsNtK/Ub1oEMT40B6EMfbhRg2iuEHFBmKAt/XYkVqKDdy5BzSyEXriH42Q/g4nLAWx8mAK9zPQPRL93Vgb/Ay3iYyFtOgyNbA00L0Dyyx1WidmTEiREMUCXE+SNkLzEDZOzVMHDpq+4ARfHHj0P0ME/YC4+u05jA3eNLnAtJdqEMTN3bSfIK2zm/YrpMHFXLotWM6Y/qcyKeat9JHaT9Uq7TvJWrVtkk/LGdifpmYc7Lf8HpbSajarFQPRWmorx9Odvj2t+qYBdWfpSiAeOBmQ4QGob3Cy2qdl6COsrujK3/3+4HDIj6IELpXTAs0xWjCSIRsIpQEDSKZgjsa/AhweDMtcPAsymOhL/1feLXgvePHgA7R0rZwSINTUjmABrgcSMTs11BG/AO/zN0NAnZjH8u391QtdvcvETuUs2CKcThqwNE4ad+BgcLd8KEP/FgQBR6ZZL+w/DgArwHYE+bvOCxZsVbFGhjhid6Tn0dYUKNItKrQ7fhpCx0/Dwx3/VZUP/6sd//WHOq57HAYI6zC4B9jPFSn65EaISvW6s9uVu30p1ygQRd0HJJkF3SgJ3Rar/mFiaXYO3Aulnyh8UIZJqXYGwQKzLP8UOPwYN45rNThkQ68Z60S3cOwGBrBed55U+2CiSPHRsmNq0zXS7aXWA7/W9qnVEBjJkWacDTfvuoXqQ7GX0H4t1PswruyyVrXVFQqosIknHOwy1S2kptxAxQ1d4jH/oeoLS/lWA6ZxP2C0Nt2GDXLS7HeNERo8RRJu2BZsKkiSfTBBIggQoIxM0YPMybUUESJftAJljWTMdXPU41m/MAuaSf9dwWIxaH0484//5r0MhJIleFt5TublKO4BM5ro7WOp9FCKUUD3wfCTKmr+LGENo6dwiG/eC2Wmn+FH7HTxCGAgsfM3+EL+n0SYj2IIK2vk/64pC1rpIwbXODbAE6Ng2NrtNi4esdlEloeGYSsxFy5sovc8LfrCj9o5+InasQg0kFoNJwpFmXkCnZuWIxxJ4pYWF94h14ZhjWGjbuDhI+dCOFr0lXpagaHD7T/TPwBBiHK2y//epUNFGFEAJrCWT3iPBYMwdiLNsg6cvyN/VsoOy6STdtglXcuMlzlm/E49M363oll1IzyokCuutfSGOcC86pHDGHBVwgPz4G9JlYFBtISaZ4VwilKMAZUXWaIp3in5llfRz1dsrajyn3M2hd/P5vcd1+mvlP79ph21UqVvIj4zyZ+Uzl4a58HFpLK/41tpYse3F5wZJ2/l/4QeKSD/wc9H+AlDwNqB17A1Vs/3ySC4hWhH/xQsFdyfgR2H+18UXWJiHxU1A6Ri+AiHX1A7RmdwDSQYHkHQXyMdoVP2u+qtB79D5NEJW4GCeAE/YAO/wQe4447O9eOom4JV9RIN532wiNKkv0YDyZqUeiZFV0PhpqMam282+OjB9TE3+DKqsYlOhbQFSXKhMrHiJjpLVNjnp/U6NJmPGIPM+ahLctfVYQVyKvup2Qdeg9CYMgnWycTokA50vFDBOIqNh6o+G5H+EuU/z6tuE097bD1IYytq/WcDf+fulQZgl0BHM2M74P6N6gcDJzIaLU2v4eGu6x8VrBmcNtpRs9k8MdpMdOlshF3cn+E0CchhIdzwjbxG4fSxu7GZL6faP6J4DYO994ZdMjQNwtXuvT8Uun9YdandvEVzW7wy96vWkb1V5eMThdf37o8Q23igszzSRfxPQDt00oUuikmmItimFPusvBDvnTcKyYdquALHFDSDKs+zrigFW23jZ/Tidltuy21CiBy8pAS/NdyTfr+Ba+Rp+eakPZZtNk2cI3DscDKWEhJnLGXCbVHhNntg8VMD2wRF4hRtVnoL0Gao13oToKkoDWNN/eXu/UuI2ggRbWLxotYJbRWGGy8sn6XXpE3t8a2v3nJJZXJbgSEJbYsN0j0vQQvqfXpeglV4IQYzMRB3wwLQbkgTOGTx2pqUC5jTb5rW1utXRgtW6V090ORShQpd5JW1khXJs3/NLfr7UuzEXNPrBtUBpYp3ygeoEohhP0Sj0k9C25Ur88ivu9XwHpwKtE4p/HnAfQbKgCgJXleXnBj7rdGvlkTpJ4HE8w13mxFggulSL99skOnDNy9Hvq8YuOhL19SD/oHlG6ECnX8Fg2tVemAi1tp02Io3mwCdQkXNKkAMaUpZE3kAwaqPACaK+GY4hZTQ8ryY19QuMMVrA50hO1ZKNGL/snOE8A5ZilmCuXUkethKJghFHea1UWNeoyZTT3iGwZlMmosKfA2W4nFiUjMFv8IDDT5UW+nrd6sVVm2iqk1UtYlSIASnAYw65BVzRxOk8QluOWh+4opVW/o1GEI8tHBYRolrNNIogwswl1ialvYHrTY0mu9U9ViChDpF/viS0x0DhymaIvZz1YtAVOCFtv+ubYMUxQ0zfm1MRrqviY5UDPx3ghW4gLwJtoKGC+D9zRqrbuZB24Bp5ws3NpQUmP6vcGCjQWItejbxb2VQ0VINvGawEhHLzaCpydLHwCeZ0hDW+qkCDv8+SHK3AvUh0OT9ajHlpQEEgq84+wYfmheAyitA5RagtIXiAGB2FnleEoec/oROuGU1ZGelO7IP+4IjcW+AjSG4A03ZYxB7xBFQCewKtFjMdi5Y2NWC1raZ1CKgsBCKhUmMKx3MI0xptGMGfr+np9/VDhhb0r4A/MsPyb9iR/iFENy6szhN+tASwkb0WGH3Q1nxudbXGKEUTG/YE0So10b4lFr4NLA1qXeF0KUCF8w3KHsnxoyHOT0g2YWewuqY7RsDGWGtQKZiPe9JtbS0/6FEe8gEiGXC4q4O+X0ZGDnPf08KRvICVkTkxmN4+t+Vi0vUefp/hDogjhSTsIInM/0Mx14g1gzcj9+o7+OYQZGWFsWBW9ts8Hupr0Hs6oODRVkWfR10Nwq9jsaz2Y6RGA2r3gvVNai7wjD3u6gbemX6DvLOYCT4wyLAVPCchV3kDjB28XWmjKV3rXGzgIlB9B/ErMIwANVoZegu0qLBWtbryH4FpKjdIHLFiJVTXCyetWLhbu6taQaZhruN6IEQ+n+D6MA8csk6rYgqyW4UnrjlrM+BwRWSzZUdZNMLSZWhQaiUbKGLLCD2V/l2I0lXmkiZ7SaN4Jt+C5sRNUFGMskmqrzj0ItIWVF68AtUmhXVtGlITxoQHiSAQCc0LeuHeConEfzpFBFQkvI06ND3fQEamA5eh03ocv9Tw3wYSzjjmElCZ/iUSkJXO5mVNFnX+8lwrPqUNk/DVmNE6BTLS0noBJ9yaR2EWsjdy9z+EQ14zN2wbV19dk+WqGPFLZd3LdG4gS85SnFrjuJbwpGfX4FDvPRXdMwknArpQ5x7CUc14BHuROWCrpn0Fag14IC+9JWAM/oT8ybxxP6CSf9SF7ph0v+iH+cMYsjj4zWTvhD0kmWeA1QGzP9fWAYnSKYcZDe4TiV3tXcQiG4soN9YQM9YQD+BJiA23s3dWS9saZpbc/JeWh4bQmp6xLtjF1zoXXfU683ozGX6NnbBVsNxfToy5PqMVYd06BgCTZzRmcfOqP4AAWIYOyO3CR4TMydNRGUTCNv1M6zoTfGNntXhfO4ZKXp5dqiTt9KXgoXtKDAGhiO+vdvhNy4b1wG8ZwBbq3vb70LgxyrX0FgPx/XJj0OjHO+3/43xfrt3vJqAvaErlnmXQL++9VeFZeebt0KK1r+p16+L+CSZiV86yXQUnCOV50fpWB5B/MVjWnbntOyO3pB12M5PbOHBZSyiByah/fgkrsuJQYjl8JPr4nXfqGg74ntH8sSBzHjRyyeWed/KPWfeE+T2E1u4c08HGuJMeHN9vzj/z/tgjiN1XVftZdb3zXBYUrTmzP/bYc4PD3NuDVODdf7/C1gRE1U/6hZZEsxCv/emPNbowo68l9wP99OIDmyH/cf2/lebKklNuwlL7x7sxnulD2E1rHDjOiCI61TLi4z2q85SpxHBg6kmPA3LanabneEtq7N/6tX9vcZX9zZuWLi8d1WvZ70v2of2FZv1+41u7rFXsO5f9XoNOq7jDjMjyNEtOUqta84yCnsEy3tXgysvd1txy3Ny74qgUxjLel8GX7zMjVoncdQ6AXvfFzB6LNhYxx2CA4qz8gDvtawMEdbpVnsPZdeSSqYGYbPZjsNms7kffCYwsWekiMN22AloKuJaqIPQJPi4FGAwgD8z+LPCPxgxC54m4PH9Ev5wuFpUKfgDHySGhcEs8GcBf27gzzXkuxRV4JoAzGTFK4RPoFeiCBWDzuwQjUZAOM1v8HgGfz6JWNl3R8r9C1h7vagJByvD9sbyWr6S+uQvWsSDMndZ3Dr7CTlDO0e7SQFc1tlMWXluO/okAMFmIWqQNoNh+/BqTGC9XmfDS+NXOZFnkt1+QmC/EnEi6VcRjyV9IOKVpOcinkr6TsRRQF8LQAv6ESDwWMSt04j+hcUeAXi29JOpJ4B6lljPDOtZYz0TrCc81fW0oR4v1BU1saIAKwqtKFyvrHhe+lCERqwlHdMZXdE1ndIJXVBz6xz9Qq8o3ulEP9FX9GsZVaNN6AP75Zwlg08yPpP64BoLusseC1vdpeuSr8NlcaJNn6nRR2q+DtVwPIJwLvBlzXL/QtAVFFr1WYiS6tfhatRdgU0gS511f1WvO2u2QoXzqhAazv1HYuC8YW+kE8LauoAj5OyNfgrhCSpmIQ1IXEReYGF31luZJmaj7sx19bmfdW+GbcwIXbCQLllojSNLnQWc+qQLj8GY6KL0oYQAB6mzQFMmCGGbTVhjK1J9RWPJEJ3qdaWmzgfDJQTDejBcjlyo8w6UQEs1HEOohmz4oIDYiI1Jd7nOiuCvYzhFFJ+xTyyjr9i5/84wh138EsZn7Nx/BfvSuf9VYI7XRY4JT8cQbhayPNBZznWWjwKo8pwFeOHUks3oN5bCHE0ZWBID+gVOVd1AFKw1vWI3Xoge8/W6c+7/JQY3fcZlfNPnkqBZ3v5w7j8W8U0ffsiu0Qp4wDfsq3QyOqZLOqHcoN65/wkU29Da0pvQS3iY0hm7BBH90mPXhmNx5v3+hLiXXZz/by4fsTeVoH6pp9lUE3bn9esuucbIbtpAdj1w5nV27YV07rJrEuPwXRcwzvNggnCHWgL+afgtIRoPzAoGfkdT6bx+RWoQF90cuZvU686ErQn95upeTxkMYYEv3ak7AVR0EKmm7gSOLi564B7QJVPXpYhy0LsbU/q/A/IXNq9f6cUBk+l+GbEv0pnSNf3mQQLZGuenOR6xxHW19CYETijOu2ZMNRyTGSeODhBkbSOILkjMivzm6nmB5XgI+IchX6gDsKPsRi/kNbWs51/vkDO61ARtjMFvB2Dt7CUx/LhhLyFjdiUdcBmUlFe3+JZZ+zorGJp17NwQYm8WR0mGagTCYRcrSfEkuKdPKxtmTOfTVWFFXnJv5qOxHR54Z+86beudyRGerC4iwp3lgcUi0HPJbh8imX9bbrCtZpPQJyJ+IOkL+Lul734kV7VDvJaVidf4+juFm/yc05qz4/qv/E9gHlK+FD1k1iBJij6yYGSzqe1l6ARVhjAkxHZb/1i1DAd7xeCdjM8lFez2QsTBVl/n/NA+1GdO38KRVYi4RLh/KYYS6KMJxKFj61jpp2V6J7DTT6r0zm49yn8rrBhi8EqV/0SwjObsVF9PhD3MtjTBh3xLl0WfodZX0gGm8VJQCCoLOMr9L4Iu4Tgvmixw0eQsgR/uvxFsCU96XI3I7k6rm7NWV59OxUyzoumVaborYJGM6SvpRLrRRoQ7O7YpTJvKfyFYZlRZY3h/CM6JW4iZz2B0lPtKsFP4UQxyU+5LxVq6f9AGouNjqQOGlrfzjNXe/aT6xprjFxAXbJ5LiAi7WCm4Ma1Cub/kPQfrDzMlReigJrIFiK+bjTm4gOcV9t3+vaiblNsY6JQg4udagRWeZvCQmpP1c04RieEAh8SIMYUQEhF65sB9TQldsyW9Bpm2ugjMbMWQ2+zGiOqxluYFeDXdVlVVipsHyDtFdYGnDxqtdthibExusdA1tn/NIJyk8GfCuOvj4xsHfuiY0FcOJOmqO2FVtT5Sgj/+74KBC0ENnE2gL5uN45w7HeBeQSCCUzXkH42wkuuSXEqeqKMpXoZ2hPeKHhfNlLIVNNOpsXOnSYqiKxPePLlz/dzh4u+cJqFzrMLt0J1hzwmd98PWZjPvC/+ORmWdiUm+NjdK36lZ+GOM4zmnwl9qewZeVivgEF9gANYKo/p4AGA7jXHWAZY7fBNANC6nCasa005NnxKG1/943K2TRrOpq9irwYA8nY2vlkdLrg6OrprazwpEyU49JBDeGmus15sGoZxdXNlDlqgaZRQ/cPA0ilXzn4qN76/02z2VNqpKG3EBt6rSX3SQ2DEm+u915//9rjerVpp4SBdLD8qJWsNE2e0+/e5gdpshsV3yJXgDWk23qqZbMTqzm9brdWfKoGk67Sf4khA6NdWYw11wqAQffoPsc2b65kEx0iu/XKuibTpHcji9v++XQndeVvaQnObulNApITTx2BSs9lMEisemGjolP/jFIV0EV1CNsF2NsA0jhCDpBlU1PUvs0lMWAAc+ZxB5cgoaJGu8f8ARU38teuWbHthPagjJsKPNCzPavF6f9hIk6f/tWOdWBzWvZc/oTzijd4Z9Ug37BIYNZsf/cNjPdob9rBz2r/+Xw/61GLYZb6cabye2Wsfh6oVUdGNcKw7+QD9KolfsDjI5mmfLOYTmPkCtXjlkh2I9h/OXS9Hvn9ZDWmxPIalI9GVFoi31X9XbU0OsygLfpLO3EZ4GZfZT3IVrwk9Kv/BPDqFR99CWoNsriyLxb6GrV9sym8P8l3miGDfbVJDb11UPoqBthm9YgwdOAz6mgtVq56CoeAd/zp2IlOJ72YPGrvCepc5HCQdXywyn1O7OOyci9Mvu1hVVtbXt9Ea8u41ewpUvR3AbhT1zW6hyD+ynDegIDFFD3yDEmNQYcBD9sP1Bu3rv79RLlUtetKR1tcvDmyKuSFPt7nQ26b3wb1YjrUjzKZLmghwjRttEGRyDnSlboiJpald7rRxgPQ3NrZbWEp5Si46WW/E9WHraNoxDE4YxEezcaRHQA9N3DvJzC5MUFglTodmgJkWmCAr1o057s6kJFKGgSL8RGPBC2uAYzEnzsbgxcD2O91OOclmp55c388t8tjzIUdzYtPC0ooWnJ7GOYunfADmbii4xqHwpwF8V0l13NGLnkPrOMfFzdP7wtEvuZAy6wr8GEeJK4KWUTICIAWlUgMxxguKNFmcgdUsvzbMSW/rREgav2SuU5UHICU/pil5SAULORypQyMF2ViAlYcWX8HSHkQSzQYGW9/Jbu9CpKOdpZwc6E+HCLBktSXfBYHzDcweaJ6DXcRbV6Ykem5Eu+aovCDaraUF6YZu8s7NpSBvomdWx6Ba2LAi5WJY1lDty7fIwKXZ1yGPfiH0wXGaqQBnJF3x8CA7Ar5i+gOP9lDVcIGAUqIXeb8ITqzvAjjW+2xdQrulaDO6Q2HngnPxAmTB0z50T+HaiY44hgKb9cg7+k/HhpE09zyBtAfP5VtvYo+BUy4VVHAsE5iVeLTA6iFieB1vjMhNXEADby1MP6eBBJKsWBUjeuAoeW6vgL2sVPCpWAS6BUC8BGDt9TP/Si+CRvQgel4vgL/9C23Yv2CN4RNDhIrwWpWfLBbm7TnatbfcvFalYGxt4iKCpWBbsXjU/9K01tifmWaotfYHPF9UKj+hDpJf0LX2ix/bCHttbPTap2BMzSmWP5tBYCop43ygQKAf32p2t5zQWlT+BSY2Cgt8Amp30WbteX/YxKPYt8B3oELPWyoR9VcM3FNMtZMSk4N+hIwt9EqteK56iZmCM3DdsUdRklugNcZ1zx7mp6nLxJWoS0u/b6brRnYwHe/DOzkOh+y6rUrTAv7iTo0qhFguwoMUgSKk8iYJWNUVmhI0IPiPs7jCNVrZ28/sYbezHBzD6pWKmDgd33UYYa5WMyRlWcx/GwgQOcOBBC1suOzdv78pUGHbxfCY0n1JWGFUVRnG5kyiFGCDV9zHgOzOv1P/DM3/vNO15FxyYoIkqUcaerbBVZW5UIG3cnaOJ+rs5MtU0q2qaRrm3tEkDMp1rb4l19g3jyeDFm1LYnb6giCjEDzoI3Rks1HHFB87Uw3t46QSILPemJJ5ggmlmXWkjbHZ3L8r3FP1XsmGqLw8S/mo4GVHXTanrTrRBY8JSD7pPS9XG39eV2bVYvDby0IZ91mzI2lKxRkGwJ3JEQesgjIcp7MrYnSUEBtvz6aqKt7Vo9oQbxgjElrXHliZwz5oKfyXgt5Bz14X1Iau2rdRb05RU0uKVlsUVXeMJbVAGW9L6UgzGMcqj4AtAaljmrl4V77m4T6uqBWaTeFIN56QYTt2W02FQtpxeRemGCRXkbuMFvfuR5jtV853YTMI1C6m1D0bBafXFa+x8CgPzyWuWhuZCJb/duWV756a4x9Ke8OJi7co5xNHucSghXvLNZl0zB72FtjJFwWm97mhqXSZ14vKxTTYbjB1UzPcafUBh+R6M91oGUKo50l+hdUH6K+NWCGdK/FVhk0Av1Guweq6IZXXVeCz1ERz4YTojBZdUPBH+BWyAFGLawdEVjGYC53FUGYregw9U6oMtVilI6ZbWR/3uQYYuxwNh3BwIg/og2a5SUE6oAzcRkIFzqE2hg45ccSaq1kjsQJLLuP5UjesKBwEZe2UaRBmD+FfWMVNwNOfVEgNHKk+hPxWBeLeFD7lBwjCgXrMovvLQsAPrGKbMhMhb3b+kTUgee+0eaH1tWl/j2QJgIN9wF9U6g3YTYxxZzNogjDplmpEJNhtURpgMUasN5yJhzrWXyRr/XuuzR/oZQ+0x8C6+tvyZEO+qAOlIUS6FSY3HxZPl17TjhH0Jvi/6GrZL8DYpYxRRrOSSRnuRJb/9aPFhpF/Ndn05bOh37fpUVN/cq/7M0VE0VtrPe83xDPuUoyt4UrqCJ3pSx0z4CzpD6Ftx4x2gYSvta7fmLNW+dUsM1oiHFY073pizBCQF1P2DY50VMd4ht2Nt+rOcB5xKtauJDCzix7KbeB4dm2CwcHUIAd9giBqOzsCB8VwuozAXEf27sx5HbsgKRGzFAtWOh5x41jGed/Ada+XgamjfrOeYDyf1GXw6qc/sy8MsVzVtsR94Uaydzy70nSRt+lAeus2RhW2q2IU0tzk+FxDJWl/iKKyLQHQEenMhBqdNgsHGTRF9pqEIZknIFg51YJ2V02+RtbzzRvXBaOp5hSejyQC3aOHGpjP2y7CDR0UNywVKcuY+Aetiqxxv1JV8xsdLvBp9t82eGVW9vtNtvmN7fit3r+t5KJ1GRC8k3kq2ms2qnNKpnBN+Eo6+weNXCEhnfIf0QX5h4dJYOceZgIu09ZXQR8euINaForbLY44DkDe3yq9GVFygbI86Uc4tXnTskNstVcVdwKC4JLdis4FjzA7RrqwJiMJcw/dPYV8iuyzuCVj2suKaiGK7M7NepHtLaq4aHNuc0ZIuXan5wARW4pgmsBIDmsBKHBeVwlt5BY5kyn8JsMvgxBqMNoGVLWkCKxuKTmGPMUWLCK7v4QhtQPBwiOlSYvbrZT8ormepheAq8lTE0j4atCTUgDOGC/tu+WbjcFaDoBwFmCWEWO9mkJj6XHxe8RXc57zVoWJyEC//FKxmBWGCKOd707yQecLBEQIvYD46diFoaybGs9nNbbbZ5HAF27aYB+M65jK53dJ0pq/sw1PswMNUE7U3m6mezcJPziwjDVBZADQFgAqaaoCmAFBxAKAphCFIyk9eagCa7AA0R4AKG6DJ3wNUIEAlJGYlQPMKoJX+7C4cEWbZtzGuiUPAlABMcFPT+M19Lp20WIIJLsFkr04uJtYKTOASbiugrty97PC+5VVeR6vKIXH/aak0I1UPeQkIUk4vuYVGa5bH1+22uG8eKESstowjRTmrXAj09d5PxrMZiINwOvLOx/ez7BI300c8+V7BA5+haHfJZ6kPHbjIJ6sZZ+PljUiOOOvfqnp9vB5n6ggvUkdO8v6+AY8pMct3+sFgCTi391YSH9qtjic8nY0VP65c4C0gHvh6fPUtWxzDteGNMC6+e3K8xjQvbMUhXHOg6vVjsZpfcgl3u98sQO4AtvcLnw3ML7gLG8R4K53bnwQi/J17AuE+6ipmyZwzvFOWwi199FcRc6sIChWsQyUcVsrZE4jzY5Zbqp08a5bPEh6cBNntmEK4Zh3qt02o7AX6tgEQAXpe2KqKSOZJrYqX/bCFV3lEVHosbOMKyXvhZpP3TzebTg2iZcleZ7OR6GWjeuCZB58yeMr6zc2mw5is18MaS6sWdJoj2Wmxw+BwCwAkELVgDoxY4l/DRdEJBOhqRjSBAE8pTawgSYl/jZRfS0OJf00T/3fOIMELaeL/wlnuntDE/81k+AWq+wNy/KZzPOPMgeTyVl6aVKJY9HOCwlICAaCMq3qR8tlK+Q1Tvujt5yU2lbttmkCcqMLT7Gf4Atl+5Uy/QEv1OtQNfz/j33d84CQQVgoeK5pZlP0IPf+Ju6b4Qw7BbeAFnLMS/wbiHCX+NdzPkvjnCoj4nRsF74bhMYDHqFjABOJ9qAzkIfR70vgDMk1EjQungpiPJjgVBKoCd0beC9BLE6JwKYzCBaG0WMTAG5APWidwkzEIUkUKWuljbTtXEK/Mi3a6i8j7CENUlAG0+uylIrvHwl4q+8orfaUtCrOQYt+Leye7ZuaggAmVd4GNXVSNmft+d2vQifblWTuNXhxodK/InYYfKn3XidXw50MNf65qwau4dhp+qA41vFPEbhiC/zBzNy+G+jG38+aCPoVbXN2QPlP0J31k/4mV9aLMmgrKBQ3o8zLfCyvfQ7Vz4a+CnJ8V3Puxc7mavnst0CGGtg6E2IPgRCU9CJBu2YgBIUoY3H57yemFiU3wRrGPYsgx1t9vGNnFSvgFEr5YCX9AwpWV8EzHPNR+fkXYR/wR5Vl8DFxgDuSvy+gRoI3w54DtGP0qdhITT5AWl857TUIx9Bz1moTEXnOLl2t0qKAd4Enfi/gPQbmMn4kt0ZcGdVHcWMtMjS9nwH0Vj1rMknw8MR+KR3+RLfjbqcxXV1MHGBJgHL6zk35/p7xLK+5++/tdskhsN63kdhy2/qM9EQ+x1cJ7t8XS+Xd/EzQUzLCuHhi8S5ondbUYSWYOUoTUew4eAswH2oVHn4I7eP2tbg3F551d15xTV2afVT245a/MIFDz9kmYzlDFPBNySLCW66h+v0l0hlpIVa8J1x0qOJ5MukVY5E9isANK3NphL1b9XBPxSr8IZ4qkf62jTUqMaajjJqJK7hpi4923J5SKAaek/Jea8n/RP6hF/PHi1c6i/JWwthdVXXQR1ovtQ4JsgiOtpkGhB1RIlZ+Y3yUa7hQ47GJuVF2YC+AnfMYVP4LAinCz+f83sJODIS4HL1NPB63EB69PB7Oy4WJ5eZAOCWRWEFIiwQnQAdB5UDoqzyqyCJR7XYpqIeUWat4twZV3S/Dm3VrNWk1rLgA=")),t=>t({workerURI:t=>{const o="text/javascript";let r=z$1();if("string"==typeof r&&(r=(new TextEncoder).encode(r)),t){const t=new Blob([r],{type:o});return URL.createObjectURL(t)}return "data:"+o+";base64,"+function(t){let o="";const r=t.length;let e=0;for(;e+2<r;e+=3){const r=t[e]<<16|t[e+1]<<8|t[e+2];o+=l[r>>18&63]+l[r>>12&63]+l[r>>6&63]+l[63&r];}const n=r-e;if(1===n){const r=t[e]<<16;o+=l[r>>18&63]+l[r>>12&63]+"==";}else if(2===n){const r=t[e]<<16|t[e+1]<<8;o+=l[r>>18&63]+l[r>>12&63]+l[r>>6&63]+"=";}return o}(r)}}));var z$1;
420
443
 
421
444
  /*
422
445
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -462,6 +485,39 @@ function getDataView(array) {
462
485
  return new DataView(array.buffer, array.byteOffset, array.byteLength);
463
486
  }
464
487
 
488
+ /*
489
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
490
+
491
+ Redistribution and use in source and binary forms, with or without
492
+ modification, are permitted provided that the following conditions are met:
493
+
494
+ 1. Redistributions of source code must retain the above copyright notice,
495
+ this list of conditions and the following disclaimer.
496
+
497
+ 2. Redistributions in binary form must reproduce the above copyright
498
+ notice, this list of conditions and the following disclaimer in
499
+ the documentation and/or other materials provided with the distribution.
500
+
501
+ 3. The names of the authors may not be used to endorse or promote products
502
+ derived from this software without specific prior written permission.
503
+
504
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
505
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
506
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
507
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
508
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
509
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
510
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
511
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
512
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
513
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
514
+ */
515
+
516
+
517
+ function isErrorObject(error) {
518
+ return Boolean(error) && typeof error == "object";
519
+ }
520
+
465
521
  /*
466
522
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
467
523
 
@@ -2601,6 +2657,7 @@ class ChunkStream extends TransformStream {
2601
2657
  constructor(chunkSize) {
2602
2658
  const pendingChunks = [];
2603
2659
  let pendingLength = 0;
2660
+ let outputSize = 0;
2604
2661
  if (!Number.isFinite(chunkSize) || chunkSize < 1) {
2605
2662
  chunkSize = DEFAULT_CHUNK_SIZE;
2606
2663
  }
@@ -2609,15 +2666,20 @@ class ChunkStream extends TransformStream {
2609
2666
  pendingChunks.push(chunk);
2610
2667
  pendingLength += chunk.length;
2611
2668
  while (pendingLength > chunkSize) {
2669
+ outputSize += chunkSize;
2612
2670
  controller.enqueue(shiftChunk());
2613
2671
  }
2614
2672
  },
2615
2673
  flush(controller) {
2616
2674
  if (pendingLength) {
2675
+ outputSize += pendingLength;
2617
2676
  controller.enqueue(concatChunks(pendingChunks, pendingLength));
2618
2677
  }
2619
2678
  }
2620
2679
  });
2680
+ Object.defineProperty(this, "outputSize", {
2681
+ get: () => outputSize
2682
+ });
2621
2683
 
2622
2684
  function shiftChunk() {
2623
2685
  const result = new Uint8Array(chunkSize);
@@ -2723,7 +2785,9 @@ function disableWebWorker(workerData) {
2723
2785
 
2724
2786
  class CodecWorker {
2725
2787
 
2726
- constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI, createWorker }, onTaskFinished) {
2788
+ constructor(workerData, { readable, writable }, workerOptions, onTaskFinished) {
2789
+ const { options, config, streamOptions, useWebWorkers, transferStreams, workerURI } = workerOptions;
2790
+ let { createWorker } = workerOptions;
2727
2791
  const { signal } = streamOptions;
2728
2792
  if (createWorkerFailed) {
2729
2793
  createWorker = UNDEFINED_VALUE;
@@ -2736,6 +2800,7 @@ class CodecWorker {
2736
2800
  .pipeThrough(new ProgressWatcherStream(streamOptions), { signal }),
2737
2801
  writable,
2738
2802
  options: Object.assign({}, options),
2803
+ workerOptions,
2739
2804
  workerURI,
2740
2805
  createWorker,
2741
2806
  transferStreams,
@@ -2817,8 +2882,8 @@ function createWorkerInterface(workerData, config) {
2817
2882
  };
2818
2883
  }
2819
2884
 
2820
- async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
2821
- let codecStream;
2885
+ async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
2886
+ let codecStream, chunkStream;
2822
2887
  try {
2823
2888
  if (options.compressed && !options.format) {
2824
2889
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
@@ -2841,9 +2906,10 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2841
2906
  }
2842
2907
  }
2843
2908
  codecStream = new CodecStream(options, config);
2909
+ chunkStream = new ChunkStream(getChunkSize(config));
2844
2910
  await readable
2845
2911
  .pipeThrough(codecStream)
2846
- .pipeThrough(new ChunkStream(getChunkSize(config)))
2912
+ .pipeThrough(chunkStream)
2847
2913
  .pipeTo(writable, { preventClose: true, preventAbort: true });
2848
2914
  const {
2849
2915
  crc32,
@@ -2857,7 +2923,15 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2857
2923
  };
2858
2924
  } catch (error) {
2859
2925
  if (codecStream) {
2860
- error.outputSize = codecStream.outputSize;
2926
+ const outputSize = chunkStream ? chunkStream.outputSize : 0;
2927
+ workerOptions.outputSize = outputSize;
2928
+ if (isErrorObject(error)) {
2929
+ try {
2930
+ error.outputSize = outputSize;
2931
+ } catch {
2932
+ // ignored
2933
+ }
2934
+ }
2861
2935
  }
2862
2936
  throw error;
2863
2937
  } finally {
@@ -2966,11 +3040,23 @@ async function runWebWorker(workerData, config) {
2966
3040
  let resolveResult, rejectResult;
2967
3041
  const result = new Promise((resolve, reject) => {
2968
3042
  resolveResult = resolve;
2969
- rejectResult = reject;
3043
+ rejectResult = error => {
3044
+ const { outputSize, workerOptions } = workerData;
3045
+ workerOptions.outputSize = outputSize;
3046
+ if (isErrorObject(error) && error.outputSize === UNDEFINED_VALUE) {
3047
+ try {
3048
+ error.outputSize = outputSize;
3049
+ } catch {
3050
+ // ignored
3051
+ }
3052
+ }
3053
+ reject(error);
3054
+ };
2970
3055
  });
2971
3056
  Object.assign(workerData, {
2972
3057
  reader: null,
2973
3058
  writer: null,
3059
+ outputSize: 0,
2974
3060
  resolveResult,
2975
3061
  rejectResult,
2976
3062
  result
@@ -3231,21 +3317,15 @@ function sendMessage(message, { worker, writer, transferStreams, workerAlive })
3231
3317
  }
3232
3318
 
3233
3319
  async function onMessage({ data }, workerData) {
3234
- const { type, value, messageId, result, error } = data;
3320
+ const { type, value, messageId, result, error, errorValue } = data;
3235
3321
  const { reader, writer, resolveResult, rejectResult, onTaskFinished, generation } = workerData;
3236
3322
  const stale = () => workerData.generation != generation;
3237
3323
  try {
3238
3324
  if (error) {
3239
- const { message, stack, code, name, outputSize, cause, codecImportFailed } = error;
3240
- const responseError = new Error(message);
3241
- Object.assign(responseError, { stack, code, name, outputSize });
3242
- if (cause) {
3243
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3244
- }
3245
- if (codecImportFailed) {
3246
- responseError.codecImportFailed = true;
3325
+ if (error.outputSize !== UNDEFINED_VALUE) {
3326
+ workerData.outputSize = error.outputSize;
3247
3327
  }
3248
- close(responseError);
3328
+ fail(getResponseError(error, errorValue));
3249
3329
  } else {
3250
3330
  if (type == MESSAGE_PULL) {
3251
3331
  const { value, done } = await reader.read();
@@ -3254,39 +3334,82 @@ async function onMessage({ data }, workerData) {
3254
3334
  }
3255
3335
  }
3256
3336
  if (type == MESSAGE_DATA) {
3337
+ const chunk = new Uint8Array(value);
3257
3338
  await writer.ready;
3258
- await writer.write(new Uint8Array(value));
3339
+ await writer.write(chunk);
3340
+ workerData.outputSize += chunk.length;
3259
3341
  if (!stale()) {
3260
3342
  sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
3261
3343
  }
3262
3344
  }
3263
3345
  if (type == MESSAGE_CLOSE) {
3264
- close(null, result);
3346
+ succeed(result);
3265
3347
  }
3266
3348
  }
3267
3349
  } catch (error) {
3268
3350
  if (!stale()) {
3269
3351
  terminateWorker$1(workerData);
3270
- close(error);
3352
+ fail(error);
3271
3353
  }
3272
3354
  }
3273
3355
 
3274
- function close(error, result) {
3275
- if (stale()) {
3276
- return;
3277
- }
3278
- if (error) {
3356
+ function fail(error) {
3357
+ if (!stale()) {
3279
3358
  rejectResult(error);
3280
- } else {
3359
+ releaseWriter();
3360
+ if (!(isErrorObject(error) && error.codecImportFailed)) {
3361
+ onTaskFinished();
3362
+ }
3363
+ }
3364
+ }
3365
+
3366
+ function succeed(result) {
3367
+ if (!stale()) {
3281
3368
  resolveResult(result);
3369
+ releaseWriter();
3370
+ onTaskFinished();
3282
3371
  }
3372
+ }
3373
+
3374
+ function releaseWriter() {
3283
3375
  if (writer) {
3284
3376
  writer.releaseLock();
3285
3377
  }
3286
- if (!(error && error.codecImportFailed)) {
3287
- onTaskFinished();
3378
+ }
3379
+ }
3380
+
3381
+ function getResponseError(errorData, errorValue) {
3382
+ const { message, stack, code, name, outputSize, cause, codecImportFailed } = errorData;
3383
+ let responseError;
3384
+ if (errorValue) {
3385
+ responseError = errorValue.value;
3386
+ } else {
3387
+ responseError = Object.assign(new Error(message), { stack, code, name });
3388
+ if (cause) {
3389
+ responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3288
3390
  }
3289
3391
  }
3392
+ if (isErrorObject(responseError)) {
3393
+ try {
3394
+ if (outputSize !== UNDEFINED_VALUE) {
3395
+ responseError.outputSize = outputSize;
3396
+ }
3397
+ if (codecImportFailed) {
3398
+ responseError.codecImportFailed = true;
3399
+ }
3400
+ if (errorValue) {
3401
+ if (responseError.name !== name) {
3402
+ responseError.name = name;
3403
+ }
3404
+ if (responseError.code !== code) {
3405
+ responseError.code = code;
3406
+ }
3407
+ }
3408
+ } catch {
3409
+ // ignored
3410
+ }
3411
+ }
3412
+ return responseError;
3290
3413
  }
3291
3414
 
3292
3415
  /*
@@ -3563,10 +3686,13 @@ function decode(value, encoding, ignoreBOM) {
3563
3686
 
3564
3687
 
3565
3688
  const ERR_HTTP_STATUS = "HTTP error ";
3689
+ const MIN_SUCCESS_HTTP_STATUS = 200;
3690
+ const MAX_SUCCESS_HTTP_STATUS = 299;
3566
3691
  const ERR_HTTP_RANGE = "HTTP Range not supported";
3567
3692
  const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
3568
3693
  const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
3569
3694
  const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
3695
+ const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
3570
3696
 
3571
3697
  const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
3572
3698
  const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
@@ -3758,6 +3884,7 @@ class BlobReader extends Reader {
3758
3884
  const reader = this;
3759
3885
  const { sourceBlob, size } = reader;
3760
3886
  const { offset = 0, size: readSize = size - offset } = options || {};
3887
+ // deno-lint-ignore valid-typeof
3761
3888
  if (typeof sourceBlob.stream == FUNCTION_TYPE) {
3762
3889
  if (!offset && readSize >= size) {
3763
3890
  return toCompatibleReadable(sourceBlob.stream());
@@ -4164,7 +4291,7 @@ async function getContentLength(httpReader, sendRequest, getRequestData) {
4164
4291
 
4165
4292
  async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
4166
4293
  const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
4167
- if (response.status < 400) {
4294
+ if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
4168
4295
  return response;
4169
4296
  } else {
4170
4297
  throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
@@ -4175,7 +4302,7 @@ function sendXMLHttpRequest(method, { url }, headers) {
4175
4302
  return new Promise((resolve, reject) => {
4176
4303
  const request = new XMLHttpRequest();
4177
4304
  request.addEventListener("load", () => {
4178
- if (request.status < 400) {
4305
+ if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
4179
4306
  const headers = [];
4180
4307
  request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
4181
4308
  const splitHeader = header.trim().split(/\s*:\s*/);
@@ -4479,8 +4606,10 @@ class GenericWriter {
4479
4606
  writable: toCompatibleWritable(writer)
4480
4607
  };
4481
4608
  }
4482
- if (writer.size === UNDEFINED_VALUE) {
4483
- writer.size = 0;
4609
+ try {
4610
+ writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
4611
+ } catch {
4612
+ throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
4484
4613
  }
4485
4614
  return writer;
4486
4615
  }
@@ -4528,6 +4657,45 @@ function createReadable(reader, options) {
4528
4657
  }
4529
4658
  }
4530
4659
 
4660
+ /*
4661
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
4662
+
4663
+ Redistribution and use in source and binary forms, with or without
4664
+ modification, are permitted provided that the following conditions are met:
4665
+
4666
+ 1. Redistributions of source code must retain the above copyright notice,
4667
+ this list of conditions and the following disclaimer.
4668
+
4669
+ 2. Redistributions in binary form must reproduce the above copyright
4670
+ notice, this list of conditions and the following disclaimer in
4671
+ the documentation and/or other materials provided with the distribution.
4672
+
4673
+ 3. The names of the authors may not be used to endorse or promote products
4674
+ derived from this software without specific prior written permission.
4675
+
4676
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4677
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4678
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4679
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4680
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4681
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4682
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4683
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4684
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4685
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4686
+ */
4687
+
4688
+
4689
+ function addWarning(warnings, reason, filename) {
4690
+ if (!warnings.some(warning => warning.reason == reason)) {
4691
+ const warning = { reason };
4692
+ if (filename !== UNDEFINED_VALUE) {
4693
+ warning.filename = filename;
4694
+ }
4695
+ warnings.push(warning);
4696
+ }
4697
+ }
4698
+
4531
4699
  /*
4532
4700
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4533
4701
 
@@ -4556,6 +4724,7 @@ function createReadable(reader, options) {
4556
4724
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4557
4725
  */
4558
4726
 
4727
+
4559
4728
  const PROPERTY_NAME_FILENAME = "filename";
4560
4729
  const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
4561
4730
  const PROPERTY_NAME_COMMENT = "comment";
@@ -4680,6 +4849,38 @@ class Entry {
4680
4849
 
4681
4850
  }
4682
4851
 
4852
+ const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
4853
+ EXTRAFIELD_TYPE_ZIP64,
4854
+ EXTRAFIELD_TYPE_AES,
4855
+ EXTRAFIELD_TYPE_NTFS,
4856
+ EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
4857
+ EXTRAFIELD_TYPE_UNICODE_PATH,
4858
+ EXTRAFIELD_TYPE_UNICODE_COMMENT,
4859
+ EXTRAFIELD_TYPE_USDZ,
4860
+ EXTRAFIELD_TYPE_INFOZIP,
4861
+ EXTRAFIELD_TYPE_UNIX,
4862
+ EXTRAFIELD_TYPE_UNIX_TYPE1,
4863
+ EXTRAFIELD_TYPE_PKWARE_UNIX
4864
+ ]);
4865
+
4866
+ function getUserExtraField(extraField) {
4867
+ if (extraField) {
4868
+ const userExtraField = new Map();
4869
+ extraField.forEach((field, type) => {
4870
+ if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
4871
+ userExtraField.set(type, field.data);
4872
+ }
4873
+ });
4874
+ if (userExtraField.size) {
4875
+ return userExtraField;
4876
+ }
4877
+ }
4878
+ }
4879
+
4880
+ function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
4881
+ return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
4882
+ }
4883
+
4683
4884
  /*
4684
4885
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4685
4886
 
@@ -4739,6 +4940,8 @@ const WARNING_PREPENDED_CENTRAL_DIRECTORY = "prepended central directory";
4739
4940
  const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4740
4941
  const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4741
4942
  const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4943
+ const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
4944
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
4742
4945
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4743
4946
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4744
4947
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
@@ -4809,7 +5012,7 @@ class ZipReader {
4809
5012
  }
4810
5013
  }
4811
5014
  if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
4812
- throwAmbiguousArchive("multiple end of central directory records");
5015
+ throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
4813
5016
  }
4814
5017
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4815
5018
  let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
@@ -5107,7 +5310,8 @@ class ZipReader {
5107
5310
  const writer = new TransformStream();
5108
5311
  const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
5109
5312
  arrayBufferPromise.catch(() => { });
5110
- await fileEntry.getData(writer, entry, zipReader.readRanges, options);
5313
+ await fileEntry.getData(writer, entry, zipReader.readRanges,
5314
+ Object.assign({}, options, { preventClose: false }));
5111
5315
  return arrayBufferPromise;
5112
5316
  };
5113
5317
  offset = endOffset;
@@ -5188,49 +5392,101 @@ class ZipReader {
5188
5392
  await reader.readable.cancel();
5189
5393
  }
5190
5394
  }
5395
+
5396
+ [SYMBOL_ASYNC_DISPOSE]() {
5397
+ return this.close();
5398
+ }
5191
5399
  }
5192
5400
 
5193
5401
  class ZipReaderStream {
5194
5402
 
5195
5403
  constructor(options = {}) {
5196
- const { readable, writable } = new TransformStream();
5197
- const gen = new ZipReader(readable, options).getEntriesGenerator();
5404
+ let sourceController;
5405
+ const { readable, writable } = new TransformStream({
5406
+ start(controller) {
5407
+ sourceController = controller;
5408
+ }
5409
+ });
5410
+ const zipReader = new ZipReader(readable, options);
5411
+ const gen = zipReader.getEntriesGenerator();
5412
+ const pendingEntries = new Set();
5198
5413
  this.readable = new ReadableStream({
5199
5414
  async pull(controller) {
5200
5415
  const { done, value } = await gen.next();
5201
5416
  if (done)
5202
5417
  return controller.close();
5203
- const entryReadable = (function () {
5204
- const { readable, writable } = new TransformStream();
5205
- if (value.getData) {
5206
- getData();
5207
- return readable;
5208
- }
5209
-
5210
- async function getData() {
5211
- try {
5212
- await value.getData(writable);
5213
- } catch (error) {
5214
- try {
5215
- await writable.abort(error);
5216
- } catch {
5217
- // ignored
5218
- }
5219
- }
5220
- }
5221
- })();
5418
+ const entryStream = createEntryStream(value, pendingEntries);
5222
5419
  const chunk = {
5223
5420
  ...value,
5224
- readable: entryReadable
5421
+ readable: entryStream.readable
5225
5422
  };
5226
5423
  delete chunk.getData;
5424
+ Object.defineProperties(chunk, {
5425
+ localDirectory: {
5426
+ get: () => value.localDirectory,
5427
+ enumerable: true
5428
+ },
5429
+ warnings: {
5430
+ get: () => value.warnings,
5431
+ enumerable: true
5432
+ }
5433
+ });
5227
5434
  controller.enqueue(chunk);
5435
+ },
5436
+ async cancel(reason) {
5437
+ const entryStreams = Array.from(pendingEntries);
5438
+ pendingEntries.clear();
5439
+ sourceController.error(reason);
5440
+ await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
5441
+ await Promise.allSettled([gen.return(), zipReader.close()]);
5228
5442
  }
5229
5443
  });
5230
5444
  this.writable = writable;
5231
5445
  }
5232
5446
  }
5233
5447
 
5448
+ function createEntryStream(entry, pendingEntries) {
5449
+ const { readable, writable } = new TransformStream();
5450
+ let dataReader;
5451
+ const entryStream = {
5452
+ cancel: async reason => {
5453
+ pendingEntries.delete(entryStream);
5454
+ await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
5455
+ }
5456
+ };
5457
+ entryStream.readable = new ReadableStream({
5458
+ async pull(controller) {
5459
+ if (!dataReader) {
5460
+ dataReader = readable.getReader();
5461
+ pendingEntries.add(entryStream);
5462
+ getData();
5463
+ }
5464
+ const { done, value } = await dataReader.read();
5465
+ if (done) {
5466
+ controller.close();
5467
+ } else {
5468
+ controller.enqueue(value);
5469
+ }
5470
+ },
5471
+ cancel: reason => entryStream.cancel(reason)
5472
+ }, { highWaterMark: 0 });
5473
+ return entryStream;
5474
+
5475
+ async function getData() {
5476
+ try {
5477
+ await entry.getData(writable, { preventClose: false });
5478
+ } catch (error) {
5479
+ try {
5480
+ await writable.abort(error);
5481
+ } catch {
5482
+ // ignored
5483
+ }
5484
+ } finally {
5485
+ pendingEntries.delete(entryStream);
5486
+ }
5487
+ }
5488
+ }
5489
+
5234
5490
  async function isZipFile(reader, options = {}) {
5235
5491
  reader = new GenericReader(reader);
5236
5492
  await initStream(reader);
@@ -5290,7 +5546,9 @@ let ZipEntry$1 = class ZipEntry {
5290
5546
  const dataView = getDataView(dataArray);
5291
5547
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
5292
5548
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
5293
- const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
5549
+ const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
5550
+ const passThroughCompression = Boolean(passThrough);
5551
+ const passThroughEncryption = passThrough === true;
5294
5552
  checkPasswordOption(password, rawPassword);
5295
5553
  password = password && password.length && password;
5296
5554
  rawPassword = rawPassword && rawPassword.length && rawPassword;
@@ -5311,7 +5569,9 @@ let ZipEntry$1 = class ZipEntry {
5311
5569
  const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5312
5570
  const entryStrictness = getStrictness(options, zipEntry.options);
5313
5571
  const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5314
- const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
5572
+ const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
5573
+ const checkLocalFilename = getCheckLocalFilename(
5574
+ checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
5315
5575
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5316
5576
  if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5317
5577
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
@@ -5342,16 +5602,17 @@ let ZipEntry$1 = class ZipEntry {
5342
5602
  if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5343
5603
  fileEntry.gid = gid;
5344
5604
  }
5345
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
5605
+ const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5606
+ const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
5346
5607
  const zipCrypto = encrypted && !extraFieldAES;
5347
- if (!passThrough) {
5608
+ if (!passThroughEncryption) {
5348
5609
  fileEntry.zipCrypto = zipCrypto;
5349
5610
  }
5350
5611
  if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5351
5612
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
5352
5613
  }
5353
- const registeredCodec = passThrough ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5354
- if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThrough) {
5614
+ const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
5615
+ if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
5355
5616
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
5356
5617
  }
5357
5618
  if (encrypted) {
@@ -5368,15 +5629,16 @@ let ZipEntry$1 = class ZipEntry {
5368
5629
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5369
5630
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5370
5631
  throwIfAborted(signal);
5371
- const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5372
5632
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
5373
5633
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
5374
5634
  if (checkOverlappingEntryOnly) {
5375
5635
  checkOverlappingEntry = true;
5376
5636
  }
5377
5637
  const { onstart, onprogress, onend } = options;
5378
- const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
5379
- const outputSize = passThrough ? compressedSize : uncompressedSize;
5638
+ const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
5639
+ const outputSize = passThroughCompression ?
5640
+ compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
5641
+ uncompressedSize;
5380
5642
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
5381
5643
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
5382
5644
  if (deflate64) {
@@ -5385,7 +5647,7 @@ let ZipEntry$1 = class ZipEntry {
5385
5647
  const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
5386
5648
  const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
5387
5649
  getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
5388
- checkCrc32Option) && !passThrough &&
5650
+ checkCrc32Option) && !passThroughCompression &&
5389
5651
  (!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
5390
5652
  const workerOptions = {
5391
5653
  options: {
@@ -5429,7 +5691,7 @@ let ZipEntry$1 = class ZipEntry {
5429
5691
  readRanges
5430
5692
  });
5431
5693
  }
5432
- let writable, abortError;
5694
+ let writable, abortError, aborted;
5433
5695
  try {
5434
5696
  if (!checkOverlappingEntryOnly) {
5435
5697
  if (checkPasswordOnly) {
@@ -5439,24 +5701,28 @@ let ZipEntry$1 = class ZipEntry {
5439
5701
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5440
5702
  ({ writable } = writer);
5441
5703
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5442
- writer.size += writtenSize;
5443
5704
  if (writtenSize != outputSize) {
5444
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
5705
+ throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5445
5706
  }
5707
+ writer.size += writtenSize;
5446
5708
  }
5447
5709
  } catch (error) {
5448
- if (error.outputSize !== UNDEFINED_VALUE) {
5710
+ const { outputSize: failedOutputSize } = workerOptions;
5711
+ if (failedOutputSize !== UNDEFINED_VALUE) {
5712
+ writer.size += failedOutputSize;
5713
+ } else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
5449
5714
  writer.size += error.outputSize;
5450
5715
  }
5451
- if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
5716
+ if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
5452
5717
  abortError = error;
5718
+ aborted = true;
5453
5719
  throw error;
5454
5720
  }
5455
5721
  } finally {
5456
5722
  const preventClose = !ownsWritable(writer) && getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
5457
5723
  if (!preventClose && writable && !writable.locked) {
5458
5724
  const writableWriter = writable.getWriter();
5459
- if (abortError) {
5725
+ if (aborted) {
5460
5726
  try {
5461
5727
  await writableWriter.abort(abortError);
5462
5728
  } catch {
@@ -6108,7 +6374,7 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
6108
6374
  if (checkLocalFilename && !maskedLocalDirectory &&
6109
6375
  (rawLocalFilename.length != rawFilename.length ||
6110
6376
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
6111
- reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
6377
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
6112
6378
  }
6113
6379
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
6114
6380
  reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
@@ -6133,16 +6399,6 @@ function reportAmbiguity(reject, warnings, reason) {
6133
6399
  }
6134
6400
  }
6135
6401
 
6136
- function addWarning(warnings, reason, filename) {
6137
- if (!warnings.some(warning => warning.reason == reason)) {
6138
- const warning = { reason };
6139
- if (filename !== UNDEFINED_VALUE) {
6140
- warning.filename = filename;
6141
- }
6142
- warnings.push(warning);
6143
- }
6144
- }
6145
-
6146
6402
  function throwAmbiguousArchive(reason) {
6147
6403
  const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
6148
6404
  error.reason = reason;
@@ -6222,7 +6478,9 @@ var zipReader = /*#__PURE__*/Object.freeze({
6222
6478
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6223
6479
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6224
6480
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6481
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
6225
6482
  WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6483
+ WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
6226
6484
  WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
6227
6485
  WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6228
6486
  WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
@@ -6275,7 +6533,7 @@ const ERR_INVALID_VERSION = "Version exceeds 65535";
6275
6533
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
6276
6534
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
6277
6535
  const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
6278
- const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
6536
+ const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
6279
6537
  const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
6280
6538
  const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
6281
6539
  const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
@@ -6287,6 +6545,7 @@ const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
6287
6545
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
6288
6546
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
6289
6547
  const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
6548
+ const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
6290
6549
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
6291
6550
  const ERR_UNDEFINED_READER = "Undefined reader";
6292
6551
  const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
@@ -6300,14 +6559,21 @@ const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be intege
6300
6559
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
6301
6560
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
6302
6561
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6562
+ const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
6563
+ const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
6564
+ const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
6565
+ const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
6303
6566
 
6304
6567
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6305
6568
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6306
6569
  const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6307
6570
  const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6571
+ const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
6572
+ const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
6308
6573
  const VENDOR_VERSION_AE_1 = 1;
6309
- const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6574
+ const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
6310
6575
  const UNIX_EXTRA_FIELD_TYPE = "unix";
6576
+ const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
6311
6577
  const MAX_LEVEL = 9;
6312
6578
 
6313
6579
  let workers = 0;
@@ -6334,9 +6600,11 @@ class ZipWriter {
6334
6600
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
6335
6601
  pendingAddFileCalls: new Set(),
6336
6602
  pendingErrors: [],
6603
+ warnings: [],
6337
6604
  bufferedWrites: 0,
6338
6605
  directWrites: 0,
6339
- lastFileEntry: UNDEFINED_VALUE
6606
+ lastFileEntry: UNDEFINED_VALUE,
6607
+ archiveClosed: false
6340
6608
  });
6341
6609
  }
6342
6610
 
@@ -6501,6 +6769,9 @@ class ZipWriter {
6501
6769
  const zipWriter = this;
6502
6770
  const { pendingAddFileCalls, writer } = this;
6503
6771
  const { writable } = writer;
6772
+ if (zipWriter.archiveClosed) {
6773
+ return getWriterData(writer);
6774
+ }
6504
6775
  if (!(comment instanceof Uint8Array)) {
6505
6776
  throw new Error(ERR_INVALID_COMMENT_TYPE);
6506
6777
  }
@@ -6511,7 +6782,7 @@ class ZipWriter {
6511
6782
  await Promise.allSettled(Array.from(pendingAddFileCalls));
6512
6783
  }
6513
6784
  await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
6514
- const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
6785
+ const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.failed && !watcher.observed);
6515
6786
  if (unobservedWatchers.length) {
6516
6787
  const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
6517
6788
  unobservedWatchers.forEach(watcher => watcher.observed = true);
@@ -6524,11 +6795,16 @@ class ZipWriter {
6524
6795
  throw error;
6525
6796
  }
6526
6797
  await closeFile(zipWriter, comment, options);
6798
+ zipWriter.archiveClosed = true;
6527
6799
  const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
6528
6800
  if (!preventClose) {
6529
6801
  await writable.getWriter().close();
6530
6802
  }
6531
- return writer.getData ? writer.getData() : writable;
6803
+ return getWriterData(writer);
6804
+ }
6805
+
6806
+ [SYMBOL_ASYNC_DISPOSE]() {
6807
+ return this.close();
6532
6808
  }
6533
6809
  }
6534
6810
 
@@ -6607,11 +6883,16 @@ class WatchedPromise extends Promise {
6607
6883
  }
6608
6884
  }
6609
6885
 
6886
+ function getWriterData(writer) {
6887
+ return writer.getData ? writer.getData() : writer.writable;
6888
+ }
6889
+
6610
6890
  function watchPromiseError(zipWriter, promise) {
6611
6891
  const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6612
6892
  const watcher = {};
6613
6893
  watchedPromise.watcher = watcher;
6614
- watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
6894
+ watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE,
6895
+ error => Object.assign(watcher, { failed: true, error }));
6615
6896
  zipWriter.pendingErrors.push(watcher);
6616
6897
  return watchedPromise;
6617
6898
  }
@@ -6625,6 +6906,14 @@ async function prependZipEntries(zipWriter, reader) {
6625
6906
 
6626
6907
  async function addFileEntry(zipWriter, name, reader, options) {
6627
6908
  options = Object.assign({}, options);
6909
+ const entry = options[OPTION_ENTRY];
6910
+ if (entry !== UNDEFINED_VALUE) {
6911
+ const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
6912
+ checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
6913
+ getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
6914
+ delete options[OPTION_ENTRY];
6915
+ options = Object.assign(entryOptions, passThroughOptions, options);
6916
+ }
6628
6917
  if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6629
6918
  name += DIRECTORY_SIGNATURE;
6630
6919
  }
@@ -6689,21 +6978,33 @@ async function addFile(zipWriter, name, reader, options) {
6689
6978
  try {
6690
6979
  const { resolvedOptions } = metadataInfo;
6691
6980
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
6692
- !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
6981
+ !resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
6693
6982
  resolvedOptions.level = 0;
6983
+ addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
6694
6984
  }
6695
6985
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
6696
6986
  ({ reader } = sizesInfo);
6697
6987
  const diskOffset = getDiskOffset(zipWriter.writer);
6698
6988
  const diskNumber = getDiskNumber(zipWriter.writer);
6989
+ let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
6990
+ const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
6991
+ if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
6992
+ crc32 = UNDEFINED_VALUE;
6993
+ }
6994
+ if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
6995
+ throw new Error(ERR_UNDEFINED_CRC32);
6996
+ }
6699
6997
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6700
6998
  signature: options[PROPERTY_NAME_SIGNATURE],
6701
- crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6999
+ crc32,
6702
7000
  offset: zipWriter.offset - diskOffset,
6703
7001
  diskNumberStart: diskNumber,
6704
7002
  [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6705
7003
  });
6706
7004
  const headerInfo = getHeaderInfo(options);
7005
+ if (headerInfo.lastModDateClamped) {
7006
+ addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
7007
+ }
6707
7008
  const dataDescriptorInfo = getDataDescriptorInfo(options);
6708
7009
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6709
7010
  fileEntry = await getFileEntry(zipWriter, name, reader, {
@@ -6730,6 +7031,95 @@ async function addFile(zipWriter, name, reader, options) {
6730
7031
  return new Entry(fileEntry);
6731
7032
  }
6732
7033
 
7034
+ function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
7035
+ if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
7036
+ throw new Error(ERR_INVALID_ENTRY);
7037
+ }
7038
+ const {
7039
+ externalFileAttributes,
7040
+ versionMadeBy,
7041
+ comment,
7042
+ lastModDate,
7043
+ rawLastModDate,
7044
+ creationDate,
7045
+ lastAccessDate,
7046
+ uncompressedSize,
7047
+ encrypted,
7048
+ zipCrypto,
7049
+ crc32,
7050
+ compressionMethod,
7051
+ extraFieldAES,
7052
+ extraFieldUnix,
7053
+ internalFileAttributes,
7054
+ extraField,
7055
+ bitFlag,
7056
+ directory,
7057
+ uid,
7058
+ gid
7059
+ } = entry;
7060
+ const entryOptions = {
7061
+ externalFileAttributes,
7062
+ versionMadeBy,
7063
+ comment,
7064
+ lastModDate,
7065
+ creationDate,
7066
+ lastAccessDate,
7067
+ internalFileAttributes,
7068
+ directory
7069
+ };
7070
+ if (bitFlag && bitFlag.languageEncodingFlag) {
7071
+ entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
7072
+ }
7073
+ const userExtraField = getUserExtraField(extraField);
7074
+ if (userExtraField) {
7075
+ entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
7076
+ }
7077
+ if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
7078
+ Object.assign(entryOptions, {
7079
+ uid,
7080
+ gid,
7081
+ unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
7082
+ });
7083
+ }
7084
+ const passThroughOptions = {};
7085
+ if (passThrough && !directory) {
7086
+ Object.assign(passThroughOptions, {
7087
+ uncompressedSize,
7088
+ crc32,
7089
+ compressionMethod
7090
+ });
7091
+ if (passThrough !== PASS_THROUGH_COMPRESSED) {
7092
+ Object.assign(passThroughOptions, {
7093
+ encrypted,
7094
+ zipCrypto,
7095
+ encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
7096
+ });
7097
+ }
7098
+ if (bitFlag) {
7099
+ passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
7100
+ passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
7101
+ }
7102
+ if (lastModDateOverride === UNDEFINED_VALUE) {
7103
+ passThroughOptions.rawLastModDate = rawLastModDate;
7104
+ } else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
7105
+ lastModDateOverride instanceof Date &&
7106
+ getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
7107
+ throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
7108
+ }
7109
+ }
7110
+ return { entryOptions, passThroughOptions };
7111
+ }
7112
+
7113
+ function getDosTimeHighByte(lastModDate) {
7114
+ let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
7115
+ if (dosLastModDate < MIN_DATE) {
7116
+ dosLastModDate = MIN_DATE;
7117
+ } else if (dosLastModDate > MAX_DATE) {
7118
+ dosLastModDate = MAX_DATE;
7119
+ }
7120
+ return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
7121
+ }
7122
+
6733
7123
  function resolveAttributes(zipWriter, name, options) {
6734
7124
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6735
7125
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
@@ -6744,7 +7134,7 @@ function resolveAttributes(zipWriter, name, options) {
6744
7134
  checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6745
7135
  checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6746
7136
  checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6747
- if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
7137
+ if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6748
7138
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6749
7139
  }
6750
7140
  if (unixExtraFieldType === UNIX_EXTRA_FIELD_TYPE &&
@@ -6752,7 +7142,7 @@ function resolveAttributes(zipWriter, name, options) {
6752
7142
  throw new Error(ERR_INVALID_UNIX_ID_SIZE);
6753
7143
  }
6754
7144
  if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
6755
- unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
7145
+ unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
6756
7146
  }
6757
7147
  let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6758
7148
  let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
@@ -6883,7 +7273,9 @@ function resolveMetadata(zipWriter, name, options) {
6883
7273
  const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6884
7274
  const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6885
7275
  const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
6886
- const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
7276
+ const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
7277
+ const passThroughCompression = Boolean(passThrough);
7278
+ const passThroughEncryption = passThrough === true;
6887
7279
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6888
7280
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6889
7281
  checkPasswordOption(password, rawPassword);
@@ -6899,10 +7291,11 @@ function resolveMetadata(zipWriter, name, options) {
6899
7291
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
6900
7292
  const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
6901
7293
  throwIfAborted(signal);
6902
- const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
7294
+ const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
7295
+ !isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
6903
7296
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
6904
- const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
6905
- if (!passThrough && compressionMethod !== UNDEFINED_VALUE &&
7297
+ const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
7298
+ if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
6906
7299
  compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
6907
7300
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6908
7301
  }
@@ -6916,15 +7309,15 @@ function resolveMetadata(zipWriter, name, options) {
6916
7309
  level = 0;
6917
7310
  }
6918
7311
  }
6919
- if (passThrough) {
6920
- level = UNDEFINED_VALUE;
7312
+ if (passThroughCompression) {
7313
+ level = toNumber(options[OPTION_LEVEL]);
6921
7314
  }
6922
7315
  let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
6923
7316
  let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
6924
7317
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
6925
7318
  dataDescriptor = false;
6926
7319
  }
6927
- if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
7320
+ if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
6928
7321
  dataDescriptor = true;
6929
7322
  }
6930
7323
  if (level !== UNDEFINED_VALUE && level != 6) {
@@ -6948,7 +7341,8 @@ function resolveMetadata(zipWriter, name, options) {
6948
7341
  lastAccessDate,
6949
7342
  creationDate,
6950
7343
  internalFileAttributes,
6951
- passThrough,
7344
+ passThroughCompression,
7345
+ passThroughEncryption,
6952
7346
  password,
6953
7347
  rawPassword,
6954
7348
  encryptionStrength,
@@ -7009,7 +7403,7 @@ function serializeExtraField(extraField) {
7009
7403
  }
7010
7404
 
7011
7405
  async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
7012
- if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7406
+ if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
7013
7407
  throw new Error(ERR_UNDEFINED_READER);
7014
7408
  }
7015
7409
  let contentSize;
@@ -7025,12 +7419,12 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
7025
7419
  }
7026
7420
 
7027
7421
  function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
7028
- const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7422
+ const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
7029
7423
  let { dataDescriptor, zip64, level, compressionMethod } = metadata;
7030
7424
  let maximumCompressedSize = 0;
7031
7425
  let uncompressedSize = 0;
7032
7426
  let unknownSize = false;
7033
- if (passThrough && hasContent) {
7427
+ if (passThroughCompression && hasContent) {
7034
7428
  uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
7035
7429
  if (uncompressedSize === UNDEFINED_VALUE) {
7036
7430
  throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
@@ -7041,17 +7435,17 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
7041
7435
  }
7042
7436
  const zip64Enabled = zip64 === true;
7043
7437
  const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
7044
- if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
7438
+ if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
7045
7439
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
7046
7440
  }
7047
- const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
7441
+ const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
7048
7442
  if (!hasContent) {
7049
7443
  level = 0;
7050
7444
  compressionMethod = COMPRESSION_METHOD_STORE;
7051
7445
  }
7052
- const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7446
+ const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
7053
7447
  if (hasContent) {
7054
- if (!passThrough) {
7448
+ if (!passThroughCompression) {
7055
7449
  if (contentSize === UNDEFINED_VALUE) {
7056
7450
  dataDescriptor = true;
7057
7451
  if (zip64 || zip64 === UNDEFINED_VALUE) {
@@ -7064,10 +7458,12 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
7064
7458
  }
7065
7459
  } else {
7066
7460
  options.uncompressedSize = uncompressedSize;
7067
- maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
7461
+ maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
7462
+ getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
7463
+ contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
7068
7464
  }
7069
7465
  }
7070
- const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
7466
+ const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
7071
7467
  if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7072
7468
  dataDescriptor = false;
7073
7469
  }
@@ -7116,6 +7512,8 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7116
7512
  const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
7117
7513
  let offset = initialOffset;
7118
7514
  let minimumEntrySize = INFINITY_VALUE;
7515
+ const entrySizes = [];
7516
+ const entriesAlreadyZip64 = new Set();
7119
7517
  for (const entry of entries) {
7120
7518
  let { name } = entry;
7121
7519
  const { size } = entry;
@@ -7127,7 +7525,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7127
7525
  ({ name } = attributesInfo);
7128
7526
  const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
7129
7527
  if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
7130
- !metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
7528
+ !metadata.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
7131
7529
  metadata.level = 0;
7132
7530
  }
7133
7531
  const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
@@ -7135,7 +7533,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7135
7533
  throw new Error(ERR_UNDETERMINED_SIZE);
7136
7534
  }
7137
7535
  const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
7138
- if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
7536
+ if (hasContent && !metadata.passThroughCompression && isCompressed(sizes.compressionMethod, sizes.level)) {
7139
7537
  throw new Error(ERR_UNDETERMINED_SIZE);
7140
7538
  }
7141
7539
  const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
@@ -7155,10 +7553,15 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7155
7553
  compressedSize
7156
7554
  }));
7157
7555
  const entrySize = entryInfo.metadataSize + compressedSize;
7556
+ entrySizes.push(entrySize);
7557
+ entriesAlreadyZip64.add(Boolean(entryOptions.zip64Enabled ||
7558
+ entryOptions.uncompressedSize >= MAX_32_BITS || compressedSize >= MAX_32_BITS));
7158
7559
  minimumEntrySize = Math.min(minimumEntrySize, entrySize);
7159
7560
  offset += entrySize;
7160
7561
  }
7161
- const layoutDependsOnWriteOrder = files.size > 1 && (usdz || offset - minimumEntrySize >= MAX_32_BITS);
7562
+ const layoutDependsOnWriteOrder = files.size > 1 && (usdz ||
7563
+ (offset - minimumEntrySize >= MAX_32_BITS &&
7564
+ (entriesAlreadyZip64.size > 1 || countEntriesBefore4GB(entrySizes, initialOffset, true) != countEntriesBefore4GB(entrySizes, initialOffset, false))));
7162
7565
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
7163
7566
  throw new Error(ERR_UNDETERMINED_SIZE);
7164
7567
  }
@@ -7176,6 +7579,20 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
7176
7579
  return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
7177
7580
  }
7178
7581
 
7582
+ function countEntriesBefore4GB(entrySizes, initialOffset, largestFirst) {
7583
+ const ordered = entrySizes.slice().sort((first, second) => largestFirst ? second - first : first - second);
7584
+ let position = initialOffset;
7585
+ let count = 0;
7586
+ for (const entrySize of ordered) {
7587
+ if (position >= MAX_32_BITS) {
7588
+ break;
7589
+ }
7590
+ position += entrySize;
7591
+ count++;
7592
+ }
7593
+ return count;
7594
+ }
7595
+
7179
7596
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7180
7597
  const {
7181
7598
  fileEntries,
@@ -7351,6 +7768,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7351
7768
  localExtraFieldZip64Length,
7352
7769
  rawExtraFieldExtendedTimestamp,
7353
7770
  extraFieldExtendedTimestampFlag,
7771
+ extraFieldExtendedTimestampTime,
7354
7772
  rawExtraFieldNTFS,
7355
7773
  rawExtraFieldUnix,
7356
7774
  rawExtraFieldAES,
@@ -7363,6 +7781,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7363
7781
  password,
7364
7782
  rawPassword,
7365
7783
  level,
7784
+ useUnicodeFileNames,
7366
7785
  zip64,
7367
7786
  zip64Enabled,
7368
7787
  zip64UncompressedSize,
@@ -7397,7 +7816,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7397
7816
  msdosAttributesRaw,
7398
7817
  msdosAttributes,
7399
7818
  useCompressionStream,
7400
- passThrough,
7819
+ passThroughCompression,
7820
+ passThroughEncryption,
7401
7821
  format,
7402
7822
  codecURI
7403
7823
  } = options;
@@ -7408,9 +7828,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7408
7828
  zip64Enabled,
7409
7829
  directory: Boolean(directory),
7410
7830
  executable: Boolean(executable),
7411
- filenameUTF8: true,
7831
+ filenameUTF8: Boolean(useUnicodeFileNames),
7412
7832
  rawFilename,
7413
- commentUTF8: true,
7833
+ commentUTF8: Boolean(useUnicodeFileNames),
7414
7834
  rawComment,
7415
7835
  rawExtraFieldZip64,
7416
7836
  localExtraFieldZip64Length,
@@ -7441,7 +7861,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7441
7861
  uncompressedSize
7442
7862
  } = options;
7443
7863
  let compressedSize = 0;
7444
- if (!passThrough) {
7864
+ if (!passThroughCompression) {
7445
7865
  uncompressedSize = 0;
7446
7866
  }
7447
7867
  const { writable } = writer;
@@ -7458,9 +7878,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7458
7878
  encryptionStrength,
7459
7879
  zipCrypto: encrypted && zipCrypto,
7460
7880
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
7461
- computeCrc32: !passThrough,
7462
- compressed: compressed && !passThrough,
7463
- encrypted: encrypted && !passThrough,
7881
+ computeCrc32: !passThroughCompression,
7882
+ compressed: compressed && !passThroughCompression,
7883
+ encrypted: encrypted && !passThroughEncryption,
7464
7884
  useWebWorkers,
7465
7885
  useCompressionStream,
7466
7886
  transferStreams,
@@ -7475,7 +7895,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7475
7895
  const result = await runWorker({ readable, writable }, workerOptions);
7476
7896
  compressedSize = result.outputSize;
7477
7897
  writer.size += compressedSize;
7478
- if (!passThrough) {
7898
+ if (!passThroughCompression) {
7479
7899
  uncompressedSize = result.inputSize;
7480
7900
  if (!encrypted || zipCrypto) {
7481
7901
  crc32 = result.crc32;
@@ -7486,7 +7906,10 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7486
7906
  throw new Error(ERR_UNSUPPORTED_FORMAT);
7487
7907
  }
7488
7908
  } catch (error) {
7489
- if (error.outputSize !== UNDEFINED_VALUE) {
7909
+ const { outputSize: failedOutputSize } = workerOptions;
7910
+ if (failedOutputSize !== UNDEFINED_VALUE) {
7911
+ writer.size += failedOutputSize;
7912
+ } else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
7490
7913
  writer.size += error.outputSize;
7491
7914
  }
7492
7915
  throw error;
@@ -7518,8 +7941,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7518
7941
  headerArray,
7519
7942
  headerView,
7520
7943
  signature: crc32,
7521
- crc32: encrypted && !zipCrypto && !passThrough ? UNDEFINED_VALUE : crc32,
7944
+ crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
7522
7945
  extraFieldExtendedTimestampFlag,
7946
+ extraFieldExtendedTimestampTime,
7523
7947
  zip64UncompressedSize,
7524
7948
  zip64CompressedSize
7525
7949
  });
@@ -7544,7 +7968,7 @@ function getHeaderInfo(options) {
7544
7968
  encryptionStrength,
7545
7969
  extendedTimestamp,
7546
7970
  ntfsTimestamp,
7547
- passThrough,
7971
+ passThroughCompression,
7548
7972
  encrypted,
7549
7973
  zip64UncompressedSize,
7550
7974
  zip64CompressedSize,
@@ -7555,7 +7979,7 @@ function getHeaderInfo(options) {
7555
7979
  let { version, compressionMethod } = options;
7556
7980
  const compressed = !directory && isCompressed(compressionMethod, level);
7557
7981
  let rawLocalExtraFieldZip64;
7558
- const uncompressedFile = passThrough || !compressed;
7982
+ const uncompressedFile = passThroughCompression || !compressed;
7559
7983
  const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
7560
7984
  const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
7561
7985
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
@@ -7567,8 +7991,8 @@ function getHeaderInfo(options) {
7567
7991
  if (zip64ExtraFieldComplete) {
7568
7992
  extraFieldZip64.writeUint64(uncompressedSize);
7569
7993
  if (uncompressedFile) {
7570
- const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7571
- extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7994
+ const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
7995
+ extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
7572
7996
  }
7573
7997
  }
7574
7998
  } else {
@@ -7587,6 +8011,7 @@ function getHeaderInfo(options) {
7587
8011
  let rawExtraFieldNTFS;
7588
8012
  let rawExtraFieldExtendedTimestamp;
7589
8013
  let extraFieldExtendedTimestampFlag;
8014
+ let extraFieldExtendedTimestampTime;
7590
8015
  if (extendedTimestamp) {
7591
8016
  const lastModTimeUnix = getTimeUnix(lastModDate);
7592
8017
  const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
@@ -7594,6 +8019,7 @@ function getHeaderInfo(options) {
7594
8019
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
7595
8020
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
7596
8021
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
8022
+ extraFieldExtendedTimestampTime = lastModTimeUnix;
7597
8023
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7598
8024
  extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
7599
8025
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
@@ -7636,7 +8062,7 @@ function getHeaderInfo(options) {
7636
8062
  let rawExtraFieldUnix;
7637
8063
  try {
7638
8064
  const { uid, gid, unixExtraFieldType } = options;
7639
- if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE$1 && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
8065
+ if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7640
8066
  const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
7641
8067
  const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
7642
8068
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
@@ -7677,7 +8103,7 @@ function getHeaderInfo(options) {
7677
8103
  }
7678
8104
  if (encrypted && !zipCrypto) {
7679
8105
  version = version > VERSION_AES ? version : VERSION_AES;
7680
- if (passThrough && crc32 !== UNDEFINED_VALUE) {
8106
+ if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
7681
8107
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7682
8108
  }
7683
8109
  setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
@@ -7739,12 +8165,14 @@ function getHeaderInfo(options) {
7739
8165
  headerArray,
7740
8166
  headerView,
7741
8167
  lastModDate: storedLastModDate,
8168
+ lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
7742
8169
  rawLastModDate,
7743
8170
  encrypted,
7744
8171
  compressed,
7745
8172
  version,
7746
8173
  compressionMethod,
7747
8174
  extraFieldExtendedTimestampFlag,
8175
+ extraFieldExtendedTimestampTime,
7748
8176
  rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
7749
8177
  localExtraFieldZip64Length,
7750
8178
  rawExtraFieldExtendedTimestamp,
@@ -7847,7 +8275,7 @@ function setEntryInfo({
7847
8275
  }, {
7848
8276
  zip64,
7849
8277
  zipCrypto,
7850
- passThrough,
8278
+ passThroughCompression,
7851
8279
  dataDescriptor
7852
8280
  }) {
7853
8281
  const {
@@ -7858,7 +8286,7 @@ function setEntryInfo({
7858
8286
  dataDescriptorView,
7859
8287
  dataDescriptorOffset
7860
8288
  } = dataDescriptorInfo;
7861
- if ((!encrypted || zipCrypto || passThrough) && crc32 !== UNDEFINED_VALUE) {
8289
+ if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
7862
8290
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
7863
8291
  if (dataDescriptor) {
7864
8292
  setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
@@ -7889,9 +8317,9 @@ function updateLocalHeader({
7889
8317
  uncompressedSize,
7890
8318
  zip64UncompressedSize,
7891
8319
  zip64CompressedSize
7892
- }, localHeaderView, { dataDescriptor, passThrough }) {
8320
+ }, localHeaderView, { dataDescriptor, passThroughCompression }) {
7893
8321
  if (!dataDescriptor) {
7894
- if (!encrypted || (passThrough && crc32 !== UNDEFINED_VALUE)) {
8322
+ if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
7895
8323
  setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
7896
8324
  }
7897
8325
  if (!zip64CompressedSize) {
@@ -7928,9 +8356,8 @@ function createDirectoryRecords(files) {
7928
8356
  rawExtraFieldUnix,
7929
8357
  rawExtraField,
7930
8358
  rawCentralExtraField,
7931
- extendedTimestamp,
7932
8359
  extraFieldExtendedTimestampFlag,
7933
- lastModDate,
8360
+ extraFieldExtendedTimestampTime,
7934
8361
  zip64Enabled,
7935
8362
  uncompressedSize,
7936
8363
  compressedSize
@@ -7973,16 +8400,15 @@ function createDirectoryRecords(files) {
7973
8400
  fileEntry.zip64Offset = zip64Offset;
7974
8401
  fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
7975
8402
  let rawExtraFieldTimestamp;
7976
- const lastModTimeUnix = getTimeUnix(lastModDate);
7977
- if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
8403
+ if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
8404
+ rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
8405
+ } else {
7978
8406
  const extraFieldTimestamp = createRecordWriter(9);
7979
8407
  extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7980
8408
  extraFieldTimestamp.writeUint16(5);
7981
8409
  extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7982
- extraFieldTimestamp.writeUint32(lastModTimeUnix);
8410
+ extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
7983
8411
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
7984
- } else {
7985
- rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
7986
8412
  }
7987
8413
  fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
7988
8414
  const extraFieldLength = getLength(
@@ -8482,6 +8908,11 @@ function getHeaderArrayData({
8482
8908
  };
8483
8909
  }
8484
8910
 
8911
+ function isPrintableASCIIText(rawText) {
8912
+ return rawText.every(characterCode =>
8913
+ characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
8914
+ }
8915
+
8485
8916
  function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
8486
8917
  let bitFlag = 0;
8487
8918
  if (useUnicodeFileNames) {
@@ -8643,7 +9074,7 @@ function formatSupported(StreamClass, format) {
8643
9074
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8644
9075
  */
8645
9076
 
8646
- const VERSION = "2.11.4";
9077
+ const VERSION = "2.13.0";
8647
9078
 
8648
9079
  /*
8649
9080
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9162,7 +9593,10 @@ setDefaultConfiguration({
9162
9593
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
9163
9594
  const ERR_DUPLICATE_IMPORTED_ENTRY = "Duplicate entry filename in the imported zip file";
9164
9595
  const ERR_INVALID_DUPLICATES = "Invalid duplicates option (must be \"throw\", \"keep-first\" or \"keep-last\")";
9165
- const ERR_ANCESTOR_ENTRY = "Entry is a ancestor of target entry";
9596
+ const ERR_ANCESTOR_ENTRY = "Entry is an ancestor of target entry";
9597
+ const ERR_ROOT_DIRECTORY_NOT_MOVABLE = "Root directory cannot be moved";
9598
+ const ERR_TARGET_NOT_DIRECTORY = "Target entry is not a directory";
9599
+ const ERR_PARENT_NOT_DIRECTORY = "Parent entry is not a directory";
9166
9600
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
9167
9601
  const DUPLICATES_THROW = "throw";
9168
9602
  const DUPLICATES_KEEP_FIRST = "keep-first";
@@ -9170,22 +9604,8 @@ const DUPLICATES_KEEP_LAST = "keep-last";
9170
9604
  const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
9171
9605
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
9172
9606
  const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
9173
- const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
9607
+ const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
9174
9608
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
9175
- const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
9176
- const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
9177
- EXTRAFIELD_TYPE_ZIP64,
9178
- EXTRAFIELD_TYPE_AES,
9179
- EXTRAFIELD_TYPE_NTFS,
9180
- EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
9181
- EXTRAFIELD_TYPE_UNICODE_PATH,
9182
- EXTRAFIELD_TYPE_UNICODE_COMMENT,
9183
- EXTRAFIELD_TYPE_USDZ,
9184
- EXTRAFIELD_TYPE_INFOZIP,
9185
- EXTRAFIELD_TYPE_UNIX,
9186
- EXTRAFIELD_TYPE_UNIX_TYPE1,
9187
- EXTRAFIELD_TYPE_PKWARE_UNIX
9188
- ]);
9189
9609
 
9190
9610
  class ZipEntry {
9191
9611
 
@@ -9317,7 +9737,7 @@ class ZipFileEntry extends ZipEntry {
9317
9737
  }));
9318
9738
  return true;
9319
9739
  } catch (error) {
9320
- if (error.message == ERR_INVALID_PASSWORD) {
9740
+ if (isErrorObject(error) && error.message == ERR_INVALID_PASSWORD) {
9321
9741
  return false;
9322
9742
  } else {
9323
9743
  throw error;
@@ -9557,6 +9977,7 @@ class ZipDirectoryEntry extends ZipEntry {
9557
9977
  await initStream(reader);
9558
9978
  zipReader = new ZipReader(reader, options);
9559
9979
  }
9980
+ checkPassThroughValue(options.passThrough);
9560
9981
  const duplicates = checkDuplicatesOption(options.duplicates);
9561
9982
  const importedEntries = [];
9562
9983
  const entries = await zipReader.getEntries(options);
@@ -9647,18 +10068,25 @@ class ZipDirectoryEntry extends ZipEntry {
9647
10068
 
9648
10069
  async exportZip(writer, options = {}) {
9649
10070
  const zipEntry = this;
10071
+ const zipWriterProvided = Boolean(writer) && typeof writer.add == FUNCTION_TYPE;
9650
10072
  options = Object.assign({}, options);
9651
- if (options.bufferedWrite === UNDEFINED_VALUE) {
10073
+ if (!zipWriterProvided && options.bufferedWrite === UNDEFINED_VALUE) {
9652
10074
  options.bufferedWrite = true;
9653
10075
  }
9654
- const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
9655
- const zipWriter = new ZipWriter(writer, options);
10076
+ const [readers] = await Promise.all([
10077
+ initReaders(zipEntry, checkReaderOptions(options.readerOptions)),
10078
+ zipWriterProvided ? UNDEFINED_VALUE : initStream(writer)
10079
+ ]);
10080
+ const zipWriter = zipWriterProvided ? writer : new ZipWriter(writer, options);
9656
10081
  await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
10082
+ if (zipWriterProvided) {
10083
+ return zipWriter;
10084
+ }
9657
10085
  await zipWriter.close(options.globalComment);
9658
10086
  return writer.getData ? writer.getData() : writer.writable;
9659
10087
  }
9660
10088
 
9661
- getExportedSize(options = {}) {
10089
+ async getExportedSize(options = {}) {
9662
10090
  const zipEntry = this;
9663
10091
  options = Object.assign({}, options);
9664
10092
  checkReaderOptions(options.readerOptions);
@@ -9673,7 +10101,7 @@ class ZipDirectoryEntry extends ZipEntry {
9673
10101
  const writeOrderGuaranteed = !options.bufferedWrite ||
9674
10102
  (entries.every(entry => entry.options.keepOrder !== false) &&
9675
10103
  children.every(child => isImplicitDirectory(child) || !child.children.length));
9676
- return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
10104
+ return await getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
9677
10105
  }
9678
10106
 
9679
10107
  getChildByName(name) {
@@ -9734,7 +10162,7 @@ class ZipFS {
9734
10162
 
9735
10163
  move(entry, destination) {
9736
10164
  if (entry == this.root) {
9737
- throw new Error("Root directory cannot be moved");
10165
+ throw new Error(ERR_ROOT_DIRECTORY_NOT_MOVABLE);
9738
10166
  } else {
9739
10167
  if (destination.directory) {
9740
10168
  if (!destination.isDescendantOf(entry)) {
@@ -9755,7 +10183,7 @@ class ZipFS {
9755
10183
  throw new Error(ERR_ANCESTOR_ENTRY);
9756
10184
  }
9757
10185
  } else {
9758
- throw new Error("Target entry is not a directory");
10186
+ throw new Error(ERR_TARGET_NOT_DIRECTORY);
9759
10187
  }
9760
10188
  }
9761
10189
  }
@@ -10068,70 +10496,11 @@ function getChildEntryOptions(child, selectedEntry, options) {
10068
10496
  let zipEntryMetadata = {};
10069
10497
  let passThroughOptions = {};
10070
10498
  if (child.data instanceof Entry) {
10071
- const {
10072
- externalFileAttributes,
10073
- versionMadeBy,
10074
- comment,
10075
- lastModDate,
10076
- rawLastModDate,
10077
- creationDate,
10078
- lastAccessDate,
10079
- uncompressedSize,
10080
- encrypted,
10081
- zipCrypto,
10082
- crc32,
10083
- compressionMethod,
10084
- extraFieldAES,
10085
- internalFileAttributes,
10086
- extraField,
10087
- bitFlag,
10088
- uid,
10089
- gid
10090
- } = child.data;
10091
- zipEntryMetadata = {
10092
- externalFileAttributes,
10093
- versionMadeBy,
10094
- comment,
10095
- lastModDate,
10096
- creationDate,
10097
- lastAccessDate,
10098
- internalFileAttributes
10099
- };
10100
- const userExtraField = getUserExtraField(extraField);
10101
- if (userExtraField) {
10102
- zipEntryMetadata.extraField = userExtraField;
10103
- }
10104
- if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
10105
- Object.assign(zipEntryMetadata, {
10106
- uid,
10107
- gid,
10108
- unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
10109
- });
10110
- }
10111
- if (isPassThrough(child, options)) {
10112
- let encryptionStrength;
10113
- if (extraFieldAES) {
10114
- encryptionStrength = extraFieldAES.strength;
10115
- }
10116
- passThroughOptions = {
10117
- passThrough: true,
10118
- encrypted,
10119
- zipCrypto,
10120
- crc32,
10121
- uncompressedSize,
10122
- encryptionStrength,
10123
- compressionMethod
10124
- };
10125
- if (bitFlag) {
10126
- passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
10127
- }
10128
- const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10129
- if (lastModDateOverride === UNDEFINED_VALUE) {
10130
- passThroughOptions.rawLastModDate = rawLastModDate;
10131
- } else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
10132
- getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
10133
- throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
10134
- }
10499
+ const passThrough = isPassThrough(child, options);
10500
+ const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
10501
+ ({ entryOptions: zipEntryMetadata, passThroughOptions } = getSourceEntryOptions(child.data, passThrough, lastModDateOverride));
10502
+ if (passThrough) {
10503
+ passThroughOptions.passThrough = true;
10135
10504
  }
10136
10505
  }
10137
10506
  const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
@@ -10141,16 +10510,6 @@ function getChildEntryOptions(child, selectedEntry, options) {
10141
10510
  return { name, entryOptions };
10142
10511
  }
10143
10512
 
10144
- function getDosTimeHighByte(lastModDate) {
10145
- let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
10146
- if (dosLastModDate < MIN_DATE) {
10147
- dosLastModDate = MIN_DATE;
10148
- } else if (dosLastModDate > MAX_DATE) {
10149
- dosLastModDate = MAX_DATE;
10150
- }
10151
- return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
10152
- }
10153
-
10154
10513
  function getDeterminedSize(child, passThrough) {
10155
10514
  const { reader } = child;
10156
10515
  if (reader && reader.size !== UNDEFINED_VALUE) {
@@ -10163,9 +10522,18 @@ function checkReaderOptions(readerOptions) {
10163
10522
  if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
10164
10523
  throw new Error(ERR_INVALID_READER_OPTIONS);
10165
10524
  }
10525
+ if (readerOptions) {
10526
+ checkPassThroughValue(readerOptions.passThrough);
10527
+ }
10166
10528
  return readerOptions;
10167
10529
  }
10168
10530
 
10531
+ function checkPassThroughValue(passThrough) {
10532
+ if (checkPassThroughOption(passThrough) === PASS_THROUGH_COMPRESSED) {
10533
+ throw new Error(ERR_UNSUPPORTED_PASS_THROUGH_VALUE);
10534
+ }
10535
+ }
10536
+
10169
10537
  function replaceContent(zipEntry, params) {
10170
10538
  const { uncompressedSize } = params;
10171
10539
  Object.assign(zipEntry, params, {
@@ -10194,20 +10562,6 @@ function isImplicitDirectory(child) {
10194
10562
  return child.directory && child.data === null;
10195
10563
  }
10196
10564
 
10197
- function getUserExtraField(extraField) {
10198
- if (extraField) {
10199
- const userExtraField = new Map();
10200
- extraField.forEach((field, type) => {
10201
- if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
10202
- userExtraField.set(type, field.data);
10203
- }
10204
- });
10205
- if (userExtraField.size) {
10206
- return userExtraField;
10207
- }
10208
- }
10209
- }
10210
-
10211
10565
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
10212
10566
  const { onstart, onprogress, onend, onentryprogress } = options;
10213
10567
  const selectedEntry = entry;
@@ -10310,6 +10664,7 @@ function addFileSystemHandle(zipEntry, handle, options) {
10310
10664
 
10311
10665
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10312
10666
  const { onstart, onprogress, onend } = options;
10667
+ checkPassThroughValue(options.passThrough);
10313
10668
  const readerOptions = checkReaderOptions(options.readerOptions);
10314
10669
  const abortController = new AbortController();
10315
10670
  const { signal } = abortController;
@@ -10385,7 +10740,7 @@ async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
10385
10740
  if (exportAborted || isExportAborted(signal.reason)) {
10386
10741
  return;
10387
10742
  }
10388
- throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
10743
+ throwIfAborted(signal);
10389
10744
  }
10390
10745
  try {
10391
10746
  if (child.directory) {
@@ -10518,7 +10873,7 @@ function addChild(parent, name, params, directory) {
10518
10873
  }
10519
10874
  return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
10520
10875
  } else {
10521
- throw new Error("Parent entry is not a directory");
10876
+ throw new Error(ERR_PARENT_NOT_DIRECTORY);
10522
10877
  }
10523
10878
  }
10524
10879
 
@@ -10652,7 +11007,7 @@ function decodeMimeTypes(data) {
10652
11007
  */
10653
11008
 
10654
11009
 
10655
- c(setDefaultConfiguration);
11010
+ i(setDefaultConfiguration);
10656
11011
 
10657
11012
  exports.BlobReader = BlobReader;
10658
11013
  exports.BlobWriter = BlobWriter;
@@ -10660,6 +11015,7 @@ exports.Data64URIReader = Data64URIReader;
10660
11015
  exports.Data64URIWriter = Data64URIWriter;
10661
11016
  exports.ERR_ABORTED = ERR_ABORTED;
10662
11017
  exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
11018
+ exports.ERR_ANCESTOR_ENTRY = ERR_ANCESTOR_ENTRY;
10663
11019
  exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
10664
11020
  exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
10665
11021
  exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
@@ -10673,7 +11029,9 @@ exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
10673
11029
  exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
10674
11030
  exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
10675
11031
  exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
11032
+ exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
10676
11033
  exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
11034
+ exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
10677
11035
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
10678
11036
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
10679
11037
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
@@ -10683,6 +11041,7 @@ exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
10683
11041
  exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
10684
11042
  exports.ERR_INVALID_DUPLICATES = ERR_INVALID_DUPLICATES;
10685
11043
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
11044
+ exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
10686
11045
  exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
10687
11046
  exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
10688
11047
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
@@ -10701,6 +11060,7 @@ exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
10701
11060
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
10702
11061
  exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
10703
11062
  exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
11063
+ exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
10704
11064
  exports.ERR_INVALID_READER = ERR_INVALID_READER;
10705
11065
  exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
10706
11066
  exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
@@ -10711,14 +11071,19 @@ exports.ERR_INVALID_UNCOMPRESSED_SIZE = ERR_INVALID_UNCOMPRESSED_SIZE;
10711
11071
  exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
10712
11072
  exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
10713
11073
  exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
11074
+ exports.ERR_INVALID_URI = ERR_INVALID_URI;
10714
11075
  exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
10715
11076
  exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
10716
11077
  exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
10717
11078
  exports.ERR_OVERLAPPING_ENTRY = ERR_OVERLAPPING_ENTRY;
11079
+ exports.ERR_PARENT_NOT_DIRECTORY = ERR_PARENT_NOT_DIRECTORY;
10718
11080
  exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
10719
11081
  exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
11082
+ exports.ERR_ROOT_DIRECTORY_NOT_MOVABLE = ERR_ROOT_DIRECTORY_NOT_MOVABLE;
10720
11083
  exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
11084
+ exports.ERR_TARGET_NOT_DIRECTORY = ERR_TARGET_NOT_DIRECTORY;
10721
11085
  exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
11086
+ exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
10722
11087
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
10723
11088
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
10724
11089
  exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
@@ -10730,10 +11095,12 @@ exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
10730
11095
  exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
10731
11096
  exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
10732
11097
  exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
11098
+ exports.ERR_UNSUPPORTED_PASS_THROUGH_VALUE = ERR_UNSUPPORTED_PASS_THROUGH_VALUE;
10733
11099
  exports.ERR_UNSUPPORTED_SPLIT_USDZ = ERR_UNSUPPORTED_SPLIT_USDZ;
10734
11100
  exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
10735
11101
  exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
10736
11102
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
11103
+ exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
10737
11104
  exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
10738
11105
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
10739
11106
  exports.HttpRangeReader = HttpRangeReader;
@@ -10747,13 +11114,17 @@ exports.Uint8ArrayReader = Uint8ArrayReader;
10747
11114
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
10748
11115
  exports.VERSION = VERSION;
10749
11116
  exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
11117
+ exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
10750
11118
  exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
11119
+ exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
10751
11120
  exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
10752
11121
  exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
10753
11122
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
10754
11123
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
10755
11124
  exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
11125
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME;
10756
11126
  exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
11127
+ exports.WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY;
10757
11128
  exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
10758
11129
  exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
10759
11130
  exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;