From 440b92eb8ea35fdabfadff623ff58fdd8b0549fc Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 14:47:27 -0400 Subject: [PATCH 01/60] Port admonition and code block CSS from RTK site --- website/src/css/custom.css | 109 ++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/website/src/css/custom.css b/website/src/css/custom.css index a6f35334fa..6baef0d53f 100755 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -1,3 +1,9 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ +/* You can override the default Infima variables here. */ :root { --ifm-color-primary: #764abc; --ifm-color-primary-dark: #6a43a9; @@ -8,13 +14,42 @@ --ifm-color-primary-lightest: #9f80d0; --ifm-code-font-size: 95%; + --ifm-code-border-radius: 3px; + --ifm-code-background: rgba(27, 31, 35, 0.05); --ifm-blockquote-color: #ecf4f9; --ifm-blockquote-color-dark: #cbddea; --ifm-code-padding-vertical: 0.1rem; --ifm-code-padding-horizontal: 0.2rem; + --ifm-pre-background: rgb(39, 40, 34); + + --ra-admonition-color: #ecf4f9; + --ra-admonition-color-dark: #2a98b9; + + --ra-admonition-color-important: #2a98b9; + + --ra-admonition-color-success: #f1fdf9; + --ra-admonition-color-success-dark: #00bf88; + + --ra-admonition-color-caution: #fffbf5; + --ra-admonition-color-caution-dark: #f0ad4e; + + --ra-admonition-color-error: #fff2f2; + --ra-admonition-color-error-dark: #d9534f; + + --ra-admonition-icon-color: black !important; } +@media screen and (max-width: 996px) { + :root { + --ifm-font-size-base: 15px; + } +} +@media screen and (min-width: 997px) { + :root { + --ifm-font-size-base: 17px; + } +} blockquote { color: var(--ifm-font-base-color); background-color: var(--ifm-blockquote-color); @@ -22,15 +57,50 @@ blockquote { border-radius: var(--ifm-global-radius); } +.docusaurus-highlight-code-line { + background-color: rgb(72, 77, 91); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); +} code { background-color: var(--ifm-color-emphasis-300); border-radius: 0.2rem; } -a code { +a code, +code a { color: inherit; } +a.contents__link > code { + color: inherit; +} + +a.contents__link.contents__link--active { + font-weight: 600; +} + +a:visited { + color: var(--ifm-color-primary); +} + +.pagination-nav .pagination-nav__link { + transition: all 0.2s ease; + border-color: var(--ifm-color-primary); +} +.pagination-nav__link .pagination-nav__link--label { + color: var(--ifm-color-primary); +} +.pagination-nav__link:hover { + background: var(--ifm-color-primary); + color: white; +} + +.pagination-nav__link:hover * { + color: white; +} + .navbar .navbar__items { flex: 1 1 auto; } @@ -114,3 +184,40 @@ a code { content: ' RECOMMENDED'; color: #2b5a99; } + + +.admonition { + color: var(--ifm-font-base-color); + border-radius: var(--ifm-global-radius); + border-left: 6px solid var(--ra-admonition-color-dark); +} + +.admonition.admonition-note, +.admonition.admonition-info, +.admonition.admonition-important, +.admonition.admonition-secondary { + --ra-admonition-color: #ecf4f9; + background-color: var(--ra-admonition-color); +} + +.admonition.admonition-success, +.admonition.admonition-tip { + background-color: var(--ra-admonition-color-success); + border-left-color: var(--ra-admonition-color-success-dark); +} + +.admonition.admonition-caution { + background-color: var(--ra-admonition-color-caution); + border-left-color: var(--ra-admonition-color-caution-dark); +} + +.admonition.admonition-warning, +.admonition.admonition-danger { + background-color: var(--ra-admonition-color-error); + border-left-color: var(--ra-admonition-color-error-dark); +} + +.admonition .admonition-icon svg { + fill: black; + stroke: black; +} From df95c143392892eef0e6e37b2c84462664eeab28 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 15:05:17 -0400 Subject: [PATCH 02/60] Restructure sidebars to add "Tutorials" section --- website/sidebars.js | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/website/sidebars.js b/website/sidebars.js index f08ecb0b8d..89dbd16377 100755 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -11,23 +11,34 @@ module.exports = { 'introduction/ecosystem', 'introduction/examples' ], - 'Basic Tutorial': [ - 'basics/basic-tutorial', - 'basics/actions', - 'basics/reducers', - 'basics/store', - 'basics/data-flow', - 'basics/usage-with-react', - 'basics/example' - ], - 'Advanced Tutorial': [ - 'advanced/advanced-tutorial', - 'advanced/async-actions', - 'advanced/async-flow', - 'advanced/middleware', - 'advanced/usage-with-react-router', - 'advanced/example-reddit-api', - 'advanced/next-steps' + Tutorials: [ + 'tutorials/quick-start', + { + type: 'category', + label: 'Basic Tutorial', + items: [ + 'basics/basic-tutorial', + 'basics/actions', + 'basics/reducers', + 'basics/store', + 'basics/data-flow', + 'basics/usage-with-react', + 'basics/example' + ] + }, + { + type: 'category', + label: 'Advanced Tutorial', + items: [ + 'advanced/advanced-tutorial', + 'advanced/async-actions', + 'advanced/async-flow', + 'advanced/middleware', + 'advanced/usage-with-react-router', + 'advanced/example-reddit-api', + 'advanced/next-steps' + ] + } ], Recipes: [ 'recipes/recipe-index', From 5d3b5077f15a7b1b3dcfc84b951cc369405317e5 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 15:05:33 -0400 Subject: [PATCH 03/60] Add empty "Quick Start" tutorial page --- docs/tutorials/quick-start.mdx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docs/tutorials/quick-start.mdx diff --git a/docs/tutorials/quick-start.mdx b/docs/tutorials/quick-start.mdx new file mode 100644 index 0000000000..4a0a50e629 --- /dev/null +++ b/docs/tutorials/quick-start.mdx @@ -0,0 +1,9 @@ +--- +id: quick-start +title: Quick Start +sidebar_label: Quick Start +hide_title: true +description: The official Quick Start tutorial for Redux - the fastest way to learn and start using Redux today! +--- + +# Quick Start From bfedc218445a0b85986443e3788c6aa95bc5be40 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 15:29:22 -0400 Subject: [PATCH 04/60] Bump Docusaurus to alpha.48 --- website/package-lock.json | 1420 ++++++++++++++++++++----------------- website/package.json | 4 +- 2 files changed, 756 insertions(+), 668 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index 71271769de..66a6a49450 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -11,11 +11,11 @@ } }, "@babel/compat-data": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.6.tgz", - "integrity": "sha512-CurCIKPTkS25Mb8mz267vU95vy+TyUpnctEX2lV33xWNmHAfjruztgiPBbXZRh3xZZy1CYvGx6XfxyTVS+sk7Q==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.0.tgz", + "integrity": "sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g==", "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.9.1", "invariant": "^2.2.4", "semver": "^5.5.0" }, @@ -28,21 +28,22 @@ } }, "@babel/core": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.6.tgz", - "integrity": "sha512-Sheg7yEJD51YHAvLEV/7Uvw95AeWqYPL3Vk3zGujJKIhJ+8oLw2ALaf3hbucILhKsgSoADOvtKRJuNVdcJkOrg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", + "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.6", - "@babel/helpers": "^7.8.4", - "@babel/parser": "^7.8.6", + "@babel/generator": "^7.9.0", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.0", + "@babel/parser": "^7.9.0", "@babel/template": "^7.8.6", - "@babel/traverse": "^7.8.6", - "@babel/types": "^7.8.6", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", + "json5": "^2.1.2", "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", @@ -57,11 +58,11 @@ } }, "@babel/generator": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.6.tgz", - "integrity": "sha512-4bpOR5ZBz+wWcMeVtcf7FbjcFzCp+817z2/gHNncIRcM9MmKzUhtWCYAq27RAfUrAFwb+OCG1s9WEaVxfi6cjg==", + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", + "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", "requires": { - "@babel/types": "^7.8.6", + "@babel/types": "^7.9.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -85,31 +86,31 @@ } }, "@babel/helper-builder-react-jsx": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz", - "integrity": "sha512-JT8mfnpTkKNCboTqZsQTdGo3l3Ik3l7QIt9hh0O9DYiwVel37VoJpILKM4YFbP2euF32nkQSb+F9cUk9b7DDXQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz", + "integrity": "sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw==", "requires": { - "@babel/types": "^7.8.3", - "esutils": "^2.0.0" + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/types": "^7.9.0" } }, - "@babel/helper-call-delegate": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz", - "integrity": "sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==", + "@babel/helper-builder-react-jsx-experimental": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.0.tgz", + "integrity": "sha512-3xJEiyuYU4Q/Ar9BsHisgdxZsRlsShMe90URZ0e6przL26CCs8NJbDoxH94kKT17PcxlMhsCAwZd90evCo26VQ==", "requires": { - "@babel/helper-hoist-variables": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-module-imports": "^7.8.3", + "@babel/types": "^7.9.0" } }, "@babel/helper-compilation-targets": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.6.tgz", - "integrity": "sha512-UrJdk27hKVJSnibFcUWYLkCL0ZywTUoot8yii1lsHJcvwrypagmYKjHLMWivQPm4s6GdyygCL8fiH5EYLxhQwQ==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz", + "integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==", "requires": { "@babel/compat-data": "^7.8.6", - "browserslist": "^4.8.5", + "browserslist": "^4.9.1", "invariant": "^2.2.4", "levenary": "^1.1.1", "semver": "^5.5.0" @@ -122,14 +123,27 @@ } } }, - "@babel/helper-create-regexp-features-plugin": { + "@babel/helper-create-class-features-plugin": { "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.6.tgz", - "integrity": "sha512-bPyujWfsHhV/ztUkwGHz/RPV1T1TDEsSZDsN42JPehndA+p1KKTh3npvTadux0ZhCrytx9tvjpWNowKby3tM6A==", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz", + "integrity": "sha512-klTBDdsr+VFFqaDHm5rR69OpEQtO2Qv8ECxHS1mNhJJvaHArR6a1xTf5K/eZW7eZpJbhCx3NW1Yt/sKsLXLblg==", + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", + "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-regex": "^7.8.3", - "regexpu-core": "^4.6.0" + "regexpu-core": "^4.7.0" } }, "@babel/helper-define-map": { @@ -194,16 +208,16 @@ } }, "@babel/helper-module-transforms": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz", - "integrity": "sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", "requires": { "@babel/helper-module-imports": "^7.8.3", "@babel/helper-replace-supers": "^7.8.6", "@babel/helper-simple-access": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", "@babel/template": "^7.8.6", - "@babel/types": "^7.8.6", + "@babel/types": "^7.9.0", "lodash": "^4.17.13" } }, @@ -268,6 +282,11 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-validator-identifier": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==" + }, "@babel/helper-wrap-function": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", @@ -280,22 +299,22 @@ } }, "@babel/helpers": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", - "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz", + "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==", "requires": { "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0" } }, "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", "requires": { + "@babel/helper-validator-identifier": "^7.9.0", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -312,9 +331,9 @@ } }, "@babel/parser": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.6.tgz", - "integrity": "sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g==" + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.8.3", @@ -353,10 +372,19 @@ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" } }, - "@babel/plugin-proposal-object-rest-spread": { + "@babel/plugin-proposal-numeric-separator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", + "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz", + "integrity": "sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow==", "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-object-rest-spread": "^7.8.0" @@ -372,20 +400,20 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz", - "integrity": "sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", + "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz", - "integrity": "sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==", + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", + "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-create-regexp-features-plugin": "^7.8.8", "@babel/helper-plugin-utils": "^7.8.3" } }, @@ -429,6 +457,14 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, "@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", @@ -461,6 +497,14 @@ "@babel/helper-plugin-utils": "^7.8.3" } }, + "@babel/plugin-syntax-typescript": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz", + "integrity": "sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, "@babel/plugin-transform-arrow-functions": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", @@ -497,9 +541,9 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz", - "integrity": "sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg==", + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz", + "integrity": "sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-define-map": "^7.8.3", @@ -520,9 +564,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz", - "integrity": "sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==", + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz", + "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==", "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -554,9 +598,9 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz", - "integrity": "sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", + "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -587,43 +631,43 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz", - "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz", + "integrity": "sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q==", "requires": { - "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz", - "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz", + "integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==", "requires": { - "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3", "@babel/helper-simple-access": "^7.8.3", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz", - "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz", + "integrity": "sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ==", "requires": { "@babel/helper-hoist-variables": "^7.8.3", - "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz", - "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", + "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", "requires": { - "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3" } }, @@ -653,11 +697,10 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz", - "integrity": "sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==", + "version": "7.9.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz", + "integrity": "sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg==", "requires": { - "@babel/helper-call-delegate": "^7.8.3", "@babel/helper-get-function-arity": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" } @@ -679,39 +722,50 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.8.3.tgz", - "integrity": "sha512-r0h+mUiyL595ikykci+fbwm9YzmuOrUBi0b+FDIKmi3fPQyFokWVEMJnRWHJPPQEjyFJyna9WZC6Viv6UHSv1g==", + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.4.tgz", + "integrity": "sha512-Mjqf3pZBNLt854CK0C/kRuXAnE6H/bo7xYojP+WGtX8glDGSibcwnsWwhwoSuRg0+EBnxPC1ouVnuetUIlPSAw==", + "requires": { + "@babel/helper-builder-react-jsx": "^7.9.0", + "@babel/helper-builder-react-jsx-experimental": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.9.0.tgz", + "integrity": "sha512-tK8hWKrQncVvrhvtOiPpKrQjfNX3DtkNLSX4ObuGcpS9p0QrGetKmlySIGR07y48Zft8WVgPakqd/bk46JrMSw==", "requires": { - "@babel/helper-builder-react-jsx": "^7.8.3", + "@babel/helper-builder-react-jsx-experimental": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-jsx": "^7.8.3" } }, "@babel/plugin-transform-react-jsx-self": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.8.3.tgz", - "integrity": "sha512-01OT7s5oa0XTLf2I8XGsL8+KqV9lx3EZV+jxn/L2LQ97CGKila2YMroTkCEIE0HV/FF7CMSRsIAybopdN9NTdg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.9.0.tgz", + "integrity": "sha512-K2ObbWPKT7KUTAoyjCsFilOkEgMvFG+y0FqOl6Lezd0/13kMkkjHskVsZvblRPj1PHA44PrToaZANrryppzTvQ==", "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-jsx": "^7.8.3" } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.8.3.tgz", - "integrity": "sha512-PLMgdMGuVDtRS/SzjNEQYUT8f4z1xb2BAT54vM1X5efkVuYBf5WyGUMbpmARcfq3NaglIwz08UVQK4HHHbC6ag==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.9.0.tgz", + "integrity": "sha512-K6m3LlSnTSfRkM6FcRk8saNEeaeyG5k7AVkBU2bZK3+1zdkSED3qNdsWrUgQBeTVD2Tp3VMmerxVO2yM5iITmw==", "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-jsx": "^7.8.3" } }, "@babel/plugin-transform-regenerator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz", - "integrity": "sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", + "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", "requires": { - "regenerator-transform": "^0.14.0" + "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { @@ -723,9 +777,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz", - "integrity": "sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz", + "integrity": "sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw==", "requires": { "@babel/helper-module-imports": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", @@ -782,6 +836,16 @@ "@babel/helper-plugin-utils": "^7.8.3" } }, + "@babel/plugin-transform-typescript": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.9.4.tgz", + "integrity": "sha512-yeWeUkKx2auDbSxRe8MusAG+n4m9BFY/v+lPjmQDgOFX5qnySkUY5oXzkp6FwPdsYqnKay6lorXYdC0n3bZO7w==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-typescript": "^7.8.3" + } + }, "@babel/plugin-transform-unicode-regex": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", @@ -792,26 +856,28 @@ } }, "@babel/preset-env": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.6.tgz", - "integrity": "sha512-M5u8llV9DIVXBFB/ArIpqJuvXpO+ymxcJ6e8ZAmzeK3sQeBNOD1y+rHvHCGG4TlEmsNpIrdecsHGHT8ZCoOSJg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz", + "integrity": "sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==", "requires": { - "@babel/compat-data": "^7.8.6", - "@babel/helper-compilation-targets": "^7.8.6", + "@babel/compat-data": "^7.9.0", + "@babel/helper-compilation-targets": "^7.8.7", "@babel/helper-module-imports": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-proposal-async-generator-functions": "^7.8.3", "@babel/plugin-proposal-dynamic-import": "^7.8.3", "@babel/plugin-proposal-json-strings": "^7.8.3", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-proposal-object-rest-spread": "^7.8.3", + "@babel/plugin-proposal-numeric-separator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.9.0", "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", - "@babel/plugin-proposal-optional-chaining": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.9.0", "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", "@babel/plugin-syntax-async-generators": "^7.8.0", "@babel/plugin-syntax-dynamic-import": "^7.8.0", "@babel/plugin-syntax-json-strings": "^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.8.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", "@babel/plugin-syntax-optional-chaining": "^7.8.0", @@ -820,26 +886,26 @@ "@babel/plugin-transform-async-to-generator": "^7.8.3", "@babel/plugin-transform-block-scoped-functions": "^7.8.3", "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.8.6", + "@babel/plugin-transform-classes": "^7.9.0", "@babel/plugin-transform-computed-properties": "^7.8.3", "@babel/plugin-transform-destructuring": "^7.8.3", "@babel/plugin-transform-dotall-regex": "^7.8.3", "@babel/plugin-transform-duplicate-keys": "^7.8.3", "@babel/plugin-transform-exponentiation-operator": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.8.6", + "@babel/plugin-transform-for-of": "^7.9.0", "@babel/plugin-transform-function-name": "^7.8.3", "@babel/plugin-transform-literals": "^7.8.3", "@babel/plugin-transform-member-expression-literals": "^7.8.3", - "@babel/plugin-transform-modules-amd": "^7.8.3", - "@babel/plugin-transform-modules-commonjs": "^7.8.3", - "@babel/plugin-transform-modules-systemjs": "^7.8.3", - "@babel/plugin-transform-modules-umd": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.9.0", + "@babel/plugin-transform-modules-commonjs": "^7.9.0", + "@babel/plugin-transform-modules-systemjs": "^7.9.0", + "@babel/plugin-transform-modules-umd": "^7.9.0", "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", "@babel/plugin-transform-new-target": "^7.8.3", "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.8.4", + "@babel/plugin-transform-parameters": "^7.8.7", "@babel/plugin-transform-property-literals": "^7.8.3", - "@babel/plugin-transform-regenerator": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", "@babel/plugin-transform-reserved-words": "^7.8.3", "@babel/plugin-transform-shorthand-properties": "^7.8.3", "@babel/plugin-transform-spread": "^7.8.3", @@ -847,8 +913,9 @@ "@babel/plugin-transform-template-literals": "^7.8.3", "@babel/plugin-transform-typeof-symbol": "^7.8.4", "@babel/plugin-transform-unicode-regex": "^7.8.3", - "@babel/types": "^7.8.6", - "browserslist": "^4.8.5", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.9.0", + "browserslist": "^4.9.1", "core-js-compat": "^3.6.2", "invariant": "^2.2.2", "levenary": "^1.1.1", @@ -862,24 +929,46 @@ } } }, + "@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", + "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, "@babel/preset-react": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.8.3.tgz", - "integrity": "sha512-9hx0CwZg92jGb7iHYQVgi0tOEHP/kM60CtWJQnmbATSPIQQ2xYzfoCI3EdqAhFBeeJwYMdWQuDUHMsuDbH9hyQ==", + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.9.4.tgz", + "integrity": "sha512-AxylVB3FXeOTQXNXyiuAQJSvss62FEotbX2Pzx3K/7c+MKJMdSg6Ose6QYllkdCFA8EInCJVw7M/o5QbLuA4ZQ==", "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-transform-react-display-name": "^7.8.3", - "@babel/plugin-transform-react-jsx": "^7.8.3", - "@babel/plugin-transform-react-jsx-self": "^7.8.3", - "@babel/plugin-transform-react-jsx-source": "^7.8.3" + "@babel/plugin-transform-react-jsx": "^7.9.4", + "@babel/plugin-transform-react-jsx-development": "^7.9.0", + "@babel/plugin-transform-react-jsx-self": "^7.9.0", + "@babel/plugin-transform-react-jsx-source": "^7.9.0" + } + }, + "@babel/preset-typescript": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz", + "integrity": "sha512-S4cueFnGrIbvYJgwsVFKdvOmpiL0XGw9MFW9D0vgRys5g36PBhZRL8NX8Gr2akz8XRtzq6HuDXPD/1nniagNUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-typescript": "^7.9.0" } }, "@babel/runtime": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.4.tgz", - "integrity": "sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ==", + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", + "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", "requires": { - "regenerator-runtime": "^0.13.2" + "regenerator-runtime": "^0.13.4" } }, "@babel/template": { @@ -893,27 +982,27 @@ } }, "@babel/traverse": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", - "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", + "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.6", + "@babel/generator": "^7.9.0", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.6.tgz", - "integrity": "sha512-wqz7pgWMIrht3gquyEFPVXeXCti72Rm8ep9b5tQKz9Yg9LzJA3HxosF1SB3Kc81KD1A3XBkkVYtJvCKS2Z/QrA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", + "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", "requires": { - "esutils": "^2.0.2", + "@babel/helper-validator-identifier": "^7.9.0", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -924,17 +1013,18 @@ "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==" }, "@docusaurus/core": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.0.0-alpha.43.tgz", - "integrity": "sha512-hHZP3gY6lJtvFhDJvl0sE4KExM81pAUkudHiGiRwevkM+SLxhe4if8ddYRPVyQ2yimbSkWHrMlY0uBr1znxzKA==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.0.0-alpha.48.tgz", + "integrity": "sha512-9PSjxopEkpb47ig0ZtuhurnH3Hokxi1prXWFFccmz86lDDgWxCctHqHdmItePbGqsIvihkNRUcG3uzGxXSQcGQ==", "requires": { "@babel/core": "^7.7.4", "@babel/plugin-syntax-dynamic-import": "^7.7.4", "@babel/plugin-transform-runtime": "^7.7.4", "@babel/preset-env": "^7.7.4", "@babel/preset-react": "^7.7.4", + "@babel/preset-typescript": "^7.7.4", "@babel/runtime": "^7.7.4", - "@docusaurus/utils": "^2.0.0-alpha.43", + "@docusaurus/utils": "^2.0.0-alpha.48", "@endiliey/static-site-generator-webpack-plugin": "^4.0.0", "babel-loader": "^8.0.6", "babel-plugin-dynamic-import-node": "^2.3.0", @@ -983,9 +1073,9 @@ } }, "@docusaurus/mdx-loader": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.0.0-alpha.43.tgz", - "integrity": "sha512-N3Hc3aKDnLLiklyfSwB20g4rgrwKymFCscCNz5AHvRliaCcO3zGTVIXcAeWTa2+B1weBqHao4Cj3Ftiv2/KaKw==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.0.0-alpha.48.tgz", + "integrity": "sha512-0Kzk6G7eoglrJJBj6mDVl0ZqGkCvw6wdFKTiLfMnHoc2hkT6tYR5CpBA8S8DJCmWKwY2vZUzY2f0lBZmqBVxWQ==", "requires": { "@babel/parser": "^7.7.4", "@babel/traverse": "^7.7.4", @@ -1004,12 +1094,12 @@ } }, "@docusaurus/plugin-content-blog": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-alpha.43.tgz", - "integrity": "sha512-bNzR4XFlU6Z8AzobZF7rB9oPnthHjzqe0Ty/fnqqnPMwiYiqjIaRk/GsxEsEQHv6dRRsJtGQZeEb4U5sAa681A==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-alpha.48.tgz", + "integrity": "sha512-+LdDTkySBO1FdPqJflUgY/OLi7444WtegIL60Wfz3v9QLJmqmcjyQ55USmICBtMO7a+y4HU4l8eT8cavVdAuoQ==", "requires": { - "@docusaurus/mdx-loader": "^2.0.0-alpha.43", - "@docusaurus/utils": "^2.0.0-alpha.43", + "@docusaurus/mdx-loader": "^2.0.0-alpha.48", + "@docusaurus/utils": "^2.0.0-alpha.48", "feed": "^4.0.0", "fs-extra": "^8.1.0", "globby": "^10.0.1", @@ -1018,12 +1108,12 @@ } }, "@docusaurus/plugin-content-docs": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-alpha.43.tgz", - "integrity": "sha512-dT+TTRRtAU1HoCD3qD6vv4YRoBd91ItFJZU7BKYFa/UpkQy+lRm51I/eygvptZfx0+pwxwZvHDsw/RdVo0aeyA==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-alpha.48.tgz", + "integrity": "sha512-p9RRUKSwPTC6IBAnxFcE3ytHA3WhgKkN0X1xrf+utyiQ6q365dC60vNKBnKtBdYQWjPQGfYXqqlutAP/ERhtUw==", "requires": { - "@docusaurus/mdx-loader": "^2.0.0-alpha.43", - "@docusaurus/utils": "^2.0.0-alpha.43", + "@docusaurus/mdx-loader": "^2.0.0-alpha.48", + "@docusaurus/utils": "^2.0.0-alpha.48", "execa": "^3.4.0", "fs-extra": "^8.1.0", "globby": "^10.0.1", @@ -1128,80 +1218,81 @@ } }, "@docusaurus/plugin-content-pages": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-alpha.43.tgz", - "integrity": "sha512-TPcHHv6l1XuhvqiXTi6Kquogjys/6yabG59qNRNsaFwRQ20vKjYvDVaVXt94zEti3PeYVlszZwksnWbAa71pbg==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-alpha.48.tgz", + "integrity": "sha512-9jS2gvlkPxQcCgN8sUt7zAsgKlo9SuToIekKTRmdzrpVfVu2xEcN/Mw5Uak8HlBgi1dr+9+TyM7drRU+VeRGTg==", "requires": { - "@docusaurus/types": "^2.0.0-alpha.43", - "@docusaurus/utils": "^2.0.0-alpha.43", + "@docusaurus/types": "^2.0.0-alpha.48", + "@docusaurus/utils": "^2.0.0-alpha.48", "globby": "^10.0.1" } }, "@docusaurus/plugin-google-analytics": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.0.0-alpha.43.tgz", - "integrity": "sha512-5QvIhjqsAroxa5bPAsaI0j500MMRUWNqRZZ3g/1nrUCFTmvUS445NEqr+oG0g+IK17kRcTwBOzzfOqAkT5OUuQ==" + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.0.0-alpha.48.tgz", + "integrity": "sha512-/yUY5qPQA/ciwviv+ndpTSJRzZAUWHBpMKH8wk9WOzCdHsHv4IYt4boV47aZBNlaNMfGmCS5eUlj1NZ+KLTPsQ==" }, "@docusaurus/plugin-google-gtag": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-alpha.43.tgz", - "integrity": "sha512-9BDZTjn7GvIn8VoYGrN3XIiL4WJ7FryovTmHcft64oj/fCFt/buR+IFUhRzGCr1Pss+2LeBQtYB6rM+W1joNuA==" + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-alpha.48.tgz", + "integrity": "sha512-VwPgs7Y9Msv+orBR68HRrKlEi7Vj3FsKta92V6T6vi3QozUFNYYET0PBsMD4xWQT/TxCW3qUYaQlTwqSu/HYmA==" }, "@docusaurus/plugin-sitemap": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-alpha.43.tgz", - "integrity": "sha512-YFuxfpSxhzz1Jpterx9xfvAOvE/m69e/A4q/mENIhPbdg0ldkmaeMRpbk1Ir7bfRz2jNhcAbLDzsKZjoJOJLdw==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-alpha.48.tgz", + "integrity": "sha512-nC5bZi1LDPrnB3d874AsvTE3vG6uI1GbzKYl5U4x3gQ/plA6OBg2SwLm/2gPnZ5viT9XYux+AVgA+ONwo43j2Q==", "requires": { - "@docusaurus/types": "^2.0.0-alpha.43", + "@docusaurus/types": "^2.0.0-alpha.48", "sitemap": "^3.2.2" } }, "@docusaurus/preset-classic": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-2.0.0-alpha.43.tgz", - "integrity": "sha512-UF7GN/Xu1VzCGL0bbASaSe09Wwp0w/jJ04Iyn89zNK3cm5ld+fPWtxPHbZZWrEpn03UNQ57pXpSm0nj7SSuLmg==", - "requires": { - "@docusaurus/plugin-content-blog": "^2.0.0-alpha.43", - "@docusaurus/plugin-content-docs": "^2.0.0-alpha.43", - "@docusaurus/plugin-content-pages": "^2.0.0-alpha.43", - "@docusaurus/plugin-google-analytics": "^2.0.0-alpha.43", - "@docusaurus/plugin-google-gtag": "^2.0.0-alpha.43", - "@docusaurus/plugin-sitemap": "^2.0.0-alpha.43", - "@docusaurus/theme-classic": "^2.0.0-alpha.43", - "@docusaurus/theme-search-algolia": "^2.0.0-alpha.43", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-2.0.0-alpha.48.tgz", + "integrity": "sha512-MjYqvp/x40WNG3Z+ch9KyQ68Mpf3yyeo8oJnGLA7gT0I3hMMKX28N0kEq5YL6ehxZM7H0qOtyKjMUow6LBnygQ==", + "requires": { + "@docusaurus/plugin-content-blog": "^2.0.0-alpha.48", + "@docusaurus/plugin-content-docs": "^2.0.0-alpha.48", + "@docusaurus/plugin-content-pages": "^2.0.0-alpha.48", + "@docusaurus/plugin-google-analytics": "^2.0.0-alpha.48", + "@docusaurus/plugin-google-gtag": "^2.0.0-alpha.48", + "@docusaurus/plugin-sitemap": "^2.0.0-alpha.48", + "@docusaurus/theme-classic": "^2.0.0-alpha.48", + "@docusaurus/theme-search-algolia": "^2.0.0-alpha.48", "remark-admonitions": "^1.1.0" } }, "@docusaurus/theme-classic": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.0.0-alpha.43.tgz", - "integrity": "sha512-/Rc1Jkncn5yqoaehBVN6/UDRuj6zCTk/oD/VakhWV3FZ9BeEvGxQ27klr0c4x2YCF+iBWilbnr+Mm/XJqNqrEQ==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.0.0-alpha.48.tgz", + "integrity": "sha512-pDC2aVQ2lsaaxMifvA98LLPDZNRz+t9/4iZYj1DHd5J+jfYLZCplH3YlEKRp3pUiJRt6delDO2S04OIAvz9ftQ==", "requires": { "@mdx-js/mdx": "^1.5.1", "@mdx-js/react": "^1.5.1", "classnames": "^2.2.6", "clipboard": "^2.0.4", - "infima": "0.2.0-alpha.4", + "infima": "0.2.0-alpha.5", "parse-numeric-range": "^0.0.2", "prism-react-renderer": "^1.0.2", + "prismjs": "^1.17.1", "react-router-dom": "^5.1.2", "react-toggle": "^4.1.1", - "remark-admonitions": "^1.1.0" + "remark-admonitions": "^1.2.0" } }, "@docusaurus/theme-search-algolia": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.0.0-alpha.43.tgz", - "integrity": "sha512-0OMWSOyBq1mW7EoBSNsF/aNBMsV09J7hho5Toy4Qom99edpCwk3DxkQV/3YVs30ADd3A+lKepdvSEsJJtvfpVg==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.0.0-alpha.48.tgz", + "integrity": "sha512-dDDc8FdX6BveRwtVowUGmn7ktwkO3INbrkj3umrNBecLNxO0uvEfRF1cfwsYIV2jScbhb9bCwoz0n/ndI2VDFQ==", "requires": { "classnames": "^2.2.6", "docsearch.js": "^2.6.3" } }, "@docusaurus/types": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.0.0-alpha.43.tgz", - "integrity": "sha512-qyrhFMwFOp6Y46a0WW5Ijop3tzrvabh2uuTgE74Lg9JA/uqpnq+RpTmw9zv6kHPrZUl0q9FlwnhgtlxPFqjTMQ==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.0.0-alpha.48.tgz", + "integrity": "sha512-tXpUlTg+Z6pO3RrMIXMGVURzJ7j4AkNaHGhR04Z7H8r7NMIL2Ysx4edhNB+7HDNU85AIwbSGbqDg6WqexdCjIA==", "requires": { "@types/webpack": "^4.41.0", "commander": "^4.0.1", @@ -1209,9 +1300,9 @@ } }, "@docusaurus/utils": { - "version": "2.0.0-alpha.43", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.0.0-alpha.43.tgz", - "integrity": "sha512-6yyrlTUdYHOvSMR8N4gJztoaA3BwUznrDFcU1AnlGhSAJoWpzNPBGQaneXEA0RbiiCwYN5rOD1Fhtq2phei1BQ==", + "version": "2.0.0-alpha.48", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.0.0-alpha.48.tgz", + "integrity": "sha512-xrFhWPfFU9upAN1Sn3lIb9B9iNsnA6BLFy9Q6VmiSbPagmLlgvyW/Z6yBoSA0j4mDuAAuF4zl3m50d5MXYFKFA==", "requires": { "escape-string-regexp": "^2.0.0", "fs-extra": "^8.1.0", @@ -1273,22 +1364,22 @@ } }, "@mdx-js/mdx": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.5.7.tgz", - "integrity": "sha512-db1E3P0HCgSUX768Y/jIcr5h41VR5AsvaOmPTydltNM4R8Uh863IqDvnkpa7l829bY/tp6wrMBWM2NH0oLuxHw==", + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.5.8.tgz", + "integrity": "sha512-OzanPTN0p9GZOEVeEuEa8QsjxxGyfFOOnI/+V1oC1su9UIN4KUg1k4n/hWTZC+VZhdW1Lfj6+Ho8nIs6L+pbDA==", "requires": { "@babel/core": "7.8.4", "@babel/plugin-syntax-jsx": "7.8.3", "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@mdx-js/util": "^1.5.7", - "babel-plugin-apply-mdx-type-prop": "^1.5.7", - "babel-plugin-extract-import-names": "^1.5.7", + "@mdx-js/util": "^1.5.8", + "babel-plugin-apply-mdx-type-prop": "^1.5.8", + "babel-plugin-extract-import-names": "^1.5.8", "camelcase-css": "2.0.1", "detab": "2.0.3", - "hast-util-raw": "5.0.1", + "hast-util-raw": "5.0.2", "lodash.uniq": "4.5.0", "mdast-util-to-hast": "7.0.0", - "remark-mdx": "^1.5.7", + "remark-mdx": "^1.5.8", "remark-parse": "7.0.2", "remark-squeeze-paragraphs": "3.0.4", "style-to-object": "0.3.0", @@ -1327,14 +1418,14 @@ } }, "@mdx-js/react": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.5.7.tgz", - "integrity": "sha512-OxX/GKyVlqY7WqyRcsIA/qr7i1Xq3kAVNUhSSnL1mfKKNKO+hwMWcZX4WS2OItLtoavA2/8TVDHpV/MWKWyfvw==" + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.5.8.tgz", + "integrity": "sha512-L3rehITVxqDHOPJFGBSHKt3Mv/p3MENYlGIwLNYU89/iVqTLMD/vz8hL9RQtKqRoMbKuWpzzLlKIObqJzthNYg==" }, "@mdx-js/util": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.5.7.tgz", - "integrity": "sha512-SV+V8A+Y33pmVT/LWk/2y51ixIyA/QH1XL+nrWAhoqre1rFtxOEZ4jr0W+bKZpeahOvkn/BQTheK+dRty9o/ig==" + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.5.8.tgz", + "integrity": "sha512-a7Gjjw8bfBSertA/pTWBA/9WKEhgaSxvQE2NTSUzaknrzGFOhs4alZSHh3RHmSFdSWv5pUuzAgsWseMLhWEVkQ==" }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", @@ -1393,15 +1484,20 @@ "@types/node": "*" } }, + "@types/html-minifier-terser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.0.0.tgz", + "integrity": "sha512-q95SP4FdkmF0CwO0F2q0H6ZgudsApaY/yCtAQNRn1gduef5fGpyEphzy0YCq/N0UFvDSnLg5V8jFK/YGXlDiCw==" + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "13.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz", - "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==" + "version": "13.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", + "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" }, "@types/q": { "version": "1.5.2", @@ -1439,9 +1535,9 @@ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" }, "@types/webpack": { - "version": "4.41.7", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.7.tgz", - "integrity": "sha512-OQG9viYwO0V1NaNV7d0n79V+n6mjOV30CwgFPIfTzwmk8DHbt+C4f2aBGdCYbo3yFyYD6sjXfqqOjwkl1j+ulA==", + "version": "4.41.9", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.9.tgz", + "integrity": "sha512-R68AotLGtaVL6HGfZRvEyYKsWcMv0CBFfSr4gxoYzhMn3LnjLV/ksP4dNi9de8dVG+Dn/GuDr1NwB/sDApB3pA==", "requires": { "@types/anymatch": "*", "@types/node": "*", @@ -1459,9 +1555,9 @@ } }, "@types/webpack-sources": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.6.tgz", - "integrity": "sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz", + "integrity": "sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw==", "requires": { "@types/node": "*", "@types/source-list-map": "*", @@ -1476,160 +1572,159 @@ } }, "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" }, "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" }, "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" }, "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", "requires": { - "@webassemblyjs/wast-printer": "1.8.5" + "@webassemblyjs/wast-printer": "1.9.0" } }, "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" }, "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" + "@webassemblyjs/ast": "1.9.0" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" }, "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" } }, "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" }, "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" } }, "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" } }, "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" } }, "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" } }, "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", "@xtuc/long": "4.2.2" } }, @@ -1658,14 +1753,14 @@ } }, "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==" + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" }, "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", + "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==" }, "address": { "version": "1.1.2", @@ -1946,17 +2041,17 @@ } }, "autoprefixer": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", - "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.5.tgz", + "integrity": "sha512-URo6Zvt7VYifomeAfJlMFnYDhow1rk2bufwkbamPEAtQFcL11moLk4PnR7n9vlu7M+BkXAZkHFA0mIcY7tjQFg==", "requires": { - "browserslist": "^4.8.3", - "caniuse-lite": "^1.0.30001020", + "browserslist": "^4.11.0", + "caniuse-lite": "^1.0.30001036", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.26", - "postcss-value-parser": "^4.0.2" + "postcss": "^7.0.27", + "postcss-value-parser": "^4.0.3" }, "dependencies": { "chalk": { @@ -2021,23 +2116,24 @@ } }, "babel-loader": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", - "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", "requires": { - "find-cache-dir": "^2.0.0", - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1", - "pify": "^4.0.1" + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" } }, "babel-plugin-apply-mdx-type-prop": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.5.7.tgz", - "integrity": "sha512-SUDwTmMmxzaAZ1YfAPnL2UI3q/JEs+fekx/QTZYEgK+cVGMwS/PrCeK9UDlTHOYJr9b4mieR+iLhm43jrav2WA==", + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.5.8.tgz", + "integrity": "sha512-xYp5F9mAnZdDRFSd1vF3XQ0GQUbIulCpnuht2jCmK30GAHL8szVL7TgzwhEGamQ6yJmP/gEyYNM9OR5D2n26eA==", "requires": { "@babel/helper-plugin-utils": "7.8.3", - "@mdx-js/util": "^1.5.7" + "@mdx-js/util": "^1.5.8" } }, "babel-plugin-dynamic-import-node": { @@ -2049,9 +2145,9 @@ } }, "babel-plugin-extract-import-names": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.5.7.tgz", - "integrity": "sha512-kZX4g9ehTyxjdbq2rb8wW307+jNu5z3KllYs8cnbapSwclT9wBErJoqvKKZAkuiaufp0r+7WaIvjhKtJ7QlG3A==", + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.5.8.tgz", + "integrity": "sha512-LcLfP8ZRBZMdMAXHLugyvvd5PY0gMmLMWFogWAUsG32X6TYW2Eavx+il2bw73KDbW+UdCC1bAJ3NuU25T1MI3g==", "requires": { "@babel/helper-plugin-utils": "7.8.3" } @@ -2155,15 +2251,6 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -2319,13 +2406,14 @@ } }, "browserslist": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", - "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.0.tgz", + "integrity": "sha512-WqEC7Yr5wUH5sg6ruR++v2SGOQYpyUdYYd4tZoAq1F7y+QXoLoYGXVbxhtaIqWmAJjtNTRjVD3HuJc1OXTel2A==", "requires": { - "caniuse-lite": "^1.0.30001030", - "electron-to-chromium": "^1.3.363", - "node-releases": "^1.1.50" + "caniuse-lite": "^1.0.30001035", + "electron-to-chromium": "^1.3.380", + "node-releases": "^1.1.52", + "pkg-up": "^3.1.0" } }, "buffer": { @@ -2369,9 +2457,9 @@ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", "requires": { "bluebird": "^3.5.5", "chownr": "^1.1.1", @@ -2420,9 +2508,9 @@ }, "dependencies": { "find-cache-dir": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.0.tgz", - "integrity": "sha512-PtXtQb7IrD8O+h6Cq1dbpJH5NzD8+9keN1zZ0YlpDzl1PwXEJEBj6u1Xa92t1Hwluoozd9TNKul5Hi2iqpsWwg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", "requires": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -2541,9 +2629,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001031", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001031.tgz", - "integrity": "sha512-DpAP5a1NGRLgYfaNCaXIRyGARi+3tJA2quZXNNA1Du26VyVkqvy2tznNu5ANyN1Y5aX44QDotZSVSUSi2uMGjg==" + "version": "1.0.30001038", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001038.tgz", + "integrity": "sha512-zii9quPo96XfOiRD4TrfYGs+QsGZpb2cGiMAzPjtf/hpFgB6zCPZgJb7I1+EATeMw/o+lG8FyRAnI+CWStHcaQ==" }, "caseless": { "version": "0.12.0", @@ -2751,9 +2839,9 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, "clipboard": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.5.tgz", - "integrity": "sha512-3IlokN96rXErcpaVpAXgsE2o+/85DEHr/Gs0pLQOonwtrjZpZLEfy9S4ZyZj+JhVMvZT8szWfKPYQSZCAKDfQg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", + "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", "requires": { "good-listener": "^1.2.2", "select": "^1.1.2", @@ -3422,11 +3510,32 @@ "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" }, "csso": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.2.tgz", - "integrity": "sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", + "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", "requires": { - "css-tree": "1.0.0-alpha.37" + "css-tree": "1.0.0-alpha.39" + }, + "dependencies": { + "css-tree": { + "version": "1.0.0-alpha.39", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", + "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "requires": { + "mdn-data": "2.0.6", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", + "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } } }, "cyclist": { @@ -3798,14 +3907,14 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "ejs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.0.1.tgz", - "integrity": "sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.0.2.tgz", + "integrity": "sha512-IncmUpn1yN84hy2shb0POJ80FWrfGNY0cxO9f4v+/sG7qcBvAtVWUA1IdzY/8EYUmOVhoKJVdJjNd3AZcnxOjA==" }, "electron-to-chromium": { - "version": "1.3.367", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.367.tgz", - "integrity": "sha512-GCHQreWs4zhKA48FNXCjvpV4kTnKoLu2PSAfKX394g34NPvTs2pPh1+jzWitNwhmOYI8zIqt36ulRVRZUgqlfA==" + "version": "1.3.390", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.390.tgz", + "integrity": "sha512-4RvbM5x+002gKI8sltkqWEk5pptn0UnzekUx8RTThAMPDSb8jjpm6SwGiSnEve7f85biyZl8DMXaipaCxDjXag==" }, "elliptic": { "version": "6.5.2", @@ -3831,6 +3940,11 @@ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, + "emoticon": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-3.2.0.tgz", + "integrity": "sha512-SNujglcLTTg+lDAcApPNgEdudaqQFiAbJCqzjNxJkvN9vAwCGi0uu8IUVvx+f16h+V44KCY6Y2yboroc9pilHg==" + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -3918,9 +4032,9 @@ } }, "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", @@ -4262,9 +4376,9 @@ } }, "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" }, "figures": { "version": "2.0.0", @@ -4274,12 +4388,6 @@ "escape-string-regexp": "^1.0.5" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, "filesize": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", @@ -4379,9 +4487,9 @@ } }, "follow-redirects": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", - "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz", + "integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==", "requires": { "debug": "^3.0.0" }, @@ -4547,13 +4655,11 @@ } }, "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", "optional": true, "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", "node-pre-gyp": "*" }, "dependencies": { @@ -4596,7 +4702,7 @@ } }, "chownr": { - "version": "1.1.3", + "version": "1.1.4", "bundled": true, "optional": true }, @@ -4746,7 +4852,7 @@ } }, "minimist": { - "version": "0.0.8", + "version": "1.2.5", "bundled": true, "optional": true }, @@ -4768,11 +4874,11 @@ } }, "mkdirp": { - "version": "0.5.1", + "version": "0.5.3", "bundled": true, "optional": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { @@ -4781,7 +4887,7 @@ "optional": true }, "needle": { - "version": "2.4.0", + "version": "2.3.3", "bundled": true, "optional": true, "requires": { @@ -4808,7 +4914,7 @@ } }, "nopt": { - "version": "4.0.1", + "version": "4.0.3", "bundled": true, "optional": true, "requires": { @@ -4830,12 +4936,13 @@ "optional": true }, "npm-packlist": { - "version": "1.4.7", + "version": "1.4.8", "bundled": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" } }, "npmlog": { @@ -4905,17 +5012,10 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } } }, "readable-stream": { - "version": "2.3.6", + "version": "2.3.7", "bundled": true, "optional": true, "requires": { @@ -5344,9 +5444,9 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "requires": { "is-glob": "^4.0.1" } @@ -5472,9 +5572,9 @@ } }, "handle-thing": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", - "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, "har-schema": { "version": "2.0.0", @@ -5622,17 +5722,17 @@ "integrity": "sha512-gW3sxfynIvZApL4L07wryYF4+C9VvH3AUi7LAnVXV4MneGEgwOByXvFo18BgmTWnm7oHAe874jKbIB1YhHSIzA==" }, "hast-util-raw": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-5.0.1.tgz", - "integrity": "sha512-iHo7G6BjRc/GU1Yun5CIEXjil0wVnIbz11C6k0JdDichSDMtYi2+NNtk6YN7EOP0JfPstX30d3pRLfaJv5CkdA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-5.0.2.tgz", + "integrity": "sha512-3ReYQcIHmzSgMq8UrDZHFL0oGlbuVGdLKs8s/Fe8BfHFAyZDrdv1fy/AGn+Fim8ZuvAHcJ61NQhVMtyfHviT/g==", "requires": { "hast-util-from-parse5": "^5.0.0", "hast-util-to-parse5": "^5.0.0", - "html-void-elements": "^1.0.1", + "html-void-elements": "^1.0.0", "parse5": "^5.0.0", "unist-util-position": "^3.0.0", "web-namespaces": "^1.0.0", - "xtend": "^4.0.1", + "xtend": "^4.0.0", "zwitch": "^1.0.0" } }, @@ -5777,9 +5877,9 @@ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" }, "html-minifier-terser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.0.4.tgz", - "integrity": "sha512-fHwmKQ+GzhlqdxEtwrqLT7MSuheiA+rif5/dZgbz3GjoMXJzcRzy1L9NXoiiyxrnap+q5guSiv8Tz5lrh9g42g==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.0.5.tgz", + "integrity": "sha512-cBSFFghQh/uHcfSiL42KxxIRMF7A144+3E44xdlctIjxEmkEfCvouxNyFH2wysXk1fCGBPwtcr3hDWlGTfkDew==", "requires": { "camel-case": "^4.1.1", "clean-css": "^4.2.3", @@ -5801,10 +5901,13 @@ "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==" }, "html-webpack-plugin": { - "version": "4.0.0-beta.11", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz", - "integrity": "sha512-4Xzepf0qWxf8CGg7/WQM5qBB2Lc/NFI7MhU59eUDTkuQp3skZczH4UA1d6oQyDEIoMDgERVhRyTdtUPZ5s5HBg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.3.tgz", + "integrity": "sha512-XCm5MGK6Yv/ey30fbhqjKIGm1r6G1HxmNorJ/xUdL/Zj3mOLtb9ZHEEIw0e4h3VzgyUrp8szCJh3VN9z1LNx7A==", "requires": { + "@types/html-minifier-terser": "^5.0.0", + "@types/tapable": "^1.0.5", + "@types/webpack": "^4.41.8", "html-minifier-terser": "^5.0.1", "loader-utils": "^1.2.3", "lodash": "^4.17.15", @@ -6115,9 +6218,9 @@ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" }, "infima": { - "version": "0.2.0-alpha.4", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.4.tgz", - "integrity": "sha512-b2uwUMI40IAyGRG0IHZpQOPPEKB41y5U+ZKHZxhtLjLJ90FCCcUiMYUbNAf7gRXvNSmotymTeydLj10Et+X3sQ==" + "version": "0.2.0-alpha.5", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.5.tgz", + "integrity": "sha512-kG8ivgCIlV4aFU7kaq1IlSybLETN2dkQaFNwcJIr2uOY6ojz7qgc9RT+TRVx6a48VYNJTz821wHVtj22XukVYw==" }, "inflight": { "version": "1.0.6", @@ -6532,9 +6635,9 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "jest-worker": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", - "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.1.tgz", + "integrity": "sha512-IHnpekk8H/hCUbBlfeaPZzU6v75bqwJp3n4dUrQuQOAgOneI4tx3jV2o8pvlXnDfcRsfkFIUD//HWXpCmR+evQ==", "requires": { "merge-stream": "^2.0.0", "supports-color": "^7.0.0" @@ -6605,11 +6708,11 @@ "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" }, "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", + "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", "requires": { - "minimist": "^1.2.0" + "minimist": "^1.2.5" } }, "jsonfile": { @@ -6872,11 +6975,6 @@ } } }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==" - }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -6956,9 +7054,9 @@ } }, "mdast-util-to-string": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.8.tgz", - "integrity": "sha512-GBracya0dOzckEEizUBzfrkWRLCHMsppuU97LPUriY9kWnYyGFWTx4VDW+sUcj2LneBz/Tp1aYp3aUCibzjtWg==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" }, "mdn-data": { "version": "2.0.4", @@ -7151,9 +7249,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { "version": "3.1.1", @@ -7231,18 +7329,11 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } + "minimist": "^1.2.5" } }, "move-concurrently": { @@ -7282,12 +7373,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "optional": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -7419,12 +7504,9 @@ } }, "node-releases": { - "version": "1.1.50", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.50.tgz", - "integrity": "sha512-lgAmPv9eYZ0bGwUYAKlr8MG6K4CvWliWqnkcT2P8mMAgVrH3lqfBPorFlxiG1pHQnqmavJZ9vbMXUTNyMLbrgQ==", - "requires": { - "semver": "^6.3.0" - } + "version": "1.1.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", + "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==" }, "nopt": { "version": "1.0.10", @@ -7944,9 +8026,9 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, "pify": { "version": "4.0.1", @@ -7975,51 +8057,11 @@ } }, "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "requires": { - "find-up": "^2.1.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - } + "find-up": "^3.0.0" } }, "portfinder": { @@ -8560,9 +8602,9 @@ } }, "postcss-modules-scope": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz", - "integrity": "sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", "requires": { "postcss": "^7.0.6", "postcss-selector-parser": "^6.0.0" @@ -8980,6 +9022,14 @@ "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.0.2.tgz", "integrity": "sha512-0++pJyRfu4v2OxI/Us/5RLui9ESDkTiLkVCtKuPZYdpB8UQWJpnJQhPrWab053XtsKW3oM0sD69uJ6N9exm1Ag==" }, + "prismjs": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.19.0.tgz", + "integrity": "sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw==", + "requires": { + "clipboard": "^2.0.0" + } + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -9033,9 +9083,9 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, "psl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, "public-encrypt": { "version": "4.0.3", @@ -9395,6 +9445,15 @@ "json5": "^1.0.1" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -9415,11 +9474,50 @@ "to-regex": "^3.0.2" } }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + } + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -9451,9 +9549,9 @@ } }, "react-error-overlay": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.6.tgz", - "integrity": "sha512-Yzpno3enVzSrSCnnljmr4b/2KUQSMZaPuqmS26t9k4nW7uwJk6STWmH9heNjPuvqUTO3jOSPkHoKgO4+Dw7uIw==" + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz", + "integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==" }, "react-fast-compare": { "version": "2.0.4", @@ -9604,24 +9702,25 @@ "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" }, "regenerate-unicode-properties": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", - "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", "requires": { "regenerate": "^1.4.0" } }, "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" }, "regenerator-transform": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", - "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", + "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", "requires": { - "private": "^0.1.6" + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" } }, "regex-not": { @@ -9662,16 +9761,16 @@ } }, "regexpu-core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", - "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", "requires": { "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" + "unicode-match-property-value-ecmascript": "^1.2.0" } }, "regjsgen": { @@ -9680,9 +9779,9 @@ "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==" }, "regjsparser": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.3.tgz", - "integrity": "sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", "requires": { "jsesc": "~0.5.0" }, @@ -9710,9 +9809,9 @@ "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" }, "remark-admonitions": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remark-admonitions/-/remark-admonitions-1.2.0.tgz", - "integrity": "sha512-h7P99HNMuSeA3HBw+RIF4PoTEI2knjPqBIfmYSgavXvA5PHgP3oHo0XKfDmmPpUZY6vBWKzcLXRZcYHNnNcJaw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/remark-admonitions/-/remark-admonitions-1.2.1.tgz", + "integrity": "sha512-Ji6p68VDvD+H1oS95Fdx9Ar5WA2wcDA4kwrrhVU7fGctC6+d3uiMICu7w7/2Xld+lnU7/gi+432+rRbup5S8ow==", "requires": { "rehype-parse": "^6.0.2", "unified": "^8.4.2", @@ -9720,34 +9819,25 @@ } }, "remark-emoji": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-2.0.2.tgz", - "integrity": "sha512-E8ZOa7Sx1YS9ivWJ8U9xpA8ldzZ4VPAfyUaKqhr1/Pr5Q8ZdQHrpDg6S+rPzMw8t89KNViB/oG9ZdJSFDrUXpA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-2.1.0.tgz", + "integrity": "sha512-lDddGsxXURV01WS9WAiS9rO/cedO1pvr9tahtLhr6qCGFhHG4yZSJW3Ha4Nw9Uk1hLNmUBtPC0+m45Ms+xEitg==", "requires": { - "node-emoji": "^1.8.1", - "unist-util-visit": "^1.4.0" - }, - "dependencies": { - "unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "requires": { - "unist-util-visit-parents": "^2.0.0" - } - } + "emoticon": "^3.2.0", + "node-emoji": "^1.10.0", + "unist-util-visit": "^2.0.2" } }, "remark-mdx": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.5.7.tgz", - "integrity": "sha512-f13ot+zaByDXYuOC4FWTpQCGP/rNbaxdhs2mLlW7ZBipm3JYR2ASFSL7RC3R7ytzm3n8v6hhcFxDKU+CwC2f4g==", + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.5.8.tgz", + "integrity": "sha512-wtqqsDuO/mU/ucEo/CDp0L8SPdS2oOE6PRsMm+lQ9TLmqgep4MBmyH8bLpoc8Wf7yjNmae/5yBzUN1YUvR/SsQ==", "requires": { "@babel/core": "7.8.4", "@babel/helper-plugin-utils": "7.8.3", "@babel/plugin-proposal-object-rest-spread": "7.8.3", "@babel/plugin-syntax-jsx": "7.8.3", - "@mdx-js/util": "^1.5.7", + "@mdx-js/util": "^1.5.8", "is-alphabetical": "1.0.4", "remark-parse": "7.0.2", "unified": "8.4.2" @@ -9775,6 +9865,15 @@ "source-map": "^0.5.0" } }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -10074,11 +10173,11 @@ } }, "schema-utils": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", - "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", "requires": { - "ajv": "^6.10.2", + "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" } }, @@ -10286,9 +10385,9 @@ } }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "simple-swizzle": { "version": "0.2.2", @@ -10935,9 +11034,9 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, "terser": { - "version": "4.6.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.6.tgz", - "integrity": "sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g==", + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.7.tgz", + "integrity": "sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==", "requires": { "commander": "^2.20.0", "source-map": "~0.6.1", @@ -10998,9 +11097,9 @@ } }, "find-cache-dir": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.0.tgz", - "integrity": "sha512-PtXtQb7IrD8O+h6Cq1dbpJH5NzD8+9keN1zZ0YlpDzl1PwXEJEBj6u1Xa92t1Hwluoozd9TNKul5Hi2iqpsWwg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", "requires": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -11351,14 +11450,14 @@ } }, "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==" }, "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==" }, "unified": { "version": "8.4.2", @@ -11673,9 +11772,9 @@ } }, "vfile": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.0.3.tgz", - "integrity": "sha512-lREgT5sF05TQk68LO6APy0In+TkFGnFEgKChK2+PHIaTrFQ9oHCKXznZ7VILwgYVBcl0gv4lGATFZBLhi2kVQg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.1.0.tgz", + "integrity": "sha512-BaTPalregj++64xbGK6uIlsurN3BCRNM/P2Pg8HezlGzKd1O9PrwIac6bd9Pdx2uTb0QHoioZ+rXKolbVXEgJg==", "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -11697,9 +11796,9 @@ "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==" }, "vfile-message": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.3.tgz", - "integrity": "sha512-qQg/2z8qnnBHL0psXyF72kCjb9YioIynvyltuNKFaUhRtqTIcIMP3xnBaPzirVZNuBrUe1qwFciSx2yApa4byw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "requires": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" @@ -11721,11 +11820,11 @@ } }, "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", + "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", "requires": { - "chokidar": "^2.0.2", + "chokidar": "^2.1.8", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0" }, @@ -11841,13 +11940,11 @@ } }, "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", "optional": true, "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", "node-pre-gyp": "*" }, "dependencies": { @@ -11890,7 +11987,7 @@ } }, "chownr": { - "version": "1.1.3", + "version": "1.1.4", "bundled": true, "optional": true }, @@ -12040,7 +12137,7 @@ } }, "minimist": { - "version": "0.0.8", + "version": "1.2.5", "bundled": true, "optional": true }, @@ -12062,11 +12159,11 @@ } }, "mkdirp": { - "version": "0.5.1", + "version": "0.5.3", "bundled": true, "optional": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { @@ -12075,7 +12172,7 @@ "optional": true }, "needle": { - "version": "2.4.0", + "version": "2.3.3", "bundled": true, "optional": true, "requires": { @@ -12102,7 +12199,7 @@ } }, "nopt": { - "version": "4.0.1", + "version": "4.0.3", "bundled": true, "optional": true, "requires": { @@ -12124,12 +12221,13 @@ "optional": true }, "npm-packlist": { - "version": "1.4.7", + "version": "1.4.8", "bundled": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" } }, "npmlog": { @@ -12199,17 +12297,10 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } } }, "readable-stream": { - "version": "2.3.6", + "version": "2.3.7", "bundled": true, "optional": true, "requires": { @@ -12457,14 +12548,14 @@ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" }, "webpack": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", - "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", + "version": "4.42.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.1.tgz", + "integrity": "sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg==", + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", "acorn": "^6.2.1", "ajv": "^6.10.2", "ajv-keywords": "^3.4.1", @@ -12476,7 +12567,7 @@ "loader-utils": "^1.2.3", "memory-fs": "^0.4.1", "micromatch": "^3.1.10", - "mkdirp": "^0.5.1", + "mkdirp": "^0.5.3", "neo-async": "^2.6.1", "node-libs-browser": "^2.2.1", "schema-utils": "^1.0.0", @@ -12634,12 +12725,12 @@ } }, "webpack-bundle-analyzer": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.0.tgz", - "integrity": "sha512-orUfvVYEfBMDXgEKAKVvab5iQ2wXneIEorGNsyuOyVYpjYrI7CUOhhXNDd3huMwQ3vNNWWlGP+hzflMFYNzi2g==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.1.tgz", + "integrity": "sha512-Nfd8HDwfSx1xBwC+P8QMGvHAOITxNBSvu/J/mCJvOwv+G4VWkU7zir9SSenTtyCi0LnVtmsc7G5SZo1uV+bxRw==", "requires": { - "acorn": "^6.0.7", - "acorn-walk": "^6.1.1", + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1", "bfj": "^6.1.1", "chalk": "^2.4.1", "commander": "^2.18.0", @@ -12653,6 +12744,11 @@ "ws": "^6.0.0" }, "dependencies": { + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -12859,13 +12955,11 @@ } }, "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", "optional": true, "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", "node-pre-gyp": "*" }, "dependencies": { @@ -12908,7 +13002,7 @@ } }, "chownr": { - "version": "1.1.3", + "version": "1.1.4", "bundled": true, "optional": true }, @@ -13058,7 +13152,7 @@ } }, "minimist": { - "version": "0.0.8", + "version": "1.2.5", "bundled": true, "optional": true }, @@ -13080,11 +13174,11 @@ } }, "mkdirp": { - "version": "0.5.1", + "version": "0.5.3", "bundled": true, "optional": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { @@ -13093,7 +13187,7 @@ "optional": true }, "needle": { - "version": "2.4.0", + "version": "2.3.3", "bundled": true, "optional": true, "requires": { @@ -13120,7 +13214,7 @@ } }, "nopt": { - "version": "4.0.1", + "version": "4.0.3", "bundled": true, "optional": true, "requires": { @@ -13142,12 +13236,13 @@ "optional": true }, "npm-packlist": { - "version": "1.4.7", + "version": "1.4.8", "bundled": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" } }, "npmlog": { @@ -13217,17 +13312,10 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } } }, "readable-stream": { - "version": "2.3.6", + "version": "2.3.7", "bundled": true, "optional": true, "requires": { diff --git a/website/package.json b/website/package.json index a490bed92f..d6a6c97e01 100755 --- a/website/package.json +++ b/website/package.json @@ -6,8 +6,8 @@ "deploy": "docusaurus deploy" }, "dependencies": { - "@docusaurus/core": "2.0.0-alpha.43", - "@docusaurus/preset-classic": "2.0.0-alpha.43", + "@docusaurus/core": "2.0.0-alpha.48", + "@docusaurus/preset-classic": "2.0.0-alpha.48", "classnames": "2.2.6", "react": "16.13.0", "react-dom": "16.13.0" From e9c893aea15b82f5222420c7d83596bbd43a4021 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 15:29:35 -0400 Subject: [PATCH 05/60] Fix text color in admonitions --- website/src/css/custom.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/src/css/custom.css b/website/src/css/custom.css index 6baef0d53f..3f579c5edc 100755 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -23,6 +23,8 @@ --ifm-code-padding-horizontal: 0.2rem; --ifm-pre-background: rgb(39, 40, 34); + --ifm-alert-color: black; + --ra-admonition-color: #ecf4f9; --ra-admonition-color-dark: #2a98b9; @@ -185,7 +187,6 @@ a:visited { color: #2b5a99; } - .admonition { color: var(--ifm-font-base-color); border-radius: var(--ifm-global-radius); From 70c6cdb787678e7fb4323d53600cea1aea05b281 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 16:14:41 -0400 Subject: [PATCH 06/60] Add blockquote styling for other pages --- website/src/css/custom.css | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/website/src/css/custom.css b/website/src/css/custom.css index 3f579c5edc..70651393b9 100755 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -145,24 +145,28 @@ a:visited { overflow: hidden; } -.style-guide details { +.style-guide details, +details.detailed-explanation { background-color: var(--ifm-blockquote-color); - margin: 1rem 0; - padding: 1rem; + margin: 0.25rem 0; + padding: 0.25rem 0.5rem; border-radius: var(--ifm-global-radius); } -.style-guide details summary { +.style-guide details summary, +details.detailed-explanation summary { cursor: pointer; } -.style-guide details summary h4 { +.style-guide details summary h4, +details.detailed-explanation summary h4 { display: inline-block; margin-top: 0; margin-bottom: 0; } -.style-guide details p { +.style-guide details p, +details.detailed-explanation p { margin-bottom: 0; } From 4cfe76382083dc18a053464c674af0bbad3018cb Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 16:14:50 -0400 Subject: [PATCH 07/60] Add DetailedExplanation component --- docs/components/DetailedExplanation.jsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docs/components/DetailedExplanation.jsx diff --git a/docs/components/DetailedExplanation.jsx b/docs/components/DetailedExplanation.jsx new file mode 100644 index 0000000000..b3701555ee --- /dev/null +++ b/docs/components/DetailedExplanation.jsx @@ -0,0 +1,15 @@ +import React from 'react' + +export const DetailedExplanation = ({ + children, + title = 'Detailed Explanation' +}) => { + return ( +
+ +

{title}

+
+ {children} +
+ ) +} From 75776e6b926abdec2862fc2ee7917e9f115e66c0 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 16:15:07 -0400 Subject: [PATCH 08/60] Initial Quick Start intro content --- docs/tutorials/quick-start.mdx | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/docs/tutorials/quick-start.mdx b/docs/tutorials/quick-start.mdx index 4a0a50e629..742ddafaf2 100644 --- a/docs/tutorials/quick-start.mdx +++ b/docs/tutorials/quick-start.mdx @@ -6,4 +6,60 @@ hide_title: true description: The official Quick Start tutorial for Redux - the fastest way to learn and start using Redux today! --- +import { DetailedExplanation } from '../components/DetailedExplanation' + # Quick Start + +:::tip What You'll Learn + +- What Redux is and why you might want to use it +- Key Redux terms and concepts +- How to write a typical React + Redux app + +::: + +## Introduction + +Welcome to the Redux Quick Start tutorial! This tutorial will introduce you to Redux, so that you can begin using it as quickly as possible. By the time you finish, you should be able to start building your own Redux applications using the tools and patterns you've learned here. + +### How to Use This Tutorial + +This page will focus on showing you _how_ to use Redux the right way, and explain just enough of the concepts so that you can understand how to build Redux apps correctly. + +We've tried to keep these explanations beginner-friendly, but we do need to make some assumptions about what you know already: + +:::important Prerequisites + +- Familiarity with [HTML & CSS](https://internetingishard.com/). +- Familiarity with ES6 syntax and features +- Knowledge of React terminology: JSX, State, Function Components, Props, Lifecycle, and Hooks +- Knowledge of asynchronous JavaScript and making AJAX calls + +::: + +If you're not already comfortable with those topics, we encourage you to take some time to become comfortable with them first, and then come back to learn about Redux. We'll be here when you're ready! + +You should make sure that you have the Redux DevTools extension installed in your browser: + +- [Redux DevTools Extension for Chrome](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en) +- [Redux DevTools Extension for Firefox](https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/) + +If you'd like to know more details about specific concepts, we'll have links to other parts of the documentation that will tell you more about how Redux works and the patterns you use with Redux: + +:::tip Want to know more? + +The [Configuring Your Store](../recipes/ConfguringYourStore.md) page has more details about setting up a Redux store + +::: + +We'll also have expandable "Detailed Explanation" sections, like this: + + + +Here you'll find more details about specific topics. We keep these collapsed by default so that you can focus on the main tutorial instructions without being distracted. + + + +## What is Redux? + +Let's start by From efb22add934d58010628133a1123c38892eb4f4f Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 18:17:14 -0400 Subject: [PATCH 09/60] Quick Start: add "What is Redux" and "Terms" sections --- docs/tutorials/quick-start.mdx | 222 +++++++++++++++++- .../img/tutorials/one-way-data-flow.png | Bin 0 -> 25103 bytes 2 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 website/static/img/tutorials/one-way-data-flow.png diff --git a/docs/tutorials/quick-start.mdx b/docs/tutorials/quick-start.mdx index 742ddafaf2..2fdebd0ab8 100644 --- a/docs/tutorials/quick-start.mdx +++ b/docs/tutorials/quick-start.mdx @@ -22,7 +22,7 @@ import { DetailedExplanation } from '../components/DetailedExplanation' Welcome to the Redux Quick Start tutorial! This tutorial will introduce you to Redux, so that you can begin using it as quickly as possible. By the time you finish, you should be able to start building your own Redux applications using the tools and patterns you've learned here. -### How to Use This Tutorial +### How to Read This Tutorial This page will focus on showing you _how_ to use Redux the right way, and explain just enough of the concepts so that you can understand how to build Redux apps correctly. @@ -62,4 +62,222 @@ Here you'll find more details about specific topics. We keep these collapsed by ## What is Redux? -Let's start by +It helps to understand what this "Redux" thing is in the first place. What does it do? What problems does it help me solve? Why would I want to use it? + +**Redux is a pattern and library for managing and updating application state, using events called "actions".** It serves as a centralized store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion. + +### Why Should I Use Redux? + +Redux helps you manage "global" state - state that is needed across many parts of your application. + +The patterns and tools provided by Redux make it easier to understand when, where, why, and how the state in your application is being updated, and how your application logic will behave when those changes occur. Redux guides you towards writing code that is predictable and testable, which helps give you confidence that your application will work as expected. + +### When Should I Use Redux? + +Redux helps you deal with shared state management, but like any tool, it has tradeoffs. There's more concepts to learn, and more code to write. It also adds some indirection to your code, and asks you to follow certain restrictions. It's a trade-off between short term and long term productivity. + +Redux is more useful when: + +- You have large amounts of application state that are needed in many places in the app +- The app state is updated frequently over time +- The logic to update that state may be complex +- The app has a medium or large-sized codebase, and might be worked on by many people + +Not all apps need Redux. Take some time to think about the kind of app you're building, and decide what tools would be best to help solve the problems you're working on. + +:::tip Want to know more? + +If you're not sure whether Redux is a good choice for your app, these resources give some more guidance: + +- **[Redux FAQ: When should I use Redux?](../faq/General.md#when-should-i-use-redux)** +- **[You Might Not Need Redux](https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367)** +- **[The Tao of Redux, Part 1 - Implementation and Intent](http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao-of-redux-part-1/)** + +::: + +### Redux Libraries and Tools + +Redux is a small standalone JS library. However, it is commonly used with several other packages: + +#### React-Redux + +Redux can integrate with any UI framework, and is most frequently used with React. [**React-Redux**](https://react-redux.js.org/) is our official package that lets your React components interact with a Redux store by reading pieces of state and dispatching actions to update the store. + +#### Redux Toolkit + +[**Redux Toolkit**](https://redux-toolkit.js.org) is our recommended approach for writing Redux logic. It contains functions that build in our suggested best practices, simplify most Redux tasks, prevent common mistakes, and make it easier to write Redux applications. + +#### Redux DevTools Extension + +The [**Redux DevTools Extension**](https://github.com/zalmoxisus/redux-devtools-extension) shows a history of the changes to the state in your Redux store over time. This allows you to debug your applications effectively, including using powerful techniques like "time-travel debugging". + +## Redux Terms and Concepts + +Before we dive into some actual code, let's talk about some of the terms and concepts you'll need to know to use Redux. + +### Understanding State Management + +Let's start by looking at a React counter component: + +```js +function Counter() { + // State: a counter value + const [counter, setCounter] = useState(0) + + // Action: code that causes an update to the state when something happens + const increment = () => { + setCounter(prevCounter => prevCounter + 1) + } + + // View: the UI definition + return ( +
+ Value: {counter} +
+ ) +} +``` + +It is a self-contained app with the following parts: + +- The **state**, the source of truth that drives our app; +- The **view**, a declarative description of the UI based on the current state +- The **actions**, the events that occur in the app based on user input, and trigger updates in the state + +This is a small example of "one-way data flow": + +- State describes the condition of the app at a specific point in time +- The UI is rendered based on that state +- When something happens (such as a user clicking a button), the state is updated based on what occurred +- The UI re-renders based on the new state + +![One-way data flow](/img/tutorials/one-way-data-flow.png) + +However, the simplicity can break down when we have **multiple components that need to share and use the same state**, especially if those components are located in different parts of the application. Sometimes this can be solved by ["lifting state up"](https://reactjs.org/docs/lifting-state-up.html) to parent components, but this doesn't always help. + +So why don't we extract the shared state out of the components, and manage it in a global singleton? With this, our component tree becomes a big "view", and any component can access the state or trigger actions, no matter where they are in the tree! + +By defining and separating the concepts involved in state management and enforcing rules that maintain independence between views and states, we give our code more structure and maintainability. + +This is the basic idea behind Redux: a single centralized place to contain the global state in your application, and specific patterns to follow when updating that state to make the code predictable. + +### Terminology + +There's some important terms that you'll need to be familiar with before we continue: + +#### Actions + +An **action** is a plain JavaScript object that has a `type` field. **You can think of an action as an event that describes something that happened in the application**. + +The `type` field should be a string that gives this action a descriptive name, like `"todos/todoAdded"`. We usually write that type string like `"domain/eventName"`, where the first part is the feature or category that this action belongs to, and the second part is the specific thing that happened. + +An action object can have other fields with additional information about what happened. By convention, we put that information in a field called `payload`. + +A typical action object might look like this: + +```js +const addTodoAction = { + type: 'todos/todoAdded', + payload: 'Buy milk' +} +``` + +#### Action Creators + +An **action creator** is a function that creates and returns an action object. We typically use these so we don't have to write the action object by hand every time: + +```js +const addTodo = text => { + return { + type: 'todos/todoAdded', + payload: 'Buy milk' + } +} +``` + +#### Reducers + +A **reducer** is a function that receives the current `state` and an `action` object, decides how to update the state if necessary, and returns the new state. + +Reducers must _always_ follow some specific rules: + +- They should only calculate the new state value based on the `state` and `action` arguments +- They are not allowed to modify the existing `state`. Instead, they must make _immutable updates_, by copying the existing `state` and making changes to the copied values. +- They must not do any asynchronous logic or other "side effects" + +```js +const initialState = { value: 0 } + +function counterReducer(state = initialState, action) { + // Check to see if the reducer cares about this action + if (action.type === 'counter/increment') { + // If so, make a copy of `state` + return { + ...state, + // and update the copy with the new value + value: state.value + 1 + } + } + // otherwise return the existing state unchanged + return state +} +``` + +#### Store + +The current Redux application state lives in an object called the **store** . + +The store is created using a reducer, and has a method called `getState` that returns the current state value: + +```js +import { configureStore } from '@reduxjs/toolkit' + +const store = configureStore({ reducer: counterReducer }) + +console.log(store.getState()) +// {value: 0} +``` + +#### Dispatch + +The Redux store has a method called `dispatch`. The only way to update the state is to call `store.dispatch()` and pass in an action object. The store will run its reducer function and save the new state value: + +```js +store.dispatch({ type: 'counter/increment' }) + +console.log(store.getState()) +// {value: 1} +``` + +**You can think of dispatching actions as "triggering an event"** in the application. Something happened, and we want the store to know about it. Reducers act like event listeners, and when they hear an action they are interested in, they update the state in response. + +We typically call action creators to dispatch the right action: + +```js +const increment = () => { + return { + type: 'counter/increment' + } +} + +store.dispatch(increment()) + +console.log(store.getState()) +// {value: 2} +``` + +#### Selectors + +**Selectors** are functions that know how to extract specific pieces of information from a store state value. As an application grows bigger, this can help avoid repeating logic as different parts of the app need to read the same data: + +```js +const selectCounterValue = state => state.value + +const currentValue = selectCounterValue(store.getState()) +console.log(currentValue) +// 2 +``` + +## Examining a React and Redux App + +Now that you know the pieces that make up a Redux app, let's look at a real working example to see how these pieces fit together. diff --git a/website/static/img/tutorials/one-way-data-flow.png b/website/static/img/tutorials/one-way-data-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..8a18b59cfef504c0549154a17f369cb3e3671b38 GIT binary patch literal 25103 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 k4@3XU+W-6YpK^N! Date: Sun, 29 Mar 2020 21:48:15 -0400 Subject: [PATCH 10/60] Quick Start: add "play with app" content --- docs/tutorials/quick-start.mdx | 143 +++++++++++++++++- .../quickstart-devtools-done-clicking.png | Bin 0 -> 41795 bytes .../quickstart-devtools-first-action.png | Bin 0 -> 34517 bytes .../tutorials/quickstart-devtools-initial.png | Bin 0 -> 31711 bytes 4 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 website/static/img/tutorials/quickstart-devtools-done-clicking.png create mode 100644 website/static/img/tutorials/quickstart-devtools-first-action.png create mode 100644 website/static/img/tutorials/quickstart-devtools-initial.png diff --git a/docs/tutorials/quick-start.mdx b/docs/tutorials/quick-start.mdx index 2fdebd0ab8..92e8ce0fd7 100644 --- a/docs/tutorials/quick-start.mdx +++ b/docs/tutorials/quick-start.mdx @@ -14,7 +14,7 @@ import { DetailedExplanation } from '../components/DetailedExplanation' - What Redux is and why you might want to use it - Key Redux terms and concepts -- How to write a typical React + Redux app +- The structure of a typical React + Redux app ::: @@ -22,6 +22,10 @@ import { DetailedExplanation } from '../components/DetailedExplanation' Welcome to the Redux Quick Start tutorial! This tutorial will introduce you to Redux, so that you can begin using it as quickly as possible. By the time you finish, you should be able to start building your own Redux applications using the tools and patterns you've learned here. +In Part 1 of this tutorial, we'll cover the key concepts and terms you need to know to use Redux, and we'll examine a typical React + Redux app to see how the pieces fit together. + +In [Part 2](./part-2.md), we'll use that knowledge to build a small blogging app with some real-world features. + ### How to Read This Tutorial This page will focus on showing you _how_ to use Redux the right way, and explain just enough of the concepts so that you can understand how to build Redux apps correctly. @@ -105,7 +109,7 @@ Redux can integrate with any UI framework, and is most frequently used with Reac #### Redux Toolkit -[**Redux Toolkit**](https://redux-toolkit.js.org) is our recommended approach for writing Redux logic. It contains functions that build in our suggested best practices, simplify most Redux tasks, prevent common mistakes, and make it easier to write Redux applications. +[**Redux Toolkit**](https://redux-toolkit.js.org) is our recommended approach for writing Redux logic. It contains packages and functions that we think are essential for building a Redux app. Redux Toolkit builds in our suggested best practices, simplifies most Redux tasks, prevents common mistakes, and makes it easier to write Redux applications. #### Redux DevTools Extension @@ -144,7 +148,7 @@ It is a self-contained app with the following parts: - The **view**, a declarative description of the UI based on the current state - The **actions**, the events that occur in the app based on user input, and trigger updates in the state -This is a small example of "one-way data flow": +This is a small example of **"one-way data flow"**: - State describes the condition of the app at a specific point in time - The UI is rendered based on that state @@ -153,7 +157,7 @@ This is a small example of "one-way data flow": ![One-way data flow](/img/tutorials/one-way-data-flow.png) -However, the simplicity can break down when we have **multiple components that need to share and use the same state**, especially if those components are located in different parts of the application. Sometimes this can be solved by ["lifting state up"](https://reactjs.org/docs/lifting-state-up.html) to parent components, but this doesn't always help. +However, the simplicity can break down when we have **multiple components that need to share and use the same state**, especially if those components are located in different parts of the application. Sometimes this can be solved by ["lifting state up"](https://reactjs.org/docs/lifting-state-up.html) to parent components, but that doesn't always help. So why don't we extract the shared state out of the components, and manage it in a global singleton? With this, our component tree becomes a big "view", and any component can access the state or trigger actions, no matter where they are in the tree! @@ -163,7 +167,7 @@ This is the basic idea behind Redux: a single centralized place to contain the g ### Terminology -There's some important terms that you'll need to be familiar with before we continue: +There's some important Redux terms that you'll need to be familiar with before we continue: #### Actions @@ -205,6 +209,8 @@ Reducers must _always_ follow some specific rules: - They are not allowed to modify the existing `state`. Instead, they must make _immutable updates_, by copying the existing `state` and making changes to the copied values. - They must not do any asynchronous logic or other "side effects" +We'll talk more about the rules of reducers later, including why they're important and how to follow them correctly. + ```js const initialState = { value: 0 } @@ -227,7 +233,7 @@ function counterReducer(state = initialState, action) { The current Redux application state lives in an object called the **store** . -The store is created using a reducer, and has a method called `getState` that returns the current state value: +The store is created by passing in a reducer, and has a method called `getState` that returns the current state value: ```js import { configureStore } from '@reduxjs/toolkit' @@ -240,7 +246,7 @@ console.log(store.getState()) #### Dispatch -The Redux store has a method called `dispatch`. The only way to update the state is to call `store.dispatch()` and pass in an action object. The store will run its reducer function and save the new state value: +The Redux store has a method called `dispatch`. The only way to update the state is to call `store.dispatch()` and pass in an action object. The store will run its reducer function and save the new state value inside, and we can call `getState()` to retrieve the updated value: ```js store.dispatch({ type: 'counter/increment' }) @@ -281,3 +287,126 @@ console.log(currentValue) ## Examining a React and Redux App Now that you know the pieces that make up a Redux app, let's look at a real working example to see how these pieces fit together. + +### The Counter Example App + +The sample project we'll look at is a small counter application that lets us add or subtract from a number as we click buttons. It may not be very exciting, but it shows all the important pieces of a React+Redux application in action. + +The project has been created using [the official Redux template for Create-React-App](https://github.com/reduxjs/cra-template-redux), and uses two important package: + +- + +Here's the live version of the project. You can play around with it by clicking the buttons in the app preview on the right, and browse through the source files on the left. + + + +If you'd like to try create this project on your own computer, you can [start a new Create-React-App project](https://create-react-app.dev/docs/getting-started#selecting-a-template) using our Redux template: + +``` +npx create-react-app redux-quickstart-example --template redux +``` + +#### Using the Counter App + +The counter app has already been set up to let us watch what happens inside as we use it. + +Try right-clicking inside the app preview in your browser, and choose "Inspect" from the menu to open up your browser's DevTools. Then, choose the "Redux" tab in the DevTools, and click the "State" button in the upper-right toolbar. You should see something that looks like this: + +![Redux DevTools: initial app state](/img/tutorials/quickstart-devtools-initial.png) + +On the right, we can see that our Redux store is starting off with an app state value that looks like this: + +```js +{ + counter: { + value: 0 + } +} +``` + +The DevTools will show us how the store state changes as we use the app. + +Let's play with the app first to see what it does. Click the "+" button in the app, then look at the "Diff" tab in the Redux DevTools: + +![Redux DevTools: first dispatched action](/img/tutorials/quickstart-devtools-first-action.png) + +We can see two important things here: + +- When we clicked the "+" button, an action with a type of `"counter/increment"` was dispatched to the store +- When that action was dispatched, the `state.counter.value` field changed from `0` to `1` + +Now try these steps: + +- Click the "+" button again. The displayed value should now be 2. +- Click the "-" button once. The displayed value should now be 1. +- Click the "Add Amount" button. The displayed value should now be 3. +- Change the number "2" in the textbox to a "3" +- Click the "Add Async" button. You should see a progress bar fill the button, and after a couple seconds, the displayed value should change to 6. + +Go back to the Redux DevTools. You should see a total of five actions dispatched, one for each time we clicked a button . Now select the last `"counter/increment"` entry from the list on the left, and click the "Action" tab on the right side: + +![Redux DevTools: done clicking buttons](/img/tutorials/quickstart-devtools-done-clicking.png) + +We can see that this action object looked like this: + +```js +{ + type: 'counter/incrementByAmount', + payload: 3 +} +``` + +And if you click the "Diff" tab, you can see that the `state.counter.value` field changed from a `3` to a `6`. + +The ability to see what is happening inside of our app and how our state is changing over time is very powerful! + +### Counter App Setup + +Now that you know what the app does, let's look at how it works. + +Here are the key files that make up this application: + +- `/src` + - `index.js`: the starting point for the app + - `App.js`: the top-level React component + - `/app` + - `store.js`: creates the Redux store instance + - `/features` + - `/counter` + - `Counter.js`: a React component that shows the UI for the counter feature + - `counterSlice.js`: the Redux logic for the counter feature + +Let's start by looking at how the Redux store is created. + +#### Creating the Redux Store + +Open up `app/store.js`, which should look like this: + +**TODO filename title here** + +```js +import { configureStore } from '@reduxjs/toolkit' +import counterReducer from '../features/counter/counterSlice' + +export default configureStore({ + reducer: { + counter: counterReducer + } +}) +``` + +The Redux store is created using the `configureStore` function from Redux Toolkit. `configureStore` requires that we pass in a `reducer` argument, which can be either a function, or an object. + +Earlier, we saw that we can pass a reducer function directly as the `reducer` argument: + +```js +const store = configureStore({ + reducer: counterReducer +}) +``` diff --git a/website/static/img/tutorials/quickstart-devtools-done-clicking.png b/website/static/img/tutorials/quickstart-devtools-done-clicking.png new file mode 100644 index 0000000000000000000000000000000000000000..5e5d405f709b53ba0e105e8cf91b310c1b2bd0c1 GIT binary patch literal 41795 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%0DgE}b-m2T}hd+GVO)wg-Bn4W- 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 WM=K<=2lWz9Sv6F2l#3K^2mKETbH^0` literal 0 HcmV?d00001 diff --git a/website/static/img/tutorials/quickstart-devtools-initial.png b/website/static/img/tutorials/quickstart-devtools-initial.png new file mode 100644 index 0000000000000000000000000000000000000000..088138480a88c76ec45b2fb85550633019aae409 GIT binary patch literal 31711 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 literal 0 HcmV?d00001 From deebd28c97cb7ced1addd8f000f68720d209a396 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 21:58:44 -0400 Subject: [PATCH 11/60] Quick Start: create nested folder and rename file --- .../quick-start-part-1.mdx} | 12 ++++++------ docs/tutorials/quick-start/quick-start-part-2.mdx | 11 +++++++++++ website/sidebars.js | 9 ++++++++- 3 files changed, 25 insertions(+), 7 deletions(-) rename docs/tutorials/{quick-start.mdx => quick-start/quick-start-part-1.mdx} (97%) create mode 100644 docs/tutorials/quick-start/quick-start-part-2.mdx diff --git a/docs/tutorials/quick-start.mdx b/docs/tutorials/quick-start/quick-start-part-1.mdx similarity index 97% rename from docs/tutorials/quick-start.mdx rename to docs/tutorials/quick-start/quick-start-part-1.mdx index 92e8ce0fd7..4c08e20c01 100644 --- a/docs/tutorials/quick-start.mdx +++ b/docs/tutorials/quick-start/quick-start-part-1.mdx @@ -1,14 +1,14 @@ --- -id: quick-start -title: Quick Start -sidebar_label: Quick Start +id: quick-start-part-1 +title: Redux Quick Start - Part 1 +sidebar_label: 'Redux Concepts and Structure' hide_title: true description: The official Quick Start tutorial for Redux - the fastest way to learn and start using Redux today! --- -import { DetailedExplanation } from '../components/DetailedExplanation' +import { DetailedExplanation } from '../../components/DetailedExplanation' -# Quick Start +# Quick Start, Part 1: Redux Concepts and Structure :::tip What You'll Learn @@ -24,7 +24,7 @@ Welcome to the Redux Quick Start tutorial! This tutorial will introduce you to R In Part 1 of this tutorial, we'll cover the key concepts and terms you need to know to use Redux, and we'll examine a typical React + Redux app to see how the pieces fit together. -In [Part 2](./part-2.md), we'll use that knowledge to build a small blogging app with some real-world features. +In [Part 2](./quick-start-part-2.md), we'll use that knowledge to build a small blogging app with some real-world features. ### How to Read This Tutorial diff --git a/docs/tutorials/quick-start/quick-start-part-2.mdx b/docs/tutorials/quick-start/quick-start-part-2.mdx new file mode 100644 index 0000000000..cedab50418 --- /dev/null +++ b/docs/tutorials/quick-start/quick-start-part-2.mdx @@ -0,0 +1,11 @@ +--- +id: quick-start-part-2 +title: Redux Quick Start - Part 2 +sidebar_label: 'Building a Redux App' +hide_title: true +description: The official Quick Start tutorial for Redux - the fastest way to learn and start using Redux today! +--- + +import { DetailedExplanation } from '../../components/DetailedExplanation' + +# Quick Start, Part 2: Building a React + Redux App diff --git a/website/sidebars.js b/website/sidebars.js index 89dbd16377..f50e2a651b 100755 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -12,7 +12,14 @@ module.exports = { 'introduction/examples' ], Tutorials: [ - 'tutorials/quick-start', + { + type: 'category', + label: 'Quick Start', + items: [ + 'tutorials/quick-start/quick-start-part-1', + 'tutorials/quick-start/quick-start-part-2' + ] + }, { type: 'category', label: 'Basic Tutorial', From c58d44f9d8459cb685311f809bf635a790ba2cb9 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 29 Mar 2020 22:38:54 -0400 Subject: [PATCH 12/60] Store setup --- .../quick-start/quick-start-part-1.mdx | 128 ++++++++++++++++-- 1 file changed, 119 insertions(+), 9 deletions(-) diff --git a/docs/tutorials/quick-start/quick-start-part-1.mdx b/docs/tutorials/quick-start/quick-start-part-1.mdx index 4c08e20c01..50584e44e3 100644 --- a/docs/tutorials/quick-start/quick-start-part-1.mdx +++ b/docs/tutorials/quick-start/quick-start-part-1.mdx @@ -292,9 +292,7 @@ Now that you know the pieces that make up a Redux app, let's look at a real work The sample project we'll look at is a small counter application that lets us add or subtract from a number as we click buttons. It may not be very exciting, but it shows all the important pieces of a React+Redux application in action. -The project has been created using [the official Redux template for Create-React-App](https://github.com/reduxjs/cra-template-redux), and uses two important package: - -- +The project has been created using [the official Redux template for Create-React-App](https://github.com/reduxjs/cra-template-redux). Out of the box, it has already been configured with a standard Redux application structure, using [Redux Toolkit](https://redux-toolkit.js.org) to create the Redux store and logic, and [React-Redux](https://react-redux.js.org) to connect together the Redux store and the React components. Here's the live version of the project. You can play around with it by clicking the buttons in the app preview on the right, and browse through the source files on the left. @@ -366,7 +364,7 @@ And if you click the "Diff" tab, you can see that the `state.counter.value` fiel The ability to see what is happening inside of our app and how our state is changing over time is very powerful! -### Counter App Setup +### Creating the Redux Store Now that you know what the app does, let's look at how it works. @@ -384,8 +382,6 @@ Here are the key files that make up this application: Let's start by looking at how the Redux store is created. -#### Creating the Redux Store - Open up `app/store.js`, which should look like this: **TODO filename title here** @@ -401,12 +397,126 @@ export default configureStore({ }) ``` -The Redux store is created using the `configureStore` function from Redux Toolkit. `configureStore` requires that we pass in a `reducer` argument, which can be either a function, or an object. +The Redux store is created using the `configureStore` function from Redux Toolkit. `configureStore` requires that we pass in a `reducer` argument. + +Our application might be made up of many different features, and each of those features might have its own reducer function. When we call `configureStore`, we can pass in all of the different reducers in an object. The key names in the object will define the keys in our final state value. + +We have a file named `features/counter/counterSlice.js` that exports a reducer function for the counter logic. We can import that `counterReducer` function here, and include it when we create the store. + +When we pass in an object like `{counter: counterReducer}`, that says that we want to have a `state.counter` section of our Redux state object, and that we want the `counterReducer` function to be in charge of deciding if and how to update the `state.counter` section whenever an action is dispatched. + +#### Redux Slices + +**A "slice" is a collection of Redux reducer logic and actions for a single feature in your app**, typically defined together in a single file. The name comes from splitting up the root Redux state object into multiple "slices" of state. -Earlier, we saw that we can pass a reducer function directly as the `reducer` argument: +For example, in a blogging app, our store setup might look like: + +```js +import { configureStore } from '@reduxjs/toolkit' +import usersReducer from '../features/users/usersSlice' +import postsReducer from '../features/posts/postsSlice' +import commentsReducer from '../features/comments/commentsSlice' + +export default configureStore({ + reducer: { + users: usersReducer, + posts: postsReducer, + comments: commentsReducer + } +}) +``` + +In that example, `state.users`, `state.posts`, and `state.comments` are each a separate "slice" of the Redux state. Since `usersReducer` is responsible for updating the `state.users` slice, we refer to it as a "slice reducer" function. + + + +A Redux store needs to have a single "root reducer" function passed in when it's created. So if we have many different slice reducer functions, how do we get a single root reducer instead, and how does this define the contents of the Redux store state? + +If we tried calling all of the slice reducers by hand, it might look like this: + +```js +function rootReducer(state = {}, action) { + return { + users: usersReducer(state.users, action), + posts: postsReducer(state.posts, action), + comments: commentsReducer(state.comments, action) + } +} +``` + +That calls each slice reducer individually, passes in the specific slice of the Redux state, and includes the return value in the final new Redux state object. + +Redux has a function called [`combineReducers`](../../api/combineReducers.md) that does this for us automatically. It accepts an object full of slice reducers as its argument, and returns a function that calls each slice reducer whenever an action is dispatched. The result from each slice reducer are all combined together into a single object as the final result. We can do the same thing as the previous example using `combineReducers`: + +```js +const rootReducer = combineReducers({ + users: usersReducer, + posts: postsReducer, + comments: commentsReducer +}) +``` + +When we pass an object of slice reducers to `configureStore`, it passes those to `combineReducers` for us to generate the root reducer. + +As we saw earlier, you can also pass a reducer function directly as the `reducer` argument: ```js const store = configureStore({ - reducer: counterReducer + reducer: rootReducer +}) +``` + + + +### The Counter Slice + +Since we know that the `counterReducer` function is coming from `feature/counter/counterSlice.js`, let's see what's in that file: + +**TODO file name here** + +```js +import { createSlice } from '@reduxjs/toolkit' + +export const counterSlice = createSlice({ + name: 'counter', + initialState: { + value: 0 + }, + reducers: { + increment: state => { + // Redux Toolkit allows us to write "mutating" logic in reducers. It + // doesn't actually mutate the state because it uses the immer library, + // which detects changes to a "draft state" and produces a brand new + // immutable state based off those changes + state.value += 1 + }, + decrement: state => { + state.value -= 1 + }, + incrementByAmount: (state, action) => { + state.value += action.payload + } + } }) + +export const { increment, decrement, incrementByAmount } = counterSlice.actions + +// The function below is called a thunk and allows us to perform async logic. It +// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This +// will call the thunk with the `dispatch` function as the first argument. Async +// code can then be executed and other actions can be dispatched +export const incrementAsync = amount => dispatch => { + setTimeout(() => { + dispatch(incrementByAmount(amount)) + }, 1000) +} + +// The function below is called a selector and allows us to select a value from +// the state. Selectors can also be defined inline where they're used instead of +// in the slice file. For example: `useSelector((state) => state.counter.value)` +export const selectCount = state => state.counter.value + +export default counterSlice.reducer ``` + +Let's break this down piece by piece. From fcb618def4b157d7167e3521d794eaa63a71938c Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Mon, 30 Mar 2020 22:17:51 -0400 Subject: [PATCH 13/60] Quick Start: add slice, reducer, immutability, and thunk sections --- .../quick-start/quick-start-part-1.mdx | 291 +++++++++++++++++- 1 file changed, 282 insertions(+), 9 deletions(-) diff --git a/docs/tutorials/quick-start/quick-start-part-1.mdx b/docs/tutorials/quick-start/quick-start-part-1.mdx index 50584e44e3..caaa2d3ae2 100644 --- a/docs/tutorials/quick-start/quick-start-part-1.mdx +++ b/docs/tutorials/quick-start/quick-start-part-1.mdx @@ -194,7 +194,7 @@ An **action creator** is a function that creates and returns an action object. W const addTodo = text => { return { type: 'todos/todoAdded', - payload: 'Buy milk' + payload: text } } ``` @@ -360,10 +360,12 @@ We can see that this action object looked like this: } ``` -And if you click the "Diff" tab, you can see that the `state.counter.value` field changed from a `3` to a `6`. +And if you click the "Diff" tab, you can see that the `state.counter.value` field changed from a `3` to a `6` in response to that action. The ability to see what is happening inside of our app and how our state is changing over time is very powerful! +The DevTools have several more commands and options to help you debug your app, and we'll look at a couple of those later. + ### Creating the Redux Store Now that you know what the app does, let's look at how it works. @@ -444,7 +446,7 @@ function rootReducer(state = {}, action) { } ``` -That calls each slice reducer individually, passes in the specific slice of the Redux state, and includes the return value in the final new Redux state object. +That calls each slice reducer individually, passes in the specific slice of the Redux state, and includes each return value in the final new Redux state object. Redux has a function called [`combineReducers`](../../api/combineReducers.md) that does this for us automatically. It accepts an object full of slice reducers as its argument, and returns a function that calls each slice reducer whenever an action is dispatched. The result from each slice reducer are all combined together into a single object as the final result. We can do the same thing as the previous example using `combineReducers`: @@ -468,9 +470,9 @@ const store = configureStore({ -### The Counter Slice +### Creating Slice Reducers and Actions -Since we know that the `counterReducer` function is coming from `feature/counter/counterSlice.js`, let's see what's in that file: +Since we know that the `counterReducer` function is coming from `feature/counter/counterSlice.js`, let's see what's in that file, piece by piece. **TODO file name here** @@ -501,6 +503,201 @@ export const counterSlice = createSlice({ export const { increment, decrement, incrementByAmount } = counterSlice.actions +export default counterSlice.reducer +``` + +Earlier, we saw that clicking the different buttons in the UI dispatched three different Redux action types: + +- `{type: "counter/increment"}` +- `{type: "counter/decrement"}` +- `{type: "counter/incrementByAmount"}` + +We know that actions are plain objects with a `type` field, that the `type` field is always a string, and that we typically have "action creator" functions that create and return the action objects. So where are those action objects, type strings, and action creators defined? + +We _could_ write those all by hand, every time. But, that would be tedious. Besides, what's _really_ important in Redux is the reducer functions, and the logic they have for calculating new state. + +Redux Toolkit has a function called `createSlice`, which takes care of the work of generating action type strings, action creator functions, and action objects. All you have to do is define a name for this slice, write an object that has some reducer functions in it, and it generates the corresponding action code automatically. The string from the `name` option is used as the first part of each action type, and the key name of each reducer function is used as the second part. So, the `"counter"` name + the `"increment"` reducer function generated an action type of `{type: "counter/increment"}`. (After all, why write this by hand if the computer can do it for us!) + +In addition to the `name` field, `createSlice` needs us to pass in the initial state value for the reducers, so that there is a `state` the first time it gets called. In this case, we're providing an object with a `value` field that starts off at 0. + +We can see here that there are three reducer functions, and that corresponds to the three different action types that were dispatched by clicking the different buttons. + +`createSlice` automatically generates action creators with the same names as the reducer functions we wrote. We can check that by calling one of them and seeing what it returns: + +```js +console.log(counterSlice.actions.increment()) +// {type: "counter/increment"} +``` + +It also generates the slice reducer function that knows how to respond to all these action types: + +```js +const newState = counterSlice.reducer( + { value: 10 }, + counterSlice.actions.increment() +) +console.log(newState) +// {value: 11} +``` + +### Rules of Reducers + +We said earlier that reducers must **always** follow some special rules: + +- They should only calculate the new state value based on the `state` and `action` arguments +- They are not allowed to modify the existing `state`. Instead, they must make _immutable updates_, by copying the existing `state` and making changes to the copied values. +- They must not do any asynchronous logic or other "side effects" + +But why are these rules important? There's a few different reasons: + +- One of the goals of Redux is to make your code predictable. When a function's output is only calculated from the input arguments, it's easier to understand how that code works, and to test it. +- On the other hand, if a function depends on variables outside itself, or behaves randomly, you never know what will happen when you run it. +- If a function modifies other values, including its arguments, that can change the way the application works unexpectedly. This can be a common source of bugs, such as "I updated my state, but now my UI isn't updating when it should!" +- Some of the Redux DevTools capabilities depend on having your reducers follow these rules correctly + +The rule about "immutable updates" is particularly important, and worth talking about further. + +### Reducers and Immutable Updates + +If something is "immutable", it can never change. JavaScript objects and arrays are all mutable by default. If I create an object, I can change the contents of its fields. If I create an array, I can change the contents as well: + +```js +const obj = { a: 1, b: 2 } +// still the same object outside, but the contents have changed +obj.b = 3 + +const arr = ['a', 'b'] +// In the same way, we can change the contents of this array +arr.push('c') +arr[1] = 'd' +``` + +This is called _mutating_ the object or array. + +In Redux, **our reducers are _never_ allowed to mutate the original / current state values!** + +So if we can't change the originals, how do we return an updated state? + +**Reducers can only make _copies_ of the original values, and then they can mutate the copies.** + +We can do this by hand using JavaScript's array / object spread operators, as well as array methods that return new copies of the array instead of mutating the original array: + +```js +const obj1 = { + a: { + // To safely update obj.a.c, we have to copy each piece + c: 3 + } + b: 2, +} + + +const obj2 = { + // copy obj + ...obj + // overwrite a + a: { + // copy obj.a + ...obj.a, + // overwrite c + c: 42 + } +} + +const arr = ["a", "b"]; +// Create a new copy of arr, with "c" appended to the end +const arr2 = arr.concat("c"); +``` + +If you're thinking that "this looks hard to remember and do correctly"... yeah, you're right! :) + +Writing immutable update logic by hand _is_ hard, and accidentally mutating state in reducers is the single most common mistake Redux users make. + +**That's why Redux Toolkit's `createSlice` function lets you write immutable updates an easier way!** + +`createSlice` uses a library called [Immer](https://immerjs.github.io/immer/docs/introduction) inside. Immer uses a special JS tool called a `Proxy` to wrap the data you provide, and lets you write code that "mutates" that wrapped data. But, Immer tracks all the changes you've tried to make, and then uses that list of changes to return a safely immutably updated value, as if you'd written all the immutable update logic by hand. + +So, instead of this: + +```js +function handwrittenReducer(state, action) { + return { + ...state, + first: { + ...state.first, + second: { + ...state.first.second, + [action.someId]: { + ...state.first.second[action.someId], + fourth: action.someValue + } + } + } + } +} +``` + +You can write code that looks like this: + +```js +function reducerWithImmer(state, action) { + state.first.second[action.someId].fourth = action.someValue +} +``` + +That's a lot easier to read! + +But, here's something _very_ important to remember: + +:::warning + +**You can _only_ write "mutating" logic in Redux Toolkit's `createSlice` and `createReducer` because they use Immer inside! If you write mutating logic in reducers without Immer, it _will_ mutate the state and cause bugs!** + +::: + +With that in mind, let's go back and look at the actual reducers from the counter slice. + +```js +export const counterSlice = createSlice({ + name: 'counter', + initialState: { + value: 0 + }, + reducers: { + increment: state => { + // Redux Toolkit allows us to write "mutating" logic in reducers. It + // doesn't actually mutate the state because it uses the immer library, + // which detects changes to a "draft state" and produces a brand new + // immutable state based off those changes + state.value += 1 + }, + decrement: state => { + state.value -= 1 + }, + incrementByAmount: (state, action) => { + state.value += action.payload + } + } +}) +``` + +We can see that the `increment` reducer will always add 1 to `state.value`. Because Immer knows we've made changes to the draft `state` object, we don't have to actually return anything here. In the same way, the `decrement` reducer subtracts 1. + +In both of those reducers, we don't actually need to have our code look at the `action` object. It will be passed in anyway, but since we don't need it, we can skip declaring `action` as a parameter for the reducers. + +On the other hand, the `incrementByAmount` reducer _does_ need to know something: how much it should be adding to the counter value. So, we declare the reducer as having both `state` and `action` arguments. In this case, we know that the amount we typed into the textbox is being put into the `action.payload` field, so we can add that to `state.value`. + +:::tip Want to Know More? + +For more information on immutability and writing immutable updates, see [the "Immutable Update Patterns" docs page](../../recipes/structuring-reducers/ImmutableUpdatePatterns.md) and [The Complete Guide to Immutability in React and Redux](https://daveceddia.com/react-redux-immutability-guide/). + +::: + +### Writing Async Logic with Thunks + +The next function that's exported from `counterSlice` might look a bit strange: + +```js // The function below is called a thunk and allows us to perform async logic. It // can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This // will call the thunk with the `dispatch` function as the first argument. Async @@ -510,13 +707,89 @@ export const incrementAsync = amount => dispatch => { dispatch(incrementByAmount(amount)) }, 1000) } +``` + +A **thunk** is a special kind of Redux function that can contain asynchronous logic. Thunks are written using two functions: + +- An inside thunk function, which gets `dispatch` and `getState` as arguments +- The outside creator function, which creates and returns the thunk function + +We can use them the same way we use a typical Redux action creator: + +```js +store.dispatch(incrementAsync(5)) +``` + +However, thunks require a special kind of addon called _middleware_ to be added to the Redux store when it's created. Fortunately, Redux Toolkit's `configureStore` function already sets that up for us automatically, so we can just go ahead and use this. + +When you need to make AJAX calls to fetch data from the server, you can put that call in a thunk. Here's an example that's written a bit longer, so you can see how it's defined: + +```js +// the outside "thunk creator" function +const fetchUserById = userId => { + // the inside "thunk function" + return async (dispatch, getState) => { + try { + // make an async call in the thunk + const user = userAPI.fetchById(userId) + // dispatch an action when we get the response back + dispatch(userLoaded(user)) + } catch (err) { + // If something went wrong, handle it here + } + } +} +``` + +We'll see thunks being used in Part 2 of this tutorial. + + + +We know that we're not allowed to put any kind of async logic in reducers. But, that logic has to live somewhere. + +If we have access to the Redux store, we could just write some async code and call `store.dispatch()` when we're done: + +```js +const store = configureStore({ reducer: counterReducer }) + +setTimeout(() => { + store.dispatch(increment()) +}, 250) +``` + +But, in a real Redux app, we're not allowed to import the store into other files, especially in our React components. + +In addition, we often need to write some async logic that we know will be used with _some_ store, eventually, but we don't know _which_ store. + +The Redux store can be extended with "middleware", which are a kind of add-on or plugin that can add extra abilities. The most common reason to use middleware is to let you write code that can have async logic, but still talk to the store at the same time. They can also modify the store so that we can call `dispatch()` and pass in values that are _not_ plain action objects, like functions or Promises. + +The Redux Thunk middleware modifies the store to let you pass functions into `dispatch`. In fact, it's short enough we can paste it here: + +```js +const thunkMiddleware = ({ dispatch, getState }) => next => action => { + if (typeof action === 'function') { + return action(dispatch, getState, extraArgument) + } + + return next(action) +} +``` + +It looks to see if the "action" that was passed into `dispatch` is actually a function instead of a plain action object. If it's actually a function, it calls the function, and returns the result. Otherwise, since this must be an action object, it passes the action forward to the store. +This gives us a way to write whatever sync or async code we want, while still having access to `dispatch` and `getState`. + + + +:::tip Want to Know More? + +See [the Redux Thunk docs](https://github.com/reduxjs/redux-thunk), the post [What the heck is a thunk?](https://daveceddia.com/what-is-a-thunk/) and the [Redux FAQ entry on "why do we use middleware for async?"](../../faq/Actions.md#how-can-i-represent-side-effects-such-as-ajax-calls-why-do-we-need-things-like-action-creators-thunks-and-middleware-to-do-async-behavior) for more information. + +::: + +```js // The function below is called a selector and allows us to select a value from // the state. Selectors can also be defined inline where they're used instead of // in the slice file. For example: `useSelector((state) => state.counter.value)` export const selectCount = state => state.counter.value - -export default counterSlice.reducer ``` - -Let's break this down piece by piece. From 072a1cc6ca1acc931fc0c977389c39053ebb05cd Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Mon, 30 Mar 2020 23:35:44 -0400 Subject: [PATCH 14/60] Quick start: Add React-Redux section --- .../quick-start/quick-start-part-1.mdx | 198 ++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/docs/tutorials/quick-start/quick-start-part-1.mdx b/docs/tutorials/quick-start/quick-start-part-1.mdx index caaa2d3ae2..af495c37b4 100644 --- a/docs/tutorials/quick-start/quick-start-part-1.mdx +++ b/docs/tutorials/quick-start/quick-start-part-1.mdx @@ -781,15 +781,213 @@ This gives us a way to write whatever sync or async code we want, while still ha +There's one more function in this file, but we'll talk about that in just a minute when we look at the `` UI component. + :::tip Want to Know More? See [the Redux Thunk docs](https://github.com/reduxjs/redux-thunk), the post [What the heck is a thunk?](https://daveceddia.com/what-is-a-thunk/) and the [Redux FAQ entry on "why do we use middleware for async?"](../../faq/Actions.md#how-can-i-represent-side-effects-such-as-ajax-calls-why-do-we-need-things-like-action-creators-thunks-and-middleware-to-do-async-behavior) for more information. ::: +### The React Counter Component + +Earlier, we saw what a standalone React `` component looks like. Our React+Redux app has a similar `` component, but it does a few things differently. + +We'll start by looking at the `Counter.js` component file: + +```js +import React, { useState } from 'react' +import { useSelector, useDispatch } from 'react-redux' +import { + decrement, + increment, + incrementByAmount, + incrementAsync, + selectCount +} from './counterSlice' +import styles from './Counter.module.css' + +export function Counter() { + const count = useSelector(selectCount) + const dispatch = useDispatch() + const [incrementAmount, setIncrementAmount] = useState('2') + + return ( +
+
+ + {count} + +
+ {/* omit additional rendering output here */} +
+ ) +} +``` + +Like with the earlier example, we have a function component called `Counter`, that stores some data in a `useState` hook. + +However, in our component, it doesn't look like we're storing the actual current counter value as state. There _is_ a variable called `count`, but it's not coming from a `useState` hook. + +While React includes several built-in hooks like `useState` and `useEffect`, other libraries can create their own [custom hooks](https://reactjs.org/docs/hooks-custom.html) that use React's hooks to build custom logic. + +The [React-Redux library](https://react-redux.js.org/) has [a set of custom hooks that allow your React component to interact with a Redux store](https://react-redux.js.org/api/hooks). + +#### Reading Data with `useSelector` + +First, the `useSelector` hook lets our component extract whatever pieces of data it needs from the Redux store state. + +Earlier, we saw that we can write "selector" functions, which take `state` as an argument and return some part of the state value. + +Our `counterSlice`.js has this selector function at the bottom: + ```js // The function below is called a selector and allows us to select a value from // the state. Selectors can also be defined inline where they're used instead of // in the slice file. For example: `useSelector((state) => state.counter.value)` export const selectCount = state => state.counter.value ``` + +If we had access to a Redux store, we could retrieve the current counter value as: + +```js +const count = selectCount(store.getState()) +console.log(count) +// 0 +``` + +Our components can't talk to the Redux store directly, because we're not allowed to import it into component files. But, `useSelector` takes care of talking to the Redux store behind the scenes for us. If we pass in a selector function, it calls `someSelector(store.getState())` for us, and returns the result. + +So, we can get the current store counter value by doing: + +```js +const count = useSelector(selectCount) +``` + +We don't have to _just_ use selectors that have already been exported, either. For example, we could write: + +```js +const countPlusTwo = useSelector(state => state.counter.value + 2) +``` + +Any time an action has been dispatched and the Redux store has been updated, `useSelector` will re-run our selector function. If the selector returns a different value than last time, `useSelector` will make sure our component re-renders with the new value. + +#### Dispatching Actions with `useDispatch` + +Similarly, we know that if we had access to a Redux store, we could dispatch actions using action creators, like `store.dispatch(increent())`. Since we don't have access to the store itself, we need some way to have access to just the `dispatch` method. + +The `useDispatch` hook does that for us, and gives us the actual `dispatch` method from the Redux store: + +```js +const dispatch = useDispatch() +``` + +From there, we can dispatch actions when the user does something like clicking on a button: + +```js + +``` + +### Component State and Forms + +By now you might be wondering, "Do I always have to put all my app's state into the Redux store?" + +The answer is **NO. Global state that is needed across the app should go in the Redux store. State that's only needed in one place should be kept in component state.** + +In this example, we have an input textbox where the user can type in the next number to be added to the counter: + +```js +const [incrementAmount, setIncrementAmount] = useState('2') + +// later +return ( +
+ setIncrementAmount(e.target.value)} + /> + + +
+) +``` + +We _could_ keep the current number string in the Redux store, by dispatching an action in the input's `onChange` handler and keeping it in our reducer. But, that doesn't give us any benefit. The only place that text string is used is here, in the `` component. (Sure, there's only one other component in this example: ``. But even if we had a larger application with many components, only `` cares about this input value.) + +So, it makes sense to keep that value in a `useState` hook here in the `` component. + +Similarly, if we had a boolean flag called `isDropdownOpen`, no other components in the app would care about that - it should really stay local to this component. + +**In a React + Redux app, your global state should go in the Redux store, and your local state should stay in React components.** + +If you're not sure where to put something, here are some common rules of thumb for determining what kind of data should be put into Redux: + +- Do other parts of the application care about this data? +- Do you need to be able to create further derived data based on this original data? +- Is the same data being used to drive multiple components? +- Is there value to you in being able to restore this state to a given point in time (ie, time travel debugging)? +- Do you want to cache the data (ie, use what's in state if it's already there instead of re-requesting it)? +- Do you want to keep this data consistent while hot-reloading UI components (which may lose their internal state when swapped)? + +This is also a good example of how to think about forms in Redux in general. **Most form state probably shouldn't be kept in Redux.** Instead, keep the data in your form components as you're editing it, and then dispatch Redux actions to update the store when the user is done. + +### Providing the Store + +We've seen that our components can use the `useSelector` and `useDispatch` hooks to talk to the Redux store. But, since we didn't import the store, how do those hooks know what Redux store to talk to? + +Now that we've seen all the different pieces of this application, it's time to circle back to the starting point of this application and see how the last pieces of the puzzle fit together. + +**index.js** + +```js +import React from 'react' +import ReactDOM from 'react-dom' +import './index.css' +import App from './App' +import store from './app/store' +import { Provider } from 'react-redux' +import * as serviceWorker from './serviceWorker' + +ReactDOM.render( + + + , + document.getElementById('root') +) +``` + +We always have to call `ReactDOM.render()` to tell React to start rendering our root `` component. In order for our hooks like `useSelector` to work right, we need to use a component called `` to pass down the Redux store behind the scenes so they can access it. + +We already created our store in `app/store.js`, so we can import it here. Then, we put our `` component around the whole ``, and pass in the store: ``. + +Now, any React components that call `useSelector` or `useDispatch` will be talking to the Redux store we gave to the ``. From b2114ba093730c562d0c582a383a18bce54ada5e Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Tue, 31 Mar 2020 00:03:29 -0400 Subject: [PATCH 15/60] Quick start: emphasize immutability, highlight JSX --- .../quick-start/quick-start-part-1.mdx | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/tutorials/quick-start/quick-start-part-1.mdx b/docs/tutorials/quick-start/quick-start-part-1.mdx index af495c37b4..88d330025a 100644 --- a/docs/tutorials/quick-start/quick-start-part-1.mdx +++ b/docs/tutorials/quick-start/quick-start-part-1.mdx @@ -574,12 +574,20 @@ arr[1] = 'd' This is called _mutating_ the object or array. +:::warning + In Redux, **our reducers are _never_ allowed to mutate the original / current state values!** +::: + So if we can't change the originals, how do we return an updated state? +:::tip + **Reducers can only make _copies_ of the original values, and then they can mutate the copies.** +::: + We can do this by hand using JavaScript's array / object spread operators, as well as array methods that return new copies of the array instead of mutating the original array: ```js @@ -607,6 +615,11 @@ const obj2 = { const arr = ["a", "b"]; // Create a new copy of arr, with "c" appended to the end const arr2 = arr.concat("c"); + +// or, we can make a copy of the original array: +const arr3 = arr.slice(); +// and mutate the copy: +arr3.push("c"); ``` If you're thinking that "this looks hard to remember and do correctly"... yeah, you're right! :) @@ -795,7 +808,7 @@ Earlier, we saw what a standalone React `` component looks like. Our Re We'll start by looking at the `Counter.js` component file: -```js +```jsx import React, { useState } from 'react' import { useSelector, useDispatch } from 'react-redux' import { @@ -837,7 +850,7 @@ export function Counter() { } ``` -Like with the earlier example, we have a function component called `Counter`, that stores some data in a `useState` hook. +Like with the earlier plain React example, we have a function component called `Counter`, that stores some data in a `useState` hook. However, in our component, it doesn't look like we're storing the actual current counter value as state. There _is_ a variable called `count`, but it's not coming from a `useState` hook. @@ -851,7 +864,7 @@ First, the `useSelector` hook lets our component extract whatever pieces of data Earlier, we saw that we can write "selector" functions, which take `state` as an argument and return some part of the state value. -Our `counterSlice`.js has this selector function at the bottom: +Our `counterSlice.js` has this selector function at the bottom: ```js // The function below is called a selector and allows us to select a value from @@ -876,7 +889,7 @@ So, we can get the current store counter value by doing: const count = useSelector(selectCount) ``` -We don't have to _just_ use selectors that have already been exported, either. For example, we could write: +We don't have to _just_ use selectors that have already been exported, either. For example, we could write a selector function as an inline argument to `useSelector`: ```js const countPlusTwo = useSelector(state => state.counter.value + 2) @@ -896,7 +909,7 @@ const dispatch = useDispatch() From there, we can dispatch actions when the user does something like clicking on a button: -```js +```jsx + // highlight-end {count}