From bf6c75a39e0e24ea7e5c3828c3e2f2204566431b Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Fri, 28 Jul 2023 18:40:19 -0400 Subject: [PATCH] fix(workbox-build): make source map filename consistent with injected source file --- packages/workbox-build/src/inject-manifest.ts | 5 ++++- .../src/lib/translate-url-to-sourcemap-paths.ts | 2 +- test/workbox-build/node/inject-manifest.js | 13 ++++++++----- .../node/lib/translate-url-to-sourcemap-paths.js | 4 ++-- .../workbox-build/static/expected-source-map.js.map | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/workbox-build/src/inject-manifest.ts b/packages/workbox-build/src/inject-manifest.ts index 8795ddcaa..fcdc68342 100644 --- a/packages/workbox-build/src/inject-manifest.ts +++ b/packages/workbox-build/src/inject-manifest.ts @@ -129,7 +129,10 @@ export async function injectManifest( searchString: options.injectionPoint!, }); - filesToWrite[options.swDest] = source; + filesToWrite[options.swDest] = source.replace( + url!, + encodeURI(upath.basename(destPath)), + ); filesToWrite[destPath] = map; } else { // If there's no sourcemap associated with swSrc, a simple string diff --git a/packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts b/packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts index 072eac40d..f0bbe69e8 100644 --- a/packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts +++ b/packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts @@ -28,7 +28,7 @@ export function translateURLToSourcemapPaths( const possibleSrcPath = upath.resolve(upath.dirname(swSrc), url); if (fse.existsSync(possibleSrcPath)) { srcPath = possibleSrcPath; - destPath = upath.resolve(upath.dirname(swDest), url); + destPath = `${swDest}.map`; } else { warning = `${errors['cant-find-sourcemap']} ${possibleSrcPath}`; } diff --git a/test/workbox-build/node/inject-manifest.js b/test/workbox-build/node/inject-manifest.js index 907e5c4ff..8d9256801 100644 --- a/test/workbox-build/node/inject-manifest.js +++ b/test/workbox-build/node/inject-manifest.js @@ -13,6 +13,9 @@ const upath = require('upath'); const tempy = require('tempy'); const {errors} = require('../../../packages/workbox-build/build/lib/errors'); +const { + getSourceMapURL, +} = require('../../../packages/workbox-build/build/lib/get-source-map-url'); const { injectManifest, } = require('../../../packages/workbox-build/build/inject-manifest'); @@ -436,11 +439,8 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function () { it(`should update the sourcemap to account for manifest injection`, async function () { const outputDir = tempy.directory(); const swSrc = upath.join(SW_SRC_DIR, 'basic-with-sourcemap.js.nolint'); - const swDest = upath.join(outputDir, 'basic-with-sourcemap.js'); - const sourcemapDest = upath.join( - outputDir, - 'basic-with-sourcemap.js.map', - ); + const swDest = upath.join(outputDir, 'sw.js'); + const sourcemapDest = `${swDest}.map`; const options = Object.assign({}, BASE_OPTIONS, { swDest, swSrc, @@ -459,6 +459,9 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function () { ); expect(actualSourcemap).to.eql(expectedSourcemap); + const actualMapURL = getSourceMapURL(await fse.readFile(swDest, 'utf-8')); + expect(actualMapURL).to.eql(upath.basename(sourcemapDest)); + // We can't validate the SW file contents. }); diff --git a/test/workbox-build/node/lib/translate-url-to-sourcemap-paths.js b/test/workbox-build/node/lib/translate-url-to-sourcemap-paths.js index dc0f60701..2f0fc9ab1 100644 --- a/test/workbox-build/node/lib/translate-url-to-sourcemap-paths.js +++ b/test/workbox-build/node/lib/translate-url-to-sourcemap-paths.js @@ -16,7 +16,7 @@ describe(`[workbox-build] lib/translate-url-to-sourcemap-paths.ts`, function () '../../../../packages/workbox-build/build/lib/translate-url-to-sourcemap-paths'; const URL = 'sw.js.map'; const SWSRC = 'src/sw.js'; - const SWDEST = 'dist/sw.js'; + const SWDEST = 'dist/service-worker.js'; it(`should return undefined paths when url is undefined`, function () { const {translateURLToSourcemapPaths} = require(MODULE_PATH); @@ -80,7 +80,7 @@ describe(`[workbox-build] lib/translate-url-to-sourcemap-paths.ts`, function () SWDEST, ); - expect(destPath).to.eql('dist/sw.js.map'); + expect(destPath).to.eql('dist/service-worker.js.map'); expect(srcPath).to.eq('src/sw.js.map'); expect(warning).to.be.undefined; }); diff --git a/test/workbox-build/static/expected-source-map.js.map b/test/workbox-build/static/expected-source-map.js.map index 58a537517..dbcc49c6b 100644 --- a/test/workbox-build/static/expected-source-map.js.map +++ b/test/workbox-build/static/expected-source-map.js.map @@ -1 +1 @@ -{"version":3,"sources":["../node_modules/workbox-core/_version.js","../node_modules/workbox-core/_private/logger.js","../node_modules/workbox-core/models/messages/messageGenerator.js","../node_modules/workbox-core/_private/WorkboxError.js","../node_modules/workbox-core/_private/assert.js","../node_modules/workbox-core/_private/cacheNames.js","../node_modules/workbox-core/_private/getFriendlyURL.js","../node_modules/workbox-core/models/quotaErrorCallbacks.js","../node_modules/workbox-core/utils/pluginUtils.js","../node_modules/workbox-core/_private/cacheWrapper.js","../node_modules/workbox-core/_private/executeQuotaErrorCallbacks.js","../node_modules/workbox-core/_private/fetchWrapper.js","../node_modules/workbox-strategies/_version.js","../node_modules/workbox-core/_private/canConstructResponseFromBodyStream.js","../node_modules/workbox-core/_private/DBWrapper.js","../node_modules/workbox-core/copyResponse.js","../node_modules/workbox-precaching/_version.js","../node_modules/workbox-precaching/utils/precachePlugins.js","../node_modules/workbox-precaching/utils/createCacheKey.js","../node_modules/workbox-precaching/PrecacheController.js","../node_modules/workbox-precaching/utils/getOrCreatePrecacheController.js","../node_modules/workbox-precaching/utils/getCacheKeyForURL.js","../node_modules/workbox-precaching/utils/generateURLVariations.js","../node_modules/workbox-precaching/utils/removeIgnoredSearchParams.js","../node_modules/workbox-precaching/addRoute.js","../node_modules/workbox-precaching/utils/addFetchListener.js","../node_modules/workbox-precaching/precache.js","../node_modules/workbox-range-requests/_version.js","../node_modules/workbox-range-requests/createPartialResponse.js","../node_modules/workbox-range-requests/utils/parseRangeHeader.js","../node_modules/workbox-range-requests/utils/calculateEffectiveBoundaries.js","../node_modules/workbox-routing/_version.js","../node_modules/workbox-routing/utils/constants.js","../node_modules/workbox-routing/utils/normalizeHandler.js","../node_modules/workbox-routing/Route.js","../node_modules/workbox-routing/RegExpRoute.js","../node_modules/workbox-routing/Router.js","../node_modules/workbox-routing/utils/getOrCreateDefaultRouter.js","../node_modules/workbox-routing/registerRoute.js","../src/js/constants.js","../src/js/getCachedMediaMetadata.js","../src/svelte/routes/Audio.svelte","../src/svelte/routes/Images.svelte","../src/svelte/routes/Videos.svelte","../src/js/service-worker.js","../node_modules/workbox-strategies/CacheOnly.js","../node_modules/workbox-range-requests/RangeRequestsPlugin.js","../node_modules/workbox-precaching/precacheAndRoute.js","../node_modules/workbox-core/skipWaiting.js","../node_modules/workbox-core/clientsClaim.js"],"names":["self","_","e","messageGenerator","code","args","msg","length","JSON","stringify","WorkboxError","Error","[object Object]","errorCode","details","super","this","name","_cacheNameDetails","googleAnalytics","precache","prefix","runtime","suffix","registration","scope","_createCacheName","cacheName","filter","value","join","cacheNames","updateDetails","fn","key","Object","keys","eachCacheNameDetail","getGoogleAnalyticsName","userCacheName","getPrecacheName","getPrefix","getRuntimeName","getSuffix","getFriendlyURL","url","urlObj","URL","String","location","href","origin","pathname","quotaErrorCallbacks","Set","pluginUtils","plugins","callbackName","plugin","matchWrapper","async","request","event","matchOptions","cache","caches","open","effectiveRequest","_getEffectiveRequest","mode","cachedResponse","match","pluginMethod","call","_isResponseSafeToCache","response","responseToCache","pluginsUsed","status","undefined","cacheKeyWillBeUsedPlugins","Request","cacheWrapper","put","updatePlugins","oldResponse","error","callback","executeQuotaErrorCallbacks","newResponse","fetchWrapper","fetch","fetchOptions","FetchEvent","preloadResponse","possiblePreloadResponse","failedFetchPlugins","originalRequest","clone","requestClone","err","thrownError","pluginFilteredRequest","fetchResponse","supportStatus","DBWrapper","version","onupgradeneeded","onversionchange","_db","_name","_version","_onupgradeneeded","_onversionchange","close","db","Promise","resolve","reject","openRequestTimedOut","setTimeout","OPEN_TIMEOUT","openRequest","indexedDB","onerror","evt","transaction","abort","result","onsuccess","bind","storeName","query","getAllKeys","count","getAllMatching","includeKeys","map","entry","index","direction","txn","done","store","objectStore","target","results","openCursor","cursor","push","continue","storeNames","type","onabort","oncomplete","method","objStore","apply","prototype","methodsToWrap","readonly","readwrite","methods","entries","IDBObjectStore","_call","copyResponse","modifier","clonedResponse","responseInit","headers","Headers","statusText","modifiedResponseInit","body","testResponse","Response","canConstructResponseFromBodyStream","blob","precachePlugins","get","newPlugins","REVISION_SEARCH_PARAM","createCacheKey","urlObject","cacheKey","revision","cacheKeyURL","originalURL","searchParams","set","PrecacheController","_cacheName","_urlsToCacheKeys","Map","_cacheKeysToIntegrities","has","firstEntry","secondEntry","integrity","toBePrecached","alreadyPrecached","alreadyCachedRequests","existingCacheKeys","precacheRequests","_addURLToCache","all","updatedURLs","item","notUpdatedURLs","currentlyCachedRequests","expectedCacheKeys","values","deletedURLs","delete","credentials","cacheWillUpdatePlugin","cacheWillUpdate","redirected","ignoreSearch","getCacheKeyForURL","precacheController","getOrCreatePrecacheController","options","urlsToCacheKeys","getURLsToCacheKeys","possibleURL","ignoreURLParametersMatching","directoryIndex","cleanURLs","urlManipulation","hash","urlWithoutIgnoredParams","paramName","some","regExp","test","removeIgnoredSearchParams","endsWith","directoryURL","cleanURL","additionalURLs","urlToAttempt","generateURLVariations","possibleCacheKey","listenerAdded","addRoute","addEventListener","precachedURL","responsePromise","then","respondWith","addFetchListener","installListener","waitUntil","install","catch","activateListener","activate","createPartialResponse","originalResponse","rangeHeader","boundaries","normalizedRangeHeader","trim","toLowerCase","startsWith","includes","rangeParts","exec","start","Number","end","parseRangeHeader","originalBlob","effectiveBoundaries","blobSize","size","effectiveStart","effectiveEnd","calculateEffectiveBoundaries","slicedBlob","slice","slicedBlobSize","slicedResponse","defaultMethod","normalizeHandler","handler","handle","Route","RegExpRoute","Router","_routes","routes","handleRequest","data","payload","requestPromises","urlsToCache","ports","postMessage","protocol","params","route","findMatchingRoute","_defaultHandler","_catchHandler","matchResult","Array","isArray","constructor","routeIndex","indexOf","splice","defaultRouter","getOrCreateDefaultRouter","addCacheListener","registerRoute","capture","captureUrl","RegExp","moduleName","funcName","requests","reverse","contentType","src","_getCachedMediaMetadata","mimeRoute","mimePrefix","broadcastChannel","BroadcastChannel","cachedMediaHandler","_plugins","_matchOptions","cachedResponseWillBeUsed","skipWaiting","clients","claim","addToCacheList","__WB_MANIFEST","mediaFiles","formData","getAll","mediaFile","Date","now","content-length","content-type","routeToRedirectTo","audioRoute","imagesRoute","videosRoute","find","redirectionUrl","redirect"],"mappings":"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","file":"basic-with-sourcemap.js","sourcesContent":["// @ts-ignore\ntry {\n self['workbox:core:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst logger = (process.env.NODE_ENV === 'production' ? null : (() => {\n let inGroup = false;\n const methodToColorMap = {\n debug: `#7f8c8d`,\n log: `#2ecc71`,\n warn: `#f39c12`,\n error: `#c0392b`,\n groupCollapsed: `#3498db`,\n groupEnd: null,\n };\n const print = function (method, args) {\n if (method === 'groupCollapsed') {\n // Safari doesn't print all console.groupCollapsed() arguments:\n // https://bugs.webkit.org/show_bug.cgi?id=182754\n if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\n console[method](...args);\n return;\n }\n }\n const styles = [\n `background: ${methodToColorMap[method]}`,\n `border-radius: 0.5em`,\n `color: white`,\n `font-weight: bold`,\n `padding: 2px 0.5em`,\n ];\n // When in a group, the workbox prefix is not displayed.\n const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];\n console[method](...logPrefix, ...args);\n if (method === 'groupCollapsed') {\n inGroup = true;\n }\n if (method === 'groupEnd') {\n inGroup = false;\n }\n };\n const api = {};\n const loggerMethods = Object.keys(methodToColorMap);\n for (const key of loggerMethods) {\n const method = key;\n api[method] = (...args) => {\n print(method, args);\n };\n }\n return api;\n})());\nexport { logger };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messages } from './messages.js';\nimport '../../_version.js';\nconst fallback = (code, ...args) => {\n let msg = code;\n if (args.length > 0) {\n msg += ` :: ${JSON.stringify(args)}`;\n }\n return msg;\n};\nconst generatorFunction = (code, details = {}) => {\n const message = messages[code];\n if (!message) {\n throw new Error(`Unable to find message for code '${code}'.`);\n }\n return message(details);\n};\nexport const messageGenerator = (process.env.NODE_ENV === 'production') ?\n fallback : generatorFunction;\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messageGenerator } from '../models/messages/messageGenerator.js';\nimport '../_version.js';\n/**\n * Workbox errors should be thrown with this class.\n * This allows use to ensure the type easily in tests,\n * helps developers identify errors from workbox\n * easily and allows use to optimise error\n * messages correctly.\n *\n * @private\n */\nclass WorkboxError extends Error {\n /**\n *\n * @param {string} errorCode The error code that\n * identifies this particular error.\n * @param {Object=} details Any relevant arguments\n * that will help developers identify issues should\n * be added as a key on the context object.\n */\n constructor(errorCode, details) {\n let message = messageGenerator(errorCode, details);\n super(message);\n this.name = errorCode;\n this.details = details;\n }\n}\nexport { WorkboxError };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from '../_private/WorkboxError.js';\nimport '../_version.js';\n/*\n * This method returns true if the current context is a service worker.\n */\nconst isSWEnv = (moduleName) => {\n if (!('ServiceWorkerGlobalScope' in self)) {\n throw new WorkboxError('not-in-sw', { moduleName });\n }\n};\n/*\n * This method throws if the supplied value is not an array.\n * The destructed values are required to produce a meaningful error for users.\n * The destructed and restructured object is so it's clear what is\n * needed.\n */\nconst isArray = (value, details) => {\n if (!Array.isArray(value)) {\n throw new WorkboxError('not-an-array', details);\n }\n};\nconst hasMethod = (object, expectedMethod, details) => {\n const type = typeof object[expectedMethod];\n if (type !== 'function') {\n details.expectedMethod = expectedMethod;\n throw new WorkboxError('missing-a-method', details);\n }\n};\nconst isType = (object, expectedType, details) => {\n if (typeof object !== expectedType) {\n details.expectedType = expectedType;\n throw new WorkboxError('incorrect-type', details);\n }\n};\nconst isInstance = (object, expectedClass, details) => {\n if (!(object instanceof expectedClass)) {\n details.expectedClass = expectedClass;\n throw new WorkboxError('incorrect-class', details);\n }\n};\nconst isOneOf = (value, validValues, details) => {\n if (!validValues.includes(value)) {\n details.validValueDescription =\n `Valid values are ${JSON.stringify(validValues)}.`;\n throw new WorkboxError('invalid-value', details);\n }\n};\nconst isArrayOfClass = (value, expectedClass, details) => {\n const error = new WorkboxError('not-array-of-class', details);\n if (!Array.isArray(value)) {\n throw error;\n }\n for (let item of value) {\n if (!(item instanceof expectedClass)) {\n throw error;\n }\n }\n};\nconst finalAssertExports = process.env.NODE_ENV === 'production' ? null : {\n hasMethod,\n isArray,\n isInstance,\n isOneOf,\n isSWEnv,\n isType,\n isArrayOfClass,\n};\nexport { finalAssertExports as assert };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst _cacheNameDetails = {\n googleAnalytics: 'googleAnalytics',\n precache: 'precache-v2',\n prefix: 'workbox',\n runtime: 'runtime',\n suffix: registration.scope,\n};\nconst _createCacheName = (cacheName) => {\n return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix]\n .filter((value) => value && value.length > 0)\n .join('-');\n};\nconst eachCacheNameDetail = (fn) => {\n for (const key of Object.keys(_cacheNameDetails)) {\n fn(key);\n }\n};\nexport const cacheNames = {\n updateDetails: (details) => {\n eachCacheNameDetail((key) => {\n if (typeof details[key] === 'string') {\n _cacheNameDetails[key] = details[key];\n }\n });\n },\n getGoogleAnalyticsName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);\n },\n getPrecacheName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.precache);\n },\n getPrefix: () => {\n return _cacheNameDetails.prefix;\n },\n getRuntimeName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.runtime);\n },\n getSuffix: () => {\n return _cacheNameDetails.suffix;\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst getFriendlyURL = (url) => {\n const urlObj = new URL(String(url), location.href);\n if (urlObj.origin === location.origin) {\n return urlObj.pathname;\n }\n return urlObj.href;\n};\nexport { getFriendlyURL };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n// Callbacks to be executed whenever there's a quota error.\nconst quotaErrorCallbacks = new Set();\nexport { quotaErrorCallbacks };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nexport const pluginUtils = {\n filter: (plugins, callbackName) => {\n return plugins.filter((plugin) => callbackName in plugin);\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from './WorkboxError.js';\nimport { assert } from './assert.js';\nimport { getFriendlyURL } from './getFriendlyURL.js';\nimport { logger } from './logger.js';\nimport { executeQuotaErrorCallbacks } from './executeQuotaErrorCallbacks.js';\nimport { pluginUtils } from '../utils/pluginUtils.js';\nimport '../_version.js';\n/**\n * Wrapper around cache.put().\n *\n * Will call `cacheDidUpdate` on plugins if the cache was updated, using\n * `matchOptions` when determining what the old entry is.\n *\n * @param {Object} options\n * @param {string} options.cacheName\n * @param {Request} options.request\n * @param {Response} options.response\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @param {Object} [options.matchOptions]\n *\n * @private\n * @memberof module:workbox-core\n */\nconst putWrapper = async ({ cacheName, request, response, event, plugins = [], matchOptions, }) => {\n if (process.env.NODE_ENV !== 'production') {\n if (request.method && request.method !== 'GET') {\n throw new WorkboxError('attempt-to-cache-non-get-request', {\n url: getFriendlyURL(request.url),\n method: request.method,\n });\n }\n }\n const effectiveRequest = await _getEffectiveRequest({\n plugins, request, mode: 'write'\n });\n if (!response) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Cannot cache non-existent response for ` +\n `'${getFriendlyURL(effectiveRequest.url)}'.`);\n }\n throw new WorkboxError('cache-put-with-no-response', {\n url: getFriendlyURL(effectiveRequest.url),\n });\n }\n let responseToCache = await _isResponseSafeToCache({\n event,\n plugins,\n response,\n request: effectiveRequest,\n });\n if (!responseToCache) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' will ` +\n `not be cached.`, responseToCache);\n }\n return;\n }\n const cache = await caches.open(cacheName);\n const updatePlugins = pluginUtils.filter(plugins, \"cacheDidUpdate\" /* CACHE_DID_UPDATE */);\n let oldResponse = updatePlugins.length > 0 ?\n await matchWrapper({ cacheName, matchOptions, request: effectiveRequest }) :\n null;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Updating the '${cacheName}' cache with a new Response for ` +\n `${getFriendlyURL(effectiveRequest.url)}.`);\n }\n try {\n await cache.put(effectiveRequest, responseToCache);\n }\n catch (error) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError\n if (error.name === 'QuotaExceededError') {\n await executeQuotaErrorCallbacks();\n }\n throw error;\n }\n for (let plugin of updatePlugins) {\n await plugin[\"cacheDidUpdate\" /* CACHE_DID_UPDATE */].call(plugin, {\n cacheName,\n event,\n oldResponse,\n newResponse: responseToCache,\n request: effectiveRequest,\n });\n }\n};\n/**\n * This is a wrapper around cache.match().\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache to match against.\n * @param {Request} options.request The Request that will be used to look up\n * cache entries.\n * @param {Event} [options.event] The event that propted the action.\n * @param {Object} [options.matchOptions] Options passed to cache.match().\n * @param {Array} [options.plugins=[]] Array of plugins.\n * @return {Response} A cached response if available.\n *\n * @private\n * @memberof module:workbox-core\n */\nconst matchWrapper = async ({ cacheName, request, event, matchOptions, plugins = [], }) => {\n const cache = await caches.open(cacheName);\n const effectiveRequest = await _getEffectiveRequest({\n plugins, request, mode: 'read'\n });\n let cachedResponse = await cache.match(effectiveRequest, matchOptions);\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n logger.debug(`Found a cached response in '${cacheName}'.`);\n }\n else {\n logger.debug(`No cached response found in '${cacheName}'.`);\n }\n }\n for (const plugin of plugins) {\n if (\"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */ in plugin) {\n const pluginMethod = plugin[\"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */];\n cachedResponse = await pluginMethod.call(plugin, {\n cacheName,\n event,\n matchOptions,\n cachedResponse,\n request: effectiveRequest,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n assert.isInstance(cachedResponse, Response, {\n moduleName: 'Plugin',\n funcName: \"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n return cachedResponse;\n};\n/**\n * This method will call cacheWillUpdate on the available plugins (or use\n * status === 200) to determine if the Response is safe and valid to cache.\n *\n * @param {Object} options\n * @param {Request} options.request\n * @param {Response} options.response\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst _isResponseSafeToCache = async ({ request, response, event, plugins = [], }) => {\n let responseToCache = response;\n let pluginsUsed = false;\n for (let plugin of plugins) {\n if (\"cacheWillUpdate\" /* CACHE_WILL_UPDATE */ in plugin) {\n pluginsUsed = true;\n const pluginMethod = plugin[\"cacheWillUpdate\" /* CACHE_WILL_UPDATE */];\n responseToCache = await pluginMethod.call(plugin, {\n request,\n response: responseToCache,\n event,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n assert.isInstance(responseToCache, Response, {\n moduleName: 'Plugin',\n funcName: \"cacheWillUpdate\" /* CACHE_WILL_UPDATE */,\n isReturnValueProblem: true,\n });\n }\n }\n if (!responseToCache) {\n break;\n }\n }\n }\n if (!pluginsUsed) {\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n if (responseToCache.status !== 200) {\n if (responseToCache.status === 0) {\n logger.warn(`The response for '${request.url}' is an opaque ` +\n `response. The caching strategy that you're using will not ` +\n `cache opaque responses by default.`);\n }\n else {\n logger.debug(`The response for '${request.url}' returned ` +\n `a status code of '${response.status}' and won't be cached as a ` +\n `result.`);\n }\n }\n }\n }\n responseToCache = responseToCache && responseToCache.status === 200 ?\n responseToCache : undefined;\n }\n return responseToCache ? responseToCache : null;\n};\n/**\n * Checks the list of plugins for the cacheKeyWillBeUsed callback, and\n * executes any of those callbacks found in sequence. The final `Request` object\n * returned by the last plugin is treated as the cache key for cache reads\n * and/or writes.\n *\n * @param {Object} options\n * @param {Request} options.request\n * @param {string} options.mode\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst _getEffectiveRequest = async ({ request, mode, plugins = [], }) => {\n const cacheKeyWillBeUsedPlugins = pluginUtils.filter(plugins, \"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */);\n let effectiveRequest = request;\n for (const plugin of cacheKeyWillBeUsedPlugins) {\n effectiveRequest = await plugin[\"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */].call(plugin, { mode, request: effectiveRequest });\n if (typeof effectiveRequest === 'string') {\n effectiveRequest = new Request(effectiveRequest);\n }\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(effectiveRequest, Request, {\n moduleName: 'Plugin',\n funcName: \"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n return effectiveRequest;\n};\nexport const cacheWrapper = {\n put: putWrapper,\n match: matchWrapper,\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from '../_private/logger.js';\nimport { quotaErrorCallbacks } from '../models/quotaErrorCallbacks.js';\nimport '../_version.js';\n/**\n * Runs all of the callback functions, one at a time sequentially, in the order\n * in which they were registered.\n *\n * @memberof workbox.core\n * @private\n */\nasync function executeQuotaErrorCallbacks() {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`About to run ${quotaErrorCallbacks.size} ` +\n `callbacks to clean up caches.`);\n }\n for (const callback of quotaErrorCallbacks) {\n await callback();\n if (process.env.NODE_ENV !== 'production') {\n logger.log(callback, 'is complete.');\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log('Finished running callbacks.');\n }\n}\nexport { executeQuotaErrorCallbacks };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from './WorkboxError.js';\nimport { logger } from './logger.js';\nimport { assert } from './assert.js';\nimport { getFriendlyURL } from '../_private/getFriendlyURL.js';\nimport { pluginUtils } from '../utils/pluginUtils.js';\nimport '../_version.js';\n/**\n * Wrapper around the fetch API.\n *\n * Will call requestWillFetch on available plugins.\n *\n * @param {Object} options\n * @param {Request|string} options.request\n * @param {Object} [options.fetchOptions]\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst wrappedFetch = async ({ request, fetchOptions, event, plugins = [], }) => {\n if (typeof request === 'string') {\n request = new Request(request);\n }\n // We *should* be able to call `await event.preloadResponse` even if it's\n // undefined, but for some reason, doing so leads to errors in our Node unit\n // tests. To work around that, explicitly check preloadResponse's value first.\n if (event instanceof FetchEvent && event.preloadResponse) {\n const possiblePreloadResponse = await event.preloadResponse;\n if (possiblePreloadResponse) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Using a preloaded navigation response for ` +\n `'${getFriendlyURL(request.url)}'`);\n }\n return possiblePreloadResponse;\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n paramName: 'request',\n expectedClass: Request,\n moduleName: 'workbox-core',\n className: 'fetchWrapper',\n funcName: 'wrappedFetch',\n });\n }\n const failedFetchPlugins = pluginUtils.filter(plugins, \"fetchDidFail\" /* FETCH_DID_FAIL */);\n // If there is a fetchDidFail plugin, we need to save a clone of the\n // original request before it's either modified by a requestWillFetch\n // plugin or before the original request's body is consumed via fetch().\n const originalRequest = failedFetchPlugins.length > 0 ?\n request.clone() : null;\n try {\n for (let plugin of plugins) {\n if (\"requestWillFetch\" /* REQUEST_WILL_FETCH */ in plugin) {\n const pluginMethod = plugin[\"requestWillFetch\" /* REQUEST_WILL_FETCH */];\n const requestClone = request.clone();\n request = (await pluginMethod.call(plugin, {\n request: requestClone,\n event,\n }));\n if (process.env.NODE_ENV !== 'production') {\n if (request) {\n assert.isInstance(request, Request, {\n moduleName: 'Plugin',\n funcName: \"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n }\n catch (err) {\n throw new WorkboxError('plugin-error-request-will-fetch', {\n thrownError: err,\n });\n }\n // The request can be altered by plugins with `requestWillFetch` making\n // the original request (Most likely from a `fetch` event) to be different\n // to the Request we make. Pass both to `fetchDidFail` to aid debugging.\n let pluginFilteredRequest = request.clone();\n try {\n let fetchResponse;\n // See https://github.com/GoogleChrome/workbox/issues/1796\n if (request.mode === 'navigate') {\n fetchResponse = await fetch(request);\n }\n else {\n fetchResponse = await fetch(request, fetchOptions);\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Network request for ` +\n `'${getFriendlyURL(request.url)}' returned a response with ` +\n `status '${fetchResponse.status}'.`);\n }\n for (const plugin of plugins) {\n if (\"fetchDidSucceed\" /* FETCH_DID_SUCCEED */ in plugin) {\n fetchResponse = await plugin[\"fetchDidSucceed\" /* FETCH_DID_SUCCEED */]\n .call(plugin, {\n event,\n request: pluginFilteredRequest,\n response: fetchResponse,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (fetchResponse) {\n assert.isInstance(fetchResponse, Response, {\n moduleName: 'Plugin',\n funcName: \"fetchDidSucceed\" /* FETCH_DID_SUCCEED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n return fetchResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Network request for ` +\n `'${getFriendlyURL(request.url)}' threw an error.`, error);\n }\n for (const plugin of failedFetchPlugins) {\n await plugin[\"fetchDidFail\" /* FETCH_DID_FAIL */].call(plugin, {\n error,\n event,\n originalRequest: originalRequest.clone(),\n request: pluginFilteredRequest.clone(),\n });\n }\n throw error;\n }\n};\nconst fetchWrapper = {\n fetch: wrappedFetch,\n};\nexport { fetchWrapper };\n","// @ts-ignore\ntry {\n self['workbox:strategies:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nlet supportStatus;\n/**\n * A utility function that determines whether the current browser supports\n * constructing a new `Response` from a `response.body` stream.\n *\n * @return {boolean} `true`, if the current browser can successfully\n * construct a `Response` from a `response.body` stream, `false` otherwise.\n *\n * @private\n */\nfunction canConstructResponseFromBodyStream() {\n if (supportStatus === undefined) {\n const testResponse = new Response('');\n if ('body' in testResponse) {\n try {\n new Response(testResponse.body);\n supportStatus = true;\n }\n catch (error) {\n supportStatus = false;\n }\n }\n supportStatus = false;\n }\n return supportStatus;\n}\nexport { canConstructResponseFromBodyStream };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * A class that wraps common IndexedDB functionality in a promise-based API.\n * It exposes all the underlying power and functionality of IndexedDB, but\n * wraps the most commonly used features in a way that's much simpler to use.\n *\n * @private\n */\nexport class DBWrapper {\n /**\n * @param {string} name\n * @param {number} version\n * @param {Object=} [callback]\n * @param {!Function} [callbacks.onupgradeneeded]\n * @param {!Function} [callbacks.onversionchange] Defaults to\n * DBWrapper.prototype._onversionchange when not specified.\n * @private\n */\n constructor(name, version, { onupgradeneeded, onversionchange, } = {}) {\n this._db = null;\n this._name = name;\n this._version = version;\n this._onupgradeneeded = onupgradeneeded;\n this._onversionchange = onversionchange || (() => this.close());\n }\n /**\n * Returns the IDBDatabase instance (not normally needed).\n * @return {IDBDatabase|undefined}\n *\n * @private\n */\n get db() {\n return this._db;\n }\n /**\n * Opens a connected to an IDBDatabase, invokes any onupgradedneeded\n * callback, and added an onversionchange callback to the database.\n *\n * @return {IDBDatabase}\n * @private\n */\n async open() {\n if (this._db)\n return;\n this._db = await new Promise((resolve, reject) => {\n // This flag is flipped to true if the timeout callback runs prior\n // to the request failing or succeeding. Note: we use a timeout instead\n // of an onblocked handler since there are cases where onblocked will\n // never never run. A timeout better handles all possible scenarios:\n // https://github.com/w3c/IndexedDB/issues/223\n let openRequestTimedOut = false;\n setTimeout(() => {\n openRequestTimedOut = true;\n reject(new Error('The open request was blocked and timed out'));\n }, this.OPEN_TIMEOUT);\n const openRequest = indexedDB.open(this._name, this._version);\n openRequest.onerror = () => reject(openRequest.error);\n openRequest.onupgradeneeded = (evt) => {\n if (openRequestTimedOut) {\n openRequest.transaction.abort();\n openRequest.result.close();\n }\n else if (typeof this._onupgradeneeded === 'function') {\n this._onupgradeneeded(evt);\n }\n };\n openRequest.onsuccess = () => {\n const db = openRequest.result;\n if (openRequestTimedOut) {\n db.close();\n }\n else {\n db.onversionchange = this._onversionchange.bind(this);\n resolve(db);\n }\n };\n });\n return this;\n }\n /**\n * Polyfills the native `getKey()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @return {Array}\n * @private\n */\n async getKey(storeName, query) {\n return (await this.getAllKeys(storeName, query, 1))[0];\n }\n /**\n * Polyfills the native `getAll()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @param {number} count\n * @return {Array}\n * @private\n */\n async getAll(storeName, query, count) {\n return await this.getAllMatching(storeName, { query, count });\n }\n /**\n * Polyfills the native `getAllKeys()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @param {number} count\n * @return {Array}\n * @private\n */\n async getAllKeys(storeName, query, count) {\n const entries = await this.getAllMatching(storeName, { query, count, includeKeys: true });\n return entries.map((entry) => entry.key);\n }\n /**\n * Supports flexible lookup in an object store by specifying an index,\n * query, direction, and count. This method returns an array of objects\n * with the signature .\n *\n * @param {string} storeName\n * @param {Object} [opts]\n * @param {string} [opts.index] The index to use (if specified).\n * @param {*} [opts.query]\n * @param {IDBCursorDirection} [opts.direction]\n * @param {number} [opts.count] The max number of results to return.\n * @param {boolean} [opts.includeKeys] When true, the structure of the\n * returned objects is changed from an array of values to an array of\n * objects in the form {key, primaryKey, value}.\n * @return {Array}\n * @private\n */\n async getAllMatching(storeName, { index, query = null, // IE/Edge errors if query === `undefined`.\n direction = 'next', count, includeKeys = false, } = {}) {\n return await this.transaction([storeName], 'readonly', (txn, done) => {\n const store = txn.objectStore(storeName);\n const target = index ? store.index(index) : store;\n const results = [];\n const request = target.openCursor(query, direction);\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n results.push(includeKeys ? cursor : cursor.value);\n if (count && results.length >= count) {\n done(results);\n }\n else {\n cursor.continue();\n }\n }\n else {\n done(results);\n }\n };\n });\n }\n /**\n * Accepts a list of stores, a transaction type, and a callback and\n * performs a transaction. A promise is returned that resolves to whatever\n * value the callback chooses. The callback holds all the transaction logic\n * and is invoked with two arguments:\n * 1. The IDBTransaction object\n * 2. A `done` function, that's used to resolve the promise when\n * when the transaction is done, if passed a value, the promise is\n * resolved to that value.\n *\n * @param {Array} storeNames An array of object store names\n * involved in the transaction.\n * @param {string} type Can be `readonly` or `readwrite`.\n * @param {!Function} callback\n * @return {*} The result of the transaction ran by the callback.\n * @private\n */\n async transaction(storeNames, type, callback) {\n await this.open();\n return await new Promise((resolve, reject) => {\n const txn = this._db.transaction(storeNames, type);\n txn.onabort = () => reject(txn.error);\n txn.oncomplete = () => resolve();\n callback(txn, (value) => resolve(value));\n });\n }\n /**\n * Delegates async to a native IDBObjectStore method.\n *\n * @param {string} method The method name.\n * @param {string} storeName The object store name.\n * @param {string} type Can be `readonly` or `readwrite`.\n * @param {...*} args The list of args to pass to the native method.\n * @return {*} The result of the transaction.\n * @private\n */\n async _call(method, storeName, type, ...args) {\n const callback = (txn, done) => {\n const objStore = txn.objectStore(storeName);\n const request = objStore[method].apply(objStore, args);\n request.onsuccess = () => done(request.result);\n };\n return await this.transaction([storeName], type, callback);\n }\n /**\n * Closes the connection opened by `DBWrapper.open()`. Generally this method\n * doesn't need to be called since:\n * 1. It's usually better to keep a connection open since opening\n * a new connection is somewhat slow.\n * 2. Connections are automatically closed when the reference is\n * garbage collected.\n * The primary use case for needing to close a connection is when another\n * reference (typically in another tab) needs to upgrade it and would be\n * blocked by the current, open connection.\n *\n * @private\n */\n close() {\n if (this._db) {\n this._db.close();\n this._db = null;\n }\n }\n}\n// Exposed on the prototype to let users modify the default timeout on a\n// per-instance or global basis.\nDBWrapper.prototype.OPEN_TIMEOUT = 2000;\n// Wrap native IDBObjectStore methods according to their mode.\nconst methodsToWrap = {\n readonly: ['get', 'count', 'getKey', 'getAll', 'getAllKeys'],\n readwrite: ['add', 'put', 'clear', 'delete'],\n};\nfor (const [mode, methods] of Object.entries(methodsToWrap)) {\n for (const method of methods) {\n if (method in IDBObjectStore.prototype) {\n // Don't use arrow functions here since we're outside of the class.\n DBWrapper.prototype[method] =\n async function (storeName, ...args) {\n return await this._call(method, storeName, mode, ...args);\n };\n }\n }\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { canConstructResponseFromBodyStream } from './_private/canConstructResponseFromBodyStream.js';\nimport './_version.js';\n/**\n * Allows developers to copy a response and modify its `headers`, `status`,\n * or `statusText` values (the values settable via a\n * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax}\n * object in the constructor).\n * To modify these values, pass a function as the second argument. That\n * function will be invoked with a single object with the response properties\n * `{headers, status, statusText}`. The return value of this function will\n * be used as the `ResponseInit` for the new `Response`. To change the values\n * either modify the passed parameter(s) and return it, or return a totally\n * new object.\n *\n * @param {Response} response\n * @param {Function} modifier\n * @alias workbox.core.copyResponse\n */\nasync function copyResponse(response, modifier) {\n const clonedResponse = response.clone();\n // Create a fresh `ResponseInit` object by cloning the headers.\n const responseInit = {\n headers: new Headers(clonedResponse.headers),\n status: clonedResponse.status,\n statusText: clonedResponse.statusText,\n };\n // Apply any user modifications.\n const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit;\n // Create the new response from the body stream and `ResponseInit`\n // modifications. Note: not all browsers support the Response.body stream,\n // so fall back to reading the entire body into memory as a blob.\n const body = canConstructResponseFromBodyStream() ?\n clonedResponse.body : await clonedResponse.blob();\n return new Response(body, modifiedResponseInit);\n}\n;\nexport { copyResponse };\n","// @ts-ignore\ntry {\n self['workbox:precaching:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst plugins = [];\nexport const precachePlugins = {\n /*\n * @return {Array}\n * @private\n */\n get() {\n return plugins;\n },\n /*\n * @param {Array} newPlugins\n * @private\n */\n add(newPlugins) {\n plugins.push(...newPlugins);\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport '../_version.js';\n// Name of the search parameter used to store revision info.\nconst REVISION_SEARCH_PARAM = '__WB_REVISION__';\n/**\n * Converts a manifest entry into a versioned URL suitable for precaching.\n *\n * @param {Object|string} entry\n * @return {string} A URL with versioning info.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function createCacheKey(entry) {\n if (!entry) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If a precache manifest entry is a string, it's assumed to be a versioned\n // URL, like '/app.abcd1234.js'. Return as-is.\n if (typeof entry === 'string') {\n const urlObject = new URL(entry, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n const { revision, url } = entry;\n if (!url) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If there's just a URL and no revision, then it's also assumed to be a\n // versioned URL.\n if (!revision) {\n const urlObject = new URL(url, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n // Otherwise, construct a properly versioned URL using the custom Workbox\n // search parameter along with the revision info.\n const cacheKeyURL = new URL(url, location.href);\n const originalURL = new URL(url, location.href);\n cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);\n return {\n cacheKey: cacheKeyURL.href,\n url: originalURL.href,\n };\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { cacheWrapper } from 'workbox-core/_private/cacheWrapper.js';\nimport { fetchWrapper } from 'workbox-core/_private/fetchWrapper.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { copyResponse } from 'workbox-core/copyResponse.js';\nimport { createCacheKey } from './utils/createCacheKey.js';\nimport { printCleanupDetails } from './utils/printCleanupDetails.js';\nimport { printInstallDetails } from './utils/printInstallDetails.js';\nimport './_version.js';\n/**\n * Performs efficient precaching of assets.\n *\n * @memberof module:workbox-precaching\n */\nclass PrecacheController {\n /**\n * Create a new PrecacheController.\n *\n * @param {string} [cacheName] An optional name for the cache, to override\n * the default precache name.\n */\n constructor(cacheName) {\n this._cacheName = cacheNames.getPrecacheName(cacheName);\n this._urlsToCacheKeys = new Map();\n this._cacheKeysToIntegrities = new Map();\n }\n /**\n * This method will add items to the precache list, removing duplicates\n * and ensuring the information is valid.\n *\n * @param {\n * Array\n * } entries Array of entries to precache.\n */\n addToCacheList(entries) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isArray(entries, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'addToCacheList',\n paramName: 'entries',\n });\n }\n for (const entry of entries) {\n const { cacheKey, url } = createCacheKey(entry);\n if (this._urlsToCacheKeys.has(url) &&\n this._urlsToCacheKeys.get(url) !== cacheKey) {\n throw new WorkboxError('add-to-cache-list-conflicting-entries', {\n firstEntry: this._urlsToCacheKeys.get(url),\n secondEntry: cacheKey,\n });\n }\n if (typeof entry !== 'string' && entry.integrity) {\n if (this._cacheKeysToIntegrities.has(cacheKey) &&\n this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {\n throw new WorkboxError('add-to-cache-list-conflicting-integrities', {\n url,\n });\n }\n this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);\n }\n this._urlsToCacheKeys.set(url, cacheKey);\n }\n }\n /**\n * Precaches new and updated assets. Call this method from the service worker\n * install event.\n *\n * @param {Object} options\n * @param {Event} [options.event] The install event (if needed).\n * @param {Array} [options.plugins] Plugins to be used for fetching\n * and caching during install.\n * @return {Promise}\n */\n async install({ event, plugins } = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (plugins) {\n assert.isArray(plugins, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'install',\n paramName: 'plugins',\n });\n }\n }\n const toBePrecached = [];\n const alreadyPrecached = [];\n const cache = await caches.open(this._cacheName);\n const alreadyCachedRequests = await cache.keys();\n const existingCacheKeys = new Set(alreadyCachedRequests.map((request) => request.url));\n for (const [url, cacheKey] of this._urlsToCacheKeys) {\n if (existingCacheKeys.has(cacheKey)) {\n alreadyPrecached.push(url);\n }\n else {\n toBePrecached.push({ cacheKey, url });\n }\n }\n const precacheRequests = toBePrecached.map(({ cacheKey, url }) => {\n const integrity = this._cacheKeysToIntegrities.get(cacheKey);\n return this._addURLToCache({ cacheKey, event, plugins, url, integrity });\n });\n await Promise.all(precacheRequests);\n const updatedURLs = toBePrecached.map((item) => item.url);\n if (process.env.NODE_ENV !== 'production') {\n printInstallDetails(updatedURLs, alreadyPrecached);\n }\n return {\n updatedURLs,\n notUpdatedURLs: alreadyPrecached,\n };\n }\n /**\n * Deletes assets that are no longer present in the current precache manifest.\n * Call this method from the service worker activate event.\n *\n * @return {Promise}\n */\n async activate() {\n const cache = await caches.open(this._cacheName);\n const currentlyCachedRequests = await cache.keys();\n const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());\n const deletedURLs = [];\n for (const request of currentlyCachedRequests) {\n if (!expectedCacheKeys.has(request.url)) {\n await cache.delete(request);\n deletedURLs.push(request.url);\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n printCleanupDetails(deletedURLs);\n }\n return { deletedURLs };\n }\n /**\n * Requests the entry and saves it to the cache if the response is valid.\n * By default, any response with a status code of less than 400 (including\n * opaque responses) is considered valid.\n *\n * If you need to use custom criteria to determine what's valid and what\n * isn't, then pass in an item in `options.plugins` that implements the\n * `cacheWillUpdate()` lifecycle event.\n *\n * @private\n * @param {Object} options\n * @param {string} options.cacheKey The string to use a cache key.\n * @param {string} options.url The URL to fetch and cache.\n * @param {Event} [options.event] The install event (if passed).\n * @param {Array} [options.plugins] An array of plugins to apply to\n * fetch and caching.\n * @param {string} [options.integrity] The value to use for the `integrity`\n * field when making the request.\n */\n async _addURLToCache({ cacheKey, url, event, plugins, integrity }) {\n const request = new Request(url, {\n integrity,\n cache: 'reload',\n credentials: 'same-origin',\n });\n let response = await fetchWrapper.fetch({\n event,\n plugins,\n request,\n });\n // Allow developers to override the default logic about what is and isn't\n // valid by passing in a plugin implementing cacheWillUpdate(), e.g.\n // a workbox.cacheableResponse.CacheableResponsePlugin instance.\n let cacheWillUpdatePlugin;\n for (const plugin of (plugins || [])) {\n if ('cacheWillUpdate' in plugin) {\n cacheWillUpdatePlugin = plugin;\n }\n }\n const isValidResponse = cacheWillUpdatePlugin ?\n // Use a callback if provided. It returns a truthy value if valid.\n // NOTE: invoke the method on the plugin instance so the `this` context\n // is correct.\n cacheWillUpdatePlugin.cacheWillUpdate({ event, request, response }) :\n // Otherwise, default to considering any response status under 400 valid.\n // This includes, by default, considering opaque responses valid.\n response.status < 400;\n // Consider this a failure, leading to the `install` handler failing, if\n // we get back an invalid response.\n if (!isValidResponse) {\n throw new WorkboxError('bad-precaching-response', {\n url,\n status: response.status,\n });\n }\n // Redirected responses cannot be used to satisfy a navigation request, so\n // any redirected response must be \"copied\" rather than cloned, so the new\n // response doesn't contain the `redirected` flag. See:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1\n if (response.redirected) {\n response = await copyResponse(response);\n }\n await cacheWrapper.put({\n event,\n plugins,\n response,\n // `request` already uses `url`. We may be able to reuse it.\n request: cacheKey === url ? request : new Request(cacheKey),\n cacheName: this._cacheName,\n matchOptions: {\n ignoreSearch: true,\n },\n });\n }\n /**\n * Returns a mapping of a precached URL to the corresponding cache key, taking\n * into account the revision information for the URL.\n *\n * @return {Map} A URL to cache key mapping.\n */\n getURLsToCacheKeys() {\n return this._urlsToCacheKeys;\n }\n /**\n * Returns a list of all the URLs that have been precached by the current\n * service worker.\n *\n * @return {Array} The precached URLs.\n */\n getCachedURLs() {\n return [...this._urlsToCacheKeys.keys()];\n }\n /**\n * Returns the cache key used for storing a given URL. If that URL is\n * unversioned, like `/index.html', then the cache key will be the original\n * URL with a search parameter appended to it.\n *\n * @param {string} url A URL whose cache key you want to look up.\n * @return {string} The versioned URL that corresponds to a cache key\n * for the original URL, or undefined if that URL isn't precached.\n */\n getCacheKeyForURL(url) {\n const urlObject = new URL(url, location.href);\n return this._urlsToCacheKeys.get(urlObject.href);\n }\n /**\n * Returns a function that looks up `url` in the precache (taking into\n * account revision information), and returns the corresponding `Response`.\n *\n * If for an unexpected reason there is a cache miss when looking up `url`,\n * this will fall back to retrieving the `Response` via `fetch()`.\n *\n * @param {string} url The precached URL which will be used to lookup the\n * `Response`.\n * @return {workbox.routing.Route~handlerCallback}\n */\n createHandlerForURL(url) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(url, 'string', {\n moduleName: 'workbox-precaching',\n funcName: 'createHandlerForURL',\n paramName: 'url',\n });\n }\n const cacheKey = this.getCacheKeyForURL(url);\n if (!cacheKey) {\n throw new WorkboxError('non-precached-url', { url });\n }\n return async () => {\n try {\n const cache = await caches.open(this._cacheName);\n const response = await cache.match(cacheKey);\n if (response) {\n return response;\n }\n // This shouldn't normally happen, but there are edge cases:\n // https://github.com/GoogleChrome/workbox/issues/1441\n throw new Error(`The cache ${this._cacheName} did not have an entry ` +\n `for ${cacheKey}.`);\n }\n catch (error) {\n // If there's either a cache miss, or the caches.match() call threw\n // an exception, then attempt to fulfill the navigation request with\n // a response from the network rather than leaving the user with a\n // failed navigation.\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Unable to respond to navigation request with ` +\n `cached response. Falling back to network.`, error);\n }\n // This might still fail if the browser is offline...\n return fetch(cacheKey);\n }\n };\n }\n ;\n}\nexport { PrecacheController };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { PrecacheController } from '../PrecacheController.js';\nimport '../_version.js';\nlet precacheController;\n/**\n * @return {PrecacheController}\n * @private\n */\nexport const getOrCreatePrecacheController = () => {\n if (!precacheController) {\n precacheController = new PrecacheController();\n }\n return precacheController;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { getOrCreatePrecacheController } from './getOrCreatePrecacheController.js';\nimport { generateURLVariations } from './generateURLVariations.js';\nimport '../_version.js';\n/**\n * This function will take the request URL and manipulate it based on the\n * configuration options.\n *\n * @param {string} url\n * @param {Object} options\n * @return {string} Returns the URL in the cache that matches the request,\n * if possible.\n *\n * @private\n */\nexport const getCacheKeyForURL = (url, options) => {\n const precacheController = getOrCreatePrecacheController();\n const urlsToCacheKeys = precacheController.getURLsToCacheKeys();\n for (const possibleURL of generateURLVariations(url, options)) {\n const possibleCacheKey = urlsToCacheKeys.get(possibleURL);\n if (possibleCacheKey) {\n return possibleCacheKey;\n }\n }\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { removeIgnoredSearchParams } from './removeIgnoredSearchParams.js';\nimport '../_version.js';\n/**\n * Generator function that yields possible variations on the original URL to\n * check, one at a time.\n *\n * @param {string} url\n * @param {Object} options\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function* generateURLVariations(url, { ignoreURLParametersMatching, directoryIndex, cleanURLs, urlManipulation, } = {}) {\n const urlObject = new URL(url, location.href);\n urlObject.hash = '';\n yield urlObject.href;\n const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching);\n yield urlWithoutIgnoredParams.href;\n if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) {\n const directoryURL = new URL(urlWithoutIgnoredParams.href);\n directoryURL.pathname += directoryIndex;\n yield directoryURL.href;\n }\n if (cleanURLs) {\n const cleanURL = new URL(urlWithoutIgnoredParams.href);\n cleanURL.pathname += '.html';\n yield cleanURL.href;\n }\n if (urlManipulation) {\n const additionalURLs = urlManipulation({ url: urlObject });\n for (const urlToAttempt of additionalURLs) {\n yield urlToAttempt.href;\n }\n }\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * Removes any URL search parameters that should be ignored.\n *\n * @param {URL} urlObject The original URL.\n * @param {Array} ignoreURLParametersMatching RegExps to test against\n * each search parameter name. Matches mean that the search parameter should be\n * ignored.\n * @return {URL} The URL with any ignored search parameters removed.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) {\n // Convert the iterable into an array at the start of the loop to make sure\n // deletion doesn't mess up iteration.\n for (const paramName of [...urlObject.searchParams.keys()]) {\n if (ignoreURLParametersMatching.some((regExp) => regExp.test(paramName))) {\n urlObject.searchParams.delete(paramName);\n }\n }\n return urlObject;\n}\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addFetchListener } from './utils/addFetchListener.js';\nimport './_version.js';\nlet listenerAdded = false;\n/**\n * Add a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * @param {Object} [options]\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox.precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n *\n * @alias workbox.precaching.addRoute\n */\nexport const addRoute = (options) => {\n if (!listenerAdded) {\n addFetchListener(options);\n listenerAdded = true;\n }\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getCacheKeyForURL } from './getCacheKeyForURL.js';\nimport '../_version.js';\n/**\n * Adds a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * NOTE: when called more than once this method will replace the previously set\n * configuration options. Calling it more than once is not recommended outside\n * of tests.\n *\n * @private\n * @param {Object} [options]\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox.precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n */\nexport const addFetchListener = ({ ignoreURLParametersMatching = [/^utm_/], directoryIndex = 'index.html', cleanURLs = true, urlManipulation, } = {}) => {\n const cacheName = cacheNames.getPrecacheName();\n addEventListener('fetch', (event) => {\n const precachedURL = getCacheKeyForURL(event.request.url, {\n cleanURLs,\n directoryIndex,\n ignoreURLParametersMatching,\n urlManipulation,\n });\n if (!precachedURL) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Precaching did not find a match for ` +\n getFriendlyURL(event.request.url));\n }\n return;\n }\n let responsePromise = caches.open(cacheName).then((cache) => {\n return cache.match(precachedURL);\n }).then((cachedResponse) => {\n if (cachedResponse) {\n return cachedResponse;\n }\n // Fall back to the network if we don't have a cached response\n // (perhaps due to manual cache cleanup).\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`The precached response for ` +\n `${getFriendlyURL(precachedURL)} in ${cacheName} was not found. ` +\n `Falling back to the network instead.`);\n }\n return fetch(precachedURL);\n });\n if (process.env.NODE_ENV !== 'production') {\n responsePromise = responsePromise.then((response) => {\n // Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Precaching is responding to: ` +\n getFriendlyURL(event.request.url));\n logger.log(`Serving the precached url: ${precachedURL}`);\n logger.groupCollapsed(`View request details here.`);\n logger.log(event.request);\n logger.groupEnd();\n logger.groupCollapsed(`View response details here.`);\n logger.log(response);\n logger.groupEnd();\n logger.groupEnd();\n return response;\n });\n }\n event.respondWith(responsePromise);\n });\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js';\nimport { precachePlugins } from './utils/precachePlugins.js';\nimport './_version.js';\nconst installListener = (event) => {\n const precacheController = getOrCreatePrecacheController();\n const plugins = precachePlugins.get();\n event.waitUntil(precacheController.install({ event, plugins })\n .catch((error) => {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Service worker installation failed. It will ` +\n `be retried automatically during the next navigation.`);\n }\n // Re-throw the error to ensure installation fails.\n throw error;\n }));\n};\nconst activateListener = (event) => {\n const precacheController = getOrCreatePrecacheController();\n event.waitUntil(precacheController.activate());\n};\n/**\n * Adds items to the precache list, removing any duplicates and\n * stores the files in the\n * [\"precache cache\"]{@link module:workbox-core.cacheNames} when the service\n * worker installs.\n *\n * This method can be called multiple times.\n *\n * Please note: This method **will not** serve any of the cached files for you.\n * It only precaches files. To respond to a network request you call\n * [addRoute()]{@link module:workbox-precaching.addRoute}.\n *\n * If you have a single array of files to precache, you can just call\n * [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}.\n *\n * @param {Array} [entries=[]] Array of entries to precache.\n *\n * @alias workbox.precaching.precache\n */\nexport const precache = (entries) => {\n const precacheController = getOrCreatePrecacheController();\n precacheController.addToCacheList(entries);\n if (entries.length > 0) {\n // NOTE: these listeners will only be added once (even if the `precache()`\n // method is called multiple times) because event listeners are implemented\n // as a set, where each listener must be unique.\n addEventListener('install', installListener);\n addEventListener('activate', activateListener);\n }\n};\n","// @ts-ignore\ntry {\n self['workbox:range-requests:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { calculateEffectiveBoundaries } from './utils/calculateEffectiveBoundaries.js';\nimport { parseRangeHeader } from './utils/parseRangeHeader.js';\nimport './_version.js';\n/**\n * Given a `Request` and `Response` objects as input, this will return a\n * promise for a new `Response`.\n *\n * If the original `Response` already contains partial content (i.e. it has\n * a status of 206), then this assumes it already fulfills the `Range:`\n * requirements, and will return it as-is.\n *\n * @param {Request} request A request, which should contain a Range:\n * header.\n * @param {Response} originalResponse A response.\n * @return {Promise} Either a `206 Partial Content` response, with\n * the response body set to the slice of content specified by the request's\n * `Range:` header, or a `416 Range Not Satisfiable` response if the\n * conditions of the `Range:` header can't be met.\n *\n * @memberof workbox.rangeRequests\n */\nasync function createPartialResponse(request, originalResponse) {\n try {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'request',\n });\n assert.isInstance(originalResponse, Response, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'originalResponse',\n });\n }\n if (originalResponse.status === 206) {\n // If we already have a 206, then just pass it through as-is;\n // see https://github.com/GoogleChrome/workbox/issues/1720\n return originalResponse;\n }\n const rangeHeader = request.headers.get('range');\n if (!rangeHeader) {\n throw new WorkboxError('no-range-header');\n }\n const boundaries = parseRangeHeader(rangeHeader);\n const originalBlob = await originalResponse.blob();\n const effectiveBoundaries = calculateEffectiveBoundaries(originalBlob, boundaries.start, boundaries.end);\n const slicedBlob = originalBlob.slice(effectiveBoundaries.start, effectiveBoundaries.end);\n const slicedBlobSize = slicedBlob.size;\n const slicedResponse = new Response(slicedBlob, {\n // Status code 206 is for a Partial Content response.\n // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206\n status: 206,\n statusText: 'Partial Content',\n headers: originalResponse.headers,\n });\n slicedResponse.headers.set('Content-Length', String(slicedBlobSize));\n slicedResponse.headers.set('Content-Range', `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` +\n originalBlob.size);\n return slicedResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to construct a partial response; returning a ` +\n `416 Range Not Satisfiable response instead.`);\n logger.groupCollapsed(`View details here.`);\n logger.log(error);\n logger.log(request);\n logger.log(originalResponse);\n logger.groupEnd();\n }\n return new Response('', {\n status: 416,\n statusText: 'Range Not Satisfiable',\n });\n }\n}\nexport { createPartialResponse };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {string} rangeHeader A Range: header value.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the parsed value of the Range: header. If either the `start` or `end` are\n * omitted, then `null` will be returned.\n *\n * @private\n */\nfunction parseRangeHeader(rangeHeader) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(rangeHeader, 'string', {\n moduleName: 'workbox-range-requests',\n funcName: 'parseRangeHeader',\n paramName: 'rangeHeader',\n });\n }\n const normalizedRangeHeader = rangeHeader.trim().toLowerCase();\n if (!normalizedRangeHeader.startsWith('bytes=')) {\n throw new WorkboxError('unit-must-be-bytes', { normalizedRangeHeader });\n }\n // Specifying multiple ranges separate by commas is valid syntax, but this\n // library only attempts to handle a single, contiguous sequence of bytes.\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#Syntax\n if (normalizedRangeHeader.includes(',')) {\n throw new WorkboxError('single-range-only', { normalizedRangeHeader });\n }\n const rangeParts = /(\\d*)-(\\d*)/.exec(normalizedRangeHeader);\n // We need either at least one of the start or end values.\n if (!rangeParts || !(rangeParts[1] || rangeParts[2])) {\n throw new WorkboxError('invalid-range-values', { normalizedRangeHeader });\n }\n return {\n start: rangeParts[1] === '' ? undefined : Number(rangeParts[1]),\n end: rangeParts[2] === '' ? undefined : Number(rangeParts[2]),\n };\n}\nexport { parseRangeHeader };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {Blob} blob A source blob.\n * @param {number} [start] The offset to use as the start of the\n * slice.\n * @param {number} [end] The offset to use as the end of the slice.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the effective boundaries to use given the size of the blob.\n *\n * @private\n */\nfunction calculateEffectiveBoundaries(blob, start, end) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(blob, Blob, {\n moduleName: 'workbox-range-requests',\n funcName: 'calculateEffectiveBoundaries',\n paramName: 'blob',\n });\n }\n const blobSize = blob.size;\n if ((end && end > blobSize) || (start && start < 0)) {\n throw new WorkboxError('range-not-satisfiable', {\n size: blobSize,\n end,\n start,\n });\n }\n let effectiveStart;\n let effectiveEnd;\n if (start !== undefined && end !== undefined) {\n effectiveStart = start;\n // Range values are inclusive, so add 1 to the value.\n effectiveEnd = end + 1;\n }\n else if (start !== undefined && end === undefined) {\n effectiveStart = start;\n effectiveEnd = blobSize;\n }\n else if (end !== undefined && start === undefined) {\n effectiveStart = blobSize - end;\n effectiveEnd = blobSize;\n }\n return {\n start: effectiveStart,\n end: effectiveEnd,\n };\n}\nexport { calculateEffectiveBoundaries };\n","// @ts-ignore\ntry {\n self['workbox:routing:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * The default HTTP method, 'GET', used when there's no specific method\n * configured for a route.\n *\n * @type {string}\n *\n * @private\n */\nexport const defaultMethod = 'GET';\n/**\n * The list of valid HTTP methods associated with requests that could be routed.\n *\n * @type {Array}\n *\n * @private\n */\nexport const validMethods = [\n 'DELETE',\n 'GET',\n 'HEAD',\n 'PATCH',\n 'POST',\n 'PUT',\n];\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {function()|Object} handler Either a function, or an object with a\n * 'handle' method.\n * @return {Object} An object with a handle method.\n *\n * @private\n */\nexport const normalizeHandler = (handler) => {\n if (handler && typeof handler === 'object') {\n if (process.env.NODE_ENV !== 'production') {\n assert.hasMethod(handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return handler;\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(handler, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return { handle: handler };\n }\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { defaultMethod, validMethods } from './utils/constants.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * A `Route` consists of a pair of callback functions, \"match\" and \"handler\".\n * The \"match\" callback determine if a route should be used to \"handle\" a\n * request by returning a non-falsy value if it can. The \"handler\" callback\n * is called when there is a match and should return a Promise that resolves\n * to a `Response`.\n *\n * @memberof workbox.routing\n */\nclass Route {\n /**\n * Constructor for Route class.\n *\n * @param {workbox.routing.Route~matchCallback} match\n * A callback function that determines whether the route matches a given\n * `fetch` event by returning a non-falsy value.\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resolving to a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(match, handler, method = defaultMethod) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(match, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'match',\n });\n if (method) {\n assert.isOneOf(method, validMethods, { paramName: 'method' });\n }\n }\n // These values are referenced directly by Router so cannot be\n // altered by minifification.\n this.handler = normalizeHandler(handler);\n this.match = match;\n this.method = method;\n }\n}\nexport { Route };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { Route } from './Route.js';\nimport './_version.js';\n/**\n * RegExpRoute makes it easy to create a regular expression based\n * [Route]{@link workbox.routing.Route}.\n *\n * For same-origin requests the RegExp only needs to match part of the URL. For\n * requests against third-party servers, you must define a RegExp that matches\n * the start of the URL.\n *\n * [See the module docs for info.]{@link https://developers.google.com/web/tools/workbox/modules/workbox-routing}\n *\n * @memberof workbox.routing\n * @extends workbox.routing.Route\n */\nclass RegExpRoute extends Route {\n /**\n * If the regulard expression contains\n * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},\n * th ecaptured values will be passed to the\n * [handler's]{@link workbox.routing.Route~handlerCallback} `params`\n * argument.\n *\n * @param {RegExp} regExp The regular expression to match against URLs.\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(regExp, handler, method) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(regExp, RegExp, {\n moduleName: 'workbox-routing',\n className: 'RegExpRoute',\n funcName: 'constructor',\n paramName: 'pattern',\n });\n }\n const match = ({ url }) => {\n const result = regExp.exec(url.href);\n // Return immediately if there's no match.\n if (!result) {\n return;\n }\n // Require that the match start at the first character in the URL string\n // if it's a cross-origin request.\n // See https://github.com/GoogleChrome/workbox/issues/281 for the context\n // behind this behavior.\n if ((url.origin !== location.origin) && (result.index !== 0)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`The regular expression '${regExp}' only partially matched ` +\n `against the cross-origin URL '${url}'. RegExpRoute's will only ` +\n `handle cross-origin requests if they match the entire URL.`);\n }\n return;\n }\n // If the route matches, but there aren't any capture groups defined, then\n // this will return [], which is truthy and therefore sufficient to\n // indicate a match.\n // If there are capture groups, then it will return their values.\n return result.slice(1);\n };\n super(match, handler, method);\n }\n}\nexport { RegExpRoute };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * The Router can be used to process a FetchEvent through one or more\n * [Routes]{@link workbox.routing.Route} responding with a Request if\n * a matching route exists.\n *\n * If no route matches a given a request, the Router will use a \"default\"\n * handler if one is defined.\n *\n * Should the matching Route throw an error, the Router will use a \"catch\"\n * handler if one is defined to gracefully deal with issues and respond with a\n * Request.\n *\n * If a request matches multiple routes, the **earliest** registered route will\n * be used to respond to the request.\n *\n * @memberof workbox.routing\n */\nclass Router {\n /**\n * Initializes a new Router.\n */\n constructor() {\n this._routes = new Map();\n }\n /**\n * @return {Map>} routes A `Map` of HTTP\n * method name ('GET', etc.) to an array of all the corresponding `Route`\n * instances that are registered.\n */\n get routes() {\n return this._routes;\n }\n /**\n * Adds a fetch event listener to respond to events when a route matches\n * the event's request.\n */\n addFetchListener() {\n self.addEventListener('fetch', (event) => {\n const { request } = event;\n const responsePromise = this.handleRequest({ request, event });\n if (responsePromise) {\n event.respondWith(responsePromise);\n }\n });\n }\n /**\n * Adds a message event listener for URLs to cache from the window.\n * This is useful to cache resources loaded on the page prior to when the\n * service worker started controlling it.\n *\n * The format of the message data sent from the window should be as follows.\n * Where the `urlsToCache` array may consist of URL strings or an array of\n * URL string + `requestInit` object (the same as you'd pass to `fetch()`).\n *\n * ```\n * {\n * type: 'CACHE_URLS',\n * payload: {\n * urlsToCache: [\n * './script1.js',\n * './script2.js',\n * ['./script3.js', {mode: 'no-cors'}],\n * ],\n * },\n * }\n * ```\n */\n addCacheListener() {\n self.addEventListener('message', async (event) => {\n if (event.data && event.data.type === 'CACHE_URLS') {\n const { payload } = event.data;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Caching URLs from the window`, payload.urlsToCache);\n }\n const requestPromises = Promise.all(payload.urlsToCache.map((entry) => {\n if (typeof entry === 'string') {\n entry = [entry];\n }\n const request = new Request(...entry);\n return this.handleRequest({ request });\n // TODO(philipwalton): TypeScript errors without this typecast for\n // some reason (probably a bug). The real type here should work but\n // doesn't: `Array | undefined>`.\n })); // TypeScript\n event.waitUntil(requestPromises);\n // If a MessageChannel was used, reply to the message on success.\n if (event.ports && event.ports[0]) {\n await requestPromises;\n event.ports[0].postMessage(true);\n }\n }\n });\n }\n /**\n * Apply the routing rules to a FetchEvent object to get a Response from an\n * appropriate Route's handler.\n *\n * @param {Object} options\n * @param {Request} options.request The request to handle (this is usually\n * from a fetch event, but it does not have to be).\n * @param {FetchEvent} [options.event] The event that triggered the request,\n * if applicable.\n * @return {Promise|undefined} A promise is returned if a\n * registered route can handle the request. If there is no matching\n * route and there's no `defaultHandler`, `undefined` is returned.\n */\n handleRequest({ request, event }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'handleRequest',\n paramName: 'options.request',\n });\n }\n const url = new URL(request.url, location.href);\n if (!url.protocol.startsWith('http')) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Workbox Router only supports URLs that start with 'http'.`);\n }\n return;\n }\n let { params, route } = this.findMatchingRoute({ url, request, event });\n let handler = route && route.handler;\n let debugMessages = [];\n if (process.env.NODE_ENV !== 'production') {\n if (handler) {\n debugMessages.push([\n `Found a route to handle this request:`, route,\n ]);\n if (params) {\n debugMessages.push([\n `Passing the following params to the route's handler:`, params,\n ]);\n }\n }\n }\n // If we don't have a handler because there was no matching route, then\n // fall back to defaultHandler if that's defined.\n if (!handler && this._defaultHandler) {\n if (process.env.NODE_ENV !== 'production') {\n debugMessages.push(`Failed to find a matching route. Falling ` +\n `back to the default handler.`);\n }\n handler = this._defaultHandler;\n }\n if (!handler) {\n if (process.env.NODE_ENV !== 'production') {\n // No handler so Workbox will do nothing. If logs is set of debug\n // i.e. verbose, we should print out this information.\n logger.debug(`No route found for: ${getFriendlyURL(url)}`);\n }\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n // We have a handler, meaning Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`);\n debugMessages.forEach((msg) => {\n if (Array.isArray(msg)) {\n logger.log(...msg);\n }\n else {\n logger.log(msg);\n }\n });\n // The Request and Response objects contains a great deal of information,\n // hide it under a group in case developers want to see it.\n logger.groupCollapsed(`View request details here.`);\n logger.log(request);\n logger.groupEnd();\n logger.groupEnd();\n }\n // Wrap in try and catch in case the handle method throws a synchronous\n // error. It should still callback to the catch handler.\n let responsePromise;\n try {\n responsePromise = handler.handle({ url, request, event, params });\n }\n catch (err) {\n responsePromise = Promise.reject(err);\n }\n if (responsePromise && this._catchHandler) {\n responsePromise = responsePromise.catch((err) => {\n if (process.env.NODE_ENV !== 'production') {\n // Still include URL here as it will be async from the console group\n // and may not make sense without the URL\n logger.groupCollapsed(`Error thrown when responding to: ` +\n ` ${getFriendlyURL(url)}. Falling back to Catch Handler.`);\n logger.error(`Error thrown by:`, route);\n logger.error(err);\n logger.groupEnd();\n }\n return this._catchHandler.handle({ url, request, event });\n });\n }\n return responsePromise;\n }\n /**\n * Checks a request and URL (and optionally an event) against the list of\n * registered routes, and if there's a match, returns the corresponding\n * route along with any params generated by the match.\n *\n * @param {Object} options\n * @param {URL} options.url\n * @param {Request} options.request The request to match.\n * @param {Event} [options.event] The corresponding event (unless N/A).\n * @return {Object} An object with `route` and `params` properties.\n * They are populated if a matching route was found or `undefined`\n * otherwise.\n */\n findMatchingRoute({ url, request, event }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(url, URL, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'findMatchingRoute',\n paramName: 'options.url',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'findMatchingRoute',\n paramName: 'options.request',\n });\n }\n const routes = this._routes.get(request.method) || [];\n for (const route of routes) {\n let params;\n let matchResult = route.match({ url, request, event });\n if (matchResult) {\n // See https://github.com/GoogleChrome/workbox/issues/2079\n params = matchResult;\n if (Array.isArray(matchResult) && matchResult.length === 0) {\n // Instead of passing an empty array in as params, use undefined.\n params = undefined;\n }\n else if ((matchResult.constructor === Object &&\n Object.keys(matchResult).length === 0)) {\n // Instead of passing an empty object in as params, use undefined.\n params = undefined;\n }\n else if (typeof matchResult === 'boolean') {\n // For the boolean value true (rather than just something truth-y),\n // don't set params.\n // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353\n params = undefined;\n }\n // Return early if have a match.\n return { route, params };\n }\n }\n // If no match was found above, return and empty object.\n return {};\n }\n /**\n * Define a default `handler` that's called when no routes explicitly\n * match the incoming request.\n *\n * Without a default handler, unmatched requests will go against the\n * network as if there were no service worker present.\n *\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setDefaultHandler(handler) {\n this._defaultHandler = normalizeHandler(handler);\n }\n /**\n * If a Route throws an error while handling a request, this `handler`\n * will be called and given a chance to provide a response.\n *\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setCatchHandler(handler) {\n this._catchHandler = normalizeHandler(handler);\n }\n /**\n * Registers a route with the router.\n *\n * @param {workbox.routing.Route} route The route to register.\n */\n registerRoute(route) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(route, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route, 'match', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.isType(route.handler, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route.handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.handler',\n });\n assert.isType(route.method, 'string', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.method',\n });\n }\n if (!this._routes.has(route.method)) {\n this._routes.set(route.method, []);\n }\n // Give precedence to all of the earlier routes by adding this additional\n // route to the end of the array.\n this._routes.get(route.method).push(route);\n }\n /**\n * Unregisters a route with the router.\n *\n * @param {workbox.routing.Route} route The route to unregister.\n */\n unregisterRoute(route) {\n if (!this._routes.has(route.method)) {\n throw new WorkboxError('unregister-route-but-not-found-with-method', {\n method: route.method,\n });\n }\n const routeIndex = this._routes.get(route.method).indexOf(route);\n if (routeIndex > -1) {\n this._routes.get(route.method).splice(routeIndex, 1);\n }\n else {\n throw new WorkboxError('unregister-route-route-not-registered');\n }\n }\n}\nexport { Router };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { Router } from '../Router.js';\nimport '../_version.js';\nlet defaultRouter;\n/**\n * Creates a new, singleton Router instance if one does not exist. If one\n * does already exist, that instance is returned.\n *\n * @private\n * @return {Router}\n */\nexport const getOrCreateDefaultRouter = () => {\n if (!defaultRouter) {\n defaultRouter = new Router();\n // The helpers that use the default Router assume these listeners exist.\n defaultRouter.addFetchListener();\n defaultRouter.addCacheListener();\n }\n return defaultRouter;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { Route } from './Route.js';\nimport { RegExpRoute } from './RegExpRoute.js';\nimport { getOrCreateDefaultRouter } from './utils/getOrCreateDefaultRouter.js';\nimport './_version.js';\n/**\n * Easily register a RegExp, string, or function with a caching\n * strategy to a singleton Router instance.\n *\n * This method will generate a Route for you if needed and\n * call [Router.registerRoute()]{@link\n * workbox.routing.Router#registerRoute}.\n *\n * @param {\n * RegExp|\n * string|\n * workbox.routing.Route~matchCallback|\n * workbox.routing.Route\n * } capture\n * If the capture param is a `Route`, all other arguments will be ignored.\n * @param {workbox.routing.Route~handlerCallback} [handler] A callback\n * function that returns a Promise resulting in a Response. This parameter\n * is required if `capture` is not a `Route` object.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n * @return {workbox.routing.Route} The generated `Route`(Useful for\n * unregistering).\n *\n * @alias workbox.routing.registerRoute\n */\nexport const registerRoute = (capture, handler, method) => {\n let route;\n if (typeof capture === 'string') {\n const captureUrl = new URL(capture, location.href);\n if (process.env.NODE_ENV !== 'production') {\n if (!(capture.startsWith('/') || capture.startsWith('http'))) {\n throw new WorkboxError('invalid-string', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n // We want to check if Express-style wildcards are in the pathname only.\n // TODO: Remove this log message in v4.\n const valueToCheck = capture.startsWith('http') ?\n captureUrl.pathname : capture;\n // See https://github.com/pillarjs/path-to-regexp#parameters\n const wildcards = '[*:?+]';\n if (valueToCheck.match(new RegExp(`${wildcards}`))) {\n logger.debug(`The '$capture' parameter contains an Express-style wildcard ` +\n `character (${wildcards}). Strings are now always interpreted as ` +\n `exact matches; use a RegExp for partial or wildcard matches.`);\n }\n }\n const matchCallback = ({ url }) => {\n if (process.env.NODE_ENV !== 'production') {\n if ((url.pathname === captureUrl.pathname) &&\n (url.origin !== captureUrl.origin)) {\n logger.debug(`${capture} only partially matches the cross-origin URL ` +\n `${url}. This route will only handle cross-origin requests ` +\n `if they match the entire URL.`);\n }\n }\n return url.href === captureUrl.href;\n };\n // If `capture` is a string then `handler` and `method` must be present.\n route = new Route(matchCallback, handler, method);\n }\n else if (capture instanceof RegExp) {\n // If `capture` is a `RegExp` then `handler` and `method` must be present.\n route = new RegExpRoute(capture, handler, method);\n }\n else if (typeof capture === 'function') {\n // If `capture` is a function then `handler` and `method` must be present.\n route = new Route(capture, handler, method);\n }\n else if (capture instanceof Route) {\n route = capture;\n }\n else {\n throw new WorkboxError('unsupported-route-type', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n const defaultRouter = getOrCreateDefaultRouter();\n defaultRouter.registerRoute(route);\n return route;\n};\n","/**\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n **/\n\nexport const cacheName = 'media';\nexport const channelName = 'messages';\nexport const fadeConfig = {duration: 200};\nexport const urlPrefix = '/_media/';\n","/**\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n **/\n\nimport {cacheName} from './constants';\n\nasync function _getCachedMediaMetadata() {\n const cache = await caches.open(cacheName);\n const requests = await cache.keys();\n return Promise.all(requests.reverse().map(async (request) => {\n const response = await cache.match(request);\n return {\n contentType: response.headers.get('content-type'),\n src: request.url,\n };\n }));\n}\nconst cachedMediaMetadataPromise = _getCachedMediaMetadata();\n\nexport async function getCachedMediaMetadata(contentTypePrefix) {\n const cachedMetadata = await cachedMediaMetadataPromise;\n return cachedMetadata.filter((metadata) => metadata.contentType.startsWith(contentTypePrefix));\n}\n\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n\n","import {CacheOnly} from 'workbox-strategies';\nimport {clientsClaim, skipWaiting} from 'workbox-core';\nimport {precacheAndRoute} from 'workbox-precaching';\nimport {RangeRequestsPlugin} from 'workbox-range-requests';\nimport {registerRoute} from 'workbox-routing';\n\nimport {cacheName, channelName, urlPrefix} from './constants';\nimport {mimeRoute as audioRoute} from '../svelte/routes/Audio.svelte';\nimport {mimeRoute as imagesRoute} from '../svelte/routes/Images.svelte';\nimport {mimeRoute as videosRoute} from '../svelte/routes/Videos.svelte';\n\nconst broadcastChannel = BroadcastChannel ? new BroadcastChannel(channelName) : null;\n\nconst shareTargetHandler = async ({event}) => {\n if (broadcastChannel) {\n broadcastChannel.postMessage('Saving media locally...');\n }\n\n const formData = await event.request.formData();\n const mediaFiles = formData.getAll('media');\n const cache = await caches.open(cacheName);\n\n for (const mediaFile of mediaFiles) {\n // TODO: Instead of bailing, come up with a\n // default name for each possible MIME type.\n if (!mediaFile.name) {\n if (broadcastChannel) {\n broadcastChannel.postMessage('Sorry! No name found on incoming media.');\n }\n continue;\n }\n await cache.put(\n // TODO: Handle scenarios in which mediaFile.name isn't set,\n // or doesn't include a proper extension.\n `${urlPrefix}${Date.now()}-${mediaFile.name}`,\n new Response(mediaFile, {\n headers: {\n 'content-length': mediaFile.size,\n 'content-type': mediaFile.type,\n },\n })\n );\n }\n\n // Use the MIME type of the first file shared to determine where we redirect.\n const routeToRedirectTo = [\n audioRoute,\n imagesRoute,\n videosRoute,\n ].find((route) => mediaFiles[0].type.startsWith(route.mimePrefix));\n\n const redirectionUrl = routeToRedirectTo ? `/#${routeToRedirectTo.href}` : '/';\n \n // After the POST succeeds, redirect to the main page.\n return Response.redirect(redirectionUrl, 303);\n};\n\nconst cachedMediaHandler = new CacheOnly({\n cacheName,\n plugins: [\n // Support for cache requests that include a Range: header.\n new RangeRequestsPlugin(),\n ],\n});\n\nskipWaiting();\nclientsClaim();\n\n// This will be replaced by the list of files to precache by\n// the `workbox injectManifest` build step.\nprecacheAndRoute(self.__WB_MANIFEST);\n\nregisterRoute(\n '/_share-target',\n shareTargetHandler,\n 'POST'\n);\n\nregisterRoute(\n new RegExp(urlPrefix),\n cachedMediaHandler\n);\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { cacheWrapper } from 'workbox-core/_private/cacheWrapper.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { messages } from './utils/messages.js';\nimport './_version.js';\n/**\n * An implementation of a\n * [cache-only]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-only}\n * request strategy.\n *\n * This class is useful if you want to take advantage of any\n * [Workbox plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}.\n *\n * If there is no cache match, this will throw a `WorkboxError` exception.\n *\n * @memberof workbox.strategies\n */\nclass CacheOnly {\n /**\n * @param {Object} options\n * @param {string} options.cacheName Cache name to store and retrieve\n * requests. Defaults to cache names provided by\n * [workbox-core]{@link workbox.core.cacheNames}.\n * @param {Array} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}\n * to use in conjunction with this caching strategy.\n * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)\n */\n constructor(options = {}) {\n this._cacheName = cacheNames.getRuntimeName(options.cacheName);\n this._plugins = options.plugins || [];\n this._matchOptions = options.matchOptions;\n }\n /**\n * This method will perform a request strategy and follows an API that\n * will work with the\n * [Workbox Router]{@link workbox.routing.Router}.\n *\n * @param {Object} options\n * @param {Request} options.request The request to run this strategy for.\n * @param {Event} [options.event] The event that triggered the request.\n * @return {Promise}\n */\n async handle({ event, request }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-strategies',\n className: 'CacheOnly',\n funcName: 'makeRequest',\n paramName: 'request',\n });\n }\n const response = await cacheWrapper.match({\n cacheName: this._cacheName,\n request,\n event,\n matchOptions: this._matchOptions,\n plugins: this._plugins,\n });\n if (process.env.NODE_ENV !== 'production') {\n logger.groupCollapsed(messages.strategyStart('CacheOnly', request));\n if (response) {\n logger.log(`Found a cached response in the '${this._cacheName}'` +\n ` cache.`);\n messages.printFinalResponse(response);\n }\n else {\n logger.log(`No response found in the '${this._cacheName}' cache.`);\n }\n logger.groupEnd();\n }\n if (!response) {\n throw new WorkboxError('no-response', { url: request.url });\n }\n return response;\n }\n}\nexport { CacheOnly };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { createPartialResponse } from './createPartialResponse.js';\nimport './_version.js';\n/**\n * The range request plugin makes it easy for a request with a 'Range' header to\n * be fulfilled by a cached response.\n *\n * It does this by intercepting the `cachedResponseWillBeUsed` plugin callback\n * and returning the appropriate subset of the cached response body.\n *\n * @memberof workbox.rangeRequests\n */\nclass RangeRequestsPlugin {\n constructor() {\n /**\n * @param {Object} options\n * @param {Request} options.request The original request, which may or may not\n * contain a Range: header.\n * @param {Response} options.cachedResponse The complete cached response.\n * @return {Promise} If request contains a 'Range' header, then a\n * new response with status 206 whose body is a subset of `cachedResponse` is\n * returned. Otherwise, `cachedResponse` is returned as-is.\n *\n * @private\n */\n this.cachedResponseWillBeUsed = async ({ request, cachedResponse }) => {\n // Only return a sliced response if there's something valid in the cache,\n // and there's a Range: header in the request.\n if (cachedResponse && request.headers.has('range')) {\n return await createPartialResponse(request, cachedResponse);\n }\n // If there was no Range: header, or if cachedResponse wasn't valid, just\n // pass it through as-is.\n return cachedResponse;\n };\n }\n}\nexport { RangeRequestsPlugin };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addRoute } from './addRoute.js';\nimport { precache } from './precache.js';\nimport './_version.js';\n/**\n * This method will add entries to the precache list and add a route to\n * respond to fetch events.\n *\n * This is a convenience method that will call\n * [precache()]{@link module:workbox-precaching.precache} and\n * [addRoute()]{@link module:workbox-precaching.addRoute} in a single call.\n *\n * @param {Array} entries Array of entries to precache.\n * @param {Object} [options] See\n * [addRoute() options]{@link module:workbox-precaching.addRoute}.\n *\n * @alias workbox.precaching.precacheAndRoute\n */\nexport const precacheAndRoute = (entries, options) => {\n precache(entries);\n addRoute(options);\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Force a service worker to become active, instead of waiting. This is\n * normally used in conjunction with `clientsClaim()`.\n *\n * @alias workbox.core.skipWaiting\n */\nexport const skipWaiting = () => {\n // We need to explicitly call `self.skipWaiting()` here because we're\n // shadowing `skipWaiting` with this local function.\n addEventListener('install', () => self.skipWaiting());\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Claim any currently available clients once the service worker\n * becomes active. This is normally used in conjunction with `skipWaiting()`.\n *\n * @alias workbox.core.clientsClaim\n */\nexport const clientsClaim = () => {\n addEventListener('activate', () => self.clients.claim());\n};\n"]} \ No newline at end of file +{"version":3,"sources":["../node_modules/workbox-core/_version.js","../node_modules/workbox-core/_private/logger.js","../node_modules/workbox-core/models/messages/messageGenerator.js","../node_modules/workbox-core/_private/WorkboxError.js","../node_modules/workbox-core/_private/assert.js","../node_modules/workbox-core/_private/cacheNames.js","../node_modules/workbox-core/_private/getFriendlyURL.js","../node_modules/workbox-core/models/quotaErrorCallbacks.js","../node_modules/workbox-core/utils/pluginUtils.js","../node_modules/workbox-core/_private/cacheWrapper.js","../node_modules/workbox-core/_private/executeQuotaErrorCallbacks.js","../node_modules/workbox-core/_private/fetchWrapper.js","../node_modules/workbox-strategies/_version.js","../node_modules/workbox-core/_private/canConstructResponseFromBodyStream.js","../node_modules/workbox-core/_private/DBWrapper.js","../node_modules/workbox-core/copyResponse.js","../node_modules/workbox-precaching/_version.js","../node_modules/workbox-precaching/utils/precachePlugins.js","../node_modules/workbox-precaching/utils/createCacheKey.js","../node_modules/workbox-precaching/PrecacheController.js","../node_modules/workbox-precaching/utils/getOrCreatePrecacheController.js","../node_modules/workbox-precaching/utils/getCacheKeyForURL.js","../node_modules/workbox-precaching/utils/generateURLVariations.js","../node_modules/workbox-precaching/utils/removeIgnoredSearchParams.js","../node_modules/workbox-precaching/addRoute.js","../node_modules/workbox-precaching/utils/addFetchListener.js","../node_modules/workbox-precaching/precache.js","../node_modules/workbox-range-requests/_version.js","../node_modules/workbox-range-requests/createPartialResponse.js","../node_modules/workbox-range-requests/utils/parseRangeHeader.js","../node_modules/workbox-range-requests/utils/calculateEffectiveBoundaries.js","../node_modules/workbox-routing/_version.js","../node_modules/workbox-routing/utils/constants.js","../node_modules/workbox-routing/utils/normalizeHandler.js","../node_modules/workbox-routing/Route.js","../node_modules/workbox-routing/RegExpRoute.js","../node_modules/workbox-routing/Router.js","../node_modules/workbox-routing/utils/getOrCreateDefaultRouter.js","../node_modules/workbox-routing/registerRoute.js","../src/js/constants.js","../src/js/getCachedMediaMetadata.js","../src/svelte/routes/Audio.svelte","../src/svelte/routes/Images.svelte","../src/svelte/routes/Videos.svelte","../src/js/service-worker.js","../node_modules/workbox-strategies/CacheOnly.js","../node_modules/workbox-range-requests/RangeRequestsPlugin.js","../node_modules/workbox-precaching/precacheAndRoute.js","../node_modules/workbox-core/skipWaiting.js","../node_modules/workbox-core/clientsClaim.js"],"names":["self","_","e","messageGenerator","code","args","msg","length","JSON","stringify","WorkboxError","Error","[object Object]","errorCode","details","super","this","name","_cacheNameDetails","googleAnalytics","precache","prefix","runtime","suffix","registration","scope","_createCacheName","cacheName","filter","value","join","cacheNames","updateDetails","fn","key","Object","keys","eachCacheNameDetail","getGoogleAnalyticsName","userCacheName","getPrecacheName","getPrefix","getRuntimeName","getSuffix","getFriendlyURL","url","urlObj","URL","String","location","href","origin","pathname","quotaErrorCallbacks","Set","pluginUtils","plugins","callbackName","plugin","matchWrapper","async","request","event","matchOptions","cache","caches","open","effectiveRequest","_getEffectiveRequest","mode","cachedResponse","match","pluginMethod","call","_isResponseSafeToCache","response","responseToCache","pluginsUsed","status","undefined","cacheKeyWillBeUsedPlugins","Request","cacheWrapper","put","updatePlugins","oldResponse","error","callback","executeQuotaErrorCallbacks","newResponse","fetchWrapper","fetch","fetchOptions","FetchEvent","preloadResponse","possiblePreloadResponse","failedFetchPlugins","originalRequest","clone","requestClone","err","thrownError","pluginFilteredRequest","fetchResponse","supportStatus","DBWrapper","version","onupgradeneeded","onversionchange","_db","_name","_version","_onupgradeneeded","_onversionchange","close","db","Promise","resolve","reject","openRequestTimedOut","setTimeout","OPEN_TIMEOUT","openRequest","indexedDB","onerror","evt","transaction","abort","result","onsuccess","bind","storeName","query","getAllKeys","count","getAllMatching","includeKeys","map","entry","index","direction","txn","done","store","objectStore","target","results","openCursor","cursor","push","continue","storeNames","type","onabort","oncomplete","method","objStore","apply","prototype","methodsToWrap","readonly","readwrite","methods","entries","IDBObjectStore","_call","copyResponse","modifier","clonedResponse","responseInit","headers","Headers","statusText","modifiedResponseInit","body","testResponse","Response","canConstructResponseFromBodyStream","blob","precachePlugins","get","newPlugins","REVISION_SEARCH_PARAM","createCacheKey","urlObject","cacheKey","revision","cacheKeyURL","originalURL","searchParams","set","PrecacheController","_cacheName","_urlsToCacheKeys","Map","_cacheKeysToIntegrities","has","firstEntry","secondEntry","integrity","toBePrecached","alreadyPrecached","alreadyCachedRequests","existingCacheKeys","precacheRequests","_addURLToCache","all","updatedURLs","item","notUpdatedURLs","currentlyCachedRequests","expectedCacheKeys","values","deletedURLs","delete","credentials","cacheWillUpdatePlugin","cacheWillUpdate","redirected","ignoreSearch","getCacheKeyForURL","precacheController","getOrCreatePrecacheController","options","urlsToCacheKeys","getURLsToCacheKeys","possibleURL","ignoreURLParametersMatching","directoryIndex","cleanURLs","urlManipulation","hash","urlWithoutIgnoredParams","paramName","some","regExp","test","removeIgnoredSearchParams","endsWith","directoryURL","cleanURL","additionalURLs","urlToAttempt","generateURLVariations","possibleCacheKey","listenerAdded","addRoute","addEventListener","precachedURL","responsePromise","then","respondWith","addFetchListener","installListener","waitUntil","install","catch","activateListener","activate","createPartialResponse","originalResponse","rangeHeader","boundaries","normalizedRangeHeader","trim","toLowerCase","startsWith","includes","rangeParts","exec","start","Number","end","parseRangeHeader","originalBlob","effectiveBoundaries","blobSize","size","effectiveStart","effectiveEnd","calculateEffectiveBoundaries","slicedBlob","slice","slicedBlobSize","slicedResponse","defaultMethod","normalizeHandler","handler","handle","Route","RegExpRoute","Router","_routes","routes","handleRequest","data","payload","requestPromises","urlsToCache","ports","postMessage","protocol","params","route","findMatchingRoute","_defaultHandler","_catchHandler","matchResult","Array","isArray","constructor","routeIndex","indexOf","splice","defaultRouter","getOrCreateDefaultRouter","addCacheListener","registerRoute","capture","captureUrl","RegExp","moduleName","funcName","requests","reverse","contentType","src","_getCachedMediaMetadata","mimeRoute","mimePrefix","broadcastChannel","BroadcastChannel","cachedMediaHandler","_plugins","_matchOptions","cachedResponseWillBeUsed","skipWaiting","clients","claim","addToCacheList","__WB_MANIFEST","mediaFiles","formData","getAll","mediaFile","Date","now","content-length","content-type","routeToRedirectTo","audioRoute","imagesRoute","videosRoute","find","redirectionUrl","redirect"],"mappings":"yBACA,IACI,KAAK,8BAAgC,IAEzC,MAAO,ICGP,MCgBa,EAdI,CAAC,KAAS,KACvB,IAAI,EAAM,EAIV,OAHI,EAAK,OAAS,IACd,UAAc,KAAK,UAAU,MAE1B,GCIX,MAAM,UAAqB,MASvB,YAAY,EAAW,GAEnB,MADc,EAAiB,EAAW,IAE1C,KAAK,KAAO,EACZ,KAAK,QAAU,GCkCvB,MCzDM,EAAoB,CACtB,gBAAiB,kBACjB,SAAU,cACV,OAAQ,UACR,QAAS,UACT,OAAQ,aAAa,OAEnB,EAAoB,GACf,CAAC,EAAkB,OAAQ,EAAW,EAAkB,QAC1D,OAAQ,GAAU,GAAS,EAAM,OAAS,GAC1C,KAAK,KAOD,EAAa,CACtB,cAAgB,IANQ,CAAC,IACzB,IAAK,MAAM,KAAO,OAAO,KAAK,GAC1B,EAAG,IAKH,CAAqB,IACW,iBAAjB,EAAQ,KACf,EAAkB,GAAO,EAAQ,OAI7C,uBAAyB,GACd,GAAiB,EAAiB,EAAkB,iBAE/D,gBAAkB,GACP,GAAiB,EAAiB,EAAkB,UAE/D,UAAW,IACA,EAAkB,OAE7B,eAAiB,GACN,GAAiB,EAAiB,EAAkB,SAE/D,UAAW,IACA,EAAkB,QCtC3B,EAAkB,IACpB,MAAM,EAAS,IAAI,IAAI,OAAO,GAAM,SAAS,MAC7C,OAAI,EAAO,SAAW,SAAS,OACpB,EAAO,SAEX,EAAO,MCJZ,EAAsB,IAAI,ICDzB,MAAM,EACD,CAAC,EAAS,IACP,EAAQ,OAAQ,GAAW,KAAgB,GCmGpD,EAAe,OAAS,UAAA,EAAW,QAAA,EAAS,MAAA,EAAO,aAAA,EAAc,QAAA,EAAU,OAC7E,MAAM,QAAc,OAAO,KAAK,GAC1B,QAAyB,EAAqB,CAChD,QAAA,EAAS,QAAA,EAAS,KAAM,SAE5B,IAAI,QAAuB,EAAM,MAAM,EAAkB,GASzD,IAAK,MAAM,KAAU,EACjB,GAAI,6BAAiE,EAAQ,CACzE,MAAM,EAAe,2BACrB,QAAuB,EAAa,KAAK,EAAQ,CAC7C,UAAA,EACA,MAAA,EACA,aAAA,EACA,eAAA,EACA,QAAS,IAarB,OAAO,GAgBL,EAAyB,OAAS,QAAA,EAAS,SAAA,EAAU,MAAA,EAAO,QAAA,EAAU,OACxE,IAAI,EAAkB,EAClB,GAAc,EAClB,IAAK,IAAI,KAAU,EACf,GAAI,oBAA6C,EAAQ,CACrD,GAAc,EACd,MAAM,EAAe,kBAerB,KAdA,QAAwB,EAAa,KAAK,EAAQ,CAC9C,QAAA,EACA,SAAU,EACV,MAAA,KAYA,MAwBZ,OApBK,IAiBD,EAAkB,GAA8C,MAA3B,EAAgB,OACjD,OAAkB,GAEnB,GAAoC,MAiBzC,EAAuB,OAAS,QAAA,EAAS,KAAA,EAAM,QAAA,EAAU,OAC3D,MAAM,EAA4B,EAAmB,EAAS,sBAC9D,IAAI,EAAmB,EACvB,IAAK,MAAM,KAAU,EAEe,iBADhC,QAAyB,qBAA0D,KAAK,EAAQ,CAAE,KAAA,EAAM,QAAS,OAE7G,EAAmB,IAAI,QAAQ,IAUvC,OAAO,GAEE,EAAe,CACxB,IAnNe,OAAS,UAAA,EAAW,QAAA,EAAS,SAAA,EAAU,MAAA,EAAO,QAAA,EAAU,GAAI,aAAA,MAS3E,MAAM,QAAyB,EAAqB,CAChD,QAAA,EAAS,QAAA,EAAS,KAAM,UAE5B,IAAK,EAKD,MAAM,IAAI,EAAa,6BAA8B,CACjD,IAAK,EAAe,EAAiB,OAG7C,IAAI,QAAwB,EAAuB,CAC/C,MAAA,EACA,QAAA,EACA,SAAA,EACA,QAAS,IAEb,IAAK,EAKD,OAEJ,MAAM,QAAc,OAAO,KAAK,GAC1B,EAAgB,EAAmB,EAAS,kBAClD,IAAI,EAAc,EAAc,OAAS,QAC/B,EAAa,CAAE,UAAA,EAAW,aAAA,EAAc,QAAS,IACvD,KAKJ,UACU,EAAM,IAAI,EAAkB,GAEtC,MAAO,GAKH,KAHmB,uBAAf,EAAM,YC9DlB,iBAKI,IAAK,MAAM,KAAY,QACb,IDyDI,GAEJ,EAEV,IAAK,IAAI,KAAU,QACT,iBAAgD,KAAK,EAAQ,CAC/D,UAAA,EACA,MAAA,EACA,YAAA,EACA,YAAa,EACb,QAAS,KAyJjB,MAAO,GEtGL,EAAe,CACjB,MAlHiB,OAAS,QAAA,EAAS,aAAA,EAAc,MAAA,EAAO,QAAA,EAAU,OAOlE,GANuB,iBAAZ,IACP,EAAU,IAAI,QAAQ,IAKtB,aAAiB,YAAc,EAAM,gBAAiB,CACtD,MAAM,QAAgC,EAAM,gBAC5C,GAAI,EAKA,OAAO,EAYf,MAAM,EAAqB,EAAmB,EAAS,gBAIjD,EAAkB,EAAmB,OAAS,EAChD,EAAQ,QAAU,KACtB,IACI,IAAK,IAAI,KAAU,EACf,GAAI,qBAA+C,EAAQ,CACvD,MAAM,EAAe,mBACf,EAAe,EAAQ,QAC7B,QAAiB,EAAa,KAAK,EAAQ,CACvC,QAAS,EACT,MAAA,KAchB,MAAO,GACH,MAAM,IAAI,EAAa,kCAAmC,CACtD,YAAa,IAMrB,IAAI,EAAwB,EAAQ,QACpC,IACI,IAAI,EAGA,EADiB,aAAjB,EAAQ,WACc,MAAM,SAGN,MAAM,EAAS,GAOzC,IAAK,MAAM,KAAU,EACb,oBAA6C,IAC7C,QAAsB,kBACjB,KAAK,EAAQ,CACd,MAAA,EACA,QAAS,EACT,SAAU,KAatB,OAAO,EAEX,MAAO,GAKH,IAAK,MAAM,KAAU,QACX,eAA4C,KAAK,EAAQ,CAC3D,MAAA,EACA,MAAA,EACA,gBAAiB,EAAgB,QACjC,QAAS,EAAsB,UAGvC,MAAM,KCzId,IACI,KAAK,oCAAsC,IAE/C,MAAO,ICIP,IAAI,ECOG,MAAM,EAUT,YAAY,EAAM,GAAS,gBAAE,EAAe,gBAAE,GAAqB,IAC/D,KAAK,IAAM,KACX,KAAK,MAAQ,EACb,KAAK,SAAW,EAChB,KAAK,iBAAmB,EACxB,KAAK,iBAAmB,QAA0B,KAAK,SAQ3D,SACI,OAAO,KAAK,IAShB,aACI,IAAI,KAAK,IAmCT,OAjCA,KAAK,UAAY,IAAI,QAAQ,CAAC,EAAS,KAMnC,IAAI,GAAsB,EAC1B,WAAW,KACP,GAAsB,EACtB,EAAO,IAAI,MAAM,gDAClB,KAAK,cACR,MAAM,EAAc,UAAU,KAAK,KAAK,MAAO,KAAK,UACpD,EAAY,QAAU,IAAM,EAAO,EAAY,OAC/C,EAAY,gBAAmB,IACvB,GACA,EAAY,YAAY,QACxB,EAAY,OAAO,SAEmB,mBAA1B,KAAK,kBACjB,KAAK,iBAAiB,IAG9B,EAAY,UAAY,KACpB,MAAM,EAAK,EAAY,OACnB,EACA,EAAG,SAGH,EAAG,gBAAkB,KAAK,iBAAiB,KAAK,MAChD,EAAQ,OAIb,KAWX,aAAa,EAAW,GACpB,aAAc,KAAK,WAAW,EAAW,EAAO,IAAI,GAYxD,aAAa,EAAW,EAAO,GAC3B,aAAa,KAAK,eAAe,EAAW,CAAE,MAAA,EAAO,MAAA,IAYzD,iBAAiB,EAAW,EAAO,GAE/B,aADsB,KAAK,eAAe,EAAW,CAAE,MAAA,EAAO,MAAA,EAAO,aAAa,KACnE,IAAK,GAAU,EAAM,KAmBxC,qBAAqB,GAAW,MAAE,EAAK,MAAE,EAAQ,KAAI,UACrD,EAAY,OAAM,MAAE,EAAK,YAAE,GAAc,GAAW,IAChD,aAAa,KAAK,YAAY,CAAC,GAAY,WAAY,CAAC,EAAK,KACzD,MAAM,EAAQ,EAAI,YAAY,GACxB,EAAS,EAAQ,EAAM,MAAM,GAAS,EACtC,EAAU,GACV,EAAU,EAAO,WAAW,EAAO,GACzC,EAAQ,UAAY,KAChB,MAAM,EAAS,EAAQ,OACnB,GACA,EAAQ,KAAK,EAAc,EAAS,EAAO,OACvC,GAAS,EAAQ,QAAU,EAC3B,EAAK,GAGL,EAAO,YAIX,EAAK,MAsBrB,kBAAkB,EAAY,EAAM,GAEhC,aADM,KAAK,aACE,IAAI,QAAQ,CAAC,EAAS,KAC/B,MAAM,EAAM,KAAK,IAAI,YAAY,EAAY,GAC7C,EAAI,QAAU,IAAM,EAAO,EAAI,OAC/B,EAAI,WAAa,IAAM,IACvB,EAAS,EAAM,GAAU,EAAQ,MAazC,YAAY,EAAQ,EAAW,KAAS,GAMpC,aAAa,KAAK,YAAY,CAAC,GAAY,EAL1B,CAAC,EAAK,KACnB,MAAM,EAAW,EAAI,YAAY,GAC3B,EAAU,EAAS,GAAQ,MAAM,EAAU,GACjD,EAAQ,UAAY,IAAM,EAAK,EAAQ,UAiB/C,QACQ,KAAK,MACL,KAAK,IAAI,QACT,KAAK,IAAM,OAMvB,EAAU,UAAU,aAAe,IAEnC,MAAM,EAAgB,CAClB,SAAU,CAAC,MAAO,QAAS,SAAU,SAAU,cAC/C,UAAW,CAAC,MAAO,MAAO,QAAS,WAEvC,IAAK,MAAO,EAAM,KAAY,OAAO,QAAQ,GACzC,IAAK,MAAM,KAAU,EACb,KAAU,eAAe,YAEzB,EAAU,UAAU,GAChB,eAAgB,KAAc,GAC1B,aAAa,KAAK,MAAM,EAAQ,EAAW,KAAS,KC3NxE,eAAe,EAAa,EAAU,GAClC,MAAM,EAAiB,EAAS,QAE1B,EAAe,CACjB,QAAS,IAAI,QAAQ,EAAe,SACpC,OAAQ,EAAe,OACvB,WAAY,EAAe,YAGzB,EAAuB,EAAW,EAAS,GAAgB,EAI3D,EFpBV,WACI,QAAsB,IAAlB,EAA6B,CAC7B,MAAM,EAAe,IAAI,SAAS,IAClC,GAAI,SAAU,EACV,IACI,IAAI,SAAS,EAAa,MAC1B,GAAgB,EAEpB,MAAO,GACH,GAAgB,EAGxB,GAAgB,EAEpB,OAAO,EEMM,GACT,EAAe,WAAa,EAAe,OAC/C,OAAO,IAAI,SAAS,EAAM,GCvC9B,IACI,KAAK,oCAAsC,IAE/C,MAAO,ICIP,MAAM,EAAU,GACH,EAAkB,CAK3B,IAAG,IACQ,EAMX,IAAI,GACA,EAAQ,QAAQ,KCZlB,EAAwB,kBAUvB,SAAS,EAAe,GAC3B,IAAK,EACD,MAAM,IAAI,EAAa,oCAAqC,CAAE,MAAA,IAIlE,GAAqB,iBAAV,EAAoB,CAC3B,MAAM,EAAY,IAAI,IAAI,EAAO,SAAS,MAC1C,MAAO,CACH,SAAU,EAAU,KACpB,IAAK,EAAU,MAGvB,MAAM,SAAE,EAAQ,IAAE,GAAQ,EAC1B,IAAK,EACD,MAAM,IAAI,EAAa,oCAAqC,CAAE,MAAA,IAIlE,IAAK,EAAU,CACX,MAAM,EAAY,IAAI,IAAI,EAAK,SAAS,MACxC,MAAO,CACH,SAAU,EAAU,KACpB,IAAK,EAAU,MAKvB,MAAM,EAAc,IAAI,IAAI,EAAK,SAAS,MACpC,EAAc,IAAI,IAAI,EAAK,SAAS,MAE1C,OADA,EAAY,aAAa,IAAI,EAAuB,GAC7C,CACH,SAAU,EAAY,KACtB,IAAK,EAAY,MC9BzB,MAAM,EAOF,YAAY,GACR,KAAK,WAAa,EAAW,gBAAgB,GAC7C,KAAK,iBAAmB,IAAI,IAC5B,KAAK,wBAA0B,IAAI,IAUvC,eAAe,GASX,IAAK,MAAM,KAAS,EAAS,CACzB,MAAM,SAAE,EAAQ,IAAE,GAAQ,EAAe,GACzC,GAAI,KAAK,iBAAiB,IAAI,IAC1B,KAAK,iBAAiB,IAAI,KAAS,EACnC,MAAM,IAAI,EAAa,wCAAyC,CAC5D,WAAY,KAAK,iBAAiB,IAAI,GACtC,YAAa,IAGrB,GAAqB,iBAAV,GAAsB,EAAM,UAAW,CAC9C,GAAI,KAAK,wBAAwB,IAAI,IACjC,KAAK,wBAAwB,IAAI,KAAc,EAAM,UACrD,MAAM,IAAI,EAAa,4CAA6C,CAChE,IAAA,IAGR,KAAK,wBAAwB,IAAI,EAAU,EAAM,WAErD,KAAK,iBAAiB,IAAI,EAAK,IAavC,eAAc,MAAE,EAAK,QAAE,GAAY,IAW/B,MAAM,EAAgB,GAChB,EAAmB,GACnB,QAAc,OAAO,KAAK,KAAK,YAC/B,QAA8B,EAAM,OACpC,EAAoB,IAAI,IAAI,EAAsB,IAAK,GAAY,EAAQ,MACjF,IAAK,MAAO,EAAK,KAAa,KAAK,iBAC3B,EAAkB,IAAI,GACtB,EAAiB,KAAK,GAGtB,EAAc,KAAK,CAAE,SAAA,EAAU,IAAA,IAGvC,MAAM,EAAmB,EAAc,IAAI,EAAG,SAAA,EAAU,IAAA,MACpD,MAAM,EAAY,KAAK,wBAAwB,IAAI,GACnD,OAAO,KAAK,eAAe,CAAE,SAAA,EAAU,MAAA,EAAO,QAAA,EAAS,IAAA,EAAK,UAAA,MAOhE,aALM,QAAQ,IAAI,GAKX,CACH,YALgB,EAAc,IAAK,GAAS,EAAK,KAMjD,eAAgB,GASxB,iBACI,MAAM,QAAc,OAAO,KAAK,KAAK,YAC/B,QAAgC,EAAM,OACtC,EAAoB,IAAI,IAAI,KAAK,iBAAiB,UAClD,EAAc,GACpB,IAAK,MAAM,KAAW,EACb,EAAkB,IAAI,EAAQ,aACzB,EAAM,OAAO,GACnB,EAAY,KAAK,EAAQ,MAMjC,MAAO,CAAE,YAAA,GAqBb,sBAAqB,SAAE,EAAQ,IAAE,EAAG,MAAE,EAAK,QAAE,EAAO,UAAE,IAClD,MAAM,EAAU,IAAI,QAAQ,EAAK,CAC7B,UAAA,EACA,MAAO,SACP,YAAa,gBAEjB,IAQI,EARA,QAAiB,EAAa,MAAM,CACpC,MAAA,EACA,QAAA,EACA,QAAA,IAMJ,IAAK,MAAM,KAAW,GAAW,GACzB,oBAAqB,IACrB,EAAwB,GAahC,KAVwB,EAIpB,EAAsB,gBAAgB,CAAE,MAAA,EAAO,QAAA,EAAS,SAAA,IAGxD,EAAS,OAAS,KAIlB,MAAM,IAAI,EAAa,0BAA2B,CAC9C,IAAA,EACA,OAAQ,EAAS,SAOrB,EAAS,aACT,QAAiB,EAAa,UAE5B,EAAa,IAAI,CACnB,MAAA,EACA,QAAA,EACA,SAAA,EAEA,QAAS,IAAa,EAAM,EAAU,IAAI,QAAQ,GAClD,UAAW,KAAK,WAChB,aAAc,CACV,cAAc,KAU1B,qBACI,OAAO,KAAK,iBAQhB,gBACI,MAAO,IAAI,KAAK,iBAAiB,QAWrC,kBAAkB,GACd,MAAM,EAAY,IAAI,IAAI,EAAK,SAAS,MACxC,OAAO,KAAK,iBAAiB,IAAI,EAAU,MAa/C,oBAAoB,GAQhB,MAAM,EAAW,KAAK,kBAAkB,GACxC,IAAK,EACD,MAAM,IAAI,EAAa,oBAAqB,CAAE,IAAA,IAElD,OAAO,UACH,IACI,MAAM,QAAc,OAAO,KAAK,KAAK,YAC/B,QAAiB,EAAM,MAAM,GACnC,GAAI,EACA,OAAO,EAIX,MAAM,IAAI,mBAAmB,KAAK,2CACvB,MAEf,MAAO,GAUH,OAAO,MAAM,MC5R7B,IAAI,EAKG,MAAM,EAAgC,KACpC,IACD,EAAqB,IAAI,GAEtB,GCGJ,MAAM,EAAoB,CAAC,EAAK,KACnC,MACM,EADqB,IACgB,qBAC3C,IAAK,MAAM,KCLR,UAAgC,GAAK,4BAAE,EAA2B,eAAE,EAAc,UAAE,EAAS,gBAAE,GAAqB,IACvH,MAAM,EAAY,IAAI,IAAI,EAAK,SAAS,MACxC,EAAU,KAAO,SACX,EAAU,KAChB,MAAM,ECHH,SAAmC,EAAW,EAA8B,IAG/E,IAAK,MAAM,IAAa,IAAI,EAAU,aAAa,QAC3C,EAA4B,KAAM,GAAW,EAAO,KAAK,KACzD,EAAU,aAAa,OAAO,GAGtC,OAAO,EDLyB,CAA0B,EAAW,GAErE,SADM,EAAwB,KAC1B,GAAkB,EAAwB,SAAS,SAAS,KAAM,CAClE,MAAM,EAAe,IAAI,IAAI,EAAwB,MACrD,EAAa,UAAY,QACnB,EAAa,KAEvB,GAAI,EAAW,CACX,MAAM,EAAW,IAAI,IAAI,EAAwB,MACjD,EAAS,UAAY,cACf,EAAS,KAEnB,GAAI,EAAiB,CACjB,MAAM,EAAiB,EAAgB,CAAE,IAAK,IAC9C,IAAK,MAAM,KAAgB,QACjB,EAAa,MDdD,CAAsB,EAAK,GAAU,CAC3D,MAAM,EAAmB,EAAgB,IAAI,GAC7C,GAAI,EACA,OAAO,IGnBnB,IAAI,GAAgB,EAyBb,MAAM,EAAY,IAChB,ICKuB,GAAG,4BAAA,EAA8B,CAAC,SAAU,eAAA,EAAiB,aAAc,UAAA,GAAY,EAAM,gBAAA,GAAqB,MAC9I,MAAM,EAAY,EAAW,kBAC7B,iBAAiB,QAAU,IACvB,MAAM,EAAe,EAAkB,EAAM,QAAQ,IAAK,CACtD,UAAA,EACA,eAAA,EACA,4BAAA,EACA,gBAAA,IAEJ,IAAK,EAKD,OAEJ,IAAI,EAAkB,OAAO,KAAK,GAAW,KAAM,GACxC,EAAM,MAAM,IACpB,KAAM,GACD,GAUG,MAAM,IAmBjB,EAAM,YAAY,MDpDlB,CAAiB,GACjB,GAAgB,IEzBlB,EAAmB,IACrB,MAAM,EAAqB,IACrB,EAAU,EAAgB,MAChC,EAAM,UAAU,EAAmB,QAAQ,CAAE,MAAA,EAAO,QAAA,IAC/C,MAAO,IAMR,MAAM,MAGR,EAAoB,IACtB,MAAM,EAAqB,IAC3B,EAAM,UAAU,EAAmB,aCzBvC,IACI,KAAK,wCAA0C,IAEnD,MAAO,IC2BP,eAAe,EAAsB,EAAS,GAC1C,IAaI,GAAgC,MAA5B,EAAiB,OAGjB,OAAO,EAEX,MAAM,EAAc,EAAQ,QAAQ,IAAI,SACxC,IAAK,EACD,MAAM,IAAI,EAAa,mBAE3B,MAAM,ECpCd,SAA0B,GAQtB,MAAM,EAAwB,EAAY,OAAO,cACjD,IAAK,EAAsB,WAAW,UAClC,MAAM,IAAI,EAAa,qBAAsB,CAAE,sBAAA,IAKnD,GAAI,EAAsB,SAAS,KAC/B,MAAM,IAAI,EAAa,oBAAqB,CAAE,sBAAA,IAElD,MAAM,EAAa,cAAc,KAAK,GAEtC,IAAK,IAAgB,EAAW,KAAM,EAAW,GAC7C,MAAM,IAAI,EAAa,uBAAwB,CAAE,sBAAA,IAErD,MAAO,CACH,MAAyB,KAAlB,EAAW,QAAY,EAAY,OAAO,EAAW,IAC5D,IAAuB,KAAlB,EAAW,QAAY,EAAY,OAAO,EAAW,KDWvC,CAAiB,GAC9B,QAAqB,EAAiB,OACtC,EEpCd,SAAsC,EAAM,EAAO,GAQ/C,MAAM,EAAW,EAAK,KACtB,GAAK,GAAO,EAAM,GAAc,GAAS,EAAQ,EAC7C,MAAM,IAAI,EAAa,wBAAyB,CAC5C,KAAM,EACN,IAAA,EACA,MAAA,IAGR,IAAI,EACA,EAcJ,YAbc,IAAV,QAA+B,IAAR,GACvB,EAAiB,EAEjB,EAAe,EAAM,QAEN,IAAV,QAA+B,IAAR,GAC5B,EAAiB,EACjB,EAAe,QAEF,IAAR,QAA+B,IAAV,IAC1B,EAAiB,EAAW,EAC5B,EAAe,GAEZ,CACH,MAAO,EACP,IAAK,GFGuB,CAA6B,EAAc,EAAW,MAAO,EAAW,KAC9F,EAAa,EAAa,MAAM,EAAoB,MAAO,EAAoB,KAC/E,EAAiB,EAAW,KAC5B,EAAiB,IAAI,SAAS,EAAY,CAG5C,OAAQ,IACR,WAAY,kBACZ,QAAS,EAAiB,UAK9B,OAHA,EAAe,QAAQ,IAAI,iBAAkB,OAAO,IACpD,EAAe,QAAQ,IAAI,yBAA0B,EAAoB,SAAS,EAAoB,IAAM,KACxG,EAAa,MACV,EAEX,MAAO,GAUH,OAAO,IAAI,SAAS,GAAI,CACpB,OAAQ,IACR,WAAY,2BGlFxB,IACI,KAAK,iCAAmC,IAE5C,MAAO,ICYA,MAAM,EAAgB,MCAhB,EAAoB,GACzB,GAA8B,iBAAZ,EASX,EAWA,CAAE,OAAQ,GCjBzB,MAAM,EAYF,YAAY,EAAO,EAAS,EAAS,GAcjC,KAAK,QAAU,EAAiB,GAChC,KAAK,MAAQ,EACb,KAAK,OAAS,GCxBtB,MAAM,UAAoB,EActB,YAAY,EAAQ,EAAS,GAiCzB,MAxBc,EAAG,IAAA,MACb,MAAM,EAAS,EAAO,KAAK,EAAI,MAE/B,GAAK,IAOA,EAAI,SAAW,SAAS,QAA6B,IAAjB,EAAO,OAYhD,OAAO,EAAO,MAAM,IAEX,EAAS,ICzC9B,MAAM,EAIF,cACI,KAAK,QAAU,IAAI,IAOvB,aACI,OAAO,KAAK,QAMhB,mBACI,KAAK,iBAAiB,QAAU,IAC5B,MAAM,QAAE,GAAY,EACd,EAAkB,KAAK,cAAc,CAAE,QAAA,EAAS,MAAA,IAClD,GACA,EAAM,YAAY,KA0B9B,mBACI,KAAK,iBAAiB,UAAW,MAAO,IACpC,GAAI,EAAM,MAA4B,eAApB,EAAM,KAAK,KAAuB,CAChD,MAAM,QAAE,GAAY,EAAM,KAIpB,EAAkB,QAAQ,IAAI,EAAQ,YAAY,IAAK,IACpC,iBAAV,IACP,EAAQ,CAAC,IAEb,MAAM,EAAU,IAAI,WAAW,GAC/B,OAAO,KAAK,cAAc,CAAE,QAAA,OAKhC,EAAM,UAAU,GAEZ,EAAM,OAAS,EAAM,MAAM,WACrB,EACN,EAAM,MAAM,GAAG,aAAY,OAkB3C,eAAc,QAAE,EAAO,MAAE,IASrB,MAAM,EAAM,IAAI,IAAI,EAAQ,IAAK,SAAS,MAC1C,IAAK,EAAI,SAAS,WAAW,QAIzB,OAEJ,IAqDI,GArDA,OAAE,EAAM,MAAE,GAAU,KAAK,kBAAkB,CAAE,IAAA,EAAK,QAAA,EAAS,MAAA,IAC3D,EAAU,GAAS,EAAM,QAuB7B,IAPK,GAAW,KAAK,kBAKjB,EAAU,KAAK,iBAEd,EAAL,CA8BA,IACI,EAAkB,EAAQ,OAAO,CAAE,IAAA,EAAK,QAAA,EAAS,MAAA,EAAO,OAAA,IAE5D,MAAO,GACH,EAAkB,QAAQ,OAAO,GAgBrC,OAdI,GAAmB,KAAK,gBACxB,EAAkB,EAAgB,MAAO,GAU9B,KAAK,cAAc,OAAO,CAAE,IAAA,EAAK,QAAA,EAAS,MAAA,MAGlD,GAeX,mBAAkB,IAAE,EAAG,QAAE,EAAO,MAAE,IAe9B,MAAM,EAAS,KAAK,QAAQ,IAAI,EAAQ,SAAW,GACnD,IAAK,MAAM,KAAS,EAAQ,CACxB,IAAI,EACA,EAAc,EAAM,MAAM,CAAE,IAAA,EAAK,QAAA,EAAS,MAAA,IAC9C,GAAI,EAmBA,OAjBA,EAAS,EACL,MAAM,QAAQ,IAAuC,IAAvB,EAAY,OAE1C,OAAS,EAEH,EAAY,cAAgB,QACE,IAApC,OAAO,KAAK,GAAa,OAEzB,OAAS,EAEmB,kBAAhB,IAIZ,OAAS,GAGN,CAAE,MAAA,EAAO,OAAA,GAIxB,MAAO,GAYX,kBAAkB,GACd,KAAK,gBAAkB,EAAiB,GAS5C,gBAAgB,GACZ,KAAK,cAAgB,EAAiB,GAO1C,cAAc,GAiCL,KAAK,QAAQ,IAAI,EAAM,SACxB,KAAK,QAAQ,IAAI,EAAM,OAAQ,IAInC,KAAK,QAAQ,IAAI,EAAM,QAAQ,KAAK,GAOxC,gBAAgB,GACZ,IAAK,KAAK,QAAQ,IAAI,EAAM,QACxB,MAAM,IAAI,EAAa,6CAA8C,CACjE,OAAQ,EAAM,SAGtB,MAAM,EAAa,KAAK,QAAQ,IAAI,EAAM,QAAQ,QAAQ,GAC1D,KAAI,GAAc,GAId,MAAM,IAAI,EAAa,yCAHvB,KAAK,QAAQ,IAAI,EAAM,QAAQ,OAAO,EAAY,ICpV9D,IAAI,EAQG,MAAM,EAA2B,KAC/B,KACD,EAAgB,IAAI,GAEN,mBACd,EAAc,oBAEX,GCcE,EAAgB,CAAC,EAAS,EAAS,KAC5C,IAAI,EACJ,GAAuB,iBAAZ,EAAsB,CAC7B,MAAM,EAAa,IAAI,IAAI,EAAS,SAAS,MAiC7C,EAAQ,IAAI,EAZU,EAAG,IAAA,KASd,EAAI,OAAS,EAAW,KAGF,EAAS,QAEzC,GAAI,aAAmB,OAExB,EAAQ,IAAI,EAAY,EAAS,EAAS,QAEzC,GAAuB,mBAAZ,EAEZ,EAAQ,IAAI,EAAM,EAAS,EAAS,OAEnC,CAAA,KAAI,aAAmB,GAIxB,MAAM,IAAI,EAAa,yBAA0B,CAC7C,WAAY,kBACZ,SAAU,gBACV,UAAW,YANf,EAAQ,EAWZ,OAFsB,IACR,cAAc,GACrB,GChFE,EAAY,SCEzB,iBACE,MAAM,QAAc,OAAO,KAAK,GAC1B,QAAiB,EAAM,OACtB,QAAQ,IAAI,EAAS,UAAU,IAAI,MAAO,IAE/C,MAAO,CACL,mBAFqB,EAAM,MAAM,IAEX,QAAQ,IAAI,gBAClC,IAAK,EAAQ,QAIgB,GAAnC,MCVe,EAAY,CAAC,KAFN,SAEY,WADN,UCCb,EAAY,MAFL,qBACM,UCCb,EAAY,MAFL,qBACM,UCPtB,EAAmB,iBAAmB,IAAI,iBLMrB,YKNqD,KA8C1E,EAAqB,IC/B3B,MAUI,YAAY,EAAU,IAClB,KAAK,WAAa,EAAW,eAAe,EAAQ,WACpD,KAAK,SAAW,EAAQ,SAAW,GACnC,KAAK,cAAgB,EAAQ,aAYjC,cAAa,MAAE,EAAK,QAAE,IASlB,MAAM,QAAiB,EAAa,MAAM,CACtC,UAAW,KAAK,WAChB,QAAA,EACA,MAAA,EACA,aAAc,KAAK,cACnB,QAAS,KAAK,WAclB,IAAK,EACD,MAAM,IAAI,EAAa,cAAe,CAAE,IAAK,EAAQ,MAEzD,OAAO,IDzB0B,CACvC,UAAA,EACA,QAAS,CAEP,IE3CJ,MACI,cAYI,KAAK,yBAA2B,OAAS,QAAA,EAAS,eAAA,KAG1C,GAAkB,EAAQ,QAAQ,IAAI,eACzB,EAAsB,EAAS,GAIzC,OCfa,IAAU,ECPtC,iBAAiB,UAAW,IAAM,KAAK,eCFvC,iBAAiB,WAAY,IAAM,KAAK,QAAQ,SvBgC5B,CAAC,IACM,IACR,eAAe,GAC9B,EAAQ,OAAS,IAIjB,iBAAiB,UAAW,GAC5B,iBAAiB,WAAY,KqB9BjC,CH6Ca,uaAAK,eG5ClB,EAAS,GH8Cb,EACE,iBA5DyB,OAAQ,MAAA,MAC7B,GACF,EAAiB,YAAY,2BAG/B,MACM,SADiB,EAAM,QAAQ,YACT,OAAO,SAC7B,QAAc,OAAO,KAAK,GAEhC,IAAK,MAAM,KAAa,EAGjB,EAAU,WAMT,EAAM,eAGK,KAAK,SAAS,EAAU,OACvC,IAAI,SAAS,EAAW,CACtB,QAAS,CACP,iBAAkB,EAAU,KAC5B,eAAgB,EAAU,SAZ1B,GACF,EAAiB,YAAY,2CAkBnC,MAAM,EAAoB,CACxB,EACA,EACA,GACA,KAAM,GAAU,EAAW,GAAG,KAAK,WAAW,EAAM,aAEhD,EAAiB,OAAyB,EAAkB,OAAS,IAG3E,OAAO,SAAS,SAAS,EAAgB,MAqBzC,QAGF,EACE,IAAI,OL5DmB,YK6DvB","file":"sw.js","sourcesContent":["// @ts-ignore\ntry {\n self['workbox:core:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst logger = (process.env.NODE_ENV === 'production' ? null : (() => {\n let inGroup = false;\n const methodToColorMap = {\n debug: `#7f8c8d`,\n log: `#2ecc71`,\n warn: `#f39c12`,\n error: `#c0392b`,\n groupCollapsed: `#3498db`,\n groupEnd: null,\n };\n const print = function (method, args) {\n if (method === 'groupCollapsed') {\n // Safari doesn't print all console.groupCollapsed() arguments:\n // https://bugs.webkit.org/show_bug.cgi?id=182754\n if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\n console[method](...args);\n return;\n }\n }\n const styles = [\n `background: ${methodToColorMap[method]}`,\n `border-radius: 0.5em`,\n `color: white`,\n `font-weight: bold`,\n `padding: 2px 0.5em`,\n ];\n // When in a group, the workbox prefix is not displayed.\n const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];\n console[method](...logPrefix, ...args);\n if (method === 'groupCollapsed') {\n inGroup = true;\n }\n if (method === 'groupEnd') {\n inGroup = false;\n }\n };\n const api = {};\n const loggerMethods = Object.keys(methodToColorMap);\n for (const key of loggerMethods) {\n const method = key;\n api[method] = (...args) => {\n print(method, args);\n };\n }\n return api;\n})());\nexport { logger };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messages } from './messages.js';\nimport '../../_version.js';\nconst fallback = (code, ...args) => {\n let msg = code;\n if (args.length > 0) {\n msg += ` :: ${JSON.stringify(args)}`;\n }\n return msg;\n};\nconst generatorFunction = (code, details = {}) => {\n const message = messages[code];\n if (!message) {\n throw new Error(`Unable to find message for code '${code}'.`);\n }\n return message(details);\n};\nexport const messageGenerator = (process.env.NODE_ENV === 'production') ?\n fallback : generatorFunction;\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messageGenerator } from '../models/messages/messageGenerator.js';\nimport '../_version.js';\n/**\n * Workbox errors should be thrown with this class.\n * This allows use to ensure the type easily in tests,\n * helps developers identify errors from workbox\n * easily and allows use to optimise error\n * messages correctly.\n *\n * @private\n */\nclass WorkboxError extends Error {\n /**\n *\n * @param {string} errorCode The error code that\n * identifies this particular error.\n * @param {Object=} details Any relevant arguments\n * that will help developers identify issues should\n * be added as a key on the context object.\n */\n constructor(errorCode, details) {\n let message = messageGenerator(errorCode, details);\n super(message);\n this.name = errorCode;\n this.details = details;\n }\n}\nexport { WorkboxError };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from '../_private/WorkboxError.js';\nimport '../_version.js';\n/*\n * This method returns true if the current context is a service worker.\n */\nconst isSWEnv = (moduleName) => {\n if (!('ServiceWorkerGlobalScope' in self)) {\n throw new WorkboxError('not-in-sw', { moduleName });\n }\n};\n/*\n * This method throws if the supplied value is not an array.\n * The destructed values are required to produce a meaningful error for users.\n * The destructed and restructured object is so it's clear what is\n * needed.\n */\nconst isArray = (value, details) => {\n if (!Array.isArray(value)) {\n throw new WorkboxError('not-an-array', details);\n }\n};\nconst hasMethod = (object, expectedMethod, details) => {\n const type = typeof object[expectedMethod];\n if (type !== 'function') {\n details.expectedMethod = expectedMethod;\n throw new WorkboxError('missing-a-method', details);\n }\n};\nconst isType = (object, expectedType, details) => {\n if (typeof object !== expectedType) {\n details.expectedType = expectedType;\n throw new WorkboxError('incorrect-type', details);\n }\n};\nconst isInstance = (object, expectedClass, details) => {\n if (!(object instanceof expectedClass)) {\n details.expectedClass = expectedClass;\n throw new WorkboxError('incorrect-class', details);\n }\n};\nconst isOneOf = (value, validValues, details) => {\n if (!validValues.includes(value)) {\n details.validValueDescription =\n `Valid values are ${JSON.stringify(validValues)}.`;\n throw new WorkboxError('invalid-value', details);\n }\n};\nconst isArrayOfClass = (value, expectedClass, details) => {\n const error = new WorkboxError('not-array-of-class', details);\n if (!Array.isArray(value)) {\n throw error;\n }\n for (let item of value) {\n if (!(item instanceof expectedClass)) {\n throw error;\n }\n }\n};\nconst finalAssertExports = process.env.NODE_ENV === 'production' ? null : {\n hasMethod,\n isArray,\n isInstance,\n isOneOf,\n isSWEnv,\n isType,\n isArrayOfClass,\n};\nexport { finalAssertExports as assert };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst _cacheNameDetails = {\n googleAnalytics: 'googleAnalytics',\n precache: 'precache-v2',\n prefix: 'workbox',\n runtime: 'runtime',\n suffix: registration.scope,\n};\nconst _createCacheName = (cacheName) => {\n return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix]\n .filter((value) => value && value.length > 0)\n .join('-');\n};\nconst eachCacheNameDetail = (fn) => {\n for (const key of Object.keys(_cacheNameDetails)) {\n fn(key);\n }\n};\nexport const cacheNames = {\n updateDetails: (details) => {\n eachCacheNameDetail((key) => {\n if (typeof details[key] === 'string') {\n _cacheNameDetails[key] = details[key];\n }\n });\n },\n getGoogleAnalyticsName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);\n },\n getPrecacheName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.precache);\n },\n getPrefix: () => {\n return _cacheNameDetails.prefix;\n },\n getRuntimeName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.runtime);\n },\n getSuffix: () => {\n return _cacheNameDetails.suffix;\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst getFriendlyURL = (url) => {\n const urlObj = new URL(String(url), location.href);\n if (urlObj.origin === location.origin) {\n return urlObj.pathname;\n }\n return urlObj.href;\n};\nexport { getFriendlyURL };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n// Callbacks to be executed whenever there's a quota error.\nconst quotaErrorCallbacks = new Set();\nexport { quotaErrorCallbacks };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nexport const pluginUtils = {\n filter: (plugins, callbackName) => {\n return plugins.filter((plugin) => callbackName in plugin);\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from './WorkboxError.js';\nimport { assert } from './assert.js';\nimport { getFriendlyURL } from './getFriendlyURL.js';\nimport { logger } from './logger.js';\nimport { executeQuotaErrorCallbacks } from './executeQuotaErrorCallbacks.js';\nimport { pluginUtils } from '../utils/pluginUtils.js';\nimport '../_version.js';\n/**\n * Wrapper around cache.put().\n *\n * Will call `cacheDidUpdate` on plugins if the cache was updated, using\n * `matchOptions` when determining what the old entry is.\n *\n * @param {Object} options\n * @param {string} options.cacheName\n * @param {Request} options.request\n * @param {Response} options.response\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @param {Object} [options.matchOptions]\n *\n * @private\n * @memberof module:workbox-core\n */\nconst putWrapper = async ({ cacheName, request, response, event, plugins = [], matchOptions, }) => {\n if (process.env.NODE_ENV !== 'production') {\n if (request.method && request.method !== 'GET') {\n throw new WorkboxError('attempt-to-cache-non-get-request', {\n url: getFriendlyURL(request.url),\n method: request.method,\n });\n }\n }\n const effectiveRequest = await _getEffectiveRequest({\n plugins, request, mode: 'write'\n });\n if (!response) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Cannot cache non-existent response for ` +\n `'${getFriendlyURL(effectiveRequest.url)}'.`);\n }\n throw new WorkboxError('cache-put-with-no-response', {\n url: getFriendlyURL(effectiveRequest.url),\n });\n }\n let responseToCache = await _isResponseSafeToCache({\n event,\n plugins,\n response,\n request: effectiveRequest,\n });\n if (!responseToCache) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' will ` +\n `not be cached.`, responseToCache);\n }\n return;\n }\n const cache = await caches.open(cacheName);\n const updatePlugins = pluginUtils.filter(plugins, \"cacheDidUpdate\" /* CACHE_DID_UPDATE */);\n let oldResponse = updatePlugins.length > 0 ?\n await matchWrapper({ cacheName, matchOptions, request: effectiveRequest }) :\n null;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Updating the '${cacheName}' cache with a new Response for ` +\n `${getFriendlyURL(effectiveRequest.url)}.`);\n }\n try {\n await cache.put(effectiveRequest, responseToCache);\n }\n catch (error) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError\n if (error.name === 'QuotaExceededError') {\n await executeQuotaErrorCallbacks();\n }\n throw error;\n }\n for (let plugin of updatePlugins) {\n await plugin[\"cacheDidUpdate\" /* CACHE_DID_UPDATE */].call(plugin, {\n cacheName,\n event,\n oldResponse,\n newResponse: responseToCache,\n request: effectiveRequest,\n });\n }\n};\n/**\n * This is a wrapper around cache.match().\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache to match against.\n * @param {Request} options.request The Request that will be used to look up\n * cache entries.\n * @param {Event} [options.event] The event that propted the action.\n * @param {Object} [options.matchOptions] Options passed to cache.match().\n * @param {Array} [options.plugins=[]] Array of plugins.\n * @return {Response} A cached response if available.\n *\n * @private\n * @memberof module:workbox-core\n */\nconst matchWrapper = async ({ cacheName, request, event, matchOptions, plugins = [], }) => {\n const cache = await caches.open(cacheName);\n const effectiveRequest = await _getEffectiveRequest({\n plugins, request, mode: 'read'\n });\n let cachedResponse = await cache.match(effectiveRequest, matchOptions);\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n logger.debug(`Found a cached response in '${cacheName}'.`);\n }\n else {\n logger.debug(`No cached response found in '${cacheName}'.`);\n }\n }\n for (const plugin of plugins) {\n if (\"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */ in plugin) {\n const pluginMethod = plugin[\"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */];\n cachedResponse = await pluginMethod.call(plugin, {\n cacheName,\n event,\n matchOptions,\n cachedResponse,\n request: effectiveRequest,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n assert.isInstance(cachedResponse, Response, {\n moduleName: 'Plugin',\n funcName: \"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n return cachedResponse;\n};\n/**\n * This method will call cacheWillUpdate on the available plugins (or use\n * status === 200) to determine if the Response is safe and valid to cache.\n *\n * @param {Object} options\n * @param {Request} options.request\n * @param {Response} options.response\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst _isResponseSafeToCache = async ({ request, response, event, plugins = [], }) => {\n let responseToCache = response;\n let pluginsUsed = false;\n for (let plugin of plugins) {\n if (\"cacheWillUpdate\" /* CACHE_WILL_UPDATE */ in plugin) {\n pluginsUsed = true;\n const pluginMethod = plugin[\"cacheWillUpdate\" /* CACHE_WILL_UPDATE */];\n responseToCache = await pluginMethod.call(plugin, {\n request,\n response: responseToCache,\n event,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n assert.isInstance(responseToCache, Response, {\n moduleName: 'Plugin',\n funcName: \"cacheWillUpdate\" /* CACHE_WILL_UPDATE */,\n isReturnValueProblem: true,\n });\n }\n }\n if (!responseToCache) {\n break;\n }\n }\n }\n if (!pluginsUsed) {\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n if (responseToCache.status !== 200) {\n if (responseToCache.status === 0) {\n logger.warn(`The response for '${request.url}' is an opaque ` +\n `response. The caching strategy that you're using will not ` +\n `cache opaque responses by default.`);\n }\n else {\n logger.debug(`The response for '${request.url}' returned ` +\n `a status code of '${response.status}' and won't be cached as a ` +\n `result.`);\n }\n }\n }\n }\n responseToCache = responseToCache && responseToCache.status === 200 ?\n responseToCache : undefined;\n }\n return responseToCache ? responseToCache : null;\n};\n/**\n * Checks the list of plugins for the cacheKeyWillBeUsed callback, and\n * executes any of those callbacks found in sequence. The final `Request` object\n * returned by the last plugin is treated as the cache key for cache reads\n * and/or writes.\n *\n * @param {Object} options\n * @param {Request} options.request\n * @param {string} options.mode\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst _getEffectiveRequest = async ({ request, mode, plugins = [], }) => {\n const cacheKeyWillBeUsedPlugins = pluginUtils.filter(plugins, \"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */);\n let effectiveRequest = request;\n for (const plugin of cacheKeyWillBeUsedPlugins) {\n effectiveRequest = await plugin[\"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */].call(plugin, { mode, request: effectiveRequest });\n if (typeof effectiveRequest === 'string') {\n effectiveRequest = new Request(effectiveRequest);\n }\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(effectiveRequest, Request, {\n moduleName: 'Plugin',\n funcName: \"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n return effectiveRequest;\n};\nexport const cacheWrapper = {\n put: putWrapper,\n match: matchWrapper,\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from '../_private/logger.js';\nimport { quotaErrorCallbacks } from '../models/quotaErrorCallbacks.js';\nimport '../_version.js';\n/**\n * Runs all of the callback functions, one at a time sequentially, in the order\n * in which they were registered.\n *\n * @memberof workbox.core\n * @private\n */\nasync function executeQuotaErrorCallbacks() {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`About to run ${quotaErrorCallbacks.size} ` +\n `callbacks to clean up caches.`);\n }\n for (const callback of quotaErrorCallbacks) {\n await callback();\n if (process.env.NODE_ENV !== 'production') {\n logger.log(callback, 'is complete.');\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log('Finished running callbacks.');\n }\n}\nexport { executeQuotaErrorCallbacks };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from './WorkboxError.js';\nimport { logger } from './logger.js';\nimport { assert } from './assert.js';\nimport { getFriendlyURL } from '../_private/getFriendlyURL.js';\nimport { pluginUtils } from '../utils/pluginUtils.js';\nimport '../_version.js';\n/**\n * Wrapper around the fetch API.\n *\n * Will call requestWillFetch on available plugins.\n *\n * @param {Object} options\n * @param {Request|string} options.request\n * @param {Object} [options.fetchOptions]\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst wrappedFetch = async ({ request, fetchOptions, event, plugins = [], }) => {\n if (typeof request === 'string') {\n request = new Request(request);\n }\n // We *should* be able to call `await event.preloadResponse` even if it's\n // undefined, but for some reason, doing so leads to errors in our Node unit\n // tests. To work around that, explicitly check preloadResponse's value first.\n if (event instanceof FetchEvent && event.preloadResponse) {\n const possiblePreloadResponse = await event.preloadResponse;\n if (possiblePreloadResponse) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Using a preloaded navigation response for ` +\n `'${getFriendlyURL(request.url)}'`);\n }\n return possiblePreloadResponse;\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n paramName: 'request',\n expectedClass: Request,\n moduleName: 'workbox-core',\n className: 'fetchWrapper',\n funcName: 'wrappedFetch',\n });\n }\n const failedFetchPlugins = pluginUtils.filter(plugins, \"fetchDidFail\" /* FETCH_DID_FAIL */);\n // If there is a fetchDidFail plugin, we need to save a clone of the\n // original request before it's either modified by a requestWillFetch\n // plugin or before the original request's body is consumed via fetch().\n const originalRequest = failedFetchPlugins.length > 0 ?\n request.clone() : null;\n try {\n for (let plugin of plugins) {\n if (\"requestWillFetch\" /* REQUEST_WILL_FETCH */ in plugin) {\n const pluginMethod = plugin[\"requestWillFetch\" /* REQUEST_WILL_FETCH */];\n const requestClone = request.clone();\n request = (await pluginMethod.call(plugin, {\n request: requestClone,\n event,\n }));\n if (process.env.NODE_ENV !== 'production') {\n if (request) {\n assert.isInstance(request, Request, {\n moduleName: 'Plugin',\n funcName: \"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n }\n catch (err) {\n throw new WorkboxError('plugin-error-request-will-fetch', {\n thrownError: err,\n });\n }\n // The request can be altered by plugins with `requestWillFetch` making\n // the original request (Most likely from a `fetch` event) to be different\n // to the Request we make. Pass both to `fetchDidFail` to aid debugging.\n let pluginFilteredRequest = request.clone();\n try {\n let fetchResponse;\n // See https://github.com/GoogleChrome/workbox/issues/1796\n if (request.mode === 'navigate') {\n fetchResponse = await fetch(request);\n }\n else {\n fetchResponse = await fetch(request, fetchOptions);\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Network request for ` +\n `'${getFriendlyURL(request.url)}' returned a response with ` +\n `status '${fetchResponse.status}'.`);\n }\n for (const plugin of plugins) {\n if (\"fetchDidSucceed\" /* FETCH_DID_SUCCEED */ in plugin) {\n fetchResponse = await plugin[\"fetchDidSucceed\" /* FETCH_DID_SUCCEED */]\n .call(plugin, {\n event,\n request: pluginFilteredRequest,\n response: fetchResponse,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (fetchResponse) {\n assert.isInstance(fetchResponse, Response, {\n moduleName: 'Plugin',\n funcName: \"fetchDidSucceed\" /* FETCH_DID_SUCCEED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n return fetchResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Network request for ` +\n `'${getFriendlyURL(request.url)}' threw an error.`, error);\n }\n for (const plugin of failedFetchPlugins) {\n await plugin[\"fetchDidFail\" /* FETCH_DID_FAIL */].call(plugin, {\n error,\n event,\n originalRequest: originalRequest.clone(),\n request: pluginFilteredRequest.clone(),\n });\n }\n throw error;\n }\n};\nconst fetchWrapper = {\n fetch: wrappedFetch,\n};\nexport { fetchWrapper };\n","// @ts-ignore\ntry {\n self['workbox:strategies:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nlet supportStatus;\n/**\n * A utility function that determines whether the current browser supports\n * constructing a new `Response` from a `response.body` stream.\n *\n * @return {boolean} `true`, if the current browser can successfully\n * construct a `Response` from a `response.body` stream, `false` otherwise.\n *\n * @private\n */\nfunction canConstructResponseFromBodyStream() {\n if (supportStatus === undefined) {\n const testResponse = new Response('');\n if ('body' in testResponse) {\n try {\n new Response(testResponse.body);\n supportStatus = true;\n }\n catch (error) {\n supportStatus = false;\n }\n }\n supportStatus = false;\n }\n return supportStatus;\n}\nexport { canConstructResponseFromBodyStream };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * A class that wraps common IndexedDB functionality in a promise-based API.\n * It exposes all the underlying power and functionality of IndexedDB, but\n * wraps the most commonly used features in a way that's much simpler to use.\n *\n * @private\n */\nexport class DBWrapper {\n /**\n * @param {string} name\n * @param {number} version\n * @param {Object=} [callback]\n * @param {!Function} [callbacks.onupgradeneeded]\n * @param {!Function} [callbacks.onversionchange] Defaults to\n * DBWrapper.prototype._onversionchange when not specified.\n * @private\n */\n constructor(name, version, { onupgradeneeded, onversionchange, } = {}) {\n this._db = null;\n this._name = name;\n this._version = version;\n this._onupgradeneeded = onupgradeneeded;\n this._onversionchange = onversionchange || (() => this.close());\n }\n /**\n * Returns the IDBDatabase instance (not normally needed).\n * @return {IDBDatabase|undefined}\n *\n * @private\n */\n get db() {\n return this._db;\n }\n /**\n * Opens a connected to an IDBDatabase, invokes any onupgradedneeded\n * callback, and added an onversionchange callback to the database.\n *\n * @return {IDBDatabase}\n * @private\n */\n async open() {\n if (this._db)\n return;\n this._db = await new Promise((resolve, reject) => {\n // This flag is flipped to true if the timeout callback runs prior\n // to the request failing or succeeding. Note: we use a timeout instead\n // of an onblocked handler since there are cases where onblocked will\n // never never run. A timeout better handles all possible scenarios:\n // https://github.com/w3c/IndexedDB/issues/223\n let openRequestTimedOut = false;\n setTimeout(() => {\n openRequestTimedOut = true;\n reject(new Error('The open request was blocked and timed out'));\n }, this.OPEN_TIMEOUT);\n const openRequest = indexedDB.open(this._name, this._version);\n openRequest.onerror = () => reject(openRequest.error);\n openRequest.onupgradeneeded = (evt) => {\n if (openRequestTimedOut) {\n openRequest.transaction.abort();\n openRequest.result.close();\n }\n else if (typeof this._onupgradeneeded === 'function') {\n this._onupgradeneeded(evt);\n }\n };\n openRequest.onsuccess = () => {\n const db = openRequest.result;\n if (openRequestTimedOut) {\n db.close();\n }\n else {\n db.onversionchange = this._onversionchange.bind(this);\n resolve(db);\n }\n };\n });\n return this;\n }\n /**\n * Polyfills the native `getKey()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @return {Array}\n * @private\n */\n async getKey(storeName, query) {\n return (await this.getAllKeys(storeName, query, 1))[0];\n }\n /**\n * Polyfills the native `getAll()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @param {number} count\n * @return {Array}\n * @private\n */\n async getAll(storeName, query, count) {\n return await this.getAllMatching(storeName, { query, count });\n }\n /**\n * Polyfills the native `getAllKeys()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @param {number} count\n * @return {Array}\n * @private\n */\n async getAllKeys(storeName, query, count) {\n const entries = await this.getAllMatching(storeName, { query, count, includeKeys: true });\n return entries.map((entry) => entry.key);\n }\n /**\n * Supports flexible lookup in an object store by specifying an index,\n * query, direction, and count. This method returns an array of objects\n * with the signature .\n *\n * @param {string} storeName\n * @param {Object} [opts]\n * @param {string} [opts.index] The index to use (if specified).\n * @param {*} [opts.query]\n * @param {IDBCursorDirection} [opts.direction]\n * @param {number} [opts.count] The max number of results to return.\n * @param {boolean} [opts.includeKeys] When true, the structure of the\n * returned objects is changed from an array of values to an array of\n * objects in the form {key, primaryKey, value}.\n * @return {Array}\n * @private\n */\n async getAllMatching(storeName, { index, query = null, // IE/Edge errors if query === `undefined`.\n direction = 'next', count, includeKeys = false, } = {}) {\n return await this.transaction([storeName], 'readonly', (txn, done) => {\n const store = txn.objectStore(storeName);\n const target = index ? store.index(index) : store;\n const results = [];\n const request = target.openCursor(query, direction);\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n results.push(includeKeys ? cursor : cursor.value);\n if (count && results.length >= count) {\n done(results);\n }\n else {\n cursor.continue();\n }\n }\n else {\n done(results);\n }\n };\n });\n }\n /**\n * Accepts a list of stores, a transaction type, and a callback and\n * performs a transaction. A promise is returned that resolves to whatever\n * value the callback chooses. The callback holds all the transaction logic\n * and is invoked with two arguments:\n * 1. The IDBTransaction object\n * 2. A `done` function, that's used to resolve the promise when\n * when the transaction is done, if passed a value, the promise is\n * resolved to that value.\n *\n * @param {Array} storeNames An array of object store names\n * involved in the transaction.\n * @param {string} type Can be `readonly` or `readwrite`.\n * @param {!Function} callback\n * @return {*} The result of the transaction ran by the callback.\n * @private\n */\n async transaction(storeNames, type, callback) {\n await this.open();\n return await new Promise((resolve, reject) => {\n const txn = this._db.transaction(storeNames, type);\n txn.onabort = () => reject(txn.error);\n txn.oncomplete = () => resolve();\n callback(txn, (value) => resolve(value));\n });\n }\n /**\n * Delegates async to a native IDBObjectStore method.\n *\n * @param {string} method The method name.\n * @param {string} storeName The object store name.\n * @param {string} type Can be `readonly` or `readwrite`.\n * @param {...*} args The list of args to pass to the native method.\n * @return {*} The result of the transaction.\n * @private\n */\n async _call(method, storeName, type, ...args) {\n const callback = (txn, done) => {\n const objStore = txn.objectStore(storeName);\n const request = objStore[method].apply(objStore, args);\n request.onsuccess = () => done(request.result);\n };\n return await this.transaction([storeName], type, callback);\n }\n /**\n * Closes the connection opened by `DBWrapper.open()`. Generally this method\n * doesn't need to be called since:\n * 1. It's usually better to keep a connection open since opening\n * a new connection is somewhat slow.\n * 2. Connections are automatically closed when the reference is\n * garbage collected.\n * The primary use case for needing to close a connection is when another\n * reference (typically in another tab) needs to upgrade it and would be\n * blocked by the current, open connection.\n *\n * @private\n */\n close() {\n if (this._db) {\n this._db.close();\n this._db = null;\n }\n }\n}\n// Exposed on the prototype to let users modify the default timeout on a\n// per-instance or global basis.\nDBWrapper.prototype.OPEN_TIMEOUT = 2000;\n// Wrap native IDBObjectStore methods according to their mode.\nconst methodsToWrap = {\n readonly: ['get', 'count', 'getKey', 'getAll', 'getAllKeys'],\n readwrite: ['add', 'put', 'clear', 'delete'],\n};\nfor (const [mode, methods] of Object.entries(methodsToWrap)) {\n for (const method of methods) {\n if (method in IDBObjectStore.prototype) {\n // Don't use arrow functions here since we're outside of the class.\n DBWrapper.prototype[method] =\n async function (storeName, ...args) {\n return await this._call(method, storeName, mode, ...args);\n };\n }\n }\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { canConstructResponseFromBodyStream } from './_private/canConstructResponseFromBodyStream.js';\nimport './_version.js';\n/**\n * Allows developers to copy a response and modify its `headers`, `status`,\n * or `statusText` values (the values settable via a\n * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax}\n * object in the constructor).\n * To modify these values, pass a function as the second argument. That\n * function will be invoked with a single object with the response properties\n * `{headers, status, statusText}`. The return value of this function will\n * be used as the `ResponseInit` for the new `Response`. To change the values\n * either modify the passed parameter(s) and return it, or return a totally\n * new object.\n *\n * @param {Response} response\n * @param {Function} modifier\n * @alias workbox.core.copyResponse\n */\nasync function copyResponse(response, modifier) {\n const clonedResponse = response.clone();\n // Create a fresh `ResponseInit` object by cloning the headers.\n const responseInit = {\n headers: new Headers(clonedResponse.headers),\n status: clonedResponse.status,\n statusText: clonedResponse.statusText,\n };\n // Apply any user modifications.\n const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit;\n // Create the new response from the body stream and `ResponseInit`\n // modifications. Note: not all browsers support the Response.body stream,\n // so fall back to reading the entire body into memory as a blob.\n const body = canConstructResponseFromBodyStream() ?\n clonedResponse.body : await clonedResponse.blob();\n return new Response(body, modifiedResponseInit);\n}\n;\nexport { copyResponse };\n","// @ts-ignore\ntry {\n self['workbox:precaching:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst plugins = [];\nexport const precachePlugins = {\n /*\n * @return {Array}\n * @private\n */\n get() {\n return plugins;\n },\n /*\n * @param {Array} newPlugins\n * @private\n */\n add(newPlugins) {\n plugins.push(...newPlugins);\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport '../_version.js';\n// Name of the search parameter used to store revision info.\nconst REVISION_SEARCH_PARAM = '__WB_REVISION__';\n/**\n * Converts a manifest entry into a versioned URL suitable for precaching.\n *\n * @param {Object|string} entry\n * @return {string} A URL with versioning info.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function createCacheKey(entry) {\n if (!entry) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If a precache manifest entry is a string, it's assumed to be a versioned\n // URL, like '/app.abcd1234.js'. Return as-is.\n if (typeof entry === 'string') {\n const urlObject = new URL(entry, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n const { revision, url } = entry;\n if (!url) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If there's just a URL and no revision, then it's also assumed to be a\n // versioned URL.\n if (!revision) {\n const urlObject = new URL(url, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n // Otherwise, construct a properly versioned URL using the custom Workbox\n // search parameter along with the revision info.\n const cacheKeyURL = new URL(url, location.href);\n const originalURL = new URL(url, location.href);\n cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);\n return {\n cacheKey: cacheKeyURL.href,\n url: originalURL.href,\n };\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { cacheWrapper } from 'workbox-core/_private/cacheWrapper.js';\nimport { fetchWrapper } from 'workbox-core/_private/fetchWrapper.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { copyResponse } from 'workbox-core/copyResponse.js';\nimport { createCacheKey } from './utils/createCacheKey.js';\nimport { printCleanupDetails } from './utils/printCleanupDetails.js';\nimport { printInstallDetails } from './utils/printInstallDetails.js';\nimport './_version.js';\n/**\n * Performs efficient precaching of assets.\n *\n * @memberof module:workbox-precaching\n */\nclass PrecacheController {\n /**\n * Create a new PrecacheController.\n *\n * @param {string} [cacheName] An optional name for the cache, to override\n * the default precache name.\n */\n constructor(cacheName) {\n this._cacheName = cacheNames.getPrecacheName(cacheName);\n this._urlsToCacheKeys = new Map();\n this._cacheKeysToIntegrities = new Map();\n }\n /**\n * This method will add items to the precache list, removing duplicates\n * and ensuring the information is valid.\n *\n * @param {\n * Array\n * } entries Array of entries to precache.\n */\n addToCacheList(entries) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isArray(entries, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'addToCacheList',\n paramName: 'entries',\n });\n }\n for (const entry of entries) {\n const { cacheKey, url } = createCacheKey(entry);\n if (this._urlsToCacheKeys.has(url) &&\n this._urlsToCacheKeys.get(url) !== cacheKey) {\n throw new WorkboxError('add-to-cache-list-conflicting-entries', {\n firstEntry: this._urlsToCacheKeys.get(url),\n secondEntry: cacheKey,\n });\n }\n if (typeof entry !== 'string' && entry.integrity) {\n if (this._cacheKeysToIntegrities.has(cacheKey) &&\n this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {\n throw new WorkboxError('add-to-cache-list-conflicting-integrities', {\n url,\n });\n }\n this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);\n }\n this._urlsToCacheKeys.set(url, cacheKey);\n }\n }\n /**\n * Precaches new and updated assets. Call this method from the service worker\n * install event.\n *\n * @param {Object} options\n * @param {Event} [options.event] The install event (if needed).\n * @param {Array} [options.plugins] Plugins to be used for fetching\n * and caching during install.\n * @return {Promise}\n */\n async install({ event, plugins } = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (plugins) {\n assert.isArray(plugins, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'install',\n paramName: 'plugins',\n });\n }\n }\n const toBePrecached = [];\n const alreadyPrecached = [];\n const cache = await caches.open(this._cacheName);\n const alreadyCachedRequests = await cache.keys();\n const existingCacheKeys = new Set(alreadyCachedRequests.map((request) => request.url));\n for (const [url, cacheKey] of this._urlsToCacheKeys) {\n if (existingCacheKeys.has(cacheKey)) {\n alreadyPrecached.push(url);\n }\n else {\n toBePrecached.push({ cacheKey, url });\n }\n }\n const precacheRequests = toBePrecached.map(({ cacheKey, url }) => {\n const integrity = this._cacheKeysToIntegrities.get(cacheKey);\n return this._addURLToCache({ cacheKey, event, plugins, url, integrity });\n });\n await Promise.all(precacheRequests);\n const updatedURLs = toBePrecached.map((item) => item.url);\n if (process.env.NODE_ENV !== 'production') {\n printInstallDetails(updatedURLs, alreadyPrecached);\n }\n return {\n updatedURLs,\n notUpdatedURLs: alreadyPrecached,\n };\n }\n /**\n * Deletes assets that are no longer present in the current precache manifest.\n * Call this method from the service worker activate event.\n *\n * @return {Promise}\n */\n async activate() {\n const cache = await caches.open(this._cacheName);\n const currentlyCachedRequests = await cache.keys();\n const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());\n const deletedURLs = [];\n for (const request of currentlyCachedRequests) {\n if (!expectedCacheKeys.has(request.url)) {\n await cache.delete(request);\n deletedURLs.push(request.url);\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n printCleanupDetails(deletedURLs);\n }\n return { deletedURLs };\n }\n /**\n * Requests the entry and saves it to the cache if the response is valid.\n * By default, any response with a status code of less than 400 (including\n * opaque responses) is considered valid.\n *\n * If you need to use custom criteria to determine what's valid and what\n * isn't, then pass in an item in `options.plugins` that implements the\n * `cacheWillUpdate()` lifecycle event.\n *\n * @private\n * @param {Object} options\n * @param {string} options.cacheKey The string to use a cache key.\n * @param {string} options.url The URL to fetch and cache.\n * @param {Event} [options.event] The install event (if passed).\n * @param {Array} [options.plugins] An array of plugins to apply to\n * fetch and caching.\n * @param {string} [options.integrity] The value to use for the `integrity`\n * field when making the request.\n */\n async _addURLToCache({ cacheKey, url, event, plugins, integrity }) {\n const request = new Request(url, {\n integrity,\n cache: 'reload',\n credentials: 'same-origin',\n });\n let response = await fetchWrapper.fetch({\n event,\n plugins,\n request,\n });\n // Allow developers to override the default logic about what is and isn't\n // valid by passing in a plugin implementing cacheWillUpdate(), e.g.\n // a workbox.cacheableResponse.CacheableResponsePlugin instance.\n let cacheWillUpdatePlugin;\n for (const plugin of (plugins || [])) {\n if ('cacheWillUpdate' in plugin) {\n cacheWillUpdatePlugin = plugin;\n }\n }\n const isValidResponse = cacheWillUpdatePlugin ?\n // Use a callback if provided. It returns a truthy value if valid.\n // NOTE: invoke the method on the plugin instance so the `this` context\n // is correct.\n cacheWillUpdatePlugin.cacheWillUpdate({ event, request, response }) :\n // Otherwise, default to considering any response status under 400 valid.\n // This includes, by default, considering opaque responses valid.\n response.status < 400;\n // Consider this a failure, leading to the `install` handler failing, if\n // we get back an invalid response.\n if (!isValidResponse) {\n throw new WorkboxError('bad-precaching-response', {\n url,\n status: response.status,\n });\n }\n // Redirected responses cannot be used to satisfy a navigation request, so\n // any redirected response must be \"copied\" rather than cloned, so the new\n // response doesn't contain the `redirected` flag. See:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1\n if (response.redirected) {\n response = await copyResponse(response);\n }\n await cacheWrapper.put({\n event,\n plugins,\n response,\n // `request` already uses `url`. We may be able to reuse it.\n request: cacheKey === url ? request : new Request(cacheKey),\n cacheName: this._cacheName,\n matchOptions: {\n ignoreSearch: true,\n },\n });\n }\n /**\n * Returns a mapping of a precached URL to the corresponding cache key, taking\n * into account the revision information for the URL.\n *\n * @return {Map} A URL to cache key mapping.\n */\n getURLsToCacheKeys() {\n return this._urlsToCacheKeys;\n }\n /**\n * Returns a list of all the URLs that have been precached by the current\n * service worker.\n *\n * @return {Array} The precached URLs.\n */\n getCachedURLs() {\n return [...this._urlsToCacheKeys.keys()];\n }\n /**\n * Returns the cache key used for storing a given URL. If that URL is\n * unversioned, like `/index.html', then the cache key will be the original\n * URL with a search parameter appended to it.\n *\n * @param {string} url A URL whose cache key you want to look up.\n * @return {string} The versioned URL that corresponds to a cache key\n * for the original URL, or undefined if that URL isn't precached.\n */\n getCacheKeyForURL(url) {\n const urlObject = new URL(url, location.href);\n return this._urlsToCacheKeys.get(urlObject.href);\n }\n /**\n * Returns a function that looks up `url` in the precache (taking into\n * account revision information), and returns the corresponding `Response`.\n *\n * If for an unexpected reason there is a cache miss when looking up `url`,\n * this will fall back to retrieving the `Response` via `fetch()`.\n *\n * @param {string} url The precached URL which will be used to lookup the\n * `Response`.\n * @return {workbox.routing.Route~handlerCallback}\n */\n createHandlerForURL(url) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(url, 'string', {\n moduleName: 'workbox-precaching',\n funcName: 'createHandlerForURL',\n paramName: 'url',\n });\n }\n const cacheKey = this.getCacheKeyForURL(url);\n if (!cacheKey) {\n throw new WorkboxError('non-precached-url', { url });\n }\n return async () => {\n try {\n const cache = await caches.open(this._cacheName);\n const response = await cache.match(cacheKey);\n if (response) {\n return response;\n }\n // This shouldn't normally happen, but there are edge cases:\n // https://github.com/GoogleChrome/workbox/issues/1441\n throw new Error(`The cache ${this._cacheName} did not have an entry ` +\n `for ${cacheKey}.`);\n }\n catch (error) {\n // If there's either a cache miss, or the caches.match() call threw\n // an exception, then attempt to fulfill the navigation request with\n // a response from the network rather than leaving the user with a\n // failed navigation.\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Unable to respond to navigation request with ` +\n `cached response. Falling back to network.`, error);\n }\n // This might still fail if the browser is offline...\n return fetch(cacheKey);\n }\n };\n }\n ;\n}\nexport { PrecacheController };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { PrecacheController } from '../PrecacheController.js';\nimport '../_version.js';\nlet precacheController;\n/**\n * @return {PrecacheController}\n * @private\n */\nexport const getOrCreatePrecacheController = () => {\n if (!precacheController) {\n precacheController = new PrecacheController();\n }\n return precacheController;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { getOrCreatePrecacheController } from './getOrCreatePrecacheController.js';\nimport { generateURLVariations } from './generateURLVariations.js';\nimport '../_version.js';\n/**\n * This function will take the request URL and manipulate it based on the\n * configuration options.\n *\n * @param {string} url\n * @param {Object} options\n * @return {string} Returns the URL in the cache that matches the request,\n * if possible.\n *\n * @private\n */\nexport const getCacheKeyForURL = (url, options) => {\n const precacheController = getOrCreatePrecacheController();\n const urlsToCacheKeys = precacheController.getURLsToCacheKeys();\n for (const possibleURL of generateURLVariations(url, options)) {\n const possibleCacheKey = urlsToCacheKeys.get(possibleURL);\n if (possibleCacheKey) {\n return possibleCacheKey;\n }\n }\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { removeIgnoredSearchParams } from './removeIgnoredSearchParams.js';\nimport '../_version.js';\n/**\n * Generator function that yields possible variations on the original URL to\n * check, one at a time.\n *\n * @param {string} url\n * @param {Object} options\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function* generateURLVariations(url, { ignoreURLParametersMatching, directoryIndex, cleanURLs, urlManipulation, } = {}) {\n const urlObject = new URL(url, location.href);\n urlObject.hash = '';\n yield urlObject.href;\n const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching);\n yield urlWithoutIgnoredParams.href;\n if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) {\n const directoryURL = new URL(urlWithoutIgnoredParams.href);\n directoryURL.pathname += directoryIndex;\n yield directoryURL.href;\n }\n if (cleanURLs) {\n const cleanURL = new URL(urlWithoutIgnoredParams.href);\n cleanURL.pathname += '.html';\n yield cleanURL.href;\n }\n if (urlManipulation) {\n const additionalURLs = urlManipulation({ url: urlObject });\n for (const urlToAttempt of additionalURLs) {\n yield urlToAttempt.href;\n }\n }\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * Removes any URL search parameters that should be ignored.\n *\n * @param {URL} urlObject The original URL.\n * @param {Array} ignoreURLParametersMatching RegExps to test against\n * each search parameter name. Matches mean that the search parameter should be\n * ignored.\n * @return {URL} The URL with any ignored search parameters removed.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) {\n // Convert the iterable into an array at the start of the loop to make sure\n // deletion doesn't mess up iteration.\n for (const paramName of [...urlObject.searchParams.keys()]) {\n if (ignoreURLParametersMatching.some((regExp) => regExp.test(paramName))) {\n urlObject.searchParams.delete(paramName);\n }\n }\n return urlObject;\n}\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addFetchListener } from './utils/addFetchListener.js';\nimport './_version.js';\nlet listenerAdded = false;\n/**\n * Add a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * @param {Object} [options]\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox.precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n *\n * @alias workbox.precaching.addRoute\n */\nexport const addRoute = (options) => {\n if (!listenerAdded) {\n addFetchListener(options);\n listenerAdded = true;\n }\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getCacheKeyForURL } from './getCacheKeyForURL.js';\nimport '../_version.js';\n/**\n * Adds a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * NOTE: when called more than once this method will replace the previously set\n * configuration options. Calling it more than once is not recommended outside\n * of tests.\n *\n * @private\n * @param {Object} [options]\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox.precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n */\nexport const addFetchListener = ({ ignoreURLParametersMatching = [/^utm_/], directoryIndex = 'index.html', cleanURLs = true, urlManipulation, } = {}) => {\n const cacheName = cacheNames.getPrecacheName();\n addEventListener('fetch', (event) => {\n const precachedURL = getCacheKeyForURL(event.request.url, {\n cleanURLs,\n directoryIndex,\n ignoreURLParametersMatching,\n urlManipulation,\n });\n if (!precachedURL) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Precaching did not find a match for ` +\n getFriendlyURL(event.request.url));\n }\n return;\n }\n let responsePromise = caches.open(cacheName).then((cache) => {\n return cache.match(precachedURL);\n }).then((cachedResponse) => {\n if (cachedResponse) {\n return cachedResponse;\n }\n // Fall back to the network if we don't have a cached response\n // (perhaps due to manual cache cleanup).\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`The precached response for ` +\n `${getFriendlyURL(precachedURL)} in ${cacheName} was not found. ` +\n `Falling back to the network instead.`);\n }\n return fetch(precachedURL);\n });\n if (process.env.NODE_ENV !== 'production') {\n responsePromise = responsePromise.then((response) => {\n // Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Precaching is responding to: ` +\n getFriendlyURL(event.request.url));\n logger.log(`Serving the precached url: ${precachedURL}`);\n logger.groupCollapsed(`View request details here.`);\n logger.log(event.request);\n logger.groupEnd();\n logger.groupCollapsed(`View response details here.`);\n logger.log(response);\n logger.groupEnd();\n logger.groupEnd();\n return response;\n });\n }\n event.respondWith(responsePromise);\n });\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js';\nimport { precachePlugins } from './utils/precachePlugins.js';\nimport './_version.js';\nconst installListener = (event) => {\n const precacheController = getOrCreatePrecacheController();\n const plugins = precachePlugins.get();\n event.waitUntil(precacheController.install({ event, plugins })\n .catch((error) => {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Service worker installation failed. It will ` +\n `be retried automatically during the next navigation.`);\n }\n // Re-throw the error to ensure installation fails.\n throw error;\n }));\n};\nconst activateListener = (event) => {\n const precacheController = getOrCreatePrecacheController();\n event.waitUntil(precacheController.activate());\n};\n/**\n * Adds items to the precache list, removing any duplicates and\n * stores the files in the\n * [\"precache cache\"]{@link module:workbox-core.cacheNames} when the service\n * worker installs.\n *\n * This method can be called multiple times.\n *\n * Please note: This method **will not** serve any of the cached files for you.\n * It only precaches files. To respond to a network request you call\n * [addRoute()]{@link module:workbox-precaching.addRoute}.\n *\n * If you have a single array of files to precache, you can just call\n * [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}.\n *\n * @param {Array} [entries=[]] Array of entries to precache.\n *\n * @alias workbox.precaching.precache\n */\nexport const precache = (entries) => {\n const precacheController = getOrCreatePrecacheController();\n precacheController.addToCacheList(entries);\n if (entries.length > 0) {\n // NOTE: these listeners will only be added once (even if the `precache()`\n // method is called multiple times) because event listeners are implemented\n // as a set, where each listener must be unique.\n addEventListener('install', installListener);\n addEventListener('activate', activateListener);\n }\n};\n","// @ts-ignore\ntry {\n self['workbox:range-requests:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { calculateEffectiveBoundaries } from './utils/calculateEffectiveBoundaries.js';\nimport { parseRangeHeader } from './utils/parseRangeHeader.js';\nimport './_version.js';\n/**\n * Given a `Request` and `Response` objects as input, this will return a\n * promise for a new `Response`.\n *\n * If the original `Response` already contains partial content (i.e. it has\n * a status of 206), then this assumes it already fulfills the `Range:`\n * requirements, and will return it as-is.\n *\n * @param {Request} request A request, which should contain a Range:\n * header.\n * @param {Response} originalResponse A response.\n * @return {Promise} Either a `206 Partial Content` response, with\n * the response body set to the slice of content specified by the request's\n * `Range:` header, or a `416 Range Not Satisfiable` response if the\n * conditions of the `Range:` header can't be met.\n *\n * @memberof workbox.rangeRequests\n */\nasync function createPartialResponse(request, originalResponse) {\n try {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'request',\n });\n assert.isInstance(originalResponse, Response, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'originalResponse',\n });\n }\n if (originalResponse.status === 206) {\n // If we already have a 206, then just pass it through as-is;\n // see https://github.com/GoogleChrome/workbox/issues/1720\n return originalResponse;\n }\n const rangeHeader = request.headers.get('range');\n if (!rangeHeader) {\n throw new WorkboxError('no-range-header');\n }\n const boundaries = parseRangeHeader(rangeHeader);\n const originalBlob = await originalResponse.blob();\n const effectiveBoundaries = calculateEffectiveBoundaries(originalBlob, boundaries.start, boundaries.end);\n const slicedBlob = originalBlob.slice(effectiveBoundaries.start, effectiveBoundaries.end);\n const slicedBlobSize = slicedBlob.size;\n const slicedResponse = new Response(slicedBlob, {\n // Status code 206 is for a Partial Content response.\n // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206\n status: 206,\n statusText: 'Partial Content',\n headers: originalResponse.headers,\n });\n slicedResponse.headers.set('Content-Length', String(slicedBlobSize));\n slicedResponse.headers.set('Content-Range', `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` +\n originalBlob.size);\n return slicedResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to construct a partial response; returning a ` +\n `416 Range Not Satisfiable response instead.`);\n logger.groupCollapsed(`View details here.`);\n logger.log(error);\n logger.log(request);\n logger.log(originalResponse);\n logger.groupEnd();\n }\n return new Response('', {\n status: 416,\n statusText: 'Range Not Satisfiable',\n });\n }\n}\nexport { createPartialResponse };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {string} rangeHeader A Range: header value.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the parsed value of the Range: header. If either the `start` or `end` are\n * omitted, then `null` will be returned.\n *\n * @private\n */\nfunction parseRangeHeader(rangeHeader) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(rangeHeader, 'string', {\n moduleName: 'workbox-range-requests',\n funcName: 'parseRangeHeader',\n paramName: 'rangeHeader',\n });\n }\n const normalizedRangeHeader = rangeHeader.trim().toLowerCase();\n if (!normalizedRangeHeader.startsWith('bytes=')) {\n throw new WorkboxError('unit-must-be-bytes', { normalizedRangeHeader });\n }\n // Specifying multiple ranges separate by commas is valid syntax, but this\n // library only attempts to handle a single, contiguous sequence of bytes.\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#Syntax\n if (normalizedRangeHeader.includes(',')) {\n throw new WorkboxError('single-range-only', { normalizedRangeHeader });\n }\n const rangeParts = /(\\d*)-(\\d*)/.exec(normalizedRangeHeader);\n // We need either at least one of the start or end values.\n if (!rangeParts || !(rangeParts[1] || rangeParts[2])) {\n throw new WorkboxError('invalid-range-values', { normalizedRangeHeader });\n }\n return {\n start: rangeParts[1] === '' ? undefined : Number(rangeParts[1]),\n end: rangeParts[2] === '' ? undefined : Number(rangeParts[2]),\n };\n}\nexport { parseRangeHeader };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {Blob} blob A source blob.\n * @param {number} [start] The offset to use as the start of the\n * slice.\n * @param {number} [end] The offset to use as the end of the slice.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the effective boundaries to use given the size of the blob.\n *\n * @private\n */\nfunction calculateEffectiveBoundaries(blob, start, end) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(blob, Blob, {\n moduleName: 'workbox-range-requests',\n funcName: 'calculateEffectiveBoundaries',\n paramName: 'blob',\n });\n }\n const blobSize = blob.size;\n if ((end && end > blobSize) || (start && start < 0)) {\n throw new WorkboxError('range-not-satisfiable', {\n size: blobSize,\n end,\n start,\n });\n }\n let effectiveStart;\n let effectiveEnd;\n if (start !== undefined && end !== undefined) {\n effectiveStart = start;\n // Range values are inclusive, so add 1 to the value.\n effectiveEnd = end + 1;\n }\n else if (start !== undefined && end === undefined) {\n effectiveStart = start;\n effectiveEnd = blobSize;\n }\n else if (end !== undefined && start === undefined) {\n effectiveStart = blobSize - end;\n effectiveEnd = blobSize;\n }\n return {\n start: effectiveStart,\n end: effectiveEnd,\n };\n}\nexport { calculateEffectiveBoundaries };\n","// @ts-ignore\ntry {\n self['workbox:routing:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * The default HTTP method, 'GET', used when there's no specific method\n * configured for a route.\n *\n * @type {string}\n *\n * @private\n */\nexport const defaultMethod = 'GET';\n/**\n * The list of valid HTTP methods associated with requests that could be routed.\n *\n * @type {Array}\n *\n * @private\n */\nexport const validMethods = [\n 'DELETE',\n 'GET',\n 'HEAD',\n 'PATCH',\n 'POST',\n 'PUT',\n];\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {function()|Object} handler Either a function, or an object with a\n * 'handle' method.\n * @return {Object} An object with a handle method.\n *\n * @private\n */\nexport const normalizeHandler = (handler) => {\n if (handler && typeof handler === 'object') {\n if (process.env.NODE_ENV !== 'production') {\n assert.hasMethod(handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return handler;\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(handler, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return { handle: handler };\n }\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { defaultMethod, validMethods } from './utils/constants.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * A `Route` consists of a pair of callback functions, \"match\" and \"handler\".\n * The \"match\" callback determine if a route should be used to \"handle\" a\n * request by returning a non-falsy value if it can. The \"handler\" callback\n * is called when there is a match and should return a Promise that resolves\n * to a `Response`.\n *\n * @memberof workbox.routing\n */\nclass Route {\n /**\n * Constructor for Route class.\n *\n * @param {workbox.routing.Route~matchCallback} match\n * A callback function that determines whether the route matches a given\n * `fetch` event by returning a non-falsy value.\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resolving to a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(match, handler, method = defaultMethod) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(match, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'match',\n });\n if (method) {\n assert.isOneOf(method, validMethods, { paramName: 'method' });\n }\n }\n // These values are referenced directly by Router so cannot be\n // altered by minifification.\n this.handler = normalizeHandler(handler);\n this.match = match;\n this.method = method;\n }\n}\nexport { Route };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { Route } from './Route.js';\nimport './_version.js';\n/**\n * RegExpRoute makes it easy to create a regular expression based\n * [Route]{@link workbox.routing.Route}.\n *\n * For same-origin requests the RegExp only needs to match part of the URL. For\n * requests against third-party servers, you must define a RegExp that matches\n * the start of the URL.\n *\n * [See the module docs for info.]{@link https://developers.google.com/web/tools/workbox/modules/workbox-routing}\n *\n * @memberof workbox.routing\n * @extends workbox.routing.Route\n */\nclass RegExpRoute extends Route {\n /**\n * If the regulard expression contains\n * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},\n * th ecaptured values will be passed to the\n * [handler's]{@link workbox.routing.Route~handlerCallback} `params`\n * argument.\n *\n * @param {RegExp} regExp The regular expression to match against URLs.\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(regExp, handler, method) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(regExp, RegExp, {\n moduleName: 'workbox-routing',\n className: 'RegExpRoute',\n funcName: 'constructor',\n paramName: 'pattern',\n });\n }\n const match = ({ url }) => {\n const result = regExp.exec(url.href);\n // Return immediately if there's no match.\n if (!result) {\n return;\n }\n // Require that the match start at the first character in the URL string\n // if it's a cross-origin request.\n // See https://github.com/GoogleChrome/workbox/issues/281 for the context\n // behind this behavior.\n if ((url.origin !== location.origin) && (result.index !== 0)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`The regular expression '${regExp}' only partially matched ` +\n `against the cross-origin URL '${url}'. RegExpRoute's will only ` +\n `handle cross-origin requests if they match the entire URL.`);\n }\n return;\n }\n // If the route matches, but there aren't any capture groups defined, then\n // this will return [], which is truthy and therefore sufficient to\n // indicate a match.\n // If there are capture groups, then it will return their values.\n return result.slice(1);\n };\n super(match, handler, method);\n }\n}\nexport { RegExpRoute };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * The Router can be used to process a FetchEvent through one or more\n * [Routes]{@link workbox.routing.Route} responding with a Request if\n * a matching route exists.\n *\n * If no route matches a given a request, the Router will use a \"default\"\n * handler if one is defined.\n *\n * Should the matching Route throw an error, the Router will use a \"catch\"\n * handler if one is defined to gracefully deal with issues and respond with a\n * Request.\n *\n * If a request matches multiple routes, the **earliest** registered route will\n * be used to respond to the request.\n *\n * @memberof workbox.routing\n */\nclass Router {\n /**\n * Initializes a new Router.\n */\n constructor() {\n this._routes = new Map();\n }\n /**\n * @return {Map>} routes A `Map` of HTTP\n * method name ('GET', etc.) to an array of all the corresponding `Route`\n * instances that are registered.\n */\n get routes() {\n return this._routes;\n }\n /**\n * Adds a fetch event listener to respond to events when a route matches\n * the event's request.\n */\n addFetchListener() {\n self.addEventListener('fetch', (event) => {\n const { request } = event;\n const responsePromise = this.handleRequest({ request, event });\n if (responsePromise) {\n event.respondWith(responsePromise);\n }\n });\n }\n /**\n * Adds a message event listener for URLs to cache from the window.\n * This is useful to cache resources loaded on the page prior to when the\n * service worker started controlling it.\n *\n * The format of the message data sent from the window should be as follows.\n * Where the `urlsToCache` array may consist of URL strings or an array of\n * URL string + `requestInit` object (the same as you'd pass to `fetch()`).\n *\n * ```\n * {\n * type: 'CACHE_URLS',\n * payload: {\n * urlsToCache: [\n * './script1.js',\n * './script2.js',\n * ['./script3.js', {mode: 'no-cors'}],\n * ],\n * },\n * }\n * ```\n */\n addCacheListener() {\n self.addEventListener('message', async (event) => {\n if (event.data && event.data.type === 'CACHE_URLS') {\n const { payload } = event.data;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Caching URLs from the window`, payload.urlsToCache);\n }\n const requestPromises = Promise.all(payload.urlsToCache.map((entry) => {\n if (typeof entry === 'string') {\n entry = [entry];\n }\n const request = new Request(...entry);\n return this.handleRequest({ request });\n // TODO(philipwalton): TypeScript errors without this typecast for\n // some reason (probably a bug). The real type here should work but\n // doesn't: `Array | undefined>`.\n })); // TypeScript\n event.waitUntil(requestPromises);\n // If a MessageChannel was used, reply to the message on success.\n if (event.ports && event.ports[0]) {\n await requestPromises;\n event.ports[0].postMessage(true);\n }\n }\n });\n }\n /**\n * Apply the routing rules to a FetchEvent object to get a Response from an\n * appropriate Route's handler.\n *\n * @param {Object} options\n * @param {Request} options.request The request to handle (this is usually\n * from a fetch event, but it does not have to be).\n * @param {FetchEvent} [options.event] The event that triggered the request,\n * if applicable.\n * @return {Promise|undefined} A promise is returned if a\n * registered route can handle the request. If there is no matching\n * route and there's no `defaultHandler`, `undefined` is returned.\n */\n handleRequest({ request, event }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'handleRequest',\n paramName: 'options.request',\n });\n }\n const url = new URL(request.url, location.href);\n if (!url.protocol.startsWith('http')) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Workbox Router only supports URLs that start with 'http'.`);\n }\n return;\n }\n let { params, route } = this.findMatchingRoute({ url, request, event });\n let handler = route && route.handler;\n let debugMessages = [];\n if (process.env.NODE_ENV !== 'production') {\n if (handler) {\n debugMessages.push([\n `Found a route to handle this request:`, route,\n ]);\n if (params) {\n debugMessages.push([\n `Passing the following params to the route's handler:`, params,\n ]);\n }\n }\n }\n // If we don't have a handler because there was no matching route, then\n // fall back to defaultHandler if that's defined.\n if (!handler && this._defaultHandler) {\n if (process.env.NODE_ENV !== 'production') {\n debugMessages.push(`Failed to find a matching route. Falling ` +\n `back to the default handler.`);\n }\n handler = this._defaultHandler;\n }\n if (!handler) {\n if (process.env.NODE_ENV !== 'production') {\n // No handler so Workbox will do nothing. If logs is set of debug\n // i.e. verbose, we should print out this information.\n logger.debug(`No route found for: ${getFriendlyURL(url)}`);\n }\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n // We have a handler, meaning Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`);\n debugMessages.forEach((msg) => {\n if (Array.isArray(msg)) {\n logger.log(...msg);\n }\n else {\n logger.log(msg);\n }\n });\n // The Request and Response objects contains a great deal of information,\n // hide it under a group in case developers want to see it.\n logger.groupCollapsed(`View request details here.`);\n logger.log(request);\n logger.groupEnd();\n logger.groupEnd();\n }\n // Wrap in try and catch in case the handle method throws a synchronous\n // error. It should still callback to the catch handler.\n let responsePromise;\n try {\n responsePromise = handler.handle({ url, request, event, params });\n }\n catch (err) {\n responsePromise = Promise.reject(err);\n }\n if (responsePromise && this._catchHandler) {\n responsePromise = responsePromise.catch((err) => {\n if (process.env.NODE_ENV !== 'production') {\n // Still include URL here as it will be async from the console group\n // and may not make sense without the URL\n logger.groupCollapsed(`Error thrown when responding to: ` +\n ` ${getFriendlyURL(url)}. Falling back to Catch Handler.`);\n logger.error(`Error thrown by:`, route);\n logger.error(err);\n logger.groupEnd();\n }\n return this._catchHandler.handle({ url, request, event });\n });\n }\n return responsePromise;\n }\n /**\n * Checks a request and URL (and optionally an event) against the list of\n * registered routes, and if there's a match, returns the corresponding\n * route along with any params generated by the match.\n *\n * @param {Object} options\n * @param {URL} options.url\n * @param {Request} options.request The request to match.\n * @param {Event} [options.event] The corresponding event (unless N/A).\n * @return {Object} An object with `route` and `params` properties.\n * They are populated if a matching route was found or `undefined`\n * otherwise.\n */\n findMatchingRoute({ url, request, event }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(url, URL, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'findMatchingRoute',\n paramName: 'options.url',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'findMatchingRoute',\n paramName: 'options.request',\n });\n }\n const routes = this._routes.get(request.method) || [];\n for (const route of routes) {\n let params;\n let matchResult = route.match({ url, request, event });\n if (matchResult) {\n // See https://github.com/GoogleChrome/workbox/issues/2079\n params = matchResult;\n if (Array.isArray(matchResult) && matchResult.length === 0) {\n // Instead of passing an empty array in as params, use undefined.\n params = undefined;\n }\n else if ((matchResult.constructor === Object &&\n Object.keys(matchResult).length === 0)) {\n // Instead of passing an empty object in as params, use undefined.\n params = undefined;\n }\n else if (typeof matchResult === 'boolean') {\n // For the boolean value true (rather than just something truth-y),\n // don't set params.\n // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353\n params = undefined;\n }\n // Return early if have a match.\n return { route, params };\n }\n }\n // If no match was found above, return and empty object.\n return {};\n }\n /**\n * Define a default `handler` that's called when no routes explicitly\n * match the incoming request.\n *\n * Without a default handler, unmatched requests will go against the\n * network as if there were no service worker present.\n *\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setDefaultHandler(handler) {\n this._defaultHandler = normalizeHandler(handler);\n }\n /**\n * If a Route throws an error while handling a request, this `handler`\n * will be called and given a chance to provide a response.\n *\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setCatchHandler(handler) {\n this._catchHandler = normalizeHandler(handler);\n }\n /**\n * Registers a route with the router.\n *\n * @param {workbox.routing.Route} route The route to register.\n */\n registerRoute(route) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(route, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route, 'match', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.isType(route.handler, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route.handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.handler',\n });\n assert.isType(route.method, 'string', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.method',\n });\n }\n if (!this._routes.has(route.method)) {\n this._routes.set(route.method, []);\n }\n // Give precedence to all of the earlier routes by adding this additional\n // route to the end of the array.\n this._routes.get(route.method).push(route);\n }\n /**\n * Unregisters a route with the router.\n *\n * @param {workbox.routing.Route} route The route to unregister.\n */\n unregisterRoute(route) {\n if (!this._routes.has(route.method)) {\n throw new WorkboxError('unregister-route-but-not-found-with-method', {\n method: route.method,\n });\n }\n const routeIndex = this._routes.get(route.method).indexOf(route);\n if (routeIndex > -1) {\n this._routes.get(route.method).splice(routeIndex, 1);\n }\n else {\n throw new WorkboxError('unregister-route-route-not-registered');\n }\n }\n}\nexport { Router };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { Router } from '../Router.js';\nimport '../_version.js';\nlet defaultRouter;\n/**\n * Creates a new, singleton Router instance if one does not exist. If one\n * does already exist, that instance is returned.\n *\n * @private\n * @return {Router}\n */\nexport const getOrCreateDefaultRouter = () => {\n if (!defaultRouter) {\n defaultRouter = new Router();\n // The helpers that use the default Router assume these listeners exist.\n defaultRouter.addFetchListener();\n defaultRouter.addCacheListener();\n }\n return defaultRouter;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { Route } from './Route.js';\nimport { RegExpRoute } from './RegExpRoute.js';\nimport { getOrCreateDefaultRouter } from './utils/getOrCreateDefaultRouter.js';\nimport './_version.js';\n/**\n * Easily register a RegExp, string, or function with a caching\n * strategy to a singleton Router instance.\n *\n * This method will generate a Route for you if needed and\n * call [Router.registerRoute()]{@link\n * workbox.routing.Router#registerRoute}.\n *\n * @param {\n * RegExp|\n * string|\n * workbox.routing.Route~matchCallback|\n * workbox.routing.Route\n * } capture\n * If the capture param is a `Route`, all other arguments will be ignored.\n * @param {workbox.routing.Route~handlerCallback} [handler] A callback\n * function that returns a Promise resulting in a Response. This parameter\n * is required if `capture` is not a `Route` object.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n * @return {workbox.routing.Route} The generated `Route`(Useful for\n * unregistering).\n *\n * @alias workbox.routing.registerRoute\n */\nexport const registerRoute = (capture, handler, method) => {\n let route;\n if (typeof capture === 'string') {\n const captureUrl = new URL(capture, location.href);\n if (process.env.NODE_ENV !== 'production') {\n if (!(capture.startsWith('/') || capture.startsWith('http'))) {\n throw new WorkboxError('invalid-string', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n // We want to check if Express-style wildcards are in the pathname only.\n // TODO: Remove this log message in v4.\n const valueToCheck = capture.startsWith('http') ?\n captureUrl.pathname : capture;\n // See https://github.com/pillarjs/path-to-regexp#parameters\n const wildcards = '[*:?+]';\n if (valueToCheck.match(new RegExp(`${wildcards}`))) {\n logger.debug(`The '$capture' parameter contains an Express-style wildcard ` +\n `character (${wildcards}). Strings are now always interpreted as ` +\n `exact matches; use a RegExp for partial or wildcard matches.`);\n }\n }\n const matchCallback = ({ url }) => {\n if (process.env.NODE_ENV !== 'production') {\n if ((url.pathname === captureUrl.pathname) &&\n (url.origin !== captureUrl.origin)) {\n logger.debug(`${capture} only partially matches the cross-origin URL ` +\n `${url}. This route will only handle cross-origin requests ` +\n `if they match the entire URL.`);\n }\n }\n return url.href === captureUrl.href;\n };\n // If `capture` is a string then `handler` and `method` must be present.\n route = new Route(matchCallback, handler, method);\n }\n else if (capture instanceof RegExp) {\n // If `capture` is a `RegExp` then `handler` and `method` must be present.\n route = new RegExpRoute(capture, handler, method);\n }\n else if (typeof capture === 'function') {\n // If `capture` is a function then `handler` and `method` must be present.\n route = new Route(capture, handler, method);\n }\n else if (capture instanceof Route) {\n route = capture;\n }\n else {\n throw new WorkboxError('unsupported-route-type', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n const defaultRouter = getOrCreateDefaultRouter();\n defaultRouter.registerRoute(route);\n return route;\n};\n","/**\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n **/\n\nexport const cacheName = 'media';\nexport const channelName = 'messages';\nexport const fadeConfig = {duration: 200};\nexport const urlPrefix = '/_media/';\n","/**\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n **/\n\nimport {cacheName} from './constants';\n\nasync function _getCachedMediaMetadata() {\n const cache = await caches.open(cacheName);\n const requests = await cache.keys();\n return Promise.all(requests.reverse().map(async (request) => {\n const response = await cache.match(request);\n return {\n contentType: response.headers.get('content-type'),\n src: request.url,\n };\n }));\n}\nconst cachedMediaMetadataPromise = _getCachedMediaMetadata();\n\nexport async function getCachedMediaMetadata(contentTypePrefix) {\n const cachedMetadata = await cachedMediaMetadataPromise;\n return cachedMetadata.filter((metadata) => metadata.contentType.startsWith(contentTypePrefix));\n}\n\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n\n","import {CacheOnly} from 'workbox-strategies';\nimport {clientsClaim, skipWaiting} from 'workbox-core';\nimport {precacheAndRoute} from 'workbox-precaching';\nimport {RangeRequestsPlugin} from 'workbox-range-requests';\nimport {registerRoute} from 'workbox-routing';\n\nimport {cacheName, channelName, urlPrefix} from './constants';\nimport {mimeRoute as audioRoute} from '../svelte/routes/Audio.svelte';\nimport {mimeRoute as imagesRoute} from '../svelte/routes/Images.svelte';\nimport {mimeRoute as videosRoute} from '../svelte/routes/Videos.svelte';\n\nconst broadcastChannel = BroadcastChannel ? new BroadcastChannel(channelName) : null;\n\nconst shareTargetHandler = async ({event}) => {\n if (broadcastChannel) {\n broadcastChannel.postMessage('Saving media locally...');\n }\n\n const formData = await event.request.formData();\n const mediaFiles = formData.getAll('media');\n const cache = await caches.open(cacheName);\n\n for (const mediaFile of mediaFiles) {\n // TODO: Instead of bailing, come up with a\n // default name for each possible MIME type.\n if (!mediaFile.name) {\n if (broadcastChannel) {\n broadcastChannel.postMessage('Sorry! No name found on incoming media.');\n }\n continue;\n }\n await cache.put(\n // TODO: Handle scenarios in which mediaFile.name isn't set,\n // or doesn't include a proper extension.\n `${urlPrefix}${Date.now()}-${mediaFile.name}`,\n new Response(mediaFile, {\n headers: {\n 'content-length': mediaFile.size,\n 'content-type': mediaFile.type,\n },\n })\n );\n }\n\n // Use the MIME type of the first file shared to determine where we redirect.\n const routeToRedirectTo = [\n audioRoute,\n imagesRoute,\n videosRoute,\n ].find((route) => mediaFiles[0].type.startsWith(route.mimePrefix));\n\n const redirectionUrl = routeToRedirectTo ? `/#${routeToRedirectTo.href}` : '/';\n \n // After the POST succeeds, redirect to the main page.\n return Response.redirect(redirectionUrl, 303);\n};\n\nconst cachedMediaHandler = new CacheOnly({\n cacheName,\n plugins: [\n // Support for cache requests that include a Range: header.\n new RangeRequestsPlugin(),\n ],\n});\n\nskipWaiting();\nclientsClaim();\n\n// This will be replaced by the list of files to precache by\n// the `workbox injectManifest` build step.\nprecacheAndRoute(self.__WB_MANIFEST);\n\nregisterRoute(\n '/_share-target',\n shareTargetHandler,\n 'POST'\n);\n\nregisterRoute(\n new RegExp(urlPrefix),\n cachedMediaHandler\n);\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { cacheWrapper } from 'workbox-core/_private/cacheWrapper.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { messages } from './utils/messages.js';\nimport './_version.js';\n/**\n * An implementation of a\n * [cache-only]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-only}\n * request strategy.\n *\n * This class is useful if you want to take advantage of any\n * [Workbox plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}.\n *\n * If there is no cache match, this will throw a `WorkboxError` exception.\n *\n * @memberof workbox.strategies\n */\nclass CacheOnly {\n /**\n * @param {Object} options\n * @param {string} options.cacheName Cache name to store and retrieve\n * requests. Defaults to cache names provided by\n * [workbox-core]{@link workbox.core.cacheNames}.\n * @param {Array} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}\n * to use in conjunction with this caching strategy.\n * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)\n */\n constructor(options = {}) {\n this._cacheName = cacheNames.getRuntimeName(options.cacheName);\n this._plugins = options.plugins || [];\n this._matchOptions = options.matchOptions;\n }\n /**\n * This method will perform a request strategy and follows an API that\n * will work with the\n * [Workbox Router]{@link workbox.routing.Router}.\n *\n * @param {Object} options\n * @param {Request} options.request The request to run this strategy for.\n * @param {Event} [options.event] The event that triggered the request.\n * @return {Promise}\n */\n async handle({ event, request }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-strategies',\n className: 'CacheOnly',\n funcName: 'makeRequest',\n paramName: 'request',\n });\n }\n const response = await cacheWrapper.match({\n cacheName: this._cacheName,\n request,\n event,\n matchOptions: this._matchOptions,\n plugins: this._plugins,\n });\n if (process.env.NODE_ENV !== 'production') {\n logger.groupCollapsed(messages.strategyStart('CacheOnly', request));\n if (response) {\n logger.log(`Found a cached response in the '${this._cacheName}'` +\n ` cache.`);\n messages.printFinalResponse(response);\n }\n else {\n logger.log(`No response found in the '${this._cacheName}' cache.`);\n }\n logger.groupEnd();\n }\n if (!response) {\n throw new WorkboxError('no-response', { url: request.url });\n }\n return response;\n }\n}\nexport { CacheOnly };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { createPartialResponse } from './createPartialResponse.js';\nimport './_version.js';\n/**\n * The range request plugin makes it easy for a request with a 'Range' header to\n * be fulfilled by a cached response.\n *\n * It does this by intercepting the `cachedResponseWillBeUsed` plugin callback\n * and returning the appropriate subset of the cached response body.\n *\n * @memberof workbox.rangeRequests\n */\nclass RangeRequestsPlugin {\n constructor() {\n /**\n * @param {Object} options\n * @param {Request} options.request The original request, which may or may not\n * contain a Range: header.\n * @param {Response} options.cachedResponse The complete cached response.\n * @return {Promise} If request contains a 'Range' header, then a\n * new response with status 206 whose body is a subset of `cachedResponse` is\n * returned. Otherwise, `cachedResponse` is returned as-is.\n *\n * @private\n */\n this.cachedResponseWillBeUsed = async ({ request, cachedResponse }) => {\n // Only return a sliced response if there's something valid in the cache,\n // and there's a Range: header in the request.\n if (cachedResponse && request.headers.has('range')) {\n return await createPartialResponse(request, cachedResponse);\n }\n // If there was no Range: header, or if cachedResponse wasn't valid, just\n // pass it through as-is.\n return cachedResponse;\n };\n }\n}\nexport { RangeRequestsPlugin };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addRoute } from './addRoute.js';\nimport { precache } from './precache.js';\nimport './_version.js';\n/**\n * This method will add entries to the precache list and add a route to\n * respond to fetch events.\n *\n * This is a convenience method that will call\n * [precache()]{@link module:workbox-precaching.precache} and\n * [addRoute()]{@link module:workbox-precaching.addRoute} in a single call.\n *\n * @param {Array} entries Array of entries to precache.\n * @param {Object} [options] See\n * [addRoute() options]{@link module:workbox-precaching.addRoute}.\n *\n * @alias workbox.precaching.precacheAndRoute\n */\nexport const precacheAndRoute = (entries, options) => {\n precache(entries);\n addRoute(options);\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Force a service worker to become active, instead of waiting. This is\n * normally used in conjunction with `clientsClaim()`.\n *\n * @alias workbox.core.skipWaiting\n */\nexport const skipWaiting = () => {\n // We need to explicitly call `self.skipWaiting()` here because we're\n // shadowing `skipWaiting` with this local function.\n addEventListener('install', () => self.skipWaiting());\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Claim any currently available clients once the service worker\n * becomes active. This is normally used in conjunction with `skipWaiting()`.\n *\n * @alias workbox.core.clientsClaim\n */\nexport const clientsClaim = () => {\n addEventListener('activate', () => self.clients.claim());\n};\n"]} \ No newline at end of file