From 7246ddea7b4b6727dfe8d9ea9e2f3ec4701316e6 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Wed, 27 Jul 2022 12:17:46 +0200 Subject: [PATCH] initial commit --- .editorconfig | 12 + .gitignore | 1 + README.md | 3 + assets/Square.ttf | Bin 0 -> 13652 bytes assets/Squareo.ttf | Bin 0 -> 18664 bytes assets/fall.wav | Bin 0 -> 19774 bytes assets/jump.wav | Bin 0 -> 23036 bytes client/.gitignore | 8 + client/.npmrc | 1 + client/.prettierignore | 13 + client/.prettierrc | 6 + client/README.md | 38 + client/package.json | 28 + client/pnpm-lock.yaml | 1342 ++++++++++++++++++++++++++++++++ client/src/app.d.ts | 11 + client/src/app.html | 12 + client/src/lib/Websocket.ts | 230 ++++++ client/src/routes/index.svelte | 2 + client/static/favicon.png | Bin 0 -> 1571 bytes client/svelte.config.js | 15 + client/tsconfig.json | 13 + client/vite.config.js | 8 + pnpm-lock.yaml | 17 + pnpm-workspace.yaml | 3 + server/package.json | 15 + server/src/index.js | 168 ++++ 26 files changed, 1946 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 assets/Square.ttf create mode 100644 assets/Squareo.ttf create mode 100644 assets/fall.wav create mode 100644 assets/jump.wav create mode 100644 client/.gitignore create mode 100644 client/.npmrc create mode 100644 client/.prettierignore create mode 100644 client/.prettierrc create mode 100644 client/README.md create mode 100644 client/package.json create mode 100644 client/pnpm-lock.yaml create mode 100644 client/src/app.d.ts create mode 100644 client/src/app.html create mode 100644 client/src/lib/Websocket.ts create mode 100644 client/src/routes/index.svelte create mode 100644 client/static/favicon.png create mode 100644 client/svelte.config.js create mode 100644 client/tsconfig.json create mode 100644 client/vite.config.js create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 server/package.json create mode 100644 server/src/index.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c1322dc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/README.md b/README.md index 12cf3e6..938a2e2 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,6 @@ A multiplayer fight between dices. ### Audio reflectable【音楽素材MusMus】- Music by MusMus + + + diff --git a/assets/Square.ttf b/assets/Square.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9f1867ee0329a3c6295704d87cb1df3c43990036 GIT binary patch literal 13652 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 literal 0 HcmV?d00001 diff --git a/assets/Squareo.ttf b/assets/Squareo.ttf new file mode 100644 index 0000000000000000000000000000000000000000..987c5b767490d3fc2b0857e6880eeb44fda844d5 GIT binary patch literal 18664 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 NC$~Cr32X=Pe*j<4nU(+m literal 0 HcmV?d00001 diff --git a/assets/fall.wav b/assets/fall.wav new file mode 100644 index 0000000000000000000000000000000000000000..caae3dd49425912fe7c937431a00927ac12eaea3 GIT binary patch literal 19774 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 U@cj;azXRXz!1p`wKYs`Q7xwD}(*OVf literal 0 HcmV?d00001 diff --git a/assets/jump.wav b/assets/jump.wav new file mode 100644 index 0000000000000000000000000000000000000000..0c15846833b95f3b12a50cf523b40172ecd3a722 GIT binary patch literal 23036 zcmb@uWpEqYx~=V4(A{E|EHg8OIV;S}%;+#PGc$9t!pzJ}W@eJbEHz2?H`VdZS$m&z z?{};2t@U@6Dw4bB9Pb# z?e=qR+Q!VGIj+3Lg`bOUrLOX-%A3{0YBcI`+BZ7H(8f5%G}AoYGQ`^0Mz?>quX02= zzc|OBT67ks#zx^^@OWYeQAIQ(H<7JqjwWs z^6P{zv0l+rBAlVOf_DUN_rK<=@#&;^D(faSim!=Q2*(Nr^GER(aF24nvpMWxtUHJp zSpz$ug%HWy#tdY>V2ouzj7Rk8^k8}k?F?-)EuKbrfAyZH`t^gC=96j5KAjg(xTyG2 z>4WmKm9wh-YwoGzw0m@gdXcfIsf)RbrHNH)tFhg%PjU#H_nh6)Ty!Lsi}k{v;(^3! zB9DkAmy_>F*wx*&$@R)*bA`DFx>vg|yMMYZZc*((M)xK)$uAN<#=4^>M%Y8I2X77B z>VL(z#;1egiL8s%AigSEE*v8m#2?9<&piUZ1si;e+lYwz77HMP`WDX_W5Bm~_~%

kK!IpH08aA1ybmn{55; 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 QDe!|2j53{3DbE1^2Afn}umAu6 literal 0 HcmV?d00001 diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..f4401a3 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example diff --git a/client/.npmrc b/client/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/client/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/client/.prettierignore b/client/.prettierignore new file mode 100644 index 0000000..3897265 --- /dev/null +++ b/client/.prettierignore @@ -0,0 +1,13 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/client/.prettierrc b/client/.prettierrc new file mode 100644 index 0000000..ff2677e --- /dev/null +++ b/client/.prettierrc @@ -0,0 +1,6 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100 +} diff --git a/client/README.md b/client/README.md new file mode 100644 index 0000000..5c91169 --- /dev/null +++ b/client/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..c873f0d --- /dev/null +++ b/client/package.json @@ -0,0 +1,28 @@ +{ + "name": "client", + "version": "0.0.1", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "package": "svelte-kit package", + "preview": "vite preview", + "prepare": "svelte-kit sync", + "check": "svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "prettier --check --plugin-search-dir=. .", + "format": "prettier --write --plugin-search-dir=. ." + }, + "devDependencies": { + "@sveltejs/adapter-auto": "next", + "@sveltejs/kit": "next", + "prettier": "^2.6.2", + "prettier-plugin-svelte": "^2.7.0", + "svelte": "^3.44.0", + "svelte-check": "^2.7.1", + "svelte-preprocess": "^4.10.6", + "tslib": "^2.3.1", + "typescript": "^4.7.4", + "vite": "^3.0.0" + }, + "type": "module" +} diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml new file mode 100644 index 0000000..cc49490 --- /dev/null +++ b/client/pnpm-lock.yaml @@ -0,0 +1,1342 @@ +lockfileVersion: 5.4 + +specifiers: + '@sveltejs/adapter-auto': next + '@sveltejs/kit': next + prettier: ^2.6.2 + prettier-plugin-svelte: ^2.7.0 + svelte: ^3.44.0 + svelte-check: ^2.7.1 + svelte-preprocess: ^4.10.6 + tslib: ^2.3.1 + typescript: ^4.7.4 + vite: ^3.0.0 + +devDependencies: + '@sveltejs/adapter-auto': 1.0.0-next.64 + '@sveltejs/kit': 1.0.0-next.396_svelte@3.49.0+vite@3.0.3 + prettier: 2.7.1 + prettier-plugin-svelte: 2.7.0_o3ioganyptcsrh6x4hnxvjkpqi + svelte: 3.49.0 + svelte-check: 2.8.0_svelte@3.49.0 + svelte-preprocess: 4.10.7_uslzfc62di2n2otc2tvfklnwji + tslib: 2.4.0 + typescript: 4.7.4 + vite: 3.0.3 + +packages: + + /@cloudflare/workers-types/3.14.1: + resolution: {integrity: sha512-B1/plF62pt+H2IJHvApK8fdOJAVsvojvacuac8x8s+JIyqbropMyqNqHTKLm3YD8ZFLGwYeFTudU+PQ7vGvBdA==} + dev: true + + /@iarna/toml/2.2.5: + resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + dev: true + + /@jridgewell/resolve-uri/3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec/1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/trace-mapping/0.3.14: + resolution: {integrity: sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@mapbox/node-pre-gyp/1.0.9: + resolution: {integrity: sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==} + hasBin: true + dependencies: + detect-libc: 2.0.1 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.6.7 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.3.7 + tar: 6.1.11 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 + dev: true + + /@rollup/pluginutils/4.2.1: + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: true + + /@sveltejs/adapter-auto/1.0.0-next.64: + resolution: {integrity: sha512-Q8DwcS6wl1GovzS9JJzaD/WL/Lfk1ur4nAF1HtmsUvZDpsPBVDqnK2AhYU4G3oFNiuHstrjAogMy5th8ptSFGw==} + dependencies: + '@sveltejs/adapter-cloudflare': 1.0.0-next.31 + '@sveltejs/adapter-netlify': 1.0.0-next.71 + '@sveltejs/adapter-vercel': 1.0.0-next.66 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@sveltejs/adapter-cloudflare/1.0.0-next.31: + resolution: {integrity: sha512-HhEFZP72GJ8AZGgFECKIiayDcLaAWi65pI0AnBfiNhCifYSlH/mPNWNVD4AWRDnXnH6XU+FLwhGDnIDwytTyYg==} + dependencies: + '@cloudflare/workers-types': 3.14.1 + esbuild: 0.14.50 + worktop: 0.8.0-next.14 + dev: true + + /@sveltejs/adapter-netlify/1.0.0-next.71: + resolution: {integrity: sha512-la1CGtWO1xul1L3zEoFAoc4EX2uxZjrZcOMS3tkKB8drxhbQsNbnTE6fmSSMFiZXhxaikczrBgQwqIaDkLTmZg==} + dependencies: + '@iarna/toml': 2.2.5 + esbuild: 0.14.50 + set-cookie-parser: 2.5.1 + tiny-glob: 0.2.9 + dev: true + + /@sveltejs/adapter-vercel/1.0.0-next.66: + resolution: {integrity: sha512-s3Hcxu9nCG/rR3C3cFbdQGjTa5W4K2kRcc6S5Xefx7itbrw+4v3KpO8ZPB6qM55XDwVxuG7260NMHVI6MUGmSA==} + dependencies: + '@vercel/nft': 0.21.0 + esbuild: 0.14.50 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@sveltejs/kit/1.0.0-next.396_svelte@3.49.0+vite@3.0.3: + resolution: {integrity: sha512-bKFpuzp9QxPkOIOEIeNeedvxEMORNqBPxUmoJXDP/Se7MrSfcxYiamjBcKrG+bgGNWmV39nD3EvUox+CXno/Ig==} + engines: {node: '>=16.9'} + hasBin: true + peerDependencies: + svelte: ^3.44.0 + vite: ^3.0.0 + dependencies: + '@sveltejs/vite-plugin-svelte': 1.0.1_svelte@3.49.0+vite@3.0.3 + chokidar: 3.5.3 + sade: 1.8.1 + svelte: 3.49.0 + vite: 3.0.3 + transitivePeerDependencies: + - diff-match-patch + - supports-color + dev: true + + /@sveltejs/vite-plugin-svelte/1.0.1_svelte@3.49.0+vite@3.0.3: + resolution: {integrity: sha512-PorCgUounn0VXcpeJu+hOweZODKmGuLHsLomwqSj+p26IwjjGffmYQfVHtiTWq+NqaUuuHWWG7vPge6UFw4Aeg==} + engines: {node: ^14.18.0 || >= 16} + peerDependencies: + diff-match-patch: ^1.0.5 + svelte: ^3.44.0 + vite: ^3.0.0 + peerDependenciesMeta: + diff-match-patch: + optional: true + dependencies: + '@rollup/pluginutils': 4.2.1 + debug: 4.3.4 + deepmerge: 4.2.2 + kleur: 4.1.5 + magic-string: 0.26.2 + svelte: 3.49.0 + svelte-hmr: 0.14.12_svelte@3.49.0 + vite: 3.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@types/node/18.6.1: + resolution: {integrity: sha512-z+2vB6yDt1fNwKOeGbckpmirO+VBDuQqecXkgeIqDlaOtmKn6hPR/viQ8cxCfqLU4fTlvM3+YjM367TukWdxpg==} + dev: true + + /@types/pug/2.0.6: + resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} + dev: true + + /@types/sass/1.43.1: + resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==} + dependencies: + '@types/node': 18.6.1 + dev: true + + /@vercel/nft/0.21.0: + resolution: {integrity: sha512-hFCAETfI5cG8l5iAiLhMC2bReC5K7SIybzrxGorv+eGspIbIFsVw7Vg85GovXm/LxA08pIDrAlrhR6GN36XB/Q==} + hasBin: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.9 + acorn: 8.8.0 + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + node-gyp-build: 4.5.0 + resolve-from: 5.0.0 + rollup-pluginutils: 2.8.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /abbrev/1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /acorn/8.8.0: + resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base/6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /anymatch/3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /aproba/2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: true + + /are-we-there-yet/2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.0 + dev: true + + /async-sema/3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + dev: true + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bindings/1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /buffer-crc32/0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: true + + /callsites/3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.2 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /chownr/2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: true + + /color-support/1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /console-control-strings/1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: true + + /debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deepmerge/4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: true + + /delegates/1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: true + + /detect-indent/6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + + /detect-libc/2.0.1: + resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} + engines: {node: '>=8'} + dev: true + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /es6-promise/3.3.1: + resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} + dev: true + + /esbuild-android-64/0.14.50: + resolution: {integrity: sha512-H7iUEm7gUJHzidsBlFPGF6FTExazcgXL/46xxLo6i6bMtPim6ZmXyTccS8yOMpy6HAC6dPZ/JCQqrkkin69n6Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-android-arm64/0.14.50: + resolution: {integrity: sha512-NFaoqEwa+OYfoYVpQWDMdKII7wZZkAjtJFo1WdnBeCYlYikvUhTnf2aPwPu5qEAw/ie1NYK0yn3cafwP+kP+OQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-64/0.14.50: + resolution: {integrity: sha512-gDQsCvGnZiJv9cfdO48QqxkRV8oKAXgR2CGp7TdIpccwFdJMHf8hyIJhMW/05b/HJjET/26Us27Jx91BFfEVSA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-arm64/0.14.50: + resolution: {integrity: sha512-36nNs5OjKIb/Q50Sgp8+rYW/PqirRiFN0NFc9hEvgPzNJxeJedktXwzfJSln4EcRFRh5Vz4IlqFRScp+aiBBzA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-64/0.14.50: + resolution: {integrity: sha512-/1pHHCUem8e/R86/uR+4v5diI2CtBdiWKiqGuPa9b/0x3Nwdh5AOH7lj+8823C6uX1e0ufwkSLkS+aFZiBCWxA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-arm64/0.14.50: + resolution: {integrity: sha512-iKwUVMQztnPZe5pUYHdMkRc9aSpvoV1mkuHlCoPtxZA3V+Kg/ptpzkcSY+fKd0kuom+l6Rc93k0UPVkP7xoqrw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-32/0.14.50: + resolution: {integrity: sha512-sWUwvf3uz7dFOpLzYuih+WQ7dRycrBWHCdoXJ4I4XdMxEHCECd8b7a9N9u7FzT6XR2gHPk9EzvchQUtiEMRwqw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-64/0.14.50: + resolution: {integrity: sha512-u0PQxPhaeI629t4Y3EEcQ0wmWG+tC/LpP2K7yDFvwuPq0jSQ8SIN+ARNYfRjGW15O2we3XJvklbGV0wRuUCPig==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm/0.14.50: + resolution: {integrity: sha512-VALZq13bhmFJYFE/mLEb+9A0w5vo8z+YDVOWeaf9vOTrSC31RohRIwtxXBnVJ7YKLYfEMzcgFYf+OFln3Y0cWg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm64/0.14.50: + resolution: {integrity: sha512-ZyfoNgsTftD7Rp5S7La5auomKdNeB3Ck+kSKXC4pp96VnHyYGjHHXWIlcbH8i+efRn9brszo1/Thl1qn8RqmhQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-mips64le/0.14.50: + resolution: {integrity: sha512-ygo31Vxn/WrmjKCHkBoutOlFG5yM9J2UhzHb0oWD9O61dGg+Hzjz9hjf5cmM7FBhAzdpOdEWHIrVOg2YAi6rTw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-ppc64le/0.14.50: + resolution: {integrity: sha512-xWCKU5UaiTUT6Wz/O7GKP9KWdfbsb7vhfgQzRfX4ahh5NZV4ozZ4+SdzYG8WxetsLy84UzLX3Pi++xpVn1OkFQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-riscv64/0.14.50: + resolution: {integrity: sha512-0+dsneSEihZTopoO9B6Z6K4j3uI7EdxBP7YSF5rTwUgCID+wHD3vM1gGT0m+pjCW+NOacU9kH/WE9N686FHAJg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-s390x/0.14.50: + resolution: {integrity: sha512-tVjqcu8o0P9H4StwbIhL1sQYm5mWATlodKB6dpEZFkcyTI8kfIGWiWcrGmkNGH2i1kBUOsdlBafPxR3nzp3TDA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-netbsd-64/0.14.50: + resolution: {integrity: sha512-0R/glfqAQ2q6MHDf7YJw/TulibugjizBxyPvZIcorH0Mb7vSimdHy0XF5uCba5CKt+r4wjax1mvO9lZ4jiAhEg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-openbsd-64/0.14.50: + resolution: {integrity: sha512-7PAtmrR5mDOFubXIkuxYQ4bdNS6XCK8AIIHUiZxq1kL8cFIH5731jPcXQ4JNy/wbj1C9sZ8rzD8BIM80Tqk29w==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-sunos-64/0.14.50: + resolution: {integrity: sha512-gBxNY/wyptvD7PkHIYcq7se6SQEXcSC8Y7mE0FJB+CGgssEWf6vBPfTTZ2b6BWKnmaP6P6qb7s/KRIV5T2PxsQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-32/0.14.50: + resolution: {integrity: sha512-MOOe6J9cqe/iW1qbIVYSAqzJFh0p2LBLhVUIWdMVnNUNjvg2/4QNX4oT4IzgDeldU+Bym9/Tn6+DxvUHJXL5Zw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-64/0.14.50: + resolution: {integrity: sha512-r/qE5Ex3w1jjGv/JlpPoWB365ldkppUlnizhMxJgojp907ZF1PgLTuW207kgzZcSCXyquL9qJkMsY+MRtaZ5yQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-arm64/0.14.50: + resolution: {integrity: sha512-EMS4lQnsIe12ZyAinOINx7eq2mjpDdhGZZWDwPZE/yUTN9cnc2Ze/xUTYIAyaJqrqQda3LnDpADKpvLvol6ENQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild/0.14.50: + resolution: {integrity: sha512-SbC3k35Ih2IC6trhbMYW7hYeGdjPKf9atTKwBUHqMCYFZZ9z8zhuvfnZihsnJypl74FjiAKjBRqFkBkAd0rS/w==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-64: 0.14.50 + esbuild-android-arm64: 0.14.50 + esbuild-darwin-64: 0.14.50 + esbuild-darwin-arm64: 0.14.50 + esbuild-freebsd-64: 0.14.50 + esbuild-freebsd-arm64: 0.14.50 + esbuild-linux-32: 0.14.50 + esbuild-linux-64: 0.14.50 + esbuild-linux-arm: 0.14.50 + esbuild-linux-arm64: 0.14.50 + esbuild-linux-mips64le: 0.14.50 + esbuild-linux-ppc64le: 0.14.50 + esbuild-linux-riscv64: 0.14.50 + esbuild-linux-s390x: 0.14.50 + esbuild-netbsd-64: 0.14.50 + esbuild-openbsd-64: 0.14.50 + esbuild-sunos-64: 0.14.50 + esbuild-windows-32: 0.14.50 + esbuild-windows-64: 0.14.50 + esbuild-windows-arm64: 0.14.50 + dev: true + + /estree-walker/0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + dev: true + + /estree-walker/2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /fast-glob/3.2.11: + resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fastq/1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-uri-to-path/1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /fs-minipass/2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + dev: true + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /gauge/3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globalyzer/0.1.0: + resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} + dev: true + + /globrex/0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + dev: true + + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /has-unicode/2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /https-proxy-agent/5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /import-fresh/3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-core-module/2.9.0: + resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} + dependencies: + has: 1.0.3 + dev: true + + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /kleur/4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /magic-string/0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /magic-string/0.26.2: + resolution: {integrity: sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A==} + engines: {node: '>=12'} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /make-dir/3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /merge2/1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /min-indent/1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimist/1.2.6: + resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + dev: true + + /minipass/3.3.4: + resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + + /minizlib/2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + yallist: 4.0.0 + dev: true + + /mkdirp/0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.6 + dev: true + + /mkdirp/1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /mri/1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true + + /mrmime/1.0.1: + resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} + engines: {node: '>=10'} + dev: true + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /node-fetch/2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-gyp-build/4.5.0: + resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} + hasBin: true + dev: true + + /nopt/5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npmlog/5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: true + + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /parent-module/1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /postcss/8.4.14: + resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /prettier-plugin-svelte/2.7.0_o3ioganyptcsrh6x4hnxvjkpqi: + resolution: {integrity: sha512-fQhhZICprZot2IqEyoiUYLTRdumULGRvw0o4dzl5jt0jfzVWdGqeYW27QTWAeXhoupEZJULmNoH3ueJwUWFLIA==} + peerDependencies: + prettier: ^1.16.4 || ^2.0.0 + svelte: ^3.2.0 + dependencies: + prettier: 2.7.1 + svelte: 3.49.0 + dev: true + + /prettier/2.7.1: + resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /queue-microtask/1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /readable-stream/3.6.0: + resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /regexparam/2.0.1: + resolution: {integrity: sha512-zRgSaYemnNYxUv+/5SeoHI0eJIgTL/A2pUtXUPLHQxUldagouJ9p+K6IbIZ/JiQuCEv2E2B1O11SjVQy3aMCkw==} + engines: {node: '>=8'} + dev: true + + /resolve-from/4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from/5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.9.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /reusify/1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf/2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup-pluginutils/2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + dependencies: + estree-walker: 0.6.1 + dev: true + + /rollup/2.77.2: + resolution: {integrity: sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /run-parallel/1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /sade/1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + dependencies: + mri: 1.2.0 + dev: true + + /safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /sander/0.5.1: + resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==} + dependencies: + es6-promise: 3.3.1 + graceful-fs: 4.2.10 + mkdirp: 0.5.6 + rimraf: 2.7.1 + dev: true + + /semver/6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver/7.3.7: + resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /set-blocking/2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /set-cookie-parser/2.5.1: + resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==} + dev: true + + /signal-exit/3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /sorcery/0.10.0: + resolution: {integrity: sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==} + hasBin: true + dependencies: + buffer-crc32: 0.2.13 + minimist: 1.2.6 + sander: 0.5.1 + sourcemap-codec: 1.4.8 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /sourcemap-codec/1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string_decoder/1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-indent/3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /svelte-check/2.8.0_svelte@3.49.0: + resolution: {integrity: sha512-HRL66BxffMAZusqe5I5k26mRWQ+BobGd9Rxm3onh7ZVu0nTk8YTKJ9vu3LVPjUGLU9IX7zS+jmwPVhJYdXJ8vg==} + hasBin: true + peerDependencies: + svelte: ^3.24.0 + dependencies: + '@jridgewell/trace-mapping': 0.3.14 + chokidar: 3.5.3 + fast-glob: 3.2.11 + import-fresh: 3.3.0 + picocolors: 1.0.0 + sade: 1.8.1 + svelte: 3.49.0 + svelte-preprocess: 4.10.7_uslzfc62di2n2otc2tvfklnwji + typescript: 4.7.4 + transitivePeerDependencies: + - '@babel/core' + - coffeescript + - less + - node-sass + - postcss + - postcss-load-config + - pug + - sass + - stylus + - sugarss + dev: true + + /svelte-hmr/0.14.12_svelte@3.49.0: + resolution: {integrity: sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==} + engines: {node: ^12.20 || ^14.13.1 || >= 16} + peerDependencies: + svelte: '>=3.19.0' + dependencies: + svelte: 3.49.0 + dev: true + + /svelte-preprocess/4.10.7_uslzfc62di2n2otc2tvfklnwji: + resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==} + engines: {node: '>= 9.11.2'} + requiresBuild: true + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + node-sass: '*' + postcss: ^7 || ^8 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 + pug: ^3.0.0 + sass: ^1.26.8 + stylus: ^0.55.0 + sugarss: ^2.0.0 + svelte: ^3.23.0 + typescript: ^3.9.5 || ^4.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + node-sass: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + dependencies: + '@types/pug': 2.0.6 + '@types/sass': 1.43.1 + detect-indent: 6.1.0 + magic-string: 0.25.9 + sorcery: 0.10.0 + strip-indent: 3.0.0 + svelte: 3.49.0 + typescript: 4.7.4 + dev: true + + /svelte/3.49.0: + resolution: {integrity: sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==} + engines: {node: '>= 8'} + dev: true + + /tar/6.1.11: + resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} + engines: {node: '>= 10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 3.3.4 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: true + + /tiny-glob/0.2.9: + resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} + dependencies: + globalyzer: 0.1.0 + globrex: 0.1.2 + dev: true + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tr46/0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + + /tslib/2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: true + + /typescript/4.7.4: + resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /vite/3.0.3: + resolution: {integrity: sha512-sDIpIcl3mv1NUaSzZwiXGEy1ZoWwwC2vkxUHY6yiDacR6zf//ZFuBJrozO62gedpE43pmxnLATNR5IYUdAEkMQ==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + less: '*' + sass: '*' + stylus: '*' + terser: ^5.4.0 + peerDependenciesMeta: + less: + optional: true + sass: + optional: true + stylus: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.14.50 + postcss: 8.4.14 + resolve: 1.22.1 + rollup: 2.77.2 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /webidl-conversions/3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + + /whatwg-url/5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + + /wide-align/1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: true + + /worktop/0.8.0-next.14: + resolution: {integrity: sha512-RZgqHu1w/JcUdWOE/BUEAzarrUUHh39eWkLdX8XpA6MfgLJF6X5Vl26CV7/wcm4O/UpZvHMGJUtB9eYTqDjc9g==} + engines: {node: '>=12'} + dependencies: + mrmime: 1.0.1 + regexparam: 2.0.1 + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true diff --git a/client/src/app.d.ts b/client/src/app.d.ts new file mode 100644 index 0000000..b28d840 --- /dev/null +++ b/client/src/app.d.ts @@ -0,0 +1,11 @@ +/// + +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface Platform {} + // interface Session {} + // interface Stuff {} +} diff --git a/client/src/app.html b/client/src/app.html new file mode 100644 index 0000000..5b53ef7 --- /dev/null +++ b/client/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +

%sveltekit.body%
+ + diff --git a/client/src/lib/Websocket.ts b/client/src/lib/Websocket.ts new file mode 100644 index 0000000..193d894 --- /dev/null +++ b/client/src/lib/Websocket.ts @@ -0,0 +1,230 @@ +import { writable, type Writable } from "svelte/store"; + +class FastEvent extends Event { + data: any; + constructor(name: string, data: any) { + super(name); + this.data = data; + } +} + +const hosts: { urls: string, credential?: string, username?: string }[] = ("stun.ipfire.org:3478\n" + + "stun.rolmail.net:3478\n" + + "stun.steinbeis-smi.de:3478\n" + + "stun.marcelproust.it:3478\n" + + "stun3.3cx.com:3478\n" + + "stun.voipraider.com:3478\n" + + "stun.kore.com:3478\n" + + "stun.voipstunt.com:3478\n" + + "stun.fairytel.at:3478\n" + + "stun.h4v.eu:3478\n" + + "stun.peethultra.be:3478\n" + + "stun.ortopediacoam.it:3478\n" + + "stun.infra.net:3478\n" + + "stun.vavadating.com:3478\n" + + "stun.mixvoip.com:3478\n" + + "stun.tele2.net:3478\n" + + "stun2.3cx.com:3478\n" + + "stun.myhowto.org:3478\n" + + "stun.cellmail.com:3478\n" + + "stun.poetamatusel.org:3478\n" + + "stun.textz.com:3478\n" + + "stun.romancecompass.com:3478\n" + + "stun.ixc.ua:3478\n" + + "stun.actionvoip.com:3478\n" + + "stun.bethesda.net:3478\n" + + "stun.parcodeinebrodi.it:3478\n" + + "stun.jay.net:3478\n" + + "stun.demos.ru:3478\n" + + "stun.cloopen.com:3478\n" + + "stun.crimeastar.net:3478\n" + + "stun.vivox.com:3478\n" + + "stun.openjobs.hu:3478\n" + + "stun.kaznpu.kz:3478\n" + + "stun.linphone.org:3478\n" + + "stun.l.google.com:19302\n" + + "stun.sonetel.net:3478").split("\n").map(t => ({ urls: "stun:" + t })); + +hosts.push({ + urls: 'turn:relay.backups.cz', + credential: 'webrtc', + username: 'webrtc' +}, + { + urls: 'turn:relay.backups.cz?transport=tcp', + credential: 'webrtc', + username: 'webrtc' + }); + +class ConnectedClient extends EventTarget { + conn: RTCPeerConnection; + sendChannel: RTCDataChannel; + candidates: any[] = []; + state: RTCDataChannelState | null = null; + + constructor(public ws: WebsocketConnection, public name: string) { + super(); + // @ts-ignore Initialized in the next function call + this.conn = null; + // @ts-ignore + this.sendChannel = null; + this.initializeConnection(); + } + + initializeConnection() { + console.log("Initializing connection"); + this.conn = new RTCPeerConnection({ + iceServers: hosts + }); + + this.conn.onicecandidate = e => { + console.log(e); + if (!e.candidate) return; + this.candidates.push(e.candidate); + this.ws.send(JSON.stringify({ t: "cand", target: this.name, d: e.candidate })); + }; + this.conn.onicecandidateerror = (e) => console.error(e); + this.conn.ondatachannel = e => { + this.sendChannel = e.channel; + let timer: any; + this.sendChannel.onclose = (e) => { + clearInterval(timer); + this.statusChanged(); + } + this.sendChannel.onopen = (e) => { + timer = setInterval(() => { + this.send({ t: "p", d: Date.now() }); + }, 300); + this.statusChanged(); + } + this.statusChanged(); + this.sendChannel.onmessage = (e) => { + const msg = JSON.parse(e.data); + switch (msg.t) { + default: + console.log("MSG", msg); + this.dispatchEvent(new FastEvent(msg.t, msg.d)); + } + }; + } + } + + send(data: any) { + this.sendChannel.send(JSON.stringify(data)); + } + + statusChanged() { + if (this.sendChannel) { + if (this.state !== this.sendChannel.readyState) { + if (this.state === "open" && ["closing", "closed"].includes(this.sendChannel.readyState)) { + this.initializeConnection(); + } + this.state = this.sendChannel.readyState; + console.log("state", this.state); + } + } + } +} + +class WebsocketConnection extends EventTarget { + ws: WebSocket; + fast: Map = new Map(); + roomName: string | null = null; + roomId: string | null = null; + + constructor(public name: string) { + super(); + // @ts-ignore Initialized in the next function call + this.ws = null; + this.connect(); + } + + connect() { + this.ws = new WebSocket("ws://" + location.hostname + ":8080"); + this.ws.addEventListener("open", () => { + console.log("WS ready"); + }); + this.ws.addEventListener("message", (e) => { + const msg = JSON.parse(e.data); + console.log(msg); + switch (msg.t) { + case "cand": { + const fast = this.fast.get(msg.source); + if (!fast) return; + if (fast.state === "open") return console.log("Already open"); + for (const candidate of msg.d) { + fast.conn.addIceCandidate(candidate).then(); + } + break; + } + case "desc": { + const fast = this.fast.get(msg.source); + if (!fast) return; + if (fast.state === "open") return console.log("Already open"); + fast.conn.setRemoteDescription(msg.d) + .then(() => fast.conn.createAnswer()) + .then(answer => fast.conn.setLocalDescription(answer)) + .then(() => + this.ws.send(JSON.stringify({ t: "desc", target: fast.name, d: fast.conn.localDescription })) + ) + break; + } + case "join": { + const fast = new ConnectedClient(this, msg.name); + this.fast.set(msg.name, fast); + if (fast.conn.localDescription) { + this.ws.send(JSON.stringify({ t: "desc", target: msg.name, d: fast.conn.localDescription })) + } + if (fast.candidates) { + this.ws.send(JSON.stringify({ t: "cand", target: msg.name, d: fast.candidates })); + } + break; + } + case "joined": { + const clients = msg.clients; + this.fast = new Map(); + for (const client of clients) { + const fast = new ConnectedClient(this, client); + if (fast.conn.localDescription) { + this.ws.send(JSON.stringify({ t: "desc", target: msg.name, d: fast.conn.localDescription })) + } + if (fast.candidates) { + this.ws.send(JSON.stringify({ t: "cand", target: msg.name, d: fast.candidates })); + } + this.fast.set(client, fast); + } + } + case "leave": { + const fast = this.fast.get(msg.name); + if (!fast) return; + fast.conn.close(); + this.fast.delete(msg.name); + } + case "left": { + console.log("Left room successfully"); + this.roomName = null; + this.roomId = null; + this.fast.forEach(connection => connection.conn.close()); + this.fast = new Map(); + } + case "list": { + list.set(msg.rooms); + } + case "error": { + console.error(msg.e); + } + } + }); + } + + refreshList() { + this.ws.send(JSON.stringify({ t: "list" })); + } + + send(data: any) { + this.ws.send(data); + } +} + +export const connection: Writable = writable(null); +export const list: Writable<{ id: string, name: string, count: number }[]|null> = writable(null); \ No newline at end of file diff --git a/client/src/routes/index.svelte b/client/src/routes/index.svelte new file mode 100644 index 0000000..5982b0a --- /dev/null +++ b/client/src/routes/index.svelte @@ -0,0 +1,2 @@ +

Welcome to SvelteKit

+

Visit kit.svelte.dev to read the documentation

diff --git a/client/static/favicon.png b/client/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..825b9e65af7c104cfb07089bb28659393b4f2097 GIT binary patch literal 1571 zcmV+;2Hg3HP)Px)-AP12RCwC$UE6KzI1p6{F2N z1VK2vi|pOpn{~#djwYcWXTI_im_u^TJgMZ4JMOsSj!0ma>B?-(Hr@X&W@|R-$}W@Z zgj#$x=!~7LGqHW?IO8+*oE1MyDp!G=L0#^lUx?;!fXv@l^6SvTnf^ac{5OurzC#ZMYc20lI%HhX816AYVs1T3heS1*WaWH z%;x>)-J}YB5#CLzU@GBR6sXYrD>Vw(Fmt#|JP;+}<#6b63Ike{Fuo!?M{yEffez;| zp!PfsuaC)>h>-AdbnwN13g*1LowNjT5?+lFVd#9$!8Z9HA|$*6dQ8EHLu}U|obW6f z2%uGv?vr=KNq7YYa2Roj;|zooo<)lf=&2yxM@e`kM$CmCR#x>gI>I|*Ubr({5Y^rb zghxQU22N}F51}^yfDSt786oMTc!W&V;d?76)9KXX1 z+6Okem(d}YXmmOiZq$!IPk5t8nnS{%?+vDFz3BevmFNgpIod~R{>@#@5x9zJKEHLHv!gHeK~n)Ld!M8DB|Kfe%~123&Hz1Z(86nU7*G5chmyDe ziV7$pB7pJ=96hpxHv9rCR29%bLOXlKU<_13_M8x)6;P8E1Kz6G<&P?$P^%c!M5`2` zfY2zg;VK5~^>TJGQzc+33-n~gKt{{of8GzUkWmU110IgI0DLxRIM>0US|TsM=L|@F z0Bun8U!cRB7-2apz=y-7*UxOxz@Z0)@QM)9wSGki1AZ38ceG7Q72z5`i;i=J`ILzL z@iUO?SBBG-0cQuo+an4TsLy-g-x;8P4UVwk|D8{W@U1Zi z!M)+jqy@nQ$p?5tsHp-6J304Q={v-B>66$P0IDx&YT(`IcZ~bZfmn11#rXd7<5s}y zBi9eim&zQc0Dk|2>$bs0PnLmDfMP5lcXRY&cvJ=zKxI^f0%-d$tD!`LBf9^jMSYUA zI8U?CWdY@}cRq6{5~y+)#h1!*-HcGW@+gZ4B};0OnC~`xQOyH19z*TA!!BJ%9s0V3F?CAJ{hTd#*tf+ur-W9MOURF-@B77_-OshsY}6 zOXRY=5%C^*26z?l)1=$bz30!so5tfABdSYzO+H=CpV~aaUefmjvfZ3Ttu9W&W3Iu6 zROlh0MFA5h;my}8lB0tAV-Rvc2Zs_CCSJnx@d`**$idgy-iMob4dJWWw|21b4NB=LfsYp0Aeh{Ov)yztQi;eL4y5 zMi>8^SzKqk8~k?UiQK^^-5d8c%bV?$F8%X~czyiaKCI2=UH} + */ +const rooms = new Map(); +/** + * @type {Map} + */ +const clients = new Map(); + +require("uWebSockets.js") + .App({}) + .ws("/", { + idleTimeout: 30, + maxPayloadLength: 16 * 1024 * 1024, + upgrade: (res, req, context) => { + console.log( + `An Http connection wants to become WebSocket, URL: ${req.getUrl()}!` + ); + + const url = req.getUrl(); + const parsed = new URL(url); + let name = parsed.searchParams.get("name"); + if (!name || typeof name !== "string" || name.length < 2 || name.length > 64 || !name.trim()) return res.end("invalid_name"); + name = name.trim(); + if (clients.forEach(client => client.name === name)) return res.end("name_used"); + /* This immediately calls open handler, you must not use res after this call */ + res.upgrade( + { + url, + name + }, + /* Spell these correctly */ + req.getHeader("sec-websocket-key"), + req.getHeader("sec-websocket-protocol"), + req.getHeader("sec-websocket-extensions"), + context + ); + }, + open: (ws) => { + console.log( + "CON", + ws.url, + ws.name, + decoder.decode(ws.getRemoteAddressAsText()) + ); + clients.set(ws, { + connection: ws, + name: ws.name, + room: null + }); + }, + message: (ws, message, isBinary) => { + if (isBinary) return ws.end(); + try { + const data = JSON.parse(decoder.decode(message)); + if(data.t === "ping") return ws.ping(); + switch(data.t) { + case "ping": { + return ws.ping(); + } + case "create": { + const client = clients.get(ws); + if(client.room) return ws.send(JSON.stringify({t: "error", m: "already_in_room"})); + const name = data.name.trim(); + if (!name || typeof name !== "string" || name.length < 2 || name.length > 64 || !name.trim()) return res.send(JSON.stringify({t: "error", m: "invalid_room_name"})); + const room = { + name: name, + host: ws, + clients: [client], + id: uuid() + }; + rooms.set(room.id, room); + client.room = room; + return ws.send(JSON.stringify({ t: "create", id: room.id, name: name })); + } + case "leave": { + const client = clients.get(ws); + const room = client.room; + if (!room) return ws.send(JSON.stringify({ t: "error", m: "room_not_found" })); + if (!room.clients.includes(client)) return ws.send(JSON.stringify({ t: "error", m: "not_in_room" })); + room.clients.splice(room.clients.indexOf(client), 1); + if (room.clients.length === 0) { + rooms.delete(room.id); + } else if(room.host == ws) { + room.host = room.clients[0]; + room.clients.forEach(client => client.connection.send(JSON.stringify({ t: "host", host: client.name }))); + } + client.room = null; + room.clients.forEach(client => client.connection.send(JSON.stringify({ t: "leave", id: room.id, name: client.name }))); + ws.send(JSON.stringify({ t: "left", id: room.id, name: client.name })); + break; + } + case "join": { + const client = clients.get(ws); + if (!client) return ws.end(); + const room = client.room; + if (!room) return ws.send(JSON.stringify({ t: "error", e: "room_not_found" })); + if (room.clients.includes(client)) return ws.send(JSON.stringify({ t: "error", e: "already_in_room" })); + room.clients.push(ws); + ws.room = room; + room.clients.slice(0, -2).forEach(client => client.connection.send(JSON.stringify({ t: "join", id: room.id, client: client.name }))); + ws.send(JSON.stringify({ t: "joined", id: room.id, client: client.name, clients: room.clients.map(t => t.name) })); + break; + } + case "cand": + case "desc": { + const client = clients.get(ws); + if (!client) return ws.end(); + const room = client.room; + if (!room) return ws.send(JSON.stringify({ t: "error", e: "room_not_found" })); + if (!room.clients.includes(client)) return ws.send(JSON.stringify({ t: "error", e: "not_in_room" })); + const targetClient = room.clients.find(t => t.name === msg.target); + if(!targetClient) return ws.send(JSON.stringify({ t: "error", e: "target_not_found" })); + if(!room.clients.includes(targetClient)) return ws.send(JSON.stringify({ t: "error", e: "target_not_in_room" })); + targetClient.connection.send(JSON.stringify({ t: msg.t, id: room.id, source: client.name, d: msg.d })); + } + case "list": { + ws.send(JSON.stringify({ t: "list", rooms: [...rooms.values()].map(t => ({ id: t.id, name: t.name, count: t.clients.length }))})); + break; + } + } + } catch (e) { + return ws.end(); + } + }, + close: (ws, code, message) => { + console.log("DIS", decoder.decode(ws.getRemoteAddressAsText())); + if (clients.get(ws)) { + let room = rooms.get(clients.get(ws)); + if (room) { + room.clients.splice(room.clients.indexOf(ws), 1); + if (room.clients.length === 0) { + rooms.delete(room.id); + } else if(room.host == ws) { + room.host = room.clients[0]; + room.clients.forEach(client => client.connection.send(JSON.stringify({ t: "host", host: client.name }))); + } + } + } + clients.delete(ws); + }, + }) + .listen(PORT, () => { + console.log(`Listening on port ${PORT}`); + });