zip-peek 0.6.3-beta.2 → 0.6.4

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.
package/dist/index.js CHANGED
@@ -14,12 +14,6 @@ const URL_EXPIRY_LEAD_MS = 10000;
14
14
  const URL_EXPIRY_RETRY_MS = 5000;
15
15
  /** Avoid delayMs=0 tight loops while a renewal is already in flight. */
16
16
  const URL_EXPIRY_MIN_DELAY_MS = 1000;
17
- /** Warn if the service worker does not reply within this window. */
18
- const WORKER_MESSAGE_HANG_WARN_MS = 5000;
19
- const logPeek = (step, details) => {
20
- console.log(`[zip-peek] ${step}`, details ?? "");
21
- };
22
- const previewUrl = (url, max = 100) => !url ? url : url.length <= max ? url : `${url.slice(0, max)}…`;
23
17
  let currentOnError;
24
18
  let currentOnUrlExpiry;
25
19
  let clientMessageListenerInstalled = false;
@@ -114,6 +108,19 @@ async function ensureZipServiceWorkerRegistered({ workerUrl, scopeUrl, reloadOnF
114
108
  }
115
109
  return false;
116
110
  }
111
+ /** Probe cookie / localStorage so registration failures can explain blocked storage. */
112
+ function describeClientStorageAccess() {
113
+ const cookieEnabled = typeof navigator !== "undefined" ? navigator.cookieEnabled : false;
114
+ let localStorageAccess = "ok";
115
+ try {
116
+ localStorage.setItem("t", "1");
117
+ localStorage.removeItem("t");
118
+ }
119
+ catch (error) {
120
+ localStorageAccess = error instanceof Error ? error.message : String(error);
121
+ }
122
+ return `cookieEnabled=${cookieEnabled}; localStorage=${localStorageAccess}`;
123
+ }
117
124
  function attachZipPeekInfo(error, info) {
118
125
  const err = (0, types_1.toZipPeekError)(error);
119
126
  if (info) {
@@ -143,32 +150,16 @@ function scheduleUrlExpiry(normalizedZipUrl, originalUrlForExpiry) {
143
150
  clearUrlExpiryTimer(normalizedZipUrl);
144
151
  trackedZipUrls.set(normalizedZipUrl, originalUrlForExpiry);
145
152
  if (!currentOnUrlExpiry) {
146
- logPeek("scheduleUrlExpiry skipped: no onUrlExpiry handler", {
147
- url: previewUrl(normalizedZipUrl),
148
- });
149
153
  return;
150
154
  }
151
155
  const expiryMs = (0, zip_utils_1.getPresignedUrlExpiryMs)(originalUrlForExpiry);
152
156
  if (expiryMs == null) {
153
- logPeek("scheduleUrlExpiry DROPPED: could not parse expiry (no timer armed)", {
154
- url: previewUrl(originalUrlForExpiry),
155
- trackedCount: trackedZipUrls.size,
156
- });
157
157
  trackedZipUrls.delete(normalizedZipUrl);
158
158
  return;
159
159
  }
160
160
  const delayMs = Math.max(URL_EXPIRY_MIN_DELAY_MS, expiryMs - Date.now() - URL_EXPIRY_LEAD_MS);
161
- logPeek("scheduleUrlExpiry armed", {
162
- url: previewUrl(normalizedZipUrl),
163
- expiryMs,
164
- delayMs,
165
- delaySec: Math.round(delayMs / 1000),
166
- msUntilExpiry: expiryMs - Date.now(),
167
- trackedCount: trackedZipUrls.size,
168
- });
169
161
  const timerId = setTimeout(() => {
170
162
  urlExpiryTimers.delete(normalizedZipUrl);
171
- logPeek("expiry timer fired", { url: previewUrl(normalizedZipUrl) });
172
163
  void invokeUrlExpiry(normalizedZipUrl);
173
164
  }, delayMs);
174
165
  urlExpiryTimers.set(normalizedZipUrl, timerId);
@@ -187,19 +178,20 @@ function checkExpiryOnWake() {
187
178
  if (!currentOnUrlExpiry) {
188
179
  return;
189
180
  }
190
- logPeek("checkExpiryOnWake", {
191
- trackedCount: trackedZipUrls.size,
192
- visibilityState: typeof document !== "undefined" ? document.visibilityState : "n/a",
193
- });
194
181
  for (const [normalized, original] of trackedZipUrls) {
195
182
  if (isZipUrlDueForRenewal(original)) {
196
- logPeek("checkExpiryOnWake: URL due, invoking expiry", { url: previewUrl(normalized) });
197
183
  void invokeUrlExpiry(normalized);
198
184
  return;
199
185
  }
200
186
  scheduleUrlExpiry(normalized, original);
201
187
  }
202
188
  }
189
+ /**
190
+ * When the tab get focused, check if the URL is due for renewal.
191
+ * If it is, invoke the onUrlExpiry handler.
192
+ * If it is not, schedule a timer to check again in 1 second.
193
+ * @returns {void}
194
+ */
203
195
  function ensureExpiryWakeListeners() {
204
196
  if (expiryWakeListenersInstalled || typeof document === "undefined") {
205
197
  return;
@@ -215,52 +207,27 @@ function ensureExpiryWakeListeners() {
215
207
  */
216
208
  function rearmExpiryIfStillTracked(normalizedZipUrl) {
217
209
  const original = trackedZipUrls.get(normalizedZipUrl);
218
- if (!original) {
219
- logPeek("rearm skipped: URL no longer tracked (renew likely succeeded)", {
220
- url: previewUrl(normalizedZipUrl),
221
- trackedCount: trackedZipUrls.size,
222
- trackedUrls: Array.from(trackedZipUrls.keys()).map((u) => previewUrl(u)),
223
- });
224
- return;
225
- }
226
- if (urlExpiryTimers.has(normalizedZipUrl)) {
227
- logPeek("rearm skipped: timer already armed", { url: previewUrl(normalizedZipUrl) });
210
+ if (!original || urlExpiryTimers.has(normalizedZipUrl)) {
228
211
  return;
229
212
  }
230
- logPeek("rearm: scheduling retry", {
231
- url: previewUrl(normalizedZipUrl),
232
- retryMs: URL_EXPIRY_RETRY_MS,
233
- });
234
213
  const timerId = setTimeout(() => {
235
214
  urlExpiryTimers.delete(normalizedZipUrl);
236
- logPeek("rearm retry timer fired", { url: previewUrl(normalizedZipUrl) });
237
215
  void invokeUrlExpiry(normalizedZipUrl);
238
216
  }, URL_EXPIRY_RETRY_MS);
239
217
  urlExpiryTimers.set(normalizedZipUrl, timerId);
240
218
  }
241
219
  async function invokeUrlExpiry(normalizedZipUrl) {
242
- if (!currentOnUrlExpiry) {
243
- logPeek("invokeUrlExpiry skipped: no handler");
244
- return;
245
- }
246
- if (urlExpiryInFlight.has(normalizedZipUrl)) {
247
- logPeek("invokeUrlExpiry skipped: already in flight", {
248
- url: previewUrl(normalizedZipUrl),
249
- inFlight: Array.from(urlExpiryInFlight).map((u) => previewUrl(u)),
250
- });
220
+ if (!currentOnUrlExpiry || urlExpiryInFlight.has(normalizedZipUrl)) {
251
221
  return;
252
222
  }
253
223
  urlExpiryInFlight.add(normalizedZipUrl);
254
- logPeek("invokeUrlExpiry calling onUrlExpiry handler", {
255
- url: previewUrl(normalizedZipUrl),
256
- original: previewUrl(trackedZipUrls.get(normalizedZipUrl)),
257
- });
258
224
  try {
259
- await currentOnUrlExpiry();
260
- logPeek("invokeUrlExpiry handler finished", { url: previewUrl(normalizedZipUrl) });
225
+ await currentOnUrlExpiry({
226
+ expiredZipURL: trackedZipUrls.get(normalizedZipUrl) ?? "",
227
+ normalizedExpiredZipURL: normalizedZipUrl,
228
+ });
261
229
  }
262
230
  catch (error) {
263
- console.error("[zip-peek] invokeUrlExpiry handler error", error);
264
231
  reportZipPeekError(currentOnError, error, "onUrlExpiry handler failed");
265
232
  }
266
233
  finally {
@@ -322,35 +289,14 @@ function normalizeAllowedZipUrls(allowedZipUrls) {
322
289
  }
323
290
  function postWorkerMessage(message) {
324
291
  const controller = navigator.serviceWorker.controller;
325
- const messageType = message && typeof message === "object" && "type" in message
326
- ? String(message.type)
327
- : "unknown";
328
292
  if (!controller) {
329
- logPeek("postWorkerMessage rejected: no SW controller", { messageType });
330
293
  return Promise.reject((0, types_1.createZipPeekError)("No active service worker controller. Reload the page after first install, or pass reloadOnFirstInstall: true."));
331
294
  }
332
- logPeek("postWorkerMessage sending", {
333
- messageType,
334
- controllerScript: controller.scriptURL,
335
- });
336
295
  return new Promise((resolve, reject) => {
337
296
  const channel = new MessageChannel();
338
- const hangTimer = setTimeout(() => {
339
- console.warn("[zip-peek] postWorkerMessage still waiting for SW reply", {
340
- messageType,
341
- waitedMs: WORKER_MESSAGE_HANG_WARN_MS,
342
- controllerScript: controller.scriptURL,
343
- });
344
- }, WORKER_MESSAGE_HANG_WARN_MS);
345
297
  channel.port1.onmessage = (event) => {
346
- clearTimeout(hangTimer);
347
298
  const response = event.data;
348
299
  channel.port1.close();
349
- logPeek("postWorkerMessage reply received", {
350
- messageType,
351
- ok: response?.ok,
352
- error: response?.error,
353
- });
354
300
  if (!response || response.ok) {
355
301
  resolve();
356
302
  }
@@ -359,9 +305,7 @@ function postWorkerMessage(message) {
359
305
  }
360
306
  };
361
307
  channel.port1.onmessageerror = () => {
362
- clearTimeout(hangTimer);
363
308
  channel.port1.close();
364
- console.error("[zip-peek] postWorkerMessage onmessageerror", { messageType });
365
309
  reject((0, types_1.createZipPeekError)("Failed to deserialize the service worker response on MessageChannel."));
366
310
  };
367
311
  controller.postMessage(message, [channel.port2]);
@@ -415,7 +359,7 @@ async function initZipPeek({ workerUrl, scopeUrl, reloadOnFirstInstall = true, c
415
359
  });
416
360
  }
417
361
  catch (error) {
418
- throw attachZipPeekInfo(error, "Service worker registration failed");
362
+ throw attachZipPeekInfo(error, `Service worker registration failed (${describeClientStorageAccess()})`);
419
363
  }
420
364
  if (reloaded) {
421
365
  return { reloaded: true, initialized: false };
@@ -480,11 +424,6 @@ async function initZipPeek({ workerUrl, scopeUrl, reloadOnFirstInstall = true, c
480
424
  * continue serving assets with the new credentials.
481
425
  */
482
426
  async function renewPresignedUrl({ previousUrl, nextUrl }) {
483
- logPeek("renewPresignedUrl start", {
484
- previousUrl: previewUrl(previousUrl),
485
- nextUrl: previewUrl(nextUrl),
486
- trackedBefore: Array.from(trackedZipUrls.keys()).map((u) => previewUrl(u)),
487
- });
488
427
  if (!("serviceWorker" in navigator)) {
489
428
  throw (0, types_1.createZipPeekError)("Service Worker API not supported in this browser.");
490
429
  }
@@ -501,19 +440,11 @@ async function renewPresignedUrl({ previousUrl, nextUrl }) {
501
440
  }
502
441
  const previous = (0, zip_utils_1.normalizeZipUrl)(resolvedPrevious);
503
442
  const next = (0, zip_utils_1.normalizeZipUrl)(resolvedNext);
504
- logPeek("renewPresignedUrl normalized", {
505
- previous: previewUrl(previous),
506
- next: previewUrl(next),
507
- sameUrl: previous === next,
508
- nextExpiryMs: (0, zip_utils_1.getPresignedUrlExpiryMs)(resolvedNext),
509
- });
510
- logPeek("renewPresignedUrl awaiting SW RENEW_ZIP_URL...");
511
443
  await postWorkerMessageOrThrow({
512
444
  type: "RENEW_ZIP_URL",
513
445
  previousUrl: previous,
514
446
  nextUrl: next,
515
447
  }, "Failed to renew ZIP URL in service worker");
516
- logPeek("renewPresignedUrl SW RENEW_ZIP_URL done");
517
448
  const files = sessionManifests.get(previous);
518
449
  if (files) {
519
450
  sessionManifests.set(next, files);
@@ -522,18 +453,11 @@ async function renewPresignedUrl({ previousUrl, nextUrl }) {
522
453
  // Drop the previous URL and any orphaned tracked URLs for the same zip path
523
454
  // (e.g. when a prior renew used a mismatched previousUrl and left a timer-less entry).
524
455
  const nextPath = zipPackagePathname(next);
525
- const removed = [];
526
456
  for (const [normalized] of [...trackedZipUrls]) {
527
457
  if (normalized === previous || zipPackagePathname(normalized) === nextPath) {
528
458
  trackedZipUrls.delete(normalized);
529
459
  clearUrlExpiryTimer(normalized);
530
- removed.push(previewUrl(normalized) ?? normalized);
531
460
  }
532
461
  }
533
- logPeek("renewPresignedUrl cleared tracked URLs", { removed, nextPath });
534
462
  scheduleUrlExpiry(next, resolvedNext);
535
- logPeek("renewPresignedUrl complete", {
536
- trackedAfter: Array.from(trackedZipUrls.keys()).map((u) => previewUrl(u)),
537
- timersArmed: urlExpiryTimers.size,
538
- });
539
463
  }
package/dist/types.d.ts CHANGED
@@ -3,12 +3,15 @@ export type ZipWorkerConfig = {
3
3
  assetCacheTtlMs?: number;
4
4
  logPrefix?: string;
5
5
  };
6
- export type ZipCacheClearingStrategy = 'keep-all' | 'keep-allowed-urls' | 'clear-all';
6
+ export type ZipCacheClearingStrategy = "keep-all" | "keep-allowed-urls" | "clear-all";
7
7
  export type ZipPeekErrorHandler = (error: Error, info?: string) => void;
8
8
  /**
9
9
  * Invoked shortly before a tracked presigned ZIP URL expires.
10
10
  */
11
- export type ZipPeekUrlExpiryHandler = () => void | Promise<void>;
11
+ export type ZipPeekUrlExpiryHandler = ({ expiredZipURL, normalizedExpiredZipURL, }: {
12
+ expiredZipURL: string;
13
+ normalizedExpiredZipURL: string;
14
+ }) => void | Promise<void>;
12
15
  export type RenewPresignedUrlOptions = {
13
16
  previousUrl: string;
14
17
  nextUrl: string;
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";var e={553(e,t){function n(e){const n=e.trim();return n.startsWith(t.ZIP_PEEK_ERROR_PREFIX)?n:`${t.ZIP_PEEK_ERROR_PREFIX} ${n}`}t.ZIP_PEEK_ERROR_PREFIX=void 0,t.formatZipPeekError=n,t.createZipPeekError=function(e){return new Error(n(e))},t.toZipPeekError=function(e){const r=e instanceof Error?e:new Error(String(e));return r.message.startsWith(t.ZIP_PEEK_ERROR_PREFIX)||(r.message=n(r.message)),r},t.errorMessage=function(e){return e instanceof Error?e.message:String(e)},t.ZIP_PEEK_ERROR_PREFIX="[zip-peek-error]"},314(e,t,n){t.persistAllowedZipUrlsConfig=o,t.ensureAllowedZipUrlsLoaded=async function(){if(s.allowedZipUrlsLoaded)return s.allowedZipUrlsLoaded;const e=(async()=>{try{const e=await caches.open(s.CONFIG_CACHE_NAME),t=await e.match(s.CONFIG_CACHE_KEY);if(!t)return;const n=await t.json();Array.isArray(n.allowedZipUrls)?(0,s.setAllowedZipUrls)(new Set(n.allowedZipUrls.filter(e=>"string"==typeof e).map(e=>(0,r.normalizeZipUrl)(e)))):(0,s.setAllowedZipUrls)(null)}catch(e){(0,i.warn)("failed to load runtime config",e)}})();return(0,s.setAllowedZipUrlsLoaded)(e),e},t.applyRuntimeConfig=async function(e){if(!e)return;let t={...s.runtimeConfig},n=!1;if("string"==typeof e.zipAssetCacheName&&e.zipAssetCacheName.trim()&&(t.zipAssetCacheName=e.zipAssetCacheName,n=!0),"number"==typeof e.assetCacheTtlMs&&Number.isFinite(e.assetCacheTtlMs)&&(t.assetCacheTtlMs=e.assetCacheTtlMs,n=!0),"string"==typeof e.logPrefix&&e.logPrefix.trim()&&(t.logPrefix=e.logPrefix,n=!0),"boolean"==typeof e.requireExactManifestPath&&(t.requireExactManifestPath=e.requireExactManifestPath,n=!0),n&&(0,s.setRuntimeConfig)(t),"allowedZipUrls"in e){const t=Array.isArray(e.allowedZipUrls)?e.allowedZipUrls.map(e=>(0,r.normalizeZipUrl)(e)):null;(0,s.setAllowedZipUrls)(t?new Set(t):null),(0,s.setAllowedZipUrlsLoaded)(Promise.resolve()),await o(t)}},t.isZipUrlAllowed=function(e){return null===s.allowedZipUrls||s.allowedZipUrls.has(e)};const r=n(343),s=n(262),i=n(266);async function o(e){try{const t=await caches.open(s.CONFIG_CACHE_NAME);await t.put(new Request(s.CONFIG_CACHE_KEY),new Response(JSON.stringify({allowedZipUrls:e}),{headers:{"Content-Type":"application/json"}}))}catch(e){(0,i.warn)("failed to persist runtime config",e)}}},800(e,t,n){t.canonicalAssetRequest=function(e,t){return new Request((0,s.canonicalZipAssetRequestUrl)(e,t),{method:"GET"})},t.clearAllZipAssets=async function(){const e=await caches.open(o.runtimeConfig.zipAssetCacheName),t=await e.keys();await Promise.all(t.map(t=>e.delete(t))),await caches.delete(o.CONFIG_CACHE_NAME),o.zipManifests.clear(),o.pendingManifestLoads.clear(),(0,o.setAllowedZipUrlsLoaded)(Promise.resolve())},t.clearZipAssetsExceptAllowed=async function(e){try{const t=new Set(e),n=await caches.open(o.runtimeConfig.zipAssetCacheName),r=await n.keys();for(const e of r){const r=e.url;if(r.includes(o.MANIFEST_CACHE_KEY)){const s=(0,l.zipUrlFromManifestCacheKey)(r);s&&!t.has(s)&&await n.delete(e);continue}const i=(0,s.parseZipAssetRequest)(r);i&&!t.has(i.zipUrl)&&await n.delete(e)}for(const e of o.zipManifests.keys())t.has(e)||o.zipManifests.delete(e)}catch(e){throw(0,r.createZipPeekError)(`Failed to clear zip assets except allowed URLs: ${(0,r.errorMessage)(e)}`)}},t.putCachedFullAssetIfAbsent=async function(e,t){try{const n=await caches.open(o.runtimeConfig.zipAssetCacheName),r=await n.match(e);if(r&&!c(r))return;const s=t.type||"application/octet-stream";await n.put(e,new Response(t,{status:200,headers:{"Content-Type":s,"Content-Length":String(t.size),"Access-Control-Allow-Origin":"*",[o.ASSET_CACHED_AT_HEADER]:String(Date.now())}}))}catch(e){(0,a.warn)("asset cache put failed",e)}},t.readCachedZipAssetIfFresh=async function(e){let t=null,n="network";try{const r=await caches.open(o.runtimeConfig.zipAssetCacheName),s=await r.match(e);if(s)if(c(s))try{await r.delete(e)}catch(e){(0,a.warn)("asset cache delete expired failed",e)}else t=await s.blob(),n="cache-api"}catch(e){(0,a.warn)("asset cache read failed",e)}return{blob:t,assetSource:n}},t.renewZipUrl=async function(e,t){const n=(0,s.normalizeZipUrl)(e),a=(0,s.normalizeZipUrl)(t);if(console.log("[zip-peek-sw] renewZipUrl start",{previous:n.slice(0,100),next:a.slice(0,100),sameUrl:n===a,allowListSize:o.allowedZipUrls?.size??null}),n===a)return void console.log("[zip-peek-sw] renewZipUrl no-op: previous === next");if(o.allowedZipUrls){const e=new Set(o.allowedZipUrls),t=e.has(n);e.delete(n),e.add(a),(0,o.setAllowedZipUrls)(e),(0,o.setAllowedZipUrlsLoaded)(Promise.resolve()),console.log("[zip-peek-sw] renewZipUrl allow-list updated",{hadPrevious:t,allowListSize:e.size}),await(0,i.persistAllowedZipUrlsConfig)(Array.from(e))}const c=o.zipManifests.get(n);c&&(o.zipManifests.set(a,c),o.zipManifests.delete(n),console.log("[zip-peek-sw] renewZipUrl remapped in-memory manifest"));const f=o.pendingManifestLoads.get(n);f&&(o.pendingManifestLoads.set(a,f),o.pendingManifestLoads.delete(n));try{const e=await caches.open(o.runtimeConfig.zipAssetCacheName),t=await e.keys();console.log("[zip-peek-sw] renewZipUrl clearing cache entries",{keyCount:t.length});let r=0;for(const i of t){const t=i.url;if(t.includes(o.MANIFEST_CACHE_KEY)){(0,l.zipUrlFromManifestCacheKey)(t)===n&&(await e.delete(i),r+=1);continue}const a=(0,s.parseZipAssetRequest)(t);a&&(0,s.normalizeZipUrl)(a.zipUrl)===n&&(await e.delete(i),r+=1)}console.log("[zip-peek-sw] renewZipUrl cache clear done",{deleted:r})}catch(e){throw console.error("[zip-peek-sw] renewZipUrl cache clear failed",e),(0,r.createZipPeekError)(`Failed to clear cached assets for renewed ZIP URL: ${(0,r.errorMessage)(e)}`)}console.log("[zip-peek-sw] renewZipUrl complete")};const r=n(553),s=n(343),i=n(314),o=n(262),a=n(266),l=n(346);function c(e){const t=e.headers.get(o.ASSET_CACHED_AT_HEADER);if(!t)return!0;const n=parseInt(t,10);return!Number.isFinite(n)||Date.now()-n>o.runtimeConfig.assetCacheTtlMs}},982(e,t,n){t.installFetchHandler=function(){self.addEventListener("fetch",e=>{const t=e.request.method;if("GET"!==t&&"HEAD"!==t)return;const n="HEAD"===t,d=(0,s.parseZipAssetRequest)(e.request.url);if(!d)return;const g=(0,s.normalizeZipUrl)(d.zipUrl),m=d.internalPath,w=(0,s.normalizeZipEntryPath)(m);e.respondWith((async()=>{try{if(await(0,i.ensureAllowedZipUrlsLoaded)(),!(0,i.isZipUrlAllowed)(g))return(0,l.warn)("zip URL not allowed",{requestedZipUrl:g}),(0,f.corsErrorResponse)(`ZIP URL not allowed (not in allowedZipUrls): ${g}`,403);let t=a.zipManifests.get(g);if(t||(t=await(0,c.ensureManifestAvailable)(g,e.clientId||void 0)??void 0),!t){const e=Array.from(a.zipManifests.keys());return(0,l.warn)("manifest missing for zipUrl",{requestedZipUrl:g,knownZipUrls:e}),(0,f.corsErrorResponse)(`ZIP manifest not loaded for ${g}. Ensure the ZIP is reachable and supports byte-range requests.`,404)}const s=(0,c.resolveManifestEntry)(t,w,g,a.runtimeConfig.requireExactManifestPath);if(!s){const e=Array.from(t.keys()).slice(0,50);return(0,l.warn)("file not in manifest",{zipUrl:g,internalPathRaw:m,internalPathNormalized:w,requireExactManifestPath:a.runtimeConfig.requireExactManifestPath,manifestSize:t.size,sampleKeys:e}),(0,f.corsErrorResponse)(`File "${m}" not found in ZIP manifest for ${g}`,404)}const{key:d,info:h,matchKind:E}=s;"zipBasenameFallback"===E&&((0,l.log)("resolved via zip-basename folder fallback",{requested:w,manifestKey:d}),(0,l.reportClientError)(new Error((0,r.formatZipPeekError)("Exact manifest path not found; resolved via zip-basename folder fallback")),`Exact manifest key "${w}" not found in ${g}; resolved using "${d}"`));const y=(0,o.canonicalAssetRequest)(g,d);if(n)return function(e,t,n){const r=(0,f.getMimeType)(t),s=(0,c.entryUncompressedSize)(n),i=e.headers.get("range");if(null!==s&&i)return u(null,r,s,"manifest",i);const o={"Content-Type":r,...p("manifest")};return null!==s&&(o["Content-Length"]=s.toString()),new Response(null,{status:200,headers:o})}(e.request,d,h);let{blob:A,assetSource:U}=await(0,o.readCachedZipAssetIfFresh)(y);if(!A){const e=await(0,f.fetchUncompressedZipEntryFromNetwork)(g,d,h,y);if(!e.ok)return e.response;A=e.blob,U="network"}return u(A,A.type,A.size,U,e.request.headers.get("range"))}catch(e){return(0,l.error)("fetch handler failed",{zipUrl:g,internalPath:m,message:(0,r.errorMessage)(e)}),(0,f.corsErrorResponse)(`Failed to serve "${m}" from ${g}: ${(0,r.errorMessage)(e)}`,500)}})())})};const r=n(553),s=n(343),i=n(314),o=n(800),a=n(262),l=n(266),c=n(346),f=n(254);function p(e){return{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":a.ASSET_SOURCE_HEADER,[a.ASSET_SOURCE_HEADER]:e}}function u(e,t,n,r,s){if(s){const i=s.replace(/^bytes=/,"");if(i.includes(","))return new Response(null,{status:416,headers:{"Content-Range":`bytes */${n}`,...p(r)}});const[o,a]=i.split("-"),l=""!==o?parseInt(o,10):NaN,c=""!==a?parseInt(a,10):n-1;if(isNaN(l)||isNaN(c)||l<0||c<l||l>=n)return new Response(null,{status:416,headers:{"Content-Range":`bytes */${n}`,...p(r)}});const f=Math.min(c,n-1),u=f-l+1,d=null===e?null:e.slice(l,f+1);return new Response(d,{status:206,headers:{"Content-Type":t,"Content-Range":`bytes ${l}-${f}/${n}`,"Content-Length":u.toString(),"Accept-Ranges":"bytes",...p(r)}})}return new Response(e,{status:200,headers:{"Content-Type":t,"Content-Length":n.toString(),...p(r)}})}},262(e,t){t.CONFIG_CACHE_KEY=t.allowedZipUrlsLoaded=t.allowedZipUrls=t.runtimeConfig=t.pendingManifestLoads=t.zipManifests=t.MANIFEST_CACHE_KEY=t.LOCAL_FILE_HEADER_SIG=t.MIME_TYPES=t.ASSET_SOURCE_HEADER=t.ASSET_CACHED_AT_HEADER=t.CONFIG_CACHE_NAME=t.kF=t.o2=void 0,t.setRuntimeConfig=function(e){t.runtimeConfig=e},t.setAllowedZipUrls=function(e){t.allowedZipUrls=e},t.setAllowedZipUrlsLoaded=function(e){t.allowedZipUrlsLoaded=e},t.o2="zip-cache-v1",t.kF=72e5,t.CONFIG_CACHE_NAME="zip-peek-config-v1",t.o2,t.CONFIG_CACHE_NAME,t.ASSET_CACHED_AT_HEADER="X-ZipSW-Cached-At",t.ASSET_SOURCE_HEADER="X-ZipSW-Asset-Source",t.MIME_TYPES={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",json:"application/json",js:"application/javascript",css:"text/css; charset=utf-8",html:"text/html; charset=utf-8",txt:"text/plain; charset=utf-8",mp4:"video/mp4",webm:"video/webm",mp3:"audio/mpeg",wav:"audio/wav",oga:"audio/ogg",ogg:"audio/ogg",xml:"application/xml",wasm:"application/wasm"},t.LOCAL_FILE_HEADER_SIG=67324752,t.MANIFEST_CACHE_KEY="__zipsw_manifest__=1",t.zipManifests=new Map,t.pendingManifestLoads=new Map,t.runtimeConfig={zipAssetCacheName:t.o2,assetCacheTtlMs:t.kF,logPrefix:"[zipSW]",requireExactManifestPath:!1},t.allowedZipUrls=null,t.allowedZipUrlsLoaded=null,t.CONFIG_CACHE_KEY=new URL("__zip_peek_runtime_config__",self.registration.scope).href},266(e,t,n){t.log=function(...e){console.log(s.runtimeConfig.logPrefix,...e)},t.warn=function(...e){console.warn(s.runtimeConfig.logPrefix,...e)},t.error=function(...e){console.error(s.runtimeConfig.logPrefix,r.ZIP_PEEK_ERROR_PREFIX,...e)},t.reportClientError=i,t.installClientErrorReporting=function(){self.addEventListener("error",e=>{i(e.error??e.message,"Service worker uncaught error")}),self.addEventListener("unhandledrejection",e=>{i(e.reason,"Service worker unhandled promise rejection")})};const r=n(553),s=n(262);function i(e,t){const n=(0,r.toZipPeekError)(e);self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(e=>{const s={type:"ZIP_SW_ERROR",error:{message:n.message,stack:n.stack},info:t?(0,r.formatZipPeekError)(t):void 0};for(const t of e)t.postMessage(s)})}},346(e,t,n){t.manifestFilesToMap=o,t.sendManifestToClientId=l,t.ensureManifestAvailable=function(e,t){const n=s.zipManifests.get(e);if(n)return Promise.resolve(n);let c=s.pendingManifestLoads.get(e);return c||(c=(async()=>{const n=await async function(e,t){const n=await a(t);return n?function(e,t){return new Promise(n=>{const r=new MessageChannel,s=setTimeout(()=>{r.port1.close(),n(null)},500);r.port1.onmessage=e=>{clearTimeout(s),r.port1.close();const t=e.data;t?.ok&&Array.isArray(t.files)?n(o(t.files)):n(null)},r.port1.onmessageerror=()=>{clearTimeout(s),r.port1.close(),n(null)};try{e.postMessage({type:"ZIP_SW_MANIFEST_REQUEST",zipUrl:t},[r.port2])}catch(e){clearTimeout(s),r.port1.close(),(0,i.warn)("failed to request manifest from client",e),n(null)}})}(n,e):null}(e,t);if(n)return s.zipManifests.set(e,n),(0,i.log)("restored manifest from client memory",{zipUrl:e,entryCount:n.size}),n;const c=await async function(e){const t=await fetch(e,{headers:{Range:"bytes=-65536"}});if(206!==t.status)return(0,i.error)("range requests not supported for ZIP manifest",{zipUrl:e,status:t.status}),null;const n=await t.arrayBuffer(),s=new DataView(n);let o=-1;for(let e=n.byteLength-22;e>=0;e--)if(101010256===s.getUint32(e,!0)){o=e;break}if(-1===o)return(0,i.error)("EOCD not found in last 64KB of ZIP file",e),null;const a=s.getUint32(o+16,!0),l=s.getUint32(o+12,!0);let c=n,f=-1;const p=t.headers.get("Content-Range");let u=0;if(p){const e=p.match(/\/(\d+)$/);e&&(u=parseInt(e[1],10))}if(u<=0)return(0,i.error)("could not determine ZIP file size from Content-Range header",{zipUrl:e,contentRange:p}),null;const d=u-n.byteLength;if(a>=d)f=a-d;else{const t=await fetch(e,{headers:{Range:`bytes=${a}-${a+l-1}`}});if(206!==t.status)return(0,i.error)("failed to fetch ZIP central directory",{zipUrl:e,status:t.status,cdOffset:a,cdSize:l}),null;c=await t.arrayBuffer(),f=0}return function(e,t,n,s){const o=new DataView(e);let a=t;const l=[];for(;a+46<=e.byteLength&&33639248===o.getUint32(a,!0);){const t=o.getUint16(a+10,!0),n=o.getUint32(a+20,!0),s=o.getUint32(a+24,!0),i=o.getUint16(a+28,!0),c=o.getUint16(a+30,!0),f=o.getUint16(a+32,!0),p=o.getUint32(a+42,!0),u=new TextDecoder;if(a+46+i>e.byteLength)break;const d=new Uint8Array(e,a+46,i),g=u.decode(d),m=(0,r.normalizeZipEntryPath)(g);""!==m&&l.push({filename:m,offset:p,compressedSize:n,uncompressedSize:s,compression:t}),a+=46+i+c+f}if(0===l.length)return(0,i.error)("no files parsed from central directory",s),null;l.sort((e,t)=>e.offset-t.offset);const c=new Map;for(let e=0;e<l.length;e++){const t=l[e],s=(0,r.normalizeZipEntryPath)(t.filename);""!==s&&(c.has(s)&&(0,i.warn)("duplicate manifest key after normalize; overwriting",s),c.set(s,{filename:t.filename,offset:t.offset,compressedSize:t.compressedSize,uncompressedSize:t.uncompressedSize,compression:t.compression,nextOffset:e<l.length-1?l[e+1].offset:n}))}return c.size>0?c:null}(c,f,a,e)}(e);return c&&(s.zipManifests.set(e,c),await l(e,c,t),(0,i.log)("manifest fetched and stored in memory",{zipUrl:e,entryCount:c.size})),c})().finally(()=>{s.pendingManifestLoads.delete(e)}),s.pendingManifestLoads.set(e,c),c)},t.entryUncompressedSize=function(e){return void 0!==e.uncompressedSize?e.uncompressedSize:0===e.compression?e.compressedSize:null},t.resolveManifestEntry=function(e,t,n,s){if(e.has(t))return{key:t,info:e.get(t),matchKind:"exact"};if(s)return null;const i=(0,r.zipBasenameWithoutExtension)(n);if(!i)return null;const o=`${i}/${t}`;return e.has(o)?{key:o,info:e.get(o),matchKind:"zipBasenameFallback"}:null},t.zipUrlFromManifestCacheKey=function(e){const t=s.MANIFEST_CACHE_KEY;if(!e.endsWith(t))return null;let n=e.slice(0,-t.length);return(n.endsWith("?")||n.endsWith("&"))&&(n=n.slice(0,-1)),n};const r=n(343),s=n(262),i=n(266);function o(e){const t=new Map;for(const n of e){const e=(0,r.normalizeZipEntryPath)(n.filename);""!==e&&(t.has(e)&&(0,i.warn)("duplicate manifest key after normalize; overwriting",e),t.set(e,n))}return t.size>0?t:null}async function a(e){if(!e)return null;const t=await self.clients.get(e);return"window"===t?.type?t:null}async function l(e,t,n){const r=await a(n);if(!r)return;const s=Array.from(t.values());try{r.postMessage({type:"ZIP_SW_MANIFEST_CREATED",zipUrl:e,files:s})}catch(e){(0,i.warn)("failed to send manifest to client",e)}}},993(e,t,n){t.installMessageHandler=function(){self.addEventListener("message",e=>{if(!e.data)return;const{type:t,zipUrl:n,files:u,config:d,allowedZipUrls:g,previousUrl:m,nextUrl:w}=e.data,h=function(e){if(!e||!("id"in e))return;const t=e.id;return"string"==typeof t?t:void 0}(e.source);if("ZIP_SW_CONFIG"===t){const t=(0,i.applyRuntimeConfig)(d).then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));return void e.waitUntil(t)}if("ZIP_MANIFEST"===t){if(n&&u){const t=(0,s.normalizeZipUrl)(n),r=(0,c.manifestFilesToMap)(u),i=a.zipManifests.get(t);if(!r)return void(0,l.warn)("rejecting empty manifest; keeping existing",{zipUrl:t,existingSize:i?i.size:0});if(i&&i.size>r.size)return void(0,l.warn)("rejecting smaller manifest; keeping existing",{zipUrl:t,incomingSize:r.size,existingSize:i.size});a.zipManifests.set(t,r),e.waitUntil((0,c.sendManifestToClientId)(t,r,h));const o=Array.from(r.keys()).slice(0,40);(0,l.log)("ZIP_MANIFEST loaded",{zipUrl:t,entryCount:r.size,sampleKeys:o,replacedExistingSize:i?i.size:0})}}else if("CLEAR_ZIP_ASSETS_EXCEPT_ALLOWED"===t&&g){const t=(0,o.clearZipAssetsExceptAllowed)(g).then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));e.waitUntil(t)}else if("CLEAR_ALL_ZIP_ASSETS"===t){const t=(0,o.clearAllZipAssets)().then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));e.waitUntil(t)}else if("PRELOAD_ZIP_MANIFESTS"===t&&g){const t=async function(e,t){const n=await Promise.all(e.map(async e=>({zipUrl:e,manifest:await(0,c.ensureManifestAvailable)(e,t)}))),s=n.filter(e=>!e.manifest).map(e=>e.zipUrl);if(s.length>0)throw(0,r.createZipPeekError)(`Failed to preload ZIP manifest(s): ${s.join(", ")}`)}(g,h).then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));e.waitUntil(t)}else if("RENEW_ZIP_URL"===t&&m&&w){console.log("[zip-peek-sw] RENEW_ZIP_URL received",{previousUrl:m.slice(0,100),nextUrl:w.slice(0,100)});const t=(0,o.renewZipUrl)(m,w).then(()=>{console.log("[zip-peek-sw] RENEW_ZIP_URL done ok"),p(e,{ok:!0})}).catch(t=>{console.error("[zip-peek-sw] RENEW_ZIP_URL failed",t),p(e,f(t))});e.waitUntil(t)}else"RENEW_ZIP_URL"===t&&console.error("[zip-peek-sw] RENEW_ZIP_URL missing previousUrl/nextUrl — no reply will be sent",{hasPrevious:Boolean(m),hasNext:Boolean(w)})})};const r=n(553),s=n(343),i=n(314),o=n(800),a=n(262),l=n(266),c=n(346);function f(e){const t=(0,r.toZipPeekError)(e);return{ok:!1,error:t.message,errorStack:t.stack}}function p(e,t){e.ports[0]?.postMessage(t)}},254(e,t,n){t.corsErrorResponse=l,t.getMimeType=c,t.fetchUncompressedZipEntryFromNetwork=async function(e,t,n,s){const f=n.offset,p=n.nextOffset-1;(0,o.log)("fetching zip chunk from",{zipUrl:e,rangeStart:f,rangeEnd:p});const u=await fetch(e,{headers:{Range:`bytes=${f}-${p}`}});if(206!==u.status)return{ok:!1,response:l(`ZIP entry fetch for "${t}" expected HTTP 206 Partial Content from ${e}, got ${u.status}`,u.status>=400?u.status:502)};const d=await u.arrayBuffer(),g=new DataView(d);if(g.getUint32(0,!0)!==i.LOCAL_FILE_HEADER_SIG)return{ok:!1,response:l(`Invalid local file header for "${t}" in ${e} (expected ZIP signature 0x04034b50)`,500)};const m=30+g.getUint16(26,!0)+g.getUint16(28,!0);if(m>d.byteLength||m+n.compressedSize>d.byteLength)return{ok:!1,response:l(`Corrupt ZIP entry "${t}" in ${e}: dataStart=${m}, compressedSize=${n.compressedSize}, bufferLength=${d.byteLength}`,500)};const w=new Uint8Array(d,m,n.compressedSize);let h;if(8===n.compression)try{h=(0,r.inflateSync)(w)}catch(n){return(0,o.warn)("inflateSync failed",{zipUrl:e,manifestKey:t,error:n}),{ok:!1,response:l(`Failed to inflate DEFLATE-compressed entry "${t}" in ${e}`,500)}}else{if(0!==n.compression)return{ok:!1,response:l(`Unsupported compression method ${n.compression} for "${t}" in ${e} (only stored/0 and DEFLATE/8 are supported)`,500)};h=w}const E=c(t),y=new Blob([h],{type:E});return await(0,a.putCachedFullAssetIfAbsent)(s,y),{ok:!0,blob:y}};const r=n(612),s=n(553),i=n(262),o=n(266),a=n(800);function l(e,t){return new Response((0,s.formatZipPeekError)(e),{status:t,headers:{"Access-Control-Allow-Origin":"*"}})}function c(e){const t=e.split(".").pop()?.toLowerCase();return t?i.MIME_TYPES[t]??"application/octet-stream":"application/octet-stream"}},343(e,t){function n(e){try{return decodeURIComponent(e)}catch{return e}}t.normalizeZipUrl=function(e,t={}){const{stripCacheBuster:n=!0,stripHash:r=!0}=t,s=e=>r?e.split("#")[0]:e;if(!n)return s(e);const i=e.indexOf("?");if(-1===i)return s(e);const o=e.indexOf("#",i),a=e.substring(0,i),l=-1===o?e.substring(i+1):e.substring(i+1,o),c=r||-1===o?"":e.substring(o),f=l.split("&").filter(e=>{const t=e.indexOf("=");return"t"!==(-1===t?e:e.substring(0,t))});return 0===f.length?a+c:a+"?"+f.join("&")+c},t.zipBasenameWithoutExtension=function(e){try{const t=new URL(e,"http://local").pathname.split("/").pop()??"";return t.endsWith(".zip")?t.slice(0,-4):t}catch{const t=e.split("?")[0].split("#")[0].split("/").pop()??"";return t.endsWith(".zip")?t.slice(0,-4):t}},t.normalizeZipEntryPath=function(e){let t=e.replace(/\\/g,"/");for(;t.startsWith("/");)t=t.slice(1);return t},t.parseZipAssetRequest=function(e){const t=/\.zip([/?])/.exec(e);if(!t)return null;const r=t.index+4,s=t[1],i=e.substring(0,r);if("/"===s){const t=e.substring(r+1),s=t.indexOf("?"),o=-1===s?t:t.substring(0,s);return""===o?null:{zipUrl:i,internalPath:n(o)}}const o=e.substring(r),a=o.indexOf("/");if(-1===a)return null;const l=o.substring(0,a),c=o.substring(a+1),f=c.indexOf("?"),p=-1===f?c:c.substring(0,f);return""===p?null:{zipUrl:i+l,internalPath:n(p)}},t.canonicalZipAssetRequestUrl=function(e,t){return e+"/"+encodeURIComponent(t)}},612(e,t){t.inflateSync=k;var n=Uint8Array,r=Uint16Array,s=Int32Array,i=new n([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),o=new n([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),a=new n([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),l=function(e,t){for(var n=new r(31),i=0;i<31;++i)n[i]=t+=1<<e[i-1];var o=new s(n[30]);for(i=1;i<30;++i)for(var a=n[i];a<n[i+1];++a)o[a]=a-n[i]<<5|i;return{b:n,r:o}},c=l(i,2),f=c.b,p=c.r;f[28]=258,p[258]=28;for(var u=l(o,0),d=u.b,g=(u.r,new r(32768)),m=0;m<32768;++m){var w=(43690&m)>>1|(21845&m)<<1;w=(61680&(w=(52428&w)>>2|(13107&w)<<2))>>4|(3855&w)<<4,g[m]=((65280&w)>>8|(255&w)<<8)>>1}var h=function(e,t,n){for(var s=e.length,i=0,o=new r(t);i<s;++i)e[i]&&++o[e[i]-1];var a,l=new r(t);for(i=1;i<t;++i)l[i]=l[i-1]+o[i-1]<<1;if(n){a=new r(1<<t);var c=15-t;for(i=0;i<s;++i)if(e[i])for(var f=i<<4|e[i],p=t-e[i],u=l[e[i]-1]++<<p,d=u|(1<<p)-1;u<=d;++u)a[g[u]>>c]=f}else for(a=new r(s),i=0;i<s;++i)e[i]&&(a[i]=g[l[e[i]-1]++]>>15-e[i]);return a},E=new n(288);for(m=0;m<144;++m)E[m]=8;for(m=144;m<256;++m)E[m]=9;for(m=256;m<280;++m)E[m]=7;for(m=280;m<288;++m)E[m]=8;var y=new n(32);for(m=0;m<32;++m)y[m]=5;var A=h(E,9,1),U=h(y,5,1),C=function(e){for(var t=e[0],n=1;n<e.length;++n)e[n]>t&&(t=e[n]);return t},z=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(7&t)&n},_=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(7&t)},Z=function(e){return(e+7)/8|0},R=function(e,t,r){return(null==t||t<0)&&(t=0),(null==r||r>e.length)&&(r=e.length),new n(e.subarray(t,r))},v=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],P=function(e,t,n){var r=new Error(t||v[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,P),!n)throw r;return r},S=function(e,t,r,s){var l=e.length,c=s?s.length:0;if(!l||t.f&&!t.l)return r||new n(0);var p=!r,u=p||2!=t.i,g=t.i;p&&(r=new n(3*l));var m=function(e){var t=r.length;if(e>t){var s=new n(Math.max(2*t,e));s.set(r),r=s}},w=t.f||0,E=t.p||0,y=t.b||0,v=t.l,S=t.d,M=t.m,k=t.n,I=8*l;do{if(!v){w=z(e,E,1);var b=z(e,E+1,3);if(E+=3,!b){var L=e[(W=Z(E)+4)-4]|e[W-3]<<8,x=W+L;if(x>l){g&&P(0);break}u&&m(y+L),r.set(e.subarray(W,x),y),t.b=y+=L,t.p=E=8*x,t.f=w;continue}if(1==b)v=A,S=U,M=9,k=5;else if(2==b){var T=z(e,E,31)+257,F=z(e,E+10,15)+4,N=T+z(e,E+5,31)+1;E+=14;for(var O=new n(N),$=new n(19),H=0;H<F;++H)$[a[H]]=z(e,E+3*H,7);E+=3*F;var D=C($),q=(1<<D)-1,K=h($,D,1);for(H=0;H<N;){var W,j=K[z(e,E,q)];if(E+=15&j,(W=j>>4)<16)O[H++]=W;else{var G=0,B=0;for(16==W?(B=3+z(e,E,3),E+=2,G=O[H-1]):17==W?(B=3+z(e,E,7),E+=3):18==W&&(B=11+z(e,E,127),E+=7);B--;)O[H++]=G}}var Y=O.subarray(0,T),X=O.subarray(T);M=C(Y),k=C(X),v=h(Y,M,1),S=h(X,k,1)}else P(1);if(E>I){g&&P(0);break}}u&&m(y+131072);for(var V=(1<<M)-1,J=(1<<k)-1,Q=E;;Q=E){var ee=(G=v[_(e,E)&V])>>4;if((E+=15&G)>I){g&&P(0);break}if(G||P(2),ee<256)r[y++]=ee;else{if(256==ee){Q=E,v=null;break}var te=ee-254;if(ee>264){var ne=i[H=ee-257];te=z(e,E,(1<<ne)-1)+f[H],E+=ne}var re=S[_(e,E)&J],se=re>>4;if(re||P(3),E+=15&re,X=d[se],se>3&&(ne=o[se],X+=_(e,E)&(1<<ne)-1,E+=ne),E>I){g&&P(0);break}u&&m(y+131072);var ie=y+te;if(y<X){var oe=c-X,ae=Math.min(X,ie);for(oe+y<0&&P(3);y<ae;++y)r[y]=s[oe+y]}for(;y<ie;++y)r[y]=r[y-X]}}t.l=v,t.p=Q,t.b=y,t.f=w,v&&(w=1,t.m=M,t.d=S,t.n=k)}while(!w);return y!=r.length&&p?R(r,0,y):r.subarray(0,y)},M=new n(0);function k(e,t){return S(e,{i:2},t&&t.out,t&&t.dictionary)}var I="undefined"!=typeof TextDecoder&&new TextDecoder;try{I.decode(M,{stream:!0})}catch(e){}"function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout&&setTimeout}};const t={};function n(r){const s=t[r];if(void 0!==s)return s.exports;const i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}(()=>{const e=n(266),t=n(982),r=n(993);self.addEventListener("install",()=>{self.skipWaiting()}),self.addEventListener("activate",e=>{e.waitUntil(self.clients.claim())}),(0,e.installClientErrorReporting)(),(0,r.installMessageHandler)(),(0,t.installFetchHandler)()})()})();
1
+ (()=>{"use strict";var e={553(e,t){function n(e){const n=e.trim();return n.startsWith(t.ZIP_PEEK_ERROR_PREFIX)?n:`${t.ZIP_PEEK_ERROR_PREFIX} ${n}`}t.ZIP_PEEK_ERROR_PREFIX=void 0,t.formatZipPeekError=n,t.createZipPeekError=function(e){return new Error(n(e))},t.toZipPeekError=function(e){const r=e instanceof Error?e:new Error(String(e));return r.message.startsWith(t.ZIP_PEEK_ERROR_PREFIX)||(r.message=n(r.message)),r},t.errorMessage=function(e){return e instanceof Error?e.message:String(e)},t.ZIP_PEEK_ERROR_PREFIX="[zip-peek-error]"},314(e,t,n){t.persistAllowedZipUrlsConfig=a,t.ensureAllowedZipUrlsLoaded=async function(){if(s.allowedZipUrlsLoaded)return s.allowedZipUrlsLoaded;const e=(async()=>{try{const e=await caches.open(s.CONFIG_CACHE_NAME),t=await e.match(s.CONFIG_CACHE_KEY);if(!t)return;const n=await t.json();Array.isArray(n.allowedZipUrls)?(0,s.setAllowedZipUrls)(new Set(n.allowedZipUrls.filter(e=>"string"==typeof e).map(e=>(0,r.normalizeZipUrl)(e)))):(0,s.setAllowedZipUrls)(null)}catch(e){(0,i.warn)("failed to load runtime config",e)}})();return(0,s.setAllowedZipUrlsLoaded)(e),e},t.applyRuntimeConfig=async function(e){if(!e)return;let t={...s.runtimeConfig},n=!1;if("string"==typeof e.zipAssetCacheName&&e.zipAssetCacheName.trim()&&(t.zipAssetCacheName=e.zipAssetCacheName,n=!0),"number"==typeof e.assetCacheTtlMs&&Number.isFinite(e.assetCacheTtlMs)&&(t.assetCacheTtlMs=e.assetCacheTtlMs,n=!0),"string"==typeof e.logPrefix&&e.logPrefix.trim()&&(t.logPrefix=e.logPrefix,n=!0),"boolean"==typeof e.requireExactManifestPath&&(t.requireExactManifestPath=e.requireExactManifestPath,n=!0),n&&(0,s.setRuntimeConfig)(t),"allowedZipUrls"in e){const t=Array.isArray(e.allowedZipUrls)?e.allowedZipUrls.map(e=>(0,r.normalizeZipUrl)(e)):null;(0,s.setAllowedZipUrls)(t?new Set(t):null),(0,s.setAllowedZipUrlsLoaded)(Promise.resolve()),await a(t)}},t.isZipUrlAllowed=function(e){return null===s.allowedZipUrls||s.allowedZipUrls.has(e)};const r=n(343),s=n(262),i=n(266);async function a(e){try{const t=await caches.open(s.CONFIG_CACHE_NAME);await t.put(new Request(s.CONFIG_CACHE_KEY),new Response(JSON.stringify({allowedZipUrls:e}),{headers:{"Content-Type":"application/json"}}))}catch(e){(0,i.warn)("failed to persist runtime config",e)}}},800(e,t,n){t.canonicalAssetRequest=function(e,t){return new Request((0,s.canonicalZipAssetRequestUrl)(e,t),{method:"GET"})},t.clearAllZipAssets=async function(){const e=await caches.open(a.runtimeConfig.zipAssetCacheName),t=await e.keys();await Promise.all(t.map(t=>e.delete(t))),await caches.delete(a.CONFIG_CACHE_NAME),a.zipManifests.clear(),a.pendingManifestLoads.clear(),(0,a.setAllowedZipUrlsLoaded)(Promise.resolve())},t.clearZipAssetsExceptAllowed=async function(e){try{const t=new Set(e),n=await caches.open(a.runtimeConfig.zipAssetCacheName),r=await n.keys();for(const e of r){const r=e.url,i=(0,s.parseZipAssetRequest)(r);i&&!t.has(i.zipUrl)&&await n.delete(e)}for(const e of a.zipManifests.keys())t.has(e)||a.zipManifests.delete(e)}catch(e){throw(0,r.createZipPeekError)(`Failed to clear zip assets except allowed URLs: ${(0,r.errorMessage)(e)}`)}},t.putCachedFullAssetIfAbsent=async function(e,t){try{const n=await caches.open(a.runtimeConfig.zipAssetCacheName),r=await n.match(e);if(r&&!l(r))return;const s=t.type||"application/octet-stream";await n.put(e,new Response(t,{status:200,headers:{"Content-Type":s,"Content-Length":String(t.size),"Access-Control-Allow-Origin":"*",[a.ASSET_CACHED_AT_HEADER]:String(Date.now())}}))}catch(e){(0,o.warn)("asset cache put failed",e)}},t.readCachedZipAssetIfFresh=async function(e){let t=null,n="network";try{const r=await caches.open(a.runtimeConfig.zipAssetCacheName),s=await r.match(e);if(s)if(l(s))try{await r.delete(e)}catch(e){(0,o.warn)("asset cache delete expired failed",e)}else t=await s.blob(),n="cache-api"}catch(e){(0,o.warn)("asset cache read failed",e)}return{blob:t,assetSource:n}},t.renewZipUrl=async function(e,t){const n=(0,s.normalizeZipUrl)(e),o=(0,s.normalizeZipUrl)(t);if(n===o)return;if(a.allowedZipUrls){const e=new Set(a.allowedZipUrls);e.delete(n),e.add(o),(0,a.setAllowedZipUrls)(e),(0,a.setAllowedZipUrlsLoaded)(Promise.resolve()),await(0,i.persistAllowedZipUrlsConfig)(Array.from(e))}const l=a.zipManifests.get(n);l&&(a.zipManifests.set(o,l),a.zipManifests.delete(n));const c=a.pendingManifestLoads.get(n);c&&(a.pendingManifestLoads.set(o,c),a.pendingManifestLoads.delete(n));try{const e=await caches.open(a.runtimeConfig.zipAssetCacheName),t=await e.keys();for(const r of t){const t=r.url,i=(0,s.parseZipAssetRequest)(t);i&&(0,s.normalizeZipUrl)(i.zipUrl)===n&&await e.delete(r)}}catch(e){throw(0,r.createZipPeekError)(`Failed to clear cached assets for renewed ZIP URL: ${(0,r.errorMessage)(e)}`)}};const r=n(553),s=n(343),i=n(314),a=n(262),o=n(266);function l(e){const t=e.headers.get(a.ASSET_CACHED_AT_HEADER);if(!t)return!0;const n=parseInt(t,10);return!Number.isFinite(n)||Date.now()-n>a.runtimeConfig.assetCacheTtlMs}},982(e,t,n){t.installFetchHandler=function(){self.addEventListener("fetch",e=>{const t=e.request.method;if("GET"!==t&&"HEAD"!==t)return;const n="HEAD"===t,d=(0,s.parseZipAssetRequest)(e.request.url);if(!d)return;const m=(0,s.normalizeZipUrl)(d.zipUrl),g=d.internalPath,w=(0,s.normalizeZipEntryPath)(g);e.respondWith((async()=>{try{if(await(0,i.ensureAllowedZipUrlsLoaded)(),!(0,i.isZipUrlAllowed)(m))return(0,l.warn)("zip URL not allowed",{requestedZipUrl:m}),(0,f.corsErrorResponse)(`ZIP URL not allowed (not in allowedZipUrls): ${m}`,403);let t=o.zipManifests.get(m);if(t||(t=await(0,c.ensureManifestAvailable)(m,e.clientId||void 0)??void 0),!t){const e=Array.from(o.zipManifests.keys());return(0,l.warn)("manifest missing for zipUrl",{requestedZipUrl:m,knownZipUrls:e}),(0,f.corsErrorResponse)(`ZIP manifest not loaded for ${m}. Ensure the ZIP is reachable and supports byte-range requests.`,404)}const s=(0,c.resolveManifestEntry)(t,w,m,o.runtimeConfig.requireExactManifestPath);if(!s){const e=Array.from(t.keys()).slice(0,50);return(0,l.warn)("file not in manifest",{zipUrl:m,internalPathRaw:g,internalPathNormalized:w,requireExactManifestPath:o.runtimeConfig.requireExactManifestPath,manifestSize:t.size,sampleKeys:e}),(0,f.corsErrorResponse)(`File "${g}" not found in ZIP manifest for ${m}`,404)}const{key:d,info:h,matchKind:E}=s;"zipBasenameFallback"===E&&((0,l.log)("resolved via zip-basename folder fallback",{requested:w,manifestKey:d}),(0,l.reportClientError)(new Error((0,r.formatZipPeekError)("Exact manifest path not found; resolved via zip-basename folder fallback")),`Exact manifest key "${w}" not found in ${m}; resolved using "${d}"`));const y=(0,a.canonicalAssetRequest)(m,d);if(n)return function(e,t,n){const r=(0,f.getMimeType)(t),s=(0,c.entryUncompressedSize)(n),i=e.headers.get("range");if(null!==s&&i)return u(null,r,s,"manifest",i);const a={"Content-Type":r,...p("manifest")};return null!==s&&(a["Content-Length"]=s.toString()),new Response(null,{status:200,headers:a})}(e.request,d,h);let{blob:A,assetSource:C}=await(0,a.readCachedZipAssetIfFresh)(y);if(!A){const e=await(0,f.fetchUncompressedZipEntryFromNetwork)(m,d,h,y);if(!e.ok)return e.response;A=e.blob,C="network"}return u(A,A.type,A.size,C,e.request.headers.get("range"))}catch(e){return(0,l.error)("fetch handler failed",{zipUrl:m,internalPath:g,message:(0,r.errorMessage)(e)}),(0,f.corsErrorResponse)(`Failed to serve "${g}" from ${m}: ${(0,r.errorMessage)(e)}`,500)}})())})};const r=n(553),s=n(343),i=n(314),a=n(800),o=n(262),l=n(266),c=n(346),f=n(254);function p(e){return{"Access-Control-Allow-Origin":"*","Access-Control-Expose-Headers":o.ASSET_SOURCE_HEADER,[o.ASSET_SOURCE_HEADER]:e}}function u(e,t,n,r,s){if(s){const i=s.replace(/^bytes=/,"");if(i.includes(","))return new Response(null,{status:416,headers:{"Content-Range":`bytes */${n}`,...p(r)}});const[a,o]=i.split("-"),l=""!==a?parseInt(a,10):NaN,c=""!==o?parseInt(o,10):n-1;if(isNaN(l)||isNaN(c)||l<0||c<l||l>=n)return new Response(null,{status:416,headers:{"Content-Range":`bytes */${n}`,...p(r)}});const f=Math.min(c,n-1),u=f-l+1,d=null===e?null:e.slice(l,f+1);return new Response(d,{status:206,headers:{"Content-Type":t,"Content-Range":`bytes ${l}-${f}/${n}`,"Content-Length":u.toString(),"Accept-Ranges":"bytes",...p(r)}})}return new Response(e,{status:200,headers:{"Content-Type":t,"Content-Length":n.toString(),...p(r)}})}},262(e,t){t.CONFIG_CACHE_KEY=t.allowedZipUrlsLoaded=t.allowedZipUrls=t.runtimeConfig=t.pendingManifestLoads=t.zipManifests=t.LOCAL_FILE_HEADER_SIG=t.MIME_TYPES=t.ASSET_SOURCE_HEADER=t.ASSET_CACHED_AT_HEADER=t.CONFIG_CACHE_NAME=t.kF=t.o2=void 0,t.setRuntimeConfig=function(e){t.runtimeConfig=e},t.setAllowedZipUrls=function(e){t.allowedZipUrls=e},t.setAllowedZipUrlsLoaded=function(e){t.allowedZipUrlsLoaded=e},t.o2="zip-cache-v1",t.kF=72e5,t.CONFIG_CACHE_NAME="zip-peek-config-v1",t.o2,t.CONFIG_CACHE_NAME,t.ASSET_CACHED_AT_HEADER="X-ZipSW-Cached-At",t.ASSET_SOURCE_HEADER="X-ZipSW-Asset-Source",t.MIME_TYPES={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",json:"application/json",js:"application/javascript",css:"text/css; charset=utf-8",html:"text/html; charset=utf-8",txt:"text/plain; charset=utf-8",mp4:"video/mp4",webm:"video/webm",mp3:"audio/mpeg",wav:"audio/wav",oga:"audio/ogg",ogg:"audio/ogg",xml:"application/xml",wasm:"application/wasm"},t.LOCAL_FILE_HEADER_SIG=67324752,t.zipManifests=new Map,t.pendingManifestLoads=new Map,t.runtimeConfig={zipAssetCacheName:t.o2,assetCacheTtlMs:t.kF,logPrefix:"[zipSW]",requireExactManifestPath:!1},t.allowedZipUrls=null,t.allowedZipUrlsLoaded=null,t.CONFIG_CACHE_KEY=new URL("__zip_peek_runtime_config__",self.registration.scope).href},266(e,t,n){t.log=function(...e){console.log(s.runtimeConfig.logPrefix,...e)},t.warn=function(...e){console.warn(s.runtimeConfig.logPrefix,...e)},t.error=function(...e){console.error(s.runtimeConfig.logPrefix,r.ZIP_PEEK_ERROR_PREFIX,...e)},t.reportClientError=i,t.installClientErrorReporting=function(){self.addEventListener("error",e=>{i(e.error??e.message,"Service worker uncaught error")}),self.addEventListener("unhandledrejection",e=>{i(e.reason,"Service worker unhandled promise rejection")})};const r=n(553),s=n(262);function i(e,t){const n=(0,r.toZipPeekError)(e);self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(e=>{const s={type:"ZIP_SW_ERROR",error:{message:n.message,stack:n.stack},info:t?(0,r.formatZipPeekError)(t):void 0};for(const t of e)t.postMessage(s)})}},346(e,t,n){t.manifestFilesToMap=a,t.sendManifestToClientId=l,t.ensureManifestAvailable=function(e,t){const n=s.zipManifests.get(e);if(n)return Promise.resolve(n);let c=s.pendingManifestLoads.get(e);return c||(c=(async()=>{const n=await async function(e,t){const n=await o(t);return n?function(e,t){return new Promise(n=>{const r=new MessageChannel,s=setTimeout(()=>{r.port1.close(),n(null)},500);r.port1.onmessage=e=>{clearTimeout(s),r.port1.close();const t=e.data;t?.ok&&Array.isArray(t.files)?n(a(t.files)):n(null)},r.port1.onmessageerror=()=>{clearTimeout(s),r.port1.close(),n(null)};try{e.postMessage({type:"ZIP_SW_MANIFEST_REQUEST",zipUrl:t},[r.port2])}catch(e){clearTimeout(s),r.port1.close(),(0,i.warn)("failed to request manifest from client",e),n(null)}})}(n,e):null}(e,t);if(n)return s.zipManifests.set(e,n),(0,i.log)("restored manifest from client memory",{zipUrl:e,entryCount:n.size}),n;const c=await async function(e){const t=await fetch(e,{headers:{Range:"bytes=-65536"}});if(206!==t.status)return(0,i.error)("range requests not supported for ZIP manifest",{zipUrl:e,status:t.status}),null;const n=await t.arrayBuffer(),s=new DataView(n);let a=-1;for(let e=n.byteLength-22;e>=0;e--)if(101010256===s.getUint32(e,!0)){a=e;break}if(-1===a)return(0,i.error)("EOCD not found in last 64KB of ZIP file",e),null;const o=s.getUint32(a+16,!0),l=s.getUint32(a+12,!0);let c=n,f=-1;const p=t.headers.get("Content-Range");let u=0;if(p){const e=p.match(/\/(\d+)$/);e&&(u=parseInt(e[1],10))}if(u<=0)return(0,i.error)("could not determine ZIP file size from Content-Range header",{zipUrl:e,contentRange:p}),null;const d=u-n.byteLength;if(o>=d)f=o-d;else{const t=await fetch(e,{headers:{Range:`bytes=${o}-${o+l-1}`}});if(206!==t.status)return(0,i.error)("failed to fetch ZIP central directory",{zipUrl:e,status:t.status,cdOffset:o,cdSize:l}),null;c=await t.arrayBuffer(),f=0}return function(e,t,n,s){const a=new DataView(e);let o=t;const l=[];for(;o+46<=e.byteLength&&33639248===a.getUint32(o,!0);){const t=a.getUint16(o+10,!0),n=a.getUint32(o+20,!0),s=a.getUint32(o+24,!0),i=a.getUint16(o+28,!0),c=a.getUint16(o+30,!0),f=a.getUint16(o+32,!0),p=a.getUint32(o+42,!0),u=new TextDecoder;if(o+46+i>e.byteLength)break;const d=new Uint8Array(e,o+46,i),m=u.decode(d),g=(0,r.normalizeZipEntryPath)(m);""!==g&&l.push({filename:g,offset:p,compressedSize:n,uncompressedSize:s,compression:t}),o+=46+i+c+f}if(0===l.length)return(0,i.error)("no files parsed from central directory",s),null;l.sort((e,t)=>e.offset-t.offset);const c=new Map;for(let e=0;e<l.length;e++){const t=l[e],s=(0,r.normalizeZipEntryPath)(t.filename);""!==s&&(c.has(s)&&(0,i.warn)("duplicate manifest key after normalize; overwriting",s),c.set(s,{filename:t.filename,offset:t.offset,compressedSize:t.compressedSize,uncompressedSize:t.uncompressedSize,compression:t.compression,nextOffset:e<l.length-1?l[e+1].offset:n}))}return c.size>0?c:null}(c,f,o,e)}(e);return c&&(s.zipManifests.set(e,c),await l(e,c,t),(0,i.log)("manifest fetched and stored in memory",{zipUrl:e,entryCount:c.size})),c})().finally(()=>{s.pendingManifestLoads.delete(e)}),s.pendingManifestLoads.set(e,c),c)},t.entryUncompressedSize=function(e){return void 0!==e.uncompressedSize?e.uncompressedSize:0===e.compression?e.compressedSize:null},t.resolveManifestEntry=function(e,t,n,s){if(e.has(t))return{key:t,info:e.get(t),matchKind:"exact"};if(s)return null;const i=(0,r.zipBasenameWithoutExtension)(n);if(!i)return null;const a=`${i}/${t}`;return e.has(a)?{key:a,info:e.get(a),matchKind:"zipBasenameFallback"}:null};const r=n(343),s=n(262),i=n(266);function a(e){const t=new Map;for(const n of e){const e=(0,r.normalizeZipEntryPath)(n.filename);""!==e&&(t.has(e)&&(0,i.warn)("duplicate manifest key after normalize; overwriting",e),t.set(e,n))}return t.size>0?t:null}async function o(e){if(!e)return null;const t=await self.clients.get(e);return"window"===t?.type?t:null}async function l(e,t,n){const r=await o(n);if(!r)return;const s=Array.from(t.values());try{r.postMessage({type:"ZIP_SW_MANIFEST_CREATED",zipUrl:e,files:s})}catch(e){(0,i.warn)("failed to send manifest to client",e)}}},993(e,t,n){t.installMessageHandler=function(){self.addEventListener("message",e=>{if(!e.data)return;const{type:t,zipUrl:n,files:u,config:d,allowedZipUrls:m,previousUrl:g,nextUrl:w}=e.data,h=function(e){if(!e||!("id"in e))return;const t=e.id;return"string"==typeof t?t:void 0}(e.source);if("ZIP_SW_CONFIG"===t){const t=(0,i.applyRuntimeConfig)(d).then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));return void e.waitUntil(t)}if("ZIP_MANIFEST"===t){if(n&&u){const t=(0,s.normalizeZipUrl)(n),r=(0,c.manifestFilesToMap)(u),i=o.zipManifests.get(t);if(!r)return void(0,l.warn)("rejecting empty manifest; keeping existing",{zipUrl:t,existingSize:i?i.size:0});if(i&&i.size>r.size)return void(0,l.warn)("rejecting smaller manifest; keeping existing",{zipUrl:t,incomingSize:r.size,existingSize:i.size});o.zipManifests.set(t,r),e.waitUntil((0,c.sendManifestToClientId)(t,r,h));const a=Array.from(r.keys()).slice(0,40);(0,l.log)("ZIP_MANIFEST loaded",{zipUrl:t,entryCount:r.size,sampleKeys:a,replacedExistingSize:i?i.size:0})}}else if("CLEAR_ZIP_ASSETS_EXCEPT_ALLOWED"===t&&m){const t=(0,a.clearZipAssetsExceptAllowed)(m).then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));e.waitUntil(t)}else if("CLEAR_ALL_ZIP_ASSETS"===t){const t=(0,a.clearAllZipAssets)().then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));e.waitUntil(t)}else if("PRELOAD_ZIP_MANIFESTS"===t&&m){const t=async function(e,t){const n=await Promise.all(e.map(async e=>({zipUrl:e,manifest:await(0,c.ensureManifestAvailable)(e,t)}))),s=n.filter(e=>!e.manifest).map(e=>e.zipUrl);if(s.length>0)throw(0,r.createZipPeekError)(`Failed to preload ZIP manifest(s): ${s.join(", ")}`)}(m,h).then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));e.waitUntil(t)}else if("RENEW_ZIP_URL"===t&&g&&w){const t=(0,a.renewZipUrl)(g,w).then(()=>p(e,{ok:!0})).catch(t=>p(e,f(t)));e.waitUntil(t)}})};const r=n(553),s=n(343),i=n(314),a=n(800),o=n(262),l=n(266),c=n(346);function f(e){const t=(0,r.toZipPeekError)(e);return{ok:!1,error:t.message,errorStack:t.stack}}function p(e,t){e.ports[0]?.postMessage(t)}},254(e,t,n){t.corsErrorResponse=l,t.getMimeType=c,t.fetchUncompressedZipEntryFromNetwork=async function(e,t,n,s){const f=n.offset,p=n.nextOffset-1;(0,a.log)("fetching zip chunk from",{zipUrl:e,rangeStart:f,rangeEnd:p});const u=await fetch(e,{headers:{Range:`bytes=${f}-${p}`}});if(206!==u.status)return{ok:!1,response:l(`ZIP entry fetch for "${t}" expected HTTP 206 Partial Content from ${e}, got ${u.status}`,u.status>=400?u.status:502)};const d=await u.arrayBuffer(),m=new DataView(d);if(m.getUint32(0,!0)!==i.LOCAL_FILE_HEADER_SIG)return{ok:!1,response:l(`Invalid local file header for "${t}" in ${e} (expected ZIP signature 0x04034b50)`,500)};const g=30+m.getUint16(26,!0)+m.getUint16(28,!0);if(g>d.byteLength||g+n.compressedSize>d.byteLength)return{ok:!1,response:l(`Corrupt ZIP entry "${t}" in ${e}: dataStart=${g}, compressedSize=${n.compressedSize}, bufferLength=${d.byteLength}`,500)};const w=new Uint8Array(d,g,n.compressedSize);let h;if(8===n.compression)try{h=(0,r.inflateSync)(w)}catch(n){return(0,a.warn)("inflateSync failed",{zipUrl:e,manifestKey:t,error:n}),{ok:!1,response:l(`Failed to inflate DEFLATE-compressed entry "${t}" in ${e}`,500)}}else{if(0!==n.compression)return{ok:!1,response:l(`Unsupported compression method ${n.compression} for "${t}" in ${e} (only stored/0 and DEFLATE/8 are supported)`,500)};h=w}const E=c(t),y=new Blob([h],{type:E});return await(0,o.putCachedFullAssetIfAbsent)(s,y),{ok:!0,blob:y}};const r=n(612),s=n(553),i=n(262),a=n(266),o=n(800);function l(e,t){return new Response((0,s.formatZipPeekError)(e),{status:t,headers:{"Access-Control-Allow-Origin":"*"}})}function c(e){const t=e.split(".").pop()?.toLowerCase();return t?i.MIME_TYPES[t]??"application/octet-stream":"application/octet-stream"}},343(e,t){function n(e){try{return decodeURIComponent(e)}catch{return e}}t.normalizeZipUrl=function(e,t={}){const{stripCacheBuster:n=!0,stripHash:r=!0}=t,s=e=>r?e.split("#")[0]:e;if(!n)return s(e);const i=e.indexOf("?");if(-1===i)return s(e);const a=e.indexOf("#",i),o=e.substring(0,i),l=-1===a?e.substring(i+1):e.substring(i+1,a),c=r||-1===a?"":e.substring(a),f=l.split("&").filter(e=>{const t=e.indexOf("=");return"t"!==(-1===t?e:e.substring(0,t))});return 0===f.length?o+c:o+"?"+f.join("&")+c},t.zipBasenameWithoutExtension=function(e){try{const t=new URL(e,"http://local").pathname.split("/").pop()??"";return t.endsWith(".zip")?t.slice(0,-4):t}catch{const t=e.split("?")[0].split("#")[0].split("/").pop()??"";return t.endsWith(".zip")?t.slice(0,-4):t}},t.normalizeZipEntryPath=function(e){let t=e.replace(/\\/g,"/");for(;t.startsWith("/");)t=t.slice(1);return t},t.parseZipAssetRequest=function(e){const t=/\.zip([/?])/.exec(e);if(!t)return null;const r=t.index+4,s=t[1],i=e.substring(0,r);if("/"===s){const t=e.substring(r+1),s=t.indexOf("?"),a=-1===s?t:t.substring(0,s);return""===a?null:{zipUrl:i,internalPath:n(a)}}const a=e.substring(r),o=a.indexOf("/");if(-1===o)return null;const l=a.substring(0,o),c=a.substring(o+1),f=c.indexOf("?"),p=-1===f?c:c.substring(0,f);return""===p?null:{zipUrl:i+l,internalPath:n(p)}},t.canonicalZipAssetRequestUrl=function(e,t){return e+"/"+encodeURIComponent(t)}},612(e,t){t.inflateSync=b;var n=Uint8Array,r=Uint16Array,s=Int32Array,i=new n([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),a=new n([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),o=new n([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),l=function(e,t){for(var n=new r(31),i=0;i<31;++i)n[i]=t+=1<<e[i-1];var a=new s(n[30]);for(i=1;i<30;++i)for(var o=n[i];o<n[i+1];++o)a[o]=o-n[i]<<5|i;return{b:n,r:a}},c=l(i,2),f=c.b,p=c.r;f[28]=258,p[258]=28;for(var u=l(a,0),d=u.b,m=(u.r,new r(32768)),g=0;g<32768;++g){var w=(43690&g)>>1|(21845&g)<<1;w=(61680&(w=(52428&w)>>2|(13107&w)<<2))>>4|(3855&w)<<4,m[g]=((65280&w)>>8|(255&w)<<8)>>1}var h=function(e,t,n){for(var s=e.length,i=0,a=new r(t);i<s;++i)e[i]&&++a[e[i]-1];var o,l=new r(t);for(i=1;i<t;++i)l[i]=l[i-1]+a[i-1]<<1;if(n){o=new r(1<<t);var c=15-t;for(i=0;i<s;++i)if(e[i])for(var f=i<<4|e[i],p=t-e[i],u=l[e[i]-1]++<<p,d=u|(1<<p)-1;u<=d;++u)o[m[u]>>c]=f}else for(o=new r(s),i=0;i<s;++i)e[i]&&(o[i]=m[l[e[i]-1]++]>>15-e[i]);return o},E=new n(288);for(g=0;g<144;++g)E[g]=8;for(g=144;g<256;++g)E[g]=9;for(g=256;g<280;++g)E[g]=7;for(g=280;g<288;++g)E[g]=8;var y=new n(32);for(g=0;g<32;++g)y[g]=5;var A=h(E,9,1),C=h(y,5,1),U=function(e){for(var t=e[0],n=1;n<e.length;++n)e[n]>t&&(t=e[n]);return t},z=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(7&t)&n},Z=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(7&t)},_=function(e){return(e+7)/8|0},R=function(e,t,r){return(null==t||t<0)&&(t=0),(null==r||r>e.length)&&(r=e.length),new n(e.subarray(t,r))},v=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],P=function(e,t,n){var r=new Error(t||v[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,P),!n)throw r;return r},S=function(e,t,r,s){var l=e.length,c=s?s.length:0;if(!l||t.f&&!t.l)return r||new n(0);var p=!r,u=p||2!=t.i,m=t.i;p&&(r=new n(3*l));var g=function(e){var t=r.length;if(e>t){var s=new n(Math.max(2*t,e));s.set(r),r=s}},w=t.f||0,E=t.p||0,y=t.b||0,v=t.l,S=t.d,M=t.m,b=t.n,k=8*l;do{if(!v){w=z(e,E,1);var I=z(e,E+1,3);if(E+=3,!I){var L=e[(W=_(E)+4)-4]|e[W-3]<<8,x=W+L;if(x>l){m&&P(0);break}u&&g(y+L),r.set(e.subarray(W,x),y),t.b=y+=L,t.p=E=8*x,t.f=w;continue}if(1==I)v=A,S=C,M=9,b=5;else if(2==I){var T=z(e,E,31)+257,F=z(e,E+10,15)+4,N=T+z(e,E+5,31)+1;E+=14;for(var O=new n(N),$=new n(19),H=0;H<F;++H)$[o[H]]=z(e,E+3*H,7);E+=3*F;var D=U($),q=(1<<D)-1,K=h($,D,1);for(H=0;H<N;){var W,j=K[z(e,E,q)];if(E+=15&j,(W=j>>4)<16)O[H++]=W;else{var G=0,B=0;for(16==W?(B=3+z(e,E,3),E+=2,G=O[H-1]):17==W?(B=3+z(e,E,7),E+=3):18==W&&(B=11+z(e,E,127),E+=7);B--;)O[H++]=G}}var X=O.subarray(0,T),Y=O.subarray(T);M=U(X),b=U(Y),v=h(X,M,1),S=h(Y,b,1)}else P(1);if(E>k){m&&P(0);break}}u&&g(y+131072);for(var V=(1<<M)-1,J=(1<<b)-1,Q=E;;Q=E){var ee=(G=v[Z(e,E)&V])>>4;if((E+=15&G)>k){m&&P(0);break}if(G||P(2),ee<256)r[y++]=ee;else{if(256==ee){Q=E,v=null;break}var te=ee-254;if(ee>264){var ne=i[H=ee-257];te=z(e,E,(1<<ne)-1)+f[H],E+=ne}var re=S[Z(e,E)&J],se=re>>4;if(re||P(3),E+=15&re,Y=d[se],se>3&&(ne=a[se],Y+=Z(e,E)&(1<<ne)-1,E+=ne),E>k){m&&P(0);break}u&&g(y+131072);var ie=y+te;if(y<Y){var ae=c-Y,oe=Math.min(Y,ie);for(ae+y<0&&P(3);y<oe;++y)r[y]=s[ae+y]}for(;y<ie;++y)r[y]=r[y-Y]}}t.l=v,t.p=Q,t.b=y,t.f=w,v&&(w=1,t.m=M,t.d=S,t.n=b)}while(!w);return y!=r.length&&p?R(r,0,y):r.subarray(0,y)},M=new n(0);function b(e,t){return S(e,{i:2},t&&t.out,t&&t.dictionary)}var k="undefined"!=typeof TextDecoder&&new TextDecoder;try{k.decode(M,{stream:!0})}catch(e){}"function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout&&setTimeout}};const t={};function n(r){const s=t[r];if(void 0!==s)return s.exports;const i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}(()=>{const e=n(266),t=n(982),r=n(993);self.addEventListener("install",()=>{self.skipWaiting()}),self.addEventListener("activate",e=>{e.waitUntil(self.clients.claim())}),(0,e.installClientErrorReporting)(),(0,r.installMessageHandler)(),(0,t.installFetchHandler)()})()})();
2
2
  //# sourceMappingURL=zipServiceWorker.js.map