diff --git a/client-new/.gitignore b/client-new/.gitignore new file mode 100644 index 0000000..1191a30 --- /dev/null +++ b/client-new/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +*.lock \ No newline at end of file diff --git a/client-new/index.html b/client-new/index.html new file mode 100644 index 0000000..81a8889 --- /dev/null +++ b/client-new/index.html @@ -0,0 +1,26 @@ + + + + + + + + + + + LeagueStats.gg + + + + + +
+ + + + + \ No newline at end of file diff --git a/client-new/package-lock.json b/client-new/package-lock.json new file mode 100644 index 0000000..32b12b3 --- /dev/null +++ b/client-new/package-lock.json @@ -0,0 +1,1703 @@ +{ + "name": "leaguestats-frontend", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "leaguestats-frontend", + "version": "0.0.0", + "dependencies": { + "axios": "^1.5.0", + "plausible-tracker": "^0.3.8", + "portal-vue": "^2.1.7", + "vue": "^2.7.14", + "vue-content-loader": "^0.2.3", + "vue-meta": "^2.4.0", + "vue-router": "^3.6.5", + "vue-sticky-sidebar": "^1.0.5", + "vuex": "^3.6.2" + }, + "devDependencies": { + "@tailwindcss/custom-forms": "^0.2.1", + "@vitejs/plugin-vue2": "^2.2.0", + "autoprefixer": "^10.4.15", + "postcss": "^8.4.30", + "postcss-import": "^12.0.1", + "tailwindcss": "^1.9.6", + "vite": "^4.4.5" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@fullhuman/postcss-purgecss": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-2.3.0.tgz", + "integrity": "sha512-qnKm5dIOyPGJ70kPZ5jiz0I9foVOic0j+cOzNDoo8KoCf6HjicIZ99UfO2OmE7vCYSKAAepEwJtNzpiiZAh9xw==", + "dev": true, + "dependencies": { + "postcss": "7.0.32", + "purgecss": "^2.3.0" + } + }, + "node_modules/@fullhuman/postcss-purgecss/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@fullhuman/postcss-purgecss/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@fullhuman/postcss-purgecss/node_modules/chalk/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@fullhuman/postcss-purgecss/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@fullhuman/postcss-purgecss/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@fullhuman/postcss-purgecss/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@fullhuman/postcss-purgecss/node_modules/postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + }, + "node_modules/@fullhuman/postcss-purgecss/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@tailwindcss/custom-forms": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/custom-forms/-/custom-forms-0.2.1.tgz", + "integrity": "sha512-XdP5XY6kxo3x5o50mWUyoYWxOPV16baagLoZ5uM41gh6IhXzhz/vJYzqrTb/lN58maGIKlpkxgVsQUNSsbAS3Q==", + "dev": true, + "dependencies": { + "lodash": "^4.17.11", + "mini-svg-data-uri": "^1.0.3", + "traverse": "^0.6.6" + }, + "peerDependencies": { + "tailwindcss": "^1.0" + } + }, + "node_modules/@vitejs/plugin-vue2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue2/-/plugin-vue2-2.2.0.tgz", + "integrity": "sha512-1km7zEuZ/9QRPvzXSjikbTYGQPG86Mq1baktpC4sXqsXlb02HQKfi+fl8qVS703JM7cgm24Ga9j+RwKmvFn90A==", + "dev": true, + "engines": { + "node": "^14.18.0 || >= 16.0.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0", + "vue": "^2.7.0-0" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "2.7.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz", + "integrity": "sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==", + "dependencies": { + "@babel/parser": "^7.18.4", + "postcss": "^8.4.14", + "source-map": "^0.6.1" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/autoprefixer": { + "version": "10.4.15", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz", + "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001520", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", + "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/babel-helper-vue-jsx-merge-props": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz", + "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001534", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz", + "integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/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 + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==", + "dev": true + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dev": true, + "dependencies": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.520", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.520.tgz", + "integrity": "sha512-Frfus2VpYADsrh1lB3v/ft/WVFlVzOIm+Q0p7U7VqHI6qr7NWHYKe+Wif3W50n7JAFoBsWVsoU0+qDks6WQ60g==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", + "integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==", + "dev": true + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/plausible-tracker": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/plausible-tracker/-/plausible-tracker-0.3.8.tgz", + "integrity": "sha512-lmOWYQ7s9KOUJ1R+YTOR3HrjdbxIS2Z4de0P/Jx2dQPteznJl2eX3tXxKClpvbfyGP59B5bbhW8ftN59HbbFSg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/portal-vue": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.7.tgz", + "integrity": "sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g==", + "peerDependencies": { + "vue": "^2.5.18" + } + }, + "node_modules/postcss": { + "version": "8.4.30", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz", + "integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-functions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz", + "integrity": "sha512-N5yWXWKA+uhpLQ9ZhBRl2bIAdM6oVJYpDojuI1nF2SzXBimJcdjFwiAouBVbO5VuOF3qA6BSFWFc3wXbbj72XQ==", + "dev": true, + "dependencies": { + "glob": "^7.1.2", + "object-assign": "^4.1.1", + "postcss": "^6.0.9", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/postcss-functions/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-functions/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-functions/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/postcss-functions/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/postcss-functions/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-functions/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-functions/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-import": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", + "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", + "dev": true, + "dependencies": { + "postcss": "^7.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-import/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/postcss-import/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-import/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-2.0.3.tgz", + "integrity": "sha512-zS59pAk3deu6dVHyrGqmC3oDXBdNdajk4k1RyxeVXCrcEDBUBHoIhE4QTsmhxgzXxsaqFDAkUZfmMa5f/N/79w==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1", + "postcss": "^7.0.18" + } + }, + "node_modules/postcss-js/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/postcss-js/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-nested": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.3.tgz", + "integrity": "sha512-rOv0W1HquRCamWy2kFl3QazJMMe1ku6rCFoAAH+9AcxdbpDeBr6k968MLWuLjvjMcGEip01ak09hKOEgpK9hvw==", + "dev": true, + "dependencies": { + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2" + } + }, + "node_modules/postcss-nested/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/postcss-nested/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/purgecss": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-2.3.0.tgz", + "integrity": "sha512-BE5CROfVGsx2XIhxGuZAT7rTH9lLeQx/6M0P7DTXQH4IUc3BBzs9JUzt4yzGf3JrH9enkeq6YJBe9CTtkm1WmQ==", + "dev": true, + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.0.0", + "postcss": "7.0.32", + "postcss-selector-parser": "^6.0.2" + }, + "bin": { + "purgecss": "bin/purgecss" + } + }, + "node_modules/purgecss/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/purgecss/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/purgecss/node_modules/chalk/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/purgecss/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/purgecss/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/purgecss/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/purgecss/node_modules/postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + }, + "node_modules/purgecss/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "dev": true, + "dependencies": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/reduce-css-calc/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "3.29.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.1.tgz", + "integrity": "sha512-c+ebvQz0VIH4KhhCpDsI+Bik0eT8ZFEVZEYw0cGMVqIP8zc+gnwl7iXCamTw7vzv2MeuZFZfdx5JJIq+ehzDlg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sticky-sidebar-v2": { + "version": "1.0.1", + "resolved": "git+ssh://git@github.com/Alucard17/sticky-sidebar-v2.git#acd8ea6cffb2cfdaae06c59acf292288714a92f1", + "license": "The MIT License (MIT)" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.9.6.tgz", + "integrity": "sha512-nY8WYM/RLPqGsPEGEV2z63riyQPcHYZUJpAwdyBzVpxQHOHqHE+F/fvbCeXhdF1+TA5l72vSkZrtYCB9hRcwkQ==", + "dev": true, + "dependencies": { + "@fullhuman/postcss-purgecss": "^2.1.2", + "autoprefixer": "^9.4.5", + "browserslist": "^4.12.0", + "bytes": "^3.0.0", + "chalk": "^3.0.0 || ^4.0.0", + "color": "^3.1.2", + "detective": "^5.2.0", + "fs-extra": "^8.0.0", + "html-tags": "^3.1.0", + "lodash": "^4.17.20", + "node-emoji": "^1.8.1", + "normalize.css": "^8.0.1", + "object-hash": "^2.0.3", + "postcss": "^7.0.11", + "postcss-functions": "^3.0.0", + "postcss-js": "^2.0.0", + "postcss-nested": "^4.1.1", + "postcss-selector-parser": "^6.0.0", + "postcss-value-parser": "^4.1.0", + "pretty-hrtime": "^1.0.3", + "reduce-css-calc": "^2.1.6", + "resolve": "^1.14.2" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/tailwindcss/node_modules/autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dev": true, + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/tailwindcss/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/tailwindcss/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/traverse": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vite": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "2.7.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.14.tgz", + "integrity": "sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==", + "dependencies": { + "@vue/compiler-sfc": "2.7.14", + "csstype": "^3.1.0" + } + }, + "node_modules/vue-content-loader": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vue-content-loader/-/vue-content-loader-0.2.3.tgz", + "integrity": "sha512-gJlNEdXkuHGvgnyY0lBMsrSsOMk+TTog5uNAil5MSLv08f/mE7Apag0VavpxJ6ieb4P5J1iVKEIhHI41HQNq9Q==", + "dependencies": { + "babel-helper-vue-jsx-merge-props": "^2.0.3" + } + }, + "node_modules/vue-meta": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/vue-meta/-/vue-meta-2.4.0.tgz", + "integrity": "sha512-XEeZUmlVeODclAjCNpWDnjgw+t3WA6gdzs6ENoIAgwO1J1d5p1tezDhtteLUFwcaQaTtayRrsx7GL6oXp/m2Jw==", + "dependencies": { + "deepmerge": "^4.2.2" + } + }, + "node_modules/vue-router": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz", + "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==" + }, + "node_modules/vue-sticky-sidebar": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vue-sticky-sidebar/-/vue-sticky-sidebar-1.0.5.tgz", + "integrity": "sha512-lYCBNzQgYSGYQr3fJTGBz8qiFuLaMvU+RMrcqeHUe16e2BzOYAzczyKbLu1xvTZ/0WXdkhaDCuo4DIIFSfXTOg==", + "dependencies": { + "sticky-sidebar-v2": "git+https://github.com/Alucard17/sticky-sidebar-v2.git" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "vue": "^2.6.11" + } + }, + "node_modules/vuex": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", + "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==", + "peerDependencies": { + "vue": "^2.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/client-new/package.json b/client-new/package.json new file mode 100644 index 0000000..e031d8c --- /dev/null +++ b/client-new/package.json @@ -0,0 +1,30 @@ +{ + "name": "leaguestats-frontend", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview --port 8080" + }, + "devDependencies": { + "@tailwindcss/custom-forms": "^0.2.1", + "@vitejs/plugin-vue2": "^2.2.0", + "autoprefixer": "^10.4.15", + "postcss": "^8.4.30", + "postcss-import": "^12.0.1", + "tailwindcss": "^1.9.6", + "vite": "^4.4.5" + }, + "dependencies": { + "axios": "^1.5.0", + "plausible-tracker": "^0.3.8", + "portal-vue": "^2.1.7", + "vue": "^2.7.14", + "vue-content-loader": "^0.2.3", + "vue-meta": "^2.4.0", + "vue-router": "^3.6.5", + "vue-sticky-sidebar": "^1.0.5", + "vuex": "^3.6.2" + } +} diff --git a/client-new/postcss.config.cjs b/client-new/postcss.config.cjs new file mode 100644 index 0000000..8567b4c --- /dev/null +++ b/client-new/postcss.config.cjs @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; \ No newline at end of file diff --git a/client-new/public/_redirects b/client-new/public/_redirects new file mode 100644 index 0000000..50a4633 --- /dev/null +++ b/client-new/public/_redirects @@ -0,0 +1 @@ +/* /index.html 200 \ No newline at end of file diff --git a/client-new/public/android-chrome-192x192.png b/client-new/public/android-chrome-192x192.png new file mode 100644 index 0000000..c97c972 Binary files /dev/null and b/client-new/public/android-chrome-192x192.png differ diff --git a/client-new/public/android-chrome-256x256.png b/client-new/public/android-chrome-256x256.png new file mode 100644 index 0000000..3ad5cf6 Binary files /dev/null and b/client-new/public/android-chrome-256x256.png differ diff --git a/client-new/public/apple-touch-icon.png b/client-new/public/apple-touch-icon.png new file mode 100644 index 0000000..2dff149 Binary files /dev/null and b/client-new/public/apple-touch-icon.png differ diff --git a/client-new/public/browserconfig.xml b/client-new/public/browserconfig.xml new file mode 100644 index 0000000..c83ddcf --- /dev/null +++ b/client-new/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #38b2ac + + + diff --git a/client-new/public/favicon-16x16.png b/client-new/public/favicon-16x16.png new file mode 100644 index 0000000..2ef7cd0 Binary files /dev/null and b/client-new/public/favicon-16x16.png differ diff --git a/client-new/public/favicon-32x32.png b/client-new/public/favicon-32x32.png new file mode 100644 index 0000000..74d4f76 Binary files /dev/null and b/client-new/public/favicon-32x32.png differ diff --git a/client-new/public/favicon.ico b/client-new/public/favicon.ico new file mode 100644 index 0000000..6629821 Binary files /dev/null and b/client-new/public/favicon.ico differ diff --git a/client-new/public/img/Logo.svg b/client-new/public/img/Logo.svg new file mode 100644 index 0000000..e7bffb9 --- /dev/null +++ b/client-new/public/img/Logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/client-new/public/img/bg-homepage-1.jpg b/client-new/public/img/bg-homepage-1.jpg new file mode 100644 index 0000000..6447e2f Binary files /dev/null and b/client-new/public/img/bg-homepage-1.jpg differ diff --git a/client-new/public/img/roles/BOTTOM.png b/client-new/public/img/roles/BOTTOM.png new file mode 100644 index 0000000..93c8c84 Binary files /dev/null and b/client-new/public/img/roles/BOTTOM.png differ diff --git a/client-new/public/img/roles/JUNGLE.png b/client-new/public/img/roles/JUNGLE.png new file mode 100644 index 0000000..fa52eeb Binary files /dev/null and b/client-new/public/img/roles/JUNGLE.png differ diff --git a/client-new/public/img/roles/MIDDLE.png b/client-new/public/img/roles/MIDDLE.png new file mode 100644 index 0000000..5b62066 Binary files /dev/null and b/client-new/public/img/roles/MIDDLE.png differ diff --git a/client-new/public/img/roles/TOP.png b/client-new/public/img/roles/TOP.png new file mode 100644 index 0000000..3bdc961 Binary files /dev/null and b/client-new/public/img/roles/TOP.png differ diff --git a/client-new/public/img/roles/UTILITY.png b/client-new/public/img/roles/UTILITY.png new file mode 100644 index 0000000..a55a20b Binary files /dev/null and b/client-new/public/img/roles/UTILITY.png differ diff --git a/client-new/public/img/runes/domination.jpg b/client-new/public/img/runes/domination.jpg new file mode 100644 index 0000000..0495784 Binary files /dev/null and b/client-new/public/img/runes/domination.jpg differ diff --git a/client-new/public/img/runes/inspiration.jpg b/client-new/public/img/runes/inspiration.jpg new file mode 100644 index 0000000..e392a4b Binary files /dev/null and b/client-new/public/img/runes/inspiration.jpg differ diff --git a/client-new/public/img/runes/precision.jpg b/client-new/public/img/runes/precision.jpg new file mode 100644 index 0000000..fb983ba Binary files /dev/null and b/client-new/public/img/runes/precision.jpg differ diff --git a/client-new/public/img/runes/resolve.jpg b/client-new/public/img/runes/resolve.jpg new file mode 100644 index 0000000..2bbf082 Binary files /dev/null and b/client-new/public/img/runes/resolve.jpg differ diff --git a/client-new/public/img/runes/sorcery.jpg b/client-new/public/img/runes/sorcery.jpg new file mode 100644 index 0000000..ba50d81 Binary files /dev/null and b/client-new/public/img/runes/sorcery.jpg differ diff --git a/client-new/public/index.html b/client-new/public/index.html new file mode 100644 index 0000000..73e5cc1 --- /dev/null +++ b/client-new/public/index.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + LeagueStats.gg + + + + + +
+ + + + \ No newline at end of file diff --git a/client-new/public/mstile-150x150.png b/client-new/public/mstile-150x150.png new file mode 100644 index 0000000..5690ed7 Binary files /dev/null and b/client-new/public/mstile-150x150.png differ diff --git a/client-new/public/robots.txt b/client-new/public/robots.txt new file mode 100644 index 0000000..75fc1a1 --- /dev/null +++ b/client-new/public/robots.txt @@ -0,0 +1,3 @@ +user-agent: * +Allow: /$ +Disallow: / diff --git a/client-new/public/safari-pinned-tab.svg b/client-new/public/safari-pinned-tab.svg new file mode 100644 index 0000000..bfe7da5 --- /dev/null +++ b/client-new/public/safari-pinned-tab.svg @@ -0,0 +1,36 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + + + + diff --git a/client-new/public/site.webmanifest b/client-new/public/site.webmanifest new file mode 100644 index 0000000..de65106 --- /dev/null +++ b/client-new/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/client-new/src/App.vue b/client-new/src/App.vue new file mode 100644 index 0000000..dcefdcf --- /dev/null +++ b/client-new/src/App.vue @@ -0,0 +1,47 @@ + + + diff --git a/client-new/src/assets/css/base.css b/client-new/src/assets/css/base.css new file mode 100644 index 0000000..3b8eb10 --- /dev/null +++ b/client-new/src/assets/css/base.css @@ -0,0 +1,77 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap'); + +::-webkit-scrollbar { + width: 8px; + height: 8px +} + +::-webkit-scrollbar, +::-webkit-scrollbar-track { + background: rgba(23, 49, 79, .6); +} + +.light-scrollbar::-webkit-scrollbar, +.light-scrollbar::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background-color: rgba(194, 217, 254, .6); + border-radius: 8px +} + +::selection { + @apply text-white bg-blue-1000; +} + +::-moz-selection { + @apply text-white bg-blue-1000; +} + +.min-w-1200 { + min-width: 1200px;; +} + +.page-wrapper { + width: 1200px; +} + +button:focus { + outline: 0; +} + +.vertical-center { + top: 50%; + transform: translateY(-50%); +} + +.horizontal-center { + left: 0; + right: 0; + margin: 0 auto; +} + +.bg-gradient { + background: linear-gradient(180deg, #2C5282 0%, rgba(44, 82, 130, 0) 100%); +} + +.bg-gradient-x { + background: linear-gradient(270deg, rgba(44,82,130,1) 0%, rgba(44,82,130,0) 100%); +} + +.text-overflow { + text-overflow: ellipsis; +} + +.heading { + background: linear-gradient( + to top, + rgb(34, 92, 155) 0%, + rgb(34, 92, 135) 100% + ); + box-shadow: rgba(235, 248, 255, 0.1) 0px -1px inset; +} + +.input-color { + background: rgba(23, 49, 79, 0.6); +} diff --git a/client-new/src/assets/css/main.css b/client-new/src/assets/css/main.css new file mode 100644 index 0000000..47e9dc6 --- /dev/null +++ b/client-new/src/assets/css/main.css @@ -0,0 +1,4 @@ +@import 'tailwind.css'; +@import 'base.css'; +@import 'transition.css'; +@import 'match.css'; diff --git a/client-new/src/assets/css/match.css b/client-new/src/assets/css/match.css new file mode 100644 index 0000000..bd9f24a --- /dev/null +++ b/client-new/src/assets/css/match.css @@ -0,0 +1,52 @@ +/* purgecss start ignore */ +.Win { + background-image: linear-gradient( + 90deg, + rgba(1, 97, 28, 0.3) 0%, + rgba(44, 82, 130, 0) 45% + ); +} + +.Fail { + background-image: linear-gradient( + 90deg, + rgba(140, 0, 0, 0.3) 0%, + rgba(44, 82, 130, 0) 45% + ); +} + +.Remake { + background-image: linear-gradient( + 90deg, + rgba(233, 169, 75, 0.3) 0%, + rgba(44, 82, 130, 0) 45% + ); +} + +.ban::after { + content: ""; + position: absolute; + left: 0px; + top: 50%; + width: calc(100% + 1px); + height: 2px; + transform: rotate(-45deg); +} + +.ban-blue::after { + background: #38b2ac; +} + +.ban-red::after { + background: #f56565; +} + +.ban-img { + filter: grayscale(100%); +} + +.ban-order { + left: -7px; + top: -5px; +} +/* purgecss end ignore */ diff --git a/client-new/src/assets/css/tailwind.css b/client-new/src/assets/css/tailwind.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/client-new/src/assets/css/tailwind.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/client-new/src/assets/css/transition.css b/client-new/src/assets/css/transition.css new file mode 100644 index 0000000..6ca5916 --- /dev/null +++ b/client-new/src/assets/css/transition.css @@ -0,0 +1,88 @@ +/* purgecss start ignore */ + +/* Fade transitions */ +.fade-enter-active, .fade-leave-active { + transition: opacity 2s; +} + +.fade-fast-enter-active, .fade-fast-leave-active { + transition: opacity .3s; +} + +.fade-fast-enter, .fade-fast-leave-to, +.fade-enter, .fade-leave-to { + opacity: 0; +} + +/* Slide fade transition (match details) */ +.slide-fade-enter-active, +.slide-fade-leave-active { + transition: all 0.4s; +} + +.slide-fade-enter, +.slide-fade-leave-to { + transform: translateX(400px); + opacity: 0; +} + +/* Tab transition */ +.tab-enter-active { + @apply transition duration-500 ease-in-out; +} + +.tab-enter, .tab-enter-leave-to { + @apply opacity-0; +} + +.tab-enter-to, .tab-enter-leave { + @apply opacity-100; +} + +/* Scale-fade transition */ +.scale-fade-enter-active { + @apply transition-all duration-75 ease-out transform; +} + +.scale-fade-leave-active { + @apply transition-all duration-75 ease-in transform; +} + +.scale-fade-enter, +.scale-fade-leave-to { + @apply scale-90 opacity-0; +} + +.scale-fade-enter-to, +.scale-fade-leave { + @apply scale-100 opacity-100; +} + +/* Grow transition (ripples) */ +.grow-enter-active, +.grow-enter-to-active { + transition: all 1500ms ease-out; +} + +.grow-leave-active, +.grow-leave-to-active { + transition: all 700ms ease-out; +} + +.grow-enter { + transform: scale(0); + opacity: 1; +} + +.grow-enter-to, +.grow-leave { + transform: scale(4); + opacity: 1; +} + +.grow-leave-to { + transform: scale(4); + opacity: 0; +} + +/* purgecss end ignore */ diff --git a/client-new/src/components/Common/CubeLoader.vue b/client-new/src/components/Common/CubeLoader.vue new file mode 100644 index 0000000..4736278 --- /dev/null +++ b/client-new/src/components/Common/CubeLoader.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/client-new/src/components/Common/DotsLoader.vue b/client-new/src/components/Common/DotsLoader.vue new file mode 100644 index 0000000..c1a80d6 --- /dev/null +++ b/client-new/src/components/Common/DotsLoader.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/client-new/src/components/Common/LazyBackgroundImage.vue b/client-new/src/components/Common/LazyBackgroundImage.vue new file mode 100644 index 0000000..4b2212b --- /dev/null +++ b/client-new/src/components/Common/LazyBackgroundImage.vue @@ -0,0 +1,74 @@ + + + diff --git a/client-new/src/components/Common/Ripple.vue b/client-new/src/components/Common/Ripple.vue new file mode 100644 index 0000000..8cbb00e --- /dev/null +++ b/client-new/src/components/Common/Ripple.vue @@ -0,0 +1,77 @@ + + + diff --git a/client-new/src/components/Common/Tooltip.vue b/client-new/src/components/Common/Tooltip.vue new file mode 100644 index 0000000..ee98dfa --- /dev/null +++ b/client-new/src/components/Common/Tooltip.vue @@ -0,0 +1,106 @@ + + + \ No newline at end of file diff --git a/client-new/src/components/Form/LoadingButton.vue b/client-new/src/components/Form/LoadingButton.vue new file mode 100644 index 0000000..108803b --- /dev/null +++ b/client-new/src/components/Form/LoadingButton.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/client-new/src/components/Form/SearchForm.vue b/client-new/src/components/Form/SearchForm.vue new file mode 100644 index 0000000..6227856 --- /dev/null +++ b/client-new/src/components/Form/SearchForm.vue @@ -0,0 +1,192 @@ + + + + + diff --git a/client-new/src/components/Form/SearchFormDropdown.vue b/client-new/src/components/Form/SearchFormDropdown.vue new file mode 100644 index 0000000..6a96ef2 --- /dev/null +++ b/client-new/src/components/Form/SearchFormDropdown.vue @@ -0,0 +1,282 @@ + + + + + diff --git a/client-new/src/components/Form/SearchFormDropdownPlayer.vue b/client-new/src/components/Form/SearchFormDropdownPlayer.vue new file mode 100644 index 0000000..9c3cb16 --- /dev/null +++ b/client-new/src/components/Form/SearchFormDropdownPlayer.vue @@ -0,0 +1,86 @@ + + + diff --git a/client-new/src/components/Form/SearchFormRegion.vue b/client-new/src/components/Form/SearchFormRegion.vue new file mode 100644 index 0000000..e27d110 --- /dev/null +++ b/client-new/src/components/Form/SearchFormRegion.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/client-new/src/components/Form/SwitchToggle.vue b/client-new/src/components/Form/SwitchToggle.vue new file mode 100644 index 0000000..6c79f13 --- /dev/null +++ b/client-new/src/components/Form/SwitchToggle.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/client-new/src/components/Global/NotificationsContainer.vue b/client-new/src/components/Global/NotificationsContainer.vue new file mode 100644 index 0000000..baf8766 --- /dev/null +++ b/client-new/src/components/Global/NotificationsContainer.vue @@ -0,0 +1,24 @@ + + + diff --git a/client-new/src/components/Global/PopupNotification.vue b/client-new/src/components/Global/PopupNotification.vue new file mode 100644 index 0000000..b490a02 --- /dev/null +++ b/client-new/src/components/Global/PopupNotification.vue @@ -0,0 +1,69 @@ + + + diff --git a/client-new/src/components/Global/SVGContainer.vue b/client-new/src/components/Global/SVGContainer.vue new file mode 100644 index 0000000..695acbb --- /dev/null +++ b/client-new/src/components/Global/SVGContainer.vue @@ -0,0 +1,35 @@ + diff --git a/client-new/src/components/Layout/MainFooter.vue b/client-new/src/components/Layout/MainFooter.vue new file mode 100644 index 0000000..d98dffb --- /dev/null +++ b/client-new/src/components/Layout/MainFooter.vue @@ -0,0 +1,163 @@ + + + diff --git a/client-new/src/components/Match/DetailedMatch.vue b/client-new/src/components/Match/DetailedMatch.vue new file mode 100644 index 0000000..5dfd121 --- /dev/null +++ b/client-new/src/components/Match/DetailedMatch.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/client-new/src/components/Match/DetailedMatchGlobalStats.vue b/client-new/src/components/Match/DetailedMatchGlobalStats.vue new file mode 100644 index 0000000..00627e7 --- /dev/null +++ b/client-new/src/components/Match/DetailedMatchGlobalStats.vue @@ -0,0 +1,106 @@ + + + diff --git a/client-new/src/components/Match/DetailedMatchTeam.vue b/client-new/src/components/Match/DetailedMatchTeam.vue new file mode 100644 index 0000000..df7dbe5 --- /dev/null +++ b/client-new/src/components/Match/DetailedMatchTeam.vue @@ -0,0 +1,482 @@ + + + + + diff --git a/client-new/src/components/Match/LiveMatch.vue b/client-new/src/components/Match/LiveMatch.vue new file mode 100644 index 0000000..82f4e1f --- /dev/null +++ b/client-new/src/components/Match/LiveMatch.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/client-new/src/components/Match/Match.vue b/client-new/src/components/Match/Match.vue new file mode 100644 index 0000000..94c40c5 --- /dev/null +++ b/client-new/src/components/Match/Match.vue @@ -0,0 +1,279 @@ + + + + + diff --git a/client-new/src/components/Match/MatchItems.vue b/client-new/src/components/Match/MatchItems.vue new file mode 100644 index 0000000..117af82 --- /dev/null +++ b/client-new/src/components/Match/MatchItems.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/client-new/src/components/Match/Runes/RuneStyle.vue b/client-new/src/components/Match/Runes/RuneStyle.vue new file mode 100644 index 0000000..35f233c --- /dev/null +++ b/client-new/src/components/Match/Runes/RuneStyle.vue @@ -0,0 +1,195 @@ + + + + + diff --git a/client-new/src/components/Match/Runes/RunesContainer.vue b/client-new/src/components/Match/Runes/RunesContainer.vue new file mode 100644 index 0000000..2c7b596 --- /dev/null +++ b/client-new/src/components/Match/Runes/RunesContainer.vue @@ -0,0 +1,104 @@ + + + diff --git a/client-new/src/components/Summoner/Champions/ChampionsSearch.vue b/client-new/src/components/Summoner/Champions/ChampionsSearch.vue new file mode 100644 index 0000000..5d8a6f1 --- /dev/null +++ b/client-new/src/components/Summoner/Champions/ChampionsSearch.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/client-new/src/components/Summoner/Champions/ChampionsTable.vue b/client-new/src/components/Summoner/Champions/ChampionsTable.vue new file mode 100644 index 0000000..fea7307 --- /dev/null +++ b/client-new/src/components/Summoner/Champions/ChampionsTable.vue @@ -0,0 +1,365 @@ + + + + + diff --git a/client-new/src/components/Summoner/Champions/FilterQueue.vue b/client-new/src/components/Summoner/Champions/FilterQueue.vue new file mode 100644 index 0000000..3285f38 --- /dev/null +++ b/client-new/src/components/Summoner/Champions/FilterQueue.vue @@ -0,0 +1,55 @@ + + + diff --git a/client-new/src/components/Summoner/Champions/OnlyMostPlayed.vue b/client-new/src/components/Summoner/Champions/OnlyMostPlayed.vue new file mode 100644 index 0000000..f0999ae --- /dev/null +++ b/client-new/src/components/Summoner/Champions/OnlyMostPlayed.vue @@ -0,0 +1,48 @@ + + + diff --git a/client-new/src/components/Summoner/FilterSeason.vue b/client-new/src/components/Summoner/FilterSeason.vue new file mode 100644 index 0000000..e9d96f8 --- /dev/null +++ b/client-new/src/components/Summoner/FilterSeason.vue @@ -0,0 +1,62 @@ + + + diff --git a/client-new/src/components/Summoner/HeaderLoader.vue b/client-new/src/components/Summoner/HeaderLoader.vue new file mode 100644 index 0000000..8bdf4f7 --- /dev/null +++ b/client-new/src/components/Summoner/HeaderLoader.vue @@ -0,0 +1,163 @@ + + + diff --git a/client-new/src/components/Summoner/Live/LiveTeam.vue b/client-new/src/components/Summoner/Live/LiveTeam.vue new file mode 100644 index 0000000..9b39f84 --- /dev/null +++ b/client-new/src/components/Summoner/Live/LiveTeam.vue @@ -0,0 +1,322 @@ + + + + + diff --git a/client-new/src/components/Summoner/Overview/OverviewLoader.vue b/client-new/src/components/Summoner/Overview/OverviewLoader.vue new file mode 100644 index 0000000..1567085 --- /dev/null +++ b/client-new/src/components/Summoner/Overview/OverviewLoader.vue @@ -0,0 +1,268 @@ + + + diff --git a/client-new/src/components/Summoner/Overview/SummonerChampions.vue b/client-new/src/components/Summoner/Overview/SummonerChampions.vue new file mode 100644 index 0000000..399a407 --- /dev/null +++ b/client-new/src/components/Summoner/Overview/SummonerChampions.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/client-new/src/components/Summoner/Overview/SummonerMates.vue b/client-new/src/components/Summoner/Overview/SummonerMates.vue new file mode 100644 index 0000000..cacb103 --- /dev/null +++ b/client-new/src/components/Summoner/Overview/SummonerMates.vue @@ -0,0 +1,106 @@ + + + diff --git a/client-new/src/components/Summoner/Overview/SummonerStats.vue b/client-new/src/components/Summoner/Overview/SummonerStats.vue new file mode 100644 index 0000000..07028b1 --- /dev/null +++ b/client-new/src/components/Summoner/Overview/SummonerStats.vue @@ -0,0 +1,289 @@ + + + diff --git a/client-new/src/components/Summoner/RecentActivity.vue b/client-new/src/components/Summoner/RecentActivity.vue new file mode 100644 index 0000000..687840e --- /dev/null +++ b/client-new/src/components/Summoner/RecentActivity.vue @@ -0,0 +1,174 @@ + + + diff --git a/client-new/src/components/Summoner/Records/RecordCard.vue b/client-new/src/components/Summoner/Records/RecordCard.vue new file mode 100644 index 0000000..d7a2c44 --- /dev/null +++ b/client-new/src/components/Summoner/Records/RecordCard.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/client-new/src/components/Summoner/SummonerRanked.vue b/client-new/src/components/Summoner/SummonerRanked.vue new file mode 100644 index 0000000..0a73ae4 --- /dev/null +++ b/client-new/src/components/Summoner/SummonerRanked.vue @@ -0,0 +1,155 @@ + + + diff --git a/client-new/src/data/data.js b/client-new/src/data/data.js new file mode 100644 index 0000000..284f5d0 --- /dev/null +++ b/client-new/src/data/data.js @@ -0,0 +1,132 @@ +export const maps = { 10: 'The Twisted Treeline', 11: "Summoner's Rift", 12: 'Howling Abyss' } + +export const gameModes = { + 0: { + type: 'Custom', + name: 'Custom Game' + }, + 900: { + type: 'Normal', + name: 'ARURF', + }, + 450: { + type: 'Normal', + name: 'ARAM', + }, + 400: { + type: 'Normal', + name: 'DRAFT 5vs5', + }, + 420: { + type: 'Ranked', + name: 'Solo/Duo', + }, + 430: { + type: 'Normal', + name: 'BLIND 5vs5', + }, + 440: { + type: 'Ranked', + name: 'FLEX 5vs5', + }, + 460: { + type: 'Normal', + name: 'BLIND 3vs3', + }, + 470: { + type: 'Ranked', + name: 'FLEX 3vs3', + }, + 700: { + type: 'Ranked', + name: 'CLASH', + }, + 720: { + type: 'Ranked', + name: 'CLASH ARAM', + }, + 800: { + type: 'Bot', + name: '3vs3 Co-op vs. AI (Intermediate)', + }, + 810: { + type: 'Bot', + name: '3vs3 Co-op vs. AI (Intro)', + }, + 820: { + type: 'Bot', + name: '3vs3 Co-op vs. AI (Beginner)', + }, + 830: { + type: 'Bot', + name: 'Co-op vs. AI (Intro)', + }, + 840: { + type: 'Bot', + name: 'Co-op vs. AI (Beginner)', + }, + 850: { + type: 'Bot', + name: 'Co-op vs. AI (Intermediate)', + }, + 920: { + type: 'Normal', + name: 'PORO KING', + }, + 1020: { + type: 'Normal', + name: 'One for All' + }, + 1300: { + type: 'Normal', + name: 'Nexus Blitz' + }, + 1400: { + type: 'Normal', + name: 'Ultimate Spellbook' + }, + 1900: { + type: 'Normal', + name: 'URF', + } +} + +/* ========= OLD 5 COLORS ========= */ +// KILLS, KP : green -> 71, 132, 116 +// DEATHS, DMGCHAMP, DMGOBJ: red -> 156, 71, 109 +// ASSISTS, GOLD, DMGTAKEN: golden -> 146, 100, 79 +// MINIONS: purple -> 140, 101, 182 +// VISION: blue -> 55, 118, 179 + +const colorValues = { + green: '54,148,109', + red: '197,85,93', + purple: '141,116,217', + teal: '104,186,191', + yellow: '166,176,134', + orange: '184,137,101', + brown: '161,127,134', + blue: '55, 118, 179', +} + +export const colors = { + // match-details + kills: colorValues['green'], + deaths: colorValues['red'], + assists: colorValues['purple'], + minions: colorValues['teal'], + vision: colorValues['yellow'], + gold: colorValues['orange'], + dmgChamp: colorValues['red'], + dmgObj: colorValues['yellow'], + dmgTaken: colorValues['red'], + kp: colorValues['brown'], + + // champions + winrate: colorValues['green'], + playrate: colorValues['purple'], + wins: colorValues['green'], + count: colorValues['purple'], + kda: colorValues['blue'], + gameLength: colorValues['green'], +} diff --git a/client-new/src/helpers/functions.js b/client-new/src/helpers/functions.js new file mode 100644 index 0000000..2b2bae7 --- /dev/null +++ b/client-new/src/helpers/functions.js @@ -0,0 +1,54 @@ +/** + * Return the relative time betweeen a chosen moment and the current time + * @param previous : time we want to get difference + */ +export function timeDifference(previous) { + const current = new Date() + const msPerMinute = 60 * 1000 + const msPerHour = msPerMinute * 60 + const msPerDay = msPerHour * 24 + const msPerWeek = msPerDay * 7 + const elapsed = current - previous + + if (elapsed < msPerMinute) { + return Math.round(elapsed / 1000) + ' seconds ago' + } else if (elapsed < msPerHour) { + return Math.round(elapsed / msPerMinute) + ' minutes ago' + } else if (elapsed < msPerDay) { + return Math.round(elapsed / msPerHour) + ' hours ago' + } else if (elapsed < msPerWeek) { + return Math.round(elapsed / msPerDay) + ' days ago' + } else { + const dateOptions = { day: '2-digit', month: '2-digit', year: 'numeric' } + return new Date(previous).toLocaleString(undefined, dateOptions).replace(/\//g, '.') + } +} + +/** + * Convert seconds to a readable string + * @param {Number} seconds + */ +export function secToTime(seconds) { + const min = Math.floor(seconds / 60) + let newSec = Math.floor(seconds - min * 60) + newSec = newSec < 10 ? '0' + newSec : newSec + + return `${min}:${newSec}` +} + +/** + * Sort an array of players by role + */ +export function sortTeamByRole(a, b) { + const sortingArr = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'UTILITY'] + return sortingArr.indexOf(a.role) - sortingArr.indexOf(b.role) +} + +/** + * Give the full CDragon image path from the iconPath field + * @param {String} iconPath + */ +export function createCDragonAssetUrl(iconPath) { + const name = iconPath.split('/assets/')[1].toLowerCase() + return `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${name}` +} diff --git a/client-new/src/helpers/summoner.js b/client-new/src/helpers/summoner.js new file mode 100644 index 0000000..6a9fe9b --- /dev/null +++ b/client-new/src/helpers/summoner.js @@ -0,0 +1,113 @@ +import { createCDragonAssetUrl, secToTime, timeDifference } from '@/helpers/functions.js' +import { maps, gameModes } from '@/data/data.js' +import store from '@/store' + +/** + * Get the url of the of the player primary rune + * @param {Object} perks : from the API + */ +export function getPrimarRune(perks) { + const primaryRune = perks.selected.length ? store.state.cdragon.runes.perks[perks.selected[0]] : null + return primaryRune ? createCDragonAssetUrl(primaryRune.icon) : null +} + +/** + * Get the url of the of the player secondary rune + * @param {Object} perks : from the API + */ +export function getSecondaryRune(perks) { + const secondaryRune = store.state.cdragon.runes.perkstyles[perks.secondaryStyle] + return secondaryRune ? createCDragonAssetUrl(secondaryRune.icon) : null +} + +/** + * Return all the infos about a list of matches built with the api data + * @param {Object} matches : all data from the api matches endpoint + */ +export function createMatchData(matches) { + for (const match of matches) { + // Runes + match.primaryRune = getPrimarRune(match.perks) + match.secondaryRune = getSecondaryRune(match.perks) + + const date = new Date(match.date) + const dateOptions = { day: '2-digit', month: '2-digit', year: 'numeric' } + const timeOptions = { hour12: false, hour: '2-digit', minute: '2-digit' } + match.fullDate = { date: date.toLocaleString(undefined, dateOptions), time: date.toLocaleString(undefined, timeOptions) } + match.date = timeDifference(match.date) + + match.map = maps[match.map] + match.gamemode = gameModes[match.gamemode] + if (!match.gamemode) { + match.gamemode = { name: 'Unknown gamemode' } + } + } + + return matches +} + +/** + * Return the formatted basic info for a summoner + * @param {Object} summonerBasic : all data from the api basic endpoint + */ +export function createBasicSummonerData(summonerBasic) { + // Ranked Stats + summonerBasic.ranked.soloQ = getLeagueData(summonerBasic.ranked.soloQ, 'Solo/Duo') + if (!summonerBasic.ranked.soloQ) delete summonerBasic.ranked.soloQ + + summonerBasic.ranked.flex5v5 = getLeagueData(summonerBasic.ranked.flex5v5, 'Flex 5vs5') + if (!summonerBasic.ranked.flex5v5) delete summonerBasic.ranked.flex5v5 + + summonerBasic.ranked.flex3v3 = getLeagueData(summonerBasic.ranked.flex3v3, 'Flex 3vs3') + if (!summonerBasic.ranked.flex3v3) delete summonerBasic.ranked.flex3v3 + + // If Summoner is Unranked + if (Object.entries(summonerBasic.ranked).length === 0) { + summonerBasic.ranked.soloQ = { + fullRank: 'Unranked', + rankImgLink: 'https://res.cloudinary.com/kln/image/upload/v1693310423/unranked.png', + leaguePoints: 0, + wins: 0, + losses: 0, + winrate: '0%', + name: 'Solo/Duo' + } + } + + return summonerBasic +} + +/** + * Return the formatted records of a summoner + * @param {Object} recordsDto : raw records from the database stats + */ +export function createRecordsData(recordsDto) { + const records = recordsDto.reduce((acc, record) => { + acc[record.what] = record + return acc + }, {}) + + records.game_duration.amount = secToTime(records.game_duration.amount) + records.gold.amount = records.gold.amount.toLocaleString() + records.damage_taken.amount = records.damage_taken.amount.toLocaleString() + records.damage_dealt_champions.amount = records.damage_dealt_champions.amount.toLocaleString() + records.damage_dealt_objectives.amount = records.damage_dealt_objectives.amount.toLocaleString() + records.kp.amount = `${records.kp.amount}%` + records.time_spent_living.amount = secToTime(records.time_spent_living.amount) + records.heal.amount = records.heal.amount.toLocaleString() + + return records +} + +/** + * Add rank img and ranked data + * @param {Object} leagueData + * @param {String} leagueName + */ +function getLeagueData(leagueData, leagueName) { + if (!leagueData) return null + + leagueData.rankImgLink = `https://res.cloudinary.com/kln/image/upload/v1693310423/${leagueData.tier}.png` + leagueData.name = leagueName + return leagueData +} diff --git a/client-new/src/layouts/Default.vue b/client-new/src/layouts/Default.vue new file mode 100644 index 0000000..4c4549f --- /dev/null +++ b/client-new/src/layouts/Default.vue @@ -0,0 +1,342 @@ + + + + + diff --git a/client-new/src/layouts/Home.vue b/client-new/src/layouts/Home.vue new file mode 100644 index 0000000..56a8b72 --- /dev/null +++ b/client-new/src/layouts/Home.vue @@ -0,0 +1,5 @@ + diff --git a/client-new/src/main.js b/client-new/src/main.js new file mode 100644 index 0000000..940f410 --- /dev/null +++ b/client-new/src/main.js @@ -0,0 +1,74 @@ +import Vue from 'vue' +import VueAxios from './plugins/axios' +import VueMeta from 'vue-meta' +import VuePlausible from './plugins/plausible' +import PortalVue from 'portal-vue' + +import './assets/css/main.css' + +import App from './App.vue' +import router from './router' +import store from './store' + +Vue.config.productionTip = false +Vue.use(VueAxios) +Vue.use(VuePlausible) +Vue.use(VueMeta) +Vue.use(PortalVue) + +Vue.filter('capitalize', (value) => { + return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase() +}) + +Vue.filter('kilo', (value, shortFormat = true) => { + return value > 1000 || shortFormat ? `${+(value / 1000).toFixed(1)}k` : value +}) + +Vue.filter('secToTime', (sec, dotNotation = false) => { + if (isNaN(sec)) return 0 + + const min = Math.floor(sec / 60) + let newSec = Math.floor(sec - min * 60) + newSec = newSec < 10 ? '0' + newSec : newSec + + return dotNotation ? `${min}:${newSec}` : `${min}m${newSec}s` +}) + +Vue.filter('secToHours', (sec) => { + if (isNaN(sec)) return 0 + + const result = [] + const d = Math.floor(sec / (3600 * 24)) + const h = Math.floor(sec % (3600 * 24) / 3600) + const m = Math.floor(sec % 3600 / 60) + + if (d > 0) { + result.push(d + ' days') + } else { + if (h > 0) { + result.push(h + 'h') + } + + if (m > 0) { + result.push(m + 'm') + } + } + + return result.join(' ') +}) + +Vue.filter('percent', (value) => { + return `${+value.toFixed(1)}%` +}) + +Vue.filter('round', (value, decimals = 2) => { + if (isNaN(value)) return 0 + + return parseFloat(value.toFixed(decimals)) +}) + +new Vue({ + router, + store, + render: h => h(App), +}).$mount('#app') diff --git a/client-new/src/mixins/liveGame.js b/client-new/src/mixins/liveGame.js new file mode 100644 index 0000000..9b31924 --- /dev/null +++ b/client-new/src/mixins/liveGame.js @@ -0,0 +1,74 @@ +import { gameModes } from '@/data/data.js' +import { sortTeamByRole } from '@/helpers/functions.js' +import { mapState } from 'vuex' + +export const liveGame = { + data() { + return { + gameLength: 0 + } + }, + + computed: { + allyTeam() { + if (!this.current || !this.current.participants) { + return [] + } + return this.current.participants.filter(p => p.teamId === this.teamColor).sort(this.sortTeamByRole) + }, + displayStartTime() { + if (this.current.gameStartTime === 0) { + return 'Not started yet' + } + return this.$options.filters.secToTime(this.gameLength, true) + }, + enemyTeam() { + if (!this.current || !this.current.participants) { + return [] + } + return this.current.participants.filter(p => p.teamId !== this.teamColor).sort(this.sortTeamByRole) + }, + gamemode() { + if (this.current.participants) { + return this.current.gameType === 'CUSTOM_GAME' ? { type: '', name: 'Custom Game' } : gameModes[this.current.gameQueueConfigId] + } else { + return { type: '', name: '' } + } + }, + gameStartTime() { + return this.current ? this.current.gameStartTime : 0 + }, + teamColor() { + return this.current.participants.find(p => p.summonerId === this.account.id).teamId + }, + ...mapState({ + account: state => state.summoner.basic.account, + current: state => state.summoner.live.match, + }) + }, + + created() { + this.updateGameLength() + + setInterval(() => { + this.gameLength++ + }, 1000) + }, + + watch: { + gameStartTime() { + this.updateGameLength() + } + }, + + methods: { + updateGameLength() { + if (this.gameStartTime === 0) { + return this.gameLength = 0 + } + + this.gameLength = (new Date() - new Date(this.gameStartTime)) / 1000 + }, + sortTeamByRole + } +} diff --git a/client-new/src/plugins/axios.js b/client-new/src/plugins/axios.js new file mode 100644 index 0000000..ce6608c --- /dev/null +++ b/client-new/src/plugins/axios.js @@ -0,0 +1,28 @@ +import axiosHttp from 'axios' +import router from '../router' +import store from '../store' + +export const axios = axiosHttp + +axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest' +axios.defaults.headers.common['Content-Type'] = 'application/json' +axios.defaults.baseURL = import.meta.env.DEV ? 'http://localhost:3333/' : 'https://api.leaguestats.gg/' + +const CancelToken = axios.CancelToken +const axiosSource = CancelToken.source() +axios.defaults.axiosSource = axiosSource +axios.defaults.cancelToken = axiosSource.token + +// Add season number to data if the route need it +axios.interceptors.request.use(function (config) { + if (config.method === 'post' && config.url !== 'summoner/basic' && router.currentRoute.meta.season) { + config.data.season = store.state.summoner.basic.currentSeason + } + return config +}) + +export default { + install(Vue) { + Vue.prototype.$axios = axiosHttp + } +} diff --git a/client-new/src/plugins/plausible.js b/client-new/src/plugins/plausible.js new file mode 100644 index 0000000..eeba99e --- /dev/null +++ b/client-new/src/plugins/plausible.js @@ -0,0 +1,15 @@ +import Plausible from 'plausible-tracker' + +export default { + install(Vue) { + const options = { + domain: 'leaguestats.gg', + trackLocalhost: false, + apiHost: 'https://stats.leaguestats.gg' + } + const plausible = Plausible(options) + plausible.enableAutoPageviews() + + Vue.prototype.$plausible = plausible + } +} diff --git a/client-new/src/router.js b/client-new/src/router.js new file mode 100644 index 0000000..ffa641e --- /dev/null +++ b/client-new/src/router.js @@ -0,0 +1,72 @@ +import Vue from 'vue' +import Router from 'vue-router' +import { axios } from './plugins/axios' + +import Home from '@/views/Home.vue' +import Summoner from '@/views/Summoner.vue' +import SummonerChampions from '@/views/SummonerChampions.vue' +import SummonerLive from '@/views/SummonerLive.vue' +import SummonerRecords from '@/views/SummonerRecords.vue' + +Vue.use(Router) + +const router = new Router({ + mode: 'history', + base: import.meta.env.BASE_URL, + routes: [ + { + path: '/', + name: 'home', + component: Home, + meta: { + layout: 'Home' + } + }, + { + path: '/summoner/:region/:name', + name: 'summoner', + component: Summoner, + meta: { + season: true + } + }, + { + path: '/summoner/:region/:name/champions', + name: 'summonerChampions', + component: SummonerChampions, + meta: { + season: true + } + }, + { + path: '/summoner/:region/:name/records', + name: 'summonerRecords', + component: SummonerRecords, + meta: { + season: true + } + }, + { + path: '/summoner/:region/:name/live', + name: 'summonerLive', + component: SummonerLive + }, + ] +}) + +router.beforeEach((to, from, next) => { + if (to.params.name !== from.params.name && from.name !== null) { + // Cancel old requests + const axiosCancel = axios.defaults.axiosSource.cancel + axiosCancel('Summoner changed') + + // Update cancel token + const CancelToken = axios.CancelToken + const axiosSource = CancelToken.source() + axios.defaults.axiosSource = axiosSource + axios.defaults.cancelToken = axiosSource.token + } + next() +}) + +export default router \ No newline at end of file diff --git a/client-new/src/store/index.js b/client-new/src/store/index.js new file mode 100644 index 0000000..d2c4fe2 --- /dev/null +++ b/client-new/src/store/index.js @@ -0,0 +1,43 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import * as cdragon from '@/store/modules/cdragon' +import * as detailedMatch from '@/store/modules/detailedMatch' +import * as notification from '@/store/modules/notification' +import * as settings from '@/store/modules/settings' +import * as summoner from '@/store/modules/summoner' + +Vue.use(Vuex) + +const debug = import.meta.env.DEV + +export default new Vuex.Store({ + modules: { + cdragon, + detailedMatch, + notification, + settings, + summoner + }, + state: { + regionsList: { + 'br': 'br1', + 'eune': 'eun1', + 'euw': 'euw1', + 'jp': 'jp1', + 'kr': 'kr', + 'lan': 'la1', + 'las': 'la2', + 'na': 'na1', + 'oce': 'oc1', + 'tr': 'tr1', + 'ru': 'ru', + 'ph': 'ph2', + 'sg': 'sg2', + 'th': 'th2', + 'tw': 'tw2', + 'vn': 'vn2', + }, + roles: ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'UTILITY'] + }, + strict: debug +}) diff --git a/client-new/src/store/modules/cdragon.js b/client-new/src/store/modules/cdragon.js new file mode 100644 index 0000000..0f928cf --- /dev/null +++ b/client-new/src/store/modules/cdragon.js @@ -0,0 +1,41 @@ +import { axios } from '@/plugins/axios' + +export const namespaced = true + +export const state = { + kStats: [ + [5008, 5005, 5007], + [5008, 5002, 5003], + [5001, 5002, 5003], + ], + runes: null, + runesOpen: false, + selectedRunes: {}, +} + +export const mutations = { + DISPLAY_HIDE_RUNES(state, selectedRunes) { + state.runesOpen = !state.runesOpen + state.selectedRunes = selectedRunes + }, + SET_RUNES(state, runes) { + state.runes = runes + }, +} + +export const actions = { + displayOrHideRunes({ commit }, selectedRunes) { + commit('DISPLAY_HIDE_RUNES', selectedRunes) + }, + async getRunes({ commit, getters }) { + if (getters.runesLoaded) { return } + + const { data } = await axios.get('cdragon/runes').catch((e) => { console.log(e) }) + console.log(data) + commit('SET_RUNES', data) + }, +} + +export const getters = { + runesLoaded: state => state.runes, +} diff --git a/client-new/src/store/modules/detailedMatch.js b/client-new/src/store/modules/detailedMatch.js new file mode 100644 index 0000000..ea34564 --- /dev/null +++ b/client-new/src/store/modules/detailedMatch.js @@ -0,0 +1,77 @@ +import Vue from 'vue' +import { axios } from '@/plugins/axios' + +export const namespaced = true + +export const state = { + matches: [] +} + +export const mutations = { + MATCH_LOADING(state, matchId) { + const alreadyIn = state.matches.find(m => m.matchId === matchId) + if (!alreadyIn) { + state.matches.push({ matchId, status: 'loading' }) + } + }, + MATCH_FOUND(state, {matchDetails, ranksLoaded }) { + matchDetails.status = 'loaded' + matchDetails.ranksLoaded = ranksLoaded + + // Set SoloQ as rank for now + if (ranksLoaded) { + for (const player of matchDetails.blueTeam.players) { + player.rank = player.rank && player.rank[420] + } + for (const player of matchDetails.redTeam.players) { + player.rank = player.rank && player.rank[420] + } + } + + const index = state.matches.findIndex(m => m.matchId === matchDetails.matchId) + Vue.set(state.matches, index, matchDetails) + }, + MATCH_RANKS_FOUND(state, { matchId, ranksByPlayer }) { + const match = state.matches.find(m => m.matchId === matchId) + + for (const player of match.blueTeam.players) { + const ranks = ranksByPlayer[player.id] + if (!ranks) continue + Vue.set(player, 'rank', ranks[420]) + } + + for (const player of match.redTeam.players) { + const ranks = ranksByPlayer[player.id] + if (!ranks) continue + Vue.set(player, 'rank', ranks[420]) + } + + match.ranksLoaded = true + }, +} + +export const actions = { + async matchDetails({ commit }, matchId) { + commit('MATCH_LOADING', matchId) + console.log('MATCH DETAILS STORE', matchId) + + const resp = await axios(({ url: 'match/details', data: { matchId }, method: 'POST' })).catch(() => { }) + console.log('--- DETAILS INFOS ---') + console.log(resp.data) + const {matchDetails, ranksLoaded} = resp.data + commit('MATCH_FOUND', {matchDetails, ranksLoaded }) + + // If the ranks of the players are not yet known + if (!ranksLoaded) { + const ranks = await axios(({ url: 'match/details/ranks', data: { matchId }, method: 'POST' })).catch(() => { }) + if (!ranks) return + console.log('--- RANK OF MATCH DETAILS ---') + console.log(ranks.data) + commit('MATCH_RANKS_FOUND', { matchId, ranksByPlayer: ranks.data }) + } + } +} + +export const getters = { + getMatchDetails: state => matchId => state.matches.find(m => m.matchId === matchId), +} diff --git a/client-new/src/store/modules/notification.js b/client-new/src/store/modules/notification.js new file mode 100644 index 0000000..2fea967 --- /dev/null +++ b/client-new/src/store/modules/notification.js @@ -0,0 +1,30 @@ +export const namespaced = true + +export const state = { + notifications: [] +} + +let nextId = 1 + +export const mutations = { + PUSH(state, notification) { + state.notifications.push({ + ...notification, + id: nextId++ + }) + }, + DELETE(state, notificationToRemove) { + state.notifications = state.notifications.filter( + notification => notification.id !== notificationToRemove.id + ) + } +} + +export const actions = { + add({ commit }, notification) { + commit('PUSH', notification) + }, + remove({ commit }, notificationToRemove) { + commit('DELETE', notificationToRemove) + } +} diff --git a/client-new/src/store/modules/settings.js b/client-new/src/store/modules/settings.js new file mode 100644 index 0000000..07687e9 --- /dev/null +++ b/client-new/src/store/modules/settings.js @@ -0,0 +1,95 @@ +export const namespaced = true + +export const state = { + favorites: [], + percent: false, + recentSearches: [], + region: 'euw', +} + +export const mutations = { + ADD_FAVORITE(state, summoner) { + state.favorites.push(summoner) + }, + ADD_SEARCH(state, summoner) { + const alreadyFav = state.favorites.find(s => s.name === summoner.name && s.region === summoner.region) + if (alreadyFav) { + return + } + + let searches = state.recentSearches + + const alreadySearch = searches.find(s => s.name === summoner.name && s.region === summoner.region) + if (alreadySearch) { + alreadySearch.date = Date.now() + searches.sort((a, b) => b.date - a.date) + return + } + + if (searches.length > 10) { + searches.pop() + } + + summoner.date = Date.now() + searches.unshift(summoner) + }, + REMOVE_FAVORITE(state, summoner) { + state.favorites = state.favorites.filter(s => s.name !== summoner.name || s.region !== summoner.region) + }, + REMOVE_SEARCH(state, summoner) { + state.recentSearches = state.recentSearches.filter(s => s.name !== summoner.name || s.region !== summoner.region) + }, + UPDATE_SETTING(state, { name, value }) { + state[name] = value + } +} + +export const actions = { + addRecentSearch({ commit, dispatch, state }, summoner) { + commit('ADD_SEARCH', summoner) + dispatch('updateSettings', { name: 'recentSearches', value: state.recentSearches, isJson: true }) + }, + removeRecentSearch({ commit, dispatch }, summoner) { + commit('REMOVE_SEARCH', summoner) + dispatch('updateSettings', { name: 'recentSearches', value: state.recentSearches, isJson: true }) + }, + updateFavorite({ commit, dispatch, state }, summoner) { + const alreadyFav = state.favorites.find(s => s.name === summoner.name && s.region === summoner.region) + if (alreadyFav) { + commit('REMOVE_FAVORITE', summoner) + } else { + if (state.favorites.length >= 6) { + // Display error message + return dispatch('notification/add', { + type: 'error', + message: 'Too many favorite summoners.' + }, { root: true }) + } + commit('ADD_FAVORITE', summoner) + const searched = state.recentSearches.find(s => s.name === summoner.name && s.region === summoner.region) + if (searched) { + dispatch('removeRecentSearch', summoner) + } + } + + dispatch('updateSettings', { name: 'favorites', value: state.favorites, isJson: true }) + }, + updatePercent({ commit }, percent) { + if (typeof (percent) !== 'boolean') { + percent = localStorage.getItem('settings-percent') === 'true' + } else { + localStorage.setItem('settings-percent', percent) + } + commit('UPDATE_SETTING', { name: 'percent', value: percent }) + }, + updateSettings({ commit }, { name, value, isJson = false }) { + if (!value) { + value = localStorage.getItem(name) + value = isJson ? JSON.parse(value) : value + if (!value) return + } else { + localStorage.setItem(name, isJson ? JSON.stringify(value) : value) + } + commit('UPDATE_SETTING', { name, value }) + } +} diff --git a/client-new/src/store/modules/summoner.js b/client-new/src/store/modules/summoner.js new file mode 100644 index 0000000..6953680 --- /dev/null +++ b/client-new/src/store/modules/summoner.js @@ -0,0 +1,247 @@ +import { axios } from '@/plugins/axios' +import { createMatchData, createBasicSummonerData, createRecordsData } from '@/helpers/summoner' + +export const namespaced = true + +export const state = { + basic: { + account: {}, + currentSeason: null, + ranked: {}, + recentActivity: [], + seasons: [], + gamemodes: [], + status: '', + }, + overview: { + NB_LOAD_GAMES: 10, + matches: [], + stats: {}, + loaded: false, + matchesLoading: false, + moreMatchesToFetch: true + }, + champions: { + list: [], + championsLoaded: false + }, + records: { + list: {}, + recordsLoaded: false + }, + live: { + match: {}, + liveLoaded: false, + playing: false, + }, +} + +export const mutations = { + BASIC_REQUEST(state) { + state.basic.status = 'loading' + state.basic.currentSeason = null + state.champions.championsLoaded = false + state.records.recordsLoaded = false + state.overview.loaded = false + state.overview.moreMatchesToFetch = true + state.live.liveLoaded = false + }, + CHAMPIONS_NOT_FOUND(state) { + state.champions.championsLoaded = false + }, + CHAMPIONS_FOUND(state, { champions }) { + state.champions.list = champions + state.champions.championsLoaded = true + }, + KEEP_LAST_X_MATCHES(state, number) { + state.overview.matches = state.overview.matches.slice(0, number) + }, + LIVE_FOUND(state, { live }) { + state.live.match = live + state.live.liveLoaded = true + }, + LIVE_LOADING(state) { + state.live.playing = true + state.live.liveLoaded = false + }, + MATCHES_LOADING(state) { + state.overview.matchesLoading = true + }, + MATCHES_FOUND(state, { newMatches, stats }) { + state.overview.matchesLoading = false + + if (newMatches.length > 0) { + state.basic.recentActivity = stats.recentActivity + state.overview.matches = [...state.overview.matches, ...newMatches] + state.overview.stats = stats + state.champions.championsLoaded = false + state.records.recordsLoaded = false + } + + state.overview.moreMatchesToFetch = newMatches.length > 0 + }, + OVERVIEW_FOUND(state, infos) { + state.basic.recentActivity = infos.stats.recentActivity + state.overview.matches = infos.matches + state.overview.stats = infos.stats + state.overview.loaded = true + state.records.recordsLoaded = false + state.overview.moreMatchesToFetch = infos.matches.length > 0 + }, + RECORDS_FOUND(state, { records }) { + state.records.list = records + state.records.recordsLoaded = true + }, + SUMMONER_FOUND(state, infos) { + state.basic.account = infos.account + state.basic.ranked = infos.ranked + state.basic.recentActivity = infos.recentActivity + state.basic.seasons = infos.seasons.sort((a, b) => b - a) + state.basic.gamemodes = infos.gamemodes + state.basic.status = 'found' + state.live.match = infos.current + state.live.playing = infos.playing + }, + SUMMONER_NOT_FOUND(state) { + state.basic.status = 'error' + }, + SUMMONER_NOT_PLAYING(state) { + state.live.match = {} + state.live.playing = false + state.live.liveLoaded = false + }, + UPDATE_SEASON(state, { season }) { + state.basic.currentSeason = season + + state.overview.loaded = false + state.champions.championsLoaded = false + state.records.recordsLoaded = false + }, +} + +export const actions = { + async basicRequest({ commit, dispatch, rootState }, { summoner, region }) { + const regionId = rootState.regionsList[region] + commit('BASIC_REQUEST') + try { + const resp = await axios(({ url: 'summoner/basic', data: { summoner, region: regionId }, method: 'POST' })) + if (!resp.data) { + dispatch('notification/add', { + type: 'error', + message: 'Summoner not found.' + }, { root: true }) + return commit('SUMMONER_NOT_FOUND') + } + + console.log(`---SUMMONER INFOS ${resp.data.account.name}---`) + console.log(resp.data) + const infos = createBasicSummonerData(resp.data) + commit('SUMMONER_FOUND', infos) + + // Add summoner to recent searches + dispatch('settings/addRecentSearch', { + name: infos.account.name, + icon: infos.account.profileIconId, + region, + }, { root: true }) + } catch (error) { + if (error.response && error.response.status === 422) { + dispatch('notification/add', { + type: 'error', + message: 'Summoner not found.' + }, { root: true }) + } + if (error.message !== 'Summoner changed') { + commit('SUMMONER_NOT_FOUND') + } + } + }, + championsNotLoaded({ commit }) { + commit('CHAMPIONS_NOT_FOUND') + }, + async championsRequest({ commit }, queue = null) { + const resp = await axios(({ url: 'summoner/champions', data: { puuid: state.basic.account.puuid, queue: queue }, method: 'POST' })).catch(() => { }) + console.log('---CHAMPIONS---') + console.log(resp.data) + + commit('CHAMPIONS_FOUND', { champions: resp.data }) + }, + async liveMatchRequest({ commit, rootState }) { + commit('LIVE_LOADING') + const resp = await axios(({ + url: 'summoner/live', + data: { + id: state.basic.account.id, + region: rootState.regionsList[rootState.settings.region] + }, + method: 'POST' + })).catch(() => { }) + console.log('---LIVE---') + console.log(resp.data) + + if (resp.data) { + commit('LIVE_FOUND', { live: resp.data }) + } else { + commit('SUMMONER_NOT_PLAYING') + } + }, + async moreMatches({ commit, rootState }) { + commit('MATCHES_LOADING') + + if (!state.overview.matches.length) return + const lastMatchId = state.overview.matches[state.overview.matches.length - 1].matchId + + const resp = await axios(({ + url: 'match', + data: { + puuid: state.basic.account.puuid, + region: rootState.regionsList[rootState.settings.region], + lastMatchId + }, + method: 'POST' + })).catch(() => { }) + console.log('---MATCHES INFOS---') + console.log(resp.data) + const newMatches = createMatchData(resp.data.matches) + commit('MATCHES_FOUND', { newMatches, stats: resp.data.stats }) + }, + async overviewRequest({ commit, rootState }) { + const resp = await axios(({ + url: 'summoner/overview', + data: { + puuid: state.basic.account.puuid, + accountId: state.basic.account.accountId, + region: rootState.regionsList[rootState.settings.region], + }, + method: 'POST' + })).catch(() => { }) + console.log('---OVERVIEW---') + console.log(resp.data) + resp.data.matches = createMatchData(resp.data.matchesDetails) + commit('OVERVIEW_FOUND', resp.data) + }, + async recordsRequest({ commit }) { + const resp = await axios(({ url: 'summoner/records', data: { puuid: state.basic.account.puuid }, method: 'POST' })).catch(() => { }) + console.log('---RECORDS---') + console.log(resp.data) + const records = resp.data.length ? createRecordsData(resp.data) : {} + + commit('RECORDS_FOUND', { records }) + }, + sliceOverviewMatches({ commit }, number) { + commit('KEEP_LAST_X_MATCHES', number) + }, + updateSeason({ commit }, season) { + commit('UPDATE_SEASON', { season }) + } +} + +export const getters = { + matchesLoading: state => state.overview.matchesLoading, + overviewLoaded: state => state.overview.loaded, + playing: state => state.live.playing, + regionFilterApplied: state => !!state.basic.currentSeason, + summonerFound: state => state.basic.status === 'found', + summonerNotFound: state => state.basic.status === 'error', + summonerLoading: state => state.basic.status === 'loading', +} diff --git a/client-new/src/style.css b/client-new/src/style.css new file mode 100644 index 0000000..796882a --- /dev/null +++ b/client-new/src/style.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/client-new/src/views/Home.vue b/client-new/src/views/Home.vue new file mode 100644 index 0000000..b3bf704 --- /dev/null +++ b/client-new/src/views/Home.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/client-new/src/views/Summoner.vue b/client-new/src/views/Summoner.vue new file mode 100644 index 0000000..959ce1b --- /dev/null +++ b/client-new/src/views/Summoner.vue @@ -0,0 +1,125 @@ + + + + + + diff --git a/client-new/src/views/SummonerChampions.vue b/client-new/src/views/SummonerChampions.vue new file mode 100644 index 0000000..00889f3 --- /dev/null +++ b/client-new/src/views/SummonerChampions.vue @@ -0,0 +1,101 @@ + + + diff --git a/client-new/src/views/SummonerLive.vue b/client-new/src/views/SummonerLive.vue new file mode 100644 index 0000000..cea12e7 --- /dev/null +++ b/client-new/src/views/SummonerLive.vue @@ -0,0 +1,82 @@ + + + diff --git a/client-new/src/views/SummonerRecords.vue b/client-new/src/views/SummonerRecords.vue new file mode 100644 index 0000000..39349e5 --- /dev/null +++ b/client-new/src/views/SummonerRecords.vue @@ -0,0 +1,312 @@ + + + + + diff --git a/client-new/tailwind.config.js b/client-new/tailwind.config.js new file mode 100644 index 0000000..5af3894 --- /dev/null +++ b/client-new/tailwind.config.js @@ -0,0 +1,86 @@ +/* +** TailwindCSS Configuration File +** +** Docs: https://tailwindcss.com/docs/configuration +** Default: https://github.com/tailwindcss/tailwindcss/blob/master/stubs/defaultConfig.stub.js +*/ +const defaultTheme = require('tailwindcss/defaultTheme') + +module.exports = { + theme: { + customForms: theme => ({ + default: { + checkbox: { + width: theme('spacing.6'), + height: theme('spacing.6'), + backgroundColor: 'rgba(23, 49, 79, 0.6)', + borderColor: theme('colors.blue.800'), + textColor: theme('colors.blue.1000'), + '&:focus': { + backgroundColor: theme('colors.blue.1000'), + borderColor: theme('colors.blue.700'), + boxShadow: undefined, + }, + '&:checked': { + backgroundColor: theme('colors.blue.1000'), + borderColor: 'transparent', + } + } + } + }), + extend: { + colors: { + teal: { + ...defaultTheme.colors.teal, + 'flashy': '#24e8cc', + }, + blue: { + ...defaultTheme.colors.blue, + 760: '#2C5C94', + 850: '#2B4B74', + 1000: '#17314f' + }, + }, + spacing: { + '2px': '2px', + '3p5': '0.875rem', + '4b': '1.15rem', + '11': '2.75rem', + }, + borderWidth: { + '3': '3px', + }, + fontFamily: { + sans: ['Inter', ...defaultTheme.fontFamily.sans], + }, + fontSize: { + xxs: '0.625rem', + }, + height: { + '200': '50rem', + '1/2': '50%', + }, + maxWidth: { + '12': '3rem', + }, + width: { + '22': '5.5rem', + }, + }, + }, + variants: { + textColor: ['responsive', 'hover', 'focus', 'group-hover'], + }, + plugins: [ + require('@tailwindcss/custom-forms'), + ], + purge: { + enabled: process.env.NODE_ENV === 'production', + content: [ + './index.html', './src/**/*.{vue,js,ts,jsx,tsx}' + ] + }, + future: { + removeDeprecatedGapUtilities: true, + }, +} diff --git a/client-new/vite.config.js b/client-new/vite.config.js new file mode 100644 index 0000000..0c06650 --- /dev/null +++ b/client-new/vite.config.js @@ -0,0 +1,17 @@ +import path from 'path'; +import vue from '@vitejs/plugin-vue2' + +export default { + esbuild: { + drop: ['console', 'debugger'], + }, + plugins: [vue()], + resolve: { + alias: { + '@/': `${path.resolve(__dirname, 'src')}/`, + }, + }, + server: { + port: 8080, + }, +} \ No newline at end of file diff --git a/leaguestats.code-workspace b/leaguestats.code-workspace index 88a0814..ee248c0 100644 --- a/leaguestats.code-workspace +++ b/leaguestats.code-workspace @@ -2,6 +2,9 @@ "folders": [ { "path": "client" + }, + { + "path": "client-new" }, { "path": "server"