From 0c5ab8bf97ded1088913f04b44f562579820d123 Mon Sep 17 00:00:00 2001 From: HF Date: Fri, 29 Jan 2021 02:15:33 +0100 Subject: [PATCH] add localisation via ttag --- i18n/de.po | 13 + i18n/es.po | 13 + package-lock.json | 919 +++++++++++++++++++++++++ package.json | 3 + scripts/bundle.js | 63 +- scripts/clean.js | 2 +- scripts/copy.js | 8 +- scripts/minifyCss.js | 6 +- src/components/ForgotPasswordModal.jsx | 3 +- src/components/Globe.jsx | 43 +- src/components/Main.jsx | 10 +- src/components/RegisterModal.jsx | 3 +- src/components/UserAreaModal.jsx | 3 +- src/web.js | 13 +- webpack.config.client.babel.js | 309 +++++---- webpack.config.client.babel.js.old | 237 +++++++ webpack.config.web.babel.js | 13 +- 17 files changed, 1454 insertions(+), 207 deletions(-) create mode 100644 i18n/de.po create mode 100644 i18n/es.po create mode 100644 webpack.config.client.babel.js.old diff --git a/i18n/de.po b/i18n/de.po new file mode 100644 index 0000000..9e73439 --- /dev/null +++ b/i18n/de.po @@ -0,0 +1,13 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=utf-8\n" +"Plural-Forms: nplurals = 2; plural = (n != 1);\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/components/ForgotPasswordModal.jsx:20 +#: src/components/RegisterModal.jsx:21 +#: src/components/UserAreaModal.jsx:128 +msgid "Consider joining us on Guilded:" +msgstr "Sprich zu uns und anderen Spielern auf guilded:" diff --git a/i18n/es.po b/i18n/es.po new file mode 100644 index 0000000..9e73439 --- /dev/null +++ b/i18n/es.po @@ -0,0 +1,13 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=utf-8\n" +"Plural-Forms: nplurals = 2; plural = (n != 1);\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/components/ForgotPasswordModal.jsx:20 +#: src/components/RegisterModal.jsx:21 +#: src/components/UserAreaModal.jsx:128 +msgid "Consider joining us on Guilded:" +msgstr "Sprich zu uns und anderen Spielern auf guilded:" diff --git a/package-lock.json b/package-lock.json index 322cdce..f1a8ed5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1592,6 +1592,15 @@ "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", "dev": true }, + "@types/formidable": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-1.0.32.tgz", + "integrity": "sha512-jOAB5+GFW+C+2xdvUcpd/CnYg2rD5xCyagJLBJU+9PB4a/DKmsAqS9yZI3j/Q9zwvM7ztPHaAIH1ijzp4cezdQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/json-schema": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", @@ -1609,6 +1618,12 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-9.4.6.tgz", "integrity": "sha512-CTUtLb6WqCCgp6P59QintjHWqzf4VL1uPA27bipLAPxFqrtK1gEYllePzTICGqQ8rYsCbpnsNypXjjDzGAAjEQ==" }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", @@ -1885,6 +1900,12 @@ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true }, + "ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=", + "dev": true + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -2237,6 +2258,17 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + } + }, "babel-plugin-react-svg": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/babel-plugin-react-svg/-/babel-plugin-react-svg-3.0.3.tgz", @@ -2258,6 +2290,43 @@ "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", "dev": true }, + "babel-plugin-ttag": { + "version": "1.7.30", + "resolved": "https://registry.npmjs.org/babel-plugin-ttag/-/babel-plugin-ttag-1.7.30.tgz", + "integrity": "sha512-rwYmxBihb/gnJRVdkZ1FmnfIaEs0u4g5zCtFvWZHz/Wo+lm9PpW08ynf/6sxiBBDPbiel0qXHCqqx4fUwkVvXg==", + "dev": true, + "requires": { + "@babel/generator": "^7.12.5", + "@babel/template": "^7.10.4", + "@babel/types": "^7.12.6", + "ajv": "6.12.3", + "babel-plugin-macros": "^2.8.0", + "dedent": "0.6.0", + "gettext-parser": "4.0.0-alpha.0", + "mkdirp": "^1.0.4", + "plural-forms": "^0.5.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "dedent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz", + "integrity": "sha1-Dm2o8M5Sg471zsXI+TlrDBtko8s=", + "dev": true + } + } + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -2555,6 +2624,16 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "requires": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + } + }, "call-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", @@ -2675,6 +2754,15 @@ "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", "dev": true }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, "cli-spinners": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", @@ -2732,6 +2820,18 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, + "co-body": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-5.2.0.tgz", + "integrity": "sha512-sX/LQ7LqUhgyaxzbe7IqwPeTr2yfpfUIQ/dgpKo6ZI4y4lpQA0YxAomWIY+7I7rHWcG02PG+OuPREzMW/5tszQ==", + "dev": true, + "requires": { + "inflation": "^2.0.0", + "qs": "^6.4.0", + "raw-body": "^2.2.0", + "type-is": "^1.6.14" + } + }, "coa": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", @@ -3048,6 +3148,24 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cookies": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", + "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==", + "dev": true, + "requires": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + } + } + }, "core-js": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.1.tgz", @@ -3091,6 +3209,39 @@ "vary": "^1" } }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "dependencies": { + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", @@ -3362,11 +3513,22 @@ "mimic-response": "^2.0.0" } }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" + }, "deep-diff": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", "integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=" }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -3586,6 +3748,26 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -4268,6 +4450,12 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4562,6 +4750,18 @@ "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, + "foreachasync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", + "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=", + "dev": true + }, + "formidable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", + "dev": true + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -4672,6 +4872,31 @@ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, + "gettext-parser": { + "version": "4.0.0-alpha.0", + "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-4.0.0-alpha.0.tgz", + "integrity": "sha512-s7udg3dOrlFtF/UREA/kkzT5Kj/C3C9lpr6oGx5F5LfIadXDntwgSWEGzJ869ROM0OnCsdmhcn+USXfLPpCXxA==", + "dev": true, + "requires": { + "content-type": "^1.0.4", + "encoding": "^0.1.12", + "readable-stream": "^3.2.0", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -4940,6 +5165,16 @@ "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", "dev": true }, + "http-assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.1.tgz", + "integrity": "sha512-rdw7q6GTlibqVVbXr0CKelfV5iY8G2HqEUkhSk297BMbSpSL8crXC+9rjKoMcZZEsksX30le6f/4ul4E28gegw==", + "dev": true, + "requires": { + "deep-equal": "~1.0.1", + "http-errors": "~1.7.2" + } + }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -4985,6 +5220,12 @@ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true }, + "hunspell-spellchecker": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hunspell-spellchecker/-/hunspell-spellchecker-1.0.2.tgz", + "integrity": "sha1-oQsL0voAplq2Kkxrc0zkltMYkQ4=", + "dev": true + }, "hyphenate-style-name": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", @@ -5128,6 +5369,12 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, + "inflation": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.0.0.tgz", + "integrity": "sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8=", + "dev": true + }, "inflection": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", @@ -5245,6 +5492,12 @@ "number-is-nan": "^1.0.0" } }, + "is-generator-function": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==", + "dev": true + }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -5350,6 +5603,12 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -5441,6 +5700,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -5472,6 +5737,156 @@ "object.assign": "^4.1.1" } }, + "keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dev": true, + "requires": { + "tsscmp": "1.0.6" + } + }, + "koa": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.13.1.tgz", + "integrity": "sha512-Lb2Dloc72auj5vK4X4qqL7B5jyDPQaZucc9sR/71byg7ryoD1NCaCm63CShk9ID9quQvDEi1bGR/iGjCG7As3w==", + "dev": true, + "requires": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.8.0", + "debug": "~3.1.0", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^1.2.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "koa-body": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/koa-body/-/koa-body-4.2.0.tgz", + "integrity": "sha512-wdGu7b9amk4Fnk/ytH8GuWwfs4fsB5iNkY8kZPpgQVb04QZSv85T0M8reb+cJmvLE8cjPYvBzRikD3s6qz8OoA==", + "dev": true, + "requires": { + "@types/formidable": "^1.0.31", + "co-body": "^5.1.1", + "formidable": "^1.1.1" + } + }, + "koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true + }, + "koa-convert": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-1.2.0.tgz", + "integrity": "sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=", + "dev": true, + "requires": { + "co": "^4.6.0", + "koa-compose": "^3.0.0" + }, + "dependencies": { + "koa-compose": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz", + "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=", + "dev": true, + "requires": { + "any-promise": "^1.1.0" + } + } + } + }, + "koa-router": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-9.4.0.tgz", + "integrity": "sha512-RO/Y8XqSNM2J5vQeDaBI/7iRpL50C9QEudY4d3T4D1A2VMKLH0swmfjxDFPiIpVDLuNN6mVD9zBI1eFTHB6QaA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.1.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "http-errors": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz", + "integrity": "sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "path-to-regexp": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz", + "integrity": "sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg==", + "dev": true + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + } + } + }, "kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -5525,6 +5940,12 @@ "immediate": "~3.0.5" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -5629,12 +6050,27 @@ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, + "lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", + "dev": true + }, "lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", "dev": true }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + } + }, "logform": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", @@ -6487,6 +6923,21 @@ } } }, + "only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=", + "dev": true + }, + "open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, "opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -6883,6 +7334,11 @@ "semver-compare": "^1.0.0" } }, + "plural-forms": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/plural-forms/-/plural-forms-0.5.3.tgz", + "integrity": "sha512-t/hkjsTeDwaK9n/z6tUiSHySTC8sPnTiS5YF3Y5p4L+eomzXh7O0vEemkjwb68/82w0Rjw4uED3X84X7vXf9lg==" + }, "postcss": { "version": "8.1.10", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.1.10.tgz", @@ -7320,6 +7776,12 @@ "util-deprecate": "~1.0.1" } }, + "readline-sync": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", + "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", + "dev": true + }, "readline2": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", @@ -7599,6 +8061,33 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } + } + }, "retry-as-promised": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", @@ -8253,6 +8742,12 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "svelte": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.32.0.tgz", + "integrity": "sha512-+EA3qfKDG0uB16s7m1z9Nc1o01G7YC4eq1cnHOzCy+fKsvGAJrjhjBIM3zCW2eZUu639UbHQElaOPQWUjBN3Yw==", + "dev": true + }, "svgo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", @@ -8614,6 +9109,15 @@ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -8676,6 +9180,391 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true + }, + "ttag": { + "version": "1.7.24", + "resolved": "https://registry.npmjs.org/ttag/-/ttag-1.7.24.tgz", + "integrity": "sha512-8H/0dS6VYqBXzVBCo8f4s48TMIkC9UrALfMkXsaNWqKo3P3UQzfE1KZXlBkrhZho2A1iJuxUgGzHSgQvkZwGmg==", + "requires": { + "dedent": "^0.7.0", + "plural-forms": "^0.5.3" + } + }, + "ttag-cli": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ttag-cli/-/ttag-cli-1.9.1.tgz", + "integrity": "sha512-MzyiyP18znJvpjf4lspyW8H+CIOZDYPcRl8FeM8KgT8DcYuWViAbPY7csmU0Wg4K5+0onScPz2HTDSsV9oHyYg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/generator": "^7.12.5", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-decorators": "^7.12.1", + "@babel/plugin-proposal-export-default-from": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "7.6.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/preset-env": "^7.12.1", + "@babel/preset-flow": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@babel/preset-typescript": "7.7.0", + "@babel/template": "^7.10.4", + "ansi": "^0.3.1", + "babel-plugin-ttag": "1.7.30", + "chalk": "^2.4.2", + "cross-spawn": "^5.1.0", + "estree-walker": "^2.0.1", + "gettext-parser": "4.0.0-alpha.0", + "hunspell-spellchecker": "^1.0.2", + "ignore": "^5.1.8", + "koa": "^2.13.0", + "koa-body": "^4.2.0", + "koa-router": "^9.1.0", + "mkdirp": "^0.5.1", + "node-fetch": "^2.6.1", + "open": "^6.4.0", + "ora": "1.3.0", + "plural-forms": "0.5.3", + "readline-sync": "^1.4.7", + "serialize-javascript": "^4.0.0", + "supports-color": "^5.0.1", + "svelte": "^3.20.1", + "tmp": "0.0.33", + "vue-sfc-parser": "^0.1.2", + "walk": "2.3.9", + "yargs": "^15.4.1" + }, + "dependencies": { + "@babel/plugin-proposal-optional-chaining": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.6.0.tgz", + "integrity": "sha512-kj4gkZ6qUggkprRq3Uh5KP8XnE1MdIO0J7MhdDX8+rAbB6dJ2UrensGIS+0NPZAaaJ1Vr0PN6oLUgXMU1uMcSg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.2.0" + } + }, + "@babel/preset-typescript": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.7.0.tgz", + "integrity": "sha512-WZ3qvtAJy8w/i6wqq5PuDnkCUXaLUTHIlJujfGHmHxsT5veAbEdEjl3cC/3nXfyD0bzlWsIiMdUhZgrXjd9QWg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.7.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cli-spinners": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", + "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ora": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-1.3.0.tgz", + "integrity": "sha1-gAeN0rkqk0r2ajrXKluRBpTt5Ro=", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.0.0", + "log-symbols": "^1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -8927,6 +9816,15 @@ "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", "dev": true }, + "vue-sfc-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/vue-sfc-parser/-/vue-sfc-parser-0.1.2.tgz", + "integrity": "sha512-fvYu4i5oxK4J25qYblmsotMINSY0KhP1LW/ElKaMin4CXQ2UqyjeUgAZaE2Zs1zYpIKGoEuMjEY+lmBghls1WQ==", + "dev": true, + "requires": { + "lodash.mapvalues": "^4.6.0" + } + }, "vue-template-compiler": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz", @@ -8937,6 +9835,15 @@ "he": "^1.1.0" } }, + "walk": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.9.tgz", + "integrity": "sha1-MbTbZnjyrgHDnqn7hyWpAx5Vins=", + "dev": true, + "requires": { + "foreachasync": "^3.0.0" + } + }, "walkdir": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.3.2.tgz", @@ -9612,6 +10519,12 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", @@ -9691,6 +10604,12 @@ } } }, + "ylru": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz", + "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 6d9e3ae..cbc81c1 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "sweetalert2": "^10.12.1", "three": "^0.123.0", "three-trackballcontrols": "^0.9.0", + "ttag": "^1.7.24", "url-search-params-polyfill": "^8.1.0", "winston": "^3.3.3", "winston-daily-rotate-file": "^4.5.0", @@ -115,6 +116,7 @@ "babel-loader": "^8.2.2", "babel-plugin-transform-react-pure-class-to-function": "^1.0.1", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", + "babel-plugin-ttag": "^1.7.30", "clean-css": "^4.2.3", "css-loader": "^5.0.1", "eslint": "^7.15.0", @@ -134,6 +136,7 @@ "react-svg-loader": "^3.0.3", "rimraf": "^3.0.2", "style-loader": "^2.0.0", + "ttag-cli": "^1.9.1", "webpack": "^5.10.0", "webpack-bundle-analyzer": "^4.2.0", "webpack-cli": "^4.2.0", diff --git a/scripts/bundle.js b/scripts/bundle.js index fed1b35..b527fed 100644 --- a/scripts/bundle.js +++ b/scripts/bundle.js @@ -7,27 +7,31 @@ * LICENSE.txt file in the root directory of this source tree. */ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable no-console */ + import fs from 'fs'; +import path from 'path'; import webpack from 'webpack'; import webpackConfigWeb from '../webpack.config.web.babel'; -import webpackConfigClient from '../webpack.config.client.babel'; +import { buildWebpackClientConfig } from '../webpack.config.client.babel'; const wpStats = { - colors: true, - reasons: false, - hash: false, - version: false, - timings: true, - chunks: true, - chunkModules: false, - cached: false, - cachedAssets: false, -} + colors: true, + reasons: false, + hash: false, + version: false, + timings: true, + chunks: true, + chunkModules: false, + cached: false, + cachedAssets: false, +}; /** * Creates application bundles from the source files. */ -function bundle() { +async function bundle() { try { /* fix image-q imports here * Pretty dirty, but we did write an issue and they might @@ -36,12 +40,21 @@ function bundle() { console.log('Patching image-q set-immediate import'); const regex = /core-js\/fn\/set-immediate/g; const files = [ - './node_modules/image-q/dist/esm/basicAPI.js', - './node_modules/image-q/dist/esm/helper.js', + path.resolve( + '..', 'node_modules', + 'image-q', 'dist', 'esm', 'basicAPI.js', + ), + path.resolve( + '..', 'node_modules', + 'image-q', 'dist', 'esm', 'helper.js', + ), ]; files.forEach((file) => { - let fileContent = fs.readFileSync(file,'utf8'); - fileContent = fileContent.replace(regex, 'core-js/features/set-immediate'); + let fileContent = fs.readFileSync(file, 'utf8'); + fileContent = fileContent.replace( + regex, + 'core-js/features/set-immediate', + ); fs.writeFileSync(file, fileContent); }); console.log('Patching image-q done'); @@ -50,8 +63,24 @@ function bundle() { } console.log('Bundle with webpack....'); + let webpackConfig = [ + webpackConfigWeb, + buildWebpackClientConfig(false, false, 'default'), + ] + + /* + * add other language configs + */ + const langDir = path.resolve(__dirname, '..', 'i18n'); + const langs = fs.readdirSync(langDir) + .filter((e) => e.endsWith('.po')) + .map((l) => l.slice(0, -3)); + webpackConfig = webpackConfig.concat( + langs.map((l) => buildWebpackClientConfig(false, false, l)), + ); + return new Promise((resolve, reject) => { - webpack([webpackConfigWeb, webpackConfigClient]).run((err, stats) => { + webpack(webpackConfig).run((err, stats) => { if (err) { return reject(err); } diff --git a/scripts/clean.js b/scripts/clean.js index abc7445..29062d8 100644 --- a/scripts/clean.js +++ b/scripts/clean.js @@ -5,7 +5,7 @@ import rimraf from 'rimraf'; import path from 'path'; -const builddir = path.resolve(__dirname, '../build'); +const builddir = path.resolve(__dirname, '..', 'build'); function clean() { diff --git a/scripts/copy.js b/scripts/copy.js index 486f226..3e2b01f 100644 --- a/scripts/copy.js +++ b/scripts/copy.js @@ -9,10 +9,10 @@ import path from 'path'; import glob from 'glob'; import mkdirp from 'mkdirp'; -const builddir = path.resolve(__dirname, '../build'); -const deploydir = path.resolve(__dirname, '../deployment'); -const publicdir = path.resolve(__dirname, '../public'); -const srcdir = path.resolve(__dirname, '../src'); +const builddir = path.resolve(__dirname, '..', 'build'); +const deploydir = path.resolve(__dirname, '..', 'deployment'); +const publicdir = path.resolve(__dirname, '..', 'public'); +const srcdir = path.resolve(__dirname, '..', 'src'); /* * following functions are copied from diff --git a/scripts/minifyCss.js b/scripts/minifyCss.js index 84f7d3e..d43ee10 100644 --- a/scripts/minifyCss.js +++ b/scripts/minifyCss.js @@ -9,10 +9,10 @@ import CleanCSS from 'clean-css'; import crypto from 'crypto'; const rootdir = path.resolve(__dirname, '..'); -const assetdir = path.resolve(__dirname, '../build/public/assets'); -const builddir = path.resolve(__dirname, '../build'); +const assetdir = path.resolve(__dirname, '..', 'build', 'public', 'assets'); +const builddir = path.resolve(__dirname, '..', 'build'); -const FOLDER = path.resolve(__dirname, '../src/styles'); +const FOLDER = path.resolve(__dirname, '..', 'src', 'styles'); const FILES = [ 'default.css', 'dark.css', diff --git a/src/components/ForgotPasswordModal.jsx b/src/components/ForgotPasswordModal.jsx index 273e44f..a9ac16e 100644 --- a/src/components/ForgotPasswordModal.jsx +++ b/src/components/ForgotPasswordModal.jsx @@ -5,6 +5,7 @@ import React from 'react'; import { connect } from 'react-redux'; +import { t } from 'ttag'; import { showUserAreaModal } from '../actions'; import NewPasswordForm from './NewPasswordForm'; @@ -16,7 +17,7 @@ const ForgotPasswordModal = ({ login }) => (


-

Consider joining us on Guilded:  +

{t`Consider joining us on Guilded:`}  pixelplanet.fun/guilded

diff --git a/src/components/Globe.jsx b/src/components/Globe.jsx index f5a11a9..afadb7b 100644 --- a/src/components/Globe.jsx +++ b/src/components/Globe.jsx @@ -29,20 +29,33 @@ const styles = [{ }]; const title = 'PixelPlanet.fun 3DGlobe'; -const description = '3D globe of our canvas'; -const scripts = [ - ASSET_SERVER + assets.three.js, - ASSET_SERVER + assets.globe.js, -]; +const description = 'pixelplanet globe'; +const defaultScripts = assets.globe.js.map( + (s) => ASSET_SERVER + s, +); const body = ; -const globeHtml = `${ReactDOM.renderToStaticMarkup( - , -)}`; -export default globeHtml; +/* + * generates string with html of globe page + * @param lang language code + * @return html of mainpage + */ +function generateGlobePage(lang: string): string { + const scripts = (assets[`globe-${lang}`]) + ? assets[`globe-${lang}`].js.map((s) => ASSET_SERVER + s) + : defaultScripts; + + const html = ReactDOM.renderToStaticMarkup( + , + ); + + return `${html}`; +} + +export default generateGlobePage; diff --git a/src/components/Main.jsx b/src/components/Main.jsx index b44df3b..96852b4 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -22,10 +22,9 @@ let code = `window.assetserver="${ASSET_SERVER}";window.availableStyles=JSON.par if (BACKUP_URL) { code += `window.backupurl="${BACKUP_URL}";`; } -const scripts = [ - ASSET_SERVER + assets.vendor.js, - ASSET_SERVER + assets.client.js, -]; +const defaultScripts = assets.client.js.map( + (s) => ASSET_SERVER + s, +); const css = [ { id: 'globcss', @@ -43,6 +42,9 @@ const css = [ */ function generateMainPage(countryCoords: Cell, lang: string): string { const [x, y] = countryCoords; + const scripts = (assets[`client-${lang}`]) + ? assets[`client-${lang}`].js.map((s) => ASSET_SERVER + s) + : defaultScripts; // eslint-disable-next-line const html = ReactDOM.renderToStaticMarkup( (

Register new account here


-

Consider joining us on Guilded:  +

{t`Consider joining us on Guilded:`}  pixelplanet.fun/guilded

diff --git a/src/components/UserAreaModal.jsx b/src/components/UserAreaModal.jsx index 659842d..0c633cf 100644 --- a/src/components/UserAreaModal.jsx +++ b/src/components/UserAreaModal.jsx @@ -5,6 +5,7 @@ import React, { Suspense } from 'react'; import { connect } from 'react-redux'; +import { t } from 'ttag'; import type { State } from '../reducers'; @@ -124,7 +125,7 @@ const UserAreaModal = ({ )} )} -

Consider joining us on Guilded:  +

{t`Consider joining us on Guilded:`}  pixelplanet.fun/guilded

diff --git a/src/web.js b/src/web.js index 89b0288..63600a8 100644 --- a/src/web.js +++ b/src/web.js @@ -26,7 +26,7 @@ import { admintools, resetPassword, } from './routes'; -import globeHtml from './components/Globe'; +import generateGlobePage from './components/Globe'; import generateMainPage from './components/Main'; import { SECOND, MONTH } from './core/constants'; @@ -142,7 +142,7 @@ app.use('/reset_password', resetPassword); // 3D Globe (react generated) // ----------------------------------------------------------------------------- const globeEtag = etag( - `${assets.globe.js}`, + assets.globe.js.join('_'), { weak: true }, ); app.get('/globe', async (req, res) => { @@ -157,7 +157,10 @@ app.get('/globe', async (req, res) => { return; } - res.status(200).send(globeHtml); + const language = req.headers['accept-language']; + const lang = (language) ? languageFromLocalisation(language) : 'en'; + + res.status(200).send(generateGlobePage(lang)); }); @@ -165,7 +168,7 @@ app.get('/globe', async (req, res) => { // Main Page (react generated) // ----------------------------------------------------------------------------- const indexEtag = etag( - `${assets.vendor.js},${assets.client.js}`, + assets.client.js.join('_'), { weak: true }, ); @@ -183,7 +186,7 @@ app.get('/', async (req, res) => { // get start coordinates based on cloudflare header country const country = req.headers['cf-ipcountry']; - let language = req.headers['accept-language']; + const language = req.headers['accept-language']; const lang = (language) ? languageFromLocalisation(language) : 'en'; const countryCoords = (country) ? ccToCoords(country) : [0, 0]; diff --git a/webpack.config.client.babel.js b/webpack.config.client.babel.js index 42c3b51..1da1ec5 100644 --- a/webpack.config.client.babel.js +++ b/webpack.config.client.babel.js @@ -8,166 +8,185 @@ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; import pkg from './package.json'; -const isDebug = process.argv.includes('--debug'); -const VERBOSE = false; -const isAnalyze = process.argv.includes('--analyze') - || process.argv.includes('--analyse'); +/* + * Emit a file with assets paths + */ +const assetPlugin = new AssetsPlugin({ + path: path.resolve(__dirname, 'build'), + filename: 'assets.json', + entrypoints: true, + prettyPrint: true, +}); +export function buildWebpackClientConfig(development, analyze, locale) { + const ttag = { + resolve: { + translations: (locale !== 'default') + ? path.resolve(__dirname, 'i18n', `${locale}.po`) + : locale, + }, + }; -const babelPlugins = [ - '@babel/transform-flow-strip-types', - ['@babel/plugin-proposal-decorators', { legacy: true }], - '@babel/plugin-proposal-function-sent', - '@babel/plugin-proposal-export-namespace-from', - '@babel/plugin-proposal-numeric-separator', - '@babel/plugin-proposal-throw-expressions', - ['@babel/plugin-proposal-class-properties', { loose: true }], - '@babel/proposal-object-rest-spread', - // react-optimize - '@babel/transform-react-constant-elements', - '@babel/transform-react-inline-elements', - 'transform-react-remove-prop-types', - 'transform-react-pure-class-to-function', -]; + const babelPlugins = [ + '@babel/transform-flow-strip-types', + ['@babel/plugin-proposal-decorators', { legacy: true }], + '@babel/plugin-proposal-function-sent', + '@babel/plugin-proposal-export-namespace-from', + '@babel/plugin-proposal-numeric-separator', + '@babel/plugin-proposal-throw-expressions', + ['@babel/plugin-proposal-class-properties', { loose: true }], + '@babel/proposal-object-rest-spread', + // react-optimize + '@babel/transform-react-constant-elements', + '@babel/transform-react-inline-elements', + 'transform-react-remove-prop-types', + 'transform-react-pure-class-to-function', + ['ttag', ttag], + ]; + return { + name: 'client', + target: 'web', -export default { - name: 'client', - target: 'web', + context: __dirname, + mode: (development) ? 'development' : 'production', + devtool: 'source-map', - context: __dirname, - mode: (isDebug) ? 'development' : 'production', - devtool: 'source-map', + entry: { + [(locale !== 'default') ? `client-${locale}` : 'client']: + ['./src/client.js'], + [(locale !== 'default') ? `globe-${locale}` : 'globe']: + ['./src/globe.js'], + }, - entry: { - client: ['./src/client.js'], - globe: ['./src/globe.js'], - }, + output: { + path: path.resolve(__dirname, 'build', 'public', 'assets'), + publicPath: '/assets/', + filename: '[name].[chunkhash:8].js', + chunkFilename: (locale !== 'default') + ? `[name]-${locale}.[chunkhash:8].js` + : '[name].[chunkhash:8].js', + }, - output: { - path: path.resolve(__dirname, './build/public/assets'), - publicPath: '/assets/', - pathinfo: VERBOSE, - filename: isDebug ? '[name].js' : '[name].[chunkhash:8].js', - chunkFilename: isDebug ? '[name].chunk.js' : '[name].[chunkhash:8].js', - }, - - resolve: { - extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'], - }, - - module: { - rules: [ - { - test: /\.svg$/, - use: [ - { - loader: 'babel-loader', - }, - { - loader: 'react-svg-loader', - options: { - svgo: { - plugins: [ - { - removeViewBox: false, - }, - { - removeDimensions: true, - }, - ], - }, - jsx: false, - }, - }, - ], + resolve: { + alias: { + ttag: 'ttag/dist/mock', }, - { - test: /\.(js|jsx|ts|tsx)$/, - loader: 'babel-loader', - include: [ - path.resolve(__dirname, './src'), - ], - options: { - cacheDirectory: isDebug, - babelrc: false, - presets: [ - ['@babel/preset-env', { - targets: { - browsers: pkg.browserslist, + extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'], + }, + + module: { + rules: [ + { + test: /\.svg$/, + use: [ + { + loader: 'babel-loader', + }, + { + loader: 'react-svg-loader', + options: { + svgo: { + plugins: [ + { + removeViewBox: false, + }, + { + removeDimensions: true, + }, + ], + }, + jsx: false, }, - modules: false, - useBuiltIns: 'usage', - corejs: { - version: 3, - }, - debug: false, - }], - '@babel/typescript', - '@babel/react', + }, ], - plugins: babelPlugins, }, - }, - { - test: /\.css/, - use: ['style-loader', - { - loader: 'css-loader', - options: { - sourceMap: isDebug, - modules: false, - }, + { + test: /\.(js|jsx|ts|tsx)$/, + loader: 'babel-loader', + include: [ + path.resolve(__dirname, 'src'), + ], + options: { + cacheDirectory: development, + babelrc: false, + presets: [ + ['@babel/preset-env', { + targets: { + browsers: pkg.browserslist, + }, + modules: false, + useBuiltIns: 'usage', + corejs: { + version: 3, + }, + debug: false, + }], + '@babel/typescript', + '@babel/react', + ], + plugins: babelPlugins, }, - ], - }, - ], - }, - - plugins: [ - // Define free variables - // https://webpack.github.io/docs/list-of-plugins.html#defineplugin - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': isDebug ? '"development"' : '"production"', - 'process.env.BROWSER': true, - }), - - // Emit a file with assets paths - // https://github.com/sporto/assets-webpack-plugin#options - new AssetsPlugin({ - path: path.resolve(__dirname, './build'), - filename: 'assets.json', - prettyPrint: true, - }), - - // Webpack Bundle Analyzer - // https://github.com/th0r/webpack-bundle-analyzer - ...isAnalyze ? [new BundleAnalyzerPlugin()] : [], - ], - - optimization: { - splitChunks: { - chunks: 'all', - name: false, - cacheGroups: { - default: false, - defaultVendors: false, - - vendor: { - name: 'vendor', - chunks: (chunk) => chunk.name === 'client', - test: /node_modules/, }, - three: { - test: /[\\/]node_modules[\\/]three[\\/]/, - name: 'three', - chunks: 'all', + { + test: /\.css/, + use: ['style-loader', + { + loader: 'css-loader', + options: { + sourceMap: development, + modules: false, + }, + }, + ], + }, + ], + }, + + plugins: [ + // Define free variables + // https://webpack.github.io/docs/list-of-plugins.html#defineplugin + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': development ? '"development"' : '"production"', + 'process.env.BROWSER': true, + }), + + assetPlugin, + + // Webpack Bundle Analyzer + // https://github.com/th0r/webpack-bundle-analyzer + ...analyze ? [new BundleAnalyzerPlugin({ analyzerPort: 8889 })] : [], + ], + + optimization: { + splitChunks: { + chunks: 'all', + name: false, + cacheGroups: { + default: false, + defaultVendors: false, + + vendor: { + name: 'vendor', + chunks: (chunk) => chunk.name.startsWith('client'), + test: /[\\/]node_modules[\\/]/, + }, + three: { + name: 'three', + chunks: 'all', + test: /[\\/]node_modules[\\/]three[\\/]/, + }, }, }, }, - }, - bail: !isDebug, + cache: true, + }; +} + +export default buildWebpackClientConfig( + process.argv.includes('--debug'), + process.argv.includes('--analyse') || process.argv.includes('--analyze'), + 'default', +); - cache: isDebug, -}; diff --git a/webpack.config.client.babel.js.old b/webpack.config.client.babel.js.old new file mode 100644 index 0000000..79bc387 --- /dev/null +++ b/webpack.config.client.babel.js.old @@ -0,0 +1,237 @@ +/** + */ + +import fs from 'fs'; +import path from 'path'; +import webpack from 'webpack'; +import AssetsPlugin from 'assets-webpack-plugin'; +import TtagWebpackPlugin from 'ttag-webpack-plugin'; +import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; + +import pkg from './package.json'; + +const isDebug = process.argv.includes('--debug'); +const VERBOSE = false; +const isAnalyze = process.argv.includes('--analyze') + || process.argv.includes('--analyse'); + +// activate for deprecation tracking +// process.traceDeprecation = true; + +const babelPlugins = [ + '@babel/transform-flow-strip-types', + ['@babel/plugin-proposal-decorators', { legacy: true }], + '@babel/plugin-proposal-function-sent', + '@babel/plugin-proposal-export-namespace-from', + '@babel/plugin-proposal-numeric-separator', + '@babel/plugin-proposal-throw-expressions', + ['@babel/plugin-proposal-class-properties', { loose: true }], + '@babel/proposal-object-rest-spread', + // react-optimize + '@babel/transform-react-constant-elements', + '@babel/transform-react-inline-elements', + 'transform-react-remove-prop-types', + 'transform-react-pure-class-to-function', +]; + +/* + * get all available languages + */ +const langDir = path.resolve(__dirname, 'i18n'); +const langs = fs.readdirSync(langDir) + .filter((e) => e.endsWith('.po')) + .map((l) => l.slice(0, -3)); + +/* + * create list of translations for ttag-webpack-plugin + */ +const translations = {}; +for (let i = 0; i < langs.length; i += 1) { + const lang = langs[i]; + translations[lang] = path.resolve(langDir, `${lang}.po`); +} + +/* + * Cache Groups for splitChunks + * (edit cache groups here, make sure that chunks is based on name) + */ +const cacheGroups = { + default: false, + defaultVendors: false, + + vendor: { + name: 'vendor', + chunks: (chunk) => chunk.name === 'client', + test: /[\\/]node_modules[\\/]/, + }, + three: { + name: 'three', + chunks: (chunk) => (chunk.name === 'globe' || chunk.name === 'voxel'), + test: /[\\/]node_modules[\\/]three[\\/]/, + }, +}; + + +/* + * automatically add Cache Groups for languages based on + * manually set cacheGroups + */ +const groups = Object.keys(cacheGroups); +for (let u = 0; u < groups.length; u += 1) { + const group = cacheGroups[groups[u]]; + if (!group.test) continue; + + for (let i = 0; i < langs.length; i += 1) { + const lang = langs[i]; + /* add lang */ + const key = `${groups[u]}-${lang}`; + const name = `${group.name}-${lang}`; + const { test, chunks } = group; + + cacheGroups[key] = { + name, + chunks: (chunk) => { + if (!chunk.name.endsWith(`-${lang}`)) { + return false; + } + return chunks({ + name: chunk.name.slice(0, -lang.length - 1), + }); + }, + test, + }; + } +} + + +export default { + name: 'client', + target: 'web', + + context: __dirname, + mode: (isDebug) ? 'development' : 'production', + devtool: 'source-map', + + entry: { + client: ['./src/client.js'], + globe: ['./src/globe.js'], + }, + + output: { + path: path.resolve(__dirname, 'build', 'public', 'assets'), + publicPath: '/assets/', + pathinfo: VERBOSE, + filename: isDebug ? '[name].js' : '[name].[chunkhash:8].js', + chunkFilename: isDebug ? '[name].chunk.js' : '[name].[chunkhash:8].js', + }, + + resolve: { + extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'], + }, + + module: { + rules: [ + { + test: /\.svg$/, + use: [ + { + loader: 'babel-loader', + }, + { + loader: 'react-svg-loader', + options: { + svgo: { + plugins: [ + { + removeViewBox: false, + }, + { + removeDimensions: true, + }, + ], + }, + jsx: false, + }, + }, + ], + }, + { + test: /\.(js|jsx|ts|tsx)$/, + loader: 'babel-loader', + include: [ + path.resolve(__dirname, 'src'), + ], + options: { + cacheDirectory: isDebug, + babelrc: false, + presets: [ + ['@babel/preset-env', { + targets: { + browsers: pkg.browserslist, + }, + modules: false, + useBuiltIns: 'usage', + corejs: { + version: 3, + }, + debug: false, + }], + '@babel/typescript', + '@babel/react', + ], + plugins: babelPlugins, + }, + }, + { + test: /\.css/, + use: ['style-loader', + { + loader: 'css-loader', + options: { + sourceMap: isDebug, + modules: false, + }, + }, + ], + }, + ], + }, + + plugins: [ + // Define free variables + // https://webpack.github.io/docs/list-of-plugins.html#defineplugin + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': isDebug ? '"development"' : '"production"', + 'process.env.BROWSER': true, + }), + + // make multiple bundles for each language + new TtagWebpackPlugin({ + translations, + }), + + // Emit a file with assets paths + // https://github.com/sporto/assets-webpack-plugin#options + new AssetsPlugin({ + path: path.resolve(__dirname, 'build'), + filename: 'assets.json', + prettyPrint: true, + }), + + // Webpack Bundle Analyzer + // https://github.com/th0r/webpack-bundle-analyzer + ...isAnalyze ? [new BundleAnalyzerPlugin()] : [], + ], + + optimization: { + splitChunks: { + chunks: 'all', + name: false, + cacheGroups, + }, + }, + + bail: !isDebug, + + cache: isDebug, +}; diff --git a/webpack.config.web.babel.js b/webpack.config.web.babel.js index 9ce3d1d..1be3495 100644 --- a/webpack.config.web.babel.js +++ b/webpack.config.web.babel.js @@ -9,7 +9,6 @@ import GeneratePackageJsonPlugin from 'generate-package-json-webpack-plugin'; import pkg from './package.json'; const isDebug = process.argv.includes('--debug'); -const VERBOSE = false; const basePackageValues = { name: pkg.name, @@ -54,8 +53,7 @@ export default { }, output: { - pathinfo: VERBOSE, - path: path.resolve(__dirname, './build'), + path: path.resolve(__dirname, 'build'), libraryTarget: 'commonjs2', }, @@ -69,7 +67,7 @@ export default { test: /\.(js|jsx|ts|tsx)$/, loader: 'babel-loader', include: [ - path.resolve(__dirname, './src'), + path.resolve(__dirname, 'src'), ], options: { cacheDirectory: isDebug, @@ -121,9 +119,8 @@ export default { }), // create package.json for deployment new GeneratePackageJsonPlugin(basePackageValues, { - debug: VERBOSE, sourcePackageFilenames: [ - path.resolve(__dirname, './package.json'), + path.resolve(__dirname, 'package.json'), ], }), ], @@ -133,8 +130,4 @@ export default { __filename: false, __dirname: false, }, - - bail: !isDebug, - - cache: isDebug, };