Commit e954181a by 万亚飞

init

parent a63a7fc6
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
/.idea
# dependencies
/node_modules
# production
/build
# misc
.DS_Store
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# React-webpack ------基于antd-mobile等库的一套移动端完美脚手架配置
## 超越京东的优化程度 首屏的load事件触发不到0.4s
# 包管理器使用yarn,下载后 yarn init ,然后 yarn 即可获取所有依赖
* 项目是移动端react antd-mobile better-scorll material-design redux react-redux 的结合
React的最新配置
* 实现需求:
* 识别JSX文件
* 识别箭头函数、识别async函数
* 支持Ant-Design-mobile的按需加载
* 支持babel-polyfill按需加载、better-scroll
* 支持预请求,服务端渲染的懒加载
* 支持预渲染,SSR,服务端渲染首屏,首屏load事件仅需要0.4秒不到的时间
* tree shaking 摇树优化 删除掉无用代码
* PWA功能,热刷新,安装后立即接管浏览器 离线后仍让可以访问网站 还可以在手机上添加网站到桌面使用
* CSS模块化,不怕命名冲突
* 小图片的base64处理
* 文件后缀省掉jsx js json等
* 实现React懒加载,按需加载 , 代码分割 并且支持服务端渲染
* 支持less sass stylus等预处理
* code spliting 优化首屏加载时间 不让一个文件体积过大
* 提取公共代码,打包成一个chunk
* 每个chunk有对应的chunkhash,每个文件有对应的contenthash,方便浏览器区别缓存
* 图片压缩
* CSS压缩
* 增加CSS前缀 兼容各种浏览器
* 对于各种不同文件打包输出指定文件夹下
* 缓存babel的编译结果,加快编译速度
* 每个入口文件,对应一个chunk,打包出来后对应一个文件 也是code spliting
* 删除HTML文件的注释等无用内容
* 每次编译删除旧的打包代码
* 将CSS文件单独抽取出来
* 让babel不仅缓存编译结果,还在第一次编译后开启多线程编译,极大加快构建速度
* 等等....
const { resolve } = require('path');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const os = require('os');
function resolveRoot(dir) {
return path.join(__dirname, '..', dir);
}
module.exports = {
entry: {
app: ['babel-polyfill', './src/index.js'],
vendor: ['react', 'better-scroll', 'react-redux', 'react-lazyload']
},
output: {
filename: '[name].[hash:8].js',
path: resolve(__dirname, '../build')
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
exclude: /node_modules/,
include: resolve(__dirname, '/src/js'),
loader: 'eslint-loader'
},
{
oneOf: [
{
test: /\.(html)$/,
loader: 'html-loader'
},
{
test: /\.(js|jsx)$/,
use: [
{
loader: 'thread-loader',
options: {
workers: os.cpus().length
}
},
{
loader: 'babel-loader',
options: {
//jsx语法
presets: [
'@babel/preset-react',
//tree shaking 按需加载babel-polifill
['@babel/preset-env', { modules: false, useBuiltIns: 'false', corejs: 2 }]
],
plugins: [
//支持import 懒加载
'@babel/plugin-syntax-dynamic-import',
//andt-mobile按需加载 true是less,如果不用less style的值可以写'css'
['import', { libraryName: 'antd-mobile', style: true }],
//识别class组件
['@babel/plugin-proposal-class-properties', { loose: true }]
],
cacheDirectory: true
}
}
]
},
{
test: /\.(less|css)$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: false,
localIdentName: '[local]--[hash:base64:5]'
}
},
{
loader: 'less-loader',
options: { javascriptEnabled: true }
}
]
},
{
test: /\.(jpg|jpeg|bmp|svg|png|webp|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[name].[hash:8].[ext]'
}
},
{
exclude: /\.(js|json|less|css|jsx)$/,
loader: 'file-loader',
options: {
outputPath: 'media/',
name: '[name].[hash].[ext]'
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin()
],
mode: 'development',
devServer: {
contentBase: '../build',
open: true,
port: 5000,
hot: true
},
resolve: {
extensions: ['.js', '.json', '.jsx', '.vue', '.scss', '.less'],
alias: {
'@utils': resolveRoot('src/utils/index.js'),
'@static': resolveRoot('src/static'),
'@': resolveRoot('src')
}
},
optimization: {
runtimeChunk: true,
splitChunks: {
chunks: 'all'
}
}
};
const { resolve } = require('path');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const WorkboxPlugin = require('workbox-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const PreloadWebpackPlugin = require('preload-webpack-plugin');
const os = require('os');
function resolveRoot(dir) {
return path.join(__dirname, '..', dir);
}
module.exports = {
entry: {
app: ['babel-polyfill', './src/index.js'],
vendor: ['react']
},
output: {
filename: '[name].[contenthash:8].js',
path: resolve(__dirname, '../dist')
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
exclude: /node_modules/,
include: resolve(__dirname, '/src/js'),
loader: 'eslint-loader'
},
{
oneOf: [
{
test: /\.(html)$/,
loader: 'html-loader'
},
{
test: /\.(js|jsx)$/,
use: [
{
loader: 'thread-loader',
options: {
workers: os.cpus().length
}
},
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-react',
//tree shaking 按需加载babel-polifill
['@babel/preset-env', { modules: false, useBuiltIns: 'false', corejs: 2 }]
],
plugins: [
//支持
'@babel/plugin-syntax-dynamic-import',
//true是less, 可以写'css' 如果不用less
['import', { libraryName: 'antd-mobile', style: true }],
['@babel/plugin-proposal-class-properties', { loose: true }]
],
cacheDirectory: true
}
}
]
},
{
test: /\.(css)$/,
loader: 'css-loader'
},
{
test: /\.(less)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: false,
localIdentName: '[local]--[hash:base64:5]'
}
},
{ loader: 'postcss-loader' },
{
loader: 'less-loader',
options: { javascriptEnabled: true }
}
]
},
{
test: /\.(jpg|jpeg|bmp|svg|png|webp|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[name].[hash:8].[ext]',
outputPath: '/img'
}
},
{
loader: 'img-loader',
options: {
plugins: [
require('imagemin-gifsicle')({
interlaced: false
}),
require('imagemin-mozjpeg')({
progressive: true,
arithmetic: false
}),
require('imagemin-pngquant')({
floyd: 0.5,
speed: 2
}),
require('imagemin-svgo')({
plugins: [{ removeTitle: true }, { convertPathData: false }]
})
]
}
}
]
},
{
exclude: /\.(js|json|less|css|jsx)$/,
loader: 'file-loader',
options: {
outputPath: 'media/',
name: '[name].[contenthash:8].[ext]'
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}),
new PreloadWebpackPlugin({
rel: 'preload',
as(entry) {
if (/\.css$/.test(entry)) return 'style';
if (/\.woff$/.test(entry)) return 'font';
if (/\.png$/.test(entry)) return 'image';
return 'script';
},
include: 'allChunks'
//include: ['app']
}),
new webpack.NamedModulesPlugin(),
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true,
importWorkboxFrom: 'local',
include: [/\.js$/, /\.css$/, /\.html$/, /\.jpg/, /\.jpeg/, /\.svg/, /\.webp/, /\.png/]
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css'
}),
new CleanWebpackPlugin(),
new OptimizeCssAssetsWebpackPlugin({
cssProcessPluginOptions: {
preset: ['default', { discardComments: { removeAll: true } }]
}
}),
new webpack.HashedModuleIdsPlugin()
// new PrerenderSPAPlugin({
// routes: ['/', '/home', '/shop'],
// staticDir: resolve(__dirname, '../dist')
// })
],
mode: 'production',
resolve: {
extensions: ['.js', '.json', '.jsx', '.vue', '.scss', '.less'],
alias: {
'@utils': resolveRoot('src/utils/index.js'),
'@static': resolveRoot('src/static'),
'@': resolveRoot('src')
}
},
optimization: {
runtimeChunk: true,
splitChunks: {
chunks: 'all'
}
}
};
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><meta http-equiv="X-UA-Compatible" content="ie=edge"><link rel="dns-prefetch" href="http://192.168.48.140"><link rel="dns-prefetch" href="http://192.168.48.140:8080"><title>Document</title><link href="https://cdn.bootcss.com/material-design-icons/3.0.1/iconfont/material-icons.min.css" rel="stylesheet"><link href="vendors~app.b1ea6b3e.css" rel="stylesheet"><link href="app.5d542828.css" rel="stylesheet"><link as="script" href="app.195e856e.js" rel="preload"><link as="style" href="app.5d542828.css" rel="preload"><link as="script" href="runtime~app.558836ef.js" rel="preload"><link as="script" href="runtime~vendor.2d1aae0e.js" rel="preload"><link as="script" href="vendor.291365be.js" rel="preload"><link as="script" href="vendors~app.8ec15845.js" rel="preload"><link as="style" href="vendors~app.b1ea6b3e.css" rel="preload"></head><body><div id="root"></div><script type="text/javascript" src="runtime~app.558836ef.js"></script><script type="text/javascript" src="vendors~app.8ec15845.js"></script><script type="text/javascript" src="app.195e856e.js"></script><script type="text/javascript" src="runtime~vendor.2d1aae0e.js"></script><script type="text/javascript" src="vendor.291365be.js"></script></body><script>window.onload=function(){var n=document.createElement("style"),e=document.documentElement.clientWidth/16;n.innerHTML="html{font-size:"+e+"px !important}",document.body.appendChild(n)}</script></html>
\ No newline at end of file
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "639ee00928fb124d43dbf26af523c48f",
"url": "/img/safe-bg@2x.639ee009.png"
},
{
"revision": "fe67cdda333caf2e3f9c",
"url": "app.195e856e.js"
},
{
"revision": "fe67cdda333caf2e3f9c",
"url": "app.5d542828.css"
},
{
"revision": "05704ad89623388e73f1f162b113dd39",
"url": "index.html"
},
{
"revision": "879a59d63331da3bcc85",
"url": "runtime~app.558836ef.js"
},
{
"revision": "f6b7f0f43ede93c7111d",
"url": "runtime~vendor.2d1aae0e.js"
},
{
"revision": "88a08b4e5eb5bfeac176",
"url": "vendor.291365be.js"
},
{
"revision": "5e26fc6e254e4e8624ad",
"url": "vendors~app.8ec15845.js"
},
{
"revision": "5e26fc6e254e4e8624ad",
"url": "vendors~app.b1ea6b3e.css"
}
]);
\ No newline at end of file
!function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],c=0,s=[];c<i.length;c++)f=i[c],o[f]&&s.push(o[f][0]),o[f]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var l=t[i];0!==o[l]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="";var i=window.webpackJsonp=window.webpackJsonp||[],l=i.push.bind(i);i.push=r,i=i.slice();for(var a=0;a<i.length;a++)r(i[a]);var p=l;t()}([]);
\ No newline at end of file
!function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],c=0,s=[];c<i.length;c++)f=i[c],o[f]&&s.push(o[f][0]),o[f]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var l=t[i];0!==o[l]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={2:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="";var i=window.webpackJsonp=window.webpackJsonp||[],l=i.push.bind(i);i.push=r,i=i.slice();for(var a=0;a<i.length;a++)r(i[a]);var p=l;t()}([]);
\ No newline at end of file
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("workbox-v4.3.1/workbox-sw.js");
workbox.setConfig({modulePathPrefix: "workbox-v4.3.1"});
importScripts(
"precache-manifest.f5c34b60f6b4002369ca8380e66bdfff.js"
);
workbox.core.skipWaiting();
workbox.core.clientsClaim();
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{"./node_modules/_object-assign@4.1.1@object-assign/index.js":function(e,t,n){"use strict";
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,u=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,c,i=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l<arguments.length;l++){for(var f in n=Object(arguments[l]))o.call(n,f)&&(i[f]=n[f]);if(r){c=r(n);for(var a=0;a<c.length;a++)u.call(n,c[a])&&(i[c[a]]=n[c[a]])}}return i}},"./node_modules/_react@16.8.6@react/cjs/react.production.min.js":function(e,t,n){"use strict";
/** @license React v16.8.6
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var o=n("./node_modules/_object-assign@4.1.1@object-assign/index.js"),u="function"==typeof Symbol&&Symbol.for,c=u?Symbol.for("react.element"):60103,i=u?Symbol.for("react.portal"):60106,l=u?Symbol.for("react.fragment"):60107,f=u?Symbol.for("react.strict_mode"):60108,a=u?Symbol.for("react.profiler"):60114,s=u?Symbol.for("react.provider"):60109,p=u?Symbol.for("react.context"):60110,y=u?Symbol.for("react.concurrent_mode"):60111,d=u?Symbol.for("react.forward_ref"):60112,m=u?Symbol.for("react.suspense"):60113,b=u?Symbol.for("react.memo"):60115,v=u?Symbol.for("react.lazy"):60116,h="function"==typeof Symbol&&Symbol.iterator;function _(e){for(var t=arguments.length-1,n="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=0;r<t;r++)n+="&args[]="+encodeURIComponent(arguments[r+1]);!function(e,t,n,r,o,u,c,i){if(!e){if(e=void 0,void 0===t)e=Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,u,c,i],f=0;(e=Error(t.replace(/%s/g,function(){return l[f++]}))).name="Invariant Violation"}throw e.framesToPop=1,e}}(!1,"Minified React error #"+e+"; visit %s for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ",n)}var j={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g={};function S(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||j}function w(){}function k(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||j}S.prototype.isReactComponent={},S.prototype.setState=function(e,t){"object"!==r(e)&&"function"!=typeof e&&null!=e&&_("85"),this.updater.enqueueSetState(this,e,t,"setState")},S.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},w.prototype=S.prototype;var O=k.prototype=new w;O.constructor=k,o(O,S.prototype),O.isPureReactComponent=!0;var x={current:null},$={current:null},C=Object.prototype.hasOwnProperty,P={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,n){var r=void 0,o={},u=null,i=null;if(null!=t)for(r in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(u=""+t.key),t)C.call(t,r)&&!P.hasOwnProperty(r)&&(o[r]=t[r]);var l=arguments.length-2;if(1===l)o.children=n;else if(1<l){for(var f=Array(l),a=0;a<l;a++)f[a]=arguments[a+2];o.children=f}if(e&&e.defaultProps)for(r in l=e.defaultProps)void 0===o[r]&&(o[r]=l[r]);return{$$typeof:c,type:e,key:u,ref:i,props:o,_owner:$.current}}function R(e){return"object"===r(e)&&null!==e&&e.$$typeof===c}var A=/\/+/g,I=[];function q(e,t,n,r){if(I.length){var o=I.pop();return o.result=e,o.keyPrefix=t,o.func=n,o.context=r,o.count=0,o}return{result:e,keyPrefix:t,func:n,context:r,count:0}}function M(e){e.result=null,e.keyPrefix=null,e.func=null,e.context=null,e.count=0,10>I.length&&I.push(e)}function U(e,t,n){return null==e?0:function e(t,n,o,u){var l=r(t);"undefined"!==l&&"boolean"!==l||(t=null);var f=!1;if(null===t)f=!0;else switch(l){case"string":case"number":f=!0;break;case"object":switch(t.$$typeof){case c:case i:f=!0}}if(f)return o(u,t,""===n?"."+F(t,0):n),1;if(f=0,n=""===n?".":n+":",Array.isArray(t))for(var a=0;a<t.length;a++){var s=n+F(l=t[a],a);f+=e(l,s,o,u)}else if(s=null===t||"object"!==r(t)?null:"function"==typeof(s=h&&t[h]||t["@@iterator"])?s:null,"function"==typeof s)for(t=s.call(t),a=0;!(l=t.next()).done;)f+=e(l=l.value,s=n+F(l,a++),o,u);else"object"===l&&_("31","[object Object]"==(o=""+t)?"object with keys {"+Object.keys(t).join(", ")+"}":o,"");return f}(e,"",t,n)}function F(e,t){return"object"===r(e)&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+(""+e).replace(/[=:]/g,function(e){return t[e]})}(e.key):t.toString(36)}function L(e,t){e.func.call(e.context,t,e.count++)}function N(e,t,n){var r=e.result,o=e.keyPrefix;e=e.func.call(e.context,t,e.count++),Array.isArray(e)?T(e,r,n,function(e){return e}):null!=e&&(R(e)&&(e=function(e,t){return{$$typeof:c,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(e,o+(!e.key||t&&t.key===e.key?"":(""+e.key).replace(A,"$&/")+"/")+n)),r.push(e))}function T(e,t,n,r,o){var u="";null!=n&&(u=(""+n).replace(A,"$&/")+"/"),U(e,N,t=q(t,u,r,o)),M(t)}function V(){var e=x.current;return null===e&&_("321"),e}var D={Children:{map:function(e,t,n){if(null==e)return e;var r=[];return T(e,r,null,t,n),r},forEach:function(e,t,n){if(null==e)return e;U(e,L,t=q(null,null,t,n)),M(t)},count:function(e){return U(e,function(){return null},null)},toArray:function(e){var t=[];return T(e,t,null,function(e){return e}),t},only:function(e){return R(e)||_("143"),e}},createRef:function(){return{current:null}},Component:S,PureComponent:k,createContext:function(e,t){return void 0===t&&(t=null),(e={$$typeof:p,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:s,_context:e},e.Consumer=e},forwardRef:function(e){return{$$typeof:d,render:e}},lazy:function(e){return{$$typeof:v,_ctor:e,_status:-1,_result:null}},memo:function(e,t){return{$$typeof:b,type:e,compare:void 0===t?null:t}},useCallback:function(e,t){return V().useCallback(e,t)},useContext:function(e,t){return V().useContext(e,t)},useEffect:function(e,t){return V().useEffect(e,t)},useImperativeHandle:function(e,t,n){return V().useImperativeHandle(e,t,n)},useDebugValue:function(){},useLayoutEffect:function(e,t){return V().useLayoutEffect(e,t)},useMemo:function(e,t){return V().useMemo(e,t)},useReducer:function(e,t,n){return V().useReducer(e,t,n)},useRef:function(e){return V().useRef(e)},useState:function(e){return V().useState(e)},Fragment:l,StrictMode:f,Suspense:m,createElement:E,cloneElement:function(e,t,n){null==e&&_("267",e);var r=void 0,u=o({},e.props),i=e.key,l=e.ref,f=e._owner;if(null!=t){void 0!==t.ref&&(l=t.ref,f=$.current),void 0!==t.key&&(i=""+t.key);var a=void 0;for(r in e.type&&e.type.defaultProps&&(a=e.type.defaultProps),t)C.call(t,r)&&!P.hasOwnProperty(r)&&(u[r]=void 0===t[r]&&void 0!==a?a[r]:t[r])}if(1===(r=arguments.length-2))u.children=n;else if(1<r){a=Array(r);for(var s=0;s<r;s++)a[s]=arguments[s+2];u.children=a}return{$$typeof:c,type:e.type,key:i,ref:l,props:u,_owner:f}},createFactory:function(e){var t=E.bind(null,e);return t.type=e,t},isValidElement:R,version:"16.8.6",unstable_ConcurrentMode:y,unstable_Profiler:a,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{ReactCurrentDispatcher:x,ReactCurrentOwner:$,assign:o}},z={default:D},B=z&&D||z;e.exports=B.default||B},"./node_modules/_react@16.8.6@react/index.js":function(e,t,n){"use strict";e.exports=n("./node_modules/_react@16.8.6@react/cjs/react.production.min.js")},1:function(e,t,n){e.exports=n("./node_modules/_react@16.8.6@react/index.js")}},[[1,2]]]);
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
this.workbox=this.workbox||{},this.workbox.backgroundSync=function(t,e,s){"use strict";try{self["workbox:background-sync:4.3.1"]&&_()}catch(t){}const i=3,n="workbox-background-sync",a="requests",r="queueName";class c{constructor(t){this.t=t,this.s=new s.DBWrapper(n,i,{onupgradeneeded:this.i})}async pushEntry(t){delete t.id,t.queueName=this.t,await this.s.add(a,t)}async unshiftEntry(t){const[e]=await this.s.getAllMatching(a,{count:1});e?t.id=e.id-1:delete t.id,t.queueName=this.t,await this.s.add(a,t)}async popEntry(){return this.h({direction:"prev"})}async shiftEntry(){return this.h({direction:"next"})}async getAll(){return await this.s.getAllMatching(a,{index:r,query:IDBKeyRange.only(this.t)})}async deleteEntry(t){await this.s.delete(a,t)}async h({direction:t}){const[e]=await this.s.getAllMatching(a,{direction:t,index:r,query:IDBKeyRange.only(this.t),count:1});if(e)return await this.deleteEntry(e.id),e}i(t){const e=t.target.result;t.oldVersion>0&&t.oldVersion<i&&e.objectStoreNames.contains(a)&&e.deleteObjectStore(a),e.createObjectStore(a,{autoIncrement:!0,keyPath:"id"}).createIndex(r,r,{unique:!1})}}const h=["method","referrer","referrerPolicy","mode","credentials","cache","redirect","integrity","keepalive"];class o{static async fromRequest(t){const e={url:t.url,headers:{}};"GET"!==t.method&&(e.body=await t.clone().arrayBuffer());for(const[s,i]of t.headers.entries())e.headers[s]=i;for(const s of h)void 0!==t[s]&&(e[s]=t[s]);return new o(e)}constructor(t){"navigate"===t.mode&&(t.mode="same-origin"),this.o=t}toObject(){const t=Object.assign({},this.o);return t.headers=Object.assign({},this.o.headers),t.body&&(t.body=t.body.slice(0)),t}toRequest(){return new Request(this.o.url,this.o)}clone(){return new o(this.toObject())}}const u="workbox-background-sync",y=10080,w=new Set;class d{constructor(t,{onSync:s,maxRetentionTime:i}={}){if(w.has(t))throw new e.WorkboxError("duplicate-queue-name",{name:t});w.add(t),this.u=t,this.l=s||this.replayRequests,this.q=i||y,this.m=new c(this.u),this.p()}get name(){return this.u}async pushRequest(t){await this.g(t,"push")}async unshiftRequest(t){await this.g(t,"unshift")}async popRequest(){return this.R("pop")}async shiftRequest(){return this.R("shift")}async getAll(){const t=await this.m.getAll(),e=Date.now(),s=[];for(const i of t){const t=60*this.q*1e3;e-i.timestamp>t?await this.m.deleteEntry(i.id):s.push(f(i))}return s}async g({request:t,metadata:e,timestamp:s=Date.now()},i){const n={requestData:(await o.fromRequest(t.clone())).toObject(),timestamp:s};e&&(n.metadata=e),await this.m[`${i}Entry`](n),this.k?this.D=!0:await this.registerSync()}async R(t){const e=Date.now(),s=await this.m[`${t}Entry`]();if(s){const i=60*this.q*1e3;return e-s.timestamp>i?this.R(t):f(s)}}async replayRequests(){let t;for(;t=await this.shiftRequest();)try{await fetch(t.request.clone())}catch(s){throw await this.unshiftRequest(t),new e.WorkboxError("queue-replay-failed",{name:this.u})}}async registerSync(){if("sync"in registration)try{await registration.sync.register(`${u}:${this.u}`)}catch(t){}}p(){"sync"in registration?self.addEventListener("sync",t=>{if(t.tag===`${u}:${this.u}`){const e=async()=>{let e;this.k=!0;try{await this.l({queue:this})}catch(t){throw e=t}finally{!this.D||e&&!t.lastChance||await this.registerSync(),this.k=!1,this.D=!1}};t.waitUntil(e())}}):this.l({queue:this})}static get _(){return w}}const f=t=>{const e={request:new o(t.requestData).toRequest(),timestamp:t.timestamp};return t.metadata&&(e.metadata=t.metadata),e};return t.Queue=d,t.Plugin=class{constructor(...t){this.v=new d(...t),this.fetchDidFail=this.fetchDidFail.bind(this)}async fetchDidFail({request:t}){await this.v.pushRequest({request:t})}},t}({},workbox.core._private,workbox.core._private);
//# sourceMappingURL=workbox-background-sync.prod.js.map
this.workbox=this.workbox||{},this.workbox.broadcastUpdate=function(e,t){"use strict";try{self["workbox:broadcast-update:4.3.1"]&&_()}catch(e){}const s=(e,t,s)=>{return!s.some(s=>e.headers.has(s)&&t.headers.has(s))||s.every(s=>{const n=e.headers.has(s)===t.headers.has(s),a=e.headers.get(s)===t.headers.get(s);return n&&a})},n="workbox",a=1e4,i=["content-length","etag","last-modified"],o=async({channel:e,cacheName:t,url:s})=>{const n={type:"CACHE_UPDATED",meta:"workbox-broadcast-update",payload:{cacheName:t,updatedURL:s}};if(e)e.postMessage(n);else{const e=await clients.matchAll({type:"window"});for(const t of e)t.postMessage(n)}};class c{constructor({headersToCheck:e,channelName:t,deferNoticationTimeout:s}={}){this.t=e||i,this.s=t||n,this.i=s||a,this.o()}notifyIfUpdated({oldResponse:e,newResponse:t,url:n,cacheName:a,event:i}){if(!s(e,t,this.t)){const e=(async()=>{i&&i.request&&"navigate"===i.request.mode&&await this.h(i),await this.l({channel:this.u(),cacheName:a,url:n})})();if(i)try{i.waitUntil(e)}catch(e){}return e}}async l(e){await o(e)}u(){return"BroadcastChannel"in self&&!this.p&&(this.p=new BroadcastChannel(this.s)),this.p}h(e){if(!this.m.has(e)){const s=new t.Deferred;this.m.set(e,s);const n=setTimeout(()=>{s.resolve()},this.i);s.promise.then(()=>clearTimeout(n))}return this.m.get(e).promise}o(){this.m=new Map,self.addEventListener("message",e=>{if("WINDOW_READY"===e.data.type&&"workbox-window"===e.data.meta&&this.m.size>0){for(const e of this.m.values())e.resolve();this.m.clear()}})}}return e.BroadcastCacheUpdate=c,e.Plugin=class{constructor(e){this.l=new c(e)}cacheDidUpdate({cacheName:e,oldResponse:t,newResponse:s,request:n,event:a}){t&&this.l.notifyIfUpdated({cacheName:e,oldResponse:t,newResponse:s,event:a,url:n.url})}},e.broadcastUpdate=o,e.responsesAreSame=s,e}({},workbox.core._private);
//# sourceMappingURL=workbox-broadcast-update.prod.js.map
this.workbox = this.workbox || {};
this.workbox.cacheableResponse = (function (exports, WorkboxError_mjs, assert_mjs, getFriendlyURL_mjs, logger_mjs) {
'use strict';
try {
self['workbox:cacheable-response:4.3.1'] && _();
} catch (e) {} // eslint-disable-line
/*
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.
*/
/**
* This class allows you to set up rules determining what
* status codes and/or headers need to be present in order for a
* [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
* to be considered cacheable.
*
* @memberof workbox.cacheableResponse
*/
class CacheableResponse {
/**
* To construct a new CacheableResponse instance you must provide at least
* one of the `config` properties.
*
* If both `statuses` and `headers` are specified, then both conditions must
* be met for the `Response` to be considered cacheable.
*
* @param {Object} config
* @param {Array<number>} [config.statuses] One or more status codes that a
* `Response` can have and be considered cacheable.
* @param {Object<string,string>} [config.headers] A mapping of header names
* and expected values that a `Response` can have and be considered cacheable.
* If multiple headers are provided, only one needs to be present.
*/
constructor(config = {}) {
{
if (!(config.statuses || config.headers)) {
throw new WorkboxError_mjs.WorkboxError('statuses-or-headers-required', {
moduleName: 'workbox-cacheable-response',
className: 'CacheableResponse',
funcName: 'constructor'
});
}
if (config.statuses) {
assert_mjs.assert.isArray(config.statuses, {
moduleName: 'workbox-cacheable-response',
className: 'CacheableResponse',
funcName: 'constructor',
paramName: 'config.statuses'
});
}
if (config.headers) {
assert_mjs.assert.isType(config.headers, 'object', {
moduleName: 'workbox-cacheable-response',
className: 'CacheableResponse',
funcName: 'constructor',
paramName: 'config.headers'
});
}
}
this._statuses = config.statuses;
this._headers = config.headers;
}
/**
* Checks a response to see whether it's cacheable or not, based on this
* object's configuration.
*
* @param {Response} response The response whose cacheability is being
* checked.
* @return {boolean} `true` if the `Response` is cacheable, and `false`
* otherwise.
*/
isResponseCacheable(response) {
{
assert_mjs.assert.isInstance(response, Response, {
moduleName: 'workbox-cacheable-response',
className: 'CacheableResponse',
funcName: 'isResponseCacheable',
paramName: 'response'
});
}
let cacheable = true;
if (this._statuses) {
cacheable = this._statuses.includes(response.status);
}
if (this._headers && cacheable) {
cacheable = Object.keys(this._headers).some(headerName => {
return response.headers.get(headerName) === this._headers[headerName];
});
}
{
if (!cacheable) {
logger_mjs.logger.groupCollapsed(`The request for ` + `'${getFriendlyURL_mjs.getFriendlyURL(response.url)}' returned a response that does ` + `not meet the criteria for being cached.`);
logger_mjs.logger.groupCollapsed(`View cacheability criteria here.`);
logger_mjs.logger.log(`Cacheable statuses: ` + JSON.stringify(this._statuses));
logger_mjs.logger.log(`Cacheable headers: ` + JSON.stringify(this._headers, null, 2));
logger_mjs.logger.groupEnd();
const logFriendlyHeaders = {};
response.headers.forEach((value, key) => {
logFriendlyHeaders[key] = value;
});
logger_mjs.logger.groupCollapsed(`View response status and headers here.`);
logger_mjs.logger.log(`Response status: ` + response.status);
logger_mjs.logger.log(`Response headers: ` + JSON.stringify(logFriendlyHeaders, null, 2));
logger_mjs.logger.groupEnd();
logger_mjs.logger.groupCollapsed(`View full response details here.`);
logger_mjs.logger.log(response.headers);
logger_mjs.logger.log(response);
logger_mjs.logger.groupEnd();
logger_mjs.logger.groupEnd();
}
}
return cacheable;
}
}
/*
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.
*/
/**
* A class implementing the `cacheWillUpdate` lifecycle callback. This makes it
* easier to add in cacheability checks to requests made via Workbox's built-in
* strategies.
*
* @memberof workbox.cacheableResponse
*/
class Plugin {
/**
* To construct a new cacheable response Plugin instance you must provide at
* least one of the `config` properties.
*
* If both `statuses` and `headers` are specified, then both conditions must
* be met for the `Response` to be considered cacheable.
*
* @param {Object} config
* @param {Array<number>} [config.statuses] One or more status codes that a
* `Response` can have and be considered cacheable.
* @param {Object<string,string>} [config.headers] A mapping of header names
* and expected values that a `Response` can have and be considered cacheable.
* If multiple headers are provided, only one needs to be present.
*/
constructor(config) {
this._cacheableResponse = new CacheableResponse(config);
}
/**
* @param {Object} options
* @param {Response} options.response
* @return {boolean}
* @private
*/
cacheWillUpdate({
response
}) {
if (this._cacheableResponse.isResponseCacheable(response)) {
return response;
}
return null;
}
}
/*
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.
*/
exports.CacheableResponse = CacheableResponse;
exports.Plugin = Plugin;
return exports;
}({}, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private));
//# sourceMappingURL=workbox-cacheable-response.dev.js.map
this.workbox=this.workbox||{},this.workbox.cacheableResponse=function(t){"use strict";try{self["workbox:cacheable-response:4.3.1"]&&_()}catch(t){}class s{constructor(t={}){this.t=t.statuses,this.s=t.headers}isResponseCacheable(t){let s=!0;return this.t&&(s=this.t.includes(t.status)),this.s&&s&&(s=Object.keys(this.s).some(s=>t.headers.get(s)===this.s[s])),s}}return t.CacheableResponse=s,t.Plugin=class{constructor(t){this.i=new s(t)}cacheWillUpdate({response:t}){return this.i.isResponseCacheable(t)?t:null}},t}({});
//# sourceMappingURL=workbox-cacheable-response.prod.js.map
{"version":3,"file":"workbox-cacheable-response.prod.js","sources":["../_version.mjs","../CacheableResponse.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:cacheable-response:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * This class allows you to set up rules determining what\n * status codes and/or headers need to be present in order for a\n * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * to be considered cacheable.\n *\n * @memberof workbox.cacheableResponse\n */\nclass CacheableResponse {\n /**\n * To construct a new CacheableResponse instance you must provide at least\n * one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array<number>} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object<string,string>} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.statuses || config.headers)) {\n throw new WorkboxError('statuses-or-headers-required', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n });\n }\n\n if (config.statuses) {\n assert.isArray(config.statuses, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.statuses',\n });\n }\n\n if (config.headers) {\n assert.isType(config.headers, 'object', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.headers',\n });\n }\n }\n\n this._statuses = config.statuses;\n this._headers = config.headers;\n }\n\n /**\n * Checks a response to see whether it's cacheable or not, based on this\n * object's configuration.\n *\n * @param {Response} response The response whose cacheability is being\n * checked.\n * @return {boolean} `true` if the `Response` is cacheable, and `false`\n * otherwise.\n */\n isResponseCacheable(response) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(response, Response, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'isResponseCacheable',\n paramName: 'response',\n });\n }\n\n let cacheable = true;\n\n if (this._statuses) {\n cacheable = this._statuses.includes(response.status);\n }\n\n if (this._headers && cacheable) {\n cacheable = Object.keys(this._headers).some((headerName) => {\n return response.headers.get(headerName) === this._headers[headerName];\n });\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!cacheable) {\n logger.groupCollapsed(`The request for ` +\n `'${getFriendlyURL(response.url)}' returned a response that does ` +\n `not meet the criteria for being cached.`);\n\n logger.groupCollapsed(`View cacheability criteria here.`);\n logger.log(`Cacheable statuses: ` +\n JSON.stringify(this._statuses));\n logger.log(`Cacheable headers: ` +\n JSON.stringify(this._headers, null, 2));\n logger.groupEnd();\n\n const logFriendlyHeaders = {};\n response.headers.forEach((value, key) => {\n logFriendlyHeaders[key] = value;\n });\n\n logger.groupCollapsed(`View response status and headers here.`);\n logger.log(`Response status: ` + response.status);\n logger.log(`Response headers: ` +\n JSON.stringify(logFriendlyHeaders, null, 2));\n logger.groupEnd();\n\n logger.groupCollapsed(`View full response details here.`);\n logger.log(response.headers);\n logger.log(response);\n logger.groupEnd();\n\n logger.groupEnd();\n }\n }\n\n return cacheable;\n }\n}\n\nexport {CacheableResponse};\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\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it\n * easier to add in cacheability checks to requests made via Workbox's built-in\n * strategies.\n *\n * @memberof workbox.cacheableResponse\n */\nclass Plugin {\n /**\n * To construct a new cacheable response Plugin instance you must provide at\n * least one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array<number>} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object<string,string>} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config) {\n this._cacheableResponse = new CacheableResponse(config);\n }\n\n /**\n * @param {Object} options\n * @param {Response} options.response\n * @return {boolean}\n * @private\n */\n cacheWillUpdate({response}) {\n if (this._cacheableResponse.isResponseCacheable(response)) {\n return response;\n }\n return null;\n }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","CacheableResponse","constructor","config","_statuses","statuses","_headers","headers","isResponseCacheable","response","cacheable","this","includes","status","Object","keys","some","headerName","get","_cacheableResponse","cacheWillUpdate"],"mappings":"sFAAA,IAAIA,KAAK,qCAAqCC,IAAI,MAAMC,ICsBxD,MAAMC,EAeJC,YAAYC,EAAS,SA6BdC,EAAYD,EAAOE,cACnBC,EAAWH,EAAOI,QAYzBC,oBAAoBC,OAUdC,GAAY,SAEZC,KAAKP,IACPM,EAAYC,KAAKP,EAAUQ,SAASH,EAASI,SAG3CF,KAAKL,GAAYI,IACnBA,EAAYI,OAAOC,KAAKJ,KAAKL,GAAUU,KAAMC,GACpCR,EAASF,QAAQW,IAAID,KAAgBN,KAAKL,EAASW,KAqCvDP,yCCpHX,MAeER,YAAYC,QACLgB,EAAqB,IAAIlB,EAAkBE,GASlDiB,iBAAgBX,SAACA,WACXE,KAAKQ,EAAmBX,oBAAoBC,GACvCA,EAEF"}
\ No newline at end of file
this.workbox=this.workbox||{},this.workbox.core=function(e){"use strict";try{self["workbox:core:4.3.1"]&&_()}catch(e){}const t=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n};class n extends Error{constructor(e,n){super(t(e,n)),this.name=e,this.details=n}}const s=new Set;const r={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:self.registration.scope},a=e=>[r.prefix,e,r.suffix].filter(e=>e.length>0).join("-"),i={updateDetails:e=>{Object.keys(r).forEach(t=>{void 0!==e[t]&&(r[t]=e[t])})},getGoogleAnalyticsName:e=>e||a(r.googleAnalytics),getPrecacheName:e=>e||a(r.precache),getPrefix:()=>r.prefix,getRuntimeName:e=>e||a(r.runtime),getSuffix:()=>r.suffix},c=e=>{const t=new URL(e,location);return t.origin===location.origin?t.pathname:t.href};async function o(){for(const e of s)await e()}const l="cacheDidUpdate",u="cacheKeyWillBeUsed",h="cacheWillUpdate",f="cachedResponseWillBeUsed",w="fetchDidFail",g="fetchDidSucceed",d="requestWillFetch",p=(e,t)=>e.filter(e=>t in e),y=async({cacheName:e,request:t,event:n,matchOptions:s,plugins:r=[]})=>{const a=await caches.open(e),i=await q({plugins:r,request:t,mode:"read"});let c=await a.match(i,s);for(const t of r)f in t&&(c=await t[f].call(t,{cacheName:e,event:n,matchOptions:s,cachedResponse:c,request:i}));return c},m=async({request:e,response:t,event:n,plugins:s})=>{let r=t,a=!1;for(let t of s)if(h in t&&(a=!0,!(r=await t[h].call(t,{request:e,response:r,event:n}))))break;return a||(r=200===r.status?r:null),r||null},q=async({request:e,mode:t,plugins:n})=>{const s=p(n,u);let r=e;for(const e of s)"string"==typeof(r=await e[u].call(e,{mode:t,request:r}))&&(r=new Request(r));return r},v={put:async({cacheName:e,request:t,response:s,event:r,plugins:a=[],matchOptions:i}={})=>{const u=await q({plugins:a,request:t,mode:"write"});if(!s)throw new n("cache-put-with-no-response",{url:c(u.url)});let h=await m({event:r,plugins:a,response:s,request:u});if(!h)return;const f=await caches.open(e),w=p(a,l);let g=w.length>0?await y({cacheName:e,matchOptions:i,request:u}):null;try{await f.put(u,h)}catch(e){throw"QuotaExceededError"===e.name&&await o(),e}for(let t of w)await t[l].call(t,{cacheName:e,event:r,oldResponse:g,newResponse:h,request:u})},match:y};class x{constructor(e,t,{onupgradeneeded:n,onversionchange:s=this.t}={}){this.s=e,this.i=t,this.o=n,this.t=s,this.l=null}get db(){return this.l}async open(){if(!this.l)return this.l=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.s,this.i);s.onerror=(()=>t(s.error)),s.onupgradeneeded=(e=>{n?(s.transaction.abort(),e.target.result.close()):this.o&&this.o(e)}),s.onsuccess=(({target:t})=>{const s=t.result;n?s.close():(s.onversionchange=this.t.bind(this),e(s))})}),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(({key:e})=>e)}async getAllMatching(e,{index:t,query:n=null,direction:s="next",count:r,includeKeys:a}={}){return await this.transaction([e],"readonly",(i,c)=>{const o=i.objectStore(e),l=t?o.index(t):o,u=[];l.openCursor(n,s).onsuccess=(({target:e})=>{const t=e.result;if(t){const{primaryKey:e,key:n,value:s}=t;u.push(a?{primaryKey:e,key:n,value:s}:s),r&&u.length>=r?c(u):t.continue()}else c(u)})})}async transaction(e,t,n){return await this.open(),await new Promise((s,r)=>{const a=this.l.transaction(e,t);a.onabort=(({target:e})=>r(e.error)),a.oncomplete=(()=>s()),n(a,e=>s(e))})}async u(e,t,n,...s){return await this.transaction([t],n,(n,r)=>{n.objectStore(t)[e](...s).onsuccess=(({target:e})=>{r(e.result)})})}t(){this.close()}close(){this.l&&(this.l.close(),this.l=null)}}x.prototype.OPEN_TIMEOUT=2e3;const b={readonly:["get","count","getKey","getAll","getAllKeys"],readwrite:["add","put","clear","delete"]};for(const[e,t]of Object.entries(b))for(const n of t)n in IDBObjectStore.prototype&&(x.prototype[n]=async function(t,...s){return await this.u(n,t,e,...s)});const D={fetch:async({request:e,fetchOptions:t,event:s,plugins:r=[]})=>{if(s&&s.preloadResponse){const e=await s.preloadResponse;if(e)return e}"string"==typeof e&&(e=new Request(e));const a=p(r,w),i=a.length>0?e.clone():null;try{for(let t of r)d in t&&(e=await t[d].call(t,{request:e.clone(),event:s}))}catch(e){throw new n("plugin-error-request-will-fetch",{thrownError:e})}let c=e.clone();try{let n;n="navigate"===e.mode?await fetch(e):await fetch(e,t);for(const e of r)g in e&&(n=await e[g].call(e,{event:s,request:c,response:n}));return n}catch(e){for(const t of a)await t[w].call(t,{error:e,event:s,originalRequest:i.clone(),request:c.clone()});throw e}}};var E=Object.freeze({assert:null,cacheNames:i,cacheWrapper:v,DBWrapper:x,Deferred:class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},deleteDatabase:async e=>{await new Promise((t,n)=>{const s=indexedDB.deleteDatabase(e);s.onerror=(({target:e})=>{n(e.error)}),s.onblocked=(()=>{n(new Error("Delete blocked"))}),s.onsuccess=(()=>{t()})})},executeQuotaErrorCallbacks:o,fetchWrapper:D,getFriendlyURL:c,logger:null,WorkboxError:n});const N={get googleAnalytics(){return i.getGoogleAnalyticsName()},get precache(){return i.getPrecacheName()},get prefix(){return i.getPrefix()},get runtime(){return i.getRuntimeName()},get suffix(){return i.getSuffix()}};try{self.workbox.v=self.workbox.v||{}}catch(e){}return e._private=E,e.clientsClaim=(()=>{addEventListener("activate",()=>clients.claim())}),e.cacheNames=N,e.registerQuotaErrorCallback=function(e){s.add(e)},e.setCacheNameDetails=(e=>{i.updateDetails(e)}),e.skipWaiting=(()=>{addEventListener("install",()=>self.skipWaiting())}),e}({});
//# sourceMappingURL=workbox-core.prod.js.map
this.workbox=this.workbox||{},this.workbox.expiration=function(t,e,s,i,a,n){"use strict";try{self["workbox:expiration:4.3.1"]&&_()}catch(t){}const h="workbox-expiration",c="cache-entries",r=t=>{const e=new URL(t,location);return e.hash="",e.href};class o{constructor(t){this.t=t,this.s=new e.DBWrapper(h,1,{onupgradeneeded:t=>this.i(t)})}i(t){const e=t.target.result.createObjectStore(c,{keyPath:"id"});e.createIndex("cacheName","cacheName",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1}),s.deleteDatabase(this.t)}async setTimestamp(t,e){t=r(t),await this.s.put(c,{url:t,timestamp:e,cacheName:this.t,id:this.h(t)})}async getTimestamp(t){return(await this.s.get(c,this.h(t))).timestamp}async expireEntries(t,e){const s=await this.s.transaction(c,"readwrite",(s,i)=>{const a=s.objectStore(c),n=[];let h=0;a.index("timestamp").openCursor(null,"prev").onsuccess=(({target:s})=>{const a=s.result;if(a){const s=a.value;s.cacheName===this.t&&(t&&s.timestamp<t||e&&h>=e?n.push(a.value):h++),a.continue()}else i(n)})}),i=[];for(const t of s)await this.s.delete(c,t.id),i.push(t.url);return i}h(t){return this.t+"|"+r(t)}}class u{constructor(t,e={}){this.o=!1,this.u=!1,this.l=e.maxEntries,this.p=e.maxAgeSeconds,this.t=t,this.m=new o(t)}async expireEntries(){if(this.o)return void(this.u=!0);this.o=!0;const t=this.p?Date.now()-1e3*this.p:void 0,e=await this.m.expireEntries(t,this.l),s=await caches.open(this.t);for(const t of e)await s.delete(t);this.o=!1,this.u&&(this.u=!1,this.expireEntries())}async updateTimestamp(t){await this.m.setTimestamp(t,Date.now())}async isURLExpired(t){return await this.m.getTimestamp(t)<Date.now()-1e3*this.p}async delete(){this.u=!1,await this.m.expireEntries(1/0)}}return t.CacheExpiration=u,t.Plugin=class{constructor(t={}){this.D=t,this.p=t.maxAgeSeconds,this.g=new Map,t.purgeOnQuotaError&&n.registerQuotaErrorCallback(()=>this.deleteCacheAndMetadata())}k(t){if(t===a.cacheNames.getRuntimeName())throw new i.WorkboxError("expire-custom-caches-only");let e=this.g.get(t);return e||(e=new u(t,this.D),this.g.set(t,e)),e}cachedResponseWillBeUsed({event:t,request:e,cacheName:s,cachedResponse:i}){if(!i)return null;let a=this.N(i);const n=this.k(s);n.expireEntries();const h=n.updateTimestamp(e.url);if(t)try{t.waitUntil(h)}catch(t){}return a?i:null}N(t){if(!this.p)return!0;const e=this._(t);return null===e||e>=Date.now()-1e3*this.p}_(t){if(!t.headers.has("date"))return null;const e=t.headers.get("date"),s=new Date(e).getTime();return isNaN(s)?null:s}async cacheDidUpdate({cacheName:t,request:e}){const s=this.k(t);await s.updateTimestamp(e.url),await s.expireEntries()}async deleteCacheAndMetadata(){for(const[t,e]of this.g)await caches.delete(t),await e.delete();this.g=new Map}},t}({},workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private,workbox.core);
//# sourceMappingURL=workbox-expiration.prod.js.map
this.workbox = this.workbox || {};
this.workbox.navigationPreload = (function (exports, logger_mjs) {
'use strict';
try {
self['workbox:navigation-preload:4.3.1'] && _();
} catch (e) {} // eslint-disable-line
/*
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.
*/
/**
* @return {boolean} Whether or not the current browser supports enabling
* navigation preload.
*
* @memberof workbox.navigationPreload
*/
function isSupported() {
return Boolean(self.registration && self.registration.navigationPreload);
}
/*
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.
*/
/**
* If the browser supports Navigation Preload, then this will disable it.
*
* @memberof workbox.navigationPreload
*/
function disable() {
if (isSupported()) {
self.addEventListener('activate', event => {
event.waitUntil(self.registration.navigationPreload.disable().then(() => {
{
logger_mjs.logger.log(`Navigation preload is disabled.`);
}
}));
});
} else {
{
logger_mjs.logger.log(`Navigation preload is not supported in this browser.`);
}
}
}
/*
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.
*/
/**
* If the browser supports Navigation Preload, then this will enable it.
*
* @param {string} [headerValue] Optionally, allows developers to
* [override](https://developers.google.com/web/updates/2017/02/navigation-preload#changing_the_header)
* the value of the `Service-Worker-Navigation-Preload` header which will be
* sent to the server when making the navigation request.
*
* @memberof workbox.navigationPreload
*/
function enable(headerValue) {
if (isSupported()) {
self.addEventListener('activate', event => {
event.waitUntil(self.registration.navigationPreload.enable().then(() => {
// Defaults to Service-Worker-Navigation-Preload: true if not set.
if (headerValue) {
self.registration.navigationPreload.setHeaderValue(headerValue);
}
{
logger_mjs.logger.log(`Navigation preload is enabled.`);
}
}));
});
} else {
{
logger_mjs.logger.log(`Navigation preload is not supported in this browser.`);
}
}
}
/*
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.
*/
exports.disable = disable;
exports.enable = enable;
exports.isSupported = isSupported;
return exports;
}({}, workbox.core._private));
//# sourceMappingURL=workbox-navigation-preload.dev.js.map
{"version":3,"file":"workbox-navigation-preload.dev.js","sources":["../_version.mjs","../isSupported.mjs","../disable.mjs","../enable.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:navigation-preload:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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\nimport './_version.mjs';\n\n/**\n * @return {boolean} Whether or not the current browser supports enabling\n * navigation preload.\n *\n * @memberof workbox.navigationPreload\n */\nfunction isSupported() {\n return Boolean(self.registration && self.registration.navigationPreload);\n}\n\nexport {isSupported};\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\nimport {logger} from 'workbox-core/_private/logger.mjs';\n\nimport {isSupported} from './isSupported.mjs';\n\nimport './_version.mjs';\n\n/**\n * If the browser supports Navigation Preload, then this will disable it.\n *\n * @memberof workbox.navigationPreload\n */\nfunction disable() {\n if (isSupported()) {\n self.addEventListener('activate', (event) => {\n event.waitUntil(\n self.registration.navigationPreload.disable().then(() => {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is disabled.`);\n }\n })\n );\n });\n } else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is not supported in this browser.`);\n }\n }\n}\n\nexport {disable};\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\nimport {logger} from 'workbox-core/_private/logger.mjs';\n\nimport {isSupported} from './isSupported.mjs';\n\nimport './_version.mjs';\n\n/**\n * If the browser supports Navigation Preload, then this will enable it.\n *\n * @param {string} [headerValue] Optionally, allows developers to\n * [override](https://developers.google.com/web/updates/2017/02/navigation-preload#changing_the_header)\n * the value of the `Service-Worker-Navigation-Preload` header which will be\n * sent to the server when making the navigation request.\n *\n * @memberof workbox.navigationPreload\n */\nfunction enable(headerValue) {\n if (isSupported()) {\n self.addEventListener('activate', (event) => {\n event.waitUntil(\n self.registration.navigationPreload.enable().then(() => {\n // Defaults to Service-Worker-Navigation-Preload: true if not set.\n if (headerValue) {\n self.registration.navigationPreload.setHeaderValue(headerValue);\n }\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is enabled.`);\n }\n })\n );\n });\n } else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is not supported in this browser.`);\n }\n }\n}\n\nexport {enable};\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\nimport {disable} from './disable.mjs';\nimport {enable} from './enable.mjs';\nimport {isSupported} from './isSupported.mjs';\nimport './_version.mjs';\n\n\n/**\n * @namespace workbox.navigationPreload\n */\n\nexport {\n disable,\n enable,\n isSupported,\n};\n"],"names":["self","_","e","isSupported","Boolean","registration","navigationPreload","disable","addEventListener","event","waitUntil","then","logger","log","enable","headerValue","setHeaderValue"],"mappings":";;;;EAAA,IAAG;EAACA,EAAAA,IAAI,CAAC,kCAAD,CAAJ,IAA0CC,CAAC,EAA3C;EAA8C,CAAlD,CAAkD,OAAMC,CAAN,EAAQ;;ECA1D;;;;;;;AAQA,EAEA;;;;;;;EAMA,SAASC,WAAT,GAAuB;EACrB,SAAOC,OAAO,CAACJ,IAAI,CAACK,YAAL,IAAqBL,IAAI,CAACK,YAAL,CAAkBC,iBAAxC,CAAd;EACD;;EClBD;;;;;;;AAQA,EAMA;;;;;;EAKA,SAASC,OAAT,GAAmB;EACjB,MAAIJ,WAAW,EAAf,EAAmB;EACjBH,IAAAA,IAAI,CAACQ,gBAAL,CAAsB,UAAtB,EAAmCC,KAAD,IAAW;EAC3CA,MAAAA,KAAK,CAACC,SAAN,CACIV,IAAI,CAACK,YAAL,CAAkBC,iBAAlB,CAAoCC,OAApC,GAA8CI,IAA9C,CAAmD,MAAM;EACvD,QAA2C;EACzCC,UAAAA,iBAAM,CAACC,GAAP,CAAY,iCAAZ;EACD;EACF,OAJD,CADJ;EAOD,KARD;EASD,GAVD,MAUO;EACL,IAA2C;EACzCD,MAAAA,iBAAM,CAACC,GAAP,CAAY,sDAAZ;EACD;EACF;EACF;;ECnCD;;;;;;;AAQA,EAMA;;;;;;;;;;;EAUA,SAASC,MAAT,CAAgBC,WAAhB,EAA6B;EAC3B,MAAIZ,WAAW,EAAf,EAAmB;EACjBH,IAAAA,IAAI,CAACQ,gBAAL,CAAsB,UAAtB,EAAmCC,KAAD,IAAW;EAC3CA,MAAAA,KAAK,CAACC,SAAN,CACIV,IAAI,CAACK,YAAL,CAAkBC,iBAAlB,CAAoCQ,MAApC,GAA6CH,IAA7C,CAAkD,MAAM;EACxD;EACE,YAAII,WAAJ,EAAiB;EACff,UAAAA,IAAI,CAACK,YAAL,CAAkBC,iBAAlB,CAAoCU,cAApC,CAAmDD,WAAnD;EACD;;EAED,QAA2C;EACzCH,UAAAA,iBAAM,CAACC,GAAP,CAAY,gCAAZ;EACD;EACF,OATD,CADJ;EAYD,KAbD;EAcD,GAfD,MAeO;EACL,IAA2C;EACzCD,MAAAA,iBAAM,CAACC,GAAP,CAAY,sDAAZ;EACD;EACF;EACF;;EC7CD;;;;;;;;;;;;;;;;;;"}
\ No newline at end of file
this.workbox=this.workbox||{},this.workbox.navigationPreload=function(t){"use strict";try{self["workbox:navigation-preload:4.3.1"]&&_()}catch(t){}function e(){return Boolean(self.registration&&self.registration.navigationPreload)}return t.disable=function(){e()&&self.addEventListener("activate",t=>{t.waitUntil(self.registration.navigationPreload.disable().then(()=>{}))})},t.enable=function(t){e()&&self.addEventListener("activate",e=>{e.waitUntil(self.registration.navigationPreload.enable().then(()=>{t&&self.registration.navigationPreload.setHeaderValue(t)}))})},t.isSupported=e,t}({});
//# sourceMappingURL=workbox-navigation-preload.prod.js.map
{"version":3,"file":"workbox-navigation-preload.prod.js","sources":["../_version.mjs","../isSupported.mjs","../disable.mjs","../enable.mjs"],"sourcesContent":["try{self['workbox:navigation-preload:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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\nimport './_version.mjs';\n\n/**\n * @return {boolean} Whether or not the current browser supports enabling\n * navigation preload.\n *\n * @memberof workbox.navigationPreload\n */\nfunction isSupported() {\n return Boolean(self.registration && self.registration.navigationPreload);\n}\n\nexport {isSupported};\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\nimport {logger} from 'workbox-core/_private/logger.mjs';\n\nimport {isSupported} from './isSupported.mjs';\n\nimport './_version.mjs';\n\n/**\n * If the browser supports Navigation Preload, then this will disable it.\n *\n * @memberof workbox.navigationPreload\n */\nfunction disable() {\n if (isSupported()) {\n self.addEventListener('activate', (event) => {\n event.waitUntil(\n self.registration.navigationPreload.disable().then(() => {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is disabled.`);\n }\n })\n );\n });\n } else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is not supported in this browser.`);\n }\n }\n}\n\nexport {disable};\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\nimport {logger} from 'workbox-core/_private/logger.mjs';\n\nimport {isSupported} from './isSupported.mjs';\n\nimport './_version.mjs';\n\n/**\n * If the browser supports Navigation Preload, then this will enable it.\n *\n * @param {string} [headerValue] Optionally, allows developers to\n * [override](https://developers.google.com/web/updates/2017/02/navigation-preload#changing_the_header)\n * the value of the `Service-Worker-Navigation-Preload` header which will be\n * sent to the server when making the navigation request.\n *\n * @memberof workbox.navigationPreload\n */\nfunction enable(headerValue) {\n if (isSupported()) {\n self.addEventListener('activate', (event) => {\n event.waitUntil(\n self.registration.navigationPreload.enable().then(() => {\n // Defaults to Service-Worker-Navigation-Preload: true if not set.\n if (headerValue) {\n self.registration.navigationPreload.setHeaderValue(headerValue);\n }\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is enabled.`);\n }\n })\n );\n });\n } else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is not supported in this browser.`);\n }\n }\n}\n\nexport {enable};\n"],"names":["self","_","e","isSupported","Boolean","registration","navigationPreload","addEventListener","event","waitUntil","disable","then","headerValue","enable","setHeaderValue"],"mappings":"sFAAA,IAAIA,KAAK,qCAAqCC,IAAI,MAAMC,ICgBxD,SAASC,WACAC,QAAQJ,KAAKK,cAAgBL,KAAKK,aAAaC,oCCExD,WACMH,KACFH,KAAKO,iBAAiB,WAAaC,IACjCA,EAAMC,UACFT,KAAKK,aAAaC,kBAAkBI,UAAUC,KAAK,qBCC7D,SAAgBC,GACVT,KACFH,KAAKO,iBAAiB,WAAaC,IACjCA,EAAMC,UACFT,KAAKK,aAAaC,kBAAkBO,SAASF,KAAK,KAE5CC,GACFZ,KAAKK,aAAaC,kBAAkBQ,eAAeF"}
\ No newline at end of file
this.workbox = this.workbox || {};
this.workbox.googleAnalytics = (function (exports, Plugin_mjs, cacheNames_mjs, getFriendlyURL_mjs, logger_mjs, Route_mjs, Router_mjs, NetworkFirst_mjs, NetworkOnly_mjs) {
'use strict';
try {
self['workbox:google-analytics:4.3.1'] && _();
} catch (e) {} // eslint-disable-line
/*
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 QUEUE_NAME = 'workbox-google-analytics';
const MAX_RETENTION_TIME = 60 * 48; // Two days in minutes
const GOOGLE_ANALYTICS_HOST = 'www.google-analytics.com';
const GTM_HOST = 'www.googletagmanager.com';
const ANALYTICS_JS_PATH = '/analytics.js';
const GTAG_JS_PATH = '/gtag/js';
const GTM_JS_PATH = '/gtm.js';
// endpoints. Most of the time the default path (/collect) is used, but
// occasionally an experimental endpoint is used when testing new features,
// (e.g. /r/collect or /j/collect)
const COLLECT_PATHS_REGEX = /^\/(\w+\/)?collect/;
/*
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.
*/
/**
* Creates the requestWillDequeue callback to be used with the background
* sync queue plugin. The callback takes the failed request and adds the
* `qt` param based on the current time, as well as applies any other
* user-defined hit modifications.
*
* @param {Object} config See workbox.googleAnalytics.initialize.
* @return {Function} The requestWillDequeu callback function.
*
* @private
*/
const createOnSyncCallback = config => {
return async ({
queue
}) => {
let entry;
while (entry = await queue.shiftRequest()) {
const {
request,
timestamp
} = entry;
const url = new URL(request.url);
try {
// Measurement protocol requests can set their payload parameters in
// either the URL query string (for GET requests) or the POST body.
const params = request.method === 'POST' ? new URLSearchParams((await request.clone().text())) : url.searchParams; // Calculate the qt param, accounting for the fact that an existing
// qt param may be present and should be updated rather than replaced.
const originalHitTime = timestamp - (Number(params.get('qt')) || 0);
const queueTime = Date.now() - originalHitTime; // Set the qt param prior to applying hitFilter or parameterOverrides.
params.set('qt', queueTime); // Apply `paramterOverrideds`, if set.
if (config.parameterOverrides) {
for (const param of Object.keys(config.parameterOverrides)) {
const value = config.parameterOverrides[param];
params.set(param, value);
}
} // Apply `hitFilter`, if set.
if (typeof config.hitFilter === 'function') {
config.hitFilter.call(null, params);
} // Retry the fetch. Ignore URL search params from the URL as they're
// now in the post body.
await fetch(new Request(url.origin + url.pathname, {
body: params.toString(),
method: 'POST',
mode: 'cors',
credentials: 'omit',
headers: {
'Content-Type': 'text/plain'
}
}));
{
logger_mjs.logger.log(`Request for '${getFriendlyURL_mjs.getFriendlyURL(url.href)}'` + `has been replayed`);
}
} catch (err) {
await queue.unshiftRequest(entry);
{
logger_mjs.logger.log(`Request for '${getFriendlyURL_mjs.getFriendlyURL(url.href)}'` + `failed to replay, putting it back in the queue.`);
}
throw err;
}
}
{
logger_mjs.logger.log(`All Google Analytics request successfully replayed; ` + `the queue is now empty!`);
}
};
};
/**
* Creates GET and POST routes to catch failed Measurement Protocol hits.
*
* @param {Plugin} queuePlugin
* @return {Array<Route>} The created routes.
*
* @private
*/
const createCollectRoutes = queuePlugin => {
const match = ({
url
}) => url.hostname === GOOGLE_ANALYTICS_HOST && COLLECT_PATHS_REGEX.test(url.pathname);
const handler = new NetworkOnly_mjs.NetworkOnly({
plugins: [queuePlugin]
});
return [new Route_mjs.Route(match, handler, 'GET'), new Route_mjs.Route(match, handler, 'POST')];
};
/**
* Creates a route with a network first strategy for the analytics.js script.
*
* @param {string} cacheName
* @return {Route} The created route.
*
* @private
*/
const createAnalyticsJsRoute = cacheName => {
const match = ({
url
}) => url.hostname === GOOGLE_ANALYTICS_HOST && url.pathname === ANALYTICS_JS_PATH;
const handler = new NetworkFirst_mjs.NetworkFirst({
cacheName
});
return new Route_mjs.Route(match, handler, 'GET');
};
/**
* Creates a route with a network first strategy for the gtag.js script.
*
* @param {string} cacheName
* @return {Route} The created route.
*
* @private
*/
const createGtagJsRoute = cacheName => {
const match = ({
url
}) => url.hostname === GTM_HOST && url.pathname === GTAG_JS_PATH;
const handler = new NetworkFirst_mjs.NetworkFirst({
cacheName
});
return new Route_mjs.Route(match, handler, 'GET');
};
/**
* Creates a route with a network first strategy for the gtm.js script.
*
* @param {string} cacheName
* @return {Route} The created route.
*
* @private
*/
const createGtmJsRoute = cacheName => {
const match = ({
url
}) => url.hostname === GTM_HOST && url.pathname === GTM_JS_PATH;
const handler = new NetworkFirst_mjs.NetworkFirst({
cacheName
});
return new Route_mjs.Route(match, handler, 'GET');
};
/**
* @param {Object=} [options]
* @param {Object} [options.cacheName] The cache name to store and retrieve
* analytics.js. Defaults to the cache names provided by `workbox-core`.
* @param {Object} [options.parameterOverrides]
* [Measurement Protocol parameters](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters),
* expressed as key/value pairs, to be added to replayed Google Analytics
* requests. This can be used to, e.g., set a custom dimension indicating
* that the request was replayed.
* @param {Function} [options.hitFilter] A function that allows you to modify
* the hit parameters prior to replaying
* the hit. The function is invoked with the original hit's URLSearchParams
* object as its only argument.
*
* @memberof workbox.googleAnalytics
*/
const initialize = (options = {}) => {
const cacheName = cacheNames_mjs.cacheNames.getGoogleAnalyticsName(options.cacheName);
const queuePlugin = new Plugin_mjs.Plugin(QUEUE_NAME, {
maxRetentionTime: MAX_RETENTION_TIME,
onSync: createOnSyncCallback(options)
});
const routes = [createGtmJsRoute(cacheName), createAnalyticsJsRoute(cacheName), createGtagJsRoute(cacheName), ...createCollectRoutes(queuePlugin)];
const router = new Router_mjs.Router();
for (const route of routes) {
router.registerRoute(route);
}
router.addFetchListener();
};
/*
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.
*/
exports.initialize = initialize;
return exports;
}({}, workbox.backgroundSync, workbox.core._private, workbox.core._private, workbox.core._private, workbox.routing, workbox.routing, workbox.strategies, workbox.strategies));
//# sourceMappingURL=workbox-offline-ga.dev.js.map
this.workbox=this.workbox||{},this.workbox.googleAnalytics=function(e,t,o,n,a,c,w){"use strict";try{self["workbox:google-analytics:4.3.1"]&&_()}catch(e){}const r=/^\/(\w+\/)?collect/,s=e=>async({queue:t})=>{let o;for(;o=await t.shiftRequest();){const{request:n,timestamp:a}=o,c=new URL(n.url);try{const w="POST"===n.method?new URLSearchParams(await n.clone().text()):c.searchParams,r=a-(Number(w.get("qt"))||0),s=Date.now()-r;if(w.set("qt",s),e.parameterOverrides)for(const t of Object.keys(e.parameterOverrides)){const o=e.parameterOverrides[t];w.set(t,o)}"function"==typeof e.hitFilter&&e.hitFilter.call(null,w),await fetch(new Request(c.origin+c.pathname,{body:w.toString(),method:"POST",mode:"cors",credentials:"omit",headers:{"Content-Type":"text/plain"}}))}catch(e){throw await t.unshiftRequest(o),e}}},i=e=>{const t=({url:e})=>"www.google-analytics.com"===e.hostname&&r.test(e.pathname),o=new w.NetworkOnly({plugins:[e]});return[new n.Route(t,o,"GET"),new n.Route(t,o,"POST")]},l=e=>{const t=new c.NetworkFirst({cacheName:e});return new n.Route(({url:e})=>"www.google-analytics.com"===e.hostname&&"/analytics.js"===e.pathname,t,"GET")},m=e=>{const t=new c.NetworkFirst({cacheName:e});return new n.Route(({url:e})=>"www.googletagmanager.com"===e.hostname&&"/gtag/js"===e.pathname,t,"GET")},u=e=>{const t=new c.NetworkFirst({cacheName:e});return new n.Route(({url:e})=>"www.googletagmanager.com"===e.hostname&&"/gtm.js"===e.pathname,t,"GET")};return e.initialize=((e={})=>{const n=o.cacheNames.getGoogleAnalyticsName(e.cacheName),c=new t.Plugin("workbox-google-analytics",{maxRetentionTime:2880,onSync:s(e)}),w=[u(n),l(n),m(n),...i(c)],r=new a.Router;for(const e of w)r.registerRoute(e);r.addFetchListener()}),e}({},workbox.backgroundSync,workbox.core._private,workbox.routing,workbox.routing,workbox.strategies,workbox.strategies);
//# sourceMappingURL=workbox-offline-ga.prod.js.map
this.workbox=this.workbox||{},this.workbox.precaching=function(t,e,n,s,c){"use strict";try{self["workbox:precaching:4.3.1"]&&_()}catch(t){}const o=[],i={get:()=>o,add(t){o.push(...t)}};const a="__WB_REVISION__";function r(t){if(!t)throw new c.WorkboxError("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new c.WorkboxError("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location);return{cacheKey:t.href,url:t.href}}const s=new URL(n,location),o=new URL(n,location);return o.searchParams.set(a,e),{cacheKey:o.href,url:s.href}}class l{constructor(t){this.t=e.cacheNames.getPrecacheName(t),this.s=new Map}addToCacheList(t){for(const e of t){const{cacheKey:t,url:n}=r(e);if(this.s.has(n)&&this.s.get(n)!==t)throw new c.WorkboxError("add-to-cache-list-conflicting-entries",{firstEntry:this.s.get(n),secondEntry:t});this.s.set(n,t)}}async install({event:t,plugins:e}={}){const n=[],s=[],c=await caches.open(this.t),o=await c.keys(),i=new Set(o.map(t=>t.url));for(const t of this.s.values())i.has(t)?s.push(t):n.push(t);const a=n.map(n=>this.o({event:t,plugins:e,url:n}));return await Promise.all(a),{updatedURLs:n,notUpdatedURLs:s}}async activate(){const t=await caches.open(this.t),e=await t.keys(),n=new Set(this.s.values()),s=[];for(const c of e)n.has(c.url)||(await t.delete(c),s.push(c.url));return{deletedURLs:s}}async o({url:t,event:e,plugins:o}){const i=new Request(t,{credentials:"same-origin"});let a,r=await s.fetchWrapper.fetch({event:e,plugins:o,request:i});for(const t of o||[])"cacheWillUpdate"in t&&(a=t.cacheWillUpdate.bind(t));if(!(a?a({event:e,request:i,response:r}):r.status<400))throw new c.WorkboxError("bad-precaching-response",{url:t,status:r.status});r.redirected&&(r=await async function(t){const e=t.clone(),n="body"in e?Promise.resolve(e.body):e.blob(),s=await n;return new Response(s,{headers:e.headers,status:e.status,statusText:e.statusText})}(r)),await n.cacheWrapper.put({event:e,plugins:o,request:i,response:r,cacheName:this.t,matchOptions:{ignoreSearch:!0}})}getURLsToCacheKeys(){return this.s}getCachedURLs(){return[...this.s.keys()]}getCacheKeyForURL(t){const e=new URL(t,location);return this.s.get(e.href)}}let u;const h=()=>(u||(u=new l),u);const d=(t,e)=>{const n=h().getURLsToCacheKeys();for(const s of function*(t,{ignoreURLParametersMatching:e,directoryIndex:n,cleanURLs:s,urlManipulation:c}={}){const o=new URL(t,location);o.hash="",yield o.href;const i=function(t,e){for(const n of[...t.searchParams.keys()])e.some(t=>t.test(n))&&t.searchParams.delete(n);return t}(o,e);if(yield i.href,n&&i.pathname.endsWith("/")){const t=new URL(i);t.pathname+=n,yield t.href}if(s){const t=new URL(i);t.pathname+=".html",yield t.href}if(c){const t=c({url:o});for(const e of t)yield e.href}}(t,e)){const t=n.get(s);if(t)return t}};let w=!1;const f=t=>{w||((({ignoreURLParametersMatching:t=[/^utm_/],directoryIndex:n="index.html",cleanURLs:s=!0,urlManipulation:c=null}={})=>{const o=e.cacheNames.getPrecacheName();addEventListener("fetch",e=>{const i=d(e.request.url,{cleanURLs:s,directoryIndex:n,ignoreURLParametersMatching:t,urlManipulation:c});if(!i)return;let a=caches.open(o).then(t=>t.match(i)).then(t=>t||fetch(i));e.respondWith(a)})})(t),w=!0)},y=t=>{const e=h(),n=i.get();t.waitUntil(e.install({event:t,plugins:n}).catch(t=>{throw t}))},p=t=>{const e=h(),n=i.get();t.waitUntil(e.activate({event:t,plugins:n}))},L=t=>{h().addToCacheList(t),t.length>0&&(addEventListener("install",y),addEventListener("activate",p))};return t.addPlugins=(t=>{i.add(t)}),t.addRoute=f,t.cleanupOutdatedCaches=(()=>{addEventListener("activate",t=>{const n=e.cacheNames.getPrecacheName();t.waitUntil((async(t,e="-precache-")=>{const n=(await caches.keys()).filter(n=>n.includes(e)&&n.includes(self.registration.scope)&&n!==t);return await Promise.all(n.map(t=>caches.delete(t))),n})(n).then(t=>{}))})}),t.getCacheKeyForURL=(t=>{return h().getCacheKeyForURL(t)}),t.precache=L,t.precacheAndRoute=((t,e)=>{L(t),f(e)}),t.PrecacheController=l,t}({},workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private);
//# sourceMappingURL=workbox-precaching.prod.js.map
this.workbox = this.workbox || {};
this.workbox.rangeRequests = (function (exports, WorkboxError_mjs, assert_mjs, logger_mjs) {
'use strict';
try {
self['workbox:range-requests:4.3.1'] && _();
} catch (e) {} // eslint-disable-line
/*
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.
*/
/**
* @param {Blob} blob A source blob.
* @param {number|null} start The offset to use as the start of the
* slice.
* @param {number|null} end The offset to use as the end of the slice.
* @return {Object} An object with `start` and `end` properties, reflecting
* the effective boundaries to use given the size of the blob.
*
* @private
*/
function calculateEffectiveBoundaries(blob, start, end) {
{
assert_mjs.assert.isInstance(blob, Blob, {
moduleName: 'workbox-range-requests',
funcName: 'calculateEffectiveBoundaries',
paramName: 'blob'
});
}
const blobSize = blob.size;
if (end > blobSize || start < 0) {
throw new WorkboxError_mjs.WorkboxError('range-not-satisfiable', {
size: blobSize,
end,
start
});
}
let effectiveStart;
let effectiveEnd;
if (start === null) {
effectiveStart = blobSize - end;
effectiveEnd = blobSize;
} else if (end === null) {
effectiveStart = start;
effectiveEnd = blobSize;
} else {
effectiveStart = start; // Range values are inclusive, so add 1 to the value.
effectiveEnd = end + 1;
}
return {
start: effectiveStart,
end: effectiveEnd
};
}
/*
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.
*/
/**
* @param {string} rangeHeader A Range: header value.
* @return {Object} An object with `start` and `end` properties, reflecting
* the parsed value of the Range: header. If either the `start` or `end` are
* omitted, then `null` will be returned.
*
* @private
*/
function parseRangeHeader(rangeHeader) {
{
assert_mjs.assert.isType(rangeHeader, 'string', {
moduleName: 'workbox-range-requests',
funcName: 'parseRangeHeader',
paramName: 'rangeHeader'
});
}
const normalizedRangeHeader = rangeHeader.trim().toLowerCase();
if (!normalizedRangeHeader.startsWith('bytes=')) {
throw new WorkboxError_mjs.WorkboxError('unit-must-be-bytes', {
normalizedRangeHeader
});
} // Specifying multiple ranges separate by commas is valid syntax, but this
// library only attempts to handle a single, contiguous sequence of bytes.
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#Syntax
if (normalizedRangeHeader.includes(',')) {
throw new WorkboxError_mjs.WorkboxError('single-range-only', {
normalizedRangeHeader
});
}
const rangeParts = /(\d*)-(\d*)/.exec(normalizedRangeHeader); // We need either at least one of the start or end values.
if (rangeParts === null || !(rangeParts[1] || rangeParts[2])) {
throw new WorkboxError_mjs.WorkboxError('invalid-range-values', {
normalizedRangeHeader
});
}
return {
start: rangeParts[1] === '' ? null : Number(rangeParts[1]),
end: rangeParts[2] === '' ? null : Number(rangeParts[2])
};
}
/*
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.
*/
/**
* Given a `Request` and `Response` objects as input, this will return a
* promise for a new `Response`.
*
* If the original `Response` already contains partial content (i.e. it has
* a status of 206), then this assumes it already fulfills the `Range:`
* requirements, and will return it as-is.
*
* @param {Request} request A request, which should contain a Range:
* header.
* @param {Response} originalResponse A response.
* @return {Promise<Response>} Either a `206 Partial Content` response, with
* the response body set to the slice of content specified by the request's
* `Range:` header, or a `416 Range Not Satisfiable` response if the
* conditions of the `Range:` header can't be met.
*
* @memberof workbox.rangeRequests
*/
async function createPartialResponse(request, originalResponse) {
try {
{
assert_mjs.assert.isInstance(request, Request, {
moduleName: 'workbox-range-requests',
funcName: 'createPartialResponse',
paramName: 'request'
});
assert_mjs.assert.isInstance(originalResponse, Response, {
moduleName: 'workbox-range-requests',
funcName: 'createPartialResponse',
paramName: 'originalResponse'
});
}
if (originalResponse.status === 206) {
// If we already have a 206, then just pass it through as-is;
// see https://github.com/GoogleChrome/workbox/issues/1720
return originalResponse;
}
const rangeHeader = request.headers.get('range');
if (!rangeHeader) {
throw new WorkboxError_mjs.WorkboxError('no-range-header');
}
const boundaries = parseRangeHeader(rangeHeader);
const originalBlob = await originalResponse.blob();
const effectiveBoundaries = calculateEffectiveBoundaries(originalBlob, boundaries.start, boundaries.end);
const slicedBlob = originalBlob.slice(effectiveBoundaries.start, effectiveBoundaries.end);
const slicedBlobSize = slicedBlob.size;
const slicedResponse = new Response(slicedBlob, {
// Status code 206 is for a Partial Content response.
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206
status: 206,
statusText: 'Partial Content',
headers: originalResponse.headers
});
slicedResponse.headers.set('Content-Length', slicedBlobSize);
slicedResponse.headers.set('Content-Range', `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` + originalBlob.size);
return slicedResponse;
} catch (error) {
{
logger_mjs.logger.warn(`Unable to construct a partial response; returning a ` + `416 Range Not Satisfiable response instead.`);
logger_mjs.logger.groupCollapsed(`View details here.`);
logger_mjs.logger.log(error);
logger_mjs.logger.log(request);
logger_mjs.logger.log(originalResponse);
logger_mjs.logger.groupEnd();
}
return new Response('', {
status: 416,
statusText: 'Range Not Satisfiable'
});
}
}
/*
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.
*/
/**
* The range request plugin makes it easy for a request with a 'Range' header to
* be fulfilled by a cached response.
*
* It does this by intercepting the `cachedResponseWillBeUsed` plugin callback
* and returning the appropriate subset of the cached response body.
*
* @memberof workbox.rangeRequests
*/
class Plugin {
/**
* @param {Object} options
* @param {Request} options.request The original request, which may or may not
* contain a Range: header.
* @param {Response} options.cachedResponse The complete cached response.
* @return {Promise<Response>} If request contains a 'Range' header, then a
* new response with status 206 whose body is a subset of `cachedResponse` is
* returned. Otherwise, `cachedResponse` is returned as-is.
*
* @private
*/
async cachedResponseWillBeUsed({
request,
cachedResponse
}) {
// Only return a sliced response if there's something valid in the cache,
// and there's a Range: header in the request.
if (cachedResponse && request.headers.has('range')) {
return await createPartialResponse(request, cachedResponse);
} // If there was no Range: header, or if cachedResponse wasn't valid, just
// pass it through as-is.
return cachedResponse;
}
}
/*
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.
*/
exports.createPartialResponse = createPartialResponse;
exports.Plugin = Plugin;
return exports;
}({}, workbox.core._private, workbox.core._private, workbox.core._private));
//# sourceMappingURL=workbox-range-requests.dev.js.map
this.workbox=this.workbox||{},this.workbox.rangeRequests=function(e,n){"use strict";try{self["workbox:range-requests:4.3.1"]&&_()}catch(e){}async function t(e,t){try{if(206===t.status)return t;const s=e.headers.get("range");if(!s)throw new n.WorkboxError("no-range-header");const a=function(e){const t=e.trim().toLowerCase();if(!t.startsWith("bytes="))throw new n.WorkboxError("unit-must-be-bytes",{normalizedRangeHeader:t});if(t.includes(","))throw new n.WorkboxError("single-range-only",{normalizedRangeHeader:t});const s=/(\d*)-(\d*)/.exec(t);if(null===s||!s[1]&&!s[2])throw new n.WorkboxError("invalid-range-values",{normalizedRangeHeader:t});return{start:""===s[1]?null:Number(s[1]),end:""===s[2]?null:Number(s[2])}}(s),r=await t.blob(),i=function(e,t,s){const a=e.size;if(s>a||t<0)throw new n.WorkboxError("range-not-satisfiable",{size:a,end:s,start:t});let r,i;return null===t?(r=a-s,i=a):null===s?(r=t,i=a):(r=t,i=s+1),{start:r,end:i}}(r,a.start,a.end),o=r.slice(i.start,i.end),u=o.size,l=new Response(o,{status:206,statusText:"Partial Content",headers:t.headers});return l.headers.set("Content-Length",u),l.headers.set("Content-Range",`bytes ${i.start}-${i.end-1}/`+r.size),l}catch(e){return new Response("",{status:416,statusText:"Range Not Satisfiable"})}}return e.createPartialResponse=t,e.Plugin=class{async cachedResponseWillBeUsed({request:e,cachedResponse:n}){return n&&e.headers.has("range")?await t(e,n):n}},e}({},workbox.core._private);
//# sourceMappingURL=workbox-range-requests.prod.js.map
this.workbox=this.workbox||{},this.workbox.routing=function(t,e,r){"use strict";try{self["workbox:routing:4.3.1"]&&_()}catch(t){}const s="GET",n=t=>t&&"object"==typeof t?t:{handle:t};class o{constructor(t,e,r){this.handler=n(e),this.match=t,this.method=r||s}}class i extends o{constructor(t,{whitelist:e=[/./],blacklist:r=[]}={}){super(t=>this.t(t),t),this.s=e,this.o=r}t({url:t,request:e}){if("navigate"!==e.mode)return!1;const r=t.pathname+t.search;for(const t of this.o)if(t.test(r))return!1;return!!this.s.some(t=>t.test(r))}}class u extends o{constructor(t,e,r){super(({url:e})=>{const r=t.exec(e.href);return r?e.origin!==location.origin&&0!==r.index?null:r.slice(1):null},e,r)}}class c{constructor(){this.i=new Map}get routes(){return this.i}addFetchListener(){self.addEventListener("fetch",t=>{const{request:e}=t,r=this.handleRequest({request:e,event:t});r&&t.respondWith(r)})}addCacheListener(){self.addEventListener("message",async t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,r=Promise.all(e.urlsToCache.map(t=>{"string"==typeof t&&(t=[t]);const e=new Request(...t);return this.handleRequest({request:e})}));t.waitUntil(r),t.ports&&t.ports[0]&&(await r,t.ports[0].postMessage(!0))}})}handleRequest({request:t,event:e}){const r=new URL(t.url,location);if(!r.protocol.startsWith("http"))return;let s,{params:n,route:o}=this.findMatchingRoute({url:r,request:t,event:e}),i=o&&o.handler;if(!i&&this.u&&(i=this.u),i){try{s=i.handle({url:r,request:t,event:e,params:n})}catch(t){s=Promise.reject(t)}return s&&this.h&&(s=s.catch(t=>this.h.handle({url:r,event:e,err:t}))),s}}findMatchingRoute({url:t,request:e,event:r}){const s=this.i.get(e.method)||[];for(const n of s){let s,o=n.match({url:t,request:e,event:r});if(o)return Array.isArray(o)&&o.length>0?s=o:o.constructor===Object&&Object.keys(o).length>0&&(s=o),{route:n,params:s}}return{}}setDefaultHandler(t){this.u=n(t)}setCatchHandler(t){this.h=n(t)}registerRoute(t){this.i.has(t.method)||this.i.set(t.method,[]),this.i.get(t.method).push(t)}unregisterRoute(t){if(!this.i.has(t.method))throw new r.WorkboxError("unregister-route-but-not-found-with-method",{method:t.method});const e=this.i.get(t.method).indexOf(t);if(!(e>-1))throw new r.WorkboxError("unregister-route-route-not-registered");this.i.get(t.method).splice(e,1)}}let a;const h=()=>(a||((a=new c).addFetchListener(),a.addCacheListener()),a);return t.NavigationRoute=i,t.RegExpRoute=u,t.registerNavigationRoute=((t,r={})=>{const s=e.cacheNames.getPrecacheName(r.cacheName),n=new i(async()=>{try{const e=await caches.match(t,{cacheName:s});if(e)return e;throw new Error(`The cache ${s} did not have an entry for `+`${t}.`)}catch(e){return fetch(t)}},{whitelist:r.whitelist,blacklist:r.blacklist});return h().registerRoute(n),n}),t.registerRoute=((t,e,s="GET")=>{let n;if("string"==typeof t){const r=new URL(t,location);n=new o(({url:t})=>t.href===r.href,e,s)}else if(t instanceof RegExp)n=new u(t,e,s);else if("function"==typeof t)n=new o(t,e,s);else{if(!(t instanceof o))throw new r.WorkboxError("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});n=t}return h().registerRoute(n),n}),t.Route=o,t.Router=c,t.setCatchHandler=(t=>{h().setCatchHandler(t)}),t.setDefaultHandler=(t=>{h().setDefaultHandler(t)}),t}({},workbox.core._private,workbox.core._private);
//# sourceMappingURL=workbox-routing.prod.js.map
this.workbox=this.workbox||{},this.workbox.strategies=function(e,t,s,n,r){"use strict";try{self["workbox:strategies:4.3.1"]&&_()}catch(e){}class i{constructor(e={}){this.t=t.cacheNames.getRuntimeName(e.cacheName),this.s=e.plugins||[],this.i=e.fetchOptions||null,this.h=e.matchOptions||null}async handle({event:e,request:t}){return this.makeRequest({event:e,request:t||e.request})}async makeRequest({event:e,request:t}){"string"==typeof t&&(t=new Request(t));let n,i=await s.cacheWrapper.match({cacheName:this.t,request:t,event:e,matchOptions:this.h,plugins:this.s});if(!i)try{i=await this.u(t,e)}catch(e){n=e}if(!i)throw new r.WorkboxError("no-response",{url:t.url,error:n});return i}async u(e,t){const r=await n.fetchWrapper.fetch({request:e,event:t,fetchOptions:this.i,plugins:this.s}),i=r.clone(),h=s.cacheWrapper.put({cacheName:this.t,request:e,response:i,event:t,plugins:this.s});if(t)try{t.waitUntil(h)}catch(e){}return r}}class h{constructor(e={}){this.t=t.cacheNames.getRuntimeName(e.cacheName),this.s=e.plugins||[],this.h=e.matchOptions||null}async handle({event:e,request:t}){return this.makeRequest({event:e,request:t||e.request})}async makeRequest({event:e,request:t}){"string"==typeof t&&(t=new Request(t));const n=await s.cacheWrapper.match({cacheName:this.t,request:t,event:e,matchOptions:this.h,plugins:this.s});if(!n)throw new r.WorkboxError("no-response",{url:t.url});return n}}const u={cacheWillUpdate:({response:e})=>200===e.status||0===e.status?e:null};class a{constructor(e={}){if(this.t=t.cacheNames.getRuntimeName(e.cacheName),e.plugins){let t=e.plugins.some(e=>!!e.cacheWillUpdate);this.s=t?e.plugins:[u,...e.plugins]}else this.s=[u];this.o=e.networkTimeoutSeconds,this.i=e.fetchOptions||null,this.h=e.matchOptions||null}async handle({event:e,request:t}){return this.makeRequest({event:e,request:t||e.request})}async makeRequest({event:e,request:t}){const s=[];"string"==typeof t&&(t=new Request(t));const n=[];let i;if(this.o){const{id:r,promise:h}=this.l({request:t,event:e,logs:s});i=r,n.push(h)}const h=this.q({timeoutId:i,request:t,event:e,logs:s});n.push(h);let u=await Promise.race(n);if(u||(u=await h),!u)throw new r.WorkboxError("no-response",{url:t.url});return u}l({request:e,logs:t,event:s}){let n;return{promise:new Promise(t=>{n=setTimeout(async()=>{t(await this.p({request:e,event:s}))},1e3*this.o)}),id:n}}async q({timeoutId:e,request:t,logs:r,event:i}){let h,u;try{u=await n.fetchWrapper.fetch({request:t,event:i,fetchOptions:this.i,plugins:this.s})}catch(e){h=e}if(e&&clearTimeout(e),h||!u)u=await this.p({request:t,event:i});else{const e=u.clone(),n=s.cacheWrapper.put({cacheName:this.t,request:t,response:e,event:i,plugins:this.s});if(i)try{i.waitUntil(n)}catch(e){}}return u}p({event:e,request:t}){return s.cacheWrapper.match({cacheName:this.t,request:t,event:e,matchOptions:this.h,plugins:this.s})}}class c{constructor(e={}){this.t=t.cacheNames.getRuntimeName(e.cacheName),this.s=e.plugins||[],this.i=e.fetchOptions||null}async handle({event:e,request:t}){return this.makeRequest({event:e,request:t||e.request})}async makeRequest({event:e,request:t}){let s,i;"string"==typeof t&&(t=new Request(t));try{i=await n.fetchWrapper.fetch({request:t,event:e,fetchOptions:this.i,plugins:this.s})}catch(e){s=e}if(!i)throw new r.WorkboxError("no-response",{url:t.url,error:s});return i}}class o{constructor(e={}){if(this.t=t.cacheNames.getRuntimeName(e.cacheName),this.s=e.plugins||[],e.plugins){let t=e.plugins.some(e=>!!e.cacheWillUpdate);this.s=t?e.plugins:[u,...e.plugins]}else this.s=[u];this.i=e.fetchOptions||null,this.h=e.matchOptions||null}async handle({event:e,request:t}){return this.makeRequest({event:e,request:t||e.request})}async makeRequest({event:e,request:t}){"string"==typeof t&&(t=new Request(t));const n=this.u({request:t,event:e});let i,h=await s.cacheWrapper.match({cacheName:this.t,request:t,event:e,matchOptions:this.h,plugins:this.s});if(h){if(e)try{e.waitUntil(n)}catch(i){}}else try{h=await n}catch(e){i=e}if(!h)throw new r.WorkboxError("no-response",{url:t.url,error:i});return h}async u({request:e,event:t}){const r=await n.fetchWrapper.fetch({request:e,event:t,fetchOptions:this.i,plugins:this.s}),i=s.cacheWrapper.put({cacheName:this.t,request:e,response:r.clone(),event:t,plugins:this.s});if(t)try{t.waitUntil(i)}catch(e){}return r}}const l={cacheFirst:i,cacheOnly:h,networkFirst:a,networkOnly:c,staleWhileRevalidate:o},q=e=>{const t=l[e];return e=>new t(e)},w=q("cacheFirst"),p=q("cacheOnly"),v=q("networkFirst"),y=q("networkOnly"),m=q("staleWhileRevalidate");return e.CacheFirst=i,e.CacheOnly=h,e.NetworkFirst=a,e.NetworkOnly=c,e.StaleWhileRevalidate=o,e.cacheFirst=w,e.cacheOnly=p,e.networkFirst=v,e.networkOnly=y,e.staleWhileRevalidate=m,e}({},workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private);
//# sourceMappingURL=workbox-strategies.prod.js.map
this.workbox=this.workbox||{},this.workbox.streams=function(e){"use strict";try{self["workbox:streams:4.3.1"]&&_()}catch(e){}function n(e){const n=e.map(e=>Promise.resolve(e).then(e=>(function(e){return e.body&&e.body.getReader?e.body.getReader():e.getReader?e.getReader():new Response(e).body.getReader()})(e)));let t,r;const s=new Promise((e,n)=>{t=e,r=n});let o=0;return{done:s,stream:new ReadableStream({pull(e){return n[o].then(e=>e.read()).then(r=>{if(r.done)return++o>=n.length?(e.close(),void t()):this.pull(e);e.enqueue(r.value)}).catch(e=>{throw r(e),e})},cancel(){t()}})}}function t(e={}){const n=new Headers(e);return n.has("content-type")||n.set("content-type","text/html"),n}function r(e,r){const{done:s,stream:o}=n(e),a=t(r);return{done:s,response:new Response(o,{headers:a})}}let s=void 0;function o(){if(void 0===s)try{new ReadableStream({start(){}}),s=!0}catch(e){s=!1}return s}return e.concatenate=n,e.concatenateToResponse=r,e.isSupported=o,e.strategy=function(e,n){return async({event:s,url:a,params:c})=>{if(o()){const{done:t,response:o}=r(e.map(e=>e({event:s,url:a,params:c})),n);return s.waitUntil(t),o}const i=await Promise.all(e.map(e=>e({event:s,url:a,params:c})).map(async e=>{const n=await e;return n instanceof Response?n.blob():n})),u=t(n);return new Response(new Blob(i),{headers:u})}},e}({});
//# sourceMappingURL=workbox-streams.prod.js.map
!function(){"use strict";try{self["workbox:sw:4.3.1"]&&_()}catch(t){}const t="https://storage.googleapis.com/workbox-cdn/releases/4.3.1",e={backgroundSync:"background-sync",broadcastUpdate:"broadcast-update",cacheableResponse:"cacheable-response",core:"core",expiration:"expiration",googleAnalytics:"offline-ga",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams"};self.workbox=new class{constructor(){return this.v={},this.t={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.s=this.t.debug?"dev":"prod",this.o=!1,new Proxy(this,{get(t,s){if(t[s])return t[s];const o=e[s];return o&&t.loadModule(`workbox-${o}`),t[s]}})}setConfig(t={}){if(this.o)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.t,t),this.s=this.t.debug?"dev":"prod"}loadModule(t){const e=this.i(t);try{importScripts(e),this.o=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}i(e){if(this.t.modulePathCb)return this.t.modulePathCb(e,this.t.debug);let s=[t];const o=`${e}.${this.s}.js`,r=this.t.modulePathPrefix;return r&&""===(s=r.split("/"))[s.length-1]&&s.splice(s.length-1,1),s.push(o),s.join("/")}}}();
//# sourceMappingURL=workbox-sw.js.map
{"version":3,"file":"workbox-sw.js","sources":["../_version.mjs","../controllers/WorkboxSW.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:sw:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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\nimport '../_version.mjs';\n\nconst CDN_PATH = `WORKBOX_CDN_ROOT_URL`;\n\nconst MODULE_KEY_TO_NAME_MAPPING = {\n // TODO(philipwalton): add jsdoc tags to associate these with their module.\n // @name backgroundSync\n // @memberof workbox\n // @see module:workbox-background-sync\n backgroundSync: 'background-sync',\n broadcastUpdate: 'broadcast-update',\n cacheableResponse: 'cacheable-response',\n core: 'core',\n expiration: 'expiration',\n googleAnalytics: 'offline-ga',\n navigationPreload: 'navigation-preload',\n precaching: 'precaching',\n rangeRequests: 'range-requests',\n routing: 'routing',\n strategies: 'strategies',\n streams: 'streams',\n};\n\n/**\n * This class can be used to make it easy to use the various parts of\n * Workbox.\n *\n * @private\n */\nexport class WorkboxSW {\n /**\n * Creates a proxy that automatically loads workbox namespaces on demand.\n *\n * @private\n */\n constructor() {\n this.v = {};\n this._options = {\n debug: self.location.hostname === 'localhost',\n modulePathPrefix: null,\n modulePathCb: null,\n };\n\n this._env = this._options.debug ? 'dev' : 'prod';\n this._modulesLoaded = false;\n\n return new Proxy(this, {\n get(target, key) {\n if (target[key]) {\n return target[key];\n }\n\n const moduleName = MODULE_KEY_TO_NAME_MAPPING[key];\n if (moduleName) {\n target.loadModule(`workbox-${moduleName}`);\n }\n\n return target[key];\n },\n });\n }\n\n /**\n * Updates the configuration options. You can specify whether to treat as a\n * debug build and whether to use a CDN or a specific path when importing\n * other workbox-modules\n *\n * @param {Object} [options]\n * @param {boolean} [options.debug] If true, `dev` builds are using, otherwise\n * `prod` builds are used. By default, `prod` is used unless on localhost.\n * @param {Function} [options.modulePathPrefix] To avoid using the CDN with\n * `workbox-sw` set the path prefix of where modules should be loaded from.\n * For example `modulePathPrefix: '/third_party/workbox/v3.0.0/'`.\n * @param {workbox~ModulePathCallback} [options.modulePathCb] If defined,\n * this callback will be responsible for determining the path of each\n * workbox module.\n *\n * @alias workbox.setConfig\n */\n setConfig(options = {}) {\n if (!this._modulesLoaded) {\n Object.assign(this._options, options);\n this._env = this._options.debug ? 'dev' : 'prod';\n } else {\n throw new Error('Config must be set before accessing workbox.* modules');\n }\n }\n\n /**\n * Load a Workbox module by passing in the appropriate module name.\n *\n * This is not generally needed unless you know there are modules that are\n * dynamically used and you want to safe guard use of the module while the\n * user may be offline.\n *\n * @param {string} moduleName\n *\n * @alias workbox.loadModule\n */\n loadModule(moduleName) {\n const modulePath = this._getImportPath(moduleName);\n try {\n importScripts(modulePath);\n this._modulesLoaded = true;\n } catch (err) {\n // TODO Add context of this error if using the CDN vs the local file.\n\n // We can't rely on workbox-core being loaded so using console\n // eslint-disable-next-line\n console.error(\n `Unable to import module '${moduleName}' from '${modulePath}'.`);\n throw err;\n }\n }\n\n /**\n * This method will get the path / CDN URL to be used for importScript calls.\n *\n * @param {string} moduleName\n * @return {string} URL to the desired module.\n *\n * @private\n */\n _getImportPath(moduleName) {\n if (this._options.modulePathCb) {\n return this._options.modulePathCb(moduleName, this._options.debug);\n }\n\n // TODO: This needs to be dynamic some how.\n let pathParts = [CDN_PATH];\n\n const fileName = `${moduleName}.${this._env}.js`;\n\n const pathPrefix = this._options.modulePathPrefix;\n if (pathPrefix) {\n // Split to avoid issues with developers ending / not ending with slash\n pathParts = pathPrefix.split('/');\n\n // We don't need a slash at the end as we will be adding\n // a filename regardless\n if (pathParts[pathParts.length - 1] === '') {\n pathParts.splice(pathParts.length - 1, 1);\n }\n }\n\n pathParts.push(fileName);\n\n return pathParts.join('/');\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*/\n\nimport {WorkboxSW} from './controllers/WorkboxSW.mjs';\nimport './_version.mjs';\n\n/**\n * @namespace workbox\n */\n\n// Don't export anything, just expose a global.\nself.workbox = new WorkboxSW();\n"],"names":["self","_","e","CDN_PATH","MODULE_KEY_TO_NAME_MAPPING","backgroundSync","broadcastUpdate","cacheableResponse","core","expiration","googleAnalytics","navigationPreload","precaching","rangeRequests","routing","strategies","streams","workbox","constructor","v","_options","debug","location","hostname","modulePathPrefix","modulePathCb","_env","this","_modulesLoaded","Proxy","get","target","key","moduleName","loadModule","setConfig","options","Error","Object","assign","modulePath","_getImportPath","importScripts","err","console","error","pathParts","fileName","pathPrefix","split","length","splice","push","join"],"mappings":"yBAAA,IAAIA,KAAK,qBAAqBC,IAAI,MAAMC,ICUxC,MAAMC,EAAY,4DAEZC,EAA6B,CAKjCC,eAAgB,kBAChBC,gBAAiB,mBACjBC,kBAAmB,qBACnBC,KAAM,OACNC,WAAY,aACZC,gBAAiB,aACjBC,kBAAmB,qBACnBC,WAAY,aACZC,cAAe,iBACfC,QAAS,UACTC,WAAY,aACZC,QAAS,WCZXhB,KAAKiB,QAAU,IDqBR,MAMLC,0BACOC,EAAI,QACJC,EAAW,CACdC,MAAkC,cAA3BrB,KAAKsB,SAASC,SACrBC,iBAAkB,KAClBC,aAAc,WAGXC,EAAOC,KAAKP,EAASC,MAAQ,MAAQ,YACrCO,GAAiB,EAEf,IAAIC,MAAMF,KAAM,CACrBG,IAAIC,EAAQC,MACND,EAAOC,UACFD,EAAOC,SAGVC,EAAa7B,EAA2B4B,UAC1CC,GACFF,EAAOG,sBAAsBD,KAGxBF,EAAOC,MAsBpBG,UAAUC,EAAU,OACbT,KAAKC,QAIF,IAAIS,MAAM,yDAHhBC,OAAOC,OAAOZ,KAAKP,EAAUgB,QACxBV,EAAOC,KAAKP,EAASC,MAAQ,MAAQ,OAiB9Ca,WAAWD,SACHO,EAAab,KAAKc,EAAeR,OAErCS,cAAcF,QACTZ,GAAiB,EACtB,MAAOe,SAKPC,QAAQC,kCACwBZ,YAAqBO,OAC/CG,GAYVF,EAAeR,MACTN,KAAKP,EAASK,oBACTE,KAAKP,EAASK,aAAaQ,EAAYN,KAAKP,EAASC,WAI1DyB,EAAY,CAAC3C,SAEX4C,KAAcd,KAAcN,KAAKD,OAEjCsB,EAAarB,KAAKP,EAASI,wBAC7BwB,GAMsC,MAJxCF,EAAYE,EAAWC,MAAM,MAIfH,EAAUI,OAAS,IAC/BJ,EAAUK,OAAOL,EAAUI,OAAS,EAAG,GAI3CJ,EAAUM,KAAKL,GAERD,EAAUO,KAAK"}
\ No newline at end of file
try{self["workbox:window:4.3.1"]&&_()}catch(n){}var n=function(n,t){return new Promise(function(i){var e=new MessageChannel;e.port1.onmessage=function(n){return i(n.data)},n.postMessage(t,[e.port2])})};function t(n,t){for(var i=0;i<t.length;i++){var e=t[i];e.enumerable=e.enumerable||!1,e.configurable=!0,"value"in e&&(e.writable=!0),Object.defineProperty(n,e.key,e)}}function i(n){if(void 0===n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return n}try{self["workbox:core:4.3.1"]&&_()}catch(n){}var e=function(){var n=this;this.promise=new Promise(function(t,i){n.resolve=t,n.reject=i})},r=function(n,t){return new URL(n,location).href===new URL(t,location).href},o=function(n,t){Object.assign(this,t,{type:n})};function u(n){return function(){for(var t=[],i=0;i<arguments.length;i++)t[i]=arguments[i];try{return Promise.resolve(n.apply(this,t))}catch(n){return Promise.reject(n)}}}function a(n,t,i){return i?t?t(n):n:(n&&n.then||(n=Promise.resolve(n)),t?n.then(t):n)}function s(){}var c=function(c){var f,h;function v(n,t){var r;return void 0===t&&(t={}),(r=c.call(this)||this).t=n,r.i=t,r.o=0,r.u=new e,r.s=new e,r.h=new e,r.v=r.v.bind(i(i(r))),r.l=r.l.bind(i(i(r))),r.g=r.g.bind(i(i(r))),r.m=r.m.bind(i(i(r))),r}h=c,(f=v).prototype=Object.create(h.prototype),f.prototype.constructor=f,f.__proto__=h;var l,w,g,d=v.prototype;return d.register=u(function(n){var t,i,e=this,u=(void 0===n?{}:n).immediate,c=void 0!==u&&u;return t=function(){return e.p=Boolean(navigator.serviceWorker.controller),e.P=e.R(),a(e.k(),function(n){e.B=n,e.P&&(e.O=e.P,e.s.resolve(e.P),e.h.resolve(e.P),e.j(e.P),e.P.addEventListener("statechange",e.l,{once:!0}));var t=e.B.waiting;return t&&r(t.scriptURL,e.t)&&(e.O=t,Promise.resolve().then(function(){e.dispatchEvent(new o("waiting",{sw:t,wasWaitingBeforeRegister:!0}))})),e.O&&e.u.resolve(e.O),e.B.addEventListener("updatefound",e.g),navigator.serviceWorker.addEventListener("controllerchange",e.m,{once:!0}),"BroadcastChannel"in self&&(e.C=new BroadcastChannel("workbox"),e.C.addEventListener("message",e.v)),navigator.serviceWorker.addEventListener("message",e.v),e.B})},(i=function(){if(!c&&"complete"!==document.readyState)return function(n,t){if(!t)return n&&n.then?n.then(s):Promise.resolve()}(new Promise(function(n){return addEventListener("load",n)}))}())&&i.then?i.then(t):t(i)}),d.getSW=u(function(){return this.O||this.u.promise}),d.messageSW=u(function(t){return a(this.getSW(),function(i){return n(i,t)})}),d.R=function(){var n=navigator.serviceWorker.controller;if(n&&r(n.scriptURL,this.t))return n},d.k=u(function(){var n=this;return function(n,t){try{var i=n()}catch(n){return t(n)}return i&&i.then?i.then(void 0,t):i}(function(){return a(navigator.serviceWorker.register(n.t,n.i),function(t){return n.L=performance.now(),t})},function(n){throw n})}),d.j=function(t){n(t,{type:"WINDOW_READY",meta:"workbox-window"})},d.g=function(){var n=this.B.installing;this.o>0||!r(n.scriptURL,this.t)||performance.now()>this.L+6e4?(this.W=n,this.B.removeEventListener("updatefound",this.g)):(this.O=n,this.u.resolve(n)),++this.o,n.addEventListener("statechange",this.l)},d.l=function(n){var t=this,i=n.target,e=i.state,r=i===this.W,u=r?"external":"",a={sw:i,originalEvent:n};!r&&this.p&&(a.isUpdate=!0),this.dispatchEvent(new o(u+e,a)),"installed"===e?this._=setTimeout(function(){"installed"===e&&t.B.waiting===i&&t.dispatchEvent(new o(u+"waiting",a))},200):"activating"===e&&(clearTimeout(this._),r||this.s.resolve(i))},d.m=function(n){var t=this.O;t===navigator.serviceWorker.controller&&(this.dispatchEvent(new o("controlling",{sw:t,originalEvent:n})),this.h.resolve(t))},d.v=function(n){var t=n.data;this.dispatchEvent(new o("message",{data:t,originalEvent:n}))},l=v,(w=[{key:"active",get:function(){return this.s.promise}},{key:"controlling",get:function(){return this.h.promise}}])&&t(l.prototype,w),g&&t(l,g),v}(function(){function n(){this.D={}}var t=n.prototype;return t.addEventListener=function(n,t){this.T(n).add(t)},t.removeEventListener=function(n,t){this.T(n).delete(t)},t.dispatchEvent=function(n){n.target=this,this.T(n.type).forEach(function(t){return t(n)})},t.T=function(n){return this.D[n]=this.D[n]||new Set},n}());export{c as Workbox,n as messageSW};
//# sourceMappingURL=workbox-window.prod.es5.mjs.map
try{self["workbox:window:4.3.1"]&&_()}catch(t){}const t=(t,s)=>new Promise(i=>{let e=new MessageChannel;e.port1.onmessage=(t=>i(t.data)),t.postMessage(s,[e.port2])});try{self["workbox:core:4.3.1"]&&_()}catch(t){}class s{constructor(){this.promise=new Promise((t,s)=>{this.resolve=t,this.reject=s})}}class i{constructor(){this.t={}}addEventListener(t,s){this.s(t).add(s)}removeEventListener(t,s){this.s(t).delete(s)}dispatchEvent(t){t.target=this,this.s(t.type).forEach(s=>s(t))}s(t){return this.t[t]=this.t[t]||new Set}}const e=(t,s)=>new URL(t,location).href===new URL(s,location).href;class n{constructor(t,s){Object.assign(this,s,{type:t})}}const h=200,a=6e4;class o extends i{constructor(t,i={}){super(),this.i=t,this.h=i,this.o=0,this.l=new s,this.g=new s,this.u=new s,this.m=this.m.bind(this),this.v=this.v.bind(this),this.p=this.p.bind(this),this._=this._.bind(this)}async register({immediate:t=!1}={}){t||"complete"===document.readyState||await new Promise(t=>addEventListener("load",t)),this.C=Boolean(navigator.serviceWorker.controller),this.W=this.L(),this.S=await this.B(),this.W&&(this.R=this.W,this.g.resolve(this.W),this.u.resolve(this.W),this.P(this.W),this.W.addEventListener("statechange",this.v,{once:!0}));const s=this.S.waiting;return s&&e(s.scriptURL,this.i)&&(this.R=s,Promise.resolve().then(()=>{this.dispatchEvent(new n("waiting",{sw:s,wasWaitingBeforeRegister:!0}))})),this.R&&this.l.resolve(this.R),this.S.addEventListener("updatefound",this.p),navigator.serviceWorker.addEventListener("controllerchange",this._,{once:!0}),"BroadcastChannel"in self&&(this.T=new BroadcastChannel("workbox"),this.T.addEventListener("message",this.m)),navigator.serviceWorker.addEventListener("message",this.m),this.S}get active(){return this.g.promise}get controlling(){return this.u.promise}async getSW(){return this.R||this.l.promise}async messageSW(s){const i=await this.getSW();return t(i,s)}L(){const t=navigator.serviceWorker.controller;if(t&&e(t.scriptURL,this.i))return t}async B(){try{const t=await navigator.serviceWorker.register(this.i,this.h);return this.U=performance.now(),t}catch(t){throw t}}P(s){t(s,{type:"WINDOW_READY",meta:"workbox-window"})}p(){const t=this.S.installing;this.o>0||!e(t.scriptURL,this.i)||performance.now()>this.U+a?(this.k=t,this.S.removeEventListener("updatefound",this.p)):(this.R=t,this.l.resolve(t)),++this.o,t.addEventListener("statechange",this.v)}v(t){const s=t.target,{state:i}=s,e=s===this.k,a=e?"external":"",o={sw:s,originalEvent:t};!e&&this.C&&(o.isUpdate=!0),this.dispatchEvent(new n(a+i,o)),"installed"===i?this.D=setTimeout(()=>{"installed"===i&&this.S.waiting===s&&this.dispatchEvent(new n(a+"waiting",o))},h):"activating"===i&&(clearTimeout(this.D),e||this.g.resolve(s))}_(t){const s=this.R;s===navigator.serviceWorker.controller&&(this.dispatchEvent(new n("controlling",{sw:s,originalEvent:t})),this.u.resolve(s))}m(t){const{data:s}=t;this.dispatchEvent(new n("message",{data:s,originalEvent:t}))}}export{o as Workbox,t as messageSW};
//# sourceMappingURL=workbox-window.prod.mjs.map
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((n=n||self).workbox={})}(this,function(n){"use strict";try{self["workbox:window:4.3.1"]&&_()}catch(n){}var t=function(n,t){return new Promise(function(i){var e=new MessageChannel;e.port1.onmessage=function(n){return i(n.data)},n.postMessage(t,[e.port2])})};function i(n,t){for(var i=0;i<t.length;i++){var e=t[i];e.enumerable=e.enumerable||!1,e.configurable=!0,"value"in e&&(e.writable=!0),Object.defineProperty(n,e.key,e)}}function e(n){if(void 0===n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return n}try{self["workbox:core:4.3.1"]&&_()}catch(n){}var r=function(){var n=this;this.promise=new Promise(function(t,i){n.resolve=t,n.reject=i})},o=function(n,t){return new URL(n,location).href===new URL(t,location).href},u=function(n,t){Object.assign(this,t,{type:n})};function s(n){return function(){for(var t=[],i=0;i<arguments.length;i++)t[i]=arguments[i];try{return Promise.resolve(n.apply(this,t))}catch(n){return Promise.reject(n)}}}function a(n,t,i){return i?t?t(n):n:(n&&n.then||(n=Promise.resolve(n)),t?n.then(t):n)}function c(){}var f=function(n){var f,h;function v(t,i){var o;return void 0===i&&(i={}),(o=n.call(this)||this).t=t,o.i=i,o.o=0,o.u=new r,o.s=new r,o.h=new r,o.v=o.v.bind(e(e(o))),o.l=o.l.bind(e(e(o))),o.g=o.g.bind(e(e(o))),o.m=o.m.bind(e(e(o))),o}h=n,(f=v).prototype=Object.create(h.prototype),f.prototype.constructor=f,f.__proto__=h;var l,w,d,g=v.prototype;return g.register=s(function(n){var t,i,e=this,r=(void 0===n?{}:n).immediate,s=void 0!==r&&r;return t=function(){return e.p=Boolean(navigator.serviceWorker.controller),e.P=e.j(),a(e.O(),function(n){e.R=n,e.P&&(e._=e.P,e.s.resolve(e.P),e.h.resolve(e.P),e.k(e.P),e.P.addEventListener("statechange",e.l,{once:!0}));var t=e.R.waiting;return t&&o(t.scriptURL,e.t)&&(e._=t,Promise.resolve().then(function(){e.dispatchEvent(new u("waiting",{sw:t,wasWaitingBeforeRegister:!0}))})),e._&&e.u.resolve(e._),e.R.addEventListener("updatefound",e.g),navigator.serviceWorker.addEventListener("controllerchange",e.m,{once:!0}),"BroadcastChannel"in self&&(e.B=new BroadcastChannel("workbox"),e.B.addEventListener("message",e.v)),navigator.serviceWorker.addEventListener("message",e.v),e.R})},(i=function(){if(!s&&"complete"!==document.readyState)return function(n,t){if(!t)return n&&n.then?n.then(c):Promise.resolve()}(new Promise(function(n){return addEventListener("load",n)}))}())&&i.then?i.then(t):t(i)}),g.getSW=s(function(){return this._||this.u.promise}),g.messageSW=s(function(n){return a(this.getSW(),function(i){return t(i,n)})}),g.j=function(){var n=navigator.serviceWorker.controller;if(n&&o(n.scriptURL,this.t))return n},g.O=s(function(){var n=this;return function(n,t){try{var i=n()}catch(n){return t(n)}return i&&i.then?i.then(void 0,t):i}(function(){return a(navigator.serviceWorker.register(n.t,n.i),function(t){return n.C=performance.now(),t})},function(n){throw n})}),g.k=function(n){t(n,{type:"WINDOW_READY",meta:"workbox-window"})},g.g=function(){var n=this.R.installing;this.o>0||!o(n.scriptURL,this.t)||performance.now()>this.C+6e4?(this.L=n,this.R.removeEventListener("updatefound",this.g)):(this._=n,this.u.resolve(n)),++this.o,n.addEventListener("statechange",this.l)},g.l=function(n){var t=this,i=n.target,e=i.state,r=i===this.L,o=r?"external":"",s={sw:i,originalEvent:n};!r&&this.p&&(s.isUpdate=!0),this.dispatchEvent(new u(o+e,s)),"installed"===e?this.W=setTimeout(function(){"installed"===e&&t.R.waiting===i&&t.dispatchEvent(new u(o+"waiting",s))},200):"activating"===e&&(clearTimeout(this.W),r||this.s.resolve(i))},g.m=function(n){var t=this._;t===navigator.serviceWorker.controller&&(this.dispatchEvent(new u("controlling",{sw:t,originalEvent:n})),this.h.resolve(t))},g.v=function(n){var t=n.data;this.dispatchEvent(new u("message",{data:t,originalEvent:n}))},l=v,(w=[{key:"active",get:function(){return this.s.promise}},{key:"controlling",get:function(){return this.h.promise}}])&&i(l.prototype,w),d&&i(l,d),v}(function(){function n(){this.D={}}var t=n.prototype;return t.addEventListener=function(n,t){this.M(n).add(t)},t.removeEventListener=function(n,t){this.M(n).delete(t)},t.dispatchEvent=function(n){n.target=this,this.M(n.type).forEach(function(t){return t(n)})},t.M=function(n){return this.D[n]=this.D[n]||new Set},n}());n.Workbox=f,n.messageSW=t,Object.defineProperty(n,"__esModule",{value:!0})});
//# sourceMappingURL=workbox-window.prod.umd.js.map
{
"name": "webpack",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/runtime": {
"version": "7.4.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz",
"integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==",
"requires": {
"regenerator-runtime": "0.13.2"
}
},
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"create-react-context": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz",
"integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==",
"requires": {
"fbjs": "0.8.17",
"gud": "1.0.0"
}
},
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"requires": {
"iconv-lite": "0.4.24"
}
},
"fbjs": {
"version": "0.8.17",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
"requires": {
"core-js": "1.2.7",
"isomorphic-fetch": "2.2.1",
"loose-envify": "1.4.0",
"object-assign": "4.1.1",
"promise": "7.3.1",
"setimmediate": "1.0.5",
"ua-parser-js": "0.7.19"
},
"dependencies": {
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
}
}
},
"gud": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
},
"history": {
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/history/-/history-4.9.0.tgz",
"integrity": "sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA==",
"requires": {
"@babel/runtime": "7.4.5",
"loose-envify": "1.4.0",
"resolve-pathname": "2.2.0",
"tiny-invariant": "1.0.4",
"tiny-warning": "1.0.2",
"value-equal": "0.4.0"
}
},
"hoist-non-react-statics": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz",
"integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==",
"requires": {
"react-is": "16.8.6"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"requires": {
"safer-buffer": "2.1.2"
}
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"isomorphic-fetch": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
"requires": {
"node-fetch": "1.7.3",
"whatwg-fetch": "3.0.0"
}
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"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": "4.0.0"
}
},
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
"requires": {
"encoding": "0.1.12",
"is-stream": "1.1.0"
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"path-to-regexp": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
"requires": {
"isarray": "0.0.1"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
}
}
},
"photoswipe": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/photoswipe/-/photoswipe-4.1.3.tgz",
"integrity": "sha512-89Z43IRUyw7ycTolo+AaiDn3W1EEIfox54hERmm9bI12IB9cvRfHSHez3XhAyU8XW2EAFrC+2sKMhh7SJwn0bA=="
},
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"requires": {
"asap": "2.0.6"
}
},
"prop-types": {
"version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
"requires": {
"loose-envify": "1.4.0",
"object-assign": "4.1.1",
"react-is": "16.8.6"
}
},
"react-is": {
"version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
},
"react-router": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.0.0.tgz",
"integrity": "sha512-6EQDakGdLG/it2x9EaCt9ZpEEPxnd0OCLBHQ1AcITAAx7nCnyvnzf76jKWG1s2/oJ7SSviUgfWHofdYljFexsA==",
"requires": {
"@babel/runtime": "7.4.5",
"create-react-context": "0.2.3",
"history": "4.9.0",
"hoist-non-react-statics": "3.3.0",
"loose-envify": "1.4.0",
"path-to-regexp": "1.7.0",
"prop-types": "15.7.2",
"react-is": "16.8.6",
"tiny-invariant": "1.0.4",
"tiny-warning": "1.0.2"
}
},
"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=="
},
"resolve-pathname": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
"integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
},
"tiny-invariant": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.4.tgz",
"integrity": "sha512-lMhRd/djQJ3MoaHEBrw8e2/uM4rs9YMNk0iOr8rHQ0QdbM7D4l0gFl3szKdeixrlyfm9Zqi4dxHCM2qVG8ND5g=="
},
"tiny-warning": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.2.tgz",
"integrity": "sha512-rru86D9CpQRLvsFG5XFdy0KdLAvjdQDyZCsRcuu60WtzFylDM3eAWSxEVz5kzL2Gp544XiUvPbVKtOA/txLi9Q=="
},
"ua-parser-js": {
"version": "0.7.19",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz",
"integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ=="
},
"value-equal": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
"integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
},
"whatwg-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
}
}
}
{
"name": "webpack",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.4.4",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/plugin-transform-runtime": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@babel/preset-react": "^7.0.0",
"@babel/runtime-corejs2": "^7.4.4",
"antd-mobile": "^2.2.13",
"autoprefixer": "^9.5.1",
"axios": "^0.18.0",
"babel-loader": "^8.0.5",
"babel-plugin-import": "^1.11.0",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.26.0",
"better-scroll": "^1.15.2",
"classnames": "^2.2.6",
"clean-webpack-plugin": "^2.0.2",
"core-js": "2",
"css-loader": "^2.1.1",
"eslint": "^4.13.1",
"eslint-loader": "^2.1.2",
"file-loader": "^3.0.1",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"imagemin": "^6.1.0",
"imagemin-gifsicle": "^6.0.1",
"imagemin-mozjpeg": "^8.0.0",
"imagemin-pngquant": "^7.0.0",
"imagemin-svgo": "^7.0.0",
"img-loader": "^3.0.1",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.6.0",
"mockjs": "^1.0.1-beta3",
"moment": "^2.24.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"photoswipe": "^4.1.3",
"postcss-loader": "^3.0.0",
"prerender-spa-plugin": "^3.4.0",
"prop-types": "^15.7.2",
"pubsub-js": "^1.7.0",
"qiniu-js": "^2.5.4",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-hot-loader": "^4.8.4",
"react-lazy-load": "^3.0.13",
"react-lazyload": "^2.5.0",
"react-lazyload-fadein": "^1.1.0",
"react-loadable": "^5.5.0",
"react-photoswipe": "^1.3.0",
"react-redux": "^7.0.3",
"react-router": "^5.0.0",
"react-router-dom": "^5.0.0",
"react-scroll": "^1.7.11",
"redux": "^4.0.1",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"style-loader": "^0.23.1",
"thread-loader": "^2.1.2",
"url-loader": "^1.1.2",
"webpack": "^4.30.0",
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^3.3.1",
"workbox-webpack-plugin": "^4.3.1"
},
"scripts": {
"start": "webpack-dev-server --config ./config/webpack.dev.js",
"dev": "webpack-dev-server --config ./config/webpack.dev.js",
"build": "webpack --config ./config/webpack.prod.js "
},
"devDependencies": {
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"preload-webpack-plugin": "^3.0.0-beta.3"
},
"theme": {
"brand-primary": "red",
"color-text-base": "#333"
}
}
module.exports = {
"plugins": {
"autoprefixer": {
"browsers": [
"ie >= 8",
"ff >= 30",
"chrome >= 34",
"safari >= 8",
"opera >= 23"
]
}
}
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="dns-prefetch" href='http://192.168.48.140'>
<link rel="dns-prefetch" href='http://192.168.48.140:8080'>
<title>Document</title>
<link href="https://cdn.bootcss.com/material-design-icons/3.0.1/iconfont/material-icons.min.css" rel="stylesheet">
</head>
<body>
<div id="root"></div>
</body>
<script>
window.onload = function () {
var stylenode = document.createElement('style');
var w = document.documentElement.clientWidth / 16;
stylenode.innerHTML = "html{font-size:" + w + "px !important}";
document.body.appendChild(stylenode);
}
// if ('serviceWorker' in navigator) {
// window.addEventListener('load', () => {
// navigator.serviceWorker.register('/service-worker.js').then((registration) => {
// console.log('SW registered: ', registration);
// }).catch((registrationError) => {
// console.log('SW registration failed: ', registrationError);
// });
// });
// }
</script>
</html>
\ No newline at end of file
import React from 'react';
import { withRouter, NavLink, Switch, Route, Redirect } from 'react-router-dom';
import Home from './pages/home';
import JobList from './pages/user/JobList';
import AddMaterial from './pages/user/addMaterial';
import TrainList from './pages/user/TrainList';
import Train from './pages/user/Train';
import NotFind from './pages/404';
import storage from '@/utils/storage.plugin';
import vc from '@/utils/vconsole';
//第二页,分类模块的文件使用react-loadable按需加载并且代码分割
class App extends React.Component {
constructor(props) {
super(props);
// this.state = {
// showSearchArr: ['/home', '/category', '/buy', 'shopcart', 'person', '/search']
// };
}
componentWillMount() {
vc();
let newObj = this.analysisQuery();
if (newObj && newObj.uid) {
storage.setSS('urlQuery', this.analysisQuery());
}
}
analysisQuery() {
let search = this.props.location.search;
if (!search) return '';
search = search.substr(1).split('&');
let obj = {};
search.forEach(item => {
let it = item.match(/(.+)=(.+)/);
obj[it[1]] = it[2];
});
return obj;
}
render() {
// let showFooter = true;
// const { pathname } = this.props.location;
// const { showSearchArr } = this.state;
// if (!showSearchArr.find(item => item === pathname)) {
// showFooter = false;
// }
return (
<div className="container">
<div className="page-content">
<Switch>
<Route path={['/user/job/add', '/user/job/:id']} component={AddMaterial} />
<Route path="/user/job" component={JobList} />
<Route path={['/user/train/add', '/user/train/:id']} component={Train} />
<Route path="/user/train" component={TrainList} />
<Route path="*" component={JobList} />
</Switch>
</div>
</div>
);
}
}
export default withRouter(App);
/**
* {showFooter ? (
<footer className="footer">
<NavLink to="/home" activeClassName="active" className="link">
<i className="material-icons">favorite_border</i>
<span>首页</span>
</NavLink>
<NavLink to="/category" activeClassName="active" className="link">
<i className="material-icons">reorder</i>
<span>分类</span>
</NavLink>
<NavLink to="/buy" activeClassName="active" className="link">
<i className="material-icons">card_giftcard</i>
<span>拼购</span>
</NavLink>
<NavLink to="/shopcart" activeClassName="active" className="link">
<i className="material-icons">bookmark_border</i>
<span>购物车</span>
</NavLink>
<NavLink to="/person" activeClassName="active" className="link">
<i className="material-icons">account_box</i>
<span>个人</span>
</NavLink>
</footer>
) : null}
* <Redirect to="/home" />
*/
//导出常用的高级组件
export { default as Header } from './static/Header/Header';
export { default as WrapLink } from './common/WrapLink/WrapLink';
/**
* Created by mqd on ${DATE}.
*/
import React, { Component } from 'react';
import {Icon} from 'antd-mobile';
import Footer from "../../Components/Footer/Footer";
export default class Loading extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
let {isLoading,Lists,total}=this.props;
return (
<div>
<div>
{
isLoading ? (
<div className="tac pt20 pb20">
<Icon type="loading" size="md"/>
<p className="grey">加载中...</p>
</div>
) : Lists
}
<div>
{this.state.total==0 && <div className="w100p tac pt40 pb40 bg-white">暂无数据</div>}
</div>
</div>
{Lists.length==total && Footer()}
</div>
);
}
}
import React from 'react';
import { Icon } from 'antd-mobile';
export default function Tips({ money }) {
if (!money) {
return null;
}
return (
<div className={'df bg-yellow fz14 ptb10 box-c orange'}>
<div className={'fx1'}>
<div className={'df aic'}>
<i className="iconfont icon-warn-s" />
因违规,需缴纳{money}
</div>
</div>
<span
className={'df aic'}
onClick={() => {
window.location.href = `/new/deposit/Pay?needPayQuality=${money}`;
}}
>
去缴纳
<Icon type={'right'} color={'orange'} size={'xs'} />
</span>
</div>
);
}
import React, { Component } from 'react';
import { ImagePicker } from 'antd-mobile';
import app from '../../../static/js/native';
import { PhotoSwipeGallery } from 'react-photoswipe';
import * as qiniu from 'qiniu-js';
import API from './api';
import 'react-photoswipe/lib/photoswipe.css';
class UpLoad extends Component {
state = {
isOpen: false,
maxSelectImageNumber: 1, //上传文件数
// certificateFiles: [],
ViewImagesIndex: 0
// viewImages: [] //查看大图list
};
componentDidMount() {
// appBridge({
// name: 'action_needLoad',
// option: {
// needLoad: false
// }
// });
}
// 获取随机字符串
random_string(len = 32) {
let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
let maxPos = chars.length;
let pwd = '';
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
// 得到后缀名
get_suffix(filename) {
let pos = filename.lastIndexOf('.');
let suffix = '';
if (pos != -1) {
suffix = filename.substring(pos);
}
return suffix;
}
// 推测文件随机名
calculate_object_name(filename) {
let suffix = this.get_suffix(filename);
let g_object_name = this.random_string(10) + suffix;
return g_object_name;
}
fileUploadQN(file) {
let _this = this;
let fileName = this.calculate_object_name(file.name);
let putExtra = {
fname: file.name,
params: {},
mimeType: ['image/png', 'image/jpeg', 'image/jpg']
};
let config = {
useCdnDomain: true,
region: qiniu.region.z0
};
let observer = {
next(res) {
_this.qiniuNext.call(_this, res);
},
error(err) {
_this.qiniuError.call(_this, err);
},
complete(res) {
_this.qiniuComplete.call(_this, res);
}
};
API.nodeQiniuFile().then(res => {
let observable = qiniu.upload(file, fileName, res.data, putExtra, config);
observable.subscribe(observer);
});
}
qiniuNext(res) {
// console.log("qiniuNext >>>>>>>")
}
qiniuError(err) {
this.props.refresh({
code: -1,
data: err
});
}
qiniuComplete(res) {
this.props.refresh({
code: 0,
data: res
});
}
//点击图片
onImageClickFun = (index, files) => {
this.setState({
ViewImagesIndex: index,
isOpen: true
});
};
//上传成功后或者删除
certificateChange = (certificateFiles, operationType, index) => {
//上传七牛云
if (operationType === 'add') {
this.fileUploadQN(certificateFiles[0].file);
} else {
this.props.delFile(certificateFiles);
}
};
//查看大图方法
closePhoto = () => {
this.setState({
isOpen: false
});
};
getThumbnailContent = item => <img src={item.thumbnail} width={80} height={80} alt="" />;
render() {
const { maxSelectImageNumber, isOpen } = this.state;
const { certificateFiles, viewImages } = this.props;
return (
<div className="photo-wrap">
<ImagePicker accept="image/png, image/jpeg, image/jpg" files={certificateFiles} onChange={this.certificateChange} onImageClick={this.onImageClickFun} selectable={certificateFiles.length < maxSelectImageNumber} />
<PhotoSwipeGallery items={viewImages} isOpen={isOpen} thumbnailContent={this.getThumbnailContent} options={{ closeOnScroll: false }} onClose={this.closePhoto} />
</div>
);
}
}
export default UpLoad;
import { nodeAxios } from './nodeAxios';
export default {
intercept(res) {
if (res.code == 0 || res.code == 200) {
return Promise.resolve(res);
} else {
return Promise.reject();
}
},
// node
nodeQiniuFile(data = {}) {
return nodeAxios.post('/qiniu/file', data).then(res => this.intercept(res));
}
};
import axios from 'axios';
const nodeAxios = axios.create({
baseURL: 'https://nodeapi.ydl.com/api',
timeout: 600000,
responseType: 'json',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json'
},
transformRequest: [
data => {
data = JSON.stringify(data);
return data;
}
],
validateStatus: status => status === 200
});
// 响应拦截
nodeAxios.interceptors.response.use((res = {}) => {
return Promise.resolve(res.data);
});
export { nodeAxios };
import { nodeAxios } from './nodeAxios';
export default {
intercept(res) {
if (res.code == 0 || res.code == 200) {
return Promise.resolve(res);
} else {
return Promise.reject();
}
},
// node
nodeQiniuFile(data = {}) {
return nodeAxios.post('/qiniu/file', data).then(res => this.intercept(res));
}
};
import axios from 'axios';
const nodeAxios = axios.create({
baseURL: 'https://nodeapi.ydl.com/api',
timeout: 600000,
responseType: 'json',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json'
},
transformRequest: [
data => {
data = JSON.stringify(data);
return data;
}
],
validateStatus: status => status === 200
});
// 响应拦截
nodeAxios.interceptors.response.use((res = {}) => {
return Promise.resolve(res.data);
});
export { nodeAxios };
import React, { Component } from 'react';
import * as qiniu from 'qiniu-js';
import API from './api';
class Page extends Component {
constructor(props) {
super(props);
}
// 获取随机字符串
random_string(len = 32) {
let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
let maxPos = chars.length;
let pwd = '';
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
// 得到后缀名
get_suffix(filename) {
let pos = filename.lastIndexOf('.');
let suffix = '';
if (pos != -1) {
suffix = filename.substring(pos);
}
return suffix;
}
// 推测文件随机名
calculate_object_name(filename) {
let suffix = this.get_suffix(filename);
let g_object_name = this.random_string(10) + suffix;
return g_object_name;
}
fileSelected() {
let _this = this;
let fileList = [];
let files = this.refs.fileDom.files,
filesLen = files.length;
console.log(files);
let file = files[0];
let fileName = this.calculate_object_name(files[0].name);
let putExtra = {
fname: files[0].name,
params: {},
mimeType: ['image/png', 'image/jpeg', 'image/gif']
};
let config = {
useCdnDomain: true,
region: qiniu.region.z0,
useCdnDomain: true
};
let observer = {
next(res) {
_this.qiniuNext.call(_this, res);
},
error(err) {
_this.qiniuError.call(_this, err);
},
complete(res) {
_this.qiniuComplete.call(_this, res);
}
};
API.nodeQiniuFile().then(res => {
let observable = qiniu.upload(file, fileName, res.data, putExtra, config);
observable.subscribe(observer);
});
}
qiniuNext(res) {
// console.log("qiniuNext >>>>>>>")
// console.log(res)
}
qiniuError(err) {
this.props.refresh({
code: -1,
data: err
});
}
qiniuComplete(res) {
this.props.refresh({
code: 0,
data: res
});
}
componentDidMount() {}
render() {
return (
<input
type="file"
name="file"
ref="fileDom"
accept="image/*"
onChange={() => {
this.fileSelected();
}}
/>
);
}
}
export default Page;
import React, { Component } from 'react';
import ClassNames from 'classnames';
class TabBar extends Component {
render() {
const { tabTexts, tabIndex, tabToggle } = this.props;
return (
<div className="nav-bar">
{tabTexts.map((tab, index) => (
<div
key={tab}
onClick={() => {
tabToggle(index);
}}
className={ClassNames('item-bar', { active: index == tabIndex })}
>
<span>{tab}</span>
</div>
))}
</div>
);
}
}
export default TabBar;
import React, { Component } from 'react';
import classNames from 'classnames';
import moment from 'moment';
import { withRouter } from 'react-router-dom';
import PropTypes from 'prop-types';
class TrainItem extends Component {
render() {
const { data, iType } = this.props;
// let trainInfo = data;
return (
<li className="train-item">
{data.auditStatus == '3' && <i className="y-icon-collate" />}
<div className="item-head df box-c">
<span className="fx1">{moment(data.modifyTime).format('YYYY-MM-DD')}</span>
{data.auditStatus == '1' && <span className="fz14 c-green">待核对</span>}
{data.auditStatus == '2' && <span className="fz14 c-red">核对失败</span>}
</div>
<div className="item-body df box-c">
{data.image && <div className="train-head" style={{ backgroundImage: `url(${data.image})` }} />}
<div className="body-con">
<div className="fz15 c-24 b ellipsis2">{data.info}</div>
{iType === 3 && (
<div className="c6 mt5">
培训时间:{moment(data.startTime).format('YYYY年MM月')}-{moment(data.endTime).format('YYYY年MM月')}
</div>
)}
</div>
</div>
<div className="item-operate box-c">
<span
onClick={() => {
this.props.delToggle({ id: data.id, delType: iType, modifyId: data.modifyId });
}}
className="o-btn"
>
删除
</span>
<span
onClick={() => {
console.log(this.props.history);
if (data.auditStatus == 1) return;
if (iType === 3) {
this.props.history.push(`/user/train/${data.id}?modifyId=${data.modifyId}`);
} else {
this.props.history.push(`/user/job/${data.id}?index=${iType}&modifyId=${data.modifyId}`);
}
}}
className={classNames('o-btn', { disabled: data.auditStatus == 1 })}
>
编辑
</span>
</div>
</li>
);
}
}
TrainItem.propTypes = {
iType: PropTypes.number,
data: PropTypes.object,
delToggle: PropTypes.func
};
export default withRouter(TrainItem);
import React, { Component } from 'react';
import { ImagePicker } from 'antd-mobile';
import { PhotoSwipeGallery } from 'react-photoswipe';
// import UploadFile from '../../common/UploadFile/file';
// import 'react-photoswipe/lib/photoswipe.css';
function getImgNaturalDimensions(imgSrc, callback) {
var nWidth, nHeight;
// if (img.naturalWidth) { // 现代浏览器
// nWidth = img.naturalWidth
// nHeight = img.naturalHeight
// } else { // IE6/7/8
const image = new Image();
image.src = imgSrc;
image.onload = () => {
callback(image.width, image.height);
};
// }
return [nWidth, nHeight];
}
class UpLoad extends Component {
state = {
isOpen: false,
maxSelectImageNumber: 2, //上传文件数
certificateFiles: [],
ViewImagesIndex: 0,
ViewImages: [] //查看大图list
};
//点击图片
onImageClickFun = (index, files) => {
console.log(index, files);
this.setState({
ViewImagesIndex: index,
isOpen: true
});
};
//上传成功后或者删除
certificateChange = (certificateFiles, operationType, index) => {
console.log(certificateFiles, operationType, index);
this.setState({
certificateFiles
});
let arr = [];
const _this = this;
certificateFiles.forEach(item => {
// imgReady(item.url, function() {
getImgNaturalDimensions(item.url, function(w, h) {
arr.push({
src: item.url,
w: w,
h: h
});
_this.setState({
ViewImages: arr
});
});
// });
});
// console.log('arr', JSON.stringify(arr));
// this.setState({
// ViewImages: arr
// });
};
//查看大图方法
closePhoto = () => {
this.setState({
isOpen: false
});
};
getThumbnailContent = item => <img src={item.thumbnail} width={120} height={90} alt="" />;
render() {
const { maxSelectImageNumber, certificateFiles, isOpen, ViewImages } = this.state;
return (
<div className="photo-wrap">
<ImagePicker files={certificateFiles} onChange={this.certificateChange} onImageClick={this.onImageClickFun} selectable={certificateFiles.length < maxSelectImageNumber} />
<PhotoSwipeGallery items={ViewImages} isOpen={isOpen} thumbnailContent={this.getThumbnailContent} options={{ closeOnScroll: false }} onClose={this.closePhoto} />
<style jsx>{``}</style>
</div>
);
}
}
export default UpLoad;
/**
* Created by mqd on ${DATE}.
*/
import React from 'react';
export default function Footer(){
return (
<div className="bg-white bdt1">
底部
</div>
);
}
import React, { PureComponent } from 'react';
export default class FooterButton extends PureComponent {
render() {
const { demoType, isFav, button } = this.props.detailData || {};
const { imgurl, shiting, joinCourse } = this.props;
return (
<div className={'fix b0 w100p bdt1'} style={{ height: '54px', zIndex: '54px', zIndex: 100, background: '#fff' }}>
<div className={'df fz10 tac'} style={{ paddingTop: '7px' }}>
<div className={'fx2 c6 df jca'}>
<p className={'df fxdc jcc w50p'} onClick={this.props.shoucang} style={{ paddingLeft: '10px' }}>
<img className="mauto" style={{ width: '20px' }} src={imgurl} />
<span>{isFav ? '已收藏' : '收藏'}</span>
</p>
{demoType ? (
<p className={'df fxdc jcc w50p pr15'} onClick={shiting}>
<img className="mauto" style={{ width: '20px' }} src="//static.ydlcdn.com/user/images/ico_listen_nor@3x.png" />
<span>试听</span>
</p>
) : (
<p className={'df fxdc jcc op5 w50p pr15'}>
<img className="mauto" style={{ width: '20px' }} src="//static.ydlcdn.com/user/images/course_ico_audio@3x.png" />
<span>试听</span>
</p>
)}
</div>
{button && button.type ? (
<div className={'fx4 bg-blue white h40 lh40 mr10 fz16 bdrs40'} style={{ background: '#108ee9' }} onClick={joinCourse}>
{button && button.desc}
</div>
) : (
<div className={'fx4 bg-blue white h40 lh40 mr10 fz16 bdrs40'} style={{ background: '#d8dade' }}>
{button && button.desc}
</div>
)}
</div>
</div>
);
}
}
import React, { PureComponent } from 'react';
export default class FooterButton extends PureComponent {
render() {
const { demoType, isFav, button } = this.props.detailData || {};
const { imgurl, shiting, joinCourse } = this.props;
return (
<div className={'fix b0 w100p bdt1'} style={{ height: '54px', zIndex: '54px', zIndex: 100, background: '#fff' }}>
<div className={'df fz10 tac'} style={{ paddingTop: '7px`' }}>
<div className={'fx2 c6 df jca'}>
<p className={'df fxdc jcc w50p'} onClick={this.props.shoucang} style={{ paddingLeft: '10px' }}>
<img className="mauto" style={{ width: '20px' }} src={imgurl} />
<span>{isFav ? '已收藏' : '收藏'}</span>
</p>
{demoType ? (
<p className={'df fxdc jcc w50p pr15'} onClick={shiting}>
<img className="mauto" style={{ width: '20px' }} src="//static.ydlcdn.com/user/images/ico_listen_nor@3x.png" />
<span>试听</span>
</p>
) : (
<p className={'df fxdc jcc op5 w50p pr15'}>
<img className="mauto" style={{ width: '20px' }} src="//static.ydlcdn.com/user/images/course_ico_audio@3x.png" />
<span>试听</span>
</p>
)}
</div>
{button && button.type ? (
<div className={'fx4 bg-blue white h40 lh40 mr10 fz16 bdrs40'} style={{ background: '#108ee9' }} onClick={joinCourse}>
{button && button.desc}
</div>
) : (
<div className={'fx4 bg-blue white h40 lh40 mr10 fz16 bdrs40'} style={{ background: '#d8dade' }}>
{button && button.desc}
</div>
)}
</div>
</div>
);
}
}
import React, { Component } from 'react';
import { NavBar, Icon } from 'antd-mobile';
export default class Header extends Component {
state = {};
componentDidMount() {}
goBack = () => {
window.history.back();
};
render() {
let { title } = this.props;
return (
<div className="navBarWrap">
<NavBar mode="dark" leftContent={<Icon type="left" onClick={this.goBack} />}>
{title}
</NavBar>
<style jsx>
{`
.navBarWrap {
position: absolute;
top: 0;
width: 100%;
height: 45px;
}
`}
</style>
</div>
);
}
}
import React, { Component } from 'react';
import storage from '@/utils/storage.plugin';
import vc from '@/utils/vconsole';
import { delHtmlTag } from '../../../utils/common';
import PropTypes from 'prop-types';
import { normalKeywords, normalDescription } from '../../../static/js/constant';
import 'antd-mobile/dist/antd-mobile.min.css';
import '@static/styles/global.less';
export default class Layout extends Component {
static propTypes = {
title: PropTypes.string,
children: PropTypes.node,
desc: PropTypes.string,
keywords: PropTypes.string,
url: PropTypes.string
};
componentDidMount() {
vc();
let newObj = this.analysisQuery();
if (newObj && newObj.uid) {
storage.setSS('urlQuery', this.analysisQuery());
}
// ENV === 'development' && storage.setLS('uid', 13090225);
}
analysisQuery() {
let search = location.search;
if (!search) return '';
search = search.substr(1).split('&');
let obj = {};
search.forEach(item => {
let it = item.match(/(.+)=(.+)/);
obj[it[1]] = it[2];
});
return obj;
}
render() {
let { title, children, keywords = normalKeywords, desc = normalDescription, ...other } = this.props;
return (
<div className="container">
{/*<Head>
<title>{title}</title>
<meta name="keywords" content={keywords} />
<meta name="description" content={delHtmlTag(desc)} />
</Head>
<Header title={title} border={true} /> */}
<div className="page-content">{children}</div>
{/*<Footer/>
<style global jsx>{`
.container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
// padding-top: 45px;
}
.container .page-content {
position: relative;
width: 100%;
height: 100%;
}
`}</style>
*/}
</div>
);
}
}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment