ncounter.git

git clone https://git.crispbyte.dev/ncounter.git

commit
b2208a7
parent
aace756
author
CheddarCrisp
date
2020-02-06 18:27:58 +0100 CET
Latest updates
15 files changed,  +1267, -131
M .gitignore
+2, -1
1@@ -1 +1,2 @@
2-node_modules/
3+node_modules/
4+dist/
D dist/index.html
+0, -52
 1@@ -1,52 +0,0 @@
 2-<!DOCTYPE html>
 3-<html>
 4-    <head>
 5-    	<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
 6-        <title>NCounter</title>
 7-        <style>
 8-        	body {
 9-        		font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
10-        	}
11-
12-        	button {
13-        		background: 0;
14-        		border: 0;
15-        	}
16-
17-        	.dialog {
18-			    display: flex;
19-			    justify-content: center;
20-			    align-items: center;
21-
22-			    position: fixed;
23-			    top: 0;
24-			    right: 0;
25-			    bottom: 0;
26-			    left: 0;
27-
28-			    background-color: rgba(0,0,0,0.25);
29-
30-			    z-index: 12;
31-
32-			    pointer-events: none;
33-			}
34-
35-			.dialog-content {
36-			    background-color: #E0E0E0;
37-			    pointer-events: all;
38-
39-			    width: 250px;
40-
41-			    border-radius: 5px;
42-			    box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
43-			    padding: 5px;
44-
45-			    display: flex;
46-			    flex-wrap: wrap;
47-			}
48-        </style>
49-    </head>
50-    <body>
51-        <script src="index.js"></script>
52-    </body>
53-</html>
D dist/index.js
+0, -1
1@@ -1 +0,0 @@
2-!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";function r(){}n.r(e);function o(t){return t()}function u(){return Object.create(null)}function c(t){t.forEach(o)}function i(t){return"function"==typeof t}function l(t,e){return t!=t?e==e:t!==e||t&&"object"==typeof t||"function"==typeof t}new Set;function a(t,e){t.appendChild(e)}function s(t,e,n){t.insertBefore(e,n||null)}function f(t){t.parentNode.removeChild(t)}function d(t){return document.createElement(t)}function m(t){return document.createTextNode(t)}function p(){return m(" ")}function $(t,e,n,r){return t.addEventListener(e,n,r),()=>t.removeEventListener(e,n,r)}function v(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function h(t,e){e=""+e,t.data!==e&&(t.data=e)}let g;function x(t){g=t}const y=[],b=Promise.resolve();let _=!1;const k=[],C=[],w=[];function O(){_||(_=!0,b.then(E))}function j(t){C.push(t)}function E(){const t=new Set;do{for(;y.length;){const t=y.shift();x(t),T(t.$$)}for(;k.length;)k.shift()();for(;C.length;){const e=C.pop();t.has(e)||(e(),t.add(e))}}while(y.length);for(;w.length;)w.pop()();_=!1}function T(t){t.fragment&&(t.update(t.dirty),c(t.before_render),t.fragment.p(t.dirty,t.ctx),t.dirty=null,t.after_render.forEach(j))}let M;function S(){M={remaining:0,callbacks:[]}}function P(){M.remaining||c(M.callbacks)}function V(t){M.callbacks.push(t)}let q;function I(t,e,n){const{fragment:r,on_mount:u,on_destroy:l,after_render:a}=t.$$;r.m(e,n),j(()=>{const e=u.map(o).filter(i);l?l.push(...e):c(e),t.$$.on_mount=[]}),a.forEach(j)}function L(t,e){t.$$&&(c(t.$$.on_destroy),t.$$.fragment.d(e),t.$$.on_destroy=t.$$.fragment=null,t.$$.ctx={})}function N(t,e,n,o,i,l){const a=g;x(t);const s=e.props||{},f=t.$$={fragment:null,ctx:null,props:l,update:r,not_equal:i,bound:u(),on_mount:[],on_destroy:[],before_render:[],after_render:[],context:new Map(a?a.$$.context:[]),callbacks:u(),dirty:null};let d=!1;var m;f.ctx=n?n(t,s,(e,n)=>{f.ctx&&i(f.ctx[e],f.ctx[e]=n)&&(f.bound[e]&&f.bound[e](n),d&&function(t,e){t.$$.dirty||(y.push(t),O(),t.$$.dirty=u()),t.$$.dirty[e]=!0}(t,e))}):s,f.update(),d=!0,c(f.before_render),f.fragment=o(f.ctx),e.target&&(e.hydrate?f.fragment.l((m=e.target,Array.from(m.childNodes))):f.fragment.c(),e.intro&&t.$$.fragment.i&&t.$$.fragment.i(),I(t,e.target,e.anchor),E()),x(a)}"undefined"!=typeof HTMLElement&&(q=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){for(const t in this.$$.slotted)this.appendChild(this.$$.slotted[t])}attributeChangedCallback(t,e,n){this[t]=n}$destroy(){L(this,!0),this.$destroy=r}$on(t,e){const n=this.$$.callbacks[t]||(this.$$.callbacks[t]=[]);return n.push(e),()=>{const t=n.indexOf(e);-1!==t&&n.splice(t,1)}}$set(){}});class A{$destroy(){L(this,!0),this.$destroy=r}$on(t,e){const n=this.$$.callbacks[t]||(this.$$.callbacks[t]=[]);return n.push(e),()=>{const t=n.indexOf(e);-1!==t&&n.splice(t,1)}}$set(){}}function B(t){var e,n,o,u=t.max-t.value;return{c(){e=d("span"),n=m(u),o=m(" remaining")},m(t,r){s(t,e,r),a(e,n),a(e,o)},p(t,e){(t.max||t.value)&&u!==(u=e.max-e.value)&&h(n,u)},i:r,o:r,d(t){t&&f(e)}}}function H(t,e,n){let{value:r,max:o}=e;return t.$set=(t=>{"value"in t&&n("value",r=t.value),"max"in t&&n("max",o=t.max)}),{value:r,max:o}}var K=class extends A{constructor(t){super(),N(this,t,H,B,l,["value","max"])}};function R(t){var e,n=new K({props:{value:t.counter.value,max:t.counter.max}});return{c(){n.$$.fragment.c()},m(t,r){I(n,t,r),e=!0},p(t,e){var r={};t.counter&&(r.value=e.counter.value),t.counter&&(r.max=e.counter.max),n.$set(r)},i(t){e||(n.$$.fragment.i(t),e=!0)},o(t){n.$$.fragment.o(t),e=!1},d(t){n.$destroy(t)}}}function z(t){var e,n;return{c(){(e=d("button")).textContent="+",v(e,"}",""),n=$(e,"click",t.click_handler)},m(t,n){s(t,e,n)},p:r,d(t){t&&f(e),n()}}}function D(t){var e,n,r,o;return{c(){e=d("input"),(r=d("button")).textContent="OK",v(e,"type","number"),o=[$(e,"input",t.input_input_handler),$(r,"click",t.increment)]},m(o,u){s(o,e,u),e.value=t.incrementValue,n=function(t){t.focus()}.call(null,e)||{},s(o,r,u)},p(t,n){t.incrementValue&&(e.value=n.incrementValue)},d(t){t&&f(e),n&&"function"==typeof n.destroy&&n.destroy(),t&&f(r),c(o)}}}function F(t){var e;return{c(){(e=d("div")).textContent="icon"},m(t,n){s(t,e,n)},d(t){t&&f(e)}}}function G(t){var e,n,r,o,u,c,i,l,v,g,x,y,b,_=t.counter.title,k=t.counter.value,C=t.counter.max&&R(t);function w(t){return t.showIncrement?D:t.counter.isClickCounter?void 0:z}var O=w(t),j=O&&O(t),E=t.counter.isClickCounter&&F();return{c(){e=d("div"),n=d("header"),r=m(_),o=p(),u=d("span"),c=m(k),i=p(),C&&C.c(),l=p(),j&&j.c(),v=p(),(g=d("button")).textContent="Reset",x=p(),E&&E.c(),e.className="counter svelte-16e2o0q",b=$(g,"click",t.reset)},m(t,f){s(t,e,f),a(e,n),a(n,r),a(e,o),a(e,u),a(u,c),a(e,i),C&&C.m(e,null),a(e,l),j&&j.m(e,null),a(e,v),a(e,g),a(e,x),E&&E.m(e,null),y=!0},p(t,n){y&&!t.counter||_===(_=n.counter.title)||h(r,_),y&&!t.counter||k===(k=n.counter.value)||h(c,k),n.counter.max?C?(C.p(t,n),C.i(1)):((C=R(n)).c(),C.i(1),C.m(e,l)):C&&(S(),V(()=>{C.d(1),C=null}),C.o(1),P()),O===(O=w(n))&&j?j.p(t,n):(j&&j.d(1),(j=O&&O(n))&&(j.c(),j.m(e,v))),n.counter.isClickCounter?E||((E=F()).c(),E.m(e,null)):E&&(E.d(1),E=null)},i(t){y||(C&&C.i(),y=!0)},o(t){C&&C.o(),y=!1},d(t){t&&f(e),C&&C.d(),j&&j.d(),E&&E.d(),b()}}}function J(t,e,n){let r,o,{counter:u}=e;return t.$set=(t=>{"counter"in t&&n("counter",u=t.counter)}),{counter:u,incrementValue:r,showIncrement:o,increment:function(){u.value+=r,n("counter",u),n("showIncrement",o=!1),n("incrementValue",r=null)},reset:function(){u.value=0,n("counter",u)},input_input_handler:function(){var t;t=this.value,n("incrementValue",r=""===t?void 0:+t)},click_handler:function(){n("showIncrement",o=!0)}}}var Q=class extends A{constructor(t){var e;super(),document.getElementById("svelte-16e2o0q-style")||((e=d("style")).id="svelte-16e2o0q-style",e.textContent=".counter.svelte-16e2o0q{border:1px solid black;margin-bottom:5px}",a(document.head,e)),N(this,t,J,G,l,["counter"])}};function U(t,e,n){const r=Object.create(t);return r.counter=e[n],r}function W(t){var e,n=new Q({props:{counter:t.counter}});return{c(){n.$$.fragment.c()},m(t,r){I(n,t,r),e=!0},p(t,e){var r={};t.counters&&(r.counter=e.counter),n.$set(r)},i(t){e||(n.$$.fragment.i(t),e=!0)},o(t){n.$$.fragment.o(t),e=!1},d(t){n.$destroy(t)}}}function X(t){for(var e,n,r=t.counters,o=[],u=0;u<r.length;u+=1)o[u]=W(U(t,r,u));function c(t,e,n){o[t]&&(e&&V(()=>{o[t].d(e),o[t]=null}),o[t].o(n))}return{c(){e=d("div");for(var t=0;t<o.length;t+=1)o[t].c()},m(t,r){s(t,e,r);for(var u=0;u<o.length;u+=1)o[u].m(e,null);n=!0},p(t,n){if(t.counters){r=n.counters;for(var u=0;u<r.length;u+=1){const c=U(n,r,u);o[u]?(o[u].p(t,c),o[u].i(1)):(o[u]=W(c),o[u].c(),o[u].i(1),o[u].m(e,null))}for(S();u<o.length;u+=1)c(u,1,1);P()}},i(t){if(!n){for(var e=0;e<r.length;e+=1)o[e].i();n=!0}},o(t){o=o.filter(Boolean);for(let t=0;t<o.length;t+=1)c(t,0);n=!1},d(t){t&&f(e),function(t,e){for(let n=0;n<t.length;n+=1)t[n]&&t[n].d(e)}(o,t)}}}function Y(t){return{counters:[{title:"Test 1",value:0},{title:"Test 2",value:10},{title:"Max Test",value:0,max:100},{title:"Click Test",value:0,isClickCounter:!0}]}}new class extends A{constructor(t){super(),N(this,t,Y,X,l,[])}}({target:document.body})}]);
M package-lock.json
+971, -16
   1@@ -4,6 +4,32 @@
   2   "lockfileVersion": 1,
   3   "requires": true,
   4   "dependencies": {
   5+    "@beyonk/google-fonts-webpack-plugin": {
   6+      "version": "1.2.3",
   7+      "resolved": "https://registry.npmjs.org/@beyonk/google-fonts-webpack-plugin/-/google-fonts-webpack-plugin-1.2.3.tgz",
   8+      "integrity": "sha512-QtWDQJmfqJrIuC6tZNNKYV9/+upRlGnu+11ycrSS22MutpSYeeqDzsSHUc0qKxfaiOAn4ASg13tj7EED5Wy68A==",
   9+      "dev": true,
  10+      "requires": {
  11+        "lodash": "^4.17.4",
  12+        "node-fetch": "^2.1.2",
  13+        "webpack-sources": "^1.1.0",
  14+        "yauzl": "^2.8.0"
  15+      },
  16+      "dependencies": {
  17+        "node-fetch": {
  18+          "version": "2.6.0",
  19+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
  20+          "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
  21+          "dev": true
  22+        }
  23+      }
  24+    },
  25+    "@types/anymatch": {
  26+      "version": "1.3.1",
  27+      "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
  28+      "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==",
  29+      "dev": true
  30+    },
  31     "@types/events": {
  32       "version": "3.0.0",
  33       "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
  34@@ -33,6 +59,76 @@
  35       "integrity": "sha1-NFKiTt+f6hOLSPrUoKAopoPaHkA=",
  36       "dev": true
  37     },
  38+    "@types/source-list-map": {
  39+      "version": "0.1.2",
  40+      "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
  41+      "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
  42+      "dev": true
  43+    },
  44+    "@types/tapable": {
  45+      "version": "1.0.5",
  46+      "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz",
  47+      "integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ==",
  48+      "dev": true
  49+    },
  50+    "@types/uglify-js": {
  51+      "version": "3.0.4",
  52+      "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz",
  53+      "integrity": "sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ==",
  54+      "dev": true,
  55+      "requires": {
  56+        "source-map": "^0.6.1"
  57+      },
  58+      "dependencies": {
  59+        "source-map": {
  60+          "version": "0.6.1",
  61+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
  62+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
  63+          "dev": true
  64+        }
  65+      }
  66+    },
  67+    "@types/webpack": {
  68+      "version": "4.41.5",
  69+      "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.5.tgz",
  70+      "integrity": "sha512-693JfV/83UZxpQY8vutDSwkDjNujy2327UrFqQciJWXh761B/aUIZIM5N05IRIZ17WwsG8VfUSE3edwXvkehiQ==",
  71+      "dev": true,
  72+      "requires": {
  73+        "@types/anymatch": "*",
  74+        "@types/node": "*",
  75+        "@types/tapable": "*",
  76+        "@types/uglify-js": "*",
  77+        "@types/webpack-sources": "*",
  78+        "source-map": "^0.6.0"
  79+      },
  80+      "dependencies": {
  81+        "source-map": {
  82+          "version": "0.6.1",
  83+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
  84+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
  85+          "dev": true
  86+        }
  87+      }
  88+    },
  89+    "@types/webpack-sources": {
  90+      "version": "0.1.6",
  91+      "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.6.tgz",
  92+      "integrity": "sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ==",
  93+      "dev": true,
  94+      "requires": {
  95+        "@types/node": "*",
  96+        "@types/source-list-map": "*",
  97+        "source-map": "^0.6.1"
  98+      },
  99+      "dependencies": {
 100+        "source-map": {
 101+          "version": "0.6.1",
 102+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
 103+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
 104+          "dev": true
 105+        }
 106+      }
 107+    },
 108     "@webassemblyjs/ast": {
 109       "version": "1.8.5",
 110       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
 111@@ -575,6 +671,12 @@
 112         "multicast-dns-service-types": "^1.1.0"
 113       }
 114     },
 115+    "boolbase": {
 116+      "version": "1.0.0",
 117+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
 118+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
 119+      "dev": true
 120+    },
 121     "brace-expansion": {
 122       "version": "1.1.11",
 123       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 124@@ -702,6 +804,12 @@
 125         "isarray": "^1.0.0"
 126       }
 127     },
 128+    "buffer-crc32": {
 129+      "version": "0.2.13",
 130+      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
 131+      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
 132+      "dev": true
 133+    },
 134     "buffer-from": {
 135       "version": "1.1.1",
 136       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
 137@@ -772,6 +880,16 @@
 138         "unset-value": "^1.0.0"
 139       }
 140     },
 141+    "camel-case": {
 142+      "version": "3.0.0",
 143+      "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
 144+      "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
 145+      "dev": true,
 146+      "requires": {
 147+        "no-case": "^2.2.0",
 148+        "upper-case": "^1.1.1"
 149+      }
 150+    },
 151     "camelcase": {
 152       "version": "5.3.1",
 153       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
 154@@ -857,6 +975,33 @@
 155         }
 156       }
 157     },
 158+    "clean-css": {
 159+      "version": "4.2.3",
 160+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
 161+      "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
 162+      "dev": true,
 163+      "requires": {
 164+        "source-map": "~0.6.0"
 165+      },
 166+      "dependencies": {
 167+        "source-map": {
 168+          "version": "0.6.1",
 169+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
 170+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
 171+          "dev": true
 172+        }
 173+      }
 174+    },
 175+    "clean-webpack-plugin": {
 176+      "version": "3.0.0",
 177+      "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz",
 178+      "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==",
 179+      "dev": true,
 180+      "requires": {
 181+        "@types/webpack": "^4.4.31",
 182+        "del": "^4.1.1"
 183+      }
 184+    },
 185     "cliui": {
 186       "version": "4.1.0",
 187       "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
 188@@ -1102,6 +1247,86 @@
 189         "randomfill": "^1.0.3"
 190       }
 191     },
 192+    "css-loader": {
 193+      "version": "3.4.2",
 194+      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz",
 195+      "integrity": "sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA==",
 196+      "dev": true,
 197+      "requires": {
 198+        "camelcase": "^5.3.1",
 199+        "cssesc": "^3.0.0",
 200+        "icss-utils": "^4.1.1",
 201+        "loader-utils": "^1.2.3",
 202+        "normalize-path": "^3.0.0",
 203+        "postcss": "^7.0.23",
 204+        "postcss-modules-extract-imports": "^2.0.0",
 205+        "postcss-modules-local-by-default": "^3.0.2",
 206+        "postcss-modules-scope": "^2.1.1",
 207+        "postcss-modules-values": "^3.0.0",
 208+        "postcss-value-parser": "^4.0.2",
 209+        "schema-utils": "^2.6.0"
 210+      },
 211+      "dependencies": {
 212+        "ajv": {
 213+          "version": "6.11.0",
 214+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
 215+          "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
 216+          "dev": true,
 217+          "requires": {
 218+            "fast-deep-equal": "^3.1.1",
 219+            "fast-json-stable-stringify": "^2.0.0",
 220+            "json-schema-traverse": "^0.4.1",
 221+            "uri-js": "^4.2.2"
 222+          }
 223+        },
 224+        "ajv-keywords": {
 225+          "version": "3.4.1",
 226+          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
 227+          "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
 228+          "dev": true
 229+        },
 230+        "fast-deep-equal": {
 231+          "version": "3.1.1",
 232+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
 233+          "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
 234+          "dev": true
 235+        },
 236+        "schema-utils": {
 237+          "version": "2.6.4",
 238+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz",
 239+          "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==",
 240+          "dev": true,
 241+          "requires": {
 242+            "ajv": "^6.10.2",
 243+            "ajv-keywords": "^3.4.1"
 244+          }
 245+        }
 246+      }
 247+    },
 248+    "css-select": {
 249+      "version": "1.2.0",
 250+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
 251+      "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
 252+      "dev": true,
 253+      "requires": {
 254+        "boolbase": "~1.0.0",
 255+        "css-what": "2.1",
 256+        "domutils": "1.5.1",
 257+        "nth-check": "~1.0.1"
 258+      }
 259+    },
 260+    "css-what": {
 261+      "version": "2.1.3",
 262+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
 263+      "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
 264+      "dev": true
 265+    },
 266+    "cssesc": {
 267+      "version": "3.0.0",
 268+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
 269+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
 270+      "dev": true
 271+    },
 272     "cyclist": {
 273       "version": "1.0.1",
 274       "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
 275@@ -1151,6 +1376,15 @@
 276         "ip-regex": "^2.1.0"
 277       }
 278     },
 279+    "define-properties": {
 280+      "version": "1.1.3",
 281+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
 282+      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
 283+      "dev": true,
 284+      "requires": {
 285+        "object-keys": "^1.0.12"
 286+      }
 287+    },
 288     "define-property": {
 289       "version": "2.0.2",
 290       "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
 291@@ -1277,12 +1511,64 @@
 292         "buffer-indexof": "^1.0.0"
 293       }
 294     },
 295+    "dom-converter": {
 296+      "version": "0.2.0",
 297+      "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
 298+      "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
 299+      "dev": true,
 300+      "requires": {
 301+        "utila": "~0.4"
 302+      }
 303+    },
 304+    "dom-serializer": {
 305+      "version": "0.2.2",
 306+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
 307+      "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
 308+      "dev": true,
 309+      "requires": {
 310+        "domelementtype": "^2.0.1",
 311+        "entities": "^2.0.0"
 312+      },
 313+      "dependencies": {
 314+        "domelementtype": {
 315+          "version": "2.0.1",
 316+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
 317+          "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
 318+          "dev": true
 319+        }
 320+      }
 321+    },
 322     "domain-browser": {
 323       "version": "1.2.0",
 324       "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
 325       "integrity": "sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto=",
 326       "dev": true
 327     },
 328+    "domelementtype": {
 329+      "version": "1.3.1",
 330+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
 331+      "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
 332+      "dev": true
 333+    },
 334+    "domhandler": {
 335+      "version": "2.4.2",
 336+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
 337+      "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
 338+      "dev": true,
 339+      "requires": {
 340+        "domelementtype": "1"
 341+      }
 342+    },
 343+    "domutils": {
 344+      "version": "1.5.1",
 345+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
 346+      "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
 347+      "dev": true,
 348+      "requires": {
 349+        "dom-serializer": "0",
 350+        "domelementtype": "1"
 351+      }
 352+    },
 353     "duplexify": {
 354       "version": "3.7.1",
 355       "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
 356@@ -1328,6 +1614,15 @@
 357       "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
 358       "dev": true
 359     },
 360+    "encoding": {
 361+      "version": "0.1.12",
 362+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
 363+      "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
 364+      "dev": true,
 365+      "requires": {
 366+        "iconv-lite": "~0.4.13"
 367+      }
 368+    },
 369     "end-of-stream": {
 370       "version": "1.4.1",
 371       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
 372@@ -1348,6 +1643,12 @@
 373         "tapable": "^1.0.0"
 374       }
 375     },
 376+    "entities": {
 377+      "version": "2.0.0",
 378+      "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
 379+      "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==",
 380+      "dev": true
 381+    },
 382     "errno": {
 383       "version": "0.1.7",
 384       "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
 385@@ -1357,6 +1658,36 @@
 386         "prr": "~1.0.1"
 387       }
 388     },
 389+    "es-abstract": {
 390+      "version": "1.17.4",
 391+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
 392+      "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
 393+      "dev": true,
 394+      "requires": {
 395+        "es-to-primitive": "^1.2.1",
 396+        "function-bind": "^1.1.1",
 397+        "has": "^1.0.3",
 398+        "has-symbols": "^1.0.1",
 399+        "is-callable": "^1.1.5",
 400+        "is-regex": "^1.0.5",
 401+        "object-inspect": "^1.7.0",
 402+        "object-keys": "^1.1.1",
 403+        "object.assign": "^4.1.0",
 404+        "string.prototype.trimleft": "^2.1.1",
 405+        "string.prototype.trimright": "^2.1.1"
 406+      }
 407+    },
 408+    "es-to-primitive": {
 409+      "version": "1.2.1",
 410+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
 411+      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
 412+      "dev": true,
 413+      "requires": {
 414+        "is-callable": "^1.1.4",
 415+        "is-date-object": "^1.0.1",
 416+        "is-symbol": "^1.0.2"
 417+      }
 418+    },
 419     "escape-html": {
 420       "version": "1.0.3",
 421       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
 422@@ -1643,6 +1974,15 @@
 423         "websocket-driver": ">=0.5.1"
 424       }
 425     },
 426+    "fd-slicer": {
 427+      "version": "1.1.0",
 428+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
 429+      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
 430+      "dev": true,
 431+      "requires": {
 432+        "pend": "~1.2.0"
 433+      }
 434+    },
 435     "figgy-pudding": {
 436       "version": "3.5.1",
 437       "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
 438@@ -1998,7 +2338,7 @@
 439           "dev": true,
 440           "optional": true,
 441           "requires": {
 442-            "safer-buffer": "2.1.2"
 443+            "safer-buffer": ">= 2.1.2 < 3"
 444           }
 445         },
 446         "ignore-walk": {
 447@@ -2102,9 +2442,9 @@
 448           "dev": true,
 449           "optional": true,
 450           "requires": {
 451-            "debug": "3.2.6",
 452-            "iconv-lite": "0.4.24",
 453-            "sax": "1.2.4"
 454+            "debug": "^3.2.6",
 455+            "iconv-lite": "^0.4.4",
 456+            "sax": "^1.2.4"
 457           }
 458         },
 459         "node-pre-gyp": {
 460@@ -2233,10 +2573,10 @@
 461           "dev": true,
 462           "optional": true,
 463           "requires": {
 464-            "deep-extend": "0.6.0",
 465-            "ini": "1.3.5",
 466-            "minimist": "1.2.0",
 467-            "strip-json-comments": "2.0.1"
 468+            "deep-extend": "^0.6.0",
 469+            "ini": "~1.3.0",
 470+            "minimist": "^1.2.0",
 471+            "strip-json-comments": "~2.0.1"
 472           },
 473           "dependencies": {
 474             "minimist": {
 475@@ -2313,9 +2653,9 @@
 476           "dev": true,
 477           "optional": true,
 478           "requires": {
 479-            "code-point-at": "1.1.0",
 480-            "is-fullwidth-code-point": "1.0.0",
 481-            "strip-ansi": "3.0.1"
 482+            "code-point-at": "^1.0.0",
 483+            "is-fullwidth-code-point": "^1.0.0",
 484+            "strip-ansi": "^3.0.0"
 485           }
 486         },
 487         "string_decoder": {
 488@@ -2324,7 +2664,7 @@
 489           "dev": true,
 490           "optional": true,
 491           "requires": {
 492-            "safe-buffer": "5.1.2"
 493+            "safe-buffer": "~5.1.0"
 494           }
 495         },
 496         "strip-ansi": {
 497@@ -2333,7 +2673,7 @@
 498           "dev": true,
 499           "optional": true,
 500           "requires": {
 501-            "ansi-regex": "2.1.1"
 502+            "ansi-regex": "^2.0.0"
 503           }
 504         },
 505         "strip-json-comments": {
 506@@ -2386,6 +2726,12 @@
 507         }
 508       }
 509     },
 510+    "function-bind": {
 511+      "version": "1.1.1",
 512+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
 513+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
 514+      "dev": true
 515+    },
 516     "get-caller-file": {
 517       "version": "1.0.3",
 518       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
 519@@ -2487,6 +2833,36 @@
 520         }
 521       }
 522     },
 523+    "google-fonts-webpack-plugin": {
 524+      "version": "0.4.4",
 525+      "resolved": "https://registry.npmjs.org/google-fonts-webpack-plugin/-/google-fonts-webpack-plugin-0.4.4.tgz",
 526+      "integrity": "sha512-+e2D9/DVBG9EDydRovzoqMZ658SsTBGbC0c65GyZqkwNvdj8vRSYQKXqbz7/yt7QaXsCPT1MpH45r3ivWOitcw==",
 527+      "dev": true,
 528+      "requires": {
 529+        "lodash": "^4.17.4",
 530+        "node-fetch": "^1.6.3",
 531+        "webpack-sources": "^0.2.0",
 532+        "yauzl": "^2.8.0"
 533+      },
 534+      "dependencies": {
 535+        "source-list-map": {
 536+          "version": "1.1.2",
 537+          "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.2.tgz",
 538+          "integrity": "sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE=",
 539+          "dev": true
 540+        },
 541+        "webpack-sources": {
 542+          "version": "0.2.3",
 543+          "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz",
 544+          "integrity": "sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=",
 545+          "dev": true,
 546+          "requires": {
 547+            "source-list-map": "^1.1.1",
 548+            "source-map": "~0.5.3"
 549+          }
 550+        }
 551+      }
 552+    },
 553     "graceful-fs": {
 554       "version": "4.1.15",
 555       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
 556@@ -2499,12 +2875,27 @@
 557       "integrity": "sha1-DgOWlf9QyT/CiFV9aW88HcZ3Z1Q=",
 558       "dev": true
 559     },
 560+    "has": {
 561+      "version": "1.0.3",
 562+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
 563+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
 564+      "dev": true,
 565+      "requires": {
 566+        "function-bind": "^1.1.1"
 567+      }
 568+    },
 569     "has-flag": {
 570       "version": "3.0.0",
 571       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
 572       "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
 573       "dev": true
 574     },
 575+    "has-symbols": {
 576+      "version": "1.0.1",
 577+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
 578+      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
 579+      "dev": true
 580+    },
 581     "has-value": {
 582       "version": "1.0.0",
 583       "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
 584@@ -2557,6 +2948,12 @@
 585         "minimalistic-assert": "^1.0.1"
 586       }
 587     },
 588+    "he": {
 589+      "version": "1.2.0",
 590+      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
 591+      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
 592+      "dev": true
 593+    },
 594     "hmac-drbg": {
 595       "version": "1.0.1",
 596       "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
 597@@ -2595,6 +2992,103 @@
 598       "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
 599       "dev": true
 600     },
 601+    "html-minifier": {
 602+      "version": "3.5.21",
 603+      "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz",
 604+      "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==",
 605+      "dev": true,
 606+      "requires": {
 607+        "camel-case": "3.0.x",
 608+        "clean-css": "4.2.x",
 609+        "commander": "2.17.x",
 610+        "he": "1.2.x",
 611+        "param-case": "2.1.x",
 612+        "relateurl": "0.2.x",
 613+        "uglify-js": "3.4.x"
 614+      },
 615+      "dependencies": {
 616+        "commander": {
 617+          "version": "2.17.1",
 618+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
 619+          "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
 620+          "dev": true
 621+        }
 622+      }
 623+    },
 624+    "html-webpack-plugin": {
 625+      "version": "3.2.0",
 626+      "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
 627+      "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=",
 628+      "dev": true,
 629+      "requires": {
 630+        "html-minifier": "^3.2.3",
 631+        "loader-utils": "^0.2.16",
 632+        "lodash": "^4.17.3",
 633+        "pretty-error": "^2.0.2",
 634+        "tapable": "^1.0.0",
 635+        "toposort": "^1.0.0",
 636+        "util.promisify": "1.0.0"
 637+      },
 638+      "dependencies": {
 639+        "big.js": {
 640+          "version": "3.2.0",
 641+          "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
 642+          "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
 643+          "dev": true
 644+        },
 645+        "json5": {
 646+          "version": "0.5.1",
 647+          "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
 648+          "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
 649+          "dev": true
 650+        },
 651+        "loader-utils": {
 652+          "version": "0.2.17",
 653+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
 654+          "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
 655+          "dev": true,
 656+          "requires": {
 657+            "big.js": "^3.1.3",
 658+            "emojis-list": "^2.0.0",
 659+            "json5": "^0.5.0",
 660+            "object-assign": "^4.0.1"
 661+          }
 662+        }
 663+      }
 664+    },
 665+    "htmlparser2": {
 666+      "version": "3.10.1",
 667+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
 668+      "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
 669+      "dev": true,
 670+      "requires": {
 671+        "domelementtype": "^1.3.1",
 672+        "domhandler": "^2.3.0",
 673+        "domutils": "^1.5.1",
 674+        "entities": "^1.1.1",
 675+        "inherits": "^2.0.1",
 676+        "readable-stream": "^3.1.1"
 677+      },
 678+      "dependencies": {
 679+        "entities": {
 680+          "version": "1.1.2",
 681+          "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
 682+          "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
 683+          "dev": true
 684+        },
 685+        "readable-stream": {
 686+          "version": "3.5.0",
 687+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz",
 688+          "integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==",
 689+          "dev": true,
 690+          "requires": {
 691+            "inherits": "^2.0.3",
 692+            "string_decoder": "^1.1.1",
 693+            "util-deprecate": "^1.0.1"
 694+          }
 695+        }
 696+      }
 697+    },
 698     "http-deceiver": {
 699       "version": "1.2.7",
 700       "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
 701@@ -2658,6 +3152,21 @@
 702         "safer-buffer": ">= 2.1.2 < 3"
 703       }
 704     },
 705+    "icss-utils": {
 706+      "version": "4.1.1",
 707+      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
 708+      "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
 709+      "dev": true,
 710+      "requires": {
 711+        "postcss": "^7.0.14"
 712+      }
 713+    },
 714+    "idb-keyval": {
 715+      "version": "3.2.0",
 716+      "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.2.0.tgz",
 717+      "integrity": "sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ==",
 718+      "dev": true
 719+    },
 720     "ieee754": {
 721       "version": "1.1.13",
 722       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
 723@@ -2686,6 +3195,12 @@
 724       "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
 725       "dev": true
 726     },
 727+    "indexes-of": {
 728+      "version": "1.0.1",
 729+      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
 730+      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
 731+      "dev": true
 732+    },
 733     "indexof": {
 734       "version": "0.0.1",
 735       "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
 736@@ -2795,6 +3310,12 @@
 737       "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=",
 738       "dev": true
 739     },
 740+    "is-callable": {
 741+      "version": "1.1.5",
 742+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
 743+      "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
 744+      "dev": true
 745+    },
 746     "is-data-descriptor": {
 747       "version": "0.1.4",
 748       "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
 749@@ -2815,6 +3336,12 @@
 750         }
 751       }
 752     },
 753+    "is-date-object": {
 754+      "version": "1.0.2",
 755+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
 756+      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
 757+      "dev": true
 758+    },
 759     "is-descriptor": {
 760       "version": "0.1.6",
 761       "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
 762@@ -2914,12 +3441,30 @@
 763         "isobject": "^3.0.1"
 764       }
 765     },
 766+    "is-regex": {
 767+      "version": "1.0.5",
 768+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
 769+      "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
 770+      "dev": true,
 771+      "requires": {
 772+        "has": "^1.0.3"
 773+      }
 774+    },
 775     "is-stream": {
 776       "version": "1.1.0",
 777       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
 778       "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
 779       "dev": true
 780     },
 781+    "is-symbol": {
 782+      "version": "1.0.3",
 783+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
 784+      "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
 785+      "dev": true,
 786+      "requires": {
 787+        "has-symbols": "^1.0.1"
 788+      }
 789+    },
 790     "is-windows": {
 791       "version": "1.0.2",
 792       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
 793@@ -3037,6 +3582,12 @@
 794       "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=",
 795       "dev": true
 796     },
 797+    "lower-case": {
 798+      "version": "1.1.4",
 799+      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
 800+      "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
 801+      "dev": true
 802+    },
 803     "lru-cache": {
 804       "version": "5.1.1",
 805       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
 806@@ -3357,6 +3908,25 @@
 807       "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=",
 808       "dev": true
 809     },
 810+    "no-case": {
 811+      "version": "2.3.2",
 812+      "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
 813+      "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
 814+      "dev": true,
 815+      "requires": {
 816+        "lower-case": "^1.1.1"
 817+      }
 818+    },
 819+    "node-fetch": {
 820+      "version": "1.7.3",
 821+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
 822+      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
 823+      "dev": true,
 824+      "requires": {
 825+        "encoding": "^0.1.11",
 826+        "is-stream": "^1.0.1"
 827+      }
 828+    },
 829     "node-forge": {
 830       "version": "0.7.5",
 831       "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz",
 832@@ -3417,6 +3987,15 @@
 833         "path-key": "^2.0.0"
 834       }
 835     },
 836+    "nth-check": {
 837+      "version": "1.0.2",
 838+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
 839+      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
 840+      "dev": true,
 841+      "requires": {
 842+        "boolbase": "~1.0.0"
 843+      }
 844+    },
 845     "number-is-nan": {
 846       "version": "1.0.1",
 847       "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
 848@@ -3460,6 +4039,18 @@
 849         }
 850       }
 851     },
 852+    "object-inspect": {
 853+      "version": "1.7.0",
 854+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
 855+      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
 856+      "dev": true
 857+    },
 858+    "object-keys": {
 859+      "version": "1.1.1",
 860+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
 861+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
 862+      "dev": true
 863+    },
 864     "object-visit": {
 865       "version": "1.0.1",
 866       "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
 867@@ -3469,6 +4060,28 @@
 868         "isobject": "^3.0.0"
 869       }
 870     },
 871+    "object.assign": {
 872+      "version": "4.1.0",
 873+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
 874+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
 875+      "dev": true,
 876+      "requires": {
 877+        "define-properties": "^1.1.2",
 878+        "function-bind": "^1.1.1",
 879+        "has-symbols": "^1.0.0",
 880+        "object-keys": "^1.0.11"
 881+      }
 882+    },
 883+    "object.getownpropertydescriptors": {
 884+      "version": "2.1.0",
 885+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
 886+      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
 887+      "dev": true,
 888+      "requires": {
 889+        "define-properties": "^1.1.3",
 890+        "es-abstract": "^1.17.0-next.1"
 891+      }
 892+    },
 893     "object.pick": {
 894       "version": "1.3.0",
 895       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
 896@@ -3608,6 +4221,15 @@
 897         "readable-stream": "^2.1.5"
 898       }
 899     },
 900+    "param-case": {
 901+      "version": "2.1.1",
 902+      "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
 903+      "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
 904+      "dev": true,
 905+      "requires": {
 906+        "no-case": "^2.2.0"
 907+      }
 908+    },
 909     "parse-asn1": {
 910       "version": "5.1.4",
 911       "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
 912@@ -3695,6 +4317,12 @@
 913         "sha.js": "^2.4.8"
 914       }
 915     },
 916+    "pend": {
 917+      "version": "1.2.0",
 918+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
 919+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
 920+      "dev": true
 921+    },
 922     "pify": {
 923       "version": "4.0.1",
 924       "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
 925@@ -3742,6 +4370,102 @@
 926       "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
 927       "dev": true
 928     },
 929+    "postcss": {
 930+      "version": "7.0.26",
 931+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz",
 932+      "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==",
 933+      "dev": true,
 934+      "requires": {
 935+        "chalk": "^2.4.2",
 936+        "source-map": "^0.6.1",
 937+        "supports-color": "^6.1.0"
 938+      },
 939+      "dependencies": {
 940+        "source-map": {
 941+          "version": "0.6.1",
 942+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
 943+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
 944+          "dev": true
 945+        },
 946+        "supports-color": {
 947+          "version": "6.1.0",
 948+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
 949+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
 950+          "dev": true,
 951+          "requires": {
 952+            "has-flag": "^3.0.0"
 953+          }
 954+        }
 955+      }
 956+    },
 957+    "postcss-modules-extract-imports": {
 958+      "version": "2.0.0",
 959+      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
 960+      "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
 961+      "dev": true,
 962+      "requires": {
 963+        "postcss": "^7.0.5"
 964+      }
 965+    },
 966+    "postcss-modules-local-by-default": {
 967+      "version": "3.0.2",
 968+      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz",
 969+      "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==",
 970+      "dev": true,
 971+      "requires": {
 972+        "icss-utils": "^4.1.1",
 973+        "postcss": "^7.0.16",
 974+        "postcss-selector-parser": "^6.0.2",
 975+        "postcss-value-parser": "^4.0.0"
 976+      }
 977+    },
 978+    "postcss-modules-scope": {
 979+      "version": "2.1.1",
 980+      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz",
 981+      "integrity": "sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ==",
 982+      "dev": true,
 983+      "requires": {
 984+        "postcss": "^7.0.6",
 985+        "postcss-selector-parser": "^6.0.0"
 986+      }
 987+    },
 988+    "postcss-modules-values": {
 989+      "version": "3.0.0",
 990+      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz",
 991+      "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==",
 992+      "dev": true,
 993+      "requires": {
 994+        "icss-utils": "^4.0.0",
 995+        "postcss": "^7.0.6"
 996+      }
 997+    },
 998+    "postcss-selector-parser": {
 999+      "version": "6.0.2",
1000+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz",
1001+      "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
1002+      "dev": true,
1003+      "requires": {
1004+        "cssesc": "^3.0.0",
1005+        "indexes-of": "^1.0.1",
1006+        "uniq": "^1.0.1"
1007+      }
1008+    },
1009+    "postcss-value-parser": {
1010+      "version": "4.0.2",
1011+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz",
1012+      "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==",
1013+      "dev": true
1014+    },
1015+    "pretty-error": {
1016+      "version": "2.1.1",
1017+      "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz",
1018+      "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=",
1019+      "dev": true,
1020+      "requires": {
1021+        "renderkid": "^2.0.1",
1022+        "utila": "~0.4"
1023+      }
1024+    },
1025     "process": {
1026       "version": "0.11.10",
1027       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
1028@@ -3934,12 +4658,48 @@
1029         "safe-regex": "^1.1.0"
1030       }
1031     },
1032+    "relateurl": {
1033+      "version": "0.2.7",
1034+      "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
1035+      "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
1036+      "dev": true
1037+    },
1038     "remove-trailing-separator": {
1039       "version": "1.1.0",
1040       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
1041       "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
1042       "dev": true
1043     },
1044+    "renderkid": {
1045+      "version": "2.0.3",
1046+      "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz",
1047+      "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==",
1048+      "dev": true,
1049+      "requires": {
1050+        "css-select": "^1.1.0",
1051+        "dom-converter": "^0.2",
1052+        "htmlparser2": "^3.3.0",
1053+        "strip-ansi": "^3.0.0",
1054+        "utila": "^0.4.0"
1055+      },
1056+      "dependencies": {
1057+        "ansi-regex": {
1058+          "version": "2.1.1",
1059+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
1060+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
1061+          "dev": true
1062+        },
1063+        "strip-ansi": {
1064+          "version": "3.0.1",
1065+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
1066+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
1067+          "dev": true,
1068+          "requires": {
1069+            "ansi-regex": "^2.0.0"
1070+          }
1071+        }
1072+      }
1073+    },
1074     "repeat-element": {
1075       "version": "1.1.3",
1076       "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
1077@@ -4170,6 +4930,15 @@
1078         "send": "0.17.1"
1079       }
1080     },
1081+    "serviceworker-webpack-plugin": {
1082+      "version": "1.0.1",
1083+      "resolved": "https://registry.npmjs.org/serviceworker-webpack-plugin/-/serviceworker-webpack-plugin-1.0.1.tgz",
1084+      "integrity": "sha512-VgDEkZ3pA0HajsRaWtl5w6bLxAXx0Y+4dm7YeTcIxVmvC9YXvstex38HOBDuYETeDS5fUlBy/47gC0QYBrG0nw==",
1085+      "dev": true,
1086+      "requires": {
1087+        "minimatch": "^3.0.4"
1088+      }
1089+    },
1090     "set-blocking": {
1091       "version": "2.0.0",
1092       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
1093@@ -4614,6 +5383,26 @@
1094         "strip-ansi": "^4.0.0"
1095       }
1096     },
1097+    "string.prototype.trimleft": {
1098+      "version": "2.1.1",
1099+      "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
1100+      "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
1101+      "dev": true,
1102+      "requires": {
1103+        "define-properties": "^1.1.3",
1104+        "function-bind": "^1.1.1"
1105+      }
1106+    },
1107+    "string.prototype.trimright": {
1108+      "version": "2.1.1",
1109+      "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
1110+      "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
1111+      "dev": true,
1112+      "requires": {
1113+        "define-properties": "^1.1.3",
1114+        "function-bind": "^1.1.1"
1115+      }
1116+    },
1117     "string_decoder": {
1118       "version": "1.1.1",
1119       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
1120@@ -4638,6 +5427,52 @@
1121       "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
1122       "dev": true
1123     },
1124+    "style-loader": {
1125+      "version": "1.1.3",
1126+      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.1.3.tgz",
1127+      "integrity": "sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw==",
1128+      "dev": true,
1129+      "requires": {
1130+        "loader-utils": "^1.2.3",
1131+        "schema-utils": "^2.6.4"
1132+      },
1133+      "dependencies": {
1134+        "ajv": {
1135+          "version": "6.11.0",
1136+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
1137+          "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
1138+          "dev": true,
1139+          "requires": {
1140+            "fast-deep-equal": "^3.1.1",
1141+            "fast-json-stable-stringify": "^2.0.0",
1142+            "json-schema-traverse": "^0.4.1",
1143+            "uri-js": "^4.2.2"
1144+          }
1145+        },
1146+        "ajv-keywords": {
1147+          "version": "3.4.1",
1148+          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
1149+          "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
1150+          "dev": true
1151+        },
1152+        "fast-deep-equal": {
1153+          "version": "3.1.1",
1154+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
1155+          "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
1156+          "dev": true
1157+        },
1158+        "schema-utils": {
1159+          "version": "2.6.4",
1160+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz",
1161+          "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==",
1162+          "dev": true,
1163+          "requires": {
1164+            "ajv": "^6.10.2",
1165+            "ajv-keywords": "^3.4.1"
1166+          }
1167+        }
1168+      }
1169+    },
1170     "supports-color": {
1171       "version": "5.5.0",
1172       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1173@@ -4808,6 +5643,12 @@
1174       "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM=",
1175       "dev": true
1176     },
1177+    "toposort": {
1178+      "version": "1.0.7",
1179+      "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz",
1180+      "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
1181+      "dev": true
1182+    },
1183     "tslib": {
1184       "version": "1.9.3",
1185       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
1186@@ -4836,6 +5677,30 @@
1187       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
1188       "dev": true
1189     },
1190+    "uglify-js": {
1191+      "version": "3.4.10",
1192+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
1193+      "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
1194+      "dev": true,
1195+      "requires": {
1196+        "commander": "~2.19.0",
1197+        "source-map": "~0.6.1"
1198+      },
1199+      "dependencies": {
1200+        "commander": {
1201+          "version": "2.19.0",
1202+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
1203+          "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
1204+          "dev": true
1205+        },
1206+        "source-map": {
1207+          "version": "0.6.1",
1208+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1209+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1210+          "dev": true
1211+        }
1212+      }
1213+    },
1214     "union-value": {
1215       "version": "1.0.1",
1216       "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
1217@@ -4848,6 +5713,12 @@
1218         "set-value": "^2.0.1"
1219       }
1220     },
1221+    "uniq": {
1222+      "version": "1.0.1",
1223+      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
1224+      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
1225+      "dev": true
1226+    },
1227     "unique-filename": {
1228       "version": "1.1.1",
1229       "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
1230@@ -4918,6 +5789,12 @@
1231       "integrity": "sha1-PbZYYA7a7sy+bbXmhNZ+6MKs0Gg=",
1232       "dev": true
1233     },
1234+    "upper-case": {
1235+      "version": "1.1.3",
1236+      "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
1237+      "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
1238+      "dev": true
1239+    },
1240     "uri-js": {
1241       "version": "4.2.2",
1242       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
1243@@ -4982,6 +5859,22 @@
1244       "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
1245       "dev": true
1246     },
1247+    "util.promisify": {
1248+      "version": "1.0.0",
1249+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
1250+      "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
1251+      "dev": true,
1252+      "requires": {
1253+        "define-properties": "^1.1.2",
1254+        "object.getownpropertydescriptors": "^2.0.3"
1255+      }
1256+    },
1257+    "utila": {
1258+      "version": "0.4.0",
1259+      "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
1260+      "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
1261+      "dev": true
1262+    },
1263     "utils-merge": {
1264       "version": "1.0.1",
1265       "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1266@@ -4989,9 +5882,9 @@
1267       "dev": true
1268     },
1269     "uuid": {
1270-      "version": "3.3.2",
1271-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
1272-      "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=",
1273+      "version": "3.4.0",
1274+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
1275+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
1276       "dev": true
1277     },
1278     "v8-compile-cache": {
1279@@ -5201,6 +6094,15 @@
1280         "uuid": "^3.3.2"
1281       }
1282     },
1283+    "webpack-merge": {
1284+      "version": "4.2.2",
1285+      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
1286+      "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==",
1287+      "dev": true,
1288+      "requires": {
1289+        "lodash": "^4.17.15"
1290+      }
1291+    },
1292     "webpack-sources": {
1293       "version": "1.3.0",
1294       "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz",
1295@@ -5250,6 +6152,49 @@
1296       "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
1297       "dev": true
1298     },
1299+    "workbox-cacheable-response": {
1300+      "version": "5.0.0",
1301+      "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-5.0.0.tgz",
1302+      "integrity": "sha512-H0sjiaS70lF+EEpWFhmbAF7mlOngkvD2UkdYIQLNeZMYPABlHsJfC4AzEeL99oZwvvaYl+PytOj+LvcnpYir9A==",
1303+      "dev": true,
1304+      "requires": {
1305+        "workbox-core": "^5.0.0"
1306+      }
1307+    },
1308+    "workbox-core": {
1309+      "version": "5.0.0",
1310+      "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-5.0.0.tgz",
1311+      "integrity": "sha512-vzUKj0Ac5l2IC66pnbIeXOjzoR/FfYaQR/q3ZWriLTEy7i7nbPPOVLGnaJbpAoEfPrlRjVysX7HIs9PRaZswig==",
1312+      "dev": true
1313+    },
1314+    "workbox-expiration": {
1315+      "version": "5.0.0",
1316+      "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-5.0.0.tgz",
1317+      "integrity": "sha512-DMFRwmYKI4PNoVAYiuMrxMlcYrd4RI2+6ggmNMIOIqXnI6kNvuZ02p9o/1zeoH+eT4jzVfoX5hTosgCd1w+otg==",
1318+      "dev": true,
1319+      "requires": {
1320+        "workbox-core": "^5.0.0"
1321+      }
1322+    },
1323+    "workbox-routing": {
1324+      "version": "5.0.0",
1325+      "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-5.0.0.tgz",
1326+      "integrity": "sha512-PbuuMKzXjDSjaKWMVGclElL2x4qvEcP7HUtDeO+qPJLCXedgyQ/TuXO/gicSh/7XEdX7iHeOd9HMYSksJ8BihA==",
1327+      "dev": true,
1328+      "requires": {
1329+        "workbox-core": "^5.0.0"
1330+      }
1331+    },
1332+    "workbox-strategies": {
1333+      "version": "5.0.0",
1334+      "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-5.0.0.tgz",
1335+      "integrity": "sha512-hvRch6eoclqnaPHfl04VHQou54ziu1J5KJ6YKIyx4nsYD/9xw4cbyGnKTaLJvHFMjK3ROB52zkGYYWbl7E9SfA==",
1336+      "dev": true,
1337+      "requires": {
1338+        "workbox-core": "^5.0.0",
1339+        "workbox-routing": "^5.0.0"
1340+      }
1341+    },
1342     "worker-farm": {
1343       "version": "1.7.0",
1344       "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
1345@@ -5359,6 +6304,16 @@
1346         "camelcase": "^5.0.0",
1347         "decamelize": "^1.2.0"
1348       }
1349+    },
1350+    "yauzl": {
1351+      "version": "2.10.0",
1352+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
1353+      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
1354+      "dev": true,
1355+      "requires": {
1356+        "buffer-crc32": "~0.2.3",
1357+        "fd-slicer": "~1.1.0"
1358+      }
1359     }
1360   }
1361 }
M package.json
+17, -3
 1@@ -5,16 +5,30 @@
 2   "private": true,
 3   "scripts": {
 4     "test": "echo \"Error: no test specified\" && exit 1",
 5-    "build": "webpack",
 6-    "start": "webpack-dev-server --open"
 7+    "build": "webpack --config webpack.prod.js",
 8+    "start": "webpack-dev-server --open --config webpack.dev.js"
 9   },
10   "author": "",
11   "license": "MIT",
12   "devDependencies": {
13+    "@beyonk/google-fonts-webpack-plugin": "^1.2.3",
14+    "clean-webpack-plugin": "^3.0.0",
15+    "css-loader": "^3.4.2",
16+    "google-fonts-webpack-plugin": "^0.4.4",
17+    "html-webpack-plugin": "^3.2.0",
18+    "idb-keyval": "^3.2.0",
19+    "serviceworker-webpack-plugin": "^1.0.1",
20+    "style-loader": "^1.1.3",
21     "svelte": "^3.4.1",
22     "svelte-loader": "^2.13.4",
23+    "uuid": "^3.4.0",
24     "webpack": "^4.31.0",
25     "webpack-cli": "^3.3.2",
26-    "webpack-dev-server": "^3.4.1"
27+    "webpack-dev-server": "^3.4.1",
28+    "webpack-merge": "^4.2.2",
29+    "workbox-cacheable-response": "^5.0.0",
30+    "workbox-expiration": "^5.0.0",
31+    "workbox-routing": "^5.0.0",
32+    "workbox-strategies": "^5.0.0"
33   }
34 }
M src/index.js
+5, -0
1@@ -1,3 +1,8 @@
2 import App from './ncounter/App.svelte';
3+import runtime from 'serviceworker-webpack-plugin/lib/runtime';
4+
5+if ('serviceWorker' in navigator) {
6+    const registration = runtime.register();
7+}
8 
9 new App({ target: document.body });
M src/ncounter/App.svelte
+9, -27
 1@@ -1,6 +1,6 @@
 2 <div class="app">
 3-{#each counters as counter}
 4-<Counter counter={ counter } on:save={() => { save(counter); } }></Counter>
 5+{#each $counters as counter}
 6+<Counter counterId={ counter.id }></Counter>
 7 {/each}
 8 </div>
 9 <button class="add" on:click="{ showAdd }"><i class="material-icons">add</i></button>
10@@ -12,38 +12,19 @@
11         <label>Target: <input type="number" bind:value={newCounter.max} /></label>
12         <label>Click counter: <input type="checkbox" bind:value={newCounter.isClickCounter} /></label>
13         <button on:click={ () => { showAddDialog = false; } }>Cancel</button>
14-        <button class="ok" on:click={ addCounter }>OK</button>
15+        <button class="ok" on:click={ add }>OK</button>
16     </div>
17 </div>
18 {/if}
19 <script>
20 import Counter from './Counter.svelte';
21+import { counters } from './db.js';
22+import './site.css';
23 
24 let showAddDialog = false;
25 
26 let newCounter = null;
27 
28-let counters = [
29-    {
30-        title: 'Test 1',
31-        value: 0
32-    },
33-    {
34-        title: 'Test 2',
35-        value: 10
36-    },
37-    {
38-        title: 'Max Test',
39-        value: 0,
40-        max: 100
41-    },
42-    {
43-        title: 'Click Test',
44-        value: 0,
45-        isClickCounter: true
46-    }
47-];
48-
49 function focus(node){
50     node.focus();
51 }
52@@ -56,7 +37,8 @@ function showAdd(){
53     newCounter = {
54         title: '',
55         value: 0,
56-        isClickCounter: false
57+        isClickCounter: false,
58+        history: []
59     }
60 
61     console.log({ newCounter });
62@@ -64,8 +46,8 @@ function showAdd(){
63     showAddDialog = true;
64 }
65 
66-function addCounter(){
67-    counters = [...counters, newCounter];
68+function add(){
69+    counters.add(newCounter);
70 
71     showAddDialog = false;
72 }
M src/ncounter/Counter.svelte
+65, -9
  1@@ -8,8 +8,10 @@
  2         {#if !counter.isClickCounter}
  3         <button on:click={ () => { showIncrement = true; } }><i class="material-icons">add</i></button>
  4         {/if}
  5+        <span class="message">{ message }</span>
  6         <button class="reset" on:click={ reset }><i class="material-icons">undo</i></button>
  7         <button on:click={ save }><i class="material-icons">save</i></button>
  8+        <button on:click={ remove }><i class="material-icons">delete</i></button>
  9     </div>
 10     {#if showIncrement}
 11     <div class="dialog">
 12@@ -25,20 +27,43 @@
 13 import MyProgress from './MyProgress.svelte';
 14 import { tick } from 'svelte';
 15 import { createEventDispatcher } from 'svelte';
 16+import { counters } from './db.js';
 17 
 18 const dispatch = createEventDispatcher();
 19 
 20-export let counter;
 21+export let counterId;
 22+
 23+$: counter = $counters.find(x => x.id == counterId);
 24 
 25 let incrementValue;
 26 let showIncrement;
 27+let message = '';
 28+
 29+const formatter = new Intl.DateTimeFormat('en-US',
 30+        {
 31+            month: 'short',
 32+            day: 'numeric',
 33+            year: 'numeric',
 34+            hour: 'numeric',
 35+            minute: 'numeric'
 36+        });
 37 
 38 function focus(node){
 39     node.focus();
 40 }
 41 
 42+function update(newCounter){
 43+    counters.update(newCounter);
 44+}
 45+
 46 function increment(){
 47-    counter.value += incrementValue;
 48+    const newCounter = {
 49+        ...counter,
 50+        value: counter.value + incrementValue
 51+    }
 52+
 53+    update(newCounter);
 54+    
 55     showIncrement = false;
 56     incrementValue = null;
 57 }
 58@@ -46,22 +71,52 @@ function increment(){
 59 function reset(e){
 60     e.stopPropagation();
 61 
 62-    if(confirm(`Reset ${counter.title}?`))
 63-        counter.value = 0;
 64+    if(confirm(`Reset ${counter.title}?`)){
 65+        const newCounter = {
 66+            ...counter,
 67+            value: 0
 68+        }
 69+
 70+        update(newCounter);
 71+    }
 72 }
 73 
 74 function save(e) {
 75     e.stopPropagation();
 76 
 77-    dispatch('save');
 78-    counter.value = 0;
 79+    const time = new Date();
 80+
 81+    const data = {
 82+        time,
 83+        value: counter.value
 84+    }
 85+
 86+    const newCounter = {
 87+        ...counter,
 88+        history: [...counter.history, data]
 89+    }
 90+
 91+    message = `Saved ${data.value} at ${formatter.format(data.time)}`;
 92+    setTimeout(() => message = '', 5000);
 93+
 94+    update(newCounter);
 95+}
 96+
 97+function remove(){
 98+    if(confirm(`Remove ${counter.title}?`))
 99+        counters.remove(counter);
100 }
101 
102 function clickCount() {
103     if(!counter.isClickCounter)
104         return;
105 
106-    counter.value++;
107+    const newCounter = {
108+        ...counter,
109+        value: counter.value + 1
110+    }
111+
112+    update(newCounter);
113 }
114 </script>
115 <style>
116@@ -79,8 +134,9 @@ function clickCount() {
117     display: flex;
118 }
119 
120-.reset {
121-    margin-left: auto;
122+.message {
123+    flex: 1;
124+    text-align: center;
125 }
126 
127 header {
A src/ncounter/db.js
+57, -0
 1@@ -0,0 +1,57 @@
 2+import { set as setDb, get as getDb } from 'idb-keyval';
 3+import { writable } from 'svelte/store';
 4+import uuid from 'uuid/v4';
 5+
 6+function createCounters(){
 7+    const {subscribe,set,update:updateVal} = writable([]);
 8+
 9+    getDb('counters').then(counters => {
10+        if(counters)
11+            set(counters);
12+    });
13+
14+    function add(counter){
15+        const newCounter = { id: uuid(), ...counter };
16+
17+        updateVal(counters => {
18+            const newCounters = [...counters, newCounter];
19+
20+            setDb('counters', newCounters);
21+
22+            return newCounters;
23+        });
24+    }
25+
26+    function update(counter){
27+        updateVal(counters => {
28+            const counterIndex = counters.findIndex(x => x.id == counter.id);
29+
30+            const newCounters = [...counters.slice(0, counterIndex), counter, ...counters.slice(counterIndex + 1)];
31+
32+            setDb('counters', newCounters);
33+
34+            return newCounters;
35+        });
36+    }
37+
38+    function remove(counter){
39+        updateVal(counters => {
40+            const counterIndex = counters.findIndex(x => x.id == counter.id);
41+
42+            const newCounters = [...counters.slice(0, counterIndex), ...counters.slice(counterIndex + 1)];
43+
44+            setDb('counters', newCounters);
45+
46+            return newCounters;
47+        })
48+    }
49+
50+    return {
51+        subscribe,
52+        add,
53+        update,
54+        remove
55+    };
56+}
57+
58+export const counters = createCounters();
A src/ncounter/site.css
+40, -0
 1@@ -0,0 +1,40 @@
 2+body {
 3+    font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
 4+}
 5+
 6+button {
 7+    background: 0;
 8+    border: 0;
 9+}
10+
11+.dialog {
12+    display: flex;
13+    justify-content: center;
14+    align-items: center;
15+
16+    position: fixed;
17+    top: 0;
18+    right: 0;
19+    bottom: 0;
20+    left: 0;
21+
22+    background-color: rgba(0,0,0,0.25);
23+
24+    z-index: 12;
25+
26+    pointer-events: none;
27+}
28+
29+.dialog-content {
30+    background-color: #E0E0E0;
31+    pointer-events: all;
32+
33+    width: 250px;
34+
35+    border-radius: 5px;
36+    box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
37+    padding: 5px;
38+
39+    display: flex;
40+    flex-wrap: wrap;
41+}
A src/sw.js
+41, -0
 1@@ -0,0 +1,41 @@
 2+import {registerRoute} from 'workbox-routing';
 3+import {CacheFirst, StaleWhileRevalidate, NetworkFirst} from 'workbox-strategies';
 4+import {CacheableResponsePlugin} from 'workbox-cacheable-response';
 5+import {ExpirationPlugin} from 'workbox-expiration';
 6+
 7+// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
 8+registerRoute(
 9+  /^https:\/\/fonts\.googleapis\.com/,
10+  new StaleWhileRevalidate({
11+    cacheName: 'google-fonts-stylesheets',
12+  })
13+);
14+
15+// Cache the underlying font files with a cache-first strategy for 1 year.
16+registerRoute(
17+  /^https:\/\/fonts\.gstatic\.com/,
18+  new CacheFirst({
19+    cacheName: 'google-fonts-webfonts',
20+    plugins: [
21+      new CacheableResponsePlugin({
22+        statuses: [0, 200],
23+      }),
24+      new ExpirationPlugin({
25+        maxAgeSeconds: 60 * 60 * 24 * 365,
26+        maxEntries: 30,
27+      }),
28+    ],
29+  })
30+);
31+
32+registerRoute(
33+    /\.(?:js|css)$/,
34+    new StaleWhileRevalidate({
35+      cacheName: 'static-resources',
36+    })
37+  );
38+  
39+registerRoute(
40+    '/',
41+    new NetworkFirst()
42+)
A webpack.common.js
+44, -0
 1@@ -0,0 +1,44 @@
 2+const path = require('path');
 3+const HtmlWebpackPlugin = require('html-webpack-plugin');
 4+const GoogleFontsPlugin = require('@beyonk/google-fonts-webpack-plugin');
 5+const { CleanWebpackPlugin } = require('clean-webpack-plugin');
 6+const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');
 7+
 8+module.exports = {
 9+    entry: './src/index.js',
10+    plugins: [
11+        new CleanWebpackPlugin(),
12+        new HtmlWebpackPlugin({
13+            title: 'NCounter',
14+        }),
15+        new GoogleFontsPlugin({
16+            fonts: [
17+                { family: "Material Icons" }
18+            ],
19+            local: false
20+        }),
21+        new ServiceWorkerWebpackPlugin({
22+            entry: path.join(__dirname, 'src/sw.js'),
23+        })
24+    ],
25+    output: {
26+        filename: 'index.js',
27+        path: path.resolve(__dirname, 'dist')
28+    },
29+    module: {
30+        rules: [
31+            {
32+                test: /\.svelte$/,
33+                exclude: /node_modules/,
34+                loader: 'svelte-loader'
35+            },
36+            {
37+                test: /\.css$/,
38+                use: [
39+                    'style-loader',
40+                    'css-loader'
41+                ]
42+            }
43+        ]
44+    },
45+}
D webpack.config.js
+0, -22
 1@@ -1,22 +0,0 @@
 2-const path = require('path');
 3-
 4-module.exports = {
 5-    entry: './src/index.js',
 6-    output: {
 7-        filename: 'index.js',
 8-        path: path.resolve(__dirname, 'dist')
 9-    },
10-    devServer: {
11-        contentBase: './dist'
12-    },
13-    module: {
14-        rules: [
15-            {
16-                test: /\.svelte$/,
17-                exclude: /node_modules/,
18-                loader: 'svelte-loader'
19-            }
20-        ]
21-    },
22-    devtool: 'inline-source-map'
23-}
A webpack.dev.js
+10, -0
 1@@ -0,0 +1,10 @@
 2+const merge = require('webpack-merge');
 3+const common = require('./webpack.common.js');
 4+
 5+module.exports = merge(common, {
 6+    mode: 'development',
 7+    devtool: 'inline-source-map',
 8+    devServer: {
 9+        contentBase: './dist',
10+    }
11+});
A webpack.prod.js
+6, -0
1@@ -0,0 +1,6 @@
2+const merge = require('webpack-merge');
3+const common = require('./webpack.common.js');
4+
5+module.exports = merge(common, {
6+    mode: 'production',
7+});