{"version":3,"sources":["../node_modules/workbox-core/_version.js","../node_modules/workbox-core/models/messages/messageGenerator.js","../node_modules/workbox-core/_private/WorkboxError.js","../node_modules/workbox-core/models/quotaErrorCallbacks.js","../node_modules/workbox-core/registerQuotaErrorCallback.js","../node_modules/workbox-core/_private/cacheNames.js","../node_modules/workbox-core/_private/cacheMatchIgnoreParams.js","../node_modules/workbox-core/_private/canConstructResponseFromBodyStream.js","../node_modules/workbox-core/_private/dontWaitFor.js","../node_modules/workbox-core/_private/DBWrapper.js","../node_modules/workbox-core/_private/Deferred.js","../node_modules/workbox-core/_private/deleteDatabase.js","../node_modules/workbox-core/_private/executeQuotaErrorCallbacks.js","../node_modules/workbox-core/_private/getFriendlyURL.js","../node_modules/workbox-core/_private/timeout.js","../node_modules/workbox-core/_private/waitUntil.js","../node_modules/workbox-core/copyResponse.js","../node_modules/workbox-core/clientsClaim.js","../node_modules/workbox-expiration/_version.js","../node_modules/workbox-expiration/models/CacheTimestampsModel.js","../node_modules/workbox-expiration/CacheExpiration.js","../node_modules/workbox-expiration/ExpirationPlugin.js","../node_modules/workbox-precaching/_version.js","../node_modules/workbox-precaching/utils/createCacheKey.js","../node_modules/workbox-precaching/utils/PrecacheInstallReportPlugin.js","../node_modules/workbox-precaching/utils/PrecacheCacheKeyPlugin.js","../node_modules/workbox-strategies/_version.js","../node_modules/workbox-strategies/StrategyHandler.js","../node_modules/workbox-strategies/Strategy.js","../node_modules/workbox-precaching/PrecacheStrategy.js","../node_modules/workbox-precaching/PrecacheController.js","../node_modules/workbox-precaching/utils/getOrCreatePrecacheController.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","../node_modules/workbox-precaching/utils/removeIgnoredSearchParams.js","../node_modules/workbox-precaching/utils/generateURLVariations.js","../node_modules/workbox-precaching/PrecacheRoute.js","../node_modules/workbox-precaching/addRoute.js","../node_modules/workbox-precaching/createHandlerBoundToURL.js","../node_modules/workbox-precaching/precache.js","../node_modules/workbox-precaching/precacheAndRoute.js","../node_modules/workbox-strategies/plugins/cacheOkAndOpaquePlugin.js","../node_modules/workbox-strategies/StaleWhileRevalidate.js","../src/extraPrecacheFiles.ts","../src/service-worker.ts"],"names":[],"mappings":"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","file":"service-worker.js","sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n    self['workbox:core:6.1.5'] && _();\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 { 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        const 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 '../_version.js';\n// Callbacks to be executed whenever there's a quota error.\nconst quotaErrorCallbacks = new Set();\nexport { quotaErrorCallbacks };\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 './_private/logger.js';\nimport { assert } from './_private/assert.js';\nimport { quotaErrorCallbacks } from './models/quotaErrorCallbacks.js';\nimport './_version.js';\n/**\n * Adds a function to the set of quotaErrorCallbacks that will be executed if\n * there's a quota error.\n *\n * @param {Function} callback\n * @memberof module:workbox-core\n */\nfunction registerQuotaErrorCallback(callback) {\n    if (process.env.NODE_ENV !== 'production') {\n        assert.isType(callback, 'function', {\n            moduleName: 'workbox-core',\n            funcName: 'register',\n            paramName: 'callback',\n        });\n    }\n    quotaErrorCallbacks.add(callback);\n    if (process.env.NODE_ENV !== 'production') {\n        logger.log('Registered a callback to respond to quota errors.', callback);\n    }\n}\nexport { registerQuotaErrorCallback };\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: typeof registration !== 'undefined' ? 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 2020 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';\nfunction stripParams(fullURL, ignoreParams) {\n    const strippedURL = new URL(fullURL);\n    for (const param of ignoreParams) {\n        strippedURL.searchParams.delete(param);\n    }\n    return strippedURL.href;\n}\n/**\n * Matches an item in the cache, ignoring specific URL params. This is similar\n * to the `ignoreSearch` option, but it allows you to ignore just specific\n * params (while continuing to match on the others).\n *\n * @private\n * @param {Cache} cache\n * @param {Request} request\n * @param {Object} matchOptions\n * @param {Array<string>} ignoreParams\n * @return {Promise<Response|undefined>}\n */\nasync function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) {\n    const strippedRequestURL = stripParams(request.url, ignoreParams);\n    // If the request doesn't include any ignored params, match as normal.\n    if (request.url === strippedRequestURL) {\n        return cache.match(request, matchOptions);\n    }\n    // Otherwise, match by comparing keys\n    const keysOptions = { ...matchOptions, ignoreSearch: true };\n    const cacheKeys = await cache.keys(request, keysOptions);\n    for (const cacheKey of cacheKeys) {\n        const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams);\n        if (strippedRequestURL === strippedCacheKeyURL) {\n            return cache.match(cacheKey, matchOptions);\n        }\n    }\n    return;\n}\nexport { cacheMatchIgnoreParams };\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 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';\n/**\n * A helper function that prevents a promise from being flagged as unused.\n *\n * @private\n **/\nexport function dontWaitFor(promise) {\n    // Effective no-op.\n    promise.then(() => { });\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 * 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<string>} 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            // TODO(philipwalton): Fix this underlying TS2684 error.\n            // @ts-ignore\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 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 Deferred class composes Promises in a way that allows for them to be\n * resolved or rejected from outside the constructor. In most cases promises\n * should be used directly, but Deferreds can be necessary when the logic to\n * resolve a promise must be separate.\n *\n * @private\n */\nclass Deferred {\n    /**\n     * Creates a promise and exposes its resolve and reject functions as methods.\n     */\n    constructor() {\n        this.promise = new Promise((resolve, reject) => {\n            this.resolve = resolve;\n            this.reject = reject;\n        });\n    }\n}\nexport { Deferred };\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 * Deletes the database.\n * Note: this is exported separately from the DBWrapper module because most\n * usages of IndexedDB in workbox dont need deleting, and this way it can be\n * reused in tests to delete databases without creating DBWrapper instances.\n *\n * @param {string} name The database name.\n * @private\n */\nexport const deleteDatabase = async (name) => {\n    await new Promise((resolve, reject) => {\n        const request = indexedDB.deleteDatabase(name);\n        request.onerror = () => {\n            reject(request.error);\n        };\n        request.onblocked = () => {\n            reject(new Error('Delete blocked'));\n        };\n        request.onsuccess = () => {\n            resolve();\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 { 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 module: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 '../_version.js';\nconst getFriendlyURL = (url) => {\n    const urlObj = new URL(String(url), location.href);\n    // See https://github.com/GoogleChrome/workbox/issues/2323\n    // We want to include everything, except for the origin if it's same-origin.\n    return urlObj.href.replace(new RegExp(`^${location.origin}`), '');\n};\nexport { getFriendlyURL };\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';\n/**\n * Returns a promise that resolves and the passed number of milliseconds.\n * This utility is an async/await-friendly version of `setTimeout`.\n *\n * @param {number} ms\n * @return {Promise}\n * @private\n */\nexport function timeout(ms) {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/*\n  Copyright 2020 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';\n/**\n * A utility method that makes it easier to use `event.waitUntil` with\n * async functions and return the result.\n *\n * @param {ExtendableEvent} event\n * @param {Function} asyncFn\n * @return {Function}\n * @private\n */\nfunction waitUntil(event, asyncFn) {\n    const returnPromise = asyncFn();\n    event.waitUntil(returnPromise);\n    return returnPromise;\n}\nexport { waitUntil };\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 { WorkboxError } from './_private/WorkboxError.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 * This method is intentionally limited to same-origin responses, regardless of\n * whether CORS was used or not.\n *\n * @param {Response} response\n * @param {Function} modifier\n * @memberof module:workbox-core\n */\nasync function copyResponse(response, modifier) {\n    let origin = null;\n    // If response.url isn't set, assume it's cross-origin and keep origin null.\n    if (response.url) {\n        const responseURL = new URL(response.url);\n        origin = responseURL.origin;\n    }\n    if (origin !== self.location.origin) {\n        throw new WorkboxError('cross-origin-copy-response', { origin });\n    }\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}\nexport { copyResponse };\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 * @memberof module:workbox-core\n */\nfunction clientsClaim() {\n    self.addEventListener('activate', () => self.clients.claim());\n}\nexport { clientsClaim };\n","\"use strict\";\n// @ts-ignore\ntry {\n    self['workbox:expiration:6.1.5'] && _();\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 { DBWrapper } from 'workbox-core/_private/DBWrapper.js';\nimport { deleteDatabase } from 'workbox-core/_private/deleteDatabase.js';\nimport '../_version.js';\nconst DB_NAME = 'workbox-expiration';\nconst OBJECT_STORE_NAME = 'cache-entries';\nconst normalizeURL = (unNormalizedUrl) => {\n    const url = new URL(unNormalizedUrl, location.href);\n    url.hash = '';\n    return url.href;\n};\n/**\n * Returns the timestamp model.\n *\n * @private\n */\nclass CacheTimestampsModel {\n    /**\n     *\n     * @param {string} cacheName\n     *\n     * @private\n     */\n    constructor(cacheName) {\n        this._cacheName = cacheName;\n        this._db = new DBWrapper(DB_NAME, 1, {\n            onupgradeneeded: (event) => this._handleUpgrade(event),\n        });\n    }\n    /**\n     * Should perform an upgrade of indexedDB.\n     *\n     * @param {Event} event\n     *\n     * @private\n     */\n    _handleUpgrade(event) {\n        const db = event.target.result;\n        // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we\n        // have to use the `id` keyPath here and create our own values (a\n        // concatenation of `url + cacheName`) instead of simply using\n        // `keyPath: ['url', 'cacheName']`, which is supported in other browsers.\n        const objStore = db.createObjectStore(OBJECT_STORE_NAME, { keyPath: 'id' });\n        // TODO(philipwalton): once we don't have to support EdgeHTML, we can\n        // create a single index with the keyPath `['cacheName', 'timestamp']`\n        // instead of doing both these indexes.\n        objStore.createIndex('cacheName', 'cacheName', { unique: false });\n        objStore.createIndex('timestamp', 'timestamp', { unique: false });\n        // Previous versions of `workbox-expiration` used `this._cacheName`\n        // as the IDBDatabase name.\n        deleteDatabase(this._cacheName);\n    }\n    /**\n     * @param {string} url\n     * @param {number} timestamp\n     *\n     * @private\n     */\n    async setTimestamp(url, timestamp) {\n        url = normalizeURL(url);\n        const entry = {\n            url,\n            timestamp,\n            cacheName: this._cacheName,\n            // Creating an ID from the URL and cache name won't be necessary once\n            // Edge switches to Chromium and all browsers we support work with\n            // array keyPaths.\n            id: this._getId(url),\n        };\n        await this._db.put(OBJECT_STORE_NAME, entry);\n    }\n    /**\n     * Returns the timestamp stored for a given URL.\n     *\n     * @param {string} url\n     * @return {number}\n     *\n     * @private\n     */\n    async getTimestamp(url) {\n        const entry = await this._db.get(OBJECT_STORE_NAME, this._getId(url));\n        return entry.timestamp;\n    }\n    /**\n     * Iterates through all the entries in the object store (from newest to\n     * oldest) and removes entries once either `maxCount` is reached or the\n     * entry's timestamp is less than `minTimestamp`.\n     *\n     * @param {number} minTimestamp\n     * @param {number} maxCount\n     * @return {Array<string>}\n     *\n     * @private\n     */\n    async expireEntries(minTimestamp, maxCount) {\n        const entriesToDelete = await this._db.transaction(OBJECT_STORE_NAME, 'readwrite', (txn, done) => {\n            const store = txn.objectStore(OBJECT_STORE_NAME);\n            const request = store.index('timestamp').openCursor(null, 'prev');\n            const entriesToDelete = [];\n            let entriesNotDeletedCount = 0;\n            request.onsuccess = () => {\n                const cursor = request.result;\n                if (cursor) {\n                    const result = cursor.value;\n                    // TODO(philipwalton): once we can use a multi-key index, we\n                    // won't have to check `cacheName` here.\n                    if (result.cacheName === this._cacheName) {\n                        // Delete an entry if it's older than the max age or\n                        // if we already have the max number allowed.\n                        if ((minTimestamp && result.timestamp < minTimestamp) ||\n                            (maxCount && entriesNotDeletedCount >= maxCount)) {\n                            // TODO(philipwalton): we should be able to delete the\n                            // entry right here, but doing so causes an iteration\n                            // bug in Safari stable (fixed in TP). Instead we can\n                            // store the keys of the entries to delete, and then\n                            // delete the separate transactions.\n                            // https://github.com/GoogleChrome/workbox/issues/1978\n                            // cursor.delete();\n                            // We only need to return the URL, not the whole entry.\n                            entriesToDelete.push(cursor.value);\n                        }\n                        else {\n                            entriesNotDeletedCount++;\n                        }\n                    }\n                    cursor.continue();\n                }\n                else {\n                    done(entriesToDelete);\n                }\n            };\n        });\n        // TODO(philipwalton): once the Safari bug in the following issue is fixed,\n        // we should be able to remove this loop and do the entry deletion in the\n        // cursor loop above:\n        // https://github.com/GoogleChrome/workbox/issues/1978\n        const urlsDeleted = [];\n        for (const entry of entriesToDelete) {\n            await this._db.delete(OBJECT_STORE_NAME, entry.id);\n            urlsDeleted.push(entry.url);\n        }\n        return urlsDeleted;\n    }\n    /**\n     * Takes a URL and returns an ID that will be unique in the object store.\n     *\n     * @param {string} url\n     * @return {string}\n     *\n     * @private\n     */\n    _getId(url) {\n        // Creating an ID from the URL and cache name won't be necessary once\n        // Edge switches to Chromium and all browsers we support work with\n        // array keyPaths.\n        return this._cacheName + '|' + normalizeURL(url);\n    }\n}\nexport { CacheTimestampsModel };\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 { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { CacheTimestampsModel } from './models/CacheTimestampsModel.js';\nimport './_version.js';\n/**\n * The `CacheExpiration` class allows you define an expiration and / or\n * limit on the number of responses stored in a\n * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache).\n *\n * @memberof module:workbox-expiration\n */\nclass CacheExpiration {\n    /**\n     * To construct a new CacheExpiration instance you must provide at least\n     * one of the `config` properties.\n     *\n     * @param {string} cacheName Name of the cache to apply restrictions to.\n     * @param {Object} config\n     * @param {number} [config.maxEntries] The maximum number of entries to cache.\n     * Entries used the least will be removed as the maximum is reached.\n     * @param {number} [config.maxAgeSeconds] The maximum age of an entry before\n     * it's treated as stale and removed.\n     * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)\n     * that will be used when calling `delete()` on the cache.\n     */\n    constructor(cacheName, config = {}) {\n        this._isRunning = false;\n        this._rerunRequested = false;\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isType(cacheName, 'string', {\n                moduleName: 'workbox-expiration',\n                className: 'CacheExpiration',\n                funcName: 'constructor',\n                paramName: 'cacheName',\n            });\n            if (!(config.maxEntries || config.maxAgeSeconds)) {\n                throw new WorkboxError('max-entries-or-age-required', {\n                    moduleName: 'workbox-expiration',\n                    className: 'CacheExpiration',\n                    funcName: 'constructor',\n                });\n            }\n            if (config.maxEntries) {\n                assert.isType(config.maxEntries, 'number', {\n                    moduleName: 'workbox-expiration',\n                    className: 'CacheExpiration',\n                    funcName: 'constructor',\n                    paramName: 'config.maxEntries',\n                });\n            }\n            if (config.maxAgeSeconds) {\n                assert.isType(config.maxAgeSeconds, 'number', {\n                    moduleName: 'workbox-expiration',\n                    className: 'CacheExpiration',\n                    funcName: 'constructor',\n                    paramName: 'config.maxAgeSeconds',\n                });\n            }\n        }\n        this._maxEntries = config.maxEntries;\n        this._maxAgeSeconds = config.maxAgeSeconds;\n        this._matchOptions = config.matchOptions;\n        this._cacheName = cacheName;\n        this._timestampModel = new CacheTimestampsModel(cacheName);\n    }\n    /**\n     * Expires entries for the given cache and given criteria.\n     */\n    async expireEntries() {\n        if (this._isRunning) {\n            this._rerunRequested = true;\n            return;\n        }\n        this._isRunning = true;\n        const minTimestamp = this._maxAgeSeconds ?\n            Date.now() - (this._maxAgeSeconds * 1000) : 0;\n        const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries);\n        // Delete URLs from the cache\n        const cache = await self.caches.open(this._cacheName);\n        for (const url of urlsExpired) {\n            await cache.delete(url, this._matchOptions);\n        }\n        if (process.env.NODE_ENV !== 'production') {\n            if (urlsExpired.length > 0) {\n                logger.groupCollapsed(`Expired ${urlsExpired.length} ` +\n                    `${urlsExpired.length === 1 ? 'entry' : 'entries'} and removed ` +\n                    `${urlsExpired.length === 1 ? 'it' : 'them'} from the ` +\n                    `'${this._cacheName}' cache.`);\n                logger.log(`Expired the following ${urlsExpired.length === 1 ?\n                    'URL' : 'URLs'}:`);\n                urlsExpired.forEach((url) => logger.log(`    ${url}`));\n                logger.groupEnd();\n            }\n            else {\n                logger.debug(`Cache expiration ran and found no entries to remove.`);\n            }\n        }\n        this._isRunning = false;\n        if (this._rerunRequested) {\n            this._rerunRequested = false;\n            dontWaitFor(this.expireEntries());\n        }\n    }\n    /**\n     * Update the timestamp for the given URL. This ensures the when\n     * removing entries based on maximum entries, most recently used\n     * is accurate or when expiring, the timestamp is up-to-date.\n     *\n     * @param {string} url\n     */\n    async updateTimestamp(url) {\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isType(url, 'string', {\n                moduleName: 'workbox-expiration',\n                className: 'CacheExpiration',\n                funcName: 'updateTimestamp',\n                paramName: 'url',\n            });\n        }\n        await this._timestampModel.setTimestamp(url, Date.now());\n    }\n    /**\n     * Can be used to check if a URL has expired or not before it's used.\n     *\n     * This requires a look up from IndexedDB, so can be slow.\n     *\n     * Note: This method will not remove the cached entry, call\n     * `expireEntries()` to remove indexedDB and Cache entries.\n     *\n     * @param {string} url\n     * @return {boolean}\n     */\n    async isURLExpired(url) {\n        if (!this._maxAgeSeconds) {\n            if (process.env.NODE_ENV !== 'production') {\n                throw new WorkboxError(`expired-test-without-max-age`, {\n                    methodName: 'isURLExpired',\n                    paramName: 'maxAgeSeconds',\n                });\n            }\n            return false;\n        }\n        else {\n            const timestamp = await this._timestampModel.getTimestamp(url);\n            const expireOlderThan = Date.now() - (this._maxAgeSeconds * 1000);\n            return (timestamp < expireOlderThan);\n        }\n    }\n    /**\n     * Removes the IndexedDB object store used to keep track of cache expiration\n     * metadata.\n     */\n    async delete() {\n        // Make sure we don't attempt another rerun if we're called in the middle of\n        // a cache expiration.\n        this._rerunRequested = false;\n        await this._timestampModel.expireEntries(Infinity); // Expires all.\n    }\n}\nexport { CacheExpiration };\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 { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { registerQuotaErrorCallback } from 'workbox-core/registerQuotaErrorCallback.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { CacheExpiration } from './CacheExpiration.js';\nimport './_version.js';\n/**\n * This plugin can be used in a `workbox-strategy` to regularly enforce a\n * limit on the age and / or the number of cached requests.\n *\n * It can only be used with `workbox-strategy` instances that have a\n * [custom `cacheName` property set](/web/tools/workbox/guides/configure-workbox#custom_cache_names_in_strategies).\n * In other words, it can't be used to expire entries in strategy that uses the\n * default runtime cache name.\n *\n * Whenever a cached request is used or updated, this plugin will look\n * at the associated cache and remove any old or extra requests.\n *\n * When using `maxAgeSeconds`, requests may be used *once* after expiring\n * because the expiration clean up will not have occurred until *after* the\n * cached request has been used. If the request has a \"Date\" header, then\n * a light weight expiration check is performed and the request will not be\n * used immediately.\n *\n * When using `maxEntries`, the entry least-recently requested will be removed\n * from the cache first.\n *\n * @memberof module:workbox-expiration\n */\nclass ExpirationPlugin {\n    /**\n     * @param {Object} config\n     * @param {number} [config.maxEntries] The maximum number of entries to cache.\n     * Entries used the least will be removed as the maximum is reached.\n     * @param {number} [config.maxAgeSeconds] The maximum age of an entry before\n     * it's treated as stale and removed.\n     * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)\n     * that will be used when calling `delete()` on the cache.\n     * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to\n     * automatic deletion if the available storage quota has been exceeded.\n     */\n    constructor(config = {}) {\n        /**\n         * A \"lifecycle\" callback that will be triggered automatically by the\n         * `workbox-strategies` handlers when a `Response` is about to be returned\n         * from a [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to\n         * the handler. It allows the `Response` to be inspected for freshness and\n         * prevents it from being used if the `Response`'s `Date` header value is\n         * older than the configured `maxAgeSeconds`.\n         *\n         * @param {Object} options\n         * @param {string} options.cacheName Name of the cache the response is in.\n         * @param {Response} options.cachedResponse The `Response` object that's been\n         *     read from a cache and whose freshness should be checked.\n         * @return {Response} Either the `cachedResponse`, if it's\n         *     fresh, or `null` if the `Response` is older than `maxAgeSeconds`.\n         *\n         * @private\n         */\n        this.cachedResponseWillBeUsed = async ({ event, request, cacheName, cachedResponse }) => {\n            if (!cachedResponse) {\n                return null;\n            }\n            const isFresh = this._isResponseDateFresh(cachedResponse);\n            // Expire entries to ensure that even if the expiration date has\n            // expired, it'll only be used once.\n            const cacheExpiration = this._getCacheExpiration(cacheName);\n            dontWaitFor(cacheExpiration.expireEntries());\n            // Update the metadata for the request URL to the current timestamp,\n            // but don't `await` it as we don't want to block the response.\n            const updateTimestampDone = cacheExpiration.updateTimestamp(request.url);\n            if (event) {\n                try {\n                    event.waitUntil(updateTimestampDone);\n                }\n                catch (error) {\n                    if (process.env.NODE_ENV !== 'production') {\n                        // The event may not be a fetch event; only log the URL if it is.\n                        if ('request' in event) {\n                            logger.warn(`Unable to ensure service worker stays alive when ` +\n                                `updating cache entry for ` +\n                                `'${getFriendlyURL(event.request.url)}'.`);\n                        }\n                    }\n                }\n            }\n            return isFresh ? cachedResponse : null;\n        };\n        /**\n         * A \"lifecycle\" callback that will be triggered automatically by the\n         * `workbox-strategies` handlers when an entry is added to a cache.\n         *\n         * @param {Object} options\n         * @param {string} options.cacheName Name of the cache that was updated.\n         * @param {string} options.request The Request for the cached entry.\n         *\n         * @private\n         */\n        this.cacheDidUpdate = async ({ cacheName, request }) => {\n            if (process.env.NODE_ENV !== 'production') {\n                assert.isType(cacheName, 'string', {\n                    moduleName: 'workbox-expiration',\n                    className: 'Plugin',\n                    funcName: 'cacheDidUpdate',\n                    paramName: 'cacheName',\n                });\n                assert.isInstance(request, Request, {\n                    moduleName: 'workbox-expiration',\n                    className: 'Plugin',\n                    funcName: 'cacheDidUpdate',\n                    paramName: 'request',\n                });\n            }\n            const cacheExpiration = this._getCacheExpiration(cacheName);\n            await cacheExpiration.updateTimestamp(request.url);\n            await cacheExpiration.expireEntries();\n        };\n        if (process.env.NODE_ENV !== 'production') {\n            if (!(config.maxEntries || config.maxAgeSeconds)) {\n                throw new WorkboxError('max-entries-or-age-required', {\n                    moduleName: 'workbox-expiration',\n                    className: 'Plugin',\n                    funcName: 'constructor',\n                });\n            }\n            if (config.maxEntries) {\n                assert.isType(config.maxEntries, 'number', {\n                    moduleName: 'workbox-expiration',\n                    className: 'Plugin',\n                    funcName: 'constructor',\n                    paramName: 'config.maxEntries',\n                });\n            }\n            if (config.maxAgeSeconds) {\n                assert.isType(config.maxAgeSeconds, 'number', {\n                    moduleName: 'workbox-expiration',\n                    className: 'Plugin',\n                    funcName: 'constructor',\n                    paramName: 'config.maxAgeSeconds',\n                });\n            }\n        }\n        this._config = config;\n        this._maxAgeSeconds = config.maxAgeSeconds;\n        this._cacheExpirations = new Map();\n        if (config.purgeOnQuotaError) {\n            registerQuotaErrorCallback(() => this.deleteCacheAndMetadata());\n        }\n    }\n    /**\n     * A simple helper method to return a CacheExpiration instance for a given\n     * cache name.\n     *\n     * @param {string} cacheName\n     * @return {CacheExpiration}\n     *\n     * @private\n     */\n    _getCacheExpiration(cacheName) {\n        if (cacheName === cacheNames.getRuntimeName()) {\n            throw new WorkboxError('expire-custom-caches-only');\n        }\n        let cacheExpiration = this._cacheExpirations.get(cacheName);\n        if (!cacheExpiration) {\n            cacheExpiration = new CacheExpiration(cacheName, this._config);\n            this._cacheExpirations.set(cacheName, cacheExpiration);\n        }\n        return cacheExpiration;\n    }\n    /**\n     * @param {Response} cachedResponse\n     * @return {boolean}\n     *\n     * @private\n     */\n    _isResponseDateFresh(cachedResponse) {\n        if (!this._maxAgeSeconds) {\n            // We aren't expiring by age, so return true, it's fresh\n            return true;\n        }\n        // Check if the 'date' header will suffice a quick expiration check.\n        // See https://github.com/GoogleChromeLabs/sw-toolbox/issues/164 for\n        // discussion.\n        const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse);\n        if (dateHeaderTimestamp === null) {\n            // Unable to parse date, so assume it's fresh.\n            return true;\n        }\n        // If we have a valid headerTime, then our response is fresh iff the\n        // headerTime plus maxAgeSeconds is greater than the current time.\n        const now = Date.now();\n        return dateHeaderTimestamp >= now - (this._maxAgeSeconds * 1000);\n    }\n    /**\n     * This method will extract the data header and parse it into a useful\n     * value.\n     *\n     * @param {Response} cachedResponse\n     * @return {number|null}\n     *\n     * @private\n     */\n    _getDateHeaderTimestamp(cachedResponse) {\n        if (!cachedResponse.headers.has('date')) {\n            return null;\n        }\n        const dateHeader = cachedResponse.headers.get('date');\n        const parsedDate = new Date(dateHeader);\n        const headerTime = parsedDate.getTime();\n        // If the Date header was invalid for some reason, parsedDate.getTime()\n        // will return NaN.\n        if (isNaN(headerTime)) {\n            return null;\n        }\n        return headerTime;\n    }\n    /**\n     * This is a helper method that performs two operations:\n     *\n     * - Deletes *all* the underlying Cache instances associated with this plugin\n     * instance, by calling caches.delete() on your behalf.\n     * - Deletes the metadata from IndexedDB used to keep track of expiration\n     * details for each Cache instance.\n     *\n     * When using cache expiration, calling this method is preferable to calling\n     * `caches.delete()` directly, since this will ensure that the IndexedDB\n     * metadata is also cleanly removed and open IndexedDB instances are deleted.\n     *\n     * Note that if you're *not* using cache expiration for a given cache, calling\n     * `caches.delete()` and passing in the cache's name should be sufficient.\n     * There is no Workbox-specific method needed for cleanup in that case.\n     */\n    async deleteCacheAndMetadata() {\n        // Do this one at a time instead of all at once via `Promise.all()` to\n        // reduce the chance of inconsistency if a promise rejects.\n        for (const [cacheName, cacheExpiration] of this._cacheExpirations) {\n            await self.caches.delete(cacheName);\n            await cacheExpiration.delete();\n        }\n        // Reset this._cacheExpirations to its initial state.\n        this._cacheExpirations = new Map();\n    }\n}\nexport { ExpirationPlugin };\n","\"use strict\";\n// @ts-ignore\ntry {\n    self['workbox:precaching:6.1.5'] && _();\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 '../_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 2020 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 plugin, designed to be used with PrecacheController, to determine the\n * of assets that were updated (or not updated) during the install event.\n *\n * @private\n */\nclass PrecacheInstallReportPlugin {\n    constructor() {\n        this.updatedURLs = [];\n        this.notUpdatedURLs = [];\n        this.handlerWillStart = async ({ request, state, }) => {\n            // TODO: `state` should never be undefined...\n            if (state) {\n                state.originalRequest = request;\n            }\n        };\n        this.cachedResponseWillBeUsed = async ({ event, state, cachedResponse, }) => {\n            if (event.type === 'install') {\n                // TODO: `state` should never be undefined...\n                const url = state.originalRequest.url;\n                if (cachedResponse) {\n                    this.notUpdatedURLs.push(url);\n                }\n                else {\n                    this.updatedURLs.push(url);\n                }\n            }\n            return cachedResponse;\n        };\n    }\n}\nexport { PrecacheInstallReportPlugin };\n","/*\n  Copyright 2020 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 plugin, designed to be used with PrecacheController, to translate URLs into\n * the corresponding cache key, based on the current revision info.\n *\n * @private\n */\nclass PrecacheCacheKeyPlugin {\n    constructor({ precacheController }) {\n        this.cacheKeyWillBeUsed = async ({ request, params, }) => {\n            const cacheKey = params && params.cacheKey ||\n                this._precacheController.getCacheKeyForURL(request.url);\n            return cacheKey ? new Request(cacheKey) : request;\n        };\n        this._precacheController = precacheController;\n    }\n}\nexport { PrecacheCacheKeyPlugin };\n","\"use strict\";\n// @ts-ignore\ntry {\n    self['workbox:strategies:6.1.5'] && _();\n}\ncatch (e) { }\n","/*\n  Copyright 2020 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 { cacheMatchIgnoreParams } from 'workbox-core/_private/cacheMatchIgnoreParams.js';\nimport { Deferred } from 'workbox-core/_private/Deferred.js';\nimport { executeQuotaErrorCallbacks } from 'workbox-core/_private/executeQuotaErrorCallbacks.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { timeout } from 'workbox-core/_private/timeout.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport './_version.js';\nfunction toRequest(input) {\n    return (typeof input === 'string') ? new Request(input) : input;\n}\n/**\n * A class created every time a Strategy instance instance calls\n * [handle()]{@link module:workbox-strategies.Strategy~handle} or\n * [handleAll()]{@link module:workbox-strategies.Strategy~handleAll} that wraps all fetch and\n * cache actions around plugin callbacks and keeps track of when the strategy\n * is \"done\" (i.e. all added `event.waitUntil()` promises have resolved).\n *\n * @memberof module:workbox-strategies\n */\nclass StrategyHandler {\n    /**\n     * Creates a new instance associated with the passed strategy and event\n     * that's handling the request.\n     *\n     * The constructor also initializes the state that will be passed to each of\n     * the plugins handling this request.\n     *\n     * @param {module:workbox-strategies.Strategy} strategy\n     * @param {Object} options\n     * @param {Request|string} options.request A request to run this strategy for.\n     * @param {ExtendableEvent} options.event The event associated with the\n     *     request.\n     * @param {URL} [options.url]\n     * @param {*} [options.params]\n     *     [match callback]{@link module:workbox-routing~matchCallback},\n     *     (if applicable).\n     */\n    constructor(strategy, options) {\n        this._cacheKeys = {};\n        /**\n         * The request the strategy is performing (passed to the strategy's\n         * `handle()` or `handleAll()` method).\n         * @name request\n         * @instance\n         * @type {Request}\n         * @memberof module:workbox-strategies.StrategyHandler\n         */\n        /**\n         * The event associated with this request.\n         * @name event\n         * @instance\n         * @type {ExtendableEvent}\n         * @memberof module:workbox-strategies.StrategyHandler\n         */\n        /**\n         * A `URL` instance of `request.url` (if passed to the strategy's\n         * `handle()` or `handleAll()` method).\n         * Note: the `url` param will be present if the strategy was invoked\n         * from a workbox `Route` object.\n         * @name url\n         * @instance\n         * @type {URL|undefined}\n         * @memberof module:workbox-strategies.StrategyHandler\n         */\n        /**\n         * A `param` value (if passed to the strategy's\n         * `handle()` or `handleAll()` method).\n         * Note: the `param` param will be present if the strategy was invoked\n         * from a workbox `Route` object and the\n         * [match callback]{@link module:workbox-routing~matchCallback} returned\n         * a truthy value (it will be that value).\n         * @name params\n         * @instance\n         * @type {*|undefined}\n         * @memberof module:workbox-strategies.StrategyHandler\n         */\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isInstance(options.event, ExtendableEvent, {\n                moduleName: 'workbox-strategies',\n                className: 'StrategyHandler',\n                funcName: 'constructor',\n                paramName: 'options.event',\n            });\n        }\n        Object.assign(this, options);\n        this.event = options.event;\n        this._strategy = strategy;\n        this._handlerDeferred = new Deferred();\n        this._extendLifetimePromises = [];\n        // Copy the plugins list (since it's mutable on the strategy),\n        // so any mutations don't affect this handler instance.\n        this._plugins = [...strategy.plugins];\n        this._pluginStateMap = new Map();\n        for (const plugin of this._plugins) {\n            this._pluginStateMap.set(plugin, {});\n        }\n        this.event.waitUntil(this._handlerDeferred.promise);\n    }\n    /**\n     * Fetches a given request (and invokes any applicable plugin callback\n     * methods) using the `fetchOptions` (for non-navigation requests) and\n     * `plugins` defined on the `Strategy` object.\n     *\n     * The following plugin lifecycle methods are invoked when using this method:\n     * - `requestWillFetch()`\n     * - `fetchDidSucceed()`\n     * - `fetchDidFail()`\n     *\n     * @param {Request|string} input The URL or request to fetch.\n     * @return {Promise<Response>}\n     */\n    async fetch(input) {\n        const { event } = this;\n        let request = toRequest(input);\n        if (request.mode === 'navigate' &&\n            event instanceof FetchEvent &&\n            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 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 = this.hasCallback('fetchDidFail') ?\n            request.clone() : null;\n        try {\n            for (const cb of this.iterateCallbacks('requestWillFetch')) {\n                request = await cb({ request: request.clone(), event });\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) different\n        // from the Request we make. Pass both to `fetchDidFail` to aid debugging.\n        const pluginFilteredRequest = request.clone();\n        try {\n            let fetchResponse;\n            // See https://github.com/GoogleChrome/workbox/issues/1796\n            fetchResponse = await fetch(request, request.mode === 'navigate' ?\n                undefined : this._strategy.fetchOptions);\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 callback of this.iterateCallbacks('fetchDidSucceed')) {\n                fetchResponse = await callback({\n                    event,\n                    request: pluginFilteredRequest,\n                    response: fetchResponse,\n                });\n            }\n            return fetchResponse;\n        }\n        catch (error) {\n            if (process.env.NODE_ENV !== 'production') {\n                logger.log(`Network request for ` +\n                    `'${getFriendlyURL(request.url)}' threw an error.`, error);\n            }\n            // `originalRequest` will only exist if a `fetchDidFail` callback\n            // is being used (see above).\n            if (originalRequest) {\n                await this.runCallbacks('fetchDidFail', {\n                    error,\n                    event,\n                    originalRequest: originalRequest.clone(),\n                    request: pluginFilteredRequest.clone(),\n                });\n            }\n            throw error;\n        }\n    }\n    /**\n     * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on\n     * the response generated by `this.fetch()`.\n     *\n     * The call to `this.cachePut()` automatically invokes `this.waitUntil()`,\n     * so you do not have to manually call `waitUntil()` on the event.\n     *\n     * @param {Request|string} input The request or URL to fetch and cache.\n     * @return {Promise<Response>}\n     */\n    async fetchAndCachePut(input) {\n        const response = await this.fetch(input);\n        const responseClone = response.clone();\n        this.waitUntil(this.cachePut(input, responseClone));\n        return response;\n    }\n    /**\n     * Matches a request from the cache (and invokes any applicable plugin\n     * callback methods) using the `cacheName`, `matchOptions`, and `plugins`\n     * defined on the strategy object.\n     *\n     * The following plugin lifecycle methods are invoked when using this method:\n     * - cacheKeyWillByUsed()\n     * - cachedResponseWillByUsed()\n     *\n     * @param {Request|string} key The Request or URL to use as the cache key.\n     * @return {Promise<Response|undefined>} A matching response, if found.\n     */\n    async cacheMatch(key) {\n        const request = toRequest(key);\n        let cachedResponse;\n        const { cacheName, matchOptions } = this._strategy;\n        const effectiveRequest = await this.getCacheKey(request, 'read');\n        const multiMatchOptions = { ...matchOptions, ...{ cacheName } };\n        cachedResponse = await caches.match(effectiveRequest, multiMatchOptions);\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 callback of this.iterateCallbacks('cachedResponseWillBeUsed')) {\n            cachedResponse = (await callback({\n                cacheName,\n                matchOptions,\n                cachedResponse,\n                request: effectiveRequest,\n                event: this.event,\n            })) || undefined;\n        }\n        return cachedResponse;\n    }\n    /**\n     * Puts a request/response pair in the cache (and invokes any applicable\n     * plugin callback methods) using the `cacheName` and `plugins` defined on\n     * the strategy object.\n     *\n     * The following plugin lifecycle methods are invoked when using this method:\n     * - cacheKeyWillByUsed()\n     * - cacheWillUpdate()\n     * - cacheDidUpdate()\n     *\n     * @param {Request|string} key The request or URL to use as the cache key.\n     * @param {Response} response The response to cache.\n     * @return {Promise<boolean>} `false` if a cacheWillUpdate caused the response\n     * not be cached, and `true` otherwise.\n     */\n    async cachePut(key, response) {\n        const request = toRequest(key);\n        // Run in the next task to avoid blocking other cache reads.\n        // https://github.com/w3c/ServiceWorker/issues/1397\n        await timeout(0);\n        const effectiveRequest = await this.getCacheKey(request, 'write');\n        if (process.env.NODE_ENV !== 'production') {\n            if (effectiveRequest.method && effectiveRequest.method !== 'GET') {\n                throw new WorkboxError('attempt-to-cache-non-get-request', {\n                    url: getFriendlyURL(effectiveRequest.url),\n                    method: effectiveRequest.method,\n                });\n            }\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        const responseToCache = await this._ensureResponseSafeToCache(response);\n        if (!responseToCache) {\n            if (process.env.NODE_ENV !== 'production') {\n                logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' ` +\n                    `will not be cached.`, responseToCache);\n            }\n            return false;\n        }\n        const { cacheName, matchOptions } = this._strategy;\n        const cache = await self.caches.open(cacheName);\n        const hasCacheUpdateCallback = this.hasCallback('cacheDidUpdate');\n        const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams(\n        // TODO(philipwalton): the `__WB_REVISION__` param is a precaching\n        // feature. Consider into ways to only add this behavior if using\n        // precaching.\n        cache, effectiveRequest.clone(), ['__WB_REVISION__'], matchOptions) :\n            null;\n        if (process.env.NODE_ENV !== 'production') {\n            logger.debug(`Updating the '${cacheName}' cache with a new Response ` +\n                `for ${getFriendlyURL(effectiveRequest.url)}.`);\n        }\n        try {\n            await cache.put(effectiveRequest, hasCacheUpdateCallback ?\n                responseToCache.clone() : 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 (const callback of this.iterateCallbacks('cacheDidUpdate')) {\n            await callback({\n                cacheName,\n                oldResponse,\n                newResponse: responseToCache.clone(),\n                request: effectiveRequest,\n                event: this.event,\n            });\n        }\n        return true;\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`\n     * object returned by the last plugin is treated as the cache key for cache\n     * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have\n     * been registered, the passed request is returned unmodified\n     *\n     * @param {Request} request\n     * @param {string} mode\n     * @return {Promise<Request>}\n     */\n    async getCacheKey(request, mode) {\n        if (!this._cacheKeys[mode]) {\n            let effectiveRequest = request;\n            for (const callback of this.iterateCallbacks('cacheKeyWillBeUsed')) {\n                effectiveRequest = toRequest(await callback({\n                    mode,\n                    request: effectiveRequest,\n                    event: this.event,\n                    params: this.params,\n                }));\n            }\n            this._cacheKeys[mode] = effectiveRequest;\n        }\n        return this._cacheKeys[mode];\n    }\n    /**\n     * Returns true if the strategy has at least one plugin with the given\n     * callback.\n     *\n     * @param {string} name The name of the callback to check for.\n     * @return {boolean}\n     */\n    hasCallback(name) {\n        for (const plugin of this._strategy.plugins) {\n            if (name in plugin) {\n                return true;\n            }\n        }\n        return false;\n    }\n    /**\n     * Runs all plugin callbacks matching the given name, in order, passing the\n     * given param object (merged ith the current plugin state) as the only\n     * argument.\n     *\n     * Note: since this method runs all plugins, it's not suitable for cases\n     * where the return value of a callback needs to be applied prior to calling\n     * the next callback. See\n     * [`iterateCallbacks()`]{@link module:workbox-strategies.StrategyHandler#iterateCallbacks}\n     * below for how to handle that case.\n     *\n     * @param {string} name The name of the callback to run within each plugin.\n     * @param {Object} param The object to pass as the first (and only) param\n     *     when executing each callback. This object will be merged with the\n     *     current plugin state prior to callback execution.\n     */\n    async runCallbacks(name, param) {\n        for (const callback of this.iterateCallbacks(name)) {\n            // TODO(philipwalton): not sure why `any` is needed. It seems like\n            // this should work with `as WorkboxPluginCallbackParam[C]`.\n            await callback(param);\n        }\n    }\n    /**\n     * Accepts a callback and returns an iterable of matching plugin callbacks,\n     * where each callback is wrapped with the current handler state (i.e. when\n     * you call each callback, whatever object parameter you pass it will\n     * be merged with the plugin's current state).\n     *\n     * @param {string} name The name fo the callback to run\n     * @return {Array<Function>}\n     */\n    *iterateCallbacks(name) {\n        for (const plugin of this._strategy.plugins) {\n            if (typeof plugin[name] === 'function') {\n                const state = this._pluginStateMap.get(plugin);\n                const statefulCallback = (param) => {\n                    const statefulParam = { ...param, state };\n                    // TODO(philipwalton): not sure why `any` is needed. It seems like\n                    // this should work with `as WorkboxPluginCallbackParam[C]`.\n                    return plugin[name](statefulParam);\n                };\n                yield statefulCallback;\n            }\n        }\n    }\n    /**\n     * Adds a promise to the\n     * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises}\n     * of the event event associated with the request being handled (usually a\n     * `FetchEvent`).\n     *\n     * Note: you can await\n     * [`doneWaiting()`]{@link module:workbox-strategies.StrategyHandler~doneWaiting}\n     * to know when all added promises have settled.\n     *\n     * @param {Promise} promise A promise to add to the extend lifetime promises\n     *     of the event that triggered the request.\n     */\n    waitUntil(promise) {\n        this._extendLifetimePromises.push(promise);\n        return promise;\n    }\n    /**\n     * Returns a promise that resolves once all promises passed to\n     * [`waitUntil()`]{@link module:workbox-strategies.StrategyHandler~waitUntil}\n     * have settled.\n     *\n     * Note: any work done after `doneWaiting()` settles should be manually\n     * passed to an event's `waitUntil()` method (not this handler's\n     * `waitUntil()` method), otherwise the service worker thread my be killed\n     * prior to your work completing.\n     */\n    async doneWaiting() {\n        let promise;\n        while (promise = this._extendLifetimePromises.shift()) {\n            await promise;\n        }\n    }\n    /**\n     * Stops running the strategy and immediately resolves any pending\n     * `waitUntil()` promises.\n     */\n    destroy() {\n        this._handlerDeferred.resolve();\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 {Request} options.request\n     * @param {Response} options.response\n     * @return {Promise<Response|undefined>}\n     *\n     * @private\n     */\n    async _ensureResponseSafeToCache(response) {\n        let responseToCache = response;\n        let pluginsUsed = false;\n        for (const callback of this.iterateCallbacks('cacheWillUpdate')) {\n            responseToCache = (await callback({\n                request: this.request,\n                response: responseToCache,\n                event: this.event,\n            })) || undefined;\n            pluginsUsed = true;\n            if (!responseToCache) {\n                break;\n            }\n        }\n        if (!pluginsUsed) {\n            if (responseToCache && responseToCache.status !== 200) {\n                responseToCache = undefined;\n            }\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 '${this.request.url}' ` +\n                                `is an opaque response. The caching strategy that you're ` +\n                                `using will not cache opaque responses by default.`);\n                        }\n                        else {\n                            logger.debug(`The response for '${this.request.url}' ` +\n                                `returned a status code of '${response.status}' and won't ` +\n                                `be cached as a result.`);\n                        }\n                    }\n                }\n            }\n        }\n        return responseToCache;\n    }\n}\nexport { StrategyHandler };\n","/*\n  Copyright 2020 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 { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { StrategyHandler } from './StrategyHandler.js';\nimport './_version.js';\n/**\n * An abstract base class that all other strategy classes must extend from:\n *\n * @memberof module:workbox-strategies\n */\nclass Strategy {\n    /**\n     * Creates a new instance of the strategy and sets all documented option\n     * properties as public instance properties.\n     *\n     * Note: if a custom strategy class extends the base Strategy class and does\n     * not need more than these properties, it does not need to define its own\n     * constructor.\n     *\n     * @param {Object} [options]\n     * @param {string} [options.cacheName] Cache name to store and retrieve\n     * requests. Defaults to the cache names provided by\n     * [workbox-core]{@link module:workbox-core.cacheNames}.\n     * @param {Array<Object>} [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.fetchOptions] Values passed along to the\n     * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)\n     * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796)\n     * `fetch()` requests made by this strategy.\n     * @param {Object} [options.matchOptions] The\n     * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions}\n     * for any `cache.match()` or `cache.put()` calls made by this strategy.\n     */\n    constructor(options = {}) {\n        /**\n         * Cache name to store and retrieve\n         * requests. Defaults to the cache names provided by\n         * [workbox-core]{@link module:workbox-core.cacheNames}.\n         *\n         * @type {string}\n         */\n        this.cacheName = cacheNames.getRuntimeName(options.cacheName);\n        /**\n         * The list\n         * [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}\n         * used by this strategy.\n         *\n         * @type {Array<Object>}\n         */\n        this.plugins = options.plugins || [];\n        /**\n         * Values passed along to the\n         * [`init`]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters}\n         * of all fetch() requests made by this strategy.\n         *\n         * @type {Object}\n         */\n        this.fetchOptions = options.fetchOptions;\n        /**\n         * The\n         * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions}\n         * for any `cache.match()` or `cache.put()` calls made by this strategy.\n         *\n         * @type {Object}\n         */\n        this.matchOptions = options.matchOptions;\n    }\n    /**\n     * Perform a request strategy and returns a `Promise` that will resolve with\n     * a `Response`, invoking all relevant plugin callbacks.\n     *\n     * When a strategy instance is registered with a Workbox\n     * [route]{@link module:workbox-routing.Route}, this method is automatically\n     * called when the route matches.\n     *\n     * Alternatively, this method can be used in a standalone `FetchEvent`\n     * listener by passing it to `event.respondWith()`.\n     *\n     * @param {FetchEvent|Object} options A `FetchEvent` or an object with the\n     *     properties listed below.\n     * @param {Request|string} options.request A request to run this strategy for.\n     * @param {ExtendableEvent} options.event The event associated with the\n     *     request.\n     * @param {URL} [options.url]\n     * @param {*} [options.params]\n     */\n    handle(options) {\n        const [responseDone] = this.handleAll(options);\n        return responseDone;\n    }\n    /**\n     * Similar to [`handle()`]{@link module:workbox-strategies.Strategy~handle}, but\n     * instead of just returning a `Promise` that resolves to a `Response` it\n     * it will return an tuple of [response, done] promises, where the former\n     * (`response`) is equivalent to what `handle()` returns, and the latter is a\n     * Promise that will resolve once any promises that were added to\n     * `event.waitUntil()` as part of performing the strategy have completed.\n     *\n     * You can await the `done` promise to ensure any extra work performed by\n     * the strategy (usually caching responses) completes successfully.\n     *\n     * @param {FetchEvent|Object} options A `FetchEvent` or an object with the\n     *     properties listed below.\n     * @param {Request|string} options.request A request to run this strategy for.\n     * @param {ExtendableEvent} options.event The event associated with the\n     *     request.\n     * @param {URL} [options.url]\n     * @param {*} [options.params]\n     * @return {Array<Promise>} A tuple of [response, done]\n     *     promises that can be used to determine when the response resolves as\n     *     well as when the handler has completed all its work.\n     */\n    handleAll(options) {\n        // Allow for flexible options to be passed.\n        if (options instanceof FetchEvent) {\n            options = {\n                event: options,\n                request: options.request,\n            };\n        }\n        const event = options.event;\n        const request = typeof options.request === 'string' ?\n            new Request(options.request) :\n            options.request;\n        const params = 'params' in options ? options.params : undefined;\n        const handler = new StrategyHandler(this, { event, request, params });\n        const responseDone = this._getResponse(handler, request, event);\n        const handlerDone = this._awaitComplete(responseDone, handler, request, event);\n        // Return an array of promises, suitable for use with Promise.all().\n        return [responseDone, handlerDone];\n    }\n    async _getResponse(handler, request, event) {\n        await handler.runCallbacks('handlerWillStart', { event, request });\n        let response = undefined;\n        try {\n            response = await this._handle(request, handler);\n            // The \"official\" Strategy subclasses all throw this error automatically,\n            // but in case a third-party Strategy doesn't, ensure that we have a\n            // consistent failure when there's no response or an error response.\n            if (!response || response.type === 'error') {\n                throw new WorkboxError('no-response', { url: request.url });\n            }\n        }\n        catch (error) {\n            for (const callback of handler.iterateCallbacks('handlerDidError')) {\n                response = await callback({ error, event, request });\n                if (response) {\n                    break;\n                }\n            }\n            if (!response) {\n                throw error;\n            }\n            else if (process.env.NODE_ENV !== 'production') {\n                logger.log(`While responding to '${getFriendlyURL(request.url)}', ` +\n                    `an ${error} error occurred. Using a fallback response provided by ` +\n                    `a handlerDidError plugin.`);\n            }\n        }\n        for (const callback of handler.iterateCallbacks('handlerWillRespond')) {\n            response = await callback({ event, request, response });\n        }\n        return response;\n    }\n    async _awaitComplete(responseDone, handler, request, event) {\n        let response;\n        let error;\n        try {\n            response = await responseDone;\n        }\n        catch (error) {\n            // Ignore errors, as response errors should be caught via the `response`\n            // promise above. The `done` promise will only throw for errors in\n            // promises passed to `handler.waitUntil()`.\n        }\n        try {\n            await handler.runCallbacks('handlerDidRespond', {\n                event,\n                request,\n                response,\n            });\n            await handler.doneWaiting();\n        }\n        catch (waitUntilError) {\n            error = waitUntilError;\n        }\n        await handler.runCallbacks('handlerDidComplete', {\n            event,\n            request,\n            response,\n            error,\n        });\n        handler.destroy();\n        if (error) {\n            throw error;\n        }\n    }\n}\nexport { Strategy };\n/**\n * Classes extending the `Strategy` based class should implement this method,\n * and leverage the [`handler`]{@link module:workbox-strategies.StrategyHandler}\n * arg to perform all fetching and cache logic, which will ensure all relevant\n * cache, cache options, fetch options and plugins are used (per the current\n * strategy instance).\n *\n * @name _handle\n * @instance\n * @abstract\n * @function\n * @param {Request} request\n * @param {module:workbox-strategies.StrategyHandler} handler\n * @return {Promise<Response>}\n *\n * @memberof module:workbox-strategies.Strategy\n */\n","/*\n  Copyright 2020 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 { copyResponse } from 'workbox-core/copyResponse.js';\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 { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { Strategy } from 'workbox-strategies/Strategy.js';\nimport './_version.js';\n/**\n * A [Strategy]{@link module:workbox-strategies.Strategy} implementation\n * specifically designed to work with\n * [PrecacheController]{@link module:workbox-precaching.PrecacheController}\n * to both cache and fetch precached assets.\n *\n * Note: an instance of this class is created automatically when creating a\n * `PrecacheController`; it's generally not necessary to create this yourself.\n *\n * @extends module:workbox-strategies.Strategy\n * @memberof module:workbox-precaching\n */\nclass PrecacheStrategy extends Strategy {\n    /**\n     *\n     * @param {Object} [options]\n     * @param {string} [options.cacheName] Cache name to store and retrieve\n     * requests. Defaults to the cache names provided by\n     * [workbox-core]{@link module:workbox-core.cacheNames}.\n     * @param {Array<Object>} [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.fetchOptions] Values passed along to the\n     * [`init`]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters}\n     * of all fetch() requests made by this strategy.\n     * @param {Object} [options.matchOptions] The\n     * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions}\n     * for any `cache.match()` or `cache.put()` calls made by this strategy.\n     * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to\n     * get the response from the network if there's a precache miss.\n     */\n    constructor(options = {}) {\n        options.cacheName = cacheNames.getPrecacheName(options.cacheName);\n        super(options);\n        this._fallbackToNetwork = options.fallbackToNetwork === false ? false : true;\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        this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin);\n    }\n    /**\n     * @private\n     * @param {Request|string} request A request to run this strategy for.\n     * @param {module:workbox-strategies.StrategyHandler} handler The event that\n     *     triggered the request.\n     * @return {Promise<Response>}\n     */\n    async _handle(request, handler) {\n        const response = await handler.cacheMatch(request);\n        if (!response) {\n            // If this is an `install` event then populate the cache. If this is a\n            // `fetch` event (or any other event) then respond with the cached\n            // response.\n            if (handler.event && handler.event.type === 'install') {\n                return await this._handleInstall(request, handler);\n            }\n            return await this._handleFetch(request, handler);\n        }\n        return response;\n    }\n    async _handleFetch(request, handler) {\n        let response;\n        // Fall back to the network if we don't have a cached response\n        // (perhaps due to manual cache cleanup).\n        if (this._fallbackToNetwork) {\n            if (process.env.NODE_ENV !== 'production') {\n                logger.warn(`The precached response for ` +\n                    `${getFriendlyURL(request.url)} in ${this.cacheName} was not ` +\n                    `found. Falling back to the network instead.`);\n            }\n            response = await handler.fetch(request);\n        }\n        else {\n            // This shouldn't normally happen, but there are edge cases:\n            // https://github.com/GoogleChrome/workbox/issues/1441\n            throw new WorkboxError('missing-precache-entry', {\n                cacheName: this.cacheName,\n                url: request.url,\n            });\n        }\n        if (process.env.NODE_ENV !== 'production') {\n            const cacheKey = handler.params && handler.params.cacheKey ||\n                await handler.getCacheKey(request, 'read');\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(request.url));\n            logger.log(`Serving the precached url: ${getFriendlyURL(cacheKey.url)}`);\n            logger.groupCollapsed(`View request details here.`);\n            logger.log(request);\n            logger.groupEnd();\n            logger.groupCollapsed(`View response details here.`);\n            logger.log(response);\n            logger.groupEnd();\n            logger.groupEnd();\n        }\n        return response;\n    }\n    async _handleInstall(request, handler) {\n        this._useDefaultCacheabilityPluginIfNeeded();\n        const response = await handler.fetch(request);\n        // Make sure we defer cachePut() until after we know the response\n        // should be cached; see https://github.com/GoogleChrome/workbox/issues/2737\n        const wasCached = await handler.cachePut(request, response.clone());\n        if (!wasCached) {\n            // Throwing here will lead to the `install` handler failing, which\n            // we want to do if *any* of the responses aren't safe to cache.\n            throw new WorkboxError('bad-precaching-response', {\n                url: request.url,\n                status: response.status,\n            });\n        }\n        return response;\n    }\n    /**\n     * This method is complex, as there a number of things to account for:\n     *\n     * The `plugins` array can be set at construction, and/or it might be added to\n     * to at any time before the strategy is used.\n     *\n     * At the time the strategy is used (i.e. during an `install` event), there\n     * needs to be at least one plugin that implements `cacheWillUpdate` in the\n     * array, other than `copyRedirectedCacheableResponsesPlugin`.\n     *\n     * - If this method is called and there are no suitable `cacheWillUpdate`\n     * plugins, we need to add `defaultPrecacheCacheabilityPlugin`.\n     *\n     * - If this method is called and there is exactly one `cacheWillUpdate`, then\n     * we don't have to do anything (this might be a previously added\n     * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin).\n     *\n     * - If this method is called and there is more than one `cacheWillUpdate`,\n     * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so,\n     * we need to remove it. (This situation is unlikely, but it could happen if\n     * the strategy is used multiple times, the first without a `cacheWillUpdate`,\n     * and then later on after manually adding a custom `cacheWillUpdate`.)\n     *\n     * See https://github.com/GoogleChrome/workbox/issues/2737 for more context.\n     *\n     * @private\n     */\n    _useDefaultCacheabilityPluginIfNeeded() {\n        let defaultPluginIndex = null;\n        let cacheWillUpdatePluginCount = 0;\n        for (const [index, plugin] of this.plugins.entries()) {\n            // Ignore the copy redirected plugin when determining what to do.\n            if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) {\n                continue;\n            }\n            // Save the default plugin's index, in case it needs to be removed.\n            if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) {\n                defaultPluginIndex = index;\n            }\n            if (plugin.cacheWillUpdate) {\n                cacheWillUpdatePluginCount++;\n            }\n        }\n        if (cacheWillUpdatePluginCount === 0) {\n            this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin);\n        }\n        else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) {\n            // Only remove the default plugin; multiple custom plugins are allowed.\n            this.plugins.splice(defaultPluginIndex, 1);\n        }\n        // Nothing needs to be done if cacheWillUpdatePluginCount is 1\n    }\n}\nPrecacheStrategy.defaultPrecacheCacheabilityPlugin = {\n    async cacheWillUpdate({ response }) {\n        if (!response || response.status >= 400) {\n            return null;\n        }\n        return response;\n    }\n};\nPrecacheStrategy.copyRedirectedCacheableResponsesPlugin = {\n    async cacheWillUpdate({ response }) {\n        return response.redirected ? await copyResponse(response) : response;\n    }\n};\nexport { PrecacheStrategy };\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 { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { waitUntil } from 'workbox-core/_private/waitUntil.js';\nimport { createCacheKey } from './utils/createCacheKey.js';\nimport { PrecacheInstallReportPlugin } from './utils/PrecacheInstallReportPlugin.js';\nimport { PrecacheCacheKeyPlugin } from './utils/PrecacheCacheKeyPlugin.js';\nimport { printCleanupDetails } from './utils/printCleanupDetails.js';\nimport { printInstallDetails } from './utils/printInstallDetails.js';\nimport { PrecacheStrategy } from './PrecacheStrategy.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 {Object} [options]\n     * @param {string} [options.cacheName] The cache to use for precaching.\n     * @param {string} [options.plugins] Plugins to use when precaching as well\n     * as responding to fetch events for precached assets.\n     * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to\n     * get the response from the network if there's a precache miss.\n     */\n    constructor({ cacheName, plugins = [], fallbackToNetwork = true } = {}) {\n        this._urlsToCacheKeys = new Map();\n        this._urlsToCacheModes = new Map();\n        this._cacheKeysToIntegrities = new Map();\n        this._strategy = new PrecacheStrategy({\n            cacheName: cacheNames.getPrecacheName(cacheName),\n            plugins: [\n                ...plugins,\n                new PrecacheCacheKeyPlugin({ precacheController: this }),\n            ],\n            fallbackToNetwork,\n        });\n        // Bind the install and activate methods to the instance.\n        this.install = this.install.bind(this);\n        this.activate = this.activate.bind(this);\n    }\n    /**\n     * @type {module:workbox-precaching.PrecacheStrategy} The strategy created by this controller and\n     * used to cache assets and respond to fetch events.\n     */\n    get strategy() {\n        return this._strategy;\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     * @param {Array<Object|string>} [entries=[]] Array of entries to precache.\n     */\n    precache(entries) {\n        this.addToCacheList(entries);\n        if (!this._installAndActiveListenersAdded) {\n            self.addEventListener('install', this.install);\n            self.addEventListener('activate', this.activate);\n            this._installAndActiveListenersAdded = true;\n        }\n    }\n    /**\n     * This method will add items to the precache list, removing duplicates\n     * and ensuring the information is valid.\n     *\n     * @param {Array<module:workbox-precaching.PrecacheController.PrecacheEntry|string>} entries\n     *     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        const urlsToWarnAbout = [];\n        for (const entry of entries) {\n            // See https://github.com/GoogleChrome/workbox/issues/2259\n            if (typeof entry === 'string') {\n                urlsToWarnAbout.push(entry);\n            }\n            else if (entry && entry.revision === undefined) {\n                urlsToWarnAbout.push(entry.url);\n            }\n            const { cacheKey, url } = createCacheKey(entry);\n            const cacheMode = (typeof entry !== 'string' && entry.revision) ?\n                'reload' : 'default';\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            this._urlsToCacheModes.set(url, cacheMode);\n            if (urlsToWarnAbout.length > 0) {\n                const warningMessage = `Workbox is precaching URLs without revision ` +\n                    `info: ${urlsToWarnAbout.join(', ')}\\nThis is generally NOT safe. ` +\n                    `Learn more at https://bit.ly/wb-precache`;\n                if (process.env.NODE_ENV === 'production') {\n                    // Use console directly to display this warning without bloating\n                    // bundle sizes by pulling in all of the logger codebase in prod.\n                    console.warn(warningMessage);\n                }\n                else {\n                    logger.warn(warningMessage);\n                }\n            }\n        }\n    }\n    /**\n     * Precaches new and updated assets. Call this method from the service worker\n     * install event.\n     *\n     * Note: this method calls `event.waitUntil()` for you, so you do not need\n     * to call it yourself in your event handlers.\n     *\n     * @param {ExtendableEvent} event\n     * @return {Promise<module:workbox-precaching.InstallResult>}\n     */\n    install(event) {\n        return waitUntil(event, async () => {\n            const installReportPlugin = new PrecacheInstallReportPlugin();\n            this.strategy.plugins.push(installReportPlugin);\n            // Cache entries one at a time.\n            // See https://github.com/GoogleChrome/workbox/issues/2528\n            for (const [url, cacheKey] of this._urlsToCacheKeys) {\n                const integrity = this._cacheKeysToIntegrities.get(cacheKey);\n                const cacheMode = this._urlsToCacheModes.get(url);\n                const request = new Request(url, {\n                    integrity,\n                    cache: cacheMode,\n                    credentials: 'same-origin',\n                });\n                await Promise.all(this.strategy.handleAll({\n                    params: { cacheKey },\n                    request,\n                    event,\n                }));\n            }\n            const { updatedURLs, notUpdatedURLs } = installReportPlugin;\n            if (process.env.NODE_ENV !== 'production') {\n                printInstallDetails(updatedURLs, notUpdatedURLs);\n            }\n            return { updatedURLs, notUpdatedURLs };\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     * Note: this method calls `event.waitUntil()` for you, so you do not need\n     * to call it yourself in your event handlers.\n     *\n     * @param {ExtendableEvent} event\n     * @return {Promise<module:workbox-precaching.CleanupResult>}\n     */\n    activate(event) {\n        return waitUntil(event, async () => {\n            const cache = await self.caches.open(this.strategy.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    /**\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<string, string>} 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<string>} 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     * This acts as a drop-in replacement for\n     * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match)\n     * with the following differences:\n     *\n     * - It knows what the name of the precache is, and only checks in that cache.\n     * - It allows you to pass in an \"original\" URL without versioning parameters,\n     * and it will automatically look up the correct cache key for the currently\n     * active revision of that URL.\n     *\n     * E.g., `matchPrecache('index.html')` will find the correct precached\n     * response for the currently active service worker, even if the actual cache\n     * key is `'/index.html?__WB_REVISION__=1234abcd'`.\n     *\n     * @param {string|Request} request The key (without revisioning parameters)\n     * to look up in the precache.\n     * @return {Promise<Response|undefined>}\n     */\n    async matchPrecache(request) {\n        const url = request instanceof Request ? request.url : request;\n        const cacheKey = this.getCacheKeyForURL(url);\n        if (cacheKey) {\n            const cache = await self.caches.open(this.strategy.cacheName);\n            return cache.match(cacheKey);\n        }\n        return undefined;\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     * @param {string} url The precached URL which will be used to lookup the\n     * `Response`.\n     * @return {module:workbox-routing~handlerCallback}\n     */\n    createHandlerBoundToURL(url) {\n        const cacheKey = this.getCacheKeyForURL(url);\n        if (!cacheKey) {\n            throw new WorkboxError('non-precached-url', { url });\n        }\n        return (options) => {\n            options.request = new Request(url);\n            options.params = { cacheKey, ...options.params };\n            return this.strategy.handle(options);\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","\"use strict\";\n// @ts-ignore\ntry {\n    self['workbox:routing:6.1.5'] && _();\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<string>}\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 module:workbox-routing\n */\nclass Route {\n    /**\n     * Constructor for Route class.\n     *\n     * @param {module:workbox-routing~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 {module:workbox-routing~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 minificaton.\n        this.handler = normalizeHandler(handler);\n        this.match = match;\n        this.method = method;\n    }\n    /**\n     *\n     * @param {module:workbox-routing-handlerCallback} handler A callback\n     * function that returns a Promise resolving to a Response\n     */\n    setCatchHandler(handler) {\n        this.catchHandler = normalizeHandler(handler);\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 module: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 module:workbox-routing\n * @extends module:workbox-routing.Route\n */\nclass RegExpRoute extends Route {\n    /**\n     * If the regular expression contains\n     * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},\n     * the captured values will be passed to the\n     * [handler's]{@link module:workbox-routing~handlerCallback} `params`\n     * argument.\n     *\n     * @param {RegExp} regExp The regular expression to match against URLs.\n     * @param {module:workbox-routing~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 { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { defaultMethod } from './utils/constants.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport './_version.js';\n/**\n * The Router can be used to process a FetchEvent through one or more\n * [Routes]{@link module: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 module:workbox-routing\n */\nclass Router {\n    /**\n     * Initializes a new Router.\n     */\n    constructor() {\n        this._routes = new Map();\n        this._defaultHandlerMap = new Map();\n    }\n    /**\n     * @return {Map<string, Array<module:workbox-routing.Route>>} 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        // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705\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        // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705\n        self.addEventListener('message', ((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, event });\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<Promise<Response> | 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                    requestPromises.then(() => 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.\n     * @param {ExtendableEvent} options.event The event that triggered the\n     *     request.\n     * @return {Promise<Response>|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        const sameOrigin = url.origin === location.origin;\n        const { params, route } = this.findMatchingRoute({\n            event,\n            request,\n            sameOrigin,\n            url,\n        });\n        let handler = route && route.handler;\n        const 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        const method = request.method;\n        if (!handler && this._defaultHandlerMap.has(method)) {\n            if (process.env.NODE_ENV !== 'production') {\n                debugMessages.push(`Failed to find a matching route. Falling ` +\n                    `back to the default handler for ${method}.`);\n            }\n            handler = this._defaultHandlerMap.get(method);\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            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        // Get route's catch handler, if it exists\n        const catchHandler = route && route.catchHandler;\n        if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) {\n            responsePromise = responsePromise.catch(async (err) => {\n                // If there's a route catch handler, process that first\n                if (catchHandler) {\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 route's Catch Handler.`);\n                        logger.error(`Error thrown by:`, route);\n                        logger.error(err);\n                        logger.groupEnd();\n                    }\n                    try {\n                        return await catchHandler.handle({ url, request, event, params });\n                    }\n                    catch (catchErr) {\n                        err = catchErr;\n                    }\n                }\n                if (this._catchHandler) {\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 global 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                throw err;\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 {boolean} options.sameOrigin The result of comparing `url.origin`\n     *     against the current origin.\n     * @param {Request} options.request The request to match.\n     * @param {Event} options.event The corresponding event.\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, sameOrigin, request, event }) {\n        const routes = this._routes.get(request.method) || [];\n        for (const route of routes) {\n            let params;\n            const matchResult = route.match({ url, sameOrigin, request, event });\n            if (matchResult) {\n                if (process.env.NODE_ENV !== 'production') {\n                    // Warn developers that using an async matchCallback is almost always\n                    // not the right thing to do. \n                    if (matchResult instanceof Promise) {\n                        logger.warn(`While routing ${getFriendlyURL(url)}, an async ` +\n                            `matchCallback function was used. Please convert the ` +\n                            `following route to use a synchronous matchCallback function:`, route);\n                    }\n                }\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     * Each HTTP method ('GET', 'POST', etc.) gets its own default handler.\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 {module:workbox-routing~handlerCallback} handler A callback\n     * function that returns a Promise resulting in a Response.\n     * @param {string} [method='GET'] The HTTP method to associate with this\n     * default handler. Each method has its own default.\n     */\n    setDefaultHandler(handler, method = defaultMethod) {\n        this._defaultHandlerMap.set(method, 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 {module:workbox-routing~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 {module: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 {module: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 [registerRoute()]{@link module:workbox-routing.Router#registerRoute}.\n *\n * @param {RegExp|string|module:workbox-routing.Route~matchCallback|module:workbox-routing.Route} capture\n * If the capture param is a `Route`, all other arguments will be ignored.\n * @param {module:workbox-routing~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 {module:workbox-routing.Route} The generated `Route`(Useful for\n * unregistering).\n *\n * @memberof module:workbox-routing\n */\nfunction 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 ((new RegExp(`${wildcards}`)).exec(valueToCheck)) {\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}\nexport { registerRoute };\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<RegExp>} 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\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 = [/^utm_/, /^fbclid$/], directoryIndex = 'index.html', cleanURLs = true, 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 2020 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 { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { Route } from 'workbox-routing/Route.js';\nimport { generateURLVariations } from './utils/generateURLVariations.js';\nimport './_version.js';\n/**\n * A subclass of [Route]{@link module:workbox-routing.Route} that takes a\n * [PrecacheController]{@link module:workbox-precaching.PrecacheController}\n * instance and uses it to match incoming requests and handle fetching\n * responses from the precache.\n *\n * @memberof module:workbox-precaching\n * @extends module:workbox-routing.Route\n */\nclass PrecacheRoute extends Route {\n    /**\n     * @param {PrecacheController} precacheController A `PrecacheController`\n     * instance used to both match requests and respond to fetch events.\n     * @param {Object} [options] Options to control how requests are matched\n     * against the list of precached URLs.\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<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] 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 {module: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    constructor(precacheController, options) {\n        const match = ({ request }) => {\n            const urlsToCacheKeys = precacheController.getURLsToCacheKeys();\n            for (const possibleURL of generateURLVariations(request.url, options)) {\n                const cacheKey = urlsToCacheKeys.get(possibleURL);\n                if (cacheKey) {\n                    return { cacheKey };\n                }\n            }\n            if (process.env.NODE_ENV !== 'production') {\n                logger.debug(`Precaching did not find a match for ` +\n                    getFriendlyURL(request.url));\n            }\n            return;\n        };\n        super(match, precacheController.strategy);\n    }\n}\nexport { PrecacheRoute };\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 { registerRoute } from 'workbox-routing/registerRoute.js';\nimport { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js';\nimport { PrecacheRoute } from './PrecacheRoute.js';\nimport './_version.js';\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] See\n * [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}.\n *\n * @memberof module:workbox-precaching\n */\nfunction addRoute(options) {\n    const precacheController = getOrCreatePrecacheController();\n    const precacheRoute = new PrecacheRoute(precacheController, options);\n    registerRoute(precacheRoute);\n}\nexport { addRoute };\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 './utils/getOrCreatePrecacheController.js';\nimport './_version.js';\n/**\n * Helper function that calls\n * {@link PrecacheController#createHandlerBoundToURL} on the default\n * {@link PrecacheController} instance.\n *\n * If you are creating your own {@link PrecacheController}, then call the\n * {@link PrecacheController#createHandlerBoundToURL} on that instance,\n * instead of using this function.\n *\n * @param {string} url The precached URL which will be used to lookup the\n * `Response`.\n * @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the\n * response from the network if there's a precache miss.\n * @return {module:workbox-routing~handlerCallback}\n *\n * @memberof module:workbox-precaching\n */\nfunction createHandlerBoundToURL(url) {\n    const precacheController = getOrCreatePrecacheController();\n    return precacheController.createHandlerBoundToURL(url);\n}\nexport { createHandlerBoundToURL };\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 './utils/getOrCreatePrecacheController.js';\nimport './_version.js';\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<Object|string>} [entries=[]] Array of entries to precache.\n *\n * @memberof module:workbox-precaching\n */\nfunction precache(entries) {\n    const precacheController = getOrCreatePrecacheController();\n    precacheController.precache(entries);\n}\nexport { precache };\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<Object|string>} entries Array of entries to precache.\n * @param {Object} [options] See\n * [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}.\n *\n * @memberof module:workbox-precaching\n */\nfunction precacheAndRoute(entries, options) {\n    precache(entries);\n    addRoute(options);\n}\nexport { precacheAndRoute };\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 cacheOkAndOpaquePlugin = {\n    /**\n     * Returns a valid response (to allow caching) if the status is 200 (OK) or\n     * 0 (opaque).\n     *\n     * @param {Object} options\n     * @param {Response} options.response\n     * @return {Response|null}\n     *\n     * @private\n     */\n    cacheWillUpdate: async ({ response }) => {\n        if (response.status === 200 || response.status === 0) {\n            return response;\n        }\n        return null;\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 { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { cacheOkAndOpaquePlugin } from './plugins/cacheOkAndOpaquePlugin.js';\nimport { Strategy } from './Strategy.js';\nimport { messages } from './utils/messages.js';\nimport './_version.js';\n/**\n * An implementation of a\n * [stale-while-revalidate]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#stale-while-revalidate}\n * request strategy.\n *\n * Resources are requested from both the cache and the network in parallel.\n * The strategy will respond with the cached version if available, otherwise\n * wait for the network response. The cache is updated with the network response\n * with each successful request.\n *\n * By default, this strategy will cache responses with a 200 status code as\n * well as [opaque responses]{@link https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests}.\n * Opaque responses are cross-origin requests where the response doesn't\n * support [CORS]{@link https://enable-cors.org/}.\n *\n * If the network request fails, and there is no cache match, this will throw\n * a `WorkboxError` exception.\n *\n * @extends module:workbox-strategies.Strategy\n * @memberof module:workbox-strategies\n */\nclass StaleWhileRevalidate extends Strategy {\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 module:workbox-core.cacheNames}.\n     * @param {Array<Object>} [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.fetchOptions] Values passed along to the\n     * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)\n     * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796)\n     * `fetch()` requests made by this strategy.\n     * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)\n     */\n    constructor(options) {\n        super(options);\n        // If this instance contains no plugins with a 'cacheWillUpdate' callback,\n        // prepend the `cacheOkAndOpaquePlugin` plugin to the plugins list.\n        if (!this.plugins.some((p) => 'cacheWillUpdate' in p)) {\n            this.plugins.unshift(cacheOkAndOpaquePlugin);\n        }\n    }\n    /**\n     * @private\n     * @param {Request|string} request A request to run this strategy for.\n     * @param {module:workbox-strategies.StrategyHandler} handler The event that\n     *     triggered the request.\n     * @return {Promise<Response>}\n     */\n    async _handle(request, handler) {\n        const logs = [];\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isInstance(request, Request, {\n                moduleName: 'workbox-strategies',\n                className: this.constructor.name,\n                funcName: 'handle',\n                paramName: 'request',\n            });\n        }\n        const fetchAndCachePromise = handler\n            .fetchAndCachePut(request)\n            .catch(() => {\n            // Swallow this error because a 'no-response' error will be thrown in\n            // main handler return flow. This will be in the `waitUntil()` flow.\n        });\n        let response = await handler.cacheMatch(request);\n        let error;\n        if (response) {\n            if (process.env.NODE_ENV !== 'production') {\n                logs.push(`Found a cached response in the '${this.cacheName}'` +\n                    ` cache. Will update with the network response in the background.`);\n            }\n        }\n        else {\n            if (process.env.NODE_ENV !== 'production') {\n                logs.push(`No response found in the '${this.cacheName}' cache. ` +\n                    `Will wait for the network response.`);\n            }\n            try {\n                // NOTE(philipwalton): Really annoying that we have to type cast here.\n                // https://github.com/microsoft/TypeScript/issues/20006\n                response = await fetchAndCachePromise;\n            }\n            catch (err) {\n                error = err;\n            }\n        }\n        if (process.env.NODE_ENV !== 'production') {\n            logger.groupCollapsed(messages.strategyStart(this.constructor.name, request));\n            for (const log of logs) {\n                logger.log(log);\n            }\n            messages.printFinalResponse(response);\n            logger.groupEnd();\n        }\n        if (!response) {\n            throw new WorkboxError('no-response', { url: request.url, error });\n        }\n        return response;\n    }\n}\nexport { StaleWhileRevalidate };\n","// Generated by get_precache_files.py\nexport const EXTRA_PRECACHE_FILES = [\n\t{ url: './assets/recorder/encoderWorker.min.wasm', revision: '2018' },\n\t{ url: '/assets/recorder/decoderWorker.min.wasm', revision: '2018' },\n];\n","/// <reference lib=\"webworker\" />\n/* eslint-disable no-restricted-globals */\n\n// This service worker can be customized!\n// See https://developers.google.com/web/tools/workbox/modules\n// for the list of available Workbox modules, or add any other\n// code you'd like.\n// You can also remove this file if you'd prefer not to use a\n// service worker, and the Workbox build step will be skipped.\n\nimport { clientsClaim } from 'workbox-core';\nimport { ExpirationPlugin } from 'workbox-expiration';\nimport { createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching';\nimport { registerRoute } from 'workbox-routing';\nimport { StaleWhileRevalidate } from 'workbox-strategies';\nimport { EXTRA_PRECACHE_FILES } from './extraPrecacheFiles';\n\ndeclare const self: ServiceWorkerGlobalScope;\n\nclientsClaim();\n\n// Precache all of the assets generated by your build process.\n// Their URLs are injected into the manifest variable below.\n// This variable must be present somewhere in your service worker file,\n// even if you decide not to use precaching. See https://cra.link/PWA\nprecacheAndRoute([\n\t...self.__WB_MANIFEST,\n\t...EXTRA_PRECACHE_FILES\n]);\n\n// Set up App Shell-style routing, so that all navigation requests\n// are fulfilled with your index.html shell. Learn more at\n// https://developers.google.com/web/fundamentals/architecture/app-shell\nconst fileExtensionRegexp = new RegExp('/[^/?]+\\\\.[^/]+$');\nregisterRoute(\n\t// Return false to exempt requests from being fulfilled by index.html.\n\t({ request, url }: { request: Request; url: URL }) => {\n\t\t// If this isn't a navigation, skip.\n\t\tif (request.mode !== 'navigate') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If this is a URL that starts with /_, skip.\n\t\tif (url.pathname.startsWith('/_')) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If this looks like a URL for a resource, because it contains\n\t\t// a file extension, skip.\n\t\tif (url.pathname.match(fileExtensionRegexp)) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return true to signal that we want to use the handler.\n\t\treturn true;\n\t},\n\tcreateHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')\n);\n\n// An example runtime caching route for requests that aren't handled by the\n// precache, in this case same-origin .png requests like those from in public/\nregisterRoute(\n\t// Add in any other file extensions or routing criteria as needed.\n\t({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'),\n\t// Customize this strategy as needed, e.g., by changing to CacheFirst.\n\tnew StaleWhileRevalidate({\n\t\tcacheName: 'images',\n\t\tplugins: [\n\t\t\t// Ensure that once this runtime cache reaches a maximum size the\n\t\t\t// least-recently used images are removed.\n\t\t\tnew ExpirationPlugin({ maxEntries: 50 }),\n\t\t],\n\t})\n);\n\n// This allows the web app to trigger skipWaiting via\n// registration.waiting.postMessage({type: 'SKIP_WAITING'})\nself.addEventListener('message', (event) => {\n\tif (event.data && event.data.type === 'SKIP_WAITING') {\n\t\tself.skipWaiting();\n\t}\n});\n\n// Any other custom service worker logic can go here.\n"]}