diff --git a/packages/workbox-build/package-lock.json b/packages/workbox-build/package-lock.json index 84f0f411b..46f7552df 100644 --- a/packages/workbox-build/package-lock.json +++ b/packages/workbox-build/package-lock.json @@ -45,6 +45,11 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -58,6 +63,13 @@ "lodash": "^4.17.13", "source-map": "^0.5.0", "trim-right": "^1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "@babel/helper-annotate-as-pure": { @@ -1357,6 +1369,11 @@ } } }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -1715,9 +1732,9 @@ } }, "magic-string": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz", - "integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==", + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", + "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", "requires": { "sourcemap-codec": "^1.4.4" } @@ -2224,6 +2241,11 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -2292,9 +2314,9 @@ } }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" }, "source-map-resolve": { "version": "0.5.2", @@ -2330,9 +2352,9 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "sourcemap-codec": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz", - "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==" + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", + "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==" }, "split-string": { "version": "3.1.0", diff --git a/packages/workbox-build/package.json b/packages/workbox-build/package.json index b7a888745..83875b1fe 100644 --- a/packages/workbox-build/package.json +++ b/packages/workbox-build/package.json @@ -24,7 +24,9 @@ "@babel/preset-env": "^7.5.5", "@babel/runtime": "^7.5.5", "@hapi/joi": "^15.1.0", + "@surma/rollup-plugin-off-main-thread": "^1.1.1", "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.0.0", "fs-extra": "^8.1.0", "glob": "^7.1.4", "lodash.template": "^4.5.0", @@ -32,9 +34,10 @@ "rollup": "^1.17.0", "rollup-plugin-babel": "^4.3.3", "rollup-plugin-node-resolve": "^5.2.0", - "@surma/rollup-plugin-off-main-thread": "^1.1.1", "rollup-plugin-replace": "^2.2.0", "rollup-plugin-terser": "^5.1.1", + "source-map": "^0.7.3", + "source-map-url": "^0.4.0", "stringify-object": "^3.3.0", "strip-comments": "^1.0.2", "tempy": "^0.3.0", diff --git a/packages/workbox-build/src/inject-manifest.js b/packages/workbox-build/src/inject-manifest.js index c7b64f773..d0d218308 100644 --- a/packages/workbox-build/src/inject-manifest.js +++ b/packages/workbox-build/src/inject-manifest.js @@ -8,6 +8,8 @@ const assert = require('assert'); const fse = require('fs-extra'); +const sourceMapURL = require('source-map-url'); +const stringify = require('fast-json-stable-stringify'); const upath = require('upath'); const errors = require('./lib/errors'); @@ -15,6 +17,8 @@ const escapeRegexp = require('./lib/escape-regexp'); const getFileManifestEntries = require('./lib/get-file-manifest-entries'); const injectManifestSchema = require('./options/schema/inject-manifest'); const rebasePath = require('./lib/rebase-path'); +const replaceAndUpdateSourceMap = + require('./lib/replace-and-update-source-map'); const validate = require('./lib/validate-options'); /** @@ -49,17 +53,13 @@ async function injectManifest(config) { })); } - if (upath.resolve(config.swSrc) === upath.resolve(config.swDest)) { - throw new Error(errors['same-src-and-dest']); - } - const globalRegexp = new RegExp(escapeRegexp(options.injectionPoint), 'g'); const {count, size, manifestEntries, warnings} = await getFileManifestEntries(options); let swFileContents; try { - swFileContents = await fse.readFile(config.swSrc, 'utf8'); + swFileContents = await fse.readFile(options.swSrc, 'utf8'); } catch (error) { throw new Error(`${errors['invalid-sw-src']} ${error.message}`); } @@ -67,7 +67,7 @@ async function injectManifest(config) { const injectionResults = swFileContents.match(globalRegexp); if (!injectionResults) { // See https://github.com/GoogleChrome/workbox/issues/2230 - if (upath.resolve(config.swSrc) === upath.resolve(config.swDest)) { + if (upath.resolve(options.swSrc) === upath.resolve(options.swDest)) { throw new Error(errors['same-src-and-dest'] + ' ' + options.injectionPoint); } @@ -78,23 +78,60 @@ async function injectManifest(config) { assert(injectionResults.length === 1, errors['multiple-injection-points'] + options.injectionPoint); - const entriesString = JSON.stringify(manifestEntries, null, 2); - swFileContents = swFileContents.replace(globalRegexp, entriesString); + const manifestString = stringify(manifestEntries); + const filesToWrite = {}; + + const url = sourceMapURL.getFrom(swFileContents); + // If our swSrc file contains a sourcemap, we would invalidate that + // mapping if we just replaced injectionPoint with the stringified manifest. + // Instead, we need to update the swDest contents as well as the sourcemap + // at the same time. + // See https://github.com/GoogleChrome/workbox/issues/2235 + if (url) { + const sourcemapSrcPath = upath.resolve(upath.dirname(options.swSrc), url); + const sourcemapDestPath = upath.resolve(upath.dirname(options.swDest), url); + + let originalMap; + try { + originalMap = await fse.readJSON(sourcemapSrcPath, 'utf8'); + } catch (error) { + throw new Error(`${errors['cant-find-sourcemap']} ${error.message}`); + } - try { - await fse.mkdirp(upath.dirname(options.swDest)); - } catch (error) { - throw new Error(errors['unable-to-make-injection-directory'] + - ` '${error.message}'`); + const {map, source} = await replaceAndUpdateSourceMap({ + originalMap, + jsFilename: upath.basename(options.swDest), + originalSource: swFileContents, + replaceString: manifestString, + searchString: options.injectionPoint, + }); + + filesToWrite[options.swDest] = source; + filesToWrite[sourcemapDestPath] = map; + } else { + // If there's no sourcemap associated with swSrc, a simple string + // replacement will suffice. + filesToWrite[options.swDest] = swFileContents.replace( + globalRegexp, manifestString); } - await fse.writeFile(config.swDest, swFileContents); + for (const [file, contents] of Object.entries(filesToWrite)) { + try { + await fse.mkdirp(upath.dirname(file)); + } catch (error) { + throw new Error(errors['unable-to-make-injection-directory'] + + ` '${error.message}'`); + } - // Wrap the single output file in an array to make the return value consistent - // with generateSW. - const filePaths = [config.swDest]; + await fse.writeFile(file, contents); + } - return {count, filePaths, size, warnings}; + return { + count, + size, + warnings, + filePaths: Object.keys(filesToWrite), + }; } module.exports = injectManifest; diff --git a/packages/workbox-build/src/lib/errors.js b/packages/workbox-build/src/lib/errors.js index 2613c64f9..f9c07e0f3 100644 --- a/packages/workbox-build/src/lib/errors.js +++ b/packages/workbox-build/src/lib/errors.js @@ -115,4 +115,6 @@ module.exports = { either precaching or runtime caching. Please ensure that the various glob options are set to match one or more files, and/or configure the runtimeCaching option.`, + 'cant-find-sourcemap': ol`The swSrc file refers to a sourcemap that can't be + opened:`, }; diff --git a/packages/workbox-build/src/lib/replace-and-update-source-map.js b/packages/workbox-build/src/lib/replace-and-update-source-map.js new file mode 100644 index 000000000..4fd853b77 --- /dev/null +++ b/packages/workbox-build/src/lib/replace-and-update-source-map.js @@ -0,0 +1,108 @@ +/* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. +*/ + +const {SourceMapConsumer, SourceMapGenerator} = require('source-map'); + +/** + * Adapted from https://github.com/nsams/sourcemap-aware-replace, with modern + * JavaScript updates, along with additional properties copied from originalMap. + * + * @param {Object} options + * @param {string} options.jsFilename The name for the file whose contents + * correspond to originalSource. + * @param {Object} options.originalMap The sourcemap for originalSource, + * prior to any replacements. + * @param {string} options.originalSource The source code, prior to any + * replacements. + * @param {string} options.replaceString A string to swap in for searchString. + * @param {string} options.searchString A string in originalSource to replace. + * Only the first occurrence will be replaced. + * @return {{source: string, map: string}} An object containing both + * originalSource with the replacement applied, and the modified originalMap. + * + * @private + */ +async function replaceAndUpdateSourceMap({ + jsFilename, + originalMap, + originalSource, + replaceString, + searchString, +}) { + const generator = new SourceMapGenerator({ + file: jsFilename, + }); + + const consumer = await new SourceMapConsumer(originalMap); + + let pos; + let src = originalSource; + const replacements = []; + let lineNum = 0; + let filePos = 0; + + const lines = src.split('\n'); + for (let line of lines) { + lineNum++; + let searchPos = 0; + while ((pos = line.indexOf(searchString, searchPos)) !== -1) { + src = src.substring(0, filePos + pos) + replaceString + + src.substring(filePos + pos + searchString.length); + line = line.substring(0, pos) + replaceString + + line.substring(pos + searchString.length); + replacements.push({line: lineNum, column: pos}); + searchPos = pos + replaceString.length; + } + filePos += line.length + 1; + } + + replacements.reverse(); + + consumer.eachMapping((mapping) => { + for (const replacement of replacements) { + if (replacement.line == mapping.generatedLine && + mapping.generatedColumn > replacement.column) { + const offset = searchString.length - replaceString.length; + mapping.generatedColumn -= offset; + } + } + + if (mapping.source) { + const newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn, + }, + original: { + line: mapping.originalLine, + column: mapping.originalColumn, + }, + source: mapping.source, + }; + return generator.addMapping(newMapping); + } + + return mapping; + }); + + consumer.destroy(); + + const updatedSourceMap = Object.assign(JSON.parse(generator.toString()), { + names: originalMap.names, + sourceRoot: originalMap.sourceRoot, + sources: originalMap.sources, + sourcesContent: originalMap.sourcesContent, + }); + + return { + map: JSON.stringify(updatedSourceMap), + source: src, + }; +} + +module.exports = replaceAndUpdateSourceMap; diff --git a/packages/workbox-webpack-plugin/package-lock.json b/packages/workbox-webpack-plugin/package-lock.json index 45e71d215..06656a757 100644 --- a/packages/workbox-webpack-plugin/package-lock.json +++ b/packages/workbox-webpack-plugin/package-lock.json @@ -1,692 +1,9 @@ { "name": "workbox-webpack-plugin", - "version": "5.0.0-alpha.2", + "version": "5.0.0-beta.0", "lockfileVersion": 1, "requires": true, "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", - "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.5.5", - "@babel/helpers": "^7.5.5", - "@babel/parser": "^7.5.5", - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5", - "convert-source-map": "^1.1.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/generator": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", - "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", - "requires": { - "@babel/types": "^7.5.5", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", - "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", - "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", - "requires": { - "@babel/helper-explode-assignable-expression": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-call-delegate": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", - "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", - "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-define-map": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", - "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.5.5", - "lodash": "^4.17.13" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", - "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", - "requires": { - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", - "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", - "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", - "requires": { - "@babel/types": "^7.5.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-transforms": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", - "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/template": "^7.4.4", - "@babel/types": "^7.5.5", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", - "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" - }, - "@babel/helper-regex": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", - "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", - "requires": { - "lodash": "^4.17.13" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", - "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-wrap-function": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-replace-supers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", - "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" - } - }, - "@babel/helper-simple-access": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", - "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", - "requires": { - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-wrap-function": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", - "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.2.0" - } - }, - "@babel/helpers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", - "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", - "requires": { - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", - "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==" - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", - "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0", - "@babel/plugin-syntax-async-generators": "^7.2.0" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", - "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.2.0" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", - "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-json-strings": "^7.2.0" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", - "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", - "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", - "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", - "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", - "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", - "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", - "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", - "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz", - "integrity": "sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.13" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", - "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.5.5", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5", - "@babel/helper-split-export-declaration": "^7.4.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", - "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", - "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", - "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", - "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", - "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", - "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", - "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", - "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", - "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", - "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", - "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", - "requires": { - "@babel/helper-module-transforms": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", - "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", - "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", - "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", - "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", - "requires": { - "regexp-tree": "^0.1.6" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", - "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", - "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", - "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", - "requires": { - "@babel/helper-call-delegate": "^7.4.4", - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", - "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", - "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", - "requires": { - "regenerator-transform": "^0.14.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", - "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", - "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", - "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", - "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", - "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", - "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", - "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/preset-env": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.5.5.tgz", - "integrity": "sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-dynamic-import": "^7.5.0", - "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-dynamic-import": "^7.2.0", - "@babel/plugin-syntax-json-strings": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.5.0", - "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.5.5", - "@babel/plugin-transform-classes": "^7.5.5", - "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.5.0", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/plugin-transform-duplicate-keys": "^7.5.0", - "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.4.4", - "@babel/plugin-transform-function-name": "^7.4.4", - "@babel/plugin-transform-literals": "^7.2.0", - "@babel/plugin-transform-member-expression-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.5.0", - "@babel/plugin-transform-modules-commonjs": "^7.5.0", - "@babel/plugin-transform-modules-systemjs": "^7.5.0", - "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", - "@babel/plugin-transform-new-target": "^7.4.4", - "@babel/plugin-transform-object-super": "^7.5.5", - "@babel/plugin-transform-parameters": "^7.4.4", - "@babel/plugin-transform-property-literals": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.4.5", - "@babel/plugin-transform-reserved-words": "^7.2.0", - "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.2.0", - "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.4.4", - "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.4.4", - "@babel/types": "^7.5.5", - "browserslist": "^4.6.0", - "core-js-compat": "^3.1.1", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.5.0" - } - }, "@babel/runtime": { "version": "7.5.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", @@ -695,734 +12,16 @@ "regenerator-runtime": "^0.13.2" } }, - "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/traverse": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", - "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.5.5", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.5.5", - "@babel/types": "^7.5.5", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", - "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@hapi/address": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz", - "integrity": "sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw==" - }, - "@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" - }, - "@hapi/hoek": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.2.1.tgz", - "integrity": "sha512-JPiBy+oSmsq3St7XlipfN5pNA6bDJ1kpa73PrK/zR29CVClDVqy04AanM/M/qx5bSF+I61DdCfAvRrujau+zRg==" - }, - "@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", - "requires": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" - } - }, - "@hapi/topo": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.3.tgz", - "integrity": "sha512-JmS9/vQK6dcUYn7wc2YZTqzIKubAQcJKu2KCKAru6es482U5RT5fP1EXCPtlXpiK7PR0On/kpQKI4fRKkzpZBQ==", - "requires": { - "@hapi/hoek": "8.x.x" - } - }, - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - }, - "@types/node": { - "version": "12.7.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.2.tgz", - "integrity": "sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg==" - }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "requires": { - "@types/node": "*" - } - }, - "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "babel-extract-comments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", - "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", - "requires": { - "babylon": "^6.18.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", - "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - } - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "browserslist": { - "version": "4.6.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", - "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", - "requires": { - "caniuse-lite": "^1.0.30000984", - "electron-to-chromium": "^1.3.191", - "node-releases": "^1.1.25" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "builtin-modules": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" - }, - "caniuse-lite": { - "version": "1.0.30000989", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", - "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" - }, - "common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" - }, - "core-js-compat": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz", - "integrity": "sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A==", - "requires": { - "browserslist": "^4.6.6", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "ejs": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.2.tgz", - "integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q==" - }, - "electron-to-chromium": { - "version": "1.3.236", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.236.tgz", - "integrity": "sha512-LWOvuJ80pLO3FtFqTcGuXB0dxdMtzSCkRmbXdY5mHUvXRQGor3sTVmyfU70aD2yF5i+fbHz52ncWr5T3xUYHlA==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", - "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==" - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=" - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" - }, - "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "requires": { - "minimist": "^1.2.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "magic-string": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", - "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node-releases": { - "version": "1.1.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.27.tgz", - "integrity": "sha512-9iXUqHKSGo6ph/tdXVbHFbhRVQln4ZDTIBJCzsa90HimnBYc5jw8RWYt4wBYFHehGyC3koIz5O4mb2fHrbPOuA==", - "requires": { - "semver": "^5.3.0" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "pretty-bytes": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", - "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==" - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" - }, - "regenerate-unicode-properties": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", - "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", - "requires": { - "regenerate": "^1.4.0" - } - }, "regenerator-runtime": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" }, - "regenerator-transform": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", - "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", - "requires": { - "private": "^0.1.6" - } - }, - "regexp-tree": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.11.tgz", - "integrity": "sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg==" - }, - "regexpu-core": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.5.tgz", - "integrity": "sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ==", - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" - } - }, - "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==" - }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - } - } - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "rollup": { - "version": "1.19.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.19.4.tgz", - "integrity": "sha512-G24w409GNj7i/Yam2cQla6qV2k6Nug8bD2DZg9v63QX/cH/dEdbNJg8H4lUm5M1bRpPKRUC465Rm9H51JTKOfQ==", - "requires": { - "@types/estree": "0.0.39", - "@types/node": "^12.6.9", - "acorn": "^6.2.1" - } - }, - "rollup-plugin-babel": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.3.3.tgz", - "integrity": "sha512-tKzWOCmIJD/6aKNz0H1GMM+lW1q9KyFubbWzGiOG540zxPPifnEAHTZwjo0g991Y+DyOZcLqBgqOdqazYE5fkw==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "rollup-pluginutils": "^2.8.1" - } - }, - "rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "requires": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" - } - }, - "rollup-plugin-off-main-thread": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.1.0.tgz", - "integrity": "sha512-bt2ZkWyetvwWBYqunL/GBqmGaV3KuhEWFo4V/MSnyydBKqLLYDMtqhU//cVrEK7DUKhJkY0HmA1upwpIuFx6Xw==", - "requires": { - "ejs": "^2.6.1", - "magic-string": "^0.25.0" - } - }, - "rollup-plugin-replace": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz", - "integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==", - "requires": { - "magic-string": "^0.25.2", - "rollup-pluginutils": "^2.6.0" - } - }, - "rollup-plugin-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.1.1.tgz", - "integrity": "sha512-McIMCDEY8EU6Y839C09UopeRR56wXHGdvKKjlfiZG/GrP6wvZQ62u2ko/Xh1MNH2M9WDL+obAAHySljIZYCuPQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "jest-worker": "^24.6.0", - "rollup-pluginutils": "^2.8.1", - "serialize-javascript": "^1.7.0", - "terser": "^4.1.0" - } - }, - "rollup-pluginutils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz", - "integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==", - "requires": { - "estree-walker": "^0.6.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "serialize-javascript": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.8.0.tgz", - "integrity": "sha512-3tHgtF4OzDmeKYj6V9nSyceRS0UJ3C7VqyD2Yj28vC/z2j6jG5FmFGahOKMD9CrglxTm3tETr87jEypaYV8DUg==" - }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -1433,123 +32,10 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sourcemap-codec": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", - "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==" - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", - "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", - "requires": { - "babel-extract-comments": "^1.0.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=" - }, - "tempy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz", - "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==", - "requires": { - "temp-dir": "^1.0.0", - "type-fest": "^0.3.1", - "unique-string": "^1.0.0" - } - }, - "terser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.2.0.tgz", - "integrity": "sha512-6lPt7lZdZ/13icQJp8XasFOwZjFJkxFFIb/N1fhYEQNoNI3Ilo3KABZ9OocZvZoB39r6SiIk/0+v/bt8nZoSeA==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" - }, - "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==" - }, - "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" - }, - "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", - "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "upath": { "version": "1.1.2", @@ -1564,162 +50,6 @@ "source-list-map": "^2.0.0", "source-map": "~0.6.1" } - }, - "workbox-background-sync": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-5.0.0-alpha.2.tgz", - "integrity": "sha512-+3DglciT2ay/rFava6BT6aPPdyUwgEY1AjNiRJm9PEmfyR2FFojJislJ8SbFAAmaQN3XpoFV8u0cZngiOsITLw==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "workbox-broadcast-update": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-5.0.0-alpha.2.tgz", - "integrity": "sha512-ILHjsrd2ow1v3Kw2QsoiqLIf9vQRtAWI5iN+4gMu5yOjeaTUMN22hVDNh6fKNyITpmJdSdQQohrrySdN0TUSew==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "workbox-build": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-5.0.0-alpha.2.tgz", - "integrity": "sha512-jJCmH4399O8ZhSSegQatADTlAd2lvUDzEVaG29gRdktDoKxfUTe94pyhVuy0cE5hdhra7lt2dPtt7ke/uPcrNA==", - "requires": { - "@babel/core": "^7.5.5", - "@babel/preset-env": "^7.5.5", - "@babel/runtime": "^7.5.5", - "@hapi/joi": "^15.1.0", - "common-tags": "^1.8.0", - "fs-extra": "^8.1.0", - "glob": "^7.1.4", - "lodash.template": "^4.5.0", - "pretty-bytes": "^5.2.0", - "rollup": "^1.17.0", - "rollup-plugin-babel": "^4.3.3", - "rollup-plugin-node-resolve": "^5.2.0", - "rollup-plugin-off-main-thread": "^1.0.1", - "rollup-plugin-replace": "^2.2.0", - "rollup-plugin-terser": "^5.1.1", - "stringify-object": "^3.3.0", - "strip-comments": "^1.0.2", - "tempy": "^0.3.0", - "upath": "^1.1.2", - "workbox-background-sync": "^5.0.0-alpha.2", - "workbox-broadcast-update": "^5.0.0-alpha.2", - "workbox-cacheable-response": "^5.0.0-alpha.2", - "workbox-core": "^5.0.0-alpha.2", - "workbox-expiration": "^5.0.0-alpha.2", - "workbox-google-analytics": "^5.0.0-alpha.2", - "workbox-navigation-preload": "^5.0.0-alpha.2", - "workbox-precaching": "^5.0.0-alpha.2", - "workbox-range-requests": "^5.0.0-alpha.2", - "workbox-routing": "^5.0.0-alpha.2", - "workbox-strategies": "^5.0.0-alpha.2", - "workbox-streams": "^5.0.0-alpha.2", - "workbox-sw": "^5.0.0-alpha.2", - "workbox-window": "^5.0.0-alpha.2" - } - }, - "workbox-cacheable-response": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-5.0.0-alpha.2.tgz", - "integrity": "sha512-wUQt/T8oIytUM/L9avjW17ETVfr+RJXon019kLhaftthn77FY2Kbwzn3635ep1wx4xS2qJOa3g3WWknFSTsSaQ==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "workbox-core": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-5.0.0-alpha.2.tgz", - "integrity": "sha512-7fRXPaBbtG/YERZYA2FFF3Z3823cak/QAiRlxIwJ/tEV4YFaUibgmSb+lmsabnrLYKNfDyxaXr+NpvFhKU8XfQ==" - }, - "workbox-expiration": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-5.0.0-alpha.2.tgz", - "integrity": "sha512-mQr38O5Q6OV+23XeE042oju66xlVrWCGph0eSj8y3+KGz6zY/GtjrFpHXTnKhi/Ebn8q6vNxLqe0RZS0BhX/cQ==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "workbox-google-analytics": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-5.0.0-alpha.2.tgz", - "integrity": "sha512-38B5jc3d19eD5X9LtyKvuFCLvzh2yVrDUZiaCNH4k1RO9SfUpdqh2WFyeXlDA5nedhB7xN8MqKpgqE2mZNzK0w==", - "requires": { - "workbox-background-sync": "^5.0.0-alpha.2", - "workbox-core": "^5.0.0-alpha.2", - "workbox-routing": "^5.0.0-alpha.2", - "workbox-strategies": "^5.0.0-alpha.2" - } - }, - "workbox-navigation-preload": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-5.0.0-alpha.2.tgz", - "integrity": "sha512-FqGaPKSBLWfK4W5wpae9GX0pjTpOQSSy9Gj8M10VlgvTsALjYfdn/CnCnTc4eTKRlbxuhGbm09fsNM3Ixke24Q==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "workbox-precaching": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-5.0.0-alpha.2.tgz", - "integrity": "sha512-Ok3bt8MjbmcrDoCZFg+FKrwsKoV9/fU4D47/4DRpOftzUH9H23zdED4eV+PnBW2qMHfON2aI0E0Y0E3wGqKv0g==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "workbox-range-requests": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-5.0.0-alpha.2.tgz", - "integrity": "sha512-HaVAwGMDgHuS7qdrgoMqN9t+wM9BqLglOcaDlwvyhHcLiNHyLfIUz7QitNX9j/tKAVx4o1y6RCOiXmvaXuMFDQ==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "workbox-routing": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-5.0.0-alpha.2.tgz", - "integrity": "sha512-2NZlUzKplHpQHPCmbRH8Q03RvT3BNyl7ITHU/Uf7O4ZkLSwiqOihvK3xP8bZablHzc/BPQ4z2UX0qRxZAUt1Lw==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "workbox-strategies": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-5.0.0-alpha.2.tgz", - "integrity": "sha512-AXXKC9GqBdIMrBCGaqUIMM7X+vvpMI48c+xKuUM2piV9aNtGjFFa2UnZbVQzRz7r5jqhPR+WN4/FhkgV9sZltA==", - "requires": { - "workbox-core": "^5.0.0-alpha.2", - "workbox-routing": "^5.0.0-alpha.2" - } - }, - "workbox-streams": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-5.0.0-alpha.2.tgz", - "integrity": "sha512-uFxmASx8wXov0dIXP8CbjG242NyJIvbc2+qOpN4EQ8KqrtLcUH+Bh6lC9Hvp7ZNlj4qo0ICySRWYZUxl5AlX4w==", - "requires": { - "workbox-core": "^5.0.0-alpha.2", - "workbox-routing": "^5.0.0-alpha.2" - } - }, - "workbox-sw": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-5.0.0-alpha.2.tgz", - "integrity": "sha512-SHuD8CZnKZ+LJd9/B2NzERd35s5qGGjf+PxT9b6nIzEdSlybFXC7YkCmapytU6imFBcEStJrD5HRy2SfcHpEKQ==" - }, - "workbox-window": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-5.0.0-alpha.2.tgz", - "integrity": "sha512-iGGjjKnBN1b2qKAlErImatei1sBKSPBdPRuPfbmEIBb8I7jT5hJTiYyuwrtsBqZVDsdYAU4FkrQGmXjGG+kv5w==", - "requires": { - "workbox-core": "^5.0.0-alpha.2" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" } } } diff --git a/packages/workbox-webpack-plugin/package.json b/packages/workbox-webpack-plugin/package.json index ca45250d1..94cb586ea 100644 --- a/packages/workbox-webpack-plugin/package.json +++ b/packages/workbox-webpack-plugin/package.json @@ -30,6 +30,7 @@ "dependencies": { "@babel/runtime": "^7.5.5", "fast-json-stable-stringify": "^2.0.0", + "source-map-url": "^0.4.0", "upath": "^1.1.2", "webpack-sources": "^1.3.0", "workbox-build": "^5.0.0-beta.0" diff --git a/packages/workbox-webpack-plugin/src/inject-manifest.js b/packages/workbox-webpack-plugin/src/inject-manifest.js index 8060383b9..1817ac5f1 100644 --- a/packages/workbox-webpack-plugin/src/inject-manifest.js +++ b/packages/workbox-webpack-plugin/src/inject-manifest.js @@ -6,8 +6,12 @@ https://opensource.org/licenses/MIT. */ -const {ConcatSource} = require('webpack-sources'); +const {RawSource} = require('webpack-sources'); const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); +const replaceAndUpdateSourceMap = require( + 'workbox-build/build/lib/replace-and-update-source-map'); +const sourceMapURL = require('source-map-url'); +const stringify = require('fast-json-stable-stringify'); const upath = require('upath'); const validate = require('workbox-build/build/lib/validate-options'); const webpackInjectManifestSchema = require( @@ -16,7 +20,6 @@ const webpackInjectManifestSchema = require( const getManifestEntriesFromCompilation = require('./lib/get-manifest-entries-from-compilation'); const relativeToOutputPath = require('./lib/relative-to-output-path'); -const stringifyManifest = require('./lib/stringify-manifest'); // Used to keep track of swDest files written by *any* instance of this plugin. // See https://github.com/GoogleChrome/workbox/issues/2181 @@ -150,16 +153,53 @@ class InjectManifest { compilation.fileDependencies.add(absoluteSwSrc); const swAsset = compilation.assets[config.swDest]; - delete compilation.assets[config.swDest]; + const initialSWAssetString = swAsset.source(); + if (!initialSWAssetString.includes(config.injectionPoint)) { + throw new Error(`Can't find ${config.injectionPoint} in your SW source.`); + } const manifestEntries = await getManifestEntriesFromCompilation( compilation, config); - const manifestDeclaration = stringifyManifest(manifestEntries, - config.injectionPoint, config.mode !== 'production'); + const manifestString = stringify(manifestEntries); + + const url = sourceMapURL.getFrom(initialSWAssetString); + // If our bundled swDest file contains a sourcemap, we would invalidate that + // mapping if we just replaced injectionPoint with the stringified manifest. + // Instead, we need to update the swDest contents as well as the sourcemap + // at the same time. + // See https://github.com/GoogleChrome/workbox/issues/2235 + if (url) { + // Translate the relative URL to what the presumed name for the webpack + // asset should be. + // TODO: Is there an "official" mapping maintained by webpack of assets to + // the name of their generated sourcemap? + const swAssetDirname = upath.dirname(config.swDest); + const sourcemapURLAssetName = upath.normalize( + upath.join(swAssetDirname, url)); + + const existingSourcemapAsset = compilation.assets[sourcemapURLAssetName]; + + if (!existingSourcemapAsset) { + throw new Error(`Can't find ${sourcemapURLAssetName} in assets.`); + } + + const {source, map} = await replaceAndUpdateSourceMap({ + jsFilename: config.swDest, + originalMap: JSON.parse(existingSourcemapAsset.source()), + originalSource: initialSWAssetString, + replaceString: manifestString, + searchString: config.injectionPoint, + }); - compilation.assets[config.swDest] = new ConcatSource( - manifestDeclaration, swAsset || ''); + compilation.assets[sourcemapURLAssetName] = new RawSource(map); + compilation.assets[config.swDest] = new RawSource(source); + } else { + // If there's no sourcemap associated with swDest, a simple string + // replacement will suffice. + compilation.assets[config.swDest] = new RawSource( + initialSWAssetString.replace(config.injectionPoint, manifestString)); + } } } diff --git a/packages/workbox-webpack-plugin/src/lib/stringify-manifest.js b/packages/workbox-webpack-plugin/src/lib/stringify-manifest.js deleted file mode 100644 index 98caeccfa..000000000 --- a/packages/workbox-webpack-plugin/src/lib/stringify-manifest.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - Copyright 2018 Google LLC - - Use of this source code is governed by an MIT-style - license that can be found in the LICENSE file or at - https://opensource.org/licenses/MIT. -*/ - -const stringify = require('fast-json-stable-stringify'); - -module.exports = (manifestEntries, injectionPoint, prettyPrint) => { - // stringify ensures that we get a consistent output, with all - // the properties of each object sorted. - // There's a hash created of the serialized JSON data, and we want the hash to - // be the same if the data is the same, without any sort-order variation. - const entriesJson = stringify( - manifestEntries, - prettyPrint ? {space: 2} : {} - ); - return `${injectionPoint} = ${entriesJson};`; -}; diff --git a/test/workbox-build/node/inject-manifest.js b/test/workbox-build/node/inject-manifest.js index c372eb176..2099a4584 100644 --- a/test/workbox-build/node/inject-manifest.js +++ b/test/workbox-build/node/inject-manifest.js @@ -371,6 +371,32 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function() { }); }); + describe(`[workbox-webpack-plugin] Sourcemap manipulation`, function() { + it(`should update the sourcemap to account for manifest injection`, async function() { + const outputDir = tempy.directory(); + const swSrc = upath.join(SW_SRC_DIR, 'basic-with-sourcemap.js.nolint'); + const swDest = upath.join(outputDir, 'basic-with-sourcemap.js'); + const sourcemapDest = upath.join(outputDir, 'basic-with-sourcemap.js.map'); + const options = Object.assign({}, BASE_OPTIONS, { + swDest, + swSrc, + }); + + const {count, filePaths, size, warnings} = await injectManifest(options); + expect(warnings).to.be.empty; + expect(count).to.eql(6); + expect(size).to.eql(2604); + expect(filePaths).to.have.members([swDest, sourcemapDest]); + + const actualSourcemap = await fse.readJSON(sourcemapDest); + const expectedSourcemap = await fse.readJSON( + upath.join(SW_SRC_DIR, '..', 'expected-source-map.js.map')); + expect(actualSourcemap).to.eql(expectedSourcemap); + + // We can't validate the SW file contents. + }); + }); + describe(`[workbox-build] removed options`, function() { // These were deprecated in v4, and formally removed in v5. const oldOptionsToValue = { diff --git a/test/workbox-build/node/lib/replace-and-update-source-map.js b/test/workbox-build/node/lib/replace-and-update-source-map.js new file mode 100644 index 000000000..9247e17aa --- /dev/null +++ b/test/workbox-build/node/lib/replace-and-update-source-map.js @@ -0,0 +1,59 @@ +/* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. +*/ + +const expect = require('chai').expect; + +const replaceAndUpdateSourceMap = require('../../../../packages/workbox-build/src/lib/replace-and-update-source-map'); + +describe(`[workbox-build] lib/replace-and-update-source-map`, function() { + // Test case borrowed from https://github.com/Rich-Harris/magic-string/blob/a312519cfe9caa78ade7f09cc2b07459d3d17f4d/test/MagicString.js#L225 + const JS_FILENAME = 'file.js'; + const SOURCE = `abcdefkl`; + const SOURCE_MAP = { + file: JS_FILENAME, + mappings: 'AAAA,GAAG,GAAG,AAAG,CAAC', + names: ['testing'], + sourceRoot: '.', + sources: ['test.js'], + sourcesContent: ['abcdefghijkl'], + version: 3, + }; + + it(`should be a no-op if there's no match`, async function() { + const {map, source} = await replaceAndUpdateSourceMap({ + jsFilename: JS_FILENAME, + originalSource: SOURCE, + originalMap: SOURCE_MAP, + searchString: 'is-not-found', + replaceString: 'ignored', + }); + + expect(JSON.parse(map)).to.eql(SOURCE_MAP); + expect(source).to.eql(SOURCE); + }); + + it(`should be perform the replacement and update the sourcemap when there is a match`, async function() { + const searchString = 'bc'; + const replaceString = 'wxyz'; + + const {map, source} = await replaceAndUpdateSourceMap({ + searchString, + replaceString, + jsFilename: JS_FILENAME, + originalSource: SOURCE, + originalMap: SOURCE_MAP, + }); + + const expectedSourceMap = Object.assign({}, SOURCE_MAP, { + mappings: 'AAAA,KAAG,GAAG,AAAG,CAAC', + }); + + expect(JSON.parse(map)).to.eql(expectedSourceMap); + expect(source).to.eql('awxyzdefkl'); + }); +}); diff --git a/test/workbox-build/static/expected-source-map.js.map b/test/workbox-build/static/expected-source-map.js.map new file mode 100644 index 000000000..58a537517 --- /dev/null +++ b/test/workbox-build/static/expected-source-map.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../node_modules/workbox-core/_version.js","../node_modules/workbox-core/_private/logger.js","../node_modules/workbox-core/models/messages/messageGenerator.js","../node_modules/workbox-core/_private/WorkboxError.js","../node_modules/workbox-core/_private/assert.js","../node_modules/workbox-core/_private/cacheNames.js","../node_modules/workbox-core/_private/getFriendlyURL.js","../node_modules/workbox-core/models/quotaErrorCallbacks.js","../node_modules/workbox-core/utils/pluginUtils.js","../node_modules/workbox-core/_private/cacheWrapper.js","../node_modules/workbox-core/_private/executeQuotaErrorCallbacks.js","../node_modules/workbox-core/_private/fetchWrapper.js","../node_modules/workbox-strategies/_version.js","../node_modules/workbox-core/_private/canConstructResponseFromBodyStream.js","../node_modules/workbox-core/_private/DBWrapper.js","../node_modules/workbox-core/copyResponse.js","../node_modules/workbox-precaching/_version.js","../node_modules/workbox-precaching/utils/precachePlugins.js","../node_modules/workbox-precaching/utils/createCacheKey.js","../node_modules/workbox-precaching/PrecacheController.js","../node_modules/workbox-precaching/utils/getOrCreatePrecacheController.js","../node_modules/workbox-precaching/utils/getCacheKeyForURL.js","../node_modules/workbox-precaching/utils/generateURLVariations.js","../node_modules/workbox-precaching/utils/removeIgnoredSearchParams.js","../node_modules/workbox-precaching/addRoute.js","../node_modules/workbox-precaching/utils/addFetchListener.js","../node_modules/workbox-precaching/precache.js","../node_modules/workbox-range-requests/_version.js","../node_modules/workbox-range-requests/createPartialResponse.js","../node_modules/workbox-range-requests/utils/parseRangeHeader.js","../node_modules/workbox-range-requests/utils/calculateEffectiveBoundaries.js","../node_modules/workbox-routing/_version.js","../node_modules/workbox-routing/utils/constants.js","../node_modules/workbox-routing/utils/normalizeHandler.js","../node_modules/workbox-routing/Route.js","../node_modules/workbox-routing/RegExpRoute.js","../node_modules/workbox-routing/Router.js","../node_modules/workbox-routing/utils/getOrCreateDefaultRouter.js","../node_modules/workbox-routing/registerRoute.js","../src/js/constants.js","../src/js/getCachedMediaMetadata.js","../src/svelte/routes/Audio.svelte","../src/svelte/routes/Images.svelte","../src/svelte/routes/Videos.svelte","../src/js/service-worker.js","../node_modules/workbox-strategies/CacheOnly.js","../node_modules/workbox-range-requests/RangeRequestsPlugin.js","../node_modules/workbox-precaching/precacheAndRoute.js","../node_modules/workbox-core/skipWaiting.js","../node_modules/workbox-core/clientsClaim.js"],"names":["self","_","e","messageGenerator","code","args","msg","length","JSON","stringify","WorkboxError","Error","[object Object]","errorCode","details","super","this","name","_cacheNameDetails","googleAnalytics","precache","prefix","runtime","suffix","registration","scope","_createCacheName","cacheName","filter","value","join","cacheNames","updateDetails","fn","key","Object","keys","eachCacheNameDetail","getGoogleAnalyticsName","userCacheName","getPrecacheName","getPrefix","getRuntimeName","getSuffix","getFriendlyURL","url","urlObj","URL","String","location","href","origin","pathname","quotaErrorCallbacks","Set","pluginUtils","plugins","callbackName","plugin","matchWrapper","async","request","event","matchOptions","cache","caches","open","effectiveRequest","_getEffectiveRequest","mode","cachedResponse","match","pluginMethod","call","_isResponseSafeToCache","response","responseToCache","pluginsUsed","status","undefined","cacheKeyWillBeUsedPlugins","Request","cacheWrapper","put","updatePlugins","oldResponse","error","callback","executeQuotaErrorCallbacks","newResponse","fetchWrapper","fetch","fetchOptions","FetchEvent","preloadResponse","possiblePreloadResponse","failedFetchPlugins","originalRequest","clone","requestClone","err","thrownError","pluginFilteredRequest","fetchResponse","supportStatus","DBWrapper","version","onupgradeneeded","onversionchange","_db","_name","_version","_onupgradeneeded","_onversionchange","close","db","Promise","resolve","reject","openRequestTimedOut","setTimeout","OPEN_TIMEOUT","openRequest","indexedDB","onerror","evt","transaction","abort","result","onsuccess","bind","storeName","query","getAllKeys","count","getAllMatching","includeKeys","map","entry","index","direction","txn","done","store","objectStore","target","results","openCursor","cursor","push","continue","storeNames","type","onabort","oncomplete","method","objStore","apply","prototype","methodsToWrap","readonly","readwrite","methods","entries","IDBObjectStore","_call","copyResponse","modifier","clonedResponse","responseInit","headers","Headers","statusText","modifiedResponseInit","body","testResponse","Response","canConstructResponseFromBodyStream","blob","precachePlugins","get","newPlugins","REVISION_SEARCH_PARAM","createCacheKey","urlObject","cacheKey","revision","cacheKeyURL","originalURL","searchParams","set","PrecacheController","_cacheName","_urlsToCacheKeys","Map","_cacheKeysToIntegrities","has","firstEntry","secondEntry","integrity","toBePrecached","alreadyPrecached","alreadyCachedRequests","existingCacheKeys","precacheRequests","_addURLToCache","all","updatedURLs","item","notUpdatedURLs","currentlyCachedRequests","expectedCacheKeys","values","deletedURLs","delete","credentials","cacheWillUpdatePlugin","cacheWillUpdate","redirected","ignoreSearch","getCacheKeyForURL","precacheController","getOrCreatePrecacheController","options","urlsToCacheKeys","getURLsToCacheKeys","possibleURL","ignoreURLParametersMatching","directoryIndex","cleanURLs","urlManipulation","hash","urlWithoutIgnoredParams","paramName","some","regExp","test","removeIgnoredSearchParams","endsWith","directoryURL","cleanURL","additionalURLs","urlToAttempt","generateURLVariations","possibleCacheKey","listenerAdded","addRoute","addEventListener","precachedURL","responsePromise","then","respondWith","addFetchListener","installListener","waitUntil","install","catch","activateListener","activate","createPartialResponse","originalResponse","rangeHeader","boundaries","normalizedRangeHeader","trim","toLowerCase","startsWith","includes","rangeParts","exec","start","Number","end","parseRangeHeader","originalBlob","effectiveBoundaries","blobSize","size","effectiveStart","effectiveEnd","calculateEffectiveBoundaries","slicedBlob","slice","slicedBlobSize","slicedResponse","defaultMethod","normalizeHandler","handler","handle","Route","RegExpRoute","Router","_routes","routes","handleRequest","data","payload","requestPromises","urlsToCache","ports","postMessage","protocol","params","route","findMatchingRoute","_defaultHandler","_catchHandler","matchResult","Array","isArray","constructor","routeIndex","indexOf","splice","defaultRouter","getOrCreateDefaultRouter","addCacheListener","registerRoute","capture","captureUrl","RegExp","moduleName","funcName","requests","reverse","contentType","src","_getCachedMediaMetadata","mimeRoute","mimePrefix","broadcastChannel","BroadcastChannel","cachedMediaHandler","_plugins","_matchOptions","cachedResponseWillBeUsed","skipWaiting","clients","claim","addToCacheList","__WB_MANIFEST","mediaFiles","formData","getAll","mediaFile","Date","now","content-length","content-type","routeToRedirectTo","audioRoute","imagesRoute","videosRoute","find","redirectionUrl","redirect"],"mappings":"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","file":"basic-with-sourcemap.js","sourcesContent":["// @ts-ignore\ntry {\n self['workbox:core:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst logger = (process.env.NODE_ENV === 'production' ? null : (() => {\n let inGroup = false;\n const methodToColorMap = {\n debug: `#7f8c8d`,\n log: `#2ecc71`,\n warn: `#f39c12`,\n error: `#c0392b`,\n groupCollapsed: `#3498db`,\n groupEnd: null,\n };\n const print = function (method, args) {\n if (method === 'groupCollapsed') {\n // Safari doesn't print all console.groupCollapsed() arguments:\n // https://bugs.webkit.org/show_bug.cgi?id=182754\n if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\n console[method](...args);\n return;\n }\n }\n const styles = [\n `background: ${methodToColorMap[method]}`,\n `border-radius: 0.5em`,\n `color: white`,\n `font-weight: bold`,\n `padding: 2px 0.5em`,\n ];\n // When in a group, the workbox prefix is not displayed.\n const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];\n console[method](...logPrefix, ...args);\n if (method === 'groupCollapsed') {\n inGroup = true;\n }\n if (method === 'groupEnd') {\n inGroup = false;\n }\n };\n const api = {};\n const loggerMethods = Object.keys(methodToColorMap);\n for (const key of loggerMethods) {\n const method = key;\n api[method] = (...args) => {\n print(method, args);\n };\n }\n return api;\n})());\nexport { logger };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messages } from './messages.js';\nimport '../../_version.js';\nconst fallback = (code, ...args) => {\n let msg = code;\n if (args.length > 0) {\n msg += ` :: ${JSON.stringify(args)}`;\n }\n return msg;\n};\nconst generatorFunction = (code, details = {}) => {\n const message = messages[code];\n if (!message) {\n throw new Error(`Unable to find message for code '${code}'.`);\n }\n return message(details);\n};\nexport const messageGenerator = (process.env.NODE_ENV === 'production') ?\n fallback : generatorFunction;\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messageGenerator } from '../models/messages/messageGenerator.js';\nimport '../_version.js';\n/**\n * Workbox errors should be thrown with this class.\n * This allows use to ensure the type easily in tests,\n * helps developers identify errors from workbox\n * easily and allows use to optimise error\n * messages correctly.\n *\n * @private\n */\nclass WorkboxError extends Error {\n /**\n *\n * @param {string} errorCode The error code that\n * identifies this particular error.\n * @param {Object=} details Any relevant arguments\n * that will help developers identify issues should\n * be added as a key on the context object.\n */\n constructor(errorCode, details) {\n let message = messageGenerator(errorCode, details);\n super(message);\n this.name = errorCode;\n this.details = details;\n }\n}\nexport { WorkboxError };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from '../_private/WorkboxError.js';\nimport '../_version.js';\n/*\n * This method returns true if the current context is a service worker.\n */\nconst isSWEnv = (moduleName) => {\n if (!('ServiceWorkerGlobalScope' in self)) {\n throw new WorkboxError('not-in-sw', { moduleName });\n }\n};\n/*\n * This method throws if the supplied value is not an array.\n * The destructed values are required to produce a meaningful error for users.\n * The destructed and restructured object is so it's clear what is\n * needed.\n */\nconst isArray = (value, details) => {\n if (!Array.isArray(value)) {\n throw new WorkboxError('not-an-array', details);\n }\n};\nconst hasMethod = (object, expectedMethod, details) => {\n const type = typeof object[expectedMethod];\n if (type !== 'function') {\n details.expectedMethod = expectedMethod;\n throw new WorkboxError('missing-a-method', details);\n }\n};\nconst isType = (object, expectedType, details) => {\n if (typeof object !== expectedType) {\n details.expectedType = expectedType;\n throw new WorkboxError('incorrect-type', details);\n }\n};\nconst isInstance = (object, expectedClass, details) => {\n if (!(object instanceof expectedClass)) {\n details.expectedClass = expectedClass;\n throw new WorkboxError('incorrect-class', details);\n }\n};\nconst isOneOf = (value, validValues, details) => {\n if (!validValues.includes(value)) {\n details.validValueDescription =\n `Valid values are ${JSON.stringify(validValues)}.`;\n throw new WorkboxError('invalid-value', details);\n }\n};\nconst isArrayOfClass = (value, expectedClass, details) => {\n const error = new WorkboxError('not-array-of-class', details);\n if (!Array.isArray(value)) {\n throw error;\n }\n for (let item of value) {\n if (!(item instanceof expectedClass)) {\n throw error;\n }\n }\n};\nconst finalAssertExports = process.env.NODE_ENV === 'production' ? null : {\n hasMethod,\n isArray,\n isInstance,\n isOneOf,\n isSWEnv,\n isType,\n isArrayOfClass,\n};\nexport { finalAssertExports as assert };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst _cacheNameDetails = {\n googleAnalytics: 'googleAnalytics',\n precache: 'precache-v2',\n prefix: 'workbox',\n runtime: 'runtime',\n suffix: registration.scope,\n};\nconst _createCacheName = (cacheName) => {\n return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix]\n .filter((value) => value && value.length > 0)\n .join('-');\n};\nconst eachCacheNameDetail = (fn) => {\n for (const key of Object.keys(_cacheNameDetails)) {\n fn(key);\n }\n};\nexport const cacheNames = {\n updateDetails: (details) => {\n eachCacheNameDetail((key) => {\n if (typeof details[key] === 'string') {\n _cacheNameDetails[key] = details[key];\n }\n });\n },\n getGoogleAnalyticsName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);\n },\n getPrecacheName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.precache);\n },\n getPrefix: () => {\n return _cacheNameDetails.prefix;\n },\n getRuntimeName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.runtime);\n },\n getSuffix: () => {\n return _cacheNameDetails.suffix;\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst getFriendlyURL = (url) => {\n const urlObj = new URL(String(url), location.href);\n if (urlObj.origin === location.origin) {\n return urlObj.pathname;\n }\n return urlObj.href;\n};\nexport { getFriendlyURL };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n// Callbacks to be executed whenever there's a quota error.\nconst quotaErrorCallbacks = new Set();\nexport { quotaErrorCallbacks };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nexport const pluginUtils = {\n filter: (plugins, callbackName) => {\n return plugins.filter((plugin) => callbackName in plugin);\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from './WorkboxError.js';\nimport { assert } from './assert.js';\nimport { getFriendlyURL } from './getFriendlyURL.js';\nimport { logger } from './logger.js';\nimport { executeQuotaErrorCallbacks } from './executeQuotaErrorCallbacks.js';\nimport { pluginUtils } from '../utils/pluginUtils.js';\nimport '../_version.js';\n/**\n * Wrapper around cache.put().\n *\n * Will call `cacheDidUpdate` on plugins if the cache was updated, using\n * `matchOptions` when determining what the old entry is.\n *\n * @param {Object} options\n * @param {string} options.cacheName\n * @param {Request} options.request\n * @param {Response} options.response\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @param {Object} [options.matchOptions]\n *\n * @private\n * @memberof module:workbox-core\n */\nconst putWrapper = async ({ cacheName, request, response, event, plugins = [], matchOptions, }) => {\n if (process.env.NODE_ENV !== 'production') {\n if (request.method && request.method !== 'GET') {\n throw new WorkboxError('attempt-to-cache-non-get-request', {\n url: getFriendlyURL(request.url),\n method: request.method,\n });\n }\n }\n const effectiveRequest = await _getEffectiveRequest({\n plugins, request, mode: 'write'\n });\n if (!response) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Cannot cache non-existent response for ` +\n `'${getFriendlyURL(effectiveRequest.url)}'.`);\n }\n throw new WorkboxError('cache-put-with-no-response', {\n url: getFriendlyURL(effectiveRequest.url),\n });\n }\n let responseToCache = await _isResponseSafeToCache({\n event,\n plugins,\n response,\n request: effectiveRequest,\n });\n if (!responseToCache) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' will ` +\n `not be cached.`, responseToCache);\n }\n return;\n }\n const cache = await caches.open(cacheName);\n const updatePlugins = pluginUtils.filter(plugins, \"cacheDidUpdate\" /* CACHE_DID_UPDATE */);\n let oldResponse = updatePlugins.length > 0 ?\n await matchWrapper({ cacheName, matchOptions, request: effectiveRequest }) :\n null;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Updating the '${cacheName}' cache with a new Response for ` +\n `${getFriendlyURL(effectiveRequest.url)}.`);\n }\n try {\n await cache.put(effectiveRequest, responseToCache);\n }\n catch (error) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError\n if (error.name === 'QuotaExceededError') {\n await executeQuotaErrorCallbacks();\n }\n throw error;\n }\n for (let plugin of updatePlugins) {\n await plugin[\"cacheDidUpdate\" /* CACHE_DID_UPDATE */].call(plugin, {\n cacheName,\n event,\n oldResponse,\n newResponse: responseToCache,\n request: effectiveRequest,\n });\n }\n};\n/**\n * This is a wrapper around cache.match().\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache to match against.\n * @param {Request} options.request The Request that will be used to look up\n * cache entries.\n * @param {Event} [options.event] The event that propted the action.\n * @param {Object} [options.matchOptions] Options passed to cache.match().\n * @param {Array} [options.plugins=[]] Array of plugins.\n * @return {Response} A cached response if available.\n *\n * @private\n * @memberof module:workbox-core\n */\nconst matchWrapper = async ({ cacheName, request, event, matchOptions, plugins = [], }) => {\n const cache = await caches.open(cacheName);\n const effectiveRequest = await _getEffectiveRequest({\n plugins, request, mode: 'read'\n });\n let cachedResponse = await cache.match(effectiveRequest, matchOptions);\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n logger.debug(`Found a cached response in '${cacheName}'.`);\n }\n else {\n logger.debug(`No cached response found in '${cacheName}'.`);\n }\n }\n for (const plugin of plugins) {\n if (\"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */ in plugin) {\n const pluginMethod = plugin[\"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */];\n cachedResponse = await pluginMethod.call(plugin, {\n cacheName,\n event,\n matchOptions,\n cachedResponse,\n request: effectiveRequest,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n assert.isInstance(cachedResponse, Response, {\n moduleName: 'Plugin',\n funcName: \"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n return cachedResponse;\n};\n/**\n * This method will call cacheWillUpdate on the available plugins (or use\n * status === 200) to determine if the Response is safe and valid to cache.\n *\n * @param {Object} options\n * @param {Request} options.request\n * @param {Response} options.response\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst _isResponseSafeToCache = async ({ request, response, event, plugins = [], }) => {\n let responseToCache = response;\n let pluginsUsed = false;\n for (let plugin of plugins) {\n if (\"cacheWillUpdate\" /* CACHE_WILL_UPDATE */ in plugin) {\n pluginsUsed = true;\n const pluginMethod = plugin[\"cacheWillUpdate\" /* CACHE_WILL_UPDATE */];\n responseToCache = await pluginMethod.call(plugin, {\n request,\n response: responseToCache,\n event,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n assert.isInstance(responseToCache, Response, {\n moduleName: 'Plugin',\n funcName: \"cacheWillUpdate\" /* CACHE_WILL_UPDATE */,\n isReturnValueProblem: true,\n });\n }\n }\n if (!responseToCache) {\n break;\n }\n }\n }\n if (!pluginsUsed) {\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n if (responseToCache.status !== 200) {\n if (responseToCache.status === 0) {\n logger.warn(`The response for '${request.url}' is an opaque ` +\n `response. The caching strategy that you're using will not ` +\n `cache opaque responses by default.`);\n }\n else {\n logger.debug(`The response for '${request.url}' returned ` +\n `a status code of '${response.status}' and won't be cached as a ` +\n `result.`);\n }\n }\n }\n }\n responseToCache = responseToCache && responseToCache.status === 200 ?\n responseToCache : undefined;\n }\n return responseToCache ? responseToCache : null;\n};\n/**\n * Checks the list of plugins for the cacheKeyWillBeUsed callback, and\n * executes any of those callbacks found in sequence. The final `Request` object\n * returned by the last plugin is treated as the cache key for cache reads\n * and/or writes.\n *\n * @param {Object} options\n * @param {Request} options.request\n * @param {string} options.mode\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst _getEffectiveRequest = async ({ request, mode, plugins = [], }) => {\n const cacheKeyWillBeUsedPlugins = pluginUtils.filter(plugins, \"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */);\n let effectiveRequest = request;\n for (const plugin of cacheKeyWillBeUsedPlugins) {\n effectiveRequest = await plugin[\"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */].call(plugin, { mode, request: effectiveRequest });\n if (typeof effectiveRequest === 'string') {\n effectiveRequest = new Request(effectiveRequest);\n }\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(effectiveRequest, Request, {\n moduleName: 'Plugin',\n funcName: \"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n return effectiveRequest;\n};\nexport const cacheWrapper = {\n put: putWrapper,\n match: matchWrapper,\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from '../_private/logger.js';\nimport { quotaErrorCallbacks } from '../models/quotaErrorCallbacks.js';\nimport '../_version.js';\n/**\n * Runs all of the callback functions, one at a time sequentially, in the order\n * in which they were registered.\n *\n * @memberof workbox.core\n * @private\n */\nasync function executeQuotaErrorCallbacks() {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`About to run ${quotaErrorCallbacks.size} ` +\n `callbacks to clean up caches.`);\n }\n for (const callback of quotaErrorCallbacks) {\n await callback();\n if (process.env.NODE_ENV !== 'production') {\n logger.log(callback, 'is complete.');\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log('Finished running callbacks.');\n }\n}\nexport { executeQuotaErrorCallbacks };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from './WorkboxError.js';\nimport { logger } from './logger.js';\nimport { assert } from './assert.js';\nimport { getFriendlyURL } from '../_private/getFriendlyURL.js';\nimport { pluginUtils } from '../utils/pluginUtils.js';\nimport '../_version.js';\n/**\n * Wrapper around the fetch API.\n *\n * Will call requestWillFetch on available plugins.\n *\n * @param {Object} options\n * @param {Request|string} options.request\n * @param {Object} [options.fetchOptions]\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst wrappedFetch = async ({ request, fetchOptions, event, plugins = [], }) => {\n if (typeof request === 'string') {\n request = new Request(request);\n }\n // We *should* be able to call `await event.preloadResponse` even if it's\n // undefined, but for some reason, doing so leads to errors in our Node unit\n // tests. To work around that, explicitly check preloadResponse's value first.\n if (event instanceof FetchEvent && event.preloadResponse) {\n const possiblePreloadResponse = await event.preloadResponse;\n if (possiblePreloadResponse) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Using a preloaded navigation response for ` +\n `'${getFriendlyURL(request.url)}'`);\n }\n return possiblePreloadResponse;\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n paramName: 'request',\n expectedClass: Request,\n moduleName: 'workbox-core',\n className: 'fetchWrapper',\n funcName: 'wrappedFetch',\n });\n }\n const failedFetchPlugins = pluginUtils.filter(plugins, \"fetchDidFail\" /* FETCH_DID_FAIL */);\n // If there is a fetchDidFail plugin, we need to save a clone of the\n // original request before it's either modified by a requestWillFetch\n // plugin or before the original request's body is consumed via fetch().\n const originalRequest = failedFetchPlugins.length > 0 ?\n request.clone() : null;\n try {\n for (let plugin of plugins) {\n if (\"requestWillFetch\" /* REQUEST_WILL_FETCH */ in plugin) {\n const pluginMethod = plugin[\"requestWillFetch\" /* REQUEST_WILL_FETCH */];\n const requestClone = request.clone();\n request = (await pluginMethod.call(plugin, {\n request: requestClone,\n event,\n }));\n if (process.env.NODE_ENV !== 'production') {\n if (request) {\n assert.isInstance(request, Request, {\n moduleName: 'Plugin',\n funcName: \"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n }\n catch (err) {\n throw new WorkboxError('plugin-error-request-will-fetch', {\n thrownError: err,\n });\n }\n // The request can be altered by plugins with `requestWillFetch` making\n // the original request (Most likely from a `fetch` event) to be different\n // to the Request we make. Pass both to `fetchDidFail` to aid debugging.\n let pluginFilteredRequest = request.clone();\n try {\n let fetchResponse;\n // See https://github.com/GoogleChrome/workbox/issues/1796\n if (request.mode === 'navigate') {\n fetchResponse = await fetch(request);\n }\n else {\n fetchResponse = await fetch(request, fetchOptions);\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Network request for ` +\n `'${getFriendlyURL(request.url)}' returned a response with ` +\n `status '${fetchResponse.status}'.`);\n }\n for (const plugin of plugins) {\n if (\"fetchDidSucceed\" /* FETCH_DID_SUCCEED */ in plugin) {\n fetchResponse = await plugin[\"fetchDidSucceed\" /* FETCH_DID_SUCCEED */]\n .call(plugin, {\n event,\n request: pluginFilteredRequest,\n response: fetchResponse,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (fetchResponse) {\n assert.isInstance(fetchResponse, Response, {\n moduleName: 'Plugin',\n funcName: \"fetchDidSucceed\" /* FETCH_DID_SUCCEED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n return fetchResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Network request for ` +\n `'${getFriendlyURL(request.url)}' threw an error.`, error);\n }\n for (const plugin of failedFetchPlugins) {\n await plugin[\"fetchDidFail\" /* FETCH_DID_FAIL */].call(plugin, {\n error,\n event,\n originalRequest: originalRequest.clone(),\n request: pluginFilteredRequest.clone(),\n });\n }\n throw error;\n }\n};\nconst fetchWrapper = {\n fetch: wrappedFetch,\n};\nexport { fetchWrapper };\n","// @ts-ignore\ntry {\n self['workbox:strategies:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nlet supportStatus;\n/**\n * A utility function that determines whether the current browser supports\n * constructing a new `Response` from a `response.body` stream.\n *\n * @return {boolean} `true`, if the current browser can successfully\n * construct a `Response` from a `response.body` stream, `false` otherwise.\n *\n * @private\n */\nfunction canConstructResponseFromBodyStream() {\n if (supportStatus === undefined) {\n const testResponse = new Response('');\n if ('body' in testResponse) {\n try {\n new Response(testResponse.body);\n supportStatus = true;\n }\n catch (error) {\n supportStatus = false;\n }\n }\n supportStatus = false;\n }\n return supportStatus;\n}\nexport { canConstructResponseFromBodyStream };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * A class that wraps common IndexedDB functionality in a promise-based API.\n * It exposes all the underlying power and functionality of IndexedDB, but\n * wraps the most commonly used features in a way that's much simpler to use.\n *\n * @private\n */\nexport class DBWrapper {\n /**\n * @param {string} name\n * @param {number} version\n * @param {Object=} [callback]\n * @param {!Function} [callbacks.onupgradeneeded]\n * @param {!Function} [callbacks.onversionchange] Defaults to\n * DBWrapper.prototype._onversionchange when not specified.\n * @private\n */\n constructor(name, version, { onupgradeneeded, onversionchange, } = {}) {\n this._db = null;\n this._name = name;\n this._version = version;\n this._onupgradeneeded = onupgradeneeded;\n this._onversionchange = onversionchange || (() => this.close());\n }\n /**\n * Returns the IDBDatabase instance (not normally needed).\n * @return {IDBDatabase|undefined}\n *\n * @private\n */\n get db() {\n return this._db;\n }\n /**\n * Opens a connected to an IDBDatabase, invokes any onupgradedneeded\n * callback, and added an onversionchange callback to the database.\n *\n * @return {IDBDatabase}\n * @private\n */\n async open() {\n if (this._db)\n return;\n this._db = await new Promise((resolve, reject) => {\n // This flag is flipped to true if the timeout callback runs prior\n // to the request failing or succeeding. Note: we use a timeout instead\n // of an onblocked handler since there are cases where onblocked will\n // never never run. A timeout better handles all possible scenarios:\n // https://github.com/w3c/IndexedDB/issues/223\n let openRequestTimedOut = false;\n setTimeout(() => {\n openRequestTimedOut = true;\n reject(new Error('The open request was blocked and timed out'));\n }, this.OPEN_TIMEOUT);\n const openRequest = indexedDB.open(this._name, this._version);\n openRequest.onerror = () => reject(openRequest.error);\n openRequest.onupgradeneeded = (evt) => {\n if (openRequestTimedOut) {\n openRequest.transaction.abort();\n openRequest.result.close();\n }\n else if (typeof this._onupgradeneeded === 'function') {\n this._onupgradeneeded(evt);\n }\n };\n openRequest.onsuccess = () => {\n const db = openRequest.result;\n if (openRequestTimedOut) {\n db.close();\n }\n else {\n db.onversionchange = this._onversionchange.bind(this);\n resolve(db);\n }\n };\n });\n return this;\n }\n /**\n * Polyfills the native `getKey()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @return {Array}\n * @private\n */\n async getKey(storeName, query) {\n return (await this.getAllKeys(storeName, query, 1))[0];\n }\n /**\n * Polyfills the native `getAll()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @param {number} count\n * @return {Array}\n * @private\n */\n async getAll(storeName, query, count) {\n return await this.getAllMatching(storeName, { query, count });\n }\n /**\n * Polyfills the native `getAllKeys()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @param {number} count\n * @return {Array}\n * @private\n */\n async getAllKeys(storeName, query, count) {\n const entries = await this.getAllMatching(storeName, { query, count, includeKeys: true });\n return entries.map((entry) => entry.key);\n }\n /**\n * Supports flexible lookup in an object store by specifying an index,\n * query, direction, and count. This method returns an array of objects\n * with the signature .\n *\n * @param {string} storeName\n * @param {Object} [opts]\n * @param {string} [opts.index] The index to use (if specified).\n * @param {*} [opts.query]\n * @param {IDBCursorDirection} [opts.direction]\n * @param {number} [opts.count] The max number of results to return.\n * @param {boolean} [opts.includeKeys] When true, the structure of the\n * returned objects is changed from an array of values to an array of\n * objects in the form {key, primaryKey, value}.\n * @return {Array}\n * @private\n */\n async getAllMatching(storeName, { index, query = null, // IE/Edge errors if query === `undefined`.\n direction = 'next', count, includeKeys = false, } = {}) {\n return await this.transaction([storeName], 'readonly', (txn, done) => {\n const store = txn.objectStore(storeName);\n const target = index ? store.index(index) : store;\n const results = [];\n const request = target.openCursor(query, direction);\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n results.push(includeKeys ? cursor : cursor.value);\n if (count && results.length >= count) {\n done(results);\n }\n else {\n cursor.continue();\n }\n }\n else {\n done(results);\n }\n };\n });\n }\n /**\n * Accepts a list of stores, a transaction type, and a callback and\n * performs a transaction. A promise is returned that resolves to whatever\n * value the callback chooses. The callback holds all the transaction logic\n * and is invoked with two arguments:\n * 1. The IDBTransaction object\n * 2. A `done` function, that's used to resolve the promise when\n * when the transaction is done, if passed a value, the promise is\n * resolved to that value.\n *\n * @param {Array} storeNames An array of object store names\n * involved in the transaction.\n * @param {string} type Can be `readonly` or `readwrite`.\n * @param {!Function} callback\n * @return {*} The result of the transaction ran by the callback.\n * @private\n */\n async transaction(storeNames, type, callback) {\n await this.open();\n return await new Promise((resolve, reject) => {\n const txn = this._db.transaction(storeNames, type);\n txn.onabort = () => reject(txn.error);\n txn.oncomplete = () => resolve();\n callback(txn, (value) => resolve(value));\n });\n }\n /**\n * Delegates async to a native IDBObjectStore method.\n *\n * @param {string} method The method name.\n * @param {string} storeName The object store name.\n * @param {string} type Can be `readonly` or `readwrite`.\n * @param {...*} args The list of args to pass to the native method.\n * @return {*} The result of the transaction.\n * @private\n */\n async _call(method, storeName, type, ...args) {\n const callback = (txn, done) => {\n const objStore = txn.objectStore(storeName);\n const request = objStore[method].apply(objStore, args);\n request.onsuccess = () => done(request.result);\n };\n return await this.transaction([storeName], type, callback);\n }\n /**\n * Closes the connection opened by `DBWrapper.open()`. Generally this method\n * doesn't need to be called since:\n * 1. It's usually better to keep a connection open since opening\n * a new connection is somewhat slow.\n * 2. Connections are automatically closed when the reference is\n * garbage collected.\n * The primary use case for needing to close a connection is when another\n * reference (typically in another tab) needs to upgrade it and would be\n * blocked by the current, open connection.\n *\n * @private\n */\n close() {\n if (this._db) {\n this._db.close();\n this._db = null;\n }\n }\n}\n// Exposed on the prototype to let users modify the default timeout on a\n// per-instance or global basis.\nDBWrapper.prototype.OPEN_TIMEOUT = 2000;\n// Wrap native IDBObjectStore methods according to their mode.\nconst methodsToWrap = {\n readonly: ['get', 'count', 'getKey', 'getAll', 'getAllKeys'],\n readwrite: ['add', 'put', 'clear', 'delete'],\n};\nfor (const [mode, methods] of Object.entries(methodsToWrap)) {\n for (const method of methods) {\n if (method in IDBObjectStore.prototype) {\n // Don't use arrow functions here since we're outside of the class.\n DBWrapper.prototype[method] =\n async function (storeName, ...args) {\n return await this._call(method, storeName, mode, ...args);\n };\n }\n }\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { canConstructResponseFromBodyStream } from './_private/canConstructResponseFromBodyStream.js';\nimport './_version.js';\n/**\n * Allows developers to copy a response and modify its `headers`, `status`,\n * or `statusText` values (the values settable via a\n * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax}\n * object in the constructor).\n * To modify these values, pass a function as the second argument. That\n * function will be invoked with a single object with the response properties\n * `{headers, status, statusText}`. The return value of this function will\n * be used as the `ResponseInit` for the new `Response`. To change the values\n * either modify the passed parameter(s) and return it, or return a totally\n * new object.\n *\n * @param {Response} response\n * @param {Function} modifier\n * @alias workbox.core.copyResponse\n */\nasync function copyResponse(response, modifier) {\n const clonedResponse = response.clone();\n // Create a fresh `ResponseInit` object by cloning the headers.\n const responseInit = {\n headers: new Headers(clonedResponse.headers),\n status: clonedResponse.status,\n statusText: clonedResponse.statusText,\n };\n // Apply any user modifications.\n const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit;\n // Create the new response from the body stream and `ResponseInit`\n // modifications. Note: not all browsers support the Response.body stream,\n // so fall back to reading the entire body into memory as a blob.\n const body = canConstructResponseFromBodyStream() ?\n clonedResponse.body : await clonedResponse.blob();\n return new Response(body, modifiedResponseInit);\n}\n;\nexport { copyResponse };\n","// @ts-ignore\ntry {\n self['workbox:precaching:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst plugins = [];\nexport const precachePlugins = {\n /*\n * @return {Array}\n * @private\n */\n get() {\n return plugins;\n },\n /*\n * @param {Array} newPlugins\n * @private\n */\n add(newPlugins) {\n plugins.push(...newPlugins);\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport '../_version.js';\n// Name of the search parameter used to store revision info.\nconst REVISION_SEARCH_PARAM = '__WB_REVISION__';\n/**\n * Converts a manifest entry into a versioned URL suitable for precaching.\n *\n * @param {Object|string} entry\n * @return {string} A URL with versioning info.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function createCacheKey(entry) {\n if (!entry) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If a precache manifest entry is a string, it's assumed to be a versioned\n // URL, like '/app.abcd1234.js'. Return as-is.\n if (typeof entry === 'string') {\n const urlObject = new URL(entry, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n const { revision, url } = entry;\n if (!url) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If there's just a URL and no revision, then it's also assumed to be a\n // versioned URL.\n if (!revision) {\n const urlObject = new URL(url, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n // Otherwise, construct a properly versioned URL using the custom Workbox\n // search parameter along with the revision info.\n const cacheKeyURL = new URL(url, location.href);\n const originalURL = new URL(url, location.href);\n cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);\n return {\n cacheKey: cacheKeyURL.href,\n url: originalURL.href,\n };\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { cacheWrapper } from 'workbox-core/_private/cacheWrapper.js';\nimport { fetchWrapper } from 'workbox-core/_private/fetchWrapper.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { copyResponse } from 'workbox-core/copyResponse.js';\nimport { createCacheKey } from './utils/createCacheKey.js';\nimport { printCleanupDetails } from './utils/printCleanupDetails.js';\nimport { printInstallDetails } from './utils/printInstallDetails.js';\nimport './_version.js';\n/**\n * Performs efficient precaching of assets.\n *\n * @memberof module:workbox-precaching\n */\nclass PrecacheController {\n /**\n * Create a new PrecacheController.\n *\n * @param {string} [cacheName] An optional name for the cache, to override\n * the default precache name.\n */\n constructor(cacheName) {\n this._cacheName = cacheNames.getPrecacheName(cacheName);\n this._urlsToCacheKeys = new Map();\n this._cacheKeysToIntegrities = new Map();\n }\n /**\n * This method will add items to the precache list, removing duplicates\n * and ensuring the information is valid.\n *\n * @param {\n * Array\n * } entries Array of entries to precache.\n */\n addToCacheList(entries) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isArray(entries, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'addToCacheList',\n paramName: 'entries',\n });\n }\n for (const entry of entries) {\n const { cacheKey, url } = createCacheKey(entry);\n if (this._urlsToCacheKeys.has(url) &&\n this._urlsToCacheKeys.get(url) !== cacheKey) {\n throw new WorkboxError('add-to-cache-list-conflicting-entries', {\n firstEntry: this._urlsToCacheKeys.get(url),\n secondEntry: cacheKey,\n });\n }\n if (typeof entry !== 'string' && entry.integrity) {\n if (this._cacheKeysToIntegrities.has(cacheKey) &&\n this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {\n throw new WorkboxError('add-to-cache-list-conflicting-integrities', {\n url,\n });\n }\n this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);\n }\n this._urlsToCacheKeys.set(url, cacheKey);\n }\n }\n /**\n * Precaches new and updated assets. Call this method from the service worker\n * install event.\n *\n * @param {Object} options\n * @param {Event} [options.event] The install event (if needed).\n * @param {Array} [options.plugins] Plugins to be used for fetching\n * and caching during install.\n * @return {Promise}\n */\n async install({ event, plugins } = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (plugins) {\n assert.isArray(plugins, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'install',\n paramName: 'plugins',\n });\n }\n }\n const toBePrecached = [];\n const alreadyPrecached = [];\n const cache = await caches.open(this._cacheName);\n const alreadyCachedRequests = await cache.keys();\n const existingCacheKeys = new Set(alreadyCachedRequests.map((request) => request.url));\n for (const [url, cacheKey] of this._urlsToCacheKeys) {\n if (existingCacheKeys.has(cacheKey)) {\n alreadyPrecached.push(url);\n }\n else {\n toBePrecached.push({ cacheKey, url });\n }\n }\n const precacheRequests = toBePrecached.map(({ cacheKey, url }) => {\n const integrity = this._cacheKeysToIntegrities.get(cacheKey);\n return this._addURLToCache({ cacheKey, event, plugins, url, integrity });\n });\n await Promise.all(precacheRequests);\n const updatedURLs = toBePrecached.map((item) => item.url);\n if (process.env.NODE_ENV !== 'production') {\n printInstallDetails(updatedURLs, alreadyPrecached);\n }\n return {\n updatedURLs,\n notUpdatedURLs: alreadyPrecached,\n };\n }\n /**\n * Deletes assets that are no longer present in the current precache manifest.\n * Call this method from the service worker activate event.\n *\n * @return {Promise}\n */\n async activate() {\n const cache = await caches.open(this._cacheName);\n const currentlyCachedRequests = await cache.keys();\n const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());\n const deletedURLs = [];\n for (const request of currentlyCachedRequests) {\n if (!expectedCacheKeys.has(request.url)) {\n await cache.delete(request);\n deletedURLs.push(request.url);\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n printCleanupDetails(deletedURLs);\n }\n return { deletedURLs };\n }\n /**\n * Requests the entry and saves it to the cache if the response is valid.\n * By default, any response with a status code of less than 400 (including\n * opaque responses) is considered valid.\n *\n * If you need to use custom criteria to determine what's valid and what\n * isn't, then pass in an item in `options.plugins` that implements the\n * `cacheWillUpdate()` lifecycle event.\n *\n * @private\n * @param {Object} options\n * @param {string} options.cacheKey The string to use a cache key.\n * @param {string} options.url The URL to fetch and cache.\n * @param {Event} [options.event] The install event (if passed).\n * @param {Array} [options.plugins] An array of plugins to apply to\n * fetch and caching.\n * @param {string} [options.integrity] The value to use for the `integrity`\n * field when making the request.\n */\n async _addURLToCache({ cacheKey, url, event, plugins, integrity }) {\n const request = new Request(url, {\n integrity,\n cache: 'reload',\n credentials: 'same-origin',\n });\n let response = await fetchWrapper.fetch({\n event,\n plugins,\n request,\n });\n // Allow developers to override the default logic about what is and isn't\n // valid by passing in a plugin implementing cacheWillUpdate(), e.g.\n // a workbox.cacheableResponse.CacheableResponsePlugin instance.\n let cacheWillUpdatePlugin;\n for (const plugin of (plugins || [])) {\n if ('cacheWillUpdate' in plugin) {\n cacheWillUpdatePlugin = plugin;\n }\n }\n const isValidResponse = cacheWillUpdatePlugin ?\n // Use a callback if provided. It returns a truthy value if valid.\n // NOTE: invoke the method on the plugin instance so the `this` context\n // is correct.\n cacheWillUpdatePlugin.cacheWillUpdate({ event, request, response }) :\n // Otherwise, default to considering any response status under 400 valid.\n // This includes, by default, considering opaque responses valid.\n response.status < 400;\n // Consider this a failure, leading to the `install` handler failing, if\n // we get back an invalid response.\n if (!isValidResponse) {\n throw new WorkboxError('bad-precaching-response', {\n url,\n status: response.status,\n });\n }\n // Redirected responses cannot be used to satisfy a navigation request, so\n // any redirected response must be \"copied\" rather than cloned, so the new\n // response doesn't contain the `redirected` flag. See:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1\n if (response.redirected) {\n response = await copyResponse(response);\n }\n await cacheWrapper.put({\n event,\n plugins,\n response,\n // `request` already uses `url`. We may be able to reuse it.\n request: cacheKey === url ? request : new Request(cacheKey),\n cacheName: this._cacheName,\n matchOptions: {\n ignoreSearch: true,\n },\n });\n }\n /**\n * Returns a mapping of a precached URL to the corresponding cache key, taking\n * into account the revision information for the URL.\n *\n * @return {Map} A URL to cache key mapping.\n */\n getURLsToCacheKeys() {\n return this._urlsToCacheKeys;\n }\n /**\n * Returns a list of all the URLs that have been precached by the current\n * service worker.\n *\n * @return {Array} The precached URLs.\n */\n getCachedURLs() {\n return [...this._urlsToCacheKeys.keys()];\n }\n /**\n * Returns the cache key used for storing a given URL. If that URL is\n * unversioned, like `/index.html', then the cache key will be the original\n * URL with a search parameter appended to it.\n *\n * @param {string} url A URL whose cache key you want to look up.\n * @return {string} The versioned URL that corresponds to a cache key\n * for the original URL, or undefined if that URL isn't precached.\n */\n getCacheKeyForURL(url) {\n const urlObject = new URL(url, location.href);\n return this._urlsToCacheKeys.get(urlObject.href);\n }\n /**\n * Returns a function that looks up `url` in the precache (taking into\n * account revision information), and returns the corresponding `Response`.\n *\n * If for an unexpected reason there is a cache miss when looking up `url`,\n * this will fall back to retrieving the `Response` via `fetch()`.\n *\n * @param {string} url The precached URL which will be used to lookup the\n * `Response`.\n * @return {workbox.routing.Route~handlerCallback}\n */\n createHandlerForURL(url) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(url, 'string', {\n moduleName: 'workbox-precaching',\n funcName: 'createHandlerForURL',\n paramName: 'url',\n });\n }\n const cacheKey = this.getCacheKeyForURL(url);\n if (!cacheKey) {\n throw new WorkboxError('non-precached-url', { url });\n }\n return async () => {\n try {\n const cache = await caches.open(this._cacheName);\n const response = await cache.match(cacheKey);\n if (response) {\n return response;\n }\n // This shouldn't normally happen, but there are edge cases:\n // https://github.com/GoogleChrome/workbox/issues/1441\n throw new Error(`The cache ${this._cacheName} did not have an entry ` +\n `for ${cacheKey}.`);\n }\n catch (error) {\n // If there's either a cache miss, or the caches.match() call threw\n // an exception, then attempt to fulfill the navigation request with\n // a response from the network rather than leaving the user with a\n // failed navigation.\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Unable to respond to navigation request with ` +\n `cached response. Falling back to network.`, error);\n }\n // This might still fail if the browser is offline...\n return fetch(cacheKey);\n }\n };\n }\n ;\n}\nexport { PrecacheController };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { PrecacheController } from '../PrecacheController.js';\nimport '../_version.js';\nlet precacheController;\n/**\n * @return {PrecacheController}\n * @private\n */\nexport const getOrCreatePrecacheController = () => {\n if (!precacheController) {\n precacheController = new PrecacheController();\n }\n return precacheController;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { getOrCreatePrecacheController } from './getOrCreatePrecacheController.js';\nimport { generateURLVariations } from './generateURLVariations.js';\nimport '../_version.js';\n/**\n * This function will take the request URL and manipulate it based on the\n * configuration options.\n *\n * @param {string} url\n * @param {Object} options\n * @return {string} Returns the URL in the cache that matches the request,\n * if possible.\n *\n * @private\n */\nexport const getCacheKeyForURL = (url, options) => {\n const precacheController = getOrCreatePrecacheController();\n const urlsToCacheKeys = precacheController.getURLsToCacheKeys();\n for (const possibleURL of generateURLVariations(url, options)) {\n const possibleCacheKey = urlsToCacheKeys.get(possibleURL);\n if (possibleCacheKey) {\n return possibleCacheKey;\n }\n }\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { removeIgnoredSearchParams } from './removeIgnoredSearchParams.js';\nimport '../_version.js';\n/**\n * Generator function that yields possible variations on the original URL to\n * check, one at a time.\n *\n * @param {string} url\n * @param {Object} options\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function* generateURLVariations(url, { ignoreURLParametersMatching, directoryIndex, cleanURLs, urlManipulation, } = {}) {\n const urlObject = new URL(url, location.href);\n urlObject.hash = '';\n yield urlObject.href;\n const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching);\n yield urlWithoutIgnoredParams.href;\n if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) {\n const directoryURL = new URL(urlWithoutIgnoredParams.href);\n directoryURL.pathname += directoryIndex;\n yield directoryURL.href;\n }\n if (cleanURLs) {\n const cleanURL = new URL(urlWithoutIgnoredParams.href);\n cleanURL.pathname += '.html';\n yield cleanURL.href;\n }\n if (urlManipulation) {\n const additionalURLs = urlManipulation({ url: urlObject });\n for (const urlToAttempt of additionalURLs) {\n yield urlToAttempt.href;\n }\n }\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * Removes any URL search parameters that should be ignored.\n *\n * @param {URL} urlObject The original URL.\n * @param {Array} ignoreURLParametersMatching RegExps to test against\n * each search parameter name. Matches mean that the search parameter should be\n * ignored.\n * @return {URL} The URL with any ignored search parameters removed.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) {\n // Convert the iterable into an array at the start of the loop to make sure\n // deletion doesn't mess up iteration.\n for (const paramName of [...urlObject.searchParams.keys()]) {\n if (ignoreURLParametersMatching.some((regExp) => regExp.test(paramName))) {\n urlObject.searchParams.delete(paramName);\n }\n }\n return urlObject;\n}\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addFetchListener } from './utils/addFetchListener.js';\nimport './_version.js';\nlet listenerAdded = false;\n/**\n * Add a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * @param {Object} [options]\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox.precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n *\n * @alias workbox.precaching.addRoute\n */\nexport const addRoute = (options) => {\n if (!listenerAdded) {\n addFetchListener(options);\n listenerAdded = true;\n }\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getCacheKeyForURL } from './getCacheKeyForURL.js';\nimport '../_version.js';\n/**\n * Adds a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * NOTE: when called more than once this method will replace the previously set\n * configuration options. Calling it more than once is not recommended outside\n * of tests.\n *\n * @private\n * @param {Object} [options]\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox.precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n */\nexport const addFetchListener = ({ ignoreURLParametersMatching = [/^utm_/], directoryIndex = 'index.html', cleanURLs = true, urlManipulation, } = {}) => {\n const cacheName = cacheNames.getPrecacheName();\n addEventListener('fetch', (event) => {\n const precachedURL = getCacheKeyForURL(event.request.url, {\n cleanURLs,\n directoryIndex,\n ignoreURLParametersMatching,\n urlManipulation,\n });\n if (!precachedURL) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Precaching did not find a match for ` +\n getFriendlyURL(event.request.url));\n }\n return;\n }\n let responsePromise = caches.open(cacheName).then((cache) => {\n return cache.match(precachedURL);\n }).then((cachedResponse) => {\n if (cachedResponse) {\n return cachedResponse;\n }\n // Fall back to the network if we don't have a cached response\n // (perhaps due to manual cache cleanup).\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`The precached response for ` +\n `${getFriendlyURL(precachedURL)} in ${cacheName} was not found. ` +\n `Falling back to the network instead.`);\n }\n return fetch(precachedURL);\n });\n if (process.env.NODE_ENV !== 'production') {\n responsePromise = responsePromise.then((response) => {\n // Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Precaching is responding to: ` +\n getFriendlyURL(event.request.url));\n logger.log(`Serving the precached url: ${precachedURL}`);\n logger.groupCollapsed(`View request details here.`);\n logger.log(event.request);\n logger.groupEnd();\n logger.groupCollapsed(`View response details here.`);\n logger.log(response);\n logger.groupEnd();\n logger.groupEnd();\n return response;\n });\n }\n event.respondWith(responsePromise);\n });\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js';\nimport { precachePlugins } from './utils/precachePlugins.js';\nimport './_version.js';\nconst installListener = (event) => {\n const precacheController = getOrCreatePrecacheController();\n const plugins = precachePlugins.get();\n event.waitUntil(precacheController.install({ event, plugins })\n .catch((error) => {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Service worker installation failed. It will ` +\n `be retried automatically during the next navigation.`);\n }\n // Re-throw the error to ensure installation fails.\n throw error;\n }));\n};\nconst activateListener = (event) => {\n const precacheController = getOrCreatePrecacheController();\n event.waitUntil(precacheController.activate());\n};\n/**\n * Adds items to the precache list, removing any duplicates and\n * stores the files in the\n * [\"precache cache\"]{@link module:workbox-core.cacheNames} when the service\n * worker installs.\n *\n * This method can be called multiple times.\n *\n * Please note: This method **will not** serve any of the cached files for you.\n * It only precaches files. To respond to a network request you call\n * [addRoute()]{@link module:workbox-precaching.addRoute}.\n *\n * If you have a single array of files to precache, you can just call\n * [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}.\n *\n * @param {Array} [entries=[]] Array of entries to precache.\n *\n * @alias workbox.precaching.precache\n */\nexport const precache = (entries) => {\n const precacheController = getOrCreatePrecacheController();\n precacheController.addToCacheList(entries);\n if (entries.length > 0) {\n // NOTE: these listeners will only be added once (even if the `precache()`\n // method is called multiple times) because event listeners are implemented\n // as a set, where each listener must be unique.\n addEventListener('install', installListener);\n addEventListener('activate', activateListener);\n }\n};\n","// @ts-ignore\ntry {\n self['workbox:range-requests:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { calculateEffectiveBoundaries } from './utils/calculateEffectiveBoundaries.js';\nimport { parseRangeHeader } from './utils/parseRangeHeader.js';\nimport './_version.js';\n/**\n * Given a `Request` and `Response` objects as input, this will return a\n * promise for a new `Response`.\n *\n * If the original `Response` already contains partial content (i.e. it has\n * a status of 206), then this assumes it already fulfills the `Range:`\n * requirements, and will return it as-is.\n *\n * @param {Request} request A request, which should contain a Range:\n * header.\n * @param {Response} originalResponse A response.\n * @return {Promise} Either a `206 Partial Content` response, with\n * the response body set to the slice of content specified by the request's\n * `Range:` header, or a `416 Range Not Satisfiable` response if the\n * conditions of the `Range:` header can't be met.\n *\n * @memberof workbox.rangeRequests\n */\nasync function createPartialResponse(request, originalResponse) {\n try {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'request',\n });\n assert.isInstance(originalResponse, Response, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'originalResponse',\n });\n }\n if (originalResponse.status === 206) {\n // If we already have a 206, then just pass it through as-is;\n // see https://github.com/GoogleChrome/workbox/issues/1720\n return originalResponse;\n }\n const rangeHeader = request.headers.get('range');\n if (!rangeHeader) {\n throw new WorkboxError('no-range-header');\n }\n const boundaries = parseRangeHeader(rangeHeader);\n const originalBlob = await originalResponse.blob();\n const effectiveBoundaries = calculateEffectiveBoundaries(originalBlob, boundaries.start, boundaries.end);\n const slicedBlob = originalBlob.slice(effectiveBoundaries.start, effectiveBoundaries.end);\n const slicedBlobSize = slicedBlob.size;\n const slicedResponse = new Response(slicedBlob, {\n // Status code 206 is for a Partial Content response.\n // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206\n status: 206,\n statusText: 'Partial Content',\n headers: originalResponse.headers,\n });\n slicedResponse.headers.set('Content-Length', String(slicedBlobSize));\n slicedResponse.headers.set('Content-Range', `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` +\n originalBlob.size);\n return slicedResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to construct a partial response; returning a ` +\n `416 Range Not Satisfiable response instead.`);\n logger.groupCollapsed(`View details here.`);\n logger.log(error);\n logger.log(request);\n logger.log(originalResponse);\n logger.groupEnd();\n }\n return new Response('', {\n status: 416,\n statusText: 'Range Not Satisfiable',\n });\n }\n}\nexport { createPartialResponse };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {string} rangeHeader A Range: header value.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the parsed value of the Range: header. If either the `start` or `end` are\n * omitted, then `null` will be returned.\n *\n * @private\n */\nfunction parseRangeHeader(rangeHeader) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(rangeHeader, 'string', {\n moduleName: 'workbox-range-requests',\n funcName: 'parseRangeHeader',\n paramName: 'rangeHeader',\n });\n }\n const normalizedRangeHeader = rangeHeader.trim().toLowerCase();\n if (!normalizedRangeHeader.startsWith('bytes=')) {\n throw new WorkboxError('unit-must-be-bytes', { normalizedRangeHeader });\n }\n // Specifying multiple ranges separate by commas is valid syntax, but this\n // library only attempts to handle a single, contiguous sequence of bytes.\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#Syntax\n if (normalizedRangeHeader.includes(',')) {\n throw new WorkboxError('single-range-only', { normalizedRangeHeader });\n }\n const rangeParts = /(\\d*)-(\\d*)/.exec(normalizedRangeHeader);\n // We need either at least one of the start or end values.\n if (!rangeParts || !(rangeParts[1] || rangeParts[2])) {\n throw new WorkboxError('invalid-range-values', { normalizedRangeHeader });\n }\n return {\n start: rangeParts[1] === '' ? undefined : Number(rangeParts[1]),\n end: rangeParts[2] === '' ? undefined : Number(rangeParts[2]),\n };\n}\nexport { parseRangeHeader };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {Blob} blob A source blob.\n * @param {number} [start] The offset to use as the start of the\n * slice.\n * @param {number} [end] The offset to use as the end of the slice.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the effective boundaries to use given the size of the blob.\n *\n * @private\n */\nfunction calculateEffectiveBoundaries(blob, start, end) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(blob, Blob, {\n moduleName: 'workbox-range-requests',\n funcName: 'calculateEffectiveBoundaries',\n paramName: 'blob',\n });\n }\n const blobSize = blob.size;\n if ((end && end > blobSize) || (start && start < 0)) {\n throw new WorkboxError('range-not-satisfiable', {\n size: blobSize,\n end,\n start,\n });\n }\n let effectiveStart;\n let effectiveEnd;\n if (start !== undefined && end !== undefined) {\n effectiveStart = start;\n // Range values are inclusive, so add 1 to the value.\n effectiveEnd = end + 1;\n }\n else if (start !== undefined && end === undefined) {\n effectiveStart = start;\n effectiveEnd = blobSize;\n }\n else if (end !== undefined && start === undefined) {\n effectiveStart = blobSize - end;\n effectiveEnd = blobSize;\n }\n return {\n start: effectiveStart,\n end: effectiveEnd,\n };\n}\nexport { calculateEffectiveBoundaries };\n","// @ts-ignore\ntry {\n self['workbox:routing:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * The default HTTP method, 'GET', used when there's no specific method\n * configured for a route.\n *\n * @type {string}\n *\n * @private\n */\nexport const defaultMethod = 'GET';\n/**\n * The list of valid HTTP methods associated with requests that could be routed.\n *\n * @type {Array}\n *\n * @private\n */\nexport const validMethods = [\n 'DELETE',\n 'GET',\n 'HEAD',\n 'PATCH',\n 'POST',\n 'PUT',\n];\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {function()|Object} handler Either a function, or an object with a\n * 'handle' method.\n * @return {Object} An object with a handle method.\n *\n * @private\n */\nexport const normalizeHandler = (handler) => {\n if (handler && typeof handler === 'object') {\n if (process.env.NODE_ENV !== 'production') {\n assert.hasMethod(handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return handler;\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(handler, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return { handle: handler };\n }\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { defaultMethod, validMethods } from './utils/constants.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * A `Route` consists of a pair of callback functions, \"match\" and \"handler\".\n * The \"match\" callback determine if a route should be used to \"handle\" a\n * request by returning a non-falsy value if it can. The \"handler\" callback\n * is called when there is a match and should return a Promise that resolves\n * to a `Response`.\n *\n * @memberof workbox.routing\n */\nclass Route {\n /**\n * Constructor for Route class.\n *\n * @param {workbox.routing.Route~matchCallback} match\n * A callback function that determines whether the route matches a given\n * `fetch` event by returning a non-falsy value.\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resolving to a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(match, handler, method = defaultMethod) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(match, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'match',\n });\n if (method) {\n assert.isOneOf(method, validMethods, { paramName: 'method' });\n }\n }\n // These values are referenced directly by Router so cannot be\n // altered by minifification.\n this.handler = normalizeHandler(handler);\n this.match = match;\n this.method = method;\n }\n}\nexport { Route };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { Route } from './Route.js';\nimport './_version.js';\n/**\n * RegExpRoute makes it easy to create a regular expression based\n * [Route]{@link workbox.routing.Route}.\n *\n * For same-origin requests the RegExp only needs to match part of the URL. For\n * requests against third-party servers, you must define a RegExp that matches\n * the start of the URL.\n *\n * [See the module docs for info.]{@link https://developers.google.com/web/tools/workbox/modules/workbox-routing}\n *\n * @memberof workbox.routing\n * @extends workbox.routing.Route\n */\nclass RegExpRoute extends Route {\n /**\n * If the regulard expression contains\n * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},\n * th ecaptured values will be passed to the\n * [handler's]{@link workbox.routing.Route~handlerCallback} `params`\n * argument.\n *\n * @param {RegExp} regExp The regular expression to match against URLs.\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(regExp, handler, method) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(regExp, RegExp, {\n moduleName: 'workbox-routing',\n className: 'RegExpRoute',\n funcName: 'constructor',\n paramName: 'pattern',\n });\n }\n const match = ({ url }) => {\n const result = regExp.exec(url.href);\n // Return immediately if there's no match.\n if (!result) {\n return;\n }\n // Require that the match start at the first character in the URL string\n // if it's a cross-origin request.\n // See https://github.com/GoogleChrome/workbox/issues/281 for the context\n // behind this behavior.\n if ((url.origin !== location.origin) && (result.index !== 0)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`The regular expression '${regExp}' only partially matched ` +\n `against the cross-origin URL '${url}'. RegExpRoute's will only ` +\n `handle cross-origin requests if they match the entire URL.`);\n }\n return;\n }\n // If the route matches, but there aren't any capture groups defined, then\n // this will return [], which is truthy and therefore sufficient to\n // indicate a match.\n // If there are capture groups, then it will return their values.\n return result.slice(1);\n };\n super(match, handler, method);\n }\n}\nexport { RegExpRoute };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * The Router can be used to process a FetchEvent through one or more\n * [Routes]{@link workbox.routing.Route} responding with a Request if\n * a matching route exists.\n *\n * If no route matches a given a request, the Router will use a \"default\"\n * handler if one is defined.\n *\n * Should the matching Route throw an error, the Router will use a \"catch\"\n * handler if one is defined to gracefully deal with issues and respond with a\n * Request.\n *\n * If a request matches multiple routes, the **earliest** registered route will\n * be used to respond to the request.\n *\n * @memberof workbox.routing\n */\nclass Router {\n /**\n * Initializes a new Router.\n */\n constructor() {\n this._routes = new Map();\n }\n /**\n * @return {Map>} routes A `Map` of HTTP\n * method name ('GET', etc.) to an array of all the corresponding `Route`\n * instances that are registered.\n */\n get routes() {\n return this._routes;\n }\n /**\n * Adds a fetch event listener to respond to events when a route matches\n * the event's request.\n */\n addFetchListener() {\n self.addEventListener('fetch', (event) => {\n const { request } = event;\n const responsePromise = this.handleRequest({ request, event });\n if (responsePromise) {\n event.respondWith(responsePromise);\n }\n });\n }\n /**\n * Adds a message event listener for URLs to cache from the window.\n * This is useful to cache resources loaded on the page prior to when the\n * service worker started controlling it.\n *\n * The format of the message data sent from the window should be as follows.\n * Where the `urlsToCache` array may consist of URL strings or an array of\n * URL string + `requestInit` object (the same as you'd pass to `fetch()`).\n *\n * ```\n * {\n * type: 'CACHE_URLS',\n * payload: {\n * urlsToCache: [\n * './script1.js',\n * './script2.js',\n * ['./script3.js', {mode: 'no-cors'}],\n * ],\n * },\n * }\n * ```\n */\n addCacheListener() {\n self.addEventListener('message', async (event) => {\n if (event.data && event.data.type === 'CACHE_URLS') {\n const { payload } = event.data;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Caching URLs from the window`, payload.urlsToCache);\n }\n const requestPromises = Promise.all(payload.urlsToCache.map((entry) => {\n if (typeof entry === 'string') {\n entry = [entry];\n }\n const request = new Request(...entry);\n return this.handleRequest({ request });\n // TODO(philipwalton): TypeScript errors without this typecast for\n // some reason (probably a bug). The real type here should work but\n // doesn't: `Array | undefined>`.\n })); // TypeScript\n event.waitUntil(requestPromises);\n // If a MessageChannel was used, reply to the message on success.\n if (event.ports && event.ports[0]) {\n await requestPromises;\n event.ports[0].postMessage(true);\n }\n }\n });\n }\n /**\n * Apply the routing rules to a FetchEvent object to get a Response from an\n * appropriate Route's handler.\n *\n * @param {Object} options\n * @param {Request} options.request The request to handle (this is usually\n * from a fetch event, but it does not have to be).\n * @param {FetchEvent} [options.event] The event that triggered the request,\n * if applicable.\n * @return {Promise|undefined} A promise is returned if a\n * registered route can handle the request. If there is no matching\n * route and there's no `defaultHandler`, `undefined` is returned.\n */\n handleRequest({ request, event }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'handleRequest',\n paramName: 'options.request',\n });\n }\n const url = new URL(request.url, location.href);\n if (!url.protocol.startsWith('http')) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Workbox Router only supports URLs that start with 'http'.`);\n }\n return;\n }\n let { params, route } = this.findMatchingRoute({ url, request, event });\n let handler = route && route.handler;\n let debugMessages = [];\n if (process.env.NODE_ENV !== 'production') {\n if (handler) {\n debugMessages.push([\n `Found a route to handle this request:`, route,\n ]);\n if (params) {\n debugMessages.push([\n `Passing the following params to the route's handler:`, params,\n ]);\n }\n }\n }\n // If we don't have a handler because there was no matching route, then\n // fall back to defaultHandler if that's defined.\n if (!handler && this._defaultHandler) {\n if (process.env.NODE_ENV !== 'production') {\n debugMessages.push(`Failed to find a matching route. Falling ` +\n `back to the default handler.`);\n }\n handler = this._defaultHandler;\n }\n if (!handler) {\n if (process.env.NODE_ENV !== 'production') {\n // No handler so Workbox will do nothing. If logs is set of debug\n // i.e. verbose, we should print out this information.\n logger.debug(`No route found for: ${getFriendlyURL(url)}`);\n }\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n // We have a handler, meaning Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`);\n debugMessages.forEach((msg) => {\n if (Array.isArray(msg)) {\n logger.log(...msg);\n }\n else {\n logger.log(msg);\n }\n });\n // The Request and Response objects contains a great deal of information,\n // hide it under a group in case developers want to see it.\n logger.groupCollapsed(`View request details here.`);\n logger.log(request);\n logger.groupEnd();\n logger.groupEnd();\n }\n // Wrap in try and catch in case the handle method throws a synchronous\n // error. It should still callback to the catch handler.\n let responsePromise;\n try {\n responsePromise = handler.handle({ url, request, event, params });\n }\n catch (err) {\n responsePromise = Promise.reject(err);\n }\n if (responsePromise && this._catchHandler) {\n responsePromise = responsePromise.catch((err) => {\n if (process.env.NODE_ENV !== 'production') {\n // Still include URL here as it will be async from the console group\n // and may not make sense without the URL\n logger.groupCollapsed(`Error thrown when responding to: ` +\n ` ${getFriendlyURL(url)}. Falling back to Catch Handler.`);\n logger.error(`Error thrown by:`, route);\n logger.error(err);\n logger.groupEnd();\n }\n return this._catchHandler.handle({ url, request, event });\n });\n }\n return responsePromise;\n }\n /**\n * Checks a request and URL (and optionally an event) against the list of\n * registered routes, and if there's a match, returns the corresponding\n * route along with any params generated by the match.\n *\n * @param {Object} options\n * @param {URL} options.url\n * @param {Request} options.request The request to match.\n * @param {Event} [options.event] The corresponding event (unless N/A).\n * @return {Object} An object with `route` and `params` properties.\n * They are populated if a matching route was found or `undefined`\n * otherwise.\n */\n findMatchingRoute({ url, request, event }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(url, URL, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'findMatchingRoute',\n paramName: 'options.url',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'findMatchingRoute',\n paramName: 'options.request',\n });\n }\n const routes = this._routes.get(request.method) || [];\n for (const route of routes) {\n let params;\n let matchResult = route.match({ url, request, event });\n if (matchResult) {\n // See https://github.com/GoogleChrome/workbox/issues/2079\n params = matchResult;\n if (Array.isArray(matchResult) && matchResult.length === 0) {\n // Instead of passing an empty array in as params, use undefined.\n params = undefined;\n }\n else if ((matchResult.constructor === Object &&\n Object.keys(matchResult).length === 0)) {\n // Instead of passing an empty object in as params, use undefined.\n params = undefined;\n }\n else if (typeof matchResult === 'boolean') {\n // For the boolean value true (rather than just something truth-y),\n // don't set params.\n // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353\n params = undefined;\n }\n // Return early if have a match.\n return { route, params };\n }\n }\n // If no match was found above, return and empty object.\n return {};\n }\n /**\n * Define a default `handler` that's called when no routes explicitly\n * match the incoming request.\n *\n * Without a default handler, unmatched requests will go against the\n * network as if there were no service worker present.\n *\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setDefaultHandler(handler) {\n this._defaultHandler = normalizeHandler(handler);\n }\n /**\n * If a Route throws an error while handling a request, this `handler`\n * will be called and given a chance to provide a response.\n *\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setCatchHandler(handler) {\n this._catchHandler = normalizeHandler(handler);\n }\n /**\n * Registers a route with the router.\n *\n * @param {workbox.routing.Route} route The route to register.\n */\n registerRoute(route) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(route, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route, 'match', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.isType(route.handler, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route.handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.handler',\n });\n assert.isType(route.method, 'string', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.method',\n });\n }\n if (!this._routes.has(route.method)) {\n this._routes.set(route.method, []);\n }\n // Give precedence to all of the earlier routes by adding this additional\n // route to the end of the array.\n this._routes.get(route.method).push(route);\n }\n /**\n * Unregisters a route with the router.\n *\n * @param {workbox.routing.Route} route The route to unregister.\n */\n unregisterRoute(route) {\n if (!this._routes.has(route.method)) {\n throw new WorkboxError('unregister-route-but-not-found-with-method', {\n method: route.method,\n });\n }\n const routeIndex = this._routes.get(route.method).indexOf(route);\n if (routeIndex > -1) {\n this._routes.get(route.method).splice(routeIndex, 1);\n }\n else {\n throw new WorkboxError('unregister-route-route-not-registered');\n }\n }\n}\nexport { Router };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { Router } from '../Router.js';\nimport '../_version.js';\nlet defaultRouter;\n/**\n * Creates a new, singleton Router instance if one does not exist. If one\n * does already exist, that instance is returned.\n *\n * @private\n * @return {Router}\n */\nexport const getOrCreateDefaultRouter = () => {\n if (!defaultRouter) {\n defaultRouter = new Router();\n // The helpers that use the default Router assume these listeners exist.\n defaultRouter.addFetchListener();\n defaultRouter.addCacheListener();\n }\n return defaultRouter;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { Route } from './Route.js';\nimport { RegExpRoute } from './RegExpRoute.js';\nimport { getOrCreateDefaultRouter } from './utils/getOrCreateDefaultRouter.js';\nimport './_version.js';\n/**\n * Easily register a RegExp, string, or function with a caching\n * strategy to a singleton Router instance.\n *\n * This method will generate a Route for you if needed and\n * call [Router.registerRoute()]{@link\n * workbox.routing.Router#registerRoute}.\n *\n * @param {\n * RegExp|\n * string|\n * workbox.routing.Route~matchCallback|\n * workbox.routing.Route\n * } capture\n * If the capture param is a `Route`, all other arguments will be ignored.\n * @param {workbox.routing.Route~handlerCallback} [handler] A callback\n * function that returns a Promise resulting in a Response. This parameter\n * is required if `capture` is not a `Route` object.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n * @return {workbox.routing.Route} The generated `Route`(Useful for\n * unregistering).\n *\n * @alias workbox.routing.registerRoute\n */\nexport const registerRoute = (capture, handler, method) => {\n let route;\n if (typeof capture === 'string') {\n const captureUrl = new URL(capture, location.href);\n if (process.env.NODE_ENV !== 'production') {\n if (!(capture.startsWith('/') || capture.startsWith('http'))) {\n throw new WorkboxError('invalid-string', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n // We want to check if Express-style wildcards are in the pathname only.\n // TODO: Remove this log message in v4.\n const valueToCheck = capture.startsWith('http') ?\n captureUrl.pathname : capture;\n // See https://github.com/pillarjs/path-to-regexp#parameters\n const wildcards = '[*:?+]';\n if (valueToCheck.match(new RegExp(`${wildcards}`))) {\n logger.debug(`The '$capture' parameter contains an Express-style wildcard ` +\n `character (${wildcards}). Strings are now always interpreted as ` +\n `exact matches; use a RegExp for partial or wildcard matches.`);\n }\n }\n const matchCallback = ({ url }) => {\n if (process.env.NODE_ENV !== 'production') {\n if ((url.pathname === captureUrl.pathname) &&\n (url.origin !== captureUrl.origin)) {\n logger.debug(`${capture} only partially matches the cross-origin URL ` +\n `${url}. This route will only handle cross-origin requests ` +\n `if they match the entire URL.`);\n }\n }\n return url.href === captureUrl.href;\n };\n // If `capture` is a string then `handler` and `method` must be present.\n route = new Route(matchCallback, handler, method);\n }\n else if (capture instanceof RegExp) {\n // If `capture` is a `RegExp` then `handler` and `method` must be present.\n route = new RegExpRoute(capture, handler, method);\n }\n else if (typeof capture === 'function') {\n // If `capture` is a function then `handler` and `method` must be present.\n route = new Route(capture, handler, method);\n }\n else if (capture instanceof Route) {\n route = capture;\n }\n else {\n throw new WorkboxError('unsupported-route-type', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n const defaultRouter = getOrCreateDefaultRouter();\n defaultRouter.registerRoute(route);\n return route;\n};\n","/**\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n **/\n\nexport const cacheName = 'media';\nexport const channelName = 'messages';\nexport const fadeConfig = {duration: 200};\nexport const urlPrefix = '/_media/';\n","/**\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n **/\n\nimport {cacheName} from './constants';\n\nasync function _getCachedMediaMetadata() {\n const cache = await caches.open(cacheName);\n const requests = await cache.keys();\n return Promise.all(requests.reverse().map(async (request) => {\n const response = await cache.match(request);\n return {\n contentType: response.headers.get('content-type'),\n src: request.url,\n };\n }));\n}\nconst cachedMediaMetadataPromise = _getCachedMediaMetadata();\n\nexport async function getCachedMediaMetadata(contentTypePrefix) {\n const cachedMetadata = await cachedMediaMetadataPromise;\n return cachedMetadata.filter((metadata) => metadata.contentType.startsWith(contentTypePrefix));\n}\n\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n\n","import {CacheOnly} from 'workbox-strategies';\nimport {clientsClaim, skipWaiting} from 'workbox-core';\nimport {precacheAndRoute} from 'workbox-precaching';\nimport {RangeRequestsPlugin} from 'workbox-range-requests';\nimport {registerRoute} from 'workbox-routing';\n\nimport {cacheName, channelName, urlPrefix} from './constants';\nimport {mimeRoute as audioRoute} from '../svelte/routes/Audio.svelte';\nimport {mimeRoute as imagesRoute} from '../svelte/routes/Images.svelte';\nimport {mimeRoute as videosRoute} from '../svelte/routes/Videos.svelte';\n\nconst broadcastChannel = BroadcastChannel ? new BroadcastChannel(channelName) : null;\n\nconst shareTargetHandler = async ({event}) => {\n if (broadcastChannel) {\n broadcastChannel.postMessage('Saving media locally...');\n }\n\n const formData = await event.request.formData();\n const mediaFiles = formData.getAll('media');\n const cache = await caches.open(cacheName);\n\n for (const mediaFile of mediaFiles) {\n // TODO: Instead of bailing, come up with a\n // default name for each possible MIME type.\n if (!mediaFile.name) {\n if (broadcastChannel) {\n broadcastChannel.postMessage('Sorry! No name found on incoming media.');\n }\n continue;\n }\n await cache.put(\n // TODO: Handle scenarios in which mediaFile.name isn't set,\n // or doesn't include a proper extension.\n `${urlPrefix}${Date.now()}-${mediaFile.name}`,\n new Response(mediaFile, {\n headers: {\n 'content-length': mediaFile.size,\n 'content-type': mediaFile.type,\n },\n })\n );\n }\n\n // Use the MIME type of the first file shared to determine where we redirect.\n const routeToRedirectTo = [\n audioRoute,\n imagesRoute,\n videosRoute,\n ].find((route) => mediaFiles[0].type.startsWith(route.mimePrefix));\n\n const redirectionUrl = routeToRedirectTo ? `/#${routeToRedirectTo.href}` : '/';\n \n // After the POST succeeds, redirect to the main page.\n return Response.redirect(redirectionUrl, 303);\n};\n\nconst cachedMediaHandler = new CacheOnly({\n cacheName,\n plugins: [\n // Support for cache requests that include a Range: header.\n new RangeRequestsPlugin(),\n ],\n});\n\nskipWaiting();\nclientsClaim();\n\n// This will be replaced by the list of files to precache by\n// the `workbox injectManifest` build step.\nprecacheAndRoute(self.__WB_MANIFEST);\n\nregisterRoute(\n '/_share-target',\n shareTargetHandler,\n 'POST'\n);\n\nregisterRoute(\n new RegExp(urlPrefix),\n cachedMediaHandler\n);\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { cacheWrapper } from 'workbox-core/_private/cacheWrapper.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { messages } from './utils/messages.js';\nimport './_version.js';\n/**\n * An implementation of a\n * [cache-only]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-only}\n * request strategy.\n *\n * This class is useful if you want to take advantage of any\n * [Workbox plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}.\n *\n * If there is no cache match, this will throw a `WorkboxError` exception.\n *\n * @memberof workbox.strategies\n */\nclass CacheOnly {\n /**\n * @param {Object} options\n * @param {string} options.cacheName Cache name to store and retrieve\n * requests. Defaults to cache names provided by\n * [workbox-core]{@link workbox.core.cacheNames}.\n * @param {Array} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}\n * to use in conjunction with this caching strategy.\n * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)\n */\n constructor(options = {}) {\n this._cacheName = cacheNames.getRuntimeName(options.cacheName);\n this._plugins = options.plugins || [];\n this._matchOptions = options.matchOptions;\n }\n /**\n * This method will perform a request strategy and follows an API that\n * will work with the\n * [Workbox Router]{@link workbox.routing.Router}.\n *\n * @param {Object} options\n * @param {Request} options.request The request to run this strategy for.\n * @param {Event} [options.event] The event that triggered the request.\n * @return {Promise}\n */\n async handle({ event, request }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-strategies',\n className: 'CacheOnly',\n funcName: 'makeRequest',\n paramName: 'request',\n });\n }\n const response = await cacheWrapper.match({\n cacheName: this._cacheName,\n request,\n event,\n matchOptions: this._matchOptions,\n plugins: this._plugins,\n });\n if (process.env.NODE_ENV !== 'production') {\n logger.groupCollapsed(messages.strategyStart('CacheOnly', request));\n if (response) {\n logger.log(`Found a cached response in the '${this._cacheName}'` +\n ` cache.`);\n messages.printFinalResponse(response);\n }\n else {\n logger.log(`No response found in the '${this._cacheName}' cache.`);\n }\n logger.groupEnd();\n }\n if (!response) {\n throw new WorkboxError('no-response', { url: request.url });\n }\n return response;\n }\n}\nexport { CacheOnly };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { createPartialResponse } from './createPartialResponse.js';\nimport './_version.js';\n/**\n * The range request plugin makes it easy for a request with a 'Range' header to\n * be fulfilled by a cached response.\n *\n * It does this by intercepting the `cachedResponseWillBeUsed` plugin callback\n * and returning the appropriate subset of the cached response body.\n *\n * @memberof workbox.rangeRequests\n */\nclass RangeRequestsPlugin {\n constructor() {\n /**\n * @param {Object} options\n * @param {Request} options.request The original request, which may or may not\n * contain a Range: header.\n * @param {Response} options.cachedResponse The complete cached response.\n * @return {Promise} If request contains a 'Range' header, then a\n * new response with status 206 whose body is a subset of `cachedResponse` is\n * returned. Otherwise, `cachedResponse` is returned as-is.\n *\n * @private\n */\n this.cachedResponseWillBeUsed = async ({ request, cachedResponse }) => {\n // Only return a sliced response if there's something valid in the cache,\n // and there's a Range: header in the request.\n if (cachedResponse && request.headers.has('range')) {\n return await createPartialResponse(request, cachedResponse);\n }\n // If there was no Range: header, or if cachedResponse wasn't valid, just\n // pass it through as-is.\n return cachedResponse;\n };\n }\n}\nexport { RangeRequestsPlugin };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addRoute } from './addRoute.js';\nimport { precache } from './precache.js';\nimport './_version.js';\n/**\n * This method will add entries to the precache list and add a route to\n * respond to fetch events.\n *\n * This is a convenience method that will call\n * [precache()]{@link module:workbox-precaching.precache} and\n * [addRoute()]{@link module:workbox-precaching.addRoute} in a single call.\n *\n * @param {Array} entries Array of entries to precache.\n * @param {Object} [options] See\n * [addRoute() options]{@link module:workbox-precaching.addRoute}.\n *\n * @alias workbox.precaching.precacheAndRoute\n */\nexport const precacheAndRoute = (entries, options) => {\n precache(entries);\n addRoute(options);\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Force a service worker to become active, instead of waiting. This is\n * normally used in conjunction with `clientsClaim()`.\n *\n * @alias workbox.core.skipWaiting\n */\nexport const skipWaiting = () => {\n // We need to explicitly call `self.skipWaiting()` here because we're\n // shadowing `skipWaiting` with this local function.\n addEventListener('install', () => self.skipWaiting());\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Claim any currently available clients once the service worker\n * becomes active. This is normally used in conjunction with `skipWaiting()`.\n *\n * @alias workbox.core.clientsClaim\n */\nexport const clientsClaim = () => {\n addEventListener('activate', () => self.clients.claim());\n};\n"]} \ No newline at end of file diff --git a/test/workbox-build/static/sw-injections/basic-with-sourcemap.js.map b/test/workbox-build/static/sw-injections/basic-with-sourcemap.js.map new file mode 100644 index 000000000..04d96aae4 --- /dev/null +++ b/test/workbox-build/static/sw-injections/basic-with-sourcemap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"basic-with-sourcemap.js","sources":["../node_modules/workbox-core/_version.js","../node_modules/workbox-core/_private/logger.js","../node_modules/workbox-core/models/messages/messageGenerator.js","../node_modules/workbox-core/_private/WorkboxError.js","../node_modules/workbox-core/_private/assert.js","../node_modules/workbox-core/_private/cacheNames.js","../node_modules/workbox-core/_private/getFriendlyURL.js","../node_modules/workbox-core/models/quotaErrorCallbacks.js","../node_modules/workbox-core/utils/pluginUtils.js","../node_modules/workbox-core/_private/cacheWrapper.js","../node_modules/workbox-core/_private/executeQuotaErrorCallbacks.js","../node_modules/workbox-core/_private/fetchWrapper.js","../node_modules/workbox-strategies/_version.js","../node_modules/workbox-core/_private/canConstructResponseFromBodyStream.js","../node_modules/workbox-core/_private/DBWrapper.js","../node_modules/workbox-core/copyResponse.js","../node_modules/workbox-precaching/_version.js","../node_modules/workbox-precaching/utils/precachePlugins.js","../node_modules/workbox-precaching/utils/createCacheKey.js","../node_modules/workbox-precaching/PrecacheController.js","../node_modules/workbox-precaching/utils/getOrCreatePrecacheController.js","../node_modules/workbox-precaching/utils/getCacheKeyForURL.js","../node_modules/workbox-precaching/utils/generateURLVariations.js","../node_modules/workbox-precaching/utils/removeIgnoredSearchParams.js","../node_modules/workbox-precaching/addRoute.js","../node_modules/workbox-precaching/utils/addFetchListener.js","../node_modules/workbox-precaching/precache.js","../node_modules/workbox-range-requests/_version.js","../node_modules/workbox-range-requests/createPartialResponse.js","../node_modules/workbox-range-requests/utils/parseRangeHeader.js","../node_modules/workbox-range-requests/utils/calculateEffectiveBoundaries.js","../node_modules/workbox-routing/_version.js","../node_modules/workbox-routing/utils/constants.js","../node_modules/workbox-routing/utils/normalizeHandler.js","../node_modules/workbox-routing/Route.js","../node_modules/workbox-routing/RegExpRoute.js","../node_modules/workbox-routing/Router.js","../node_modules/workbox-routing/utils/getOrCreateDefaultRouter.js","../node_modules/workbox-routing/registerRoute.js","../src/js/constants.js","../src/js/getCachedMediaMetadata.js","../src/svelte/routes/Audio.svelte","../src/svelte/routes/Images.svelte","../src/svelte/routes/Videos.svelte","../src/js/service-worker.js","../node_modules/workbox-strategies/CacheOnly.js","../node_modules/workbox-range-requests/RangeRequestsPlugin.js","../node_modules/workbox-precaching/precacheAndRoute.js","../node_modules/workbox-core/skipWaiting.js","../node_modules/workbox-core/clientsClaim.js"],"sourcesContent":["// @ts-ignore\ntry {\n self['workbox:core:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst logger = (process.env.NODE_ENV === 'production' ? null : (() => {\n let inGroup = false;\n const methodToColorMap = {\n debug: `#7f8c8d`,\n log: `#2ecc71`,\n warn: `#f39c12`,\n error: `#c0392b`,\n groupCollapsed: `#3498db`,\n groupEnd: null,\n };\n const print = function (method, args) {\n if (method === 'groupCollapsed') {\n // Safari doesn't print all console.groupCollapsed() arguments:\n // https://bugs.webkit.org/show_bug.cgi?id=182754\n if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\n console[method](...args);\n return;\n }\n }\n const styles = [\n `background: ${methodToColorMap[method]}`,\n `border-radius: 0.5em`,\n `color: white`,\n `font-weight: bold`,\n `padding: 2px 0.5em`,\n ];\n // When in a group, the workbox prefix is not displayed.\n const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];\n console[method](...logPrefix, ...args);\n if (method === 'groupCollapsed') {\n inGroup = true;\n }\n if (method === 'groupEnd') {\n inGroup = false;\n }\n };\n const api = {};\n const loggerMethods = Object.keys(methodToColorMap);\n for (const key of loggerMethods) {\n const method = key;\n api[method] = (...args) => {\n print(method, args);\n };\n }\n return api;\n})());\nexport { logger };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messages } from './messages.js';\nimport '../../_version.js';\nconst fallback = (code, ...args) => {\n let msg = code;\n if (args.length > 0) {\n msg += ` :: ${JSON.stringify(args)}`;\n }\n return msg;\n};\nconst generatorFunction = (code, details = {}) => {\n const message = messages[code];\n if (!message) {\n throw new Error(`Unable to find message for code '${code}'.`);\n }\n return message(details);\n};\nexport const messageGenerator = (process.env.NODE_ENV === 'production') ?\n fallback : generatorFunction;\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { messageGenerator } from '../models/messages/messageGenerator.js';\nimport '../_version.js';\n/**\n * Workbox errors should be thrown with this class.\n * This allows use to ensure the type easily in tests,\n * helps developers identify errors from workbox\n * easily and allows use to optimise error\n * messages correctly.\n *\n * @private\n */\nclass WorkboxError extends Error {\n /**\n *\n * @param {string} errorCode The error code that\n * identifies this particular error.\n * @param {Object=} details Any relevant arguments\n * that will help developers identify issues should\n * be added as a key on the context object.\n */\n constructor(errorCode, details) {\n let message = messageGenerator(errorCode, details);\n super(message);\n this.name = errorCode;\n this.details = details;\n }\n}\nexport { WorkboxError };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from '../_private/WorkboxError.js';\nimport '../_version.js';\n/*\n * This method returns true if the current context is a service worker.\n */\nconst isSWEnv = (moduleName) => {\n if (!('ServiceWorkerGlobalScope' in self)) {\n throw new WorkboxError('not-in-sw', { moduleName });\n }\n};\n/*\n * This method throws if the supplied value is not an array.\n * The destructed values are required to produce a meaningful error for users.\n * The destructed and restructured object is so it's clear what is\n * needed.\n */\nconst isArray = (value, details) => {\n if (!Array.isArray(value)) {\n throw new WorkboxError('not-an-array', details);\n }\n};\nconst hasMethod = (object, expectedMethod, details) => {\n const type = typeof object[expectedMethod];\n if (type !== 'function') {\n details.expectedMethod = expectedMethod;\n throw new WorkboxError('missing-a-method', details);\n }\n};\nconst isType = (object, expectedType, details) => {\n if (typeof object !== expectedType) {\n details.expectedType = expectedType;\n throw new WorkboxError('incorrect-type', details);\n }\n};\nconst isInstance = (object, expectedClass, details) => {\n if (!(object instanceof expectedClass)) {\n details.expectedClass = expectedClass;\n throw new WorkboxError('incorrect-class', details);\n }\n};\nconst isOneOf = (value, validValues, details) => {\n if (!validValues.includes(value)) {\n details.validValueDescription =\n `Valid values are ${JSON.stringify(validValues)}.`;\n throw new WorkboxError('invalid-value', details);\n }\n};\nconst isArrayOfClass = (value, expectedClass, details) => {\n const error = new WorkboxError('not-array-of-class', details);\n if (!Array.isArray(value)) {\n throw error;\n }\n for (let item of value) {\n if (!(item instanceof expectedClass)) {\n throw error;\n }\n }\n};\nconst finalAssertExports = process.env.NODE_ENV === 'production' ? null : {\n hasMethod,\n isArray,\n isInstance,\n isOneOf,\n isSWEnv,\n isType,\n isArrayOfClass,\n};\nexport { finalAssertExports as assert };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst _cacheNameDetails = {\n googleAnalytics: 'googleAnalytics',\n precache: 'precache-v2',\n prefix: 'workbox',\n runtime: 'runtime',\n suffix: registration.scope,\n};\nconst _createCacheName = (cacheName) => {\n return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix]\n .filter((value) => value && value.length > 0)\n .join('-');\n};\nconst eachCacheNameDetail = (fn) => {\n for (const key of Object.keys(_cacheNameDetails)) {\n fn(key);\n }\n};\nexport const cacheNames = {\n updateDetails: (details) => {\n eachCacheNameDetail((key) => {\n if (typeof details[key] === 'string') {\n _cacheNameDetails[key] = details[key];\n }\n });\n },\n getGoogleAnalyticsName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);\n },\n getPrecacheName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.precache);\n },\n getPrefix: () => {\n return _cacheNameDetails.prefix;\n },\n getRuntimeName: (userCacheName) => {\n return userCacheName || _createCacheName(_cacheNameDetails.runtime);\n },\n getSuffix: () => {\n return _cacheNameDetails.suffix;\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst getFriendlyURL = (url) => {\n const urlObj = new URL(String(url), location.href);\n if (urlObj.origin === location.origin) {\n return urlObj.pathname;\n }\n return urlObj.href;\n};\nexport { getFriendlyURL };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n// Callbacks to be executed whenever there's a quota error.\nconst quotaErrorCallbacks = new Set();\nexport { quotaErrorCallbacks };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nexport const pluginUtils = {\n filter: (plugins, callbackName) => {\n return plugins.filter((plugin) => callbackName in plugin);\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from './WorkboxError.js';\nimport { assert } from './assert.js';\nimport { getFriendlyURL } from './getFriendlyURL.js';\nimport { logger } from './logger.js';\nimport { executeQuotaErrorCallbacks } from './executeQuotaErrorCallbacks.js';\nimport { pluginUtils } from '../utils/pluginUtils.js';\nimport '../_version.js';\n/**\n * Wrapper around cache.put().\n *\n * Will call `cacheDidUpdate` on plugins if the cache was updated, using\n * `matchOptions` when determining what the old entry is.\n *\n * @param {Object} options\n * @param {string} options.cacheName\n * @param {Request} options.request\n * @param {Response} options.response\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @param {Object} [options.matchOptions]\n *\n * @private\n * @memberof module:workbox-core\n */\nconst putWrapper = async ({ cacheName, request, response, event, plugins = [], matchOptions, }) => {\n if (process.env.NODE_ENV !== 'production') {\n if (request.method && request.method !== 'GET') {\n throw new WorkboxError('attempt-to-cache-non-get-request', {\n url: getFriendlyURL(request.url),\n method: request.method,\n });\n }\n }\n const effectiveRequest = await _getEffectiveRequest({\n plugins, request, mode: 'write'\n });\n if (!response) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Cannot cache non-existent response for ` +\n `'${getFriendlyURL(effectiveRequest.url)}'.`);\n }\n throw new WorkboxError('cache-put-with-no-response', {\n url: getFriendlyURL(effectiveRequest.url),\n });\n }\n let responseToCache = await _isResponseSafeToCache({\n event,\n plugins,\n response,\n request: effectiveRequest,\n });\n if (!responseToCache) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' will ` +\n `not be cached.`, responseToCache);\n }\n return;\n }\n const cache = await caches.open(cacheName);\n const updatePlugins = pluginUtils.filter(plugins, \"cacheDidUpdate\" /* CACHE_DID_UPDATE */);\n let oldResponse = updatePlugins.length > 0 ?\n await matchWrapper({ cacheName, matchOptions, request: effectiveRequest }) :\n null;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Updating the '${cacheName}' cache with a new Response for ` +\n `${getFriendlyURL(effectiveRequest.url)}.`);\n }\n try {\n await cache.put(effectiveRequest, responseToCache);\n }\n catch (error) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError\n if (error.name === 'QuotaExceededError') {\n await executeQuotaErrorCallbacks();\n }\n throw error;\n }\n for (let plugin of updatePlugins) {\n await plugin[\"cacheDidUpdate\" /* CACHE_DID_UPDATE */].call(plugin, {\n cacheName,\n event,\n oldResponse,\n newResponse: responseToCache,\n request: effectiveRequest,\n });\n }\n};\n/**\n * This is a wrapper around cache.match().\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache to match against.\n * @param {Request} options.request The Request that will be used to look up\n * cache entries.\n * @param {Event} [options.event] The event that propted the action.\n * @param {Object} [options.matchOptions] Options passed to cache.match().\n * @param {Array} [options.plugins=[]] Array of plugins.\n * @return {Response} A cached response if available.\n *\n * @private\n * @memberof module:workbox-core\n */\nconst matchWrapper = async ({ cacheName, request, event, matchOptions, plugins = [], }) => {\n const cache = await caches.open(cacheName);\n const effectiveRequest = await _getEffectiveRequest({\n plugins, request, mode: 'read'\n });\n let cachedResponse = await cache.match(effectiveRequest, matchOptions);\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n logger.debug(`Found a cached response in '${cacheName}'.`);\n }\n else {\n logger.debug(`No cached response found in '${cacheName}'.`);\n }\n }\n for (const plugin of plugins) {\n if (\"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */ in plugin) {\n const pluginMethod = plugin[\"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */];\n cachedResponse = await pluginMethod.call(plugin, {\n cacheName,\n event,\n matchOptions,\n cachedResponse,\n request: effectiveRequest,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (cachedResponse) {\n assert.isInstance(cachedResponse, Response, {\n moduleName: 'Plugin',\n funcName: \"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n return cachedResponse;\n};\n/**\n * This method will call cacheWillUpdate on the available plugins (or use\n * status === 200) to determine if the Response is safe and valid to cache.\n *\n * @param {Object} options\n * @param {Request} options.request\n * @param {Response} options.response\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst _isResponseSafeToCache = async ({ request, response, event, plugins = [], }) => {\n let responseToCache = response;\n let pluginsUsed = false;\n for (let plugin of plugins) {\n if (\"cacheWillUpdate\" /* CACHE_WILL_UPDATE */ in plugin) {\n pluginsUsed = true;\n const pluginMethod = plugin[\"cacheWillUpdate\" /* CACHE_WILL_UPDATE */];\n responseToCache = await pluginMethod.call(plugin, {\n request,\n response: responseToCache,\n event,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n assert.isInstance(responseToCache, Response, {\n moduleName: 'Plugin',\n funcName: \"cacheWillUpdate\" /* CACHE_WILL_UPDATE */,\n isReturnValueProblem: true,\n });\n }\n }\n if (!responseToCache) {\n break;\n }\n }\n }\n if (!pluginsUsed) {\n if (process.env.NODE_ENV !== 'production') {\n if (responseToCache) {\n if (responseToCache.status !== 200) {\n if (responseToCache.status === 0) {\n logger.warn(`The response for '${request.url}' is an opaque ` +\n `response. The caching strategy that you're using will not ` +\n `cache opaque responses by default.`);\n }\n else {\n logger.debug(`The response for '${request.url}' returned ` +\n `a status code of '${response.status}' and won't be cached as a ` +\n `result.`);\n }\n }\n }\n }\n responseToCache = responseToCache && responseToCache.status === 200 ?\n responseToCache : undefined;\n }\n return responseToCache ? responseToCache : null;\n};\n/**\n * Checks the list of plugins for the cacheKeyWillBeUsed callback, and\n * executes any of those callbacks found in sequence. The final `Request` object\n * returned by the last plugin is treated as the cache key for cache reads\n * and/or writes.\n *\n * @param {Object} options\n * @param {Request} options.request\n * @param {string} options.mode\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst _getEffectiveRequest = async ({ request, mode, plugins = [], }) => {\n const cacheKeyWillBeUsedPlugins = pluginUtils.filter(plugins, \"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */);\n let effectiveRequest = request;\n for (const plugin of cacheKeyWillBeUsedPlugins) {\n effectiveRequest = await plugin[\"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */].call(plugin, { mode, request: effectiveRequest });\n if (typeof effectiveRequest === 'string') {\n effectiveRequest = new Request(effectiveRequest);\n }\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(effectiveRequest, Request, {\n moduleName: 'Plugin',\n funcName: \"cacheKeyWillBeUsed\" /* CACHE_KEY_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n return effectiveRequest;\n};\nexport const cacheWrapper = {\n put: putWrapper,\n match: matchWrapper,\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from '../_private/logger.js';\nimport { quotaErrorCallbacks } from '../models/quotaErrorCallbacks.js';\nimport '../_version.js';\n/**\n * Runs all of the callback functions, one at a time sequentially, in the order\n * in which they were registered.\n *\n * @memberof workbox.core\n * @private\n */\nasync function executeQuotaErrorCallbacks() {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`About to run ${quotaErrorCallbacks.size} ` +\n `callbacks to clean up caches.`);\n }\n for (const callback of quotaErrorCallbacks) {\n await callback();\n if (process.env.NODE_ENV !== 'production') {\n logger.log(callback, 'is complete.');\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log('Finished running callbacks.');\n }\n}\nexport { executeQuotaErrorCallbacks };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from './WorkboxError.js';\nimport { logger } from './logger.js';\nimport { assert } from './assert.js';\nimport { getFriendlyURL } from '../_private/getFriendlyURL.js';\nimport { pluginUtils } from '../utils/pluginUtils.js';\nimport '../_version.js';\n/**\n * Wrapper around the fetch API.\n *\n * Will call requestWillFetch on available plugins.\n *\n * @param {Object} options\n * @param {Request|string} options.request\n * @param {Object} [options.fetchOptions]\n * @param {Event} [options.event]\n * @param {Array} [options.plugins=[]]\n * @return {Promise}\n *\n * @private\n * @memberof module:workbox-core\n */\nconst wrappedFetch = async ({ request, fetchOptions, event, plugins = [], }) => {\n if (typeof request === 'string') {\n request = new Request(request);\n }\n // We *should* be able to call `await event.preloadResponse` even if it's\n // undefined, but for some reason, doing so leads to errors in our Node unit\n // tests. To work around that, explicitly check preloadResponse's value first.\n if (event instanceof FetchEvent && event.preloadResponse) {\n const possiblePreloadResponse = await event.preloadResponse;\n if (possiblePreloadResponse) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Using a preloaded navigation response for ` +\n `'${getFriendlyURL(request.url)}'`);\n }\n return possiblePreloadResponse;\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n paramName: 'request',\n expectedClass: Request,\n moduleName: 'workbox-core',\n className: 'fetchWrapper',\n funcName: 'wrappedFetch',\n });\n }\n const failedFetchPlugins = pluginUtils.filter(plugins, \"fetchDidFail\" /* FETCH_DID_FAIL */);\n // If there is a fetchDidFail plugin, we need to save a clone of the\n // original request before it's either modified by a requestWillFetch\n // plugin or before the original request's body is consumed via fetch().\n const originalRequest = failedFetchPlugins.length > 0 ?\n request.clone() : null;\n try {\n for (let plugin of plugins) {\n if (\"requestWillFetch\" /* REQUEST_WILL_FETCH */ in plugin) {\n const pluginMethod = plugin[\"requestWillFetch\" /* REQUEST_WILL_FETCH */];\n const requestClone = request.clone();\n request = (await pluginMethod.call(plugin, {\n request: requestClone,\n event,\n }));\n if (process.env.NODE_ENV !== 'production') {\n if (request) {\n assert.isInstance(request, Request, {\n moduleName: 'Plugin',\n funcName: \"cachedResponseWillBeUsed\" /* CACHED_RESPONSE_WILL_BE_USED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n }\n catch (err) {\n throw new WorkboxError('plugin-error-request-will-fetch', {\n thrownError: err,\n });\n }\n // The request can be altered by plugins with `requestWillFetch` making\n // the original request (Most likely from a `fetch` event) to be different\n // to the Request we make. Pass both to `fetchDidFail` to aid debugging.\n let pluginFilteredRequest = request.clone();\n try {\n let fetchResponse;\n // See https://github.com/GoogleChrome/workbox/issues/1796\n if (request.mode === 'navigate') {\n fetchResponse = await fetch(request);\n }\n else {\n fetchResponse = await fetch(request, fetchOptions);\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Network request for ` +\n `'${getFriendlyURL(request.url)}' returned a response with ` +\n `status '${fetchResponse.status}'.`);\n }\n for (const plugin of plugins) {\n if (\"fetchDidSucceed\" /* FETCH_DID_SUCCEED */ in plugin) {\n fetchResponse = await plugin[\"fetchDidSucceed\" /* FETCH_DID_SUCCEED */]\n .call(plugin, {\n event,\n request: pluginFilteredRequest,\n response: fetchResponse,\n });\n if (process.env.NODE_ENV !== 'production') {\n if (fetchResponse) {\n assert.isInstance(fetchResponse, Response, {\n moduleName: 'Plugin',\n funcName: \"fetchDidSucceed\" /* FETCH_DID_SUCCEED */,\n isReturnValueProblem: true,\n });\n }\n }\n }\n }\n return fetchResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Network request for ` +\n `'${getFriendlyURL(request.url)}' threw an error.`, error);\n }\n for (const plugin of failedFetchPlugins) {\n await plugin[\"fetchDidFail\" /* FETCH_DID_FAIL */].call(plugin, {\n error,\n event,\n originalRequest: originalRequest.clone(),\n request: pluginFilteredRequest.clone(),\n });\n }\n throw error;\n }\n};\nconst fetchWrapper = {\n fetch: wrappedFetch,\n};\nexport { fetchWrapper };\n","// @ts-ignore\ntry {\n self['workbox:strategies:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nlet supportStatus;\n/**\n * A utility function that determines whether the current browser supports\n * constructing a new `Response` from a `response.body` stream.\n *\n * @return {boolean} `true`, if the current browser can successfully\n * construct a `Response` from a `response.body` stream, `false` otherwise.\n *\n * @private\n */\nfunction canConstructResponseFromBodyStream() {\n if (supportStatus === undefined) {\n const testResponse = new Response('');\n if ('body' in testResponse) {\n try {\n new Response(testResponse.body);\n supportStatus = true;\n }\n catch (error) {\n supportStatus = false;\n }\n }\n supportStatus = false;\n }\n return supportStatus;\n}\nexport { canConstructResponseFromBodyStream };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * A class that wraps common IndexedDB functionality in a promise-based API.\n * It exposes all the underlying power and functionality of IndexedDB, but\n * wraps the most commonly used features in a way that's much simpler to use.\n *\n * @private\n */\nexport class DBWrapper {\n /**\n * @param {string} name\n * @param {number} version\n * @param {Object=} [callback]\n * @param {!Function} [callbacks.onupgradeneeded]\n * @param {!Function} [callbacks.onversionchange] Defaults to\n * DBWrapper.prototype._onversionchange when not specified.\n * @private\n */\n constructor(name, version, { onupgradeneeded, onversionchange, } = {}) {\n this._db = null;\n this._name = name;\n this._version = version;\n this._onupgradeneeded = onupgradeneeded;\n this._onversionchange = onversionchange || (() => this.close());\n }\n /**\n * Returns the IDBDatabase instance (not normally needed).\n * @return {IDBDatabase|undefined}\n *\n * @private\n */\n get db() {\n return this._db;\n }\n /**\n * Opens a connected to an IDBDatabase, invokes any onupgradedneeded\n * callback, and added an onversionchange callback to the database.\n *\n * @return {IDBDatabase}\n * @private\n */\n async open() {\n if (this._db)\n return;\n this._db = await new Promise((resolve, reject) => {\n // This flag is flipped to true if the timeout callback runs prior\n // to the request failing or succeeding. Note: we use a timeout instead\n // of an onblocked handler since there are cases where onblocked will\n // never never run. A timeout better handles all possible scenarios:\n // https://github.com/w3c/IndexedDB/issues/223\n let openRequestTimedOut = false;\n setTimeout(() => {\n openRequestTimedOut = true;\n reject(new Error('The open request was blocked and timed out'));\n }, this.OPEN_TIMEOUT);\n const openRequest = indexedDB.open(this._name, this._version);\n openRequest.onerror = () => reject(openRequest.error);\n openRequest.onupgradeneeded = (evt) => {\n if (openRequestTimedOut) {\n openRequest.transaction.abort();\n openRequest.result.close();\n }\n else if (typeof this._onupgradeneeded === 'function') {\n this._onupgradeneeded(evt);\n }\n };\n openRequest.onsuccess = () => {\n const db = openRequest.result;\n if (openRequestTimedOut) {\n db.close();\n }\n else {\n db.onversionchange = this._onversionchange.bind(this);\n resolve(db);\n }\n };\n });\n return this;\n }\n /**\n * Polyfills the native `getKey()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @return {Array}\n * @private\n */\n async getKey(storeName, query) {\n return (await this.getAllKeys(storeName, query, 1))[0];\n }\n /**\n * Polyfills the native `getAll()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @param {number} count\n * @return {Array}\n * @private\n */\n async getAll(storeName, query, count) {\n return await this.getAllMatching(storeName, { query, count });\n }\n /**\n * Polyfills the native `getAllKeys()` method. Note, this is overridden at\n * runtime if the browser supports the native method.\n *\n * @param {string} storeName\n * @param {*} query\n * @param {number} count\n * @return {Array}\n * @private\n */\n async getAllKeys(storeName, query, count) {\n const entries = await this.getAllMatching(storeName, { query, count, includeKeys: true });\n return entries.map((entry) => entry.key);\n }\n /**\n * Supports flexible lookup in an object store by specifying an index,\n * query, direction, and count. This method returns an array of objects\n * with the signature .\n *\n * @param {string} storeName\n * @param {Object} [opts]\n * @param {string} [opts.index] The index to use (if specified).\n * @param {*} [opts.query]\n * @param {IDBCursorDirection} [opts.direction]\n * @param {number} [opts.count] The max number of results to return.\n * @param {boolean} [opts.includeKeys] When true, the structure of the\n * returned objects is changed from an array of values to an array of\n * objects in the form {key, primaryKey, value}.\n * @return {Array}\n * @private\n */\n async getAllMatching(storeName, { index, query = null, // IE/Edge errors if query === `undefined`.\n direction = 'next', count, includeKeys = false, } = {}) {\n return await this.transaction([storeName], 'readonly', (txn, done) => {\n const store = txn.objectStore(storeName);\n const target = index ? store.index(index) : store;\n const results = [];\n const request = target.openCursor(query, direction);\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n results.push(includeKeys ? cursor : cursor.value);\n if (count && results.length >= count) {\n done(results);\n }\n else {\n cursor.continue();\n }\n }\n else {\n done(results);\n }\n };\n });\n }\n /**\n * Accepts a list of stores, a transaction type, and a callback and\n * performs a transaction. A promise is returned that resolves to whatever\n * value the callback chooses. The callback holds all the transaction logic\n * and is invoked with two arguments:\n * 1. The IDBTransaction object\n * 2. A `done` function, that's used to resolve the promise when\n * when the transaction is done, if passed a value, the promise is\n * resolved to that value.\n *\n * @param {Array} storeNames An array of object store names\n * involved in the transaction.\n * @param {string} type Can be `readonly` or `readwrite`.\n * @param {!Function} callback\n * @return {*} The result of the transaction ran by the callback.\n * @private\n */\n async transaction(storeNames, type, callback) {\n await this.open();\n return await new Promise((resolve, reject) => {\n const txn = this._db.transaction(storeNames, type);\n txn.onabort = () => reject(txn.error);\n txn.oncomplete = () => resolve();\n callback(txn, (value) => resolve(value));\n });\n }\n /**\n * Delegates async to a native IDBObjectStore method.\n *\n * @param {string} method The method name.\n * @param {string} storeName The object store name.\n * @param {string} type Can be `readonly` or `readwrite`.\n * @param {...*} args The list of args to pass to the native method.\n * @return {*} The result of the transaction.\n * @private\n */\n async _call(method, storeName, type, ...args) {\n const callback = (txn, done) => {\n const objStore = txn.objectStore(storeName);\n const request = objStore[method].apply(objStore, args);\n request.onsuccess = () => done(request.result);\n };\n return await this.transaction([storeName], type, callback);\n }\n /**\n * Closes the connection opened by `DBWrapper.open()`. Generally this method\n * doesn't need to be called since:\n * 1. It's usually better to keep a connection open since opening\n * a new connection is somewhat slow.\n * 2. Connections are automatically closed when the reference is\n * garbage collected.\n * The primary use case for needing to close a connection is when another\n * reference (typically in another tab) needs to upgrade it and would be\n * blocked by the current, open connection.\n *\n * @private\n */\n close() {\n if (this._db) {\n this._db.close();\n this._db = null;\n }\n }\n}\n// Exposed on the prototype to let users modify the default timeout on a\n// per-instance or global basis.\nDBWrapper.prototype.OPEN_TIMEOUT = 2000;\n// Wrap native IDBObjectStore methods according to their mode.\nconst methodsToWrap = {\n readonly: ['get', 'count', 'getKey', 'getAll', 'getAllKeys'],\n readwrite: ['add', 'put', 'clear', 'delete'],\n};\nfor (const [mode, methods] of Object.entries(methodsToWrap)) {\n for (const method of methods) {\n if (method in IDBObjectStore.prototype) {\n // Don't use arrow functions here since we're outside of the class.\n DBWrapper.prototype[method] =\n async function (storeName, ...args) {\n return await this._call(method, storeName, mode, ...args);\n };\n }\n }\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { canConstructResponseFromBodyStream } from './_private/canConstructResponseFromBodyStream.js';\nimport './_version.js';\n/**\n * Allows developers to copy a response and modify its `headers`, `status`,\n * or `statusText` values (the values settable via a\n * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax}\n * object in the constructor).\n * To modify these values, pass a function as the second argument. That\n * function will be invoked with a single object with the response properties\n * `{headers, status, statusText}`. The return value of this function will\n * be used as the `ResponseInit` for the new `Response`. To change the values\n * either modify the passed parameter(s) and return it, or return a totally\n * new object.\n *\n * @param {Response} response\n * @param {Function} modifier\n * @alias workbox.core.copyResponse\n */\nasync function copyResponse(response, modifier) {\n const clonedResponse = response.clone();\n // Create a fresh `ResponseInit` object by cloning the headers.\n const responseInit = {\n headers: new Headers(clonedResponse.headers),\n status: clonedResponse.status,\n statusText: clonedResponse.statusText,\n };\n // Apply any user modifications.\n const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit;\n // Create the new response from the body stream and `ResponseInit`\n // modifications. Note: not all browsers support the Response.body stream,\n // so fall back to reading the entire body into memory as a blob.\n const body = canConstructResponseFromBodyStream() ?\n clonedResponse.body : await clonedResponse.blob();\n return new Response(body, modifiedResponseInit);\n}\n;\nexport { copyResponse };\n","// @ts-ignore\ntry {\n self['workbox:precaching:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nconst plugins = [];\nexport const precachePlugins = {\n /*\n * @return {Array}\n * @private\n */\n get() {\n return plugins;\n },\n /*\n * @param {Array} newPlugins\n * @private\n */\n add(newPlugins) {\n plugins.push(...newPlugins);\n },\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport '../_version.js';\n// Name of the search parameter used to store revision info.\nconst REVISION_SEARCH_PARAM = '__WB_REVISION__';\n/**\n * Converts a manifest entry into a versioned URL suitable for precaching.\n *\n * @param {Object|string} entry\n * @return {string} A URL with versioning info.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function createCacheKey(entry) {\n if (!entry) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If a precache manifest entry is a string, it's assumed to be a versioned\n // URL, like '/app.abcd1234.js'. Return as-is.\n if (typeof entry === 'string') {\n const urlObject = new URL(entry, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n const { revision, url } = entry;\n if (!url) {\n throw new WorkboxError('add-to-cache-list-unexpected-type', { entry });\n }\n // If there's just a URL and no revision, then it's also assumed to be a\n // versioned URL.\n if (!revision) {\n const urlObject = new URL(url, location.href);\n return {\n cacheKey: urlObject.href,\n url: urlObject.href,\n };\n }\n // Otherwise, construct a properly versioned URL using the custom Workbox\n // search parameter along with the revision info.\n const cacheKeyURL = new URL(url, location.href);\n const originalURL = new URL(url, location.href);\n cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);\n return {\n cacheKey: cacheKeyURL.href,\n url: originalURL.href,\n };\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { cacheWrapper } from 'workbox-core/_private/cacheWrapper.js';\nimport { fetchWrapper } from 'workbox-core/_private/fetchWrapper.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { copyResponse } from 'workbox-core/copyResponse.js';\nimport { createCacheKey } from './utils/createCacheKey.js';\nimport { printCleanupDetails } from './utils/printCleanupDetails.js';\nimport { printInstallDetails } from './utils/printInstallDetails.js';\nimport './_version.js';\n/**\n * Performs efficient precaching of assets.\n *\n * @memberof module:workbox-precaching\n */\nclass PrecacheController {\n /**\n * Create a new PrecacheController.\n *\n * @param {string} [cacheName] An optional name for the cache, to override\n * the default precache name.\n */\n constructor(cacheName) {\n this._cacheName = cacheNames.getPrecacheName(cacheName);\n this._urlsToCacheKeys = new Map();\n this._cacheKeysToIntegrities = new Map();\n }\n /**\n * This method will add items to the precache list, removing duplicates\n * and ensuring the information is valid.\n *\n * @param {\n * Array\n * } entries Array of entries to precache.\n */\n addToCacheList(entries) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isArray(entries, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'addToCacheList',\n paramName: 'entries',\n });\n }\n for (const entry of entries) {\n const { cacheKey, url } = createCacheKey(entry);\n if (this._urlsToCacheKeys.has(url) &&\n this._urlsToCacheKeys.get(url) !== cacheKey) {\n throw new WorkboxError('add-to-cache-list-conflicting-entries', {\n firstEntry: this._urlsToCacheKeys.get(url),\n secondEntry: cacheKey,\n });\n }\n if (typeof entry !== 'string' && entry.integrity) {\n if (this._cacheKeysToIntegrities.has(cacheKey) &&\n this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {\n throw new WorkboxError('add-to-cache-list-conflicting-integrities', {\n url,\n });\n }\n this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);\n }\n this._urlsToCacheKeys.set(url, cacheKey);\n }\n }\n /**\n * Precaches new and updated assets. Call this method from the service worker\n * install event.\n *\n * @param {Object} options\n * @param {Event} [options.event] The install event (if needed).\n * @param {Array} [options.plugins] Plugins to be used for fetching\n * and caching during install.\n * @return {Promise}\n */\n async install({ event, plugins } = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (plugins) {\n assert.isArray(plugins, {\n moduleName: 'workbox-precaching',\n className: 'PrecacheController',\n funcName: 'install',\n paramName: 'plugins',\n });\n }\n }\n const toBePrecached = [];\n const alreadyPrecached = [];\n const cache = await caches.open(this._cacheName);\n const alreadyCachedRequests = await cache.keys();\n const existingCacheKeys = new Set(alreadyCachedRequests.map((request) => request.url));\n for (const [url, cacheKey] of this._urlsToCacheKeys) {\n if (existingCacheKeys.has(cacheKey)) {\n alreadyPrecached.push(url);\n }\n else {\n toBePrecached.push({ cacheKey, url });\n }\n }\n const precacheRequests = toBePrecached.map(({ cacheKey, url }) => {\n const integrity = this._cacheKeysToIntegrities.get(cacheKey);\n return this._addURLToCache({ cacheKey, event, plugins, url, integrity });\n });\n await Promise.all(precacheRequests);\n const updatedURLs = toBePrecached.map((item) => item.url);\n if (process.env.NODE_ENV !== 'production') {\n printInstallDetails(updatedURLs, alreadyPrecached);\n }\n return {\n updatedURLs,\n notUpdatedURLs: alreadyPrecached,\n };\n }\n /**\n * Deletes assets that are no longer present in the current precache manifest.\n * Call this method from the service worker activate event.\n *\n * @return {Promise}\n */\n async activate() {\n const cache = await caches.open(this._cacheName);\n const currentlyCachedRequests = await cache.keys();\n const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());\n const deletedURLs = [];\n for (const request of currentlyCachedRequests) {\n if (!expectedCacheKeys.has(request.url)) {\n await cache.delete(request);\n deletedURLs.push(request.url);\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n printCleanupDetails(deletedURLs);\n }\n return { deletedURLs };\n }\n /**\n * Requests the entry and saves it to the cache if the response is valid.\n * By default, any response with a status code of less than 400 (including\n * opaque responses) is considered valid.\n *\n * If you need to use custom criteria to determine what's valid and what\n * isn't, then pass in an item in `options.plugins` that implements the\n * `cacheWillUpdate()` lifecycle event.\n *\n * @private\n * @param {Object} options\n * @param {string} options.cacheKey The string to use a cache key.\n * @param {string} options.url The URL to fetch and cache.\n * @param {Event} [options.event] The install event (if passed).\n * @param {Array} [options.plugins] An array of plugins to apply to\n * fetch and caching.\n * @param {string} [options.integrity] The value to use for the `integrity`\n * field when making the request.\n */\n async _addURLToCache({ cacheKey, url, event, plugins, integrity }) {\n const request = new Request(url, {\n integrity,\n cache: 'reload',\n credentials: 'same-origin',\n });\n let response = await fetchWrapper.fetch({\n event,\n plugins,\n request,\n });\n // Allow developers to override the default logic about what is and isn't\n // valid by passing in a plugin implementing cacheWillUpdate(), e.g.\n // a workbox.cacheableResponse.CacheableResponsePlugin instance.\n let cacheWillUpdatePlugin;\n for (const plugin of (plugins || [])) {\n if ('cacheWillUpdate' in plugin) {\n cacheWillUpdatePlugin = plugin;\n }\n }\n const isValidResponse = cacheWillUpdatePlugin ?\n // Use a callback if provided. It returns a truthy value if valid.\n // NOTE: invoke the method on the plugin instance so the `this` context\n // is correct.\n cacheWillUpdatePlugin.cacheWillUpdate({ event, request, response }) :\n // Otherwise, default to considering any response status under 400 valid.\n // This includes, by default, considering opaque responses valid.\n response.status < 400;\n // Consider this a failure, leading to the `install` handler failing, if\n // we get back an invalid response.\n if (!isValidResponse) {\n throw new WorkboxError('bad-precaching-response', {\n url,\n status: response.status,\n });\n }\n // Redirected responses cannot be used to satisfy a navigation request, so\n // any redirected response must be \"copied\" rather than cloned, so the new\n // response doesn't contain the `redirected` flag. See:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1\n if (response.redirected) {\n response = await copyResponse(response);\n }\n await cacheWrapper.put({\n event,\n plugins,\n response,\n // `request` already uses `url`. We may be able to reuse it.\n request: cacheKey === url ? request : new Request(cacheKey),\n cacheName: this._cacheName,\n matchOptions: {\n ignoreSearch: true,\n },\n });\n }\n /**\n * Returns a mapping of a precached URL to the corresponding cache key, taking\n * into account the revision information for the URL.\n *\n * @return {Map} A URL to cache key mapping.\n */\n getURLsToCacheKeys() {\n return this._urlsToCacheKeys;\n }\n /**\n * Returns a list of all the URLs that have been precached by the current\n * service worker.\n *\n * @return {Array} The precached URLs.\n */\n getCachedURLs() {\n return [...this._urlsToCacheKeys.keys()];\n }\n /**\n * Returns the cache key used for storing a given URL. If that URL is\n * unversioned, like `/index.html', then the cache key will be the original\n * URL with a search parameter appended to it.\n *\n * @param {string} url A URL whose cache key you want to look up.\n * @return {string} The versioned URL that corresponds to a cache key\n * for the original URL, or undefined if that URL isn't precached.\n */\n getCacheKeyForURL(url) {\n const urlObject = new URL(url, location.href);\n return this._urlsToCacheKeys.get(urlObject.href);\n }\n /**\n * Returns a function that looks up `url` in the precache (taking into\n * account revision information), and returns the corresponding `Response`.\n *\n * If for an unexpected reason there is a cache miss when looking up `url`,\n * this will fall back to retrieving the `Response` via `fetch()`.\n *\n * @param {string} url The precached URL which will be used to lookup the\n * `Response`.\n * @return {workbox.routing.Route~handlerCallback}\n */\n createHandlerForURL(url) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(url, 'string', {\n moduleName: 'workbox-precaching',\n funcName: 'createHandlerForURL',\n paramName: 'url',\n });\n }\n const cacheKey = this.getCacheKeyForURL(url);\n if (!cacheKey) {\n throw new WorkboxError('non-precached-url', { url });\n }\n return async () => {\n try {\n const cache = await caches.open(this._cacheName);\n const response = await cache.match(cacheKey);\n if (response) {\n return response;\n }\n // This shouldn't normally happen, but there are edge cases:\n // https://github.com/GoogleChrome/workbox/issues/1441\n throw new Error(`The cache ${this._cacheName} did not have an entry ` +\n `for ${cacheKey}.`);\n }\n catch (error) {\n // If there's either a cache miss, or the caches.match() call threw\n // an exception, then attempt to fulfill the navigation request with\n // a response from the network rather than leaving the user with a\n // failed navigation.\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Unable to respond to navigation request with ` +\n `cached response. Falling back to network.`, error);\n }\n // This might still fail if the browser is offline...\n return fetch(cacheKey);\n }\n };\n }\n ;\n}\nexport { PrecacheController };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { PrecacheController } from '../PrecacheController.js';\nimport '../_version.js';\nlet precacheController;\n/**\n * @return {PrecacheController}\n * @private\n */\nexport const getOrCreatePrecacheController = () => {\n if (!precacheController) {\n precacheController = new PrecacheController();\n }\n return precacheController;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { getOrCreatePrecacheController } from './getOrCreatePrecacheController.js';\nimport { generateURLVariations } from './generateURLVariations.js';\nimport '../_version.js';\n/**\n * This function will take the request URL and manipulate it based on the\n * configuration options.\n *\n * @param {string} url\n * @param {Object} options\n * @return {string} Returns the URL in the cache that matches the request,\n * if possible.\n *\n * @private\n */\nexport const getCacheKeyForURL = (url, options) => {\n const precacheController = getOrCreatePrecacheController();\n const urlsToCacheKeys = precacheController.getURLsToCacheKeys();\n for (const possibleURL of generateURLVariations(url, options)) {\n const possibleCacheKey = urlsToCacheKeys.get(possibleURL);\n if (possibleCacheKey) {\n return possibleCacheKey;\n }\n }\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { removeIgnoredSearchParams } from './removeIgnoredSearchParams.js';\nimport '../_version.js';\n/**\n * Generator function that yields possible variations on the original URL to\n * check, one at a time.\n *\n * @param {string} url\n * @param {Object} options\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function* generateURLVariations(url, { ignoreURLParametersMatching, directoryIndex, cleanURLs, urlManipulation, } = {}) {\n const urlObject = new URL(url, location.href);\n urlObject.hash = '';\n yield urlObject.href;\n const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching);\n yield urlWithoutIgnoredParams.href;\n if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) {\n const directoryURL = new URL(urlWithoutIgnoredParams.href);\n directoryURL.pathname += directoryIndex;\n yield directoryURL.href;\n }\n if (cleanURLs) {\n const cleanURL = new URL(urlWithoutIgnoredParams.href);\n cleanURL.pathname += '.html';\n yield cleanURL.href;\n }\n if (urlManipulation) {\n const additionalURLs = urlManipulation({ url: urlObject });\n for (const urlToAttempt of additionalURLs) {\n yield urlToAttempt.href;\n }\n }\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * Removes any URL search parameters that should be ignored.\n *\n * @param {URL} urlObject The original URL.\n * @param {Array} ignoreURLParametersMatching RegExps to test against\n * each search parameter name. Matches mean that the search parameter should be\n * ignored.\n * @return {URL} The URL with any ignored search parameters removed.\n *\n * @private\n * @memberof module:workbox-precaching\n */\nexport function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) {\n // Convert the iterable into an array at the start of the loop to make sure\n // deletion doesn't mess up iteration.\n for (const paramName of [...urlObject.searchParams.keys()]) {\n if (ignoreURLParametersMatching.some((regExp) => regExp.test(paramName))) {\n urlObject.searchParams.delete(paramName);\n }\n }\n return urlObject;\n}\n","/*\n Copyright 2019 Google LLC\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addFetchListener } from './utils/addFetchListener.js';\nimport './_version.js';\nlet listenerAdded = false;\n/**\n * Add a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * @param {Object} [options]\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox.precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n *\n * @alias workbox.precaching.addRoute\n */\nexport const addRoute = (options) => {\n if (!listenerAdded) {\n addFetchListener(options);\n listenerAdded = true;\n }\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getCacheKeyForURL } from './getCacheKeyForURL.js';\nimport '../_version.js';\n/**\n * Adds a `fetch` listener to the service worker that will\n * respond to\n * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}\n * with precached assets.\n *\n * Requests for assets that aren't precached, the `FetchEvent` will not be\n * responded to, allowing the event to fall through to other `fetch` event\n * listeners.\n *\n * NOTE: when called more than once this method will replace the previously set\n * configuration options. Calling it more than once is not recommended outside\n * of tests.\n *\n * @private\n * @param {Object} [options]\n * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will\n * check cache entries for a URLs ending with '/' to see if there is a hit when\n * appending the `directoryIndex` value.\n * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/]] An\n * array of regex's to remove search params when looking for a cache match.\n * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will\n * check the cache for the URL with a `.html` added to the end of the end.\n * @param {workbox.precaching~urlManipulation} [options.urlManipulation]\n * This is a function that should take a URL and return an array of\n * alternative URLs that should be checked for precache matches.\n */\nexport const addFetchListener = ({ ignoreURLParametersMatching = [/^utm_/], directoryIndex = 'index.html', cleanURLs = true, urlManipulation, } = {}) => {\n const cacheName = cacheNames.getPrecacheName();\n addEventListener('fetch', (event) => {\n const precachedURL = getCacheKeyForURL(event.request.url, {\n cleanURLs,\n directoryIndex,\n ignoreURLParametersMatching,\n urlManipulation,\n });\n if (!precachedURL) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Precaching did not find a match for ` +\n getFriendlyURL(event.request.url));\n }\n return;\n }\n let responsePromise = caches.open(cacheName).then((cache) => {\n return cache.match(precachedURL);\n }).then((cachedResponse) => {\n if (cachedResponse) {\n return cachedResponse;\n }\n // Fall back to the network if we don't have a cached response\n // (perhaps due to manual cache cleanup).\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`The precached response for ` +\n `${getFriendlyURL(precachedURL)} in ${cacheName} was not found. ` +\n `Falling back to the network instead.`);\n }\n return fetch(precachedURL);\n });\n if (process.env.NODE_ENV !== 'production') {\n responsePromise = responsePromise.then((response) => {\n // Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Precaching is responding to: ` +\n getFriendlyURL(event.request.url));\n logger.log(`Serving the precached url: ${precachedURL}`);\n logger.groupCollapsed(`View request details here.`);\n logger.log(event.request);\n logger.groupEnd();\n logger.groupCollapsed(`View response details here.`);\n logger.log(response);\n logger.groupEnd();\n logger.groupEnd();\n return response;\n });\n }\n event.respondWith(responsePromise);\n });\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js';\nimport { precachePlugins } from './utils/precachePlugins.js';\nimport './_version.js';\nconst installListener = (event) => {\n const precacheController = getOrCreatePrecacheController();\n const plugins = precachePlugins.get();\n event.waitUntil(precacheController.install({ event, plugins })\n .catch((error) => {\n if (process.env.NODE_ENV !== 'production') {\n logger.error(`Service worker installation failed. It will ` +\n `be retried automatically during the next navigation.`);\n }\n // Re-throw the error to ensure installation fails.\n throw error;\n }));\n};\nconst activateListener = (event) => {\n const precacheController = getOrCreatePrecacheController();\n event.waitUntil(precacheController.activate());\n};\n/**\n * Adds items to the precache list, removing any duplicates and\n * stores the files in the\n * [\"precache cache\"]{@link module:workbox-core.cacheNames} when the service\n * worker installs.\n *\n * This method can be called multiple times.\n *\n * Please note: This method **will not** serve any of the cached files for you.\n * It only precaches files. To respond to a network request you call\n * [addRoute()]{@link module:workbox-precaching.addRoute}.\n *\n * If you have a single array of files to precache, you can just call\n * [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}.\n *\n * @param {Array} [entries=[]] Array of entries to precache.\n *\n * @alias workbox.precaching.precache\n */\nexport const precache = (entries) => {\n const precacheController = getOrCreatePrecacheController();\n precacheController.addToCacheList(entries);\n if (entries.length > 0) {\n // NOTE: these listeners will only be added once (even if the `precache()`\n // method is called multiple times) because event listeners are implemented\n // as a set, where each listener must be unique.\n addEventListener('install', installListener);\n addEventListener('activate', activateListener);\n }\n};\n","// @ts-ignore\ntry {\n self['workbox:range-requests:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { calculateEffectiveBoundaries } from './utils/calculateEffectiveBoundaries.js';\nimport { parseRangeHeader } from './utils/parseRangeHeader.js';\nimport './_version.js';\n/**\n * Given a `Request` and `Response` objects as input, this will return a\n * promise for a new `Response`.\n *\n * If the original `Response` already contains partial content (i.e. it has\n * a status of 206), then this assumes it already fulfills the `Range:`\n * requirements, and will return it as-is.\n *\n * @param {Request} request A request, which should contain a Range:\n * header.\n * @param {Response} originalResponse A response.\n * @return {Promise} Either a `206 Partial Content` response, with\n * the response body set to the slice of content specified by the request's\n * `Range:` header, or a `416 Range Not Satisfiable` response if the\n * conditions of the `Range:` header can't be met.\n *\n * @memberof workbox.rangeRequests\n */\nasync function createPartialResponse(request, originalResponse) {\n try {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'request',\n });\n assert.isInstance(originalResponse, Response, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'originalResponse',\n });\n }\n if (originalResponse.status === 206) {\n // If we already have a 206, then just pass it through as-is;\n // see https://github.com/GoogleChrome/workbox/issues/1720\n return originalResponse;\n }\n const rangeHeader = request.headers.get('range');\n if (!rangeHeader) {\n throw new WorkboxError('no-range-header');\n }\n const boundaries = parseRangeHeader(rangeHeader);\n const originalBlob = await originalResponse.blob();\n const effectiveBoundaries = calculateEffectiveBoundaries(originalBlob, boundaries.start, boundaries.end);\n const slicedBlob = originalBlob.slice(effectiveBoundaries.start, effectiveBoundaries.end);\n const slicedBlobSize = slicedBlob.size;\n const slicedResponse = new Response(slicedBlob, {\n // Status code 206 is for a Partial Content response.\n // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206\n status: 206,\n statusText: 'Partial Content',\n headers: originalResponse.headers,\n });\n slicedResponse.headers.set('Content-Length', String(slicedBlobSize));\n slicedResponse.headers.set('Content-Range', `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` +\n originalBlob.size);\n return slicedResponse;\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to construct a partial response; returning a ` +\n `416 Range Not Satisfiable response instead.`);\n logger.groupCollapsed(`View details here.`);\n logger.log(error);\n logger.log(request);\n logger.log(originalResponse);\n logger.groupEnd();\n }\n return new Response('', {\n status: 416,\n statusText: 'Range Not Satisfiable',\n });\n }\n}\nexport { createPartialResponse };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {string} rangeHeader A Range: header value.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the parsed value of the Range: header. If either the `start` or `end` are\n * omitted, then `null` will be returned.\n *\n * @private\n */\nfunction parseRangeHeader(rangeHeader) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(rangeHeader, 'string', {\n moduleName: 'workbox-range-requests',\n funcName: 'parseRangeHeader',\n paramName: 'rangeHeader',\n });\n }\n const normalizedRangeHeader = rangeHeader.trim().toLowerCase();\n if (!normalizedRangeHeader.startsWith('bytes=')) {\n throw new WorkboxError('unit-must-be-bytes', { normalizedRangeHeader });\n }\n // Specifying multiple ranges separate by commas is valid syntax, but this\n // library only attempts to handle a single, contiguous sequence of bytes.\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#Syntax\n if (normalizedRangeHeader.includes(',')) {\n throw new WorkboxError('single-range-only', { normalizedRangeHeader });\n }\n const rangeParts = /(\\d*)-(\\d*)/.exec(normalizedRangeHeader);\n // We need either at least one of the start or end values.\n if (!rangeParts || !(rangeParts[1] || rangeParts[2])) {\n throw new WorkboxError('invalid-range-values', { normalizedRangeHeader });\n }\n return {\n start: rangeParts[1] === '' ? undefined : Number(rangeParts[1]),\n end: rangeParts[2] === '' ? undefined : Number(rangeParts[2]),\n };\n}\nexport { parseRangeHeader };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {Blob} blob A source blob.\n * @param {number} [start] The offset to use as the start of the\n * slice.\n * @param {number} [end] The offset to use as the end of the slice.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the effective boundaries to use given the size of the blob.\n *\n * @private\n */\nfunction calculateEffectiveBoundaries(blob, start, end) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(blob, Blob, {\n moduleName: 'workbox-range-requests',\n funcName: 'calculateEffectiveBoundaries',\n paramName: 'blob',\n });\n }\n const blobSize = blob.size;\n if ((end && end > blobSize) || (start && start < 0)) {\n throw new WorkboxError('range-not-satisfiable', {\n size: blobSize,\n end,\n start,\n });\n }\n let effectiveStart;\n let effectiveEnd;\n if (start !== undefined && end !== undefined) {\n effectiveStart = start;\n // Range values are inclusive, so add 1 to the value.\n effectiveEnd = end + 1;\n }\n else if (start !== undefined && end === undefined) {\n effectiveStart = start;\n effectiveEnd = blobSize;\n }\n else if (end !== undefined && start === undefined) {\n effectiveStart = blobSize - end;\n effectiveEnd = blobSize;\n }\n return {\n start: effectiveStart,\n end: effectiveEnd,\n };\n}\nexport { calculateEffectiveBoundaries };\n","// @ts-ignore\ntry {\n self['workbox:routing:5.0.0-beta.0'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\n/**\n * The default HTTP method, 'GET', used when there's no specific method\n * configured for a route.\n *\n * @type {string}\n *\n * @private\n */\nexport const defaultMethod = 'GET';\n/**\n * The list of valid HTTP methods associated with requests that could be routed.\n *\n * @type {Array}\n *\n * @private\n */\nexport const validMethods = [\n 'DELETE',\n 'GET',\n 'HEAD',\n 'PATCH',\n 'POST',\n 'PUT',\n];\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {function()|Object} handler Either a function, or an object with a\n * 'handle' method.\n * @return {Object} An object with a handle method.\n *\n * @private\n */\nexport const normalizeHandler = (handler) => {\n if (handler && typeof handler === 'object') {\n if (process.env.NODE_ENV !== 'production') {\n assert.hasMethod(handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return handler;\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(handler, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'handler',\n });\n }\n return { handle: handler };\n }\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { defaultMethod, validMethods } from './utils/constants.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * A `Route` consists of a pair of callback functions, \"match\" and \"handler\".\n * The \"match\" callback determine if a route should be used to \"handle\" a\n * request by returning a non-falsy value if it can. The \"handler\" callback\n * is called when there is a match and should return a Promise that resolves\n * to a `Response`.\n *\n * @memberof workbox.routing\n */\nclass Route {\n /**\n * Constructor for Route class.\n *\n * @param {workbox.routing.Route~matchCallback} match\n * A callback function that determines whether the route matches a given\n * `fetch` event by returning a non-falsy value.\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resolving to a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(match, handler, method = defaultMethod) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(match, 'function', {\n moduleName: 'workbox-routing',\n className: 'Route',\n funcName: 'constructor',\n paramName: 'match',\n });\n if (method) {\n assert.isOneOf(method, validMethods, { paramName: 'method' });\n }\n }\n // These values are referenced directly by Router so cannot be\n // altered by minifification.\n this.handler = normalizeHandler(handler);\n this.match = match;\n this.method = method;\n }\n}\nexport { Route };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { Route } from './Route.js';\nimport './_version.js';\n/**\n * RegExpRoute makes it easy to create a regular expression based\n * [Route]{@link workbox.routing.Route}.\n *\n * For same-origin requests the RegExp only needs to match part of the URL. For\n * requests against third-party servers, you must define a RegExp that matches\n * the start of the URL.\n *\n * [See the module docs for info.]{@link https://developers.google.com/web/tools/workbox/modules/workbox-routing}\n *\n * @memberof workbox.routing\n * @extends workbox.routing.Route\n */\nclass RegExpRoute extends Route {\n /**\n * If the regulard expression contains\n * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},\n * th ecaptured values will be passed to the\n * [handler's]{@link workbox.routing.Route~handlerCallback} `params`\n * argument.\n *\n * @param {RegExp} regExp The regular expression to match against URLs.\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n */\n constructor(regExp, handler, method) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(regExp, RegExp, {\n moduleName: 'workbox-routing',\n className: 'RegExpRoute',\n funcName: 'constructor',\n paramName: 'pattern',\n });\n }\n const match = ({ url }) => {\n const result = regExp.exec(url.href);\n // Return immediately if there's no match.\n if (!result) {\n return;\n }\n // Require that the match start at the first character in the URL string\n // if it's a cross-origin request.\n // See https://github.com/GoogleChrome/workbox/issues/281 for the context\n // behind this behavior.\n if ((url.origin !== location.origin) && (result.index !== 0)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`The regular expression '${regExp}' only partially matched ` +\n `against the cross-origin URL '${url}'. RegExpRoute's will only ` +\n `handle cross-origin requests if they match the entire URL.`);\n }\n return;\n }\n // If the route matches, but there aren't any capture groups defined, then\n // this will return [], which is truthy and therefore sufficient to\n // indicate a match.\n // If there are capture groups, then it will return their values.\n return result.slice(1);\n };\n super(match, handler, method);\n }\n}\nexport { RegExpRoute };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { normalizeHandler } from './utils/normalizeHandler.js';\nimport './_version.js';\n/**\n * The Router can be used to process a FetchEvent through one or more\n * [Routes]{@link workbox.routing.Route} responding with a Request if\n * a matching route exists.\n *\n * If no route matches a given a request, the Router will use a \"default\"\n * handler if one is defined.\n *\n * Should the matching Route throw an error, the Router will use a \"catch\"\n * handler if one is defined to gracefully deal with issues and respond with a\n * Request.\n *\n * If a request matches multiple routes, the **earliest** registered route will\n * be used to respond to the request.\n *\n * @memberof workbox.routing\n */\nclass Router {\n /**\n * Initializes a new Router.\n */\n constructor() {\n this._routes = new Map();\n }\n /**\n * @return {Map>} routes A `Map` of HTTP\n * method name ('GET', etc.) to an array of all the corresponding `Route`\n * instances that are registered.\n */\n get routes() {\n return this._routes;\n }\n /**\n * Adds a fetch event listener to respond to events when a route matches\n * the event's request.\n */\n addFetchListener() {\n self.addEventListener('fetch', (event) => {\n const { request } = event;\n const responsePromise = this.handleRequest({ request, event });\n if (responsePromise) {\n event.respondWith(responsePromise);\n }\n });\n }\n /**\n * Adds a message event listener for URLs to cache from the window.\n * This is useful to cache resources loaded on the page prior to when the\n * service worker started controlling it.\n *\n * The format of the message data sent from the window should be as follows.\n * Where the `urlsToCache` array may consist of URL strings or an array of\n * URL string + `requestInit` object (the same as you'd pass to `fetch()`).\n *\n * ```\n * {\n * type: 'CACHE_URLS',\n * payload: {\n * urlsToCache: [\n * './script1.js',\n * './script2.js',\n * ['./script3.js', {mode: 'no-cors'}],\n * ],\n * },\n * }\n * ```\n */\n addCacheListener() {\n self.addEventListener('message', async (event) => {\n if (event.data && event.data.type === 'CACHE_URLS') {\n const { payload } = event.data;\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Caching URLs from the window`, payload.urlsToCache);\n }\n const requestPromises = Promise.all(payload.urlsToCache.map((entry) => {\n if (typeof entry === 'string') {\n entry = [entry];\n }\n const request = new Request(...entry);\n return this.handleRequest({ request });\n // TODO(philipwalton): TypeScript errors without this typecast for\n // some reason (probably a bug). The real type here should work but\n // doesn't: `Array | undefined>`.\n })); // TypeScript\n event.waitUntil(requestPromises);\n // If a MessageChannel was used, reply to the message on success.\n if (event.ports && event.ports[0]) {\n await requestPromises;\n event.ports[0].postMessage(true);\n }\n }\n });\n }\n /**\n * Apply the routing rules to a FetchEvent object to get a Response from an\n * appropriate Route's handler.\n *\n * @param {Object} options\n * @param {Request} options.request The request to handle (this is usually\n * from a fetch event, but it does not have to be).\n * @param {FetchEvent} [options.event] The event that triggered the request,\n * if applicable.\n * @return {Promise|undefined} A promise is returned if a\n * registered route can handle the request. If there is no matching\n * route and there's no `defaultHandler`, `undefined` is returned.\n */\n handleRequest({ request, event }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'handleRequest',\n paramName: 'options.request',\n });\n }\n const url = new URL(request.url, location.href);\n if (!url.protocol.startsWith('http')) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Workbox Router only supports URLs that start with 'http'.`);\n }\n return;\n }\n let { params, route } = this.findMatchingRoute({ url, request, event });\n let handler = route && route.handler;\n let debugMessages = [];\n if (process.env.NODE_ENV !== 'production') {\n if (handler) {\n debugMessages.push([\n `Found a route to handle this request:`, route,\n ]);\n if (params) {\n debugMessages.push([\n `Passing the following params to the route's handler:`, params,\n ]);\n }\n }\n }\n // If we don't have a handler because there was no matching route, then\n // fall back to defaultHandler if that's defined.\n if (!handler && this._defaultHandler) {\n if (process.env.NODE_ENV !== 'production') {\n debugMessages.push(`Failed to find a matching route. Falling ` +\n `back to the default handler.`);\n }\n handler = this._defaultHandler;\n }\n if (!handler) {\n if (process.env.NODE_ENV !== 'production') {\n // No handler so Workbox will do nothing. If logs is set of debug\n // i.e. verbose, we should print out this information.\n logger.debug(`No route found for: ${getFriendlyURL(url)}`);\n }\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n // We have a handler, meaning Workbox is going to handle the route.\n // print the routing details to the console.\n logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`);\n debugMessages.forEach((msg) => {\n if (Array.isArray(msg)) {\n logger.log(...msg);\n }\n else {\n logger.log(msg);\n }\n });\n // The Request and Response objects contains a great deal of information,\n // hide it under a group in case developers want to see it.\n logger.groupCollapsed(`View request details here.`);\n logger.log(request);\n logger.groupEnd();\n logger.groupEnd();\n }\n // Wrap in try and catch in case the handle method throws a synchronous\n // error. It should still callback to the catch handler.\n let responsePromise;\n try {\n responsePromise = handler.handle({ url, request, event, params });\n }\n catch (err) {\n responsePromise = Promise.reject(err);\n }\n if (responsePromise && this._catchHandler) {\n responsePromise = responsePromise.catch((err) => {\n if (process.env.NODE_ENV !== 'production') {\n // Still include URL here as it will be async from the console group\n // and may not make sense without the URL\n logger.groupCollapsed(`Error thrown when responding to: ` +\n ` ${getFriendlyURL(url)}. Falling back to Catch Handler.`);\n logger.error(`Error thrown by:`, route);\n logger.error(err);\n logger.groupEnd();\n }\n return this._catchHandler.handle({ url, request, event });\n });\n }\n return responsePromise;\n }\n /**\n * Checks a request and URL (and optionally an event) against the list of\n * registered routes, and if there's a match, returns the corresponding\n * route along with any params generated by the match.\n *\n * @param {Object} options\n * @param {URL} options.url\n * @param {Request} options.request The request to match.\n * @param {Event} [options.event] The corresponding event (unless N/A).\n * @return {Object} An object with `route` and `params` properties.\n * They are populated if a matching route was found or `undefined`\n * otherwise.\n */\n findMatchingRoute({ url, request, event }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(url, URL, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'findMatchingRoute',\n paramName: 'options.url',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'findMatchingRoute',\n paramName: 'options.request',\n });\n }\n const routes = this._routes.get(request.method) || [];\n for (const route of routes) {\n let params;\n let matchResult = route.match({ url, request, event });\n if (matchResult) {\n // See https://github.com/GoogleChrome/workbox/issues/2079\n params = matchResult;\n if (Array.isArray(matchResult) && matchResult.length === 0) {\n // Instead of passing an empty array in as params, use undefined.\n params = undefined;\n }\n else if ((matchResult.constructor === Object &&\n Object.keys(matchResult).length === 0)) {\n // Instead of passing an empty object in as params, use undefined.\n params = undefined;\n }\n else if (typeof matchResult === 'boolean') {\n // For the boolean value true (rather than just something truth-y),\n // don't set params.\n // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353\n params = undefined;\n }\n // Return early if have a match.\n return { route, params };\n }\n }\n // If no match was found above, return and empty object.\n return {};\n }\n /**\n * Define a default `handler` that's called when no routes explicitly\n * match the incoming request.\n *\n * Without a default handler, unmatched requests will go against the\n * network as if there were no service worker present.\n *\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setDefaultHandler(handler) {\n this._defaultHandler = normalizeHandler(handler);\n }\n /**\n * If a Route throws an error while handling a request, this `handler`\n * will be called and given a chance to provide a response.\n *\n * @param {workbox.routing.Route~handlerCallback} handler A callback\n * function that returns a Promise resulting in a Response.\n */\n setCatchHandler(handler) {\n this._catchHandler = normalizeHandler(handler);\n }\n /**\n * Registers a route with the router.\n *\n * @param {workbox.routing.Route} route The route to register.\n */\n registerRoute(route) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(route, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route, 'match', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.isType(route.handler, 'object', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route',\n });\n assert.hasMethod(route.handler, 'handle', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.handler',\n });\n assert.isType(route.method, 'string', {\n moduleName: 'workbox-routing',\n className: 'Router',\n funcName: 'registerRoute',\n paramName: 'route.method',\n });\n }\n if (!this._routes.has(route.method)) {\n this._routes.set(route.method, []);\n }\n // Give precedence to all of the earlier routes by adding this additional\n // route to the end of the array.\n this._routes.get(route.method).push(route);\n }\n /**\n * Unregisters a route with the router.\n *\n * @param {workbox.routing.Route} route The route to unregister.\n */\n unregisterRoute(route) {\n if (!this._routes.has(route.method)) {\n throw new WorkboxError('unregister-route-but-not-found-with-method', {\n method: route.method,\n });\n }\n const routeIndex = this._routes.get(route.method).indexOf(route);\n if (routeIndex > -1) {\n this._routes.get(route.method).splice(routeIndex, 1);\n }\n else {\n throw new WorkboxError('unregister-route-route-not-registered');\n }\n }\n}\nexport { Router };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { Router } from '../Router.js';\nimport '../_version.js';\nlet defaultRouter;\n/**\n * Creates a new, singleton Router instance if one does not exist. If one\n * does already exist, that instance is returned.\n *\n * @private\n * @return {Router}\n */\nexport const getOrCreateDefaultRouter = () => {\n if (!defaultRouter) {\n defaultRouter = new Router();\n // The helpers that use the default Router assume these listeners exist.\n defaultRouter.addFetchListener();\n defaultRouter.addCacheListener();\n }\n return defaultRouter;\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { Route } from './Route.js';\nimport { RegExpRoute } from './RegExpRoute.js';\nimport { getOrCreateDefaultRouter } from './utils/getOrCreateDefaultRouter.js';\nimport './_version.js';\n/**\n * Easily register a RegExp, string, or function with a caching\n * strategy to a singleton Router instance.\n *\n * This method will generate a Route for you if needed and\n * call [Router.registerRoute()]{@link\n * workbox.routing.Router#registerRoute}.\n *\n * @param {\n * RegExp|\n * string|\n * workbox.routing.Route~matchCallback|\n * workbox.routing.Route\n * } capture\n * If the capture param is a `Route`, all other arguments will be ignored.\n * @param {workbox.routing.Route~handlerCallback} [handler] A callback\n * function that returns a Promise resulting in a Response. This parameter\n * is required if `capture` is not a `Route` object.\n * @param {string} [method='GET'] The HTTP method to match the Route\n * against.\n * @return {workbox.routing.Route} The generated `Route`(Useful for\n * unregistering).\n *\n * @alias workbox.routing.registerRoute\n */\nexport const registerRoute = (capture, handler, method) => {\n let route;\n if (typeof capture === 'string') {\n const captureUrl = new URL(capture, location.href);\n if (process.env.NODE_ENV !== 'production') {\n if (!(capture.startsWith('/') || capture.startsWith('http'))) {\n throw new WorkboxError('invalid-string', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n // We want to check if Express-style wildcards are in the pathname only.\n // TODO: Remove this log message in v4.\n const valueToCheck = capture.startsWith('http') ?\n captureUrl.pathname : capture;\n // See https://github.com/pillarjs/path-to-regexp#parameters\n const wildcards = '[*:?+]';\n if (valueToCheck.match(new RegExp(`${wildcards}`))) {\n logger.debug(`The '$capture' parameter contains an Express-style wildcard ` +\n `character (${wildcards}). Strings are now always interpreted as ` +\n `exact matches; use a RegExp for partial or wildcard matches.`);\n }\n }\n const matchCallback = ({ url }) => {\n if (process.env.NODE_ENV !== 'production') {\n if ((url.pathname === captureUrl.pathname) &&\n (url.origin !== captureUrl.origin)) {\n logger.debug(`${capture} only partially matches the cross-origin URL ` +\n `${url}. This route will only handle cross-origin requests ` +\n `if they match the entire URL.`);\n }\n }\n return url.href === captureUrl.href;\n };\n // If `capture` is a string then `handler` and `method` must be present.\n route = new Route(matchCallback, handler, method);\n }\n else if (capture instanceof RegExp) {\n // If `capture` is a `RegExp` then `handler` and `method` must be present.\n route = new RegExpRoute(capture, handler, method);\n }\n else if (typeof capture === 'function') {\n // If `capture` is a function then `handler` and `method` must be present.\n route = new Route(capture, handler, method);\n }\n else if (capture instanceof Route) {\n route = capture;\n }\n else {\n throw new WorkboxError('unsupported-route-type', {\n moduleName: 'workbox-routing',\n funcName: 'registerRoute',\n paramName: 'capture',\n });\n }\n const defaultRouter = getOrCreateDefaultRouter();\n defaultRouter.registerRoute(route);\n return route;\n};\n","/**\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n **/\n\nexport const cacheName = 'media';\nexport const channelName = 'messages';\nexport const fadeConfig = {duration: 200};\nexport const urlPrefix = '/_media/';\n","/**\n * Copyright 2019 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n **/\n\nimport {cacheName} from './constants';\n\nasync function _getCachedMediaMetadata() {\n const cache = await caches.open(cacheName);\n const requests = await cache.keys();\n return Promise.all(requests.reverse().map(async (request) => {\n const response = await cache.match(request);\n return {\n contentType: response.headers.get('content-type'),\n src: request.url,\n };\n }));\n}\nconst cachedMediaMetadataPromise = _getCachedMediaMetadata();\n\nexport async function getCachedMediaMetadata(contentTypePrefix) {\n const cachedMetadata = await cachedMediaMetadataPromise;\n return cachedMetadata.filter((metadata) => metadata.contentType.startsWith(contentTypePrefix));\n}\n\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n","\n\n\n\n\n\n
\n {#await cachedMediaMetadataPromise then cachedMediaMetadatas}\n \n {/await}\n
\n\n","import {CacheOnly} from 'workbox-strategies';\nimport {clientsClaim, skipWaiting} from 'workbox-core';\nimport {precacheAndRoute} from 'workbox-precaching';\nimport {RangeRequestsPlugin} from 'workbox-range-requests';\nimport {registerRoute} from 'workbox-routing';\n\nimport {cacheName, channelName, urlPrefix} from './constants';\nimport {mimeRoute as audioRoute} from '../svelte/routes/Audio.svelte';\nimport {mimeRoute as imagesRoute} from '../svelte/routes/Images.svelte';\nimport {mimeRoute as videosRoute} from '../svelte/routes/Videos.svelte';\n\nconst broadcastChannel = BroadcastChannel ? new BroadcastChannel(channelName) : null;\n\nconst shareTargetHandler = async ({event}) => {\n if (broadcastChannel) {\n broadcastChannel.postMessage('Saving media locally...');\n }\n\n const formData = await event.request.formData();\n const mediaFiles = formData.getAll('media');\n const cache = await caches.open(cacheName);\n\n for (const mediaFile of mediaFiles) {\n // TODO: Instead of bailing, come up with a\n // default name for each possible MIME type.\n if (!mediaFile.name) {\n if (broadcastChannel) {\n broadcastChannel.postMessage('Sorry! No name found on incoming media.');\n }\n continue;\n }\n await cache.put(\n // TODO: Handle scenarios in which mediaFile.name isn't set,\n // or doesn't include a proper extension.\n `${urlPrefix}${Date.now()}-${mediaFile.name}`,\n new Response(mediaFile, {\n headers: {\n 'content-length': mediaFile.size,\n 'content-type': mediaFile.type,\n },\n })\n );\n }\n\n // Use the MIME type of the first file shared to determine where we redirect.\n const routeToRedirectTo = [\n audioRoute,\n imagesRoute,\n videosRoute,\n ].find((route) => mediaFiles[0].type.startsWith(route.mimePrefix));\n\n const redirectionUrl = routeToRedirectTo ? `/#${routeToRedirectTo.href}` : '/';\n \n // After the POST succeeds, redirect to the main page.\n return Response.redirect(redirectionUrl, 303);\n};\n\nconst cachedMediaHandler = new CacheOnly({\n cacheName,\n plugins: [\n // Support for cache requests that include a Range: header.\n new RangeRequestsPlugin(),\n ],\n});\n\nskipWaiting();\nclientsClaim();\n\n// This will be replaced by the list of files to precache by\n// the `workbox injectManifest` build step.\nprecacheAndRoute(self.__WB_MANIFEST);\n\nregisterRoute(\n '/_share-target',\n shareTargetHandler,\n 'POST'\n);\n\nregisterRoute(\n new RegExp(urlPrefix),\n cachedMediaHandler\n);\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { cacheWrapper } from 'workbox-core/_private/cacheWrapper.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { messages } from './utils/messages.js';\nimport './_version.js';\n/**\n * An implementation of a\n * [cache-only]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-only}\n * request strategy.\n *\n * This class is useful if you want to take advantage of any\n * [Workbox plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}.\n *\n * If there is no cache match, this will throw a `WorkboxError` exception.\n *\n * @memberof workbox.strategies\n */\nclass CacheOnly {\n /**\n * @param {Object} options\n * @param {string} options.cacheName Cache name to store and retrieve\n * requests. Defaults to cache names provided by\n * [workbox-core]{@link workbox.core.cacheNames}.\n * @param {Array} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}\n * to use in conjunction with this caching strategy.\n * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)\n */\n constructor(options = {}) {\n this._cacheName = cacheNames.getRuntimeName(options.cacheName);\n this._plugins = options.plugins || [];\n this._matchOptions = options.matchOptions;\n }\n /**\n * This method will perform a request strategy and follows an API that\n * will work with the\n * [Workbox Router]{@link workbox.routing.Router}.\n *\n * @param {Object} options\n * @param {Request} options.request The request to run this strategy for.\n * @param {Event} [options.event] The event that triggered the request.\n * @return {Promise}\n */\n async handle({ event, request }) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(request, Request, {\n moduleName: 'workbox-strategies',\n className: 'CacheOnly',\n funcName: 'makeRequest',\n paramName: 'request',\n });\n }\n const response = await cacheWrapper.match({\n cacheName: this._cacheName,\n request,\n event,\n matchOptions: this._matchOptions,\n plugins: this._plugins,\n });\n if (process.env.NODE_ENV !== 'production') {\n logger.groupCollapsed(messages.strategyStart('CacheOnly', request));\n if (response) {\n logger.log(`Found a cached response in the '${this._cacheName}'` +\n ` cache.`);\n messages.printFinalResponse(response);\n }\n else {\n logger.log(`No response found in the '${this._cacheName}' cache.`);\n }\n logger.groupEnd();\n }\n if (!response) {\n throw new WorkboxError('no-response', { url: request.url });\n }\n return response;\n }\n}\nexport { CacheOnly };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { createPartialResponse } from './createPartialResponse.js';\nimport './_version.js';\n/**\n * The range request plugin makes it easy for a request with a 'Range' header to\n * be fulfilled by a cached response.\n *\n * It does this by intercepting the `cachedResponseWillBeUsed` plugin callback\n * and returning the appropriate subset of the cached response body.\n *\n * @memberof workbox.rangeRequests\n */\nclass RangeRequestsPlugin {\n constructor() {\n /**\n * @param {Object} options\n * @param {Request} options.request The original request, which may or may not\n * contain a Range: header.\n * @param {Response} options.cachedResponse The complete cached response.\n * @return {Promise} If request contains a 'Range' header, then a\n * new response with status 206 whose body is a subset of `cachedResponse` is\n * returned. Otherwise, `cachedResponse` is returned as-is.\n *\n * @private\n */\n this.cachedResponseWillBeUsed = async ({ request, cachedResponse }) => {\n // Only return a sliced response if there's something valid in the cache,\n // and there's a Range: header in the request.\n if (cachedResponse && request.headers.has('range')) {\n return await createPartialResponse(request, cachedResponse);\n }\n // If there was no Range: header, or if cachedResponse wasn't valid, just\n // pass it through as-is.\n return cachedResponse;\n };\n }\n}\nexport { RangeRequestsPlugin };\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { addRoute } from './addRoute.js';\nimport { precache } from './precache.js';\nimport './_version.js';\n/**\n * This method will add entries to the precache list and add a route to\n * respond to fetch events.\n *\n * This is a convenience method that will call\n * [precache()]{@link module:workbox-precaching.precache} and\n * [addRoute()]{@link module:workbox-precaching.addRoute} in a single call.\n *\n * @param {Array} entries Array of entries to precache.\n * @param {Object} [options] See\n * [addRoute() options]{@link module:workbox-precaching.addRoute}.\n *\n * @alias workbox.precaching.precacheAndRoute\n */\nexport const precacheAndRoute = (entries, options) => {\n precache(entries);\n addRoute(options);\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Force a service worker to become active, instead of waiting. This is\n * normally used in conjunction with `clientsClaim()`.\n *\n * @alias workbox.core.skipWaiting\n */\nexport const skipWaiting = () => {\n // We need to explicitly call `self.skipWaiting()` here because we're\n // shadowing `skipWaiting` with this local function.\n addEventListener('install', () => self.skipWaiting());\n};\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * Claim any currently available clients once the service worker\n * becomes active. This is normally used in conjunction with `skipWaiting()`.\n *\n * @alias workbox.core.clientsClaim\n */\nexport const clientsClaim = () => {\n addEventListener('activate', () => self.clients.claim());\n};\n"],"names":["self","_","e","messageGenerator","code","args","msg","length","JSON","stringify","WorkboxError","Error","[object Object]","errorCode","details","super","this","name","_cacheNameDetails","googleAnalytics","precache","prefix","runtime","suffix","registration","scope","_createCacheName","cacheName","filter","value","join","cacheNames","updateDetails","fn","key","Object","keys","eachCacheNameDetail","getGoogleAnalyticsName","userCacheName","getPrecacheName","getPrefix","getRuntimeName","getSuffix","getFriendlyURL","url","urlObj","URL","String","location","href","origin","pathname","quotaErrorCallbacks","Set","pluginUtils","plugins","callbackName","plugin","matchWrapper","async","request","event","matchOptions","cache","caches","open","effectiveRequest","_getEffectiveRequest","mode","cachedResponse","match","pluginMethod","call","_isResponseSafeToCache","response","responseToCache","pluginsUsed","status","undefined","cacheKeyWillBeUsedPlugins","Request","cacheWrapper","put","updatePlugins","oldResponse","error","callback","executeQuotaErrorCallbacks","newResponse","fetchWrapper","fetch","fetchOptions","FetchEvent","preloadResponse","possiblePreloadResponse","failedFetchPlugins","originalRequest","clone","requestClone","err","thrownError","pluginFilteredRequest","fetchResponse","supportStatus","DBWrapper","version","onupgradeneeded","onversionchange","_db","_name","_version","_onupgradeneeded","_onversionchange","close","db","Promise","resolve","reject","openRequestTimedOut","setTimeout","OPEN_TIMEOUT","openRequest","indexedDB","onerror","evt","transaction","abort","result","onsuccess","bind","storeName","query","getAllKeys","count","getAllMatching","includeKeys","map","entry","index","direction","txn","done","store","objectStore","target","results","openCursor","cursor","push","continue","storeNames","type","onabort","oncomplete","method","objStore","apply","prototype","methodsToWrap","readonly","readwrite","methods","entries","IDBObjectStore","_call","copyResponse","modifier","clonedResponse","responseInit","headers","Headers","statusText","modifiedResponseInit","body","testResponse","Response","canConstructResponseFromBodyStream","blob","precachePlugins","get","newPlugins","REVISION_SEARCH_PARAM","createCacheKey","urlObject","cacheKey","revision","cacheKeyURL","originalURL","searchParams","set","PrecacheController","_cacheName","_urlsToCacheKeys","Map","_cacheKeysToIntegrities","has","firstEntry","secondEntry","integrity","toBePrecached","alreadyPrecached","alreadyCachedRequests","existingCacheKeys","precacheRequests","_addURLToCache","all","updatedURLs","item","notUpdatedURLs","currentlyCachedRequests","expectedCacheKeys","values","deletedURLs","delete","credentials","cacheWillUpdatePlugin","cacheWillUpdate","redirected","ignoreSearch","getCacheKeyForURL","precacheController","getOrCreatePrecacheController","options","urlsToCacheKeys","getURLsToCacheKeys","possibleURL","ignoreURLParametersMatching","directoryIndex","cleanURLs","urlManipulation","hash","urlWithoutIgnoredParams","paramName","some","regExp","test","removeIgnoredSearchParams","endsWith","directoryURL","cleanURL","additionalURLs","urlToAttempt","generateURLVariations","possibleCacheKey","listenerAdded","addRoute","addEventListener","precachedURL","responsePromise","then","respondWith","addFetchListener","installListener","waitUntil","install","catch","activateListener","activate","createPartialResponse","originalResponse","rangeHeader","boundaries","normalizedRangeHeader","trim","toLowerCase","startsWith","includes","rangeParts","exec","start","Number","end","parseRangeHeader","originalBlob","effectiveBoundaries","blobSize","size","effectiveStart","effectiveEnd","calculateEffectiveBoundaries","slicedBlob","slice","slicedBlobSize","slicedResponse","defaultMethod","normalizeHandler","handler","handle","Route","RegExpRoute","Router","_routes","routes","handleRequest","data","payload","requestPromises","urlsToCache","ports","postMessage","protocol","params","route","findMatchingRoute","_defaultHandler","_catchHandler","matchResult","Array","isArray","constructor","routeIndex","indexOf","splice","defaultRouter","getOrCreateDefaultRouter","addCacheListener","registerRoute","capture","captureUrl","RegExp","moduleName","funcName","requests","reverse","contentType","src","_getCachedMediaMetadata","mimeRoute","mimePrefix","broadcastChannel","BroadcastChannel","cachedMediaHandler","_plugins","_matchOptions","cachedResponseWillBeUsed","skipWaiting","clients","claim","addToCacheList","__WB_MANIFEST","mediaFiles","formData","getAll","mediaFile","Date","now","content-length","content-type","routeToRedirectTo","audioRoute","imagesRoute","videosRoute","find","redirectionUrl","redirect"],"mappings":"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"} diff --git a/test/workbox-build/static/sw-injections/basic-with-sourcemap.js.nolint b/test/workbox-build/static/sw-injections/basic-with-sourcemap.js.nolint new file mode 100644 index 000000000..a6f661f51 --- /dev/null +++ b/test/workbox-build/static/sw-injections/basic-with-sourcemap.js.nolint @@ -0,0 +1,2 @@ +!function(){"use strict";try{self["workbox:core:5.0.0-beta.0"]&&_()}catch(e){}const e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n};class t extends Error{constructor(t,n){super(e(t,n)),this.name=t,this.details=n}}const n={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:registration.scope},s=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join("-"),a={updateDetails:e=>{(e=>{for(const t of Object.keys(n))e(t)})(t=>{"string"==typeof e[t]&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||s(n.googleAnalytics),getPrecacheName:e=>e||s(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||s(n.runtime),getSuffix:()=>n.suffix},r=e=>{const t=new URL(String(e),location.href);return t.origin===location.origin?t.pathname:t.href},o=new Set;const i=(e,t)=>e.filter(e=>t in e),c=async({cacheName:e,request:t,event:n,matchOptions:s,plugins:a=[]})=>{const r=await caches.open(e),o=await l({plugins:a,request:t,mode:"read"});let i=await r.match(o,s);for(const t of a)if("cachedResponseWillBeUsed"in t){const a=t.cachedResponseWillBeUsed;i=await a.call(t,{cacheName:e,event:n,matchOptions:s,cachedResponse:i,request:o})}return i},h=async({request:e,response:t,event:n,plugins:s=[]})=>{let a=t,r=!1;for(let t of s)if("cacheWillUpdate"in t){r=!0;const s=t.cacheWillUpdate;if(!(a=await s.call(t,{request:e,response:a,event:n})))break}return r||(a=a&&200===a.status?a:void 0),a||null},l=async({request:e,mode:t,plugins:n=[]})=>{const s=i(n,"cacheKeyWillBeUsed");let a=e;for(const e of s)"string"==typeof(a=await e.cacheKeyWillBeUsed.call(e,{mode:t,request:a}))&&(a=new Request(a));return a},u={put:async({cacheName:e,request:n,response:s,event:a,plugins:u=[],matchOptions:d})=>{const f=await l({plugins:u,request:n,mode:"write"});if(!s)throw new t("cache-put-with-no-response",{url:r(f.url)});let p=await h({event:a,plugins:u,response:s,request:f});if(!p)return;const g=await caches.open(e),w=i(u,"cacheDidUpdate");let y=w.length>0?await c({cacheName:e,matchOptions:d,request:f}):null;try{await g.put(f,p)}catch(e){throw"QuotaExceededError"===e.name&&await async function(){for(const e of o)await e()}(),e}for(let t of w)await t.cacheDidUpdate.call(t,{cacheName:e,event:a,oldResponse:y,newResponse:p,request:f})},match:c},d={fetch:async({request:e,fetchOptions:n,event:s,plugins:a=[]})=>{if("string"==typeof e&&(e=new Request(e)),s instanceof FetchEvent&&s.preloadResponse){const e=await s.preloadResponse;if(e)return e}const r=i(a,"fetchDidFail"),o=r.length>0?e.clone():null;try{for(let t of a)if("requestWillFetch"in t){const n=t.requestWillFetch,a=e.clone();e=await n.call(t,{request:a,event:s})}}catch(e){throw new t("plugin-error-request-will-fetch",{thrownError:e})}let c=e.clone();try{let t;t="navigate"===e.mode?await fetch(e):await fetch(e,n);for(const e of a)"fetchDidSucceed"in e&&(t=await e.fetchDidSucceed.call(e,{event:s,request:c,response:t}));return t}catch(e){for(const t of r)await t.fetchDidFail.call(t,{error:e,event:s,originalRequest:o.clone(),request:c.clone()});throw e}}};try{self["workbox:strategies:5.0.0-beta.0"]&&_()}catch(e){}let f;class p{constructor(e,t,{onupgradeneeded:n,onversionchange:s}={}){this._db=null,this._name=e,this._version=t,this._onupgradeneeded=n,this._onversionchange=s||(()=>this.close())}get db(){return this._db}async open(){if(!this._db)return this._db=await new Promise((e,t)=>{let n=!1;setTimeout(()=>{n=!0,t(new Error("The open request was blocked and timed out"))},this.OPEN_TIMEOUT);const s=indexedDB.open(this._name,this._version);s.onerror=()=>t(s.error),s.onupgradeneeded=e=>{n?(s.transaction.abort(),s.result.close()):"function"==typeof this._onupgradeneeded&&this._onupgradeneeded(e)},s.onsuccess=()=>{const t=s.result;n?t.close():(t.onversionchange=this._onversionchange.bind(this),e(t))}}),this}async getKey(e,t){return(await this.getAllKeys(e,t,1))[0]}async getAll(e,t,n){return await this.getAllMatching(e,{query:t,count:n})}async getAllKeys(e,t,n){return(await this.getAllMatching(e,{query:t,count:n,includeKeys:!0})).map(e=>e.key)}async getAllMatching(e,{index:t,query:n=null,direction:s="next",count:a,includeKeys:r=!1}={}){return await this.transaction([e],"readonly",(o,i)=>{const c=o.objectStore(e),h=t?c.index(t):c,l=[],u=h.openCursor(n,s);u.onsuccess=()=>{const e=u.result;e?(l.push(r?e:e.value),a&&l.length>=a?i(l):e.continue()):i(l)}})}async transaction(e,t,n){return await this.open(),await new Promise((s,a)=>{const r=this._db.transaction(e,t);r.onabort=()=>a(r.error),r.oncomplete=()=>s(),n(r,e=>s(e))})}async _call(e,t,n,...s){return await this.transaction([t],n,(n,a)=>{const r=n.objectStore(t),o=r[e].apply(r,s);o.onsuccess=()=>a(o.result)})}close(){this._db&&(this._db.close(),this._db=null)}}p.prototype.OPEN_TIMEOUT=2e3;const g={readonly:["get","count","getKey","getAll","getAllKeys"],readwrite:["add","put","clear","delete"]};for(const[e,t]of Object.entries(g))for(const n of t)n in IDBObjectStore.prototype&&(p.prototype[n]=async function(t,...s){return await this._call(n,t,e,...s)});async function w(e,t){const n=e.clone(),s={headers:new Headers(n.headers),status:n.status,statusText:n.statusText},a=t?t(s):s,r=function(){if(void 0===f){const e=new Response("");if("body"in e)try{new Response(e.body),f=!0}catch(e){f=!1}f=!1}return f}()?n.body:await n.blob();return new Response(r,a)}try{self["workbox:precaching:5.0.0-beta.0"]&&_()}catch(e){}const y=[],m={get:()=>y,add(e){y.push(...e)}},v="__WB_REVISION__";function R(e){if(!e)throw new t("add-to-cache-list-unexpected-type",{entry:e});if("string"==typeof e){const t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}const{revision:n,url:s}=e;if(!s)throw new t("add-to-cache-list-unexpected-type",{entry:e});if(!n){const e=new URL(s,location.href);return{cacheKey:e.href,url:e.href}}const a=new URL(s,location.href),r=new URL(s,location.href);return a.searchParams.set(v,n),{cacheKey:a.href,url:r.href}}class b{constructor(e){this._cacheName=a.getPrecacheName(e),this._urlsToCacheKeys=new Map,this._cacheKeysToIntegrities=new Map}addToCacheList(e){for(const n of e){const{cacheKey:e,url:s}=R(n);if(this._urlsToCacheKeys.has(s)&&this._urlsToCacheKeys.get(s)!==e)throw new t("add-to-cache-list-conflicting-entries",{firstEntry:this._urlsToCacheKeys.get(s),secondEntry:e});if("string"!=typeof n&&n.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==n.integrity)throw new t("add-to-cache-list-conflicting-integrities",{url:s});this._cacheKeysToIntegrities.set(e,n.integrity)}this._urlsToCacheKeys.set(s,e)}}async install({event:e,plugins:t}={}){const n=[],s=[],a=await caches.open(this._cacheName),r=await a.keys(),o=new Set(r.map(e=>e.url));for(const[e,t]of this._urlsToCacheKeys)o.has(t)?s.push(e):n.push({cacheKey:t,url:e});const i=n.map(({cacheKey:n,url:s})=>{const a=this._cacheKeysToIntegrities.get(n);return this._addURLToCache({cacheKey:n,event:e,plugins:t,url:s,integrity:a})});return await Promise.all(i),{updatedURLs:n.map(e=>e.url),notUpdatedURLs:s}}async activate(){const e=await caches.open(this._cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),s=[];for(const a of t)n.has(a.url)||(await e.delete(a),s.push(a.url));return{deletedURLs:s}}async _addURLToCache({cacheKey:e,url:n,event:s,plugins:a,integrity:r}){const o=new Request(n,{integrity:r,cache:"reload",credentials:"same-origin"});let i,c=await d.fetch({event:s,plugins:a,request:o});for(const e of a||[])"cacheWillUpdate"in e&&(i=e);if(!(i?i.cacheWillUpdate({event:s,request:o,response:c}):c.status<400))throw new t("bad-precaching-response",{url:n,status:c.status});c.redirected&&(c=await w(c)),await u.put({event:s,plugins:a,response:c,request:e===n?o:new Request(e),cacheName:this._cacheName,matchOptions:{ignoreSearch:!0}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}createHandlerForURL(e){const n=this.getCacheKeyForURL(e);if(!n)throw new t("non-precached-url",{url:e});return async()=>{try{const e=await caches.open(this._cacheName),t=await e.match(n);if(t)return t;throw new Error(`The cache ${this._cacheName} did not have an entry `+`for ${n}.`)}catch(e){return fetch(n)}}}}let q;const U=()=>(q||(q=new b),q);const L=(e,t)=>{const n=U().getURLsToCacheKeys();for(const s of function*(e,{ignoreURLParametersMatching:t,directoryIndex:n,cleanURLs:s,urlManipulation:a}={}){const r=new URL(e,location.href);r.hash="",yield r.href;const o=function(e,t=[]){for(const n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}(r,t);if(yield o.href,n&&o.pathname.endsWith("/")){const e=new URL(o.href);e.pathname+=n,yield e.href}if(s){const e=new URL(o.href);e.pathname+=".html",yield e.href}if(a){const e=a({url:r});for(const t of e)yield t.href}}(e,t)){const e=n.get(s);if(e)return e}};let x=!1;const T=e=>{x||((({ignoreURLParametersMatching:e=[/^utm_/],directoryIndex:t="index.html",cleanURLs:n=!0,urlManipulation:s}={})=>{const r=a.getPrecacheName();addEventListener("fetch",a=>{const o=L(a.request.url,{cleanURLs:n,directoryIndex:t,ignoreURLParametersMatching:e,urlManipulation:s});if(!o)return;let i=caches.open(r).then(e=>e.match(o)).then(e=>e||fetch(o));a.respondWith(i)})})(e),x=!0)},K=e=>{const t=U(),n=m.get();e.waitUntil(t.install({event:e,plugins:n}).catch(e=>{throw e}))},N=e=>{const t=U();e.waitUntil(t.activate())};try{self["workbox:range-requests:5.0.0-beta.0"]&&_()}catch(e){}async function C(e,n){try{if(206===n.status)return n;const s=e.headers.get("range");if(!s)throw new t("no-range-header");const a=function(e){const n=e.trim().toLowerCase();if(!n.startsWith("bytes="))throw new t("unit-must-be-bytes",{normalizedRangeHeader:n});if(n.includes(","))throw new t("single-range-only",{normalizedRangeHeader:n});const s=/(\d*)-(\d*)/.exec(n);if(!s||!s[1]&&!s[2])throw new t("invalid-range-values",{normalizedRangeHeader:n});return{start:""===s[1]?void 0:Number(s[1]),end:""===s[2]?void 0:Number(s[2])}}(s),r=await n.blob(),o=function(e,n,s){const a=e.size;if(s&&s>a||n&&n<0)throw new t("range-not-satisfiable",{size:a,end:s,start:n});let r,o;return void 0!==n&&void 0!==s?(r=n,o=s+1):void 0!==n&&void 0===s?(r=n,o=a):void 0!==s&&void 0===n&&(r=a-s,o=a),{start:r,end:o}}(r,a.start,a.end),i=r.slice(o.start,o.end),c=i.size,h=new Response(i,{status:206,statusText:"Partial Content",headers:n.headers});return h.headers.set("Content-Length",String(c)),h.headers.set("Content-Range",`bytes ${o.start}-${o.end-1}/`+r.size),h}catch(e){return new Response("",{status:416,statusText:"Range Not Satisfiable"})}}try{self["workbox:routing:5.0.0-beta.0"]&&_()}catch(e){}const E="GET",P=e=>e&&"object"==typeof e?e:{handle:e};class O{constructor(e,t,n=E){this.handler=P(t),this.match=e,this.method=n}}class M extends O{constructor(e,t,n){super(({url:t})=>{const n=e.exec(t.href);if(n&&(t.origin===location.origin||0===n.index))return n.slice(1)},t,n)}}class S{constructor(){this._routes=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",e=>{const{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)})}addCacheListener(){self.addEventListener("message",async e=>{if(e.data&&"CACHE_URLS"===e.data.type){const{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(e=>{"string"==typeof e&&(e=[e]);const t=new Request(...e);return this.handleRequest({request:t})}));e.waitUntil(n),e.ports&&e.ports[0]&&(await n,e.ports[0].postMessage(!0))}})}handleRequest({request:e,event:t}){const n=new URL(e.url,location.href);if(!n.protocol.startsWith("http"))return;let s,{params:a,route:r}=this.findMatchingRoute({url:n,request:e,event:t}),o=r&&r.handler;if(!o&&this._defaultHandler&&(o=this._defaultHandler),o){try{s=o.handle({url:n,request:e,event:t,params:a})}catch(e){s=Promise.reject(e)}return s&&this._catchHandler&&(s=s.catch(s=>this._catchHandler.handle({url:n,request:e,event:t}))),s}}findMatchingRoute({url:e,request:t,event:n}){const s=this._routes.get(t.method)||[];for(const a of s){let s,r=a.match({url:e,request:t,event:n});if(r)return s=r,Array.isArray(r)&&0===r.length?s=void 0:r.constructor===Object&&0===Object.keys(r).length?s=void 0:"boolean"==typeof r&&(s=void 0),{route:a,params:s}}return{}}setDefaultHandler(e){this._defaultHandler=P(e)}setCatchHandler(e){this._catchHandler=P(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t("unregister-route-but-not-found-with-method",{method:e.method});const n=this._routes.get(e.method).indexOf(e);if(!(n>-1))throw new t("unregister-route-route-not-registered");this._routes.get(e.method).splice(n,1)}}let W;const k=()=>(W||((W=new S).addFetchListener(),W.addCacheListener()),W),A=(e,n,s)=>{let a;if("string"==typeof e){const t=new URL(e,location.href);a=new O(({url:e})=>e.href===t.href,n,s)}else if(e instanceof RegExp)a=new M(e,n,s);else if("function"==typeof e)a=new O(e,n,s);else{if(!(e instanceof O))throw new t("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});a=e}return k().registerRoute(a),a},H="media";!async function(){const e=await caches.open(H),t=await e.keys();Promise.all(t.reverse().map(async t=>{return{contentType:(await e.match(t)).headers.get("content-type"),src:t.url}}))}();const I={href:"/audio",mimePrefix:"audio/"},D={href:"/images",mimePrefix:"image/"},B={href:"/videos",mimePrefix:"video/"},F=BroadcastChannel?new BroadcastChannel("messages"):null,j=new class{constructor(e={}){this._cacheName=a.getRuntimeName(e.cacheName),this._plugins=e.plugins||[],this._matchOptions=e.matchOptions}async handle({event:e,request:n}){const s=await u.match({cacheName:this._cacheName,request:n,event:e,matchOptions:this._matchOptions,plugins:this._plugins});if(!s)throw new t("no-response",{url:n.url});return s}}({cacheName:H,plugins:[new class{constructor(){this.cachedResponseWillBeUsed=async({request:e,cachedResponse:t})=>t&&e.headers.has("range")?await C(e,t):t}}]});var z;addEventListener("install",()=>self.skipWaiting()),addEventListener("activate",()=>self.clients.claim()),(e=>{U().addToCacheList(e),e.length>0&&(addEventListener("install",K),addEventListener("activate",N))})(self.__WB_MANIFEST),T(z),A("/_share-target",async({event:e})=>{F&&F.postMessage("Saving media locally...");const t=(await e.request.formData()).getAll("media"),n=await caches.open(H);for(const e of t)e.name?await n.put(`/_media/${Date.now()}-${e.name}`,new Response(e,{headers:{"content-length":e.size,"content-type":e.type}})):F&&F.postMessage("Sorry! No name found on incoming media.");const s=[I,D,B].find(e=>t[0].type.startsWith(e.mimePrefix)),a=s?`/#${s.href}`:"/";return Response.redirect(a,303)},"POST"),A(new RegExp("/_media/"),j)}(); +//# sourceMappingURL=basic-with-sourcemap.js.map diff --git a/test/workbox-webpack-plugin/node/inject-manifest.js b/test/workbox-webpack-plugin/node/inject-manifest.js index ff67ca70d..cf1bb0f01 100644 --- a/test/workbox-webpack-plugin/node/inject-manifest.js +++ b/test/workbox-webpack-plugin/node/inject-manifest.js @@ -10,6 +10,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const WorkerPlugin = require('worker-plugin'); const expect = require('chai').expect; +const fse = require('fs-extra'); const globby = require('globby'); const upath = require('upath'); const tempy = require('tempy'); @@ -473,6 +474,112 @@ describe(`[workbox-webpack-plugin] InjectManifest (End to End)`, function() { }); }); + describe(`[workbox-webpack-plugin] Sourcemap manipulation`, function() { + it(`should update the sourcemap to account for manifest injection`, function(done) { + const outputDir = tempy.directory(); + const config = { + mode: 'production', + entry: upath.join(SRC_DIR, WEBPACK_ENTRY_FILENAME), + output: { + filename: WEBPACK_ENTRY_FILENAME, + path: outputDir, + }, + devtool: 'source-map', + plugins: [ + new InjectManifest({ + swSrc: SW_SRC, + swDest: 'service-worker.js', + }), + ], + }; + + const compiler = webpack(config); + compiler.run(async (webpackError, stats) => { + const swFile = upath.join(outputDir, 'service-worker.js'); + try { + webpackBuildCheck(webpackError, stats); + + const files = await globby(outputDir); + expect(files).to.have.length(4); + + const expectedSourcemap = await fse.readJSON( + upath.join(__dirname, '..', 'static', 'expected-service-worker.js.map')); + const actualSourcemap = await fse.readJSON(upath.join(outputDir, 'service-worker.js.map')); + expect(actualSourcemap).to.eql(expectedSourcemap); + + await validateServiceWorkerRuntime({ + swFile, + entryPoint: 'injectManifest', + expectedMethodCalls: { + precacheAndRoute: [[[{ + revision: '35ecfdff688561581ddd68a107ef1c46', + url: 'webpackEntry.js', + }], {}]], + }, + }); + + done(); + } catch (error) { + done(error); + } + }); + }); + + it(`should handle a custom output.sourceMapFilename`, function(done) { + const outputDir = tempy.directory(); + + const sourceMapFilename = upath.join('subdir', '[file].map'); + const config = { + mode: 'production', + entry: upath.join(SRC_DIR, WEBPACK_ENTRY_FILENAME), + output: { + sourceMapFilename, + filename: WEBPACK_ENTRY_FILENAME, + path: outputDir, + }, + devtool: 'source-map', + plugins: [ + new InjectManifest({ + swSrc: SW_SRC, + swDest: 'service-worker.js', + }), + ], + }; + + const compiler = webpack(config); + compiler.run(async (webpackError, stats) => { + const swFile = upath.join(outputDir, 'service-worker.js'); + try { + webpackBuildCheck(webpackError, stats); + + const files = await globby(outputDir); + expect(files).to.have.length(4); + + const expectedSourcemap = await fse.readJSON( + upath.join(__dirname, '..', 'static', 'expected-service-worker.js.map')); + const actualSourcemap = await fse.readJSON( + upath.join(outputDir, 'subdir', 'service-worker.js.map')); + expect(actualSourcemap).to.eql(expectedSourcemap); + + await validateServiceWorkerRuntime({ + swFile, + entryPoint: 'injectManifest', + expectedMethodCalls: { + precacheAndRoute: [[[{ + revision: 'cbdf84623d52128c960fd35af74cdfbc', + url: 'webpackEntry.js', + }], {}]], + }, + }); + + done(); + } catch (error) { + done(error); + } + }); + }); + }); + describe(`[workbox-webpack-plugin] Filtering via include/exclude`, function() { it(`should exclude .map and manifest.js files by default`, function(done) { const outputDir = tempy.directory(); diff --git a/test/workbox-webpack-plugin/static/expected-service-worker.js.map b/test/workbox-webpack-plugin/static/expected-service-worker.js.map new file mode 100644 index 000000000..d31d9dca0 --- /dev/null +++ b/test/workbox-webpack-plugin/static/expected-service-worker.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./test/workbox-webpack-plugin/static/sw-src.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","workbox","precaching","precacheAndRoute","self","__WB_MANIFEST"],"mappings":"aACA,IAAA,KAGA,SAAA,EAAA,GAGA,GAAA,EAAA,GACA,OAAA,EAAA,GAAA,QAGA,IAAA,EAAA,EAAA,IACA,EAAA,EACA,GAAA,EACA,YAUA,OANA,EAAA,GAAA,KAAA,EAAA,QAAA,IAAA,QAAA,GAGA,EAAA,GAAA,EAGA,EAAA,QAKA,EAAA,EAAA,EAGA,EAAA,EAAA,EAGA,EAAA,EAAA,SAAA,EAAA,EAAA,GACA,EAAA,EAAA,EAAA,IACA,OAAA,eAAA,EAAA,GAA0C,YAAA,EAAA,IAAA,KAK1C,EAAA,EAAA,SAAA,GACA,oBAAA,eAAA,aACA,OAAA,eAAA,EAAA,OAAA,aAAwD,MAAA,WAExD,OAAA,eAAA,EAAA,cAAiD,OAAA,KAQjD,EAAA,EAAA,SAAA,EAAA,GAEA,GADA,EAAA,IAAA,EAAA,EAAA,IACA,EAAA,EAAA,OAAA,EACA,KAAA,GAAA,iBAAA,QAAA,WAAA,OAAA,EACA,IAAA,EAAA,OAAA,OAAA,MAGA,GAFA,EAAA,EAAA,GACA,OAAA,eAAA,EAAA,WAAyC,YAAA,EAAA,UACzC,EAAA,GAAA,iBAAA,EAAA,QAAA,KAAA,EAAA,EAAA,EAAA,EAAA,EAAA,SAAA,GAAgH,OAAA,EAAA,IAAqB,KAAA,KAAA,IACrI,OAAA,GAIA,EAAA,EAAA,SAAA,GACA,IAAA,EAAA,KAAA,WACA,WAA2B,OAAA,EAAA,SAC3B,WAAiC,OAAA,GAEjC,OADA,EAAA,EAAA,EAAA,IAAA,GACA,GAIA,EAAA,EAAA,SAAA,EAAA,GAAsD,OAAA,OAAA,UAAA,eAAA,KAAA,EAAA,IAGtD,EAAA,EAAA,GAIA,IAAA,EAAA,mBC1EA,QAAA,WAAA,iBAAA,4DAAA","file":"service-worker.js","sourceRoot":"","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\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*/\n\nworkbox.precaching.precacheAndRoute(self.__WB_MANIFEST, {});\n"]} \ No newline at end of file