You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					1864 lines
				
				66 KiB
			
		
		
			
		
	
	
					1864 lines
				
				66 KiB
			| 
											8 months ago
										 | (() => { | ||
|  |   var __defProp = Object.defineProperty; | ||
|  |   var __defProps = Object.defineProperties; | ||
|  |   var __getOwnPropDescs = Object.getOwnPropertyDescriptors; | ||
|  |   var __getOwnPropSymbols = Object.getOwnPropertySymbols; | ||
|  |   var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
|  |   var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
|  |   var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
|  |   var __spreadValues = (a, b) => { | ||
|  |     for (var prop in b || (b = {})) | ||
|  |       if (__hasOwnProp.call(b, prop)) | ||
|  |         __defNormalProp(a, prop, b[prop]); | ||
|  |     if (__getOwnPropSymbols) | ||
|  |       for (var prop of __getOwnPropSymbols(b)) { | ||
|  |         if (__propIsEnum.call(b, prop)) | ||
|  |           __defNormalProp(a, prop, b[prop]); | ||
|  |       } | ||
|  |     return a; | ||
|  |   }; | ||
|  |   var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/named-cache-storage.mjs
 | ||
|  |   var NamedCacheStorage = class { | ||
|  |     constructor(original, cacheNamePrefix) { | ||
|  |       this.original = original; | ||
|  |       this.cacheNamePrefix = cacheNamePrefix; | ||
|  |     } | ||
|  |     delete(cacheName) { | ||
|  |       return this.original.delete(`${this.cacheNamePrefix}:${cacheName}`); | ||
|  |     } | ||
|  |     has(cacheName) { | ||
|  |       return this.original.has(`${this.cacheNamePrefix}:${cacheName}`); | ||
|  |     } | ||
|  |     async keys() { | ||
|  |       const prefix = `${this.cacheNamePrefix}:`; | ||
|  |       const allCacheNames = await this.original.keys(); | ||
|  |       const ownCacheNames = allCacheNames.filter((name) => name.startsWith(prefix)); | ||
|  |       return ownCacheNames.map((name) => name.slice(prefix.length)); | ||
|  |     } | ||
|  |     match(request, options) { | ||
|  |       return this.original.match(request, options); | ||
|  |     } | ||
|  |     async open(cacheName) { | ||
|  |       const cache = await this.original.open(`${this.cacheNamePrefix}:${cacheName}`); | ||
|  |       return Object.assign(cache, { name: cacheName }); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/adapter.mjs
 | ||
|  |   var Adapter = class { | ||
|  |     constructor(scopeUrl, caches) { | ||
|  |       this.scopeUrl = scopeUrl; | ||
|  |       const parsedScopeUrl = this.parseUrl(this.scopeUrl); | ||
|  |       this.origin = parsedScopeUrl.origin; | ||
|  |       this.caches = new NamedCacheStorage(caches, `ngsw:${parsedScopeUrl.path}`); | ||
|  |     } | ||
|  |     newRequest(input, init) { | ||
|  |       return new Request(input, init); | ||
|  |     } | ||
|  |     newResponse(body, init) { | ||
|  |       return new Response(body, init); | ||
|  |     } | ||
|  |     newHeaders(headers) { | ||
|  |       return new Headers(headers); | ||
|  |     } | ||
|  |     isClient(source) { | ||
|  |       return source instanceof Client; | ||
|  |     } | ||
|  |     get time() { | ||
|  |       return Date.now(); | ||
|  |     } | ||
|  |     normalizeUrl(url) { | ||
|  |       const parsed = this.parseUrl(url, this.scopeUrl); | ||
|  |       return parsed.origin === this.origin ? parsed.path : url; | ||
|  |     } | ||
|  |     parseUrl(url, relativeTo) { | ||
|  |       const parsed = !relativeTo ? new URL(url) : new URL(url, relativeTo); | ||
|  |       return { origin: parsed.origin, path: parsed.pathname, search: parsed.search }; | ||
|  |     } | ||
|  |     timeout(ms) { | ||
|  |       return new Promise((resolve) => { | ||
|  |         setTimeout(() => resolve(), ms); | ||
|  |       }); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/database.mjs
 | ||
|  |   var NotFound = class { | ||
|  |     constructor(table, key) { | ||
|  |       this.table = table; | ||
|  |       this.key = key; | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/db-cache.mjs
 | ||
|  |   var CacheDatabase = class { | ||
|  |     constructor(adapter2) { | ||
|  |       this.adapter = adapter2; | ||
|  |       this.cacheNamePrefix = "db"; | ||
|  |       this.tables = /* @__PURE__ */ new Map(); | ||
|  |     } | ||
|  |     "delete"(name) { | ||
|  |       if (this.tables.has(name)) { | ||
|  |         this.tables.delete(name); | ||
|  |       } | ||
|  |       return this.adapter.caches.delete(`${this.cacheNamePrefix}:${name}`); | ||
|  |     } | ||
|  |     async list() { | ||
|  |       const prefix = `${this.cacheNamePrefix}:`; | ||
|  |       const allCacheNames = await this.adapter.caches.keys(); | ||
|  |       const dbCacheNames = allCacheNames.filter((name) => name.startsWith(prefix)); | ||
|  |       return dbCacheNames.map((name) => name.slice(prefix.length)); | ||
|  |     } | ||
|  |     async open(name, cacheQueryOptions) { | ||
|  |       if (!this.tables.has(name)) { | ||
|  |         const cache = await this.adapter.caches.open(`${this.cacheNamePrefix}:${name}`); | ||
|  |         const table = new CacheTable(name, cache, this.adapter, cacheQueryOptions); | ||
|  |         this.tables.set(name, table); | ||
|  |       } | ||
|  |       return this.tables.get(name); | ||
|  |     } | ||
|  |   }; | ||
|  |   var CacheTable = class { | ||
|  |     constructor(name, cache, adapter2, cacheQueryOptions) { | ||
|  |       this.name = name; | ||
|  |       this.cache = cache; | ||
|  |       this.adapter = adapter2; | ||
|  |       this.cacheQueryOptions = cacheQueryOptions; | ||
|  |       this.cacheName = this.cache.name; | ||
|  |     } | ||
|  |     request(key) { | ||
|  |       return this.adapter.newRequest("/" + key); | ||
|  |     } | ||
|  |     "delete"(key) { | ||
|  |       return this.cache.delete(this.request(key), this.cacheQueryOptions); | ||
|  |     } | ||
|  |     keys() { | ||
|  |       return this.cache.keys().then((requests) => requests.map((req) => req.url.slice(1))); | ||
|  |     } | ||
|  |     read(key) { | ||
|  |       return this.cache.match(this.request(key), this.cacheQueryOptions).then((res) => { | ||
|  |         if (res === void 0) { | ||
|  |           return Promise.reject(new NotFound(this.name, key)); | ||
|  |         } | ||
|  |         return res.json(); | ||
|  |       }); | ||
|  |     } | ||
|  |     write(key, value) { | ||
|  |       return this.cache.put(this.request(key), this.adapter.newResponse(JSON.stringify(value))); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/api.mjs
 | ||
|  |   var UpdateCacheStatus; | ||
|  |   (function(UpdateCacheStatus2) { | ||
|  |     UpdateCacheStatus2[UpdateCacheStatus2["NOT_CACHED"] = 0] = "NOT_CACHED"; | ||
|  |     UpdateCacheStatus2[UpdateCacheStatus2["CACHED_BUT_UNUSED"] = 1] = "CACHED_BUT_UNUSED"; | ||
|  |     UpdateCacheStatus2[UpdateCacheStatus2["CACHED"] = 2] = "CACHED"; | ||
|  |   })(UpdateCacheStatus || (UpdateCacheStatus = {})); | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/error.mjs
 | ||
|  |   var SwCriticalError = class extends Error { | ||
|  |     constructor() { | ||
|  |       super(...arguments); | ||
|  |       this.isCritical = true; | ||
|  |     } | ||
|  |   }; | ||
|  |   function errorToString(error) { | ||
|  |     if (error instanceof Error) { | ||
|  |       return `${error.message}
 | ||
|  | ${error.stack}`;
 | ||
|  |     } else { | ||
|  |       return `${error}`; | ||
|  |     } | ||
|  |   } | ||
|  |   var SwUnrecoverableStateError = class extends SwCriticalError { | ||
|  |     constructor() { | ||
|  |       super(...arguments); | ||
|  |       this.isUnrecoverableState = true; | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/sha1.mjs
 | ||
|  |   function sha1(str) { | ||
|  |     const utf8 = str; | ||
|  |     const words32 = stringToWords32(utf8, Endian.Big); | ||
|  |     return _sha1(words32, utf8.length * 8); | ||
|  |   } | ||
|  |   function sha1Binary(buffer) { | ||
|  |     const words32 = arrayBufferToWords32(buffer, Endian.Big); | ||
|  |     return _sha1(words32, buffer.byteLength * 8); | ||
|  |   } | ||
|  |   function _sha1(words32, len) { | ||
|  |     const w = []; | ||
|  |     let [a, b, c, d, e] = [1732584193, 4023233417, 2562383102, 271733878, 3285377520]; | ||
|  |     words32[len >> 5] |= 128 << 24 - len % 32; | ||
|  |     words32[(len + 64 >> 9 << 4) + 15] = len; | ||
|  |     for (let i = 0; i < words32.length; i += 16) { | ||
|  |       const [h0, h1, h2, h3, h4] = [a, b, c, d, e]; | ||
|  |       for (let j = 0; j < 80; j++) { | ||
|  |         if (j < 16) { | ||
|  |           w[j] = words32[i + j]; | ||
|  |         } else { | ||
|  |           w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); | ||
|  |         } | ||
|  |         const [f, k] = fk(j, b, c, d); | ||
|  |         const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32); | ||
|  |         [e, d, c, b, a] = [d, c, rol32(b, 30), a, temp]; | ||
|  |       } | ||
|  |       [a, b, c, d, e] = [add32(a, h0), add32(b, h1), add32(c, h2), add32(d, h3), add32(e, h4)]; | ||
|  |     } | ||
|  |     return byteStringToHexString(words32ToByteString([a, b, c, d, e])); | ||
|  |   } | ||
|  |   function add32(a, b) { | ||
|  |     return add32to64(a, b)[1]; | ||
|  |   } | ||
|  |   function add32to64(a, b) { | ||
|  |     const low = (a & 65535) + (b & 65535); | ||
|  |     const high = (a >>> 16) + (b >>> 16) + (low >>> 16); | ||
|  |     return [high >>> 16, high << 16 | low & 65535]; | ||
|  |   } | ||
|  |   function rol32(a, count) { | ||
|  |     return a << count | a >>> 32 - count; | ||
|  |   } | ||
|  |   var Endian; | ||
|  |   (function(Endian2) { | ||
|  |     Endian2[Endian2["Little"] = 0] = "Little"; | ||
|  |     Endian2[Endian2["Big"] = 1] = "Big"; | ||
|  |   })(Endian || (Endian = {})); | ||
|  |   function fk(index, b, c, d) { | ||
|  |     if (index < 20) { | ||
|  |       return [b & c | ~b & d, 1518500249]; | ||
|  |     } | ||
|  |     if (index < 40) { | ||
|  |       return [b ^ c ^ d, 1859775393]; | ||
|  |     } | ||
|  |     if (index < 60) { | ||
|  |       return [b & c | b & d | c & d, 2400959708]; | ||
|  |     } | ||
|  |     return [b ^ c ^ d, 3395469782]; | ||
|  |   } | ||
|  |   function stringToWords32(str, endian) { | ||
|  |     const size = str.length + 3 >>> 2; | ||
|  |     const words32 = []; | ||
|  |     for (let i = 0; i < size; i++) { | ||
|  |       words32[i] = wordAt(str, i * 4, endian); | ||
|  |     } | ||
|  |     return words32; | ||
|  |   } | ||
|  |   function arrayBufferToWords32(buffer, endian) { | ||
|  |     const size = buffer.byteLength + 3 >>> 2; | ||
|  |     const words32 = []; | ||
|  |     const view = new Uint8Array(buffer); | ||
|  |     for (let i = 0; i < size; i++) { | ||
|  |       words32[i] = wordAt(view, i * 4, endian); | ||
|  |     } | ||
|  |     return words32; | ||
|  |   } | ||
|  |   function byteAt(str, index) { | ||
|  |     if (typeof str === "string") { | ||
|  |       return index >= str.length ? 0 : str.charCodeAt(index) & 255; | ||
|  |     } else { | ||
|  |       return index >= str.byteLength ? 0 : str[index] & 255; | ||
|  |     } | ||
|  |   } | ||
|  |   function wordAt(str, index, endian) { | ||
|  |     let word = 0; | ||
|  |     if (endian === Endian.Big) { | ||
|  |       for (let i = 0; i < 4; i++) { | ||
|  |         word += byteAt(str, index + i) << 24 - 8 * i; | ||
|  |       } | ||
|  |     } else { | ||
|  |       for (let i = 0; i < 4; i++) { | ||
|  |         word += byteAt(str, index + i) << 8 * i; | ||
|  |       } | ||
|  |     } | ||
|  |     return word; | ||
|  |   } | ||
|  |   function words32ToByteString(words32) { | ||
|  |     return words32.reduce((str, word) => str + word32ToByteString(word), ""); | ||
|  |   } | ||
|  |   function word32ToByteString(word) { | ||
|  |     let str = ""; | ||
|  |     for (let i = 0; i < 4; i++) { | ||
|  |       str += String.fromCharCode(word >>> 8 * (3 - i) & 255); | ||
|  |     } | ||
|  |     return str; | ||
|  |   } | ||
|  |   function byteStringToHexString(str) { | ||
|  |     let hex = ""; | ||
|  |     for (let i = 0; i < str.length; i++) { | ||
|  |       const b = byteAt(str, i); | ||
|  |       hex += (b >>> 4).toString(16) + (b & 15).toString(16); | ||
|  |     } | ||
|  |     return hex.toLowerCase(); | ||
|  |   } | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/assets.mjs
 | ||
|  |   var AssetGroup = class { | ||
|  |     constructor(scope2, adapter2, idle, config, hashes, db, cacheNamePrefix) { | ||
|  |       this.scope = scope2; | ||
|  |       this.adapter = adapter2; | ||
|  |       this.idle = idle; | ||
|  |       this.config = config; | ||
|  |       this.hashes = hashes; | ||
|  |       this.db = db; | ||
|  |       this.inFlightRequests = /* @__PURE__ */ new Map(); | ||
|  |       this.urls = []; | ||
|  |       this.patterns = []; | ||
|  |       this.name = config.name; | ||
|  |       this.urls = config.urls.map((url) => adapter2.normalizeUrl(url)); | ||
|  |       this.patterns = config.patterns.map((pattern) => new RegExp(pattern)); | ||
|  |       this.cache = adapter2.caches.open(`${cacheNamePrefix}:${config.name}:cache`); | ||
|  |       this.metadata = this.db.open(`${cacheNamePrefix}:${config.name}:meta`, config.cacheQueryOptions); | ||
|  |     } | ||
|  |     async cacheStatus(url) { | ||
|  |       const cache = await this.cache; | ||
|  |       const meta = await this.metadata; | ||
|  |       const req = this.adapter.newRequest(url); | ||
|  |       const res = await cache.match(req, this.config.cacheQueryOptions); | ||
|  |       if (res === void 0) { | ||
|  |         return UpdateCacheStatus.NOT_CACHED; | ||
|  |       } | ||
|  |       try { | ||
|  |         const data = await meta.read(req.url); | ||
|  |         if (!data.used) { | ||
|  |           return UpdateCacheStatus.CACHED_BUT_UNUSED; | ||
|  |         } | ||
|  |       } catch (_) { | ||
|  |       } | ||
|  |       return UpdateCacheStatus.CACHED; | ||
|  |     } | ||
|  |     async getCacheNames() { | ||
|  |       const [cache, metadata] = await Promise.all([this.cache, this.metadata]); | ||
|  |       return [cache.name, metadata.cacheName]; | ||
|  |     } | ||
|  |     async handleFetch(req, _event) { | ||
|  |       const url = this.adapter.normalizeUrl(req.url); | ||
|  |       if (this.urls.indexOf(url) !== -1 || this.patterns.some((pattern) => pattern.test(url))) { | ||
|  |         const cache = await this.cache; | ||
|  |         let cachedResponse; | ||
|  |         try { | ||
|  |           cachedResponse = await cache.match(req, this.config.cacheQueryOptions); | ||
|  |         } catch (error) { | ||
|  |           throw new SwCriticalError(`Cache is throwing while looking for a match: ${error}`); | ||
|  |         } | ||
|  |         if (cachedResponse !== void 0) { | ||
|  |           if (this.hashes.has(url)) { | ||
|  |             return cachedResponse; | ||
|  |           } else { | ||
|  |             if (await this.needToRevalidate(req, cachedResponse)) { | ||
|  |               this.idle.schedule(`revalidate(${cache.name}): ${req.url}`, async () => { | ||
|  |                 await this.fetchAndCacheOnce(req); | ||
|  |               }); | ||
|  |             } | ||
|  |             return cachedResponse; | ||
|  |           } | ||
|  |         } | ||
|  |         const res = await this.fetchAndCacheOnce(this.newRequestWithMetadata(req.url, req)); | ||
|  |         return res.clone(); | ||
|  |       } else { | ||
|  |         return null; | ||
|  |       } | ||
|  |     } | ||
|  |     async needToRevalidate(req, res) { | ||
|  |       if (res.headers.has("Cache-Control")) { | ||
|  |         const cacheControl = res.headers.get("Cache-Control"); | ||
|  |         const cacheDirectives = cacheControl.split(",").map((v) => v.trim()).map((v) => v.split("=")); | ||
|  |         cacheDirectives.forEach((v) => v[0] = v[0].toLowerCase()); | ||
|  |         const maxAgeDirective = cacheDirectives.find((v) => v[0] === "max-age"); | ||
|  |         const cacheAge = maxAgeDirective ? maxAgeDirective[1] : void 0; | ||
|  |         if (!cacheAge) { | ||
|  |           return true; | ||
|  |         } | ||
|  |         try { | ||
|  |           const maxAge = 1e3 * parseInt(cacheAge); | ||
|  |           let ts; | ||
|  |           try { | ||
|  |             const metaTable = await this.metadata; | ||
|  |             ts = (await metaTable.read(req.url)).ts; | ||
|  |           } catch (e) { | ||
|  |             const date = res.headers.get("Date"); | ||
|  |             if (date === null) { | ||
|  |               return true; | ||
|  |             } | ||
|  |             ts = Date.parse(date); | ||
|  |           } | ||
|  |           const age = this.adapter.time - ts; | ||
|  |           return age < 0 || age > maxAge; | ||
|  |         } catch (e) { | ||
|  |           return true; | ||
|  |         } | ||
|  |       } else if (res.headers.has("Expires")) { | ||
|  |         const expiresStr = res.headers.get("Expires"); | ||
|  |         try { | ||
|  |           return this.adapter.time > Date.parse(expiresStr); | ||
|  |         } catch (e) { | ||
|  |           return true; | ||
|  |         } | ||
|  |       } else { | ||
|  |         return true; | ||
|  |       } | ||
|  |     } | ||
|  |     async fetchFromCacheOnly(url) { | ||
|  |       const cache = await this.cache; | ||
|  |       const metaTable = await this.metadata; | ||
|  |       const request = this.adapter.newRequest(url); | ||
|  |       const response = await cache.match(request, this.config.cacheQueryOptions); | ||
|  |       if (response === void 0) { | ||
|  |         return null; | ||
|  |       } | ||
|  |       let metadata = void 0; | ||
|  |       try { | ||
|  |         metadata = await metaTable.read(request.url); | ||
|  |       } catch (e) { | ||
|  |       } | ||
|  |       return { response, metadata }; | ||
|  |     } | ||
|  |     async unhashedResources() { | ||
|  |       const cache = await this.cache; | ||
|  |       return (await cache.keys()).map((request) => this.adapter.normalizeUrl(request.url)).filter((url) => !this.hashes.has(url)); | ||
|  |     } | ||
|  |     async fetchAndCacheOnce(req, used = true) { | ||
|  |       if (this.inFlightRequests.has(req.url)) { | ||
|  |         return this.inFlightRequests.get(req.url); | ||
|  |       } | ||
|  |       const fetchOp = this.fetchFromNetwork(req); | ||
|  |       this.inFlightRequests.set(req.url, fetchOp); | ||
|  |       try { | ||
|  |         const res = await fetchOp; | ||
|  |         if (!res.ok) { | ||
|  |           throw new Error(`Response not Ok (fetchAndCacheOnce): request for ${req.url} returned response ${res.status} ${res.statusText}`); | ||
|  |         } | ||
|  |         try { | ||
|  |           const cache = await this.cache; | ||
|  |           await cache.put(req, res.clone()); | ||
|  |           if (!this.hashes.has(this.adapter.normalizeUrl(req.url))) { | ||
|  |             const meta = { ts: this.adapter.time, used }; | ||
|  |             const metaTable = await this.metadata; | ||
|  |             await metaTable.write(req.url, meta); | ||
|  |           } | ||
|  |           return res; | ||
|  |         } catch (err) { | ||
|  |           throw new SwCriticalError(`Failed to update the caches for request to '${req.url}' (fetchAndCacheOnce): ${errorToString(err)}`); | ||
|  |         } | ||
|  |       } finally { | ||
|  |         this.inFlightRequests.delete(req.url); | ||
|  |       } | ||
|  |     } | ||
|  |     async fetchFromNetwork(req, redirectLimit = 3) { | ||
|  |       const res = await this.cacheBustedFetchFromNetwork(req); | ||
|  |       if (res["redirected"] && !!res.url) { | ||
|  |         if (redirectLimit === 0) { | ||
|  |           throw new SwCriticalError(`Response hit redirect limit (fetchFromNetwork): request redirected too many times, next is ${res.url}`); | ||
|  |         } | ||
|  |         return this.fetchFromNetwork(this.newRequestWithMetadata(res.url, req), redirectLimit - 1); | ||
|  |       } | ||
|  |       return res; | ||
|  |     } | ||
|  |     async cacheBustedFetchFromNetwork(req) { | ||
|  |       const url = this.adapter.normalizeUrl(req.url); | ||
|  |       if (this.hashes.has(url)) { | ||
|  |         const canonicalHash = this.hashes.get(url); | ||
|  |         let response = await this.safeFetch(req); | ||
|  |         let makeCacheBustedRequest = response.ok; | ||
|  |         if (makeCacheBustedRequest) { | ||
|  |           const fetchedHash = sha1Binary(await response.clone().arrayBuffer()); | ||
|  |           makeCacheBustedRequest = fetchedHash !== canonicalHash; | ||
|  |         } | ||
|  |         if (makeCacheBustedRequest) { | ||
|  |           const cacheBustReq = this.newRequestWithMetadata(this.cacheBust(req.url), req); | ||
|  |           response = await this.safeFetch(cacheBustReq); | ||
|  |           if (response.ok) { | ||
|  |             const cacheBustedHash = sha1Binary(await response.clone().arrayBuffer()); | ||
|  |             if (canonicalHash !== cacheBustedHash) { | ||
|  |               throw new SwCriticalError(`Hash mismatch (cacheBustedFetchFromNetwork): ${req.url}: expected ${canonicalHash}, got ${cacheBustedHash} (after cache busting)`); | ||
|  |             } | ||
|  |           } | ||
|  |         } | ||
|  |         if (!response.ok && response.status === 404) { | ||
|  |           throw new SwUnrecoverableStateError(`Failed to retrieve hashed resource from the server. (AssetGroup: ${this.config.name} | URL: ${url})`); | ||
|  |         } | ||
|  |         return response; | ||
|  |       } else { | ||
|  |         return this.safeFetch(req); | ||
|  |       } | ||
|  |     } | ||
|  |     async maybeUpdate(updateFrom, req, cache) { | ||
|  |       const url = this.adapter.normalizeUrl(req.url); | ||
|  |       if (this.hashes.has(url)) { | ||
|  |         const hash = this.hashes.get(url); | ||
|  |         const res = await updateFrom.lookupResourceWithHash(url, hash); | ||
|  |         if (res !== null) { | ||
|  |           await cache.put(req, res); | ||
|  |           return true; | ||
|  |         } | ||
|  |       } | ||
|  |       return false; | ||
|  |     } | ||
|  |     newRequestWithMetadata(url, options) { | ||
|  |       return this.adapter.newRequest(url, { headers: options.headers }); | ||
|  |     } | ||
|  |     cacheBust(url) { | ||
|  |       return url + (url.indexOf("?") === -1 ? "?" : "&") + "ngsw-cache-bust=" + Math.random(); | ||
|  |     } | ||
|  |     async safeFetch(req) { | ||
|  |       try { | ||
|  |         return await this.scope.fetch(req); | ||
|  |       } catch (e) { | ||
|  |         return this.adapter.newResponse("", { | ||
|  |           status: 504, | ||
|  |           statusText: "Gateway Timeout" | ||
|  |         }); | ||
|  |       } | ||
|  |     } | ||
|  |   }; | ||
|  |   var PrefetchAssetGroup = class extends AssetGroup { | ||
|  |     async initializeFully(updateFrom) { | ||
|  |       const cache = await this.cache; | ||
|  |       await this.urls.reduce(async (previous, url) => { | ||
|  |         await previous; | ||
|  |         const req = this.adapter.newRequest(url); | ||
|  |         let alreadyCached = false; | ||
|  |         try { | ||
|  |           alreadyCached = await cache.match(req, this.config.cacheQueryOptions) !== void 0; | ||
|  |         } catch (error) { | ||
|  |           throw new SwCriticalError(`Cache is throwing while looking for a match in a PrefetchAssetGroup: ${error}`); | ||
|  |         } | ||
|  |         if (alreadyCached) { | ||
|  |           return; | ||
|  |         } | ||
|  |         if (updateFrom !== void 0 && await this.maybeUpdate(updateFrom, req, cache)) { | ||
|  |           return; | ||
|  |         } | ||
|  |         await this.fetchAndCacheOnce(req, false); | ||
|  |       }, Promise.resolve()); | ||
|  |       if (updateFrom !== void 0) { | ||
|  |         const metaTable = await this.metadata; | ||
|  |         await (await updateFrom.previouslyCachedResources()).filter((url) => this.urls.indexOf(url) !== -1 || this.patterns.some((pattern) => pattern.test(url))).reduce(async (previous, url) => { | ||
|  |           await previous; | ||
|  |           const req = this.adapter.newRequest(url); | ||
|  |           const alreadyCached = await cache.match(req, this.config.cacheQueryOptions) !== void 0; | ||
|  |           if (alreadyCached) { | ||
|  |             return; | ||
|  |           } | ||
|  |           const res = await updateFrom.lookupResourceWithoutHash(url); | ||
|  |           if (res === null || res.metadata === void 0) { | ||
|  |             return; | ||
|  |           } | ||
|  |           await cache.put(req, res.response); | ||
|  |           await metaTable.write(req.url, __spreadProps(__spreadValues({}, res.metadata), { used: false })); | ||
|  |         }, Promise.resolve()); | ||
|  |       } | ||
|  |     } | ||
|  |   }; | ||
|  |   var LazyAssetGroup = class extends AssetGroup { | ||
|  |     async initializeFully(updateFrom) { | ||
|  |       if (updateFrom === void 0) { | ||
|  |         return; | ||
|  |       } | ||
|  |       const cache = await this.cache; | ||
|  |       await this.urls.reduce(async (previous, url) => { | ||
|  |         await previous; | ||
|  |         const req = this.adapter.newRequest(url); | ||
|  |         let alreadyCached = false; | ||
|  |         try { | ||
|  |           alreadyCached = await cache.match(req, this.config.cacheQueryOptions) !== void 0; | ||
|  |         } catch (error) { | ||
|  |           throw new SwCriticalError(`Cache is throwing while looking for a match in a LazyAssetGroup: ${error}`); | ||
|  |         } | ||
|  |         if (alreadyCached) { | ||
|  |           return; | ||
|  |         } | ||
|  |         const updated = await this.maybeUpdate(updateFrom, req, cache); | ||
|  |         if (this.config.updateMode === "prefetch" && !updated) { | ||
|  |           const cacheStatus = await updateFrom.recentCacheStatus(url); | ||
|  |           if (cacheStatus !== UpdateCacheStatus.CACHED) { | ||
|  |             return; | ||
|  |           } | ||
|  |           await this.fetchAndCacheOnce(req, false); | ||
|  |         } | ||
|  |       }, Promise.resolve()); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/data.mjs
 | ||
|  |   var LruList = class { | ||
|  |     constructor(state) { | ||
|  |       if (state === void 0) { | ||
|  |         state = { | ||
|  |           head: null, | ||
|  |           tail: null, | ||
|  |           map: {}, | ||
|  |           count: 0 | ||
|  |         }; | ||
|  |       } | ||
|  |       this.state = state; | ||
|  |     } | ||
|  |     get size() { | ||
|  |       return this.state.count; | ||
|  |     } | ||
|  |     pop() { | ||
|  |       if (this.state.tail === null) { | ||
|  |         return null; | ||
|  |       } | ||
|  |       const url = this.state.tail; | ||
|  |       this.remove(url); | ||
|  |       return url; | ||
|  |     } | ||
|  |     remove(url) { | ||
|  |       const node = this.state.map[url]; | ||
|  |       if (node === void 0) { | ||
|  |         return false; | ||
|  |       } | ||
|  |       if (this.state.head === url) { | ||
|  |         if (node.next === null) { | ||
|  |           this.state.head = null; | ||
|  |           this.state.tail = null; | ||
|  |           this.state.map = {}; | ||
|  |           this.state.count = 0; | ||
|  |           return true; | ||
|  |         } | ||
|  |         const next = this.state.map[node.next]; | ||
|  |         next.previous = null; | ||
|  |         this.state.head = next.url; | ||
|  |         node.next = null; | ||
|  |         delete this.state.map[url]; | ||
|  |         this.state.count--; | ||
|  |         return true; | ||
|  |       } | ||
|  |       const previous = this.state.map[node.previous]; | ||
|  |       previous.next = node.next; | ||
|  |       if (node.next !== null) { | ||
|  |         this.state.map[node.next].previous = node.previous; | ||
|  |       } else { | ||
|  |         this.state.tail = node.previous; | ||
|  |       } | ||
|  |       node.next = null; | ||
|  |       node.previous = null; | ||
|  |       delete this.state.map[url]; | ||
|  |       this.state.count--; | ||
|  |       return true; | ||
|  |     } | ||
|  |     accessed(url) { | ||
|  |       if (this.state.head === url) { | ||
|  |         return; | ||
|  |       } | ||
|  |       const node = this.state.map[url] || { url, next: null, previous: null }; | ||
|  |       if (this.state.map[url] !== void 0) { | ||
|  |         this.remove(url); | ||
|  |       } | ||
|  |       if (this.state.head !== null) { | ||
|  |         this.state.map[this.state.head].previous = url; | ||
|  |       } | ||
|  |       node.next = this.state.head; | ||
|  |       this.state.head = url; | ||
|  |       if (this.state.tail === null) { | ||
|  |         this.state.tail = url; | ||
|  |       } | ||
|  |       this.state.map[url] = node; | ||
|  |       this.state.count++; | ||
|  |     } | ||
|  |   }; | ||
|  |   var DataGroup = class { | ||
|  |     constructor(scope2, adapter2, config, db, debugHandler, cacheNamePrefix) { | ||
|  |       this.scope = scope2; | ||
|  |       this.adapter = adapter2; | ||
|  |       this.config = config; | ||
|  |       this.db = db; | ||
|  |       this.debugHandler = debugHandler; | ||
|  |       this._lru = null; | ||
|  |       this.patterns = config.patterns.map((pattern) => new RegExp(pattern)); | ||
|  |       this.cache = adapter2.caches.open(`${cacheNamePrefix}:${config.name}:cache`); | ||
|  |       this.lruTable = this.db.open(`${cacheNamePrefix}:${config.name}:lru`, config.cacheQueryOptions); | ||
|  |       this.ageTable = this.db.open(`${cacheNamePrefix}:${config.name}:age`, config.cacheQueryOptions); | ||
|  |     } | ||
|  |     async lru() { | ||
|  |       if (this._lru === null) { | ||
|  |         const table = await this.lruTable; | ||
|  |         try { | ||
|  |           this._lru = new LruList(await table.read("lru")); | ||
|  |         } catch (e) { | ||
|  |           this._lru = new LruList(); | ||
|  |         } | ||
|  |       } | ||
|  |       return this._lru; | ||
|  |     } | ||
|  |     async syncLru() { | ||
|  |       if (this._lru === null) { | ||
|  |         return; | ||
|  |       } | ||
|  |       const table = await this.lruTable; | ||
|  |       try { | ||
|  |         return table.write("lru", this._lru.state); | ||
|  |       } catch (err) { | ||
|  |         this.debugHandler.log(err, `DataGroup(${this.config.name}@${this.config.version}).syncLru()`); | ||
|  |       } | ||
|  |     } | ||
|  |     async handleFetch(req, event) { | ||
|  |       if (!this.patterns.some((pattern) => pattern.test(req.url))) { | ||
|  |         return null; | ||
|  |       } | ||
|  |       const lru = await this.lru(); | ||
|  |       switch (req.method) { | ||
|  |         case "OPTIONS": | ||
|  |           return null; | ||
|  |         case "GET": | ||
|  |         case "HEAD": | ||
|  |           switch (this.config.strategy) { | ||
|  |             case "freshness": | ||
|  |               return this.handleFetchWithFreshness(req, event, lru); | ||
|  |             case "performance": | ||
|  |               return this.handleFetchWithPerformance(req, event, lru); | ||
|  |             default: | ||
|  |               throw new Error(`Unknown strategy: ${this.config.strategy}`); | ||
|  |           } | ||
|  |         default: | ||
|  |           const wasCached = lru.remove(req.url); | ||
|  |           if (wasCached) { | ||
|  |             await this.clearCacheForUrl(req.url); | ||
|  |           } | ||
|  |           await this.syncLru(); | ||
|  |           return this.safeFetch(req); | ||
|  |       } | ||
|  |     } | ||
|  |     async handleFetchWithPerformance(req, event, lru) { | ||
|  |       var _a; | ||
|  |       const okToCacheOpaque = (_a = this.config.cacheOpaqueResponses) != null ? _a : false; | ||
|  |       let res = null; | ||
|  |       const fromCache = await this.loadFromCache(req, lru); | ||
|  |       if (fromCache !== null) { | ||
|  |         res = fromCache.res; | ||
|  |         if (this.config.refreshAheadMs !== void 0 && fromCache.age >= this.config.refreshAheadMs) { | ||
|  |           event.waitUntil(this.safeCacheResponse(req, this.safeFetch(req), lru, okToCacheOpaque)); | ||
|  |         } | ||
|  |       } | ||
|  |       if (res !== null) { | ||
|  |         return res; | ||
|  |       } | ||
|  |       const [timeoutFetch, networkFetch] = this.networkFetchWithTimeout(req); | ||
|  |       res = await timeoutFetch; | ||
|  |       if (res === void 0) { | ||
|  |         res = this.adapter.newResponse(null, { status: 504, statusText: "Gateway Timeout" }); | ||
|  |         event.waitUntil(this.safeCacheResponse(req, networkFetch, lru, okToCacheOpaque)); | ||
|  |       } else { | ||
|  |         await this.safeCacheResponse(req, res, lru, okToCacheOpaque); | ||
|  |       } | ||
|  |       return res; | ||
|  |     } | ||
|  |     async handleFetchWithFreshness(req, event, lru) { | ||
|  |       var _a; | ||
|  |       const okToCacheOpaque = (_a = this.config.cacheOpaqueResponses) != null ? _a : true; | ||
|  |       const [timeoutFetch, networkFetch] = this.networkFetchWithTimeout(req); | ||
|  |       let res; | ||
|  |       try { | ||
|  |         res = await timeoutFetch; | ||
|  |       } catch (e) { | ||
|  |         res = void 0; | ||
|  |       } | ||
|  |       if (res === void 0) { | ||
|  |         event.waitUntil(this.safeCacheResponse(req, networkFetch, lru, okToCacheOpaque)); | ||
|  |         const fromCache = await this.loadFromCache(req, lru); | ||
|  |         res = fromCache !== null ? fromCache.res : null; | ||
|  |       } else { | ||
|  |         await this.safeCacheResponse(req, res, lru, okToCacheOpaque); | ||
|  |       } | ||
|  |       if (res !== null) { | ||
|  |         return res; | ||
|  |       } | ||
|  |       return networkFetch; | ||
|  |     } | ||
|  |     networkFetchWithTimeout(req) { | ||
|  |       if (this.config.timeoutMs !== void 0) { | ||
|  |         const networkFetch = this.scope.fetch(req); | ||
|  |         const safeNetworkFetch = (async () => { | ||
|  |           try { | ||
|  |             return await networkFetch; | ||
|  |           } catch (e) { | ||
|  |             return this.adapter.newResponse(null, { | ||
|  |               status: 504, | ||
|  |               statusText: "Gateway Timeout" | ||
|  |             }); | ||
|  |           } | ||
|  |         })(); | ||
|  |         const networkFetchUndefinedError = (async () => { | ||
|  |           try { | ||
|  |             return await networkFetch; | ||
|  |           } catch (e) { | ||
|  |             return void 0; | ||
|  |           } | ||
|  |         })(); | ||
|  |         const timeout = this.adapter.timeout(this.config.timeoutMs); | ||
|  |         return [Promise.race([networkFetchUndefinedError, timeout]), safeNetworkFetch]; | ||
|  |       } else { | ||
|  |         const networkFetch = this.safeFetch(req); | ||
|  |         return [networkFetch, networkFetch]; | ||
|  |       } | ||
|  |     } | ||
|  |     async safeCacheResponse(req, resOrPromise, lru, okToCacheOpaque) { | ||
|  |       try { | ||
|  |         const res = await resOrPromise; | ||
|  |         try { | ||
|  |           await this.cacheResponse(req, res, lru, okToCacheOpaque); | ||
|  |         } catch (err) { | ||
|  |           this.debugHandler.log(err, `DataGroup(${this.config.name}@${this.config.version}).safeCacheResponse(${req.url}, status: ${res.status})`); | ||
|  |         } | ||
|  |       } catch (e) { | ||
|  |       } | ||
|  |     } | ||
|  |     async loadFromCache(req, lru) { | ||
|  |       const cache = await this.cache; | ||
|  |       let res = await cache.match(req, this.config.cacheQueryOptions); | ||
|  |       if (res !== void 0) { | ||
|  |         try { | ||
|  |           const ageTable = await this.ageTable; | ||
|  |           const age = this.adapter.time - (await ageTable.read(req.url)).age; | ||
|  |           if (age <= this.config.maxAge) { | ||
|  |             lru.accessed(req.url); | ||
|  |             return { res, age }; | ||
|  |           } | ||
|  |         } catch (e) { | ||
|  |         } | ||
|  |         lru.remove(req.url); | ||
|  |         await this.clearCacheForUrl(req.url); | ||
|  |         await this.syncLru(); | ||
|  |       } | ||
|  |       return null; | ||
|  |     } | ||
|  |     async cacheResponse(req, res, lru, okToCacheOpaque = false) { | ||
|  |       if (!(res.ok || okToCacheOpaque && res.type === "opaque")) { | ||
|  |         return; | ||
|  |       } | ||
|  |       if (lru.size >= this.config.maxSize) { | ||
|  |         const evictedUrl = lru.pop(); | ||
|  |         if (evictedUrl !== null) { | ||
|  |           await this.clearCacheForUrl(evictedUrl); | ||
|  |         } | ||
|  |       } | ||
|  |       lru.accessed(req.url); | ||
|  |       await (await this.cache).put(req, res.clone()); | ||
|  |       const ageTable = await this.ageTable; | ||
|  |       await ageTable.write(req.url, { age: this.adapter.time }); | ||
|  |       await this.syncLru(); | ||
|  |     } | ||
|  |     async cleanup() { | ||
|  |       await Promise.all([ | ||
|  |         this.cache.then((cache) => this.adapter.caches.delete(cache.name)), | ||
|  |         this.ageTable.then((table) => this.db.delete(table.name)), | ||
|  |         this.lruTable.then((table) => this.db.delete(table.name)) | ||
|  |       ]); | ||
|  |     } | ||
|  |     async getCacheNames() { | ||
|  |       const [cache, ageTable, lruTable] = await Promise.all([ | ||
|  |         this.cache, | ||
|  |         this.ageTable, | ||
|  |         this.lruTable | ||
|  |       ]); | ||
|  |       return [cache.name, ageTable.cacheName, lruTable.cacheName]; | ||
|  |     } | ||
|  |     async clearCacheForUrl(url) { | ||
|  |       const [cache, ageTable] = await Promise.all([this.cache, this.ageTable]); | ||
|  |       await Promise.all([ | ||
|  |         cache.delete(this.adapter.newRequest(url, { method: "GET" }), this.config.cacheQueryOptions), | ||
|  |         cache.delete(this.adapter.newRequest(url, { method: "HEAD" }), this.config.cacheQueryOptions), | ||
|  |         ageTable.delete(url) | ||
|  |       ]); | ||
|  |     } | ||
|  |     async safeFetch(req) { | ||
|  |       try { | ||
|  |         return this.scope.fetch(req); | ||
|  |       } catch (e) { | ||
|  |         return this.adapter.newResponse(null, { | ||
|  |           status: 504, | ||
|  |           statusText: "Gateway Timeout" | ||
|  |         }); | ||
|  |       } | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/app-version.mjs
 | ||
|  |   var BACKWARDS_COMPATIBILITY_NAVIGATION_URLS = [ | ||
|  |     { positive: true, regex: "^/.*$" }, | ||
|  |     { positive: false, regex: "^/.*\\.[^/]*$" }, | ||
|  |     { positive: false, regex: "^/.*__" } | ||
|  |   ]; | ||
|  |   var AppVersion = class { | ||
|  |     get okay() { | ||
|  |       return this._okay; | ||
|  |     } | ||
|  |     constructor(scope2, adapter2, database, idle, debugHandler, manifest, manifestHash) { | ||
|  |       this.scope = scope2; | ||
|  |       this.adapter = adapter2; | ||
|  |       this.database = database; | ||
|  |       this.debugHandler = debugHandler; | ||
|  |       this.manifest = manifest; | ||
|  |       this.manifestHash = manifestHash; | ||
|  |       this.hashTable = /* @__PURE__ */ new Map(); | ||
|  |       this._okay = true; | ||
|  |       this.indexUrl = this.adapter.normalizeUrl(this.manifest.index); | ||
|  |       Object.keys(manifest.hashTable).forEach((url) => { | ||
|  |         this.hashTable.set(adapter2.normalizeUrl(url), manifest.hashTable[url]); | ||
|  |       }); | ||
|  |       const assetCacheNamePrefix = `${manifestHash}:assets`; | ||
|  |       this.assetGroups = (manifest.assetGroups || []).map((config) => { | ||
|  |         switch (config.installMode) { | ||
|  |           case "prefetch": | ||
|  |             return new PrefetchAssetGroup(scope2, adapter2, idle, config, this.hashTable, database, assetCacheNamePrefix); | ||
|  |           case "lazy": | ||
|  |             return new LazyAssetGroup(scope2, adapter2, idle, config, this.hashTable, database, assetCacheNamePrefix); | ||
|  |         } | ||
|  |       }); | ||
|  |       this.dataGroups = (manifest.dataGroups || []).map((config) => new DataGroup(scope2, adapter2, config, database, debugHandler, `${config.version}:data`)); | ||
|  |       manifest.navigationUrls = manifest.navigationUrls || BACKWARDS_COMPATIBILITY_NAVIGATION_URLS; | ||
|  |       const includeUrls = manifest.navigationUrls.filter((spec) => spec.positive); | ||
|  |       const excludeUrls = manifest.navigationUrls.filter((spec) => !spec.positive); | ||
|  |       this.navigationUrls = { | ||
|  |         include: includeUrls.map((spec) => new RegExp(spec.regex)), | ||
|  |         exclude: excludeUrls.map((spec) => new RegExp(spec.regex)) | ||
|  |       }; | ||
|  |     } | ||
|  |     async initializeFully(updateFrom) { | ||
|  |       try { | ||
|  |         await this.assetGroups.reduce(async (previous, group) => { | ||
|  |           await previous; | ||
|  |           return group.initializeFully(updateFrom); | ||
|  |         }, Promise.resolve()); | ||
|  |       } catch (err) { | ||
|  |         this._okay = false; | ||
|  |         throw err; | ||
|  |       } | ||
|  |     } | ||
|  |     async handleFetch(req, event) { | ||
|  |       const asset = await this.assetGroups.reduce(async (potentialResponse, group) => { | ||
|  |         const resp = await potentialResponse; | ||
|  |         if (resp !== null) { | ||
|  |           return resp; | ||
|  |         } | ||
|  |         return group.handleFetch(req, event); | ||
|  |       }, Promise.resolve(null)); | ||
|  |       if (asset !== null) { | ||
|  |         return asset; | ||
|  |       } | ||
|  |       const data = await this.dataGroups.reduce(async (potentialResponse, group) => { | ||
|  |         const resp = await potentialResponse; | ||
|  |         if (resp !== null) { | ||
|  |           return resp; | ||
|  |         } | ||
|  |         return group.handleFetch(req, event); | ||
|  |       }, Promise.resolve(null)); | ||
|  |       if (data !== null) { | ||
|  |         return data; | ||
|  |       } | ||
|  |       if (this.adapter.normalizeUrl(req.url) !== this.indexUrl && this.isNavigationRequest(req)) { | ||
|  |         if (this.manifest.navigationRequestStrategy === "freshness") { | ||
|  |           try { | ||
|  |             return await this.scope.fetch(req); | ||
|  |           } catch (e) { | ||
|  |           } | ||
|  |         } | ||
|  |         return this.handleFetch(this.adapter.newRequest(this.indexUrl), event); | ||
|  |       } | ||
|  |       return null; | ||
|  |     } | ||
|  |     isNavigationRequest(req) { | ||
|  |       if (req.method !== "GET" || req.mode !== "navigate") { | ||
|  |         return false; | ||
|  |       } | ||
|  |       if (!this.acceptsTextHtml(req)) { | ||
|  |         return false; | ||
|  |       } | ||
|  |       const urlPrefix = this.scope.registration.scope.replace(/\/$/, ""); | ||
|  |       const url = req.url.startsWith(urlPrefix) ? req.url.slice(urlPrefix.length) : req.url; | ||
|  |       const urlWithoutQueryOrHash = url.replace(/[?#].*$/, ""); | ||
|  |       return this.navigationUrls.include.some((regex) => regex.test(urlWithoutQueryOrHash)) && !this.navigationUrls.exclude.some((regex) => regex.test(urlWithoutQueryOrHash)); | ||
|  |     } | ||
|  |     async lookupResourceWithHash(url, hash) { | ||
|  |       if (!this.hashTable.has(url)) { | ||
|  |         return null; | ||
|  |       } | ||
|  |       if (this.hashTable.get(url) !== hash) { | ||
|  |         return null; | ||
|  |       } | ||
|  |       const cacheState = await this.lookupResourceWithoutHash(url); | ||
|  |       return cacheState && cacheState.response; | ||
|  |     } | ||
|  |     lookupResourceWithoutHash(url) { | ||
|  |       return this.assetGroups.reduce(async (potentialResponse, group) => { | ||
|  |         const resp = await potentialResponse; | ||
|  |         if (resp !== null) { | ||
|  |           return resp; | ||
|  |         } | ||
|  |         return group.fetchFromCacheOnly(url); | ||
|  |       }, Promise.resolve(null)); | ||
|  |     } | ||
|  |     previouslyCachedResources() { | ||
|  |       return this.assetGroups.reduce(async (resources, group) => (await resources).concat(await group.unhashedResources()), Promise.resolve([])); | ||
|  |     } | ||
|  |     async recentCacheStatus(url) { | ||
|  |       return this.assetGroups.reduce(async (current, group) => { | ||
|  |         const status = await current; | ||
|  |         if (status === UpdateCacheStatus.CACHED) { | ||
|  |           return status; | ||
|  |         } | ||
|  |         const groupStatus = await group.cacheStatus(url); | ||
|  |         if (groupStatus === UpdateCacheStatus.NOT_CACHED) { | ||
|  |           return status; | ||
|  |         } | ||
|  |         return groupStatus; | ||
|  |       }, Promise.resolve(UpdateCacheStatus.NOT_CACHED)); | ||
|  |     } | ||
|  |     async getCacheNames() { | ||
|  |       const allGroupCacheNames = await Promise.all([ | ||
|  |         ...this.assetGroups.map((group) => group.getCacheNames()), | ||
|  |         ...this.dataGroups.map((group) => group.getCacheNames()) | ||
|  |       ]); | ||
|  |       return [].concat(...allGroupCacheNames); | ||
|  |     } | ||
|  |     get appData() { | ||
|  |       return this.manifest.appData || null; | ||
|  |     } | ||
|  |     acceptsTextHtml(req) { | ||
|  |       const accept = req.headers.get("Accept"); | ||
|  |       if (accept === null) { | ||
|  |         return false; | ||
|  |       } | ||
|  |       const values = accept.split(","); | ||
|  |       return values.some((value) => value.trim().toLowerCase() === "text/html"); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/debug.mjs
 | ||
|  |   var SW_VERSION = "17.3.12"; | ||
|  |   var DEBUG_LOG_BUFFER_SIZE = 100; | ||
|  |   var DebugHandler = class { | ||
|  |     constructor(driver, adapter2) { | ||
|  |       this.driver = driver; | ||
|  |       this.adapter = adapter2; | ||
|  |       this.debugLogA = []; | ||
|  |       this.debugLogB = []; | ||
|  |     } | ||
|  |     async handleFetch(req) { | ||
|  |       const [state, versions, idle] = await Promise.all([ | ||
|  |         this.driver.debugState(), | ||
|  |         this.driver.debugVersions(), | ||
|  |         this.driver.debugIdleState() | ||
|  |       ]); | ||
|  |       const msgState = `NGSW Debug Info:
 | ||
|  | 
 | ||
|  | Driver version: ${SW_VERSION} | ||
|  | Driver state: ${state.state} (${state.why}) | ||
|  | Latest manifest hash: ${state.latestHash || "none"} | ||
|  | Last update check: ${this.since(state.lastUpdateCheck)}`;
 | ||
|  |       const msgVersions = versions.map((version) => `=== Version ${version.hash} ===
 | ||
|  | 
 | ||
|  | Clients: ${version.clients.join(", ")}`).join("\n\n");
 | ||
|  |       const msgIdle = `=== Idle Task Queue ===
 | ||
|  | Last update tick: ${this.since(idle.lastTrigger)} | ||
|  | Last update run: ${this.since(idle.lastRun)} | ||
|  | Task queue: | ||
|  | ${idle.queue.map((v) => " * " + v).join("\n")} | ||
|  | 
 | ||
|  | Debug log: | ||
|  | ${this.formatDebugLog(this.debugLogB)} | ||
|  | ${this.formatDebugLog(this.debugLogA)} | ||
|  | `;
 | ||
|  |       return this.adapter.newResponse(`${msgState}
 | ||
|  | 
 | ||
|  | ${msgVersions} | ||
|  | 
 | ||
|  | ${msgIdle}`, { headers: this.adapter.newHeaders({ "Content-Type": "text/plain" }) });
 | ||
|  |     } | ||
|  |     since(time) { | ||
|  |       if (time === null) { | ||
|  |         return "never"; | ||
|  |       } | ||
|  |       let age = this.adapter.time - time; | ||
|  |       const days = Math.floor(age / 864e5); | ||
|  |       age = age % 864e5; | ||
|  |       const hours = Math.floor(age / 36e5); | ||
|  |       age = age % 36e5; | ||
|  |       const minutes = Math.floor(age / 6e4); | ||
|  |       age = age % 6e4; | ||
|  |       const seconds = Math.floor(age / 1e3); | ||
|  |       const millis = age % 1e3; | ||
|  |       return (days > 0 ? `${days}d` : "") + (hours > 0 ? `${hours}h` : "") + (minutes > 0 ? `${minutes}m` : "") + (seconds > 0 ? `${seconds}s` : "") + (millis > 0 ? `${millis}u` : ""); | ||
|  |     } | ||
|  |     log(value, context = "") { | ||
|  |       if (this.debugLogA.length === DEBUG_LOG_BUFFER_SIZE) { | ||
|  |         this.debugLogB = this.debugLogA; | ||
|  |         this.debugLogA = []; | ||
|  |       } | ||
|  |       if (typeof value !== "string") { | ||
|  |         value = this.errorToString(value); | ||
|  |       } | ||
|  |       this.debugLogA.push({ value, time: this.adapter.time, context }); | ||
|  |     } | ||
|  |     errorToString(err) { | ||
|  |       return `${err.name}(${err.message}, ${err.stack})`; | ||
|  |     } | ||
|  |     formatDebugLog(log) { | ||
|  |       return log.map((entry) => `[${this.since(entry.time)}] ${entry.value} ${entry.context}`).join("\n"); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/idle.mjs
 | ||
|  |   var IdleScheduler = class { | ||
|  |     constructor(adapter2, delay, maxDelay, debug) { | ||
|  |       this.adapter = adapter2; | ||
|  |       this.delay = delay; | ||
|  |       this.maxDelay = maxDelay; | ||
|  |       this.debug = debug; | ||
|  |       this.queue = []; | ||
|  |       this.scheduled = null; | ||
|  |       this.empty = Promise.resolve(); | ||
|  |       this.emptyResolve = null; | ||
|  |       this.lastTrigger = null; | ||
|  |       this.lastRun = null; | ||
|  |       this.oldestScheduledAt = null; | ||
|  |     } | ||
|  |     async trigger() { | ||
|  |       var _a; | ||
|  |       this.lastTrigger = this.adapter.time; | ||
|  |       if (this.queue.length === 0) { | ||
|  |         return; | ||
|  |       } | ||
|  |       if (this.scheduled !== null) { | ||
|  |         this.scheduled.cancel = true; | ||
|  |       } | ||
|  |       const scheduled = { | ||
|  |         cancel: false | ||
|  |       }; | ||
|  |       this.scheduled = scheduled; | ||
|  |       const now = this.adapter.time; | ||
|  |       const maxDelay = Math.max(0, ((_a = this.oldestScheduledAt) != null ? _a : now) + this.maxDelay - now); | ||
|  |       const delay = Math.min(maxDelay, this.delay); | ||
|  |       await this.adapter.timeout(delay); | ||
|  |       if (scheduled.cancel) { | ||
|  |         return; | ||
|  |       } | ||
|  |       this.scheduled = null; | ||
|  |       await this.execute(); | ||
|  |     } | ||
|  |     async execute() { | ||
|  |       this.lastRun = this.adapter.time; | ||
|  |       while (this.queue.length > 0) { | ||
|  |         const queue = this.queue; | ||
|  |         this.queue = []; | ||
|  |         await queue.reduce(async (previous, task) => { | ||
|  |           await previous; | ||
|  |           try { | ||
|  |             await task.run(); | ||
|  |           } catch (err) { | ||
|  |             this.debug.log(err, `while running idle task ${task.desc}`); | ||
|  |           } | ||
|  |         }, Promise.resolve()); | ||
|  |       } | ||
|  |       if (this.emptyResolve !== null) { | ||
|  |         this.emptyResolve(); | ||
|  |         this.emptyResolve = null; | ||
|  |       } | ||
|  |       this.empty = Promise.resolve(); | ||
|  |       this.oldestScheduledAt = null; | ||
|  |     } | ||
|  |     schedule(desc, run) { | ||
|  |       this.queue.push({ desc, run }); | ||
|  |       if (this.emptyResolve === null) { | ||
|  |         this.empty = new Promise((resolve) => { | ||
|  |           this.emptyResolve = resolve; | ||
|  |         }); | ||
|  |       } | ||
|  |       if (this.oldestScheduledAt === null) { | ||
|  |         this.oldestScheduledAt = this.adapter.time; | ||
|  |       } | ||
|  |     } | ||
|  |     get size() { | ||
|  |       return this.queue.length; | ||
|  |     } | ||
|  |     get taskDescriptions() { | ||
|  |       return this.queue.map((task) => task.desc); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/manifest.mjs
 | ||
|  |   function hashManifest(manifest) { | ||
|  |     return sha1(JSON.stringify(manifest)); | ||
|  |   } | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/msg.mjs
 | ||
|  |   function isMsgCheckForUpdates(msg) { | ||
|  |     return msg.action === "CHECK_FOR_UPDATES"; | ||
|  |   } | ||
|  |   function isMsgActivateUpdate(msg) { | ||
|  |     return msg.action === "ACTIVATE_UPDATE"; | ||
|  |   } | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/driver.mjs
 | ||
|  |   var IDLE_DELAY = 5e3; | ||
|  |   var MAX_IDLE_DELAY = 3e4; | ||
|  |   var SUPPORTED_CONFIG_VERSION = 1; | ||
|  |   var NOTIFICATION_OPTION_NAMES = [ | ||
|  |     "actions", | ||
|  |     "badge", | ||
|  |     "body", | ||
|  |     "data", | ||
|  |     "dir", | ||
|  |     "icon", | ||
|  |     "image", | ||
|  |     "lang", | ||
|  |     "renotify", | ||
|  |     "requireInteraction", | ||
|  |     "silent", | ||
|  |     "tag", | ||
|  |     "timestamp", | ||
|  |     "title", | ||
|  |     "vibrate" | ||
|  |   ]; | ||
|  |   var DriverReadyState; | ||
|  |   (function(DriverReadyState2) { | ||
|  |     DriverReadyState2[DriverReadyState2["NORMAL"] = 0] = "NORMAL"; | ||
|  |     DriverReadyState2[DriverReadyState2["EXISTING_CLIENTS_ONLY"] = 1] = "EXISTING_CLIENTS_ONLY"; | ||
|  |     DriverReadyState2[DriverReadyState2["SAFE_MODE"] = 2] = "SAFE_MODE"; | ||
|  |   })(DriverReadyState || (DriverReadyState = {})); | ||
|  |   var Driver = class { | ||
|  |     constructor(scope2, adapter2, db) { | ||
|  |       this.scope = scope2; | ||
|  |       this.adapter = adapter2; | ||
|  |       this.db = db; | ||
|  |       this.state = DriverReadyState.NORMAL; | ||
|  |       this.stateMessage = "(nominal)"; | ||
|  |       this.initialized = null; | ||
|  |       this.clientVersionMap = /* @__PURE__ */ new Map(); | ||
|  |       this.versions = /* @__PURE__ */ new Map(); | ||
|  |       this.latestHash = null; | ||
|  |       this.lastUpdateCheck = null; | ||
|  |       this.scheduledNavUpdateCheck = false; | ||
|  |       this.loggedInvalidOnlyIfCachedRequest = false; | ||
|  |       this.controlTable = this.db.open("control"); | ||
|  |       this.ngswStatePath = this.adapter.parseUrl("ngsw/state", this.scope.registration.scope).path; | ||
|  |       this.scope.addEventListener("install", (event) => { | ||
|  |         event.waitUntil(this.scope.skipWaiting()); | ||
|  |       }); | ||
|  |       this.scope.addEventListener("activate", (event) => { | ||
|  |         event.waitUntil((async () => { | ||
|  |           await this.scope.clients.claim(); | ||
|  |           this.idle.schedule("activate: cleanup-old-sw-caches", async () => { | ||
|  |             try { | ||
|  |               await this.cleanupOldSwCaches(); | ||
|  |             } catch (err) { | ||
|  |               this.debugger.log(err, "cleanupOldSwCaches @ activate: cleanup-old-sw-caches"); | ||
|  |             } | ||
|  |           }); | ||
|  |         })()); | ||
|  |         if (this.scope.registration.active !== null) { | ||
|  |           this.scope.registration.active.postMessage({ action: "INITIALIZE" }); | ||
|  |         } | ||
|  |       }); | ||
|  |       this.scope.addEventListener("fetch", (event) => this.onFetch(event)); | ||
|  |       this.scope.addEventListener("message", (event) => this.onMessage(event)); | ||
|  |       this.scope.addEventListener("push", (event) => this.onPush(event)); | ||
|  |       this.scope.addEventListener("notificationclick", (event) => this.onClick(event)); | ||
|  |       this.debugger = new DebugHandler(this, this.adapter); | ||
|  |       this.idle = new IdleScheduler(this.adapter, IDLE_DELAY, MAX_IDLE_DELAY, this.debugger); | ||
|  |     } | ||
|  |     onFetch(event) { | ||
|  |       const req = event.request; | ||
|  |       const scopeUrl = this.scope.registration.scope; | ||
|  |       const requestUrlObj = this.adapter.parseUrl(req.url, scopeUrl); | ||
|  |       if (req.headers.has("ngsw-bypass") || /[?&]ngsw-bypass(?:[=&]|$)/i.test(requestUrlObj.search)) { | ||
|  |         return; | ||
|  |       } | ||
|  |       if (requestUrlObj.path === this.ngswStatePath) { | ||
|  |         event.respondWith(this.debugger.handleFetch(req)); | ||
|  |         return; | ||
|  |       } | ||
|  |       if (this.state === DriverReadyState.SAFE_MODE) { | ||
|  |         event.waitUntil(this.idle.trigger()); | ||
|  |         return; | ||
|  |       } | ||
|  |       if (requestUrlObj.origin.startsWith("http:") && scopeUrl.startsWith("https:")) { | ||
|  |         this.debugger.log(`Ignoring passive mixed content request: Driver.fetch(${req.url})`); | ||
|  |         return; | ||
|  |       } | ||
|  |       if (req.cache === "only-if-cached" && req.mode !== "same-origin") { | ||
|  |         if (!this.loggedInvalidOnlyIfCachedRequest) { | ||
|  |           this.loggedInvalidOnlyIfCachedRequest = true; | ||
|  |           this.debugger.log(`Ignoring invalid request: 'only-if-cached' can be set only with 'same-origin' mode`, `Driver.fetch(${req.url}, cache: ${req.cache}, mode: ${req.mode})`); | ||
|  |         } | ||
|  |         return; | ||
|  |       } | ||
|  |       event.respondWith(this.handleFetch(event)); | ||
|  |     } | ||
|  |     onMessage(event) { | ||
|  |       if (this.state === DriverReadyState.SAFE_MODE) { | ||
|  |         return; | ||
|  |       } | ||
|  |       const data = event.data; | ||
|  |       if (!data || !data.action) { | ||
|  |         return; | ||
|  |       } | ||
|  |       event.waitUntil((async () => { | ||
|  |         if (data.action === "INITIALIZE") { | ||
|  |           return this.ensureInitialized(event); | ||
|  |         } | ||
|  |         if (!this.adapter.isClient(event.source)) { | ||
|  |           return; | ||
|  |         } | ||
|  |         await this.ensureInitialized(event); | ||
|  |         await this.handleMessage(data, event.source); | ||
|  |       })()); | ||
|  |     } | ||
|  |     onPush(msg) { | ||
|  |       if (!msg.data) { | ||
|  |         return; | ||
|  |       } | ||
|  |       msg.waitUntil(this.handlePush(msg.data.json())); | ||
|  |     } | ||
|  |     onClick(event) { | ||
|  |       event.waitUntil(this.handleClick(event.notification, event.action)); | ||
|  |     } | ||
|  |     async ensureInitialized(event) { | ||
|  |       if (this.initialized !== null) { | ||
|  |         return this.initialized; | ||
|  |       } | ||
|  |       try { | ||
|  |         this.initialized = this.initialize(); | ||
|  |         await this.initialized; | ||
|  |       } catch (error) { | ||
|  |         this.state = DriverReadyState.SAFE_MODE; | ||
|  |         this.stateMessage = `Initialization failed due to error: ${errorToString(error)}`; | ||
|  |         throw error; | ||
|  |       } finally { | ||
|  |         event.waitUntil(this.idle.trigger()); | ||
|  |       } | ||
|  |     } | ||
|  |     async handleMessage(msg, from) { | ||
|  |       if (isMsgCheckForUpdates(msg)) { | ||
|  |         const action = this.checkForUpdate(); | ||
|  |         await this.completeOperation(from, action, msg.nonce); | ||
|  |       } else if (isMsgActivateUpdate(msg)) { | ||
|  |         const action = this.updateClient(from); | ||
|  |         await this.completeOperation(from, action, msg.nonce); | ||
|  |       } | ||
|  |     } | ||
|  |     async handlePush(data) { | ||
|  |       await this.broadcast({ | ||
|  |         type: "PUSH", | ||
|  |         data | ||
|  |       }); | ||
|  |       if (!data.notification || !data.notification.title) { | ||
|  |         return; | ||
|  |       } | ||
|  |       const desc = data.notification; | ||
|  |       let options = {}; | ||
|  |       NOTIFICATION_OPTION_NAMES.filter((name) => desc.hasOwnProperty(name)).forEach((name) => options[name] = desc[name]); | ||
|  |       await this.scope.registration.showNotification(desc["title"], options); | ||
|  |     } | ||
|  |     async handleClick(notification, action) { | ||
|  |       var _a, _b, _c; | ||
|  |       notification.close(); | ||
|  |       const options = {}; | ||
|  |       NOTIFICATION_OPTION_NAMES.filter((name) => name in notification).forEach((name) => options[name] = notification[name]); | ||
|  |       const notificationAction = action === "" || action === void 0 ? "default" : action; | ||
|  |       const onActionClick = (_b = (_a = notification == null ? void 0 : notification.data) == null ? void 0 : _a.onActionClick) == null ? void 0 : _b[notificationAction]; | ||
|  |       const urlToOpen = new URL((_c = onActionClick == null ? void 0 : onActionClick.url) != null ? _c : "", this.scope.registration.scope).href; | ||
|  |       switch (onActionClick == null ? void 0 : onActionClick.operation) { | ||
|  |         case "openWindow": | ||
|  |           await this.scope.clients.openWindow(urlToOpen); | ||
|  |           break; | ||
|  |         case "focusLastFocusedOrOpen": { | ||
|  |           let matchingClient = await this.getLastFocusedMatchingClient(this.scope); | ||
|  |           if (matchingClient) { | ||
|  |             await (matchingClient == null ? void 0 : matchingClient.focus()); | ||
|  |           } else { | ||
|  |             await this.scope.clients.openWindow(urlToOpen); | ||
|  |           } | ||
|  |           break; | ||
|  |         } | ||
|  |         case "navigateLastFocusedOrOpen": { | ||
|  |           let matchingClient = await this.getLastFocusedMatchingClient(this.scope); | ||
|  |           if (matchingClient) { | ||
|  |             matchingClient = await matchingClient.navigate(urlToOpen); | ||
|  |             await (matchingClient == null ? void 0 : matchingClient.focus()); | ||
|  |           } else { | ||
|  |             await this.scope.clients.openWindow(urlToOpen); | ||
|  |           } | ||
|  |           break; | ||
|  |         } | ||
|  |         case "sendRequest": { | ||
|  |           await this.scope.fetch(urlToOpen); | ||
|  |           break; | ||
|  |         } | ||
|  |         default: | ||
|  |           break; | ||
|  |       } | ||
|  |       await this.broadcast({ | ||
|  |         type: "NOTIFICATION_CLICK", | ||
|  |         data: { action, notification: options } | ||
|  |       }); | ||
|  |     } | ||
|  |     async getLastFocusedMatchingClient(scope2) { | ||
|  |       const windowClients = await scope2.clients.matchAll({ type: "window" }); | ||
|  |       return windowClients[0]; | ||
|  |     } | ||
|  |     async completeOperation(client, promise, nonce) { | ||
|  |       const response = { type: "OPERATION_COMPLETED", nonce }; | ||
|  |       try { | ||
|  |         client.postMessage(__spreadProps(__spreadValues({}, response), { | ||
|  |           result: await promise | ||
|  |         })); | ||
|  |       } catch (e) { | ||
|  |         client.postMessage(__spreadProps(__spreadValues({}, response), { | ||
|  |           error: e.toString() | ||
|  |         })); | ||
|  |       } | ||
|  |     } | ||
|  |     async updateClient(client) { | ||
|  |       const existing = this.clientVersionMap.get(client.id); | ||
|  |       if (existing === this.latestHash) { | ||
|  |         return false; | ||
|  |       } | ||
|  |       let previous = void 0; | ||
|  |       if (existing !== void 0) { | ||
|  |         const existingVersion = this.versions.get(existing); | ||
|  |         previous = this.mergeHashWithAppData(existingVersion.manifest, existing); | ||
|  |       } | ||
|  |       this.clientVersionMap.set(client.id, this.latestHash); | ||
|  |       await this.sync(); | ||
|  |       const current = this.versions.get(this.latestHash); | ||
|  |       return true; | ||
|  |     } | ||
|  |     async handleFetch(event) { | ||
|  |       try { | ||
|  |         await this.ensureInitialized(event); | ||
|  |       } catch (e) { | ||
|  |         return this.safeFetch(event.request); | ||
|  |       } | ||
|  |       if (event.request.mode === "navigate" && !this.scheduledNavUpdateCheck) { | ||
|  |         this.scheduledNavUpdateCheck = true; | ||
|  |         this.idle.schedule("check-updates-on-navigation", async () => { | ||
|  |           this.scheduledNavUpdateCheck = false; | ||
|  |           await this.checkForUpdate(); | ||
|  |         }); | ||
|  |       } | ||
|  |       const appVersion = await this.assignVersion(event); | ||
|  |       let res = null; | ||
|  |       try { | ||
|  |         if (appVersion !== null) { | ||
|  |           try { | ||
|  |             res = await appVersion.handleFetch(event.request, event); | ||
|  |           } catch (err) { | ||
|  |             if (err.isUnrecoverableState) { | ||
|  |               await this.notifyClientsAboutUnrecoverableState(appVersion, err.message); | ||
|  |             } | ||
|  |             if (err.isCritical) { | ||
|  |               this.debugger.log(err, `Driver.handleFetch(version: ${appVersion.manifestHash})`); | ||
|  |               await this.versionFailed(appVersion, err); | ||
|  |               return this.safeFetch(event.request); | ||
|  |             } | ||
|  |             throw err; | ||
|  |           } | ||
|  |         } | ||
|  |         if (res === null) { | ||
|  |           return this.safeFetch(event.request); | ||
|  |         } | ||
|  |         return res; | ||
|  |       } finally { | ||
|  |         event.waitUntil(this.idle.trigger()); | ||
|  |       } | ||
|  |     } | ||
|  |     async initialize() { | ||
|  |       const table = await this.controlTable; | ||
|  |       let manifests, assignments, latest; | ||
|  |       try { | ||
|  |         [manifests, assignments, latest] = await Promise.all([ | ||
|  |           table.read("manifests"), | ||
|  |           table.read("assignments"), | ||
|  |           table.read("latest") | ||
|  |         ]); | ||
|  |         if (!this.versions.has(latest.latest) && !manifests.hasOwnProperty(latest.latest)) { | ||
|  |           this.debugger.log(`Missing manifest for latest version hash ${latest.latest}`, "initialize: read from DB"); | ||
|  |           throw new Error(`Missing manifest for latest hash ${latest.latest}`); | ||
|  |         } | ||
|  |         this.idle.schedule("init post-load (update)", async () => { | ||
|  |           await this.checkForUpdate(); | ||
|  |         }); | ||
|  |       } catch (_) { | ||
|  |         const manifest = await this.fetchLatestManifest(); | ||
|  |         const hash = hashManifest(manifest); | ||
|  |         manifests = { [hash]: manifest }; | ||
|  |         assignments = {}; | ||
|  |         latest = { latest: hash }; | ||
|  |         await Promise.all([ | ||
|  |           table.write("manifests", manifests), | ||
|  |           table.write("assignments", assignments), | ||
|  |           table.write("latest", latest) | ||
|  |         ]); | ||
|  |       } | ||
|  |       this.idle.schedule("init post-load (cleanup)", async () => { | ||
|  |         await this.cleanupCaches(); | ||
|  |       }); | ||
|  |       Object.keys(manifests).forEach((hash) => { | ||
|  |         const manifest = manifests[hash]; | ||
|  |         if (!this.versions.has(hash)) { | ||
|  |           this.versions.set(hash, new AppVersion(this.scope, this.adapter, this.db, this.idle, this.debugger, manifest, hash)); | ||
|  |         } | ||
|  |       }); | ||
|  |       Object.keys(assignments).forEach((clientId) => { | ||
|  |         const hash = assignments[clientId]; | ||
|  |         if (this.versions.has(hash)) { | ||
|  |           this.clientVersionMap.set(clientId, hash); | ||
|  |         } else { | ||
|  |           this.clientVersionMap.set(clientId, latest.latest); | ||
|  |           this.debugger.log(`Unknown version ${hash} mapped for client ${clientId}, using latest instead`, `initialize: map assignments`); | ||
|  |         } | ||
|  |       }); | ||
|  |       this.latestHash = latest.latest; | ||
|  |       if (!this.versions.has(latest.latest)) { | ||
|  |         throw new Error(`Invariant violated (initialize): latest hash ${latest.latest} has no known manifest`); | ||
|  |       } | ||
|  |       await Promise.all(Object.keys(manifests).map(async (hash) => { | ||
|  |         try { | ||
|  |           await this.scheduleInitialization(this.versions.get(hash)); | ||
|  |         } catch (err) { | ||
|  |           this.debugger.log(err, `initialize: schedule init of ${hash}`); | ||
|  |         } | ||
|  |       })); | ||
|  |     } | ||
|  |     lookupVersionByHash(hash, debugName = "lookupVersionByHash") { | ||
|  |       if (!this.versions.has(hash)) { | ||
|  |         throw new Error(`Invariant violated (${debugName}): want AppVersion for ${hash} but not loaded`); | ||
|  |       } | ||
|  |       return this.versions.get(hash); | ||
|  |     } | ||
|  |     async assignVersion(event) { | ||
|  |       const clientId = event.resultingClientId || event.clientId; | ||
|  |       if (clientId) { | ||
|  |         if (this.clientVersionMap.has(clientId)) { | ||
|  |           const hash = this.clientVersionMap.get(clientId); | ||
|  |           let appVersion = this.lookupVersionByHash(hash, "assignVersion"); | ||
|  |           if (this.state === DriverReadyState.NORMAL && hash !== this.latestHash && appVersion.isNavigationRequest(event.request)) { | ||
|  |             if (this.latestHash === null) { | ||
|  |               throw new Error(`Invariant violated (assignVersion): latestHash was null`); | ||
|  |             } | ||
|  |             const client = await this.scope.clients.get(clientId); | ||
|  |             if (client) { | ||
|  |               await this.updateClient(client); | ||
|  |             } | ||
|  |             appVersion = this.lookupVersionByHash(this.latestHash, "assignVersion"); | ||
|  |           } | ||
|  |           return appVersion; | ||
|  |         } else { | ||
|  |           if (this.state !== DriverReadyState.NORMAL) { | ||
|  |             return null; | ||
|  |           } | ||
|  |           if (this.latestHash === null) { | ||
|  |             throw new Error(`Invariant violated (assignVersion): latestHash was null`); | ||
|  |           } | ||
|  |           this.clientVersionMap.set(clientId, this.latestHash); | ||
|  |           await this.sync(); | ||
|  |           return this.lookupVersionByHash(this.latestHash, "assignVersion"); | ||
|  |         } | ||
|  |       } else { | ||
|  |         if (this.state !== DriverReadyState.NORMAL) { | ||
|  |           return null; | ||
|  |         } | ||
|  |         if (this.latestHash === null) { | ||
|  |           throw new Error(`Invariant violated (assignVersion): latestHash was null`); | ||
|  |         } | ||
|  |         return this.lookupVersionByHash(this.latestHash, "assignVersion"); | ||
|  |       } | ||
|  |     } | ||
|  |     async fetchLatestManifest(ignoreOfflineError = false) { | ||
|  |       const res = await this.safeFetch(this.adapter.newRequest("ngsw.json?ngsw-cache-bust=" + Math.random())); | ||
|  |       if (!res.ok) { | ||
|  |         if (res.status === 404) { | ||
|  |           await this.deleteAllCaches(); | ||
|  |           await this.scope.registration.unregister(); | ||
|  |         } else if ((res.status === 503 || res.status === 504) && ignoreOfflineError) { | ||
|  |           return null; | ||
|  |         } | ||
|  |         throw new Error(`Manifest fetch failed! (status: ${res.status})`); | ||
|  |       } | ||
|  |       this.lastUpdateCheck = this.adapter.time; | ||
|  |       return res.json(); | ||
|  |     } | ||
|  |     async deleteAllCaches() { | ||
|  |       const cacheNames = await this.adapter.caches.keys(); | ||
|  |       await Promise.all(cacheNames.map((name) => this.adapter.caches.delete(name))); | ||
|  |     } | ||
|  |     async scheduleInitialization(appVersion) { | ||
|  |       const initialize = async () => { | ||
|  |         try { | ||
|  |           await appVersion.initializeFully(); | ||
|  |         } catch (err) { | ||
|  |           this.debugger.log(err, `initializeFully for ${appVersion.manifestHash}`); | ||
|  |           await this.versionFailed(appVersion, err); | ||
|  |         } | ||
|  |       }; | ||
|  |       if (this.scope.registration.scope.indexOf("://localhost") > -1) { | ||
|  |         return initialize(); | ||
|  |       } | ||
|  |       this.idle.schedule(`initialization(${appVersion.manifestHash})`, initialize); | ||
|  |     } | ||
|  |     async versionFailed(appVersion, err) { | ||
|  |       const broken = Array.from(this.versions.entries()).find(([hash, version]) => version === appVersion); | ||
|  |       if (broken === void 0) { | ||
|  |         return; | ||
|  |       } | ||
|  |       const brokenHash = broken[0]; | ||
|  |       if (this.latestHash === brokenHash) { | ||
|  |         this.state = DriverReadyState.EXISTING_CLIENTS_ONLY; | ||
|  |         this.stateMessage = `Degraded due to: ${errorToString(err)}`; | ||
|  |       } | ||
|  |     } | ||
|  |     async setupUpdate(manifest, hash) { | ||
|  |       try { | ||
|  |         const newVersion = new AppVersion(this.scope, this.adapter, this.db, this.idle, this.debugger, manifest, hash); | ||
|  |         if (manifest.configVersion !== SUPPORTED_CONFIG_VERSION) { | ||
|  |           await this.deleteAllCaches(); | ||
|  |           await this.scope.registration.unregister(); | ||
|  |           throw new Error(`Invalid config version: expected ${SUPPORTED_CONFIG_VERSION}, got ${manifest.configVersion}.`); | ||
|  |         } | ||
|  |         await newVersion.initializeFully(this); | ||
|  |         this.versions.set(hash, newVersion); | ||
|  |         this.latestHash = hash; | ||
|  |         if (this.state === DriverReadyState.EXISTING_CLIENTS_ONLY) { | ||
|  |           this.state = DriverReadyState.NORMAL; | ||
|  |           this.stateMessage = "(nominal)"; | ||
|  |         } | ||
|  |         await this.sync(); | ||
|  |         await this.notifyClientsAboutVersionReady(manifest, hash); | ||
|  |       } catch (e) { | ||
|  |         await this.notifyClientsAboutVersionInstallationFailed(manifest, hash, e); | ||
|  |         throw e; | ||
|  |       } | ||
|  |     } | ||
|  |     async checkForUpdate() { | ||
|  |       let hash = "(unknown)"; | ||
|  |       try { | ||
|  |         const manifest = await this.fetchLatestManifest(true); | ||
|  |         if (manifest === null) { | ||
|  |           this.debugger.log("Check for update aborted. (Client or server offline.)"); | ||
|  |           return false; | ||
|  |         } | ||
|  |         hash = hashManifest(manifest); | ||
|  |         if (this.versions.has(hash)) { | ||
|  |           await this.notifyClientsAboutNoNewVersionDetected(manifest, hash); | ||
|  |           return false; | ||
|  |         } | ||
|  |         await this.notifyClientsAboutVersionDetected(manifest, hash); | ||
|  |         await this.setupUpdate(manifest, hash); | ||
|  |         return true; | ||
|  |       } catch (err) { | ||
|  |         this.debugger.log(err, `Error occurred while updating to manifest ${hash}`); | ||
|  |         this.state = DriverReadyState.EXISTING_CLIENTS_ONLY; | ||
|  |         this.stateMessage = `Degraded due to failed initialization: ${errorToString(err)}`; | ||
|  |         return false; | ||
|  |       } | ||
|  |     } | ||
|  |     async sync() { | ||
|  |       const table = await this.controlTable; | ||
|  |       const manifests = {}; | ||
|  |       this.versions.forEach((version, hash) => { | ||
|  |         manifests[hash] = version.manifest; | ||
|  |       }); | ||
|  |       const assignments = {}; | ||
|  |       this.clientVersionMap.forEach((hash, clientId) => { | ||
|  |         assignments[clientId] = hash; | ||
|  |       }); | ||
|  |       const latest = { | ||
|  |         latest: this.latestHash | ||
|  |       }; | ||
|  |       await Promise.all([ | ||
|  |         table.write("manifests", manifests), | ||
|  |         table.write("assignments", assignments), | ||
|  |         table.write("latest", latest) | ||
|  |       ]); | ||
|  |     } | ||
|  |     async cleanupCaches() { | ||
|  |       try { | ||
|  |         const activeClients = new Set((await this.scope.clients.matchAll()).map((client) => client.id)); | ||
|  |         const knownClients = Array.from(this.clientVersionMap.keys()); | ||
|  |         const obsoleteClients = knownClients.filter((id) => !activeClients.has(id)); | ||
|  |         obsoleteClients.forEach((id) => this.clientVersionMap.delete(id)); | ||
|  |         const usedVersions = new Set(this.clientVersionMap.values()); | ||
|  |         const obsoleteVersions = Array.from(this.versions.keys()).filter((version) => !usedVersions.has(version) && version !== this.latestHash); | ||
|  |         obsoleteVersions.forEach((version) => this.versions.delete(version)); | ||
|  |         await this.sync(); | ||
|  |         const allCaches = await this.adapter.caches.keys(); | ||
|  |         const usedCaches = new Set(await this.getCacheNames()); | ||
|  |         const cachesToDelete = allCaches.filter((name) => !usedCaches.has(name)); | ||
|  |         await Promise.all(cachesToDelete.map((name) => this.adapter.caches.delete(name))); | ||
|  |       } catch (err) { | ||
|  |         this.debugger.log(err, "cleanupCaches"); | ||
|  |       } | ||
|  |     } | ||
|  |     async cleanupOldSwCaches() { | ||
|  |       const caches = this.adapter.caches.original; | ||
|  |       const cacheNames = await caches.keys(); | ||
|  |       const oldSwCacheNames = cacheNames.filter((name) => /^ngsw:(?!\/)/.test(name)); | ||
|  |       await Promise.all(oldSwCacheNames.map((name) => caches.delete(name))); | ||
|  |     } | ||
|  |     lookupResourceWithHash(url, hash) { | ||
|  |       return Array.from(this.versions.values()).reduce(async (prev, version) => { | ||
|  |         if (await prev !== null) { | ||
|  |           return prev; | ||
|  |         } | ||
|  |         return version.lookupResourceWithHash(url, hash); | ||
|  |       }, Promise.resolve(null)); | ||
|  |     } | ||
|  |     async lookupResourceWithoutHash(url) { | ||
|  |       await this.initialized; | ||
|  |       const version = this.versions.get(this.latestHash); | ||
|  |       return version ? version.lookupResourceWithoutHash(url) : null; | ||
|  |     } | ||
|  |     async previouslyCachedResources() { | ||
|  |       await this.initialized; | ||
|  |       const version = this.versions.get(this.latestHash); | ||
|  |       return version ? version.previouslyCachedResources() : []; | ||
|  |     } | ||
|  |     async recentCacheStatus(url) { | ||
|  |       const version = this.versions.get(this.latestHash); | ||
|  |       return version ? version.recentCacheStatus(url) : UpdateCacheStatus.NOT_CACHED; | ||
|  |     } | ||
|  |     mergeHashWithAppData(manifest, hash) { | ||
|  |       return { | ||
|  |         hash, | ||
|  |         appData: manifest.appData | ||
|  |       }; | ||
|  |     } | ||
|  |     async notifyClientsAboutUnrecoverableState(appVersion, reason) { | ||
|  |       const broken = Array.from(this.versions.entries()).find(([hash, version]) => version === appVersion); | ||
|  |       if (broken === void 0) { | ||
|  |         return; | ||
|  |       } | ||
|  |       const brokenHash = broken[0]; | ||
|  |       const affectedClients = Array.from(this.clientVersionMap.entries()).filter(([clientId, hash]) => hash === brokenHash).map(([clientId]) => clientId); | ||
|  |       await Promise.all(affectedClients.map(async (clientId) => { | ||
|  |         const client = await this.scope.clients.get(clientId); | ||
|  |         if (client) { | ||
|  |           client.postMessage({ type: "UNRECOVERABLE_STATE", reason }); | ||
|  |         } | ||
|  |       })); | ||
|  |     } | ||
|  |     async notifyClientsAboutVersionInstallationFailed(manifest, hash, error) { | ||
|  |       await this.initialized; | ||
|  |       const clients = await this.scope.clients.matchAll(); | ||
|  |       await Promise.all(clients.map(async (client) => { | ||
|  |         client.postMessage({ | ||
|  |           type: "VERSION_INSTALLATION_FAILED", | ||
|  |           version: this.mergeHashWithAppData(manifest, hash), | ||
|  |           error: errorToString(error) | ||
|  |         }); | ||
|  |       })); | ||
|  |     } | ||
|  |     async notifyClientsAboutNoNewVersionDetected(manifest, hash) { | ||
|  |       await this.initialized; | ||
|  |       const clients = await this.scope.clients.matchAll(); | ||
|  |       await Promise.all(clients.map(async (client) => { | ||
|  |         client.postMessage({ | ||
|  |           type: "NO_NEW_VERSION_DETECTED", | ||
|  |           version: this.mergeHashWithAppData(manifest, hash) | ||
|  |         }); | ||
|  |       })); | ||
|  |     } | ||
|  |     async notifyClientsAboutVersionDetected(manifest, hash) { | ||
|  |       await this.initialized; | ||
|  |       const clients = await this.scope.clients.matchAll(); | ||
|  |       await Promise.all(clients.map(async (client) => { | ||
|  |         const version = this.clientVersionMap.get(client.id); | ||
|  |         if (version === void 0) { | ||
|  |           return; | ||
|  |         } | ||
|  |         client.postMessage({ | ||
|  |           type: "VERSION_DETECTED", | ||
|  |           version: this.mergeHashWithAppData(manifest, hash) | ||
|  |         }); | ||
|  |       })); | ||
|  |     } | ||
|  |     async notifyClientsAboutVersionReady(manifest, hash) { | ||
|  |       await this.initialized; | ||
|  |       const clients = await this.scope.clients.matchAll(); | ||
|  |       await Promise.all(clients.map(async (client) => { | ||
|  |         const version = this.clientVersionMap.get(client.id); | ||
|  |         if (version === void 0) { | ||
|  |           return; | ||
|  |         } | ||
|  |         if (version === this.latestHash) { | ||
|  |           return; | ||
|  |         } | ||
|  |         const current = this.versions.get(version); | ||
|  |         const notice = { | ||
|  |           type: "VERSION_READY", | ||
|  |           currentVersion: this.mergeHashWithAppData(current.manifest, version), | ||
|  |           latestVersion: this.mergeHashWithAppData(manifest, hash) | ||
|  |         }; | ||
|  |         client.postMessage(notice); | ||
|  |       })); | ||
|  |     } | ||
|  |     async broadcast(msg) { | ||
|  |       const clients = await this.scope.clients.matchAll(); | ||
|  |       clients.forEach((client) => { | ||
|  |         client.postMessage(msg); | ||
|  |       }); | ||
|  |     } | ||
|  |     async debugState() { | ||
|  |       return { | ||
|  |         state: DriverReadyState[this.state], | ||
|  |         why: this.stateMessage, | ||
|  |         latestHash: this.latestHash, | ||
|  |         lastUpdateCheck: this.lastUpdateCheck | ||
|  |       }; | ||
|  |     } | ||
|  |     async debugVersions() { | ||
|  |       return Array.from(this.versions.keys()).map((hash) => { | ||
|  |         const version = this.versions.get(hash); | ||
|  |         const clients = Array.from(this.clientVersionMap.entries()).filter(([clientId, version2]) => version2 === hash).map(([clientId, version2]) => clientId); | ||
|  |         return { | ||
|  |           hash, | ||
|  |           manifest: version.manifest, | ||
|  |           clients, | ||
|  |           status: "" | ||
|  |         }; | ||
|  |       }); | ||
|  |     } | ||
|  |     async debugIdleState() { | ||
|  |       return { | ||
|  |         queue: this.idle.taskDescriptions, | ||
|  |         lastTrigger: this.idle.lastTrigger, | ||
|  |         lastRun: this.idle.lastRun | ||
|  |       }; | ||
|  |     } | ||
|  |     async safeFetch(req) { | ||
|  |       try { | ||
|  |         return await this.scope.fetch(req); | ||
|  |       } catch (err) { | ||
|  |         this.debugger.log(err, `Driver.fetch(${req.url})`); | ||
|  |         return this.adapter.newResponse(null, { | ||
|  |           status: 504, | ||
|  |           statusText: "Gateway Timeout" | ||
|  |         }); | ||
|  |       } | ||
|  |     } | ||
|  |     async getCacheNames() { | ||
|  |       const controlTable = await this.controlTable; | ||
|  |       const appVersions = Array.from(this.versions.values()); | ||
|  |       const appVersionCacheNames = await Promise.all(appVersions.map((version) => version.getCacheNames())); | ||
|  |       return [controlTable.cacheName].concat(...appVersionCacheNames); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   // bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/main.mjs
 | ||
|  |   var scope = self; | ||
|  |   var adapter = new Adapter(scope.registration.scope, self.caches); | ||
|  |   new Driver(scope, adapter, new CacheDatabase(adapter)); | ||
|  | })(); | ||
|  | /** | ||
|  |  * @license | ||
|  |  * Copyright Google LLC All Rights Reserved. | ||
|  |  * | ||
|  |  * Use of this source code is governed by an MIT-style license that can be | ||
|  |  * found in the LICENSE file at https://angular.io/license
 | ||
|  |  */ |